martanne / vis

A vi-like editor based on Plan 9's structural regular expressions
Other
4.23k stars 256 forks source link

Pass up terminal CSI as events to Lua. #872

Closed ezdiy closed 3 years ago

ezdiy commented 3 years ago

It allows to implement custom stuff such as mouse pointer or paste mode entirely in Lua.

In (neo)Vim, stuff like this is often hacked in really awkward and conflicting map fashion bound to scripts. I don't think doing so is wise as CSI are not really user input, but rather a state signal of the terminal emulator. Further complicated by that the CSI command itself is not actually a prefix code, but a last character in sequence (with variable data inbetween), making most of map-like binding useless.

An example of paste mode in visrc with this patch:

require 'vis'
local vis = vis
local io = io
local _ENV = setmetatable({}, {__index = function(t,k) return _ENV[k] or vis.events[k] or vis.modes[k] or function(...) return vis[k](vis, ...) end end })

command 'set expandtab'
command 'set autoindent'

-- enable/disable bracketed paste
subscribe(START, function() io.stdout:write("\x1b[?2004h"); io.stdout:flush() end)
subscribe(QUIT, function() io.stdout:write("\x1b[?2004l"); io.stdout:flush() end)

-- processing of bracketed pastes
subscribe(TERM_CSI, function(cmd, arg)
    if (cmd == 126) then
        if arg == 200 then
            command 'set expandtab off'
            command 'set autoindent off'
        elseif arg == 201 then
            command 'set expandtab'
            command 'set autoindent'
        end
    end
end)