summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua')
-rw-r--r--lua/clever_f/acquisition_service.lua78
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