diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:02:34 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:02:34 +0200 |
| commit | dbbbe30b637fccfacb15cd7317d4af87b658cfb5 (patch) | |
| tree | 8978cf092b8432a8f1e39d75ee4029f813a50fad /lua/clever_f/acquisition_service.lua | |
| parent | 154f639078470763fa788d31fac9b020d26b7825 (diff) | |
Normalize ordinary acquisition input
Diffstat (limited to 'lua/clever_f/acquisition_service.lua')
| -rw-r--r-- | lua/clever_f/acquisition_service.lua | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/lua/clever_f/acquisition_service.lua b/lua/clever_f/acquisition_service.lua index 707f568..b1e74bb 100644 --- a/lua/clever_f/acquisition_service.lua +++ b/lua/clever_f/acquisition_service.lua @@ -118,6 +118,7 @@ function TemporaryResourceScope.new(request, feedback) direct_marker = nil, cursor_presentation_lease = nil, input_packet = nil, + acquired_target = nil, } return scope end @@ -151,6 +152,10 @@ function TemporaryResourceScope:set_input_packet(packet) return set_scope_resource(self, "input_packet", packet) end +function TemporaryResourceScope:set_acquired_target(target) + return set_scope_resource(self, "acquired_target", target) +end + function TemporaryResourceScope:release() local record = scope_records[self] if record == nil then @@ -301,6 +306,72 @@ function AcquisitionService:started_scope_count() return service_records[self].started_scope_count end +local function utf8_first_code(character) + local first = string.byte(character, 1) + if first < 0x80 then + return first + end + local length + local code + if first >= 0xc2 and first <= 0xdf then + length = 2 + code = first - 0xc0 + elseif first >= 0xe0 and first <= 0xef then + length = 3 + code = first - 0xe0 + elseif first >= 0xf0 and first <= 0xf4 then + length = 4 + code = first - 0xf0 + else + fail("ordinary input must start with a valid editor character", 3) + end + for index = 2, length do + local byte = string.byte(character, index) + if byte == nil or byte < 0x80 or byte > 0xbf then + fail("ordinary input must contain a complete editor character", 3) + end + code = code * 0x40 + byte - 0x80 + end + return code +end + +local function first_editor_character(text) + local characters = text_topology.split_editor_characters(text) + if #characters == 0 then + fail("ordinary input must contain an editor character", 3) + end + return characters[1] +end + +function M.normalize_ordinary_input(packet) + packet = domain.InputPacket.from_table(packet) + local text + if packet.kind == domain.InputPacketKind.TEXT then + text = packet.text + elseif packet.kind == domain.InputPacketKind.RAW_BYTES then + local bytes = packet:bytes() + local characters = {} + for index = 1, #bytes do + characters[index] = string.char(bytes[index]) + end + text = table.concat(characters) + else + fail("ordinary input packet must contain text or raw bytes", 2) + end + local character = first_editor_character(text) + local runtime = rawget(_G, "vim") + local first_code + if type(runtime) == "table" + and type(runtime.fn) == "table" + and type(runtime.fn.char2nr) == "function" + then + first_code = runtime.fn.char2nr(character) + else + first_code = utf8_first_code(character) + end + return domain.TargetValue.character(character, first_code) +end + function M.is_terminal_artifact(packet) packet = domain.InputPacket.from_table(packet) if packet.kind ~= domain.InputPacketKind.RAW_BYTES then @@ -377,7 +448,12 @@ function AcquisitionService:acquire(descriptor, context, position, count, macro_ record.host:show_prompt(M.PROMPT) end record.transitions:BeginAcquisition(request.context, request.descriptor) - scope:set_input_packet(read_input_packet(record.host)) + local packet = scope:set_input_packet(read_input_packet(record.host)) + if packet.kind == domain.InputPacketKind.TEXT + or packet.kind == domain.InputPacketKind.RAW_BYTES + then + scope:set_acquired_target(M.normalize_ordinary_input(packet)) + end return request end |
