hchunhui / librime-lua

Extending RIME with Lua scripts
BSD 3-Clause "New" or "Revised" License
357 stars 43 forks source link

Wrap Spans #361

Closed ksqsf closed 3 months ago

ksqsf commented 3 months ago

Spans is necessary for syllable-level navigation, like this:

https://github.com/user-attachments/assets/b8d5c545-3eec-4809-8cba-752ab3f51acb

This video uses the following script initial_jump.lua, which showcases what can be done with Spans: after pressing Shift+Control+S, it jumps to the beginning of a syllable whose initial is s.

local kReject = 0
local kAccepted = 1
local kNoop = 2

local function PreviousStopWithInitial(spans, input, initial, caret_pos, start)
   local stop = spans:previous_stop(caret_pos)
   while stop >= start do
      local char = input:sub(stop+1,stop+1)
      print('i='..tostring(i)..' char='..char..' stop='..tostring(stop))
      if char == initial then
         return stop
      end
      local next = spans:previous_stop(stop)
      if next == stop then
         return nil
      end
      stop = next
   end
   return nil
end

local function ComputeSpans(segmentation)
   local spans = Spans()
   local len = segmentation.size
   for i = 0, len - 1 do
      local seg = segmentation:get_at(i)
      local cand = seg:get_selected_candidate()
      if cand then
         local phrase = cand:to_phrase()
         if phrase then
            spans:add_spans(phrase:spans())
         end
      end
      spans:add_span(seg._start, seg._end)
   end
   return spans
end

return function(key_event, env)
   print('Got key: ' .. key_event:repr())

   local ctx = env.engine.context
   local composition = env.engine.context.composition
   local segmentation = composition:toSegmentation()
   local spans = ComputeSpans(segmentation)

   if key_event:repr() == 'Shift+Control+S' then
      local stop = PreviousStopWithInitial(spans, ctx.input, 's', ctx.caret_pos, segmentation:get_confirmed_position())
      if stop then
         ctx.caret_pos = stop
         return kAccepted
      end
   end

   return kNoop
end

(Disclaimer: this script is not complete. It's just for demonstration purposes.)

hchunhui commented 3 months ago

LGTM. Thanks!