From daf4b8d3894cca25b3015d35e9168b7b2569d43b Mon Sep 17 00:00:00 2001 From: Ez Diy Date: Thu, 17 Sep 2020 00:43:27 +0200 Subject: Pass up terminal CSI as events to Lua. --- lua/vis.lua | 2 ++ main.c | 1 + vis-core.h | 1 + vis-lua.c | 21 +++++++++++++++++++++ vis-lua.h | 1 + vis.c | 15 +++++++++++++++ vis.h | 1 + 7 files changed, 42 insertions(+) diff --git a/lua/vis.lua b/lua/vis.lua index 479d1ee..dd17192 100644 --- a/lua/vis.lua +++ b/lua/vis.lua @@ -151,6 +151,7 @@ local events = { WIN_HIGHLIGHT = "Event::WIN_HIGHLIGHT", -- see @{win_highlight} WIN_OPEN = "Event::WIN_OPEN", -- see @{win_open} WIN_STATUS = "Event::WIN_STATUS", -- see @{win_status} + TERM_CSI = "Event::TERM_CSI", -- see @{term_csi} } events.file_close = function(...) events.emit(events.FILE_CLOSE, ...) end @@ -165,6 +166,7 @@ events.win_close = function(...) events.emit(events.WIN_CLOSE, ...) end events.win_highlight = function(...) events.emit(events.WIN_HIGHLIGHT, ...) end events.win_open = function(...) events.emit(events.WIN_OPEN, ...) end events.win_status = function(...) events.emit(events.WIN_STATUS, ...) end +events.term_csi = function(...) events.emit(events.TERM_CSI, ...) end local handlers = {} diff --git a/main.c b/main.c index 618f389..eb855ae 100644 --- a/main.c +++ b/main.c @@ -2213,6 +2213,7 @@ int main(int argc, char *argv[]) { .win_close = vis_lua_win_close, .win_highlight = vis_lua_win_highlight, .win_status = vis_lua_win_status, + .term_csi = vis_lua_term_csi, }; vis = vis_new(ui_term_new(), &event); diff --git a/vis-core.h b/vis-core.h index d409f88..b33ecdf 100644 --- a/vis-core.h +++ b/vis-core.h @@ -235,6 +235,7 @@ enum VisEvents { VIS_EVENT_WIN_CLOSE, VIS_EVENT_WIN_HIGHLIGHT, VIS_EVENT_WIN_STATUS, + VIS_EVENT_TERM_CSI, }; bool vis_event_emit(Vis*, enum VisEvents, ...); diff --git a/vis-lua.c b/vis-lua.c index 7741f41..40a619d 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -161,6 +161,7 @@ void vis_lua_win_open(Vis *vis, Win *win) { } void vis_lua_win_close(Vis *vis, Win *win) { } void vis_lua_win_highlight(Vis *vis, Win *win) { } void vis_lua_win_status(Vis *vis, Win *win) { window_status_update(vis, win); } +void vis_lua_term_csi(Vis *vis, const long *csi) { } #else @@ -3075,4 +3076,24 @@ void vis_lua_win_status(Vis *vis, Win *win) { lua_pop(L, 1); } +/*** + * CSI command received from terminal. + * @function term_csi + * @param List of CSI parameters + */ +void vis_lua_term_csi(Vis *vis, const long *csi) { + lua_State *L = vis->lua; + if (!L) + return; + vis_lua_event_get(L, "term_csi"); + if (lua_isfunction(L, -1)) { + int nargs = csi[1]; + lua_pushinteger(L, csi[0]); + for (int i = 0; i < nargs; i++) + lua_pushinteger(L, csi[2 + i]); + pcall(vis, L, 1 + nargs, 0); + } + lua_pop(L, 1); +} + #endif diff --git a/vis-lua.h b/vis-lua.h index c9ef1ec..da64233 100644 --- a/vis-lua.h +++ b/vis-lua.h @@ -37,5 +37,6 @@ void vis_lua_win_open(Vis*, Win*); void vis_lua_win_close(Vis*, Win*); void vis_lua_win_highlight(Vis*, Win*); void vis_lua_win_status(Vis*, Win*); +void vis_lua_term_csi(Vis*, const long *); #endif diff --git a/vis.c b/vis.c index c4e8fa1..182ee98 100644 --- a/vis.c +++ b/vis.c @@ -100,6 +100,10 @@ bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { if (vis->event->quit) vis->event->quit(vis); break; + case VIS_EVENT_TERM_CSI: + if (vis->event->term_csi) + vis->event->term_csi(vis, va_arg(ap, const long *)); + break; } va_end(ap); @@ -1304,6 +1308,17 @@ static const char *getkey(Vis *vis) { } TermKey *termkey = vis->ui->termkey_get(vis->ui); + if (key.type == TERMKEY_TYPE_UNKNOWN_CSI) { + long args[18]; + size_t nargs; + unsigned long cmd; + if (termkey_interpret_csi(termkey, &key, &args[2], &nargs, &cmd) == TERMKEY_RES_KEY) { + args[0] = (long)cmd; + args[1] = nargs; + vis_event_emit(vis, VIS_EVENT_TERM_CSI, args); + } + return getkey(vis); + } termkey_strfkey(termkey, vis->key, sizeof(vis->key), &key, TERMKEY_FORMAT_VIM); return vis->key; } diff --git a/vis.h b/vis.h index bdc452e..c575c9b 100644 --- a/vis.h +++ b/vis.h @@ -57,6 +57,7 @@ typedef struct { void (*win_close)(Vis*, Win*); void (*win_highlight)(Vis*, Win*); void (*win_status)(Vis*, Win*); + void (*term_csi)(Vis*, const long *); } VisEvent; /** Union used to pass arguments to key action functions. */ -- cgit v1.2.3