local RUNEX_BIN = {CLINK_BIN}
local function runex_is_safe_line(line)
return not line:find("[%z\1-\31]")
end
local function runex_shell_quote(s)
return '"' .. s:gsub('"', '\\"') .. '"'
end
local function runex_call_hook(line, cursor)
if not runex_is_safe_line(line) then
return nil
end
local cmd = '"' .. runex_shell_quote(RUNEX_BIN)
.. ' hook --shell clink --line ' .. runex_shell_quote(line)
.. ' --cursor ' .. tostring(cursor)
.. ' 2>&1"'
local handle = io.popen(cmd)
if not handle then return nil end
local out = handle:read("*a")
handle:close()
if not out or out == "" then return nil end
local chunk, err = load(out, "=runex_hook", "t", {})
if not chunk then return nil end
local ok, result = pcall(chunk)
if not ok or type(result) ~= "table" then return nil end
if type(result.line) ~= "string" or type(result.cursor) ~= "number" then
return nil
end
return result
end
function runex_expand(rl_buffer, line_state)
local line = rl_buffer:getbuffer()
local cursor = rl_buffer:getcursor()
local result = runex_call_hook(line, cursor - 1)
if result and result.line ~= line then
rl_buffer:beginundogroup()
rl_buffer:remove(1, rl_buffer:getlength() + 1)
rl_buffer:insert(result.line)
rl_buffer:setcursor(result.cursor + 1)
rl_buffer:endundogroup()
else
rl_buffer:insert(" ")
end
end
rl.describemacro([["luafunc:runex_expand"]], "Expand a runex abbreviation and insert a space")
{CLINK_BINDING}