mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
feat(ui): implement ui_client event handlers
This commit is contained in:
parent
aa35d15a0d
commit
794d2744f3
5
src/nvim/CMakeLists.txt
Normal file → Executable file
5
src/nvim/CMakeLists.txt
Normal file → Executable file
@ -39,6 +39,7 @@ set(GENERATED_UI_EVENTS ${GENERATED_DIR}/ui_events.generated.h)
|
|||||||
set(GENERATED_UI_EVENTS_CALL ${GENERATED_DIR}/ui_events_call.generated.h)
|
set(GENERATED_UI_EVENTS_CALL ${GENERATED_DIR}/ui_events_call.generated.h)
|
||||||
set(GENERATED_UI_EVENTS_REMOTE ${GENERATED_DIR}/ui_events_remote.generated.h)
|
set(GENERATED_UI_EVENTS_REMOTE ${GENERATED_DIR}/ui_events_remote.generated.h)
|
||||||
set(GENERATED_UI_EVENTS_BRIDGE ${GENERATED_DIR}/ui_events_bridge.generated.h)
|
set(GENERATED_UI_EVENTS_BRIDGE ${GENERATED_DIR}/ui_events_bridge.generated.h)
|
||||||
|
set(GENERATED_UI_EVENTS_REDRAW ${GENERATED_DIR}/ui_events_redraw.generated.h)
|
||||||
set(GENERATED_UI_EVENTS_METADATA ${GENERATED_DIR}/api/private/ui_events_metadata.generated.h)
|
set(GENERATED_UI_EVENTS_METADATA ${GENERATED_DIR}/api/private/ui_events_metadata.generated.h)
|
||||||
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
|
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
|
||||||
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
|
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
|
||||||
@ -271,6 +272,7 @@ foreach(sfile ${NVIM_SOURCES}
|
|||||||
"${GENERATED_UI_EVENTS_REMOTE}"
|
"${GENERATED_UI_EVENTS_REMOTE}"
|
||||||
"${GENERATED_UI_EVENTS_BRIDGE}"
|
"${GENERATED_UI_EVENTS_BRIDGE}"
|
||||||
"${GENERATED_KEYSETS}"
|
"${GENERATED_KEYSETS}"
|
||||||
|
"${GENERATED_UI_EVENTS_REDRAW}"
|
||||||
)
|
)
|
||||||
get_filename_component(full_d ${sfile} PATH)
|
get_filename_component(full_d ${sfile} PATH)
|
||||||
file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}")
|
file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}")
|
||||||
@ -368,6 +370,7 @@ add_custom_command(
|
|||||||
${GENERATED_UI_EVENTS_REMOTE}
|
${GENERATED_UI_EVENTS_REMOTE}
|
||||||
${GENERATED_UI_EVENTS_BRIDGE}
|
${GENERATED_UI_EVENTS_BRIDGE}
|
||||||
${GENERATED_UI_EVENTS_METADATA}
|
${GENERATED_UI_EVENTS_METADATA}
|
||||||
|
${GENERATED_UI_EVENTS_REDRAW}
|
||||||
COMMAND ${LUA_PRG} ${API_UI_EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
|
COMMAND ${LUA_PRG} ${API_UI_EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
|
${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
|
||||||
${GENERATED_UI_EVENTS}
|
${GENERATED_UI_EVENTS}
|
||||||
@ -375,6 +378,8 @@ add_custom_command(
|
|||||||
${GENERATED_UI_EVENTS_REMOTE}
|
${GENERATED_UI_EVENTS_REMOTE}
|
||||||
${GENERATED_UI_EVENTS_BRIDGE}
|
${GENERATED_UI_EVENTS_BRIDGE}
|
||||||
${GENERATED_UI_EVENTS_METADATA}
|
${GENERATED_UI_EVENTS_METADATA}
|
||||||
|
${GENERATED_UI_EVENTS_REDRAW}
|
||||||
|
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${API_UI_EVENTS_GENERATOR}
|
${API_UI_EVENTS_GENERATOR}
|
||||||
${GENERATOR_C_GRAMMAR}
|
${GENERATOR_C_GRAMMAR}
|
||||||
|
@ -84,7 +84,7 @@ void grid_clear(Integer grid)
|
|||||||
void grid_cursor_goto(Integer grid, Integer row, Integer col)
|
void grid_cursor_goto(Integer grid, Integer row, Integer col)
|
||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
||||||
void grid_line(Integer grid, Integer row, Integer col_start, Array data)
|
void grid_line(Integer grid, Integer row, Integer col_start, Array data)
|
||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY;
|
FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY FUNC_API_CLIENT_IMPL;
|
||||||
void grid_scroll(Integer grid, Integer top, Integer bot,
|
void grid_scroll(Integer grid, Integer top, Integer bot,
|
||||||
Integer left, Integer right, Integer rows, Integer cols)
|
Integer left, Integer right, Integer rows, Integer cols)
|
||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
||||||
|
@ -49,6 +49,7 @@ local c_proto = Ct(
|
|||||||
(fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) *
|
(fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) *
|
||||||
(fill * Cg((P('FUNC_API_BRIDGE_IMPL') * Cc(true)), 'bridge_impl') ^ -1) *
|
(fill * Cg((P('FUNC_API_BRIDGE_IMPL') * Cc(true)), 'bridge_impl') ^ -1) *
|
||||||
(fill * Cg((P('FUNC_API_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1) *
|
(fill * Cg((P('FUNC_API_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1) *
|
||||||
|
(fill * Cg((P('FUNC_API_CLIENT_IMPL') * Cc(true)), 'client_impl') ^ -1) *
|
||||||
fill * P(';')
|
fill * P(';')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
62
src/nvim/generators/gen_api_ui_events.lua
Normal file → Executable file
62
src/nvim/generators/gen_api_ui_events.lua
Normal file → Executable file
@ -3,15 +3,16 @@ local mpack = require('mpack')
|
|||||||
local nvimdir = arg[1]
|
local nvimdir = arg[1]
|
||||||
package.path = nvimdir .. '/?.lua;' .. package.path
|
package.path = nvimdir .. '/?.lua;' .. package.path
|
||||||
|
|
||||||
assert(#arg == 7)
|
assert(#arg == 8)
|
||||||
local input = io.open(arg[2], 'rb')
|
local input = io.open(arg[2], 'rb')
|
||||||
local proto_output = io.open(arg[3], 'wb')
|
local proto_output = io.open(arg[3], 'wb')
|
||||||
local call_output = io.open(arg[4], 'wb')
|
local call_output = io.open(arg[4], 'wb')
|
||||||
local remote_output = io.open(arg[5], 'wb')
|
local remote_output = io.open(arg[5], 'wb')
|
||||||
local bridge_output = io.open(arg[6], 'wb')
|
local bridge_output = io.open(arg[6], 'wb')
|
||||||
local metadata_output = io.open(arg[7], 'wb')
|
local metadata_output = io.open(arg[7], 'wb')
|
||||||
|
local redraw_output = io.open(arg[8], 'wb')
|
||||||
|
|
||||||
local c_grammar = require('generators.c_grammar')
|
c_grammar = require('generators.c_grammar')
|
||||||
local events = c_grammar.grammar:match(input:read('*all'))
|
local events = c_grammar.grammar:match(input:read('*all'))
|
||||||
|
|
||||||
local function write_signature(output, ev, prefix, notype)
|
local function write_signature(output, ev, prefix, notype)
|
||||||
@ -50,6 +51,35 @@ local function write_arglist(output, ev, need_copy)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function extract_and_write_arglist(output, ev)
|
||||||
|
local hlattrs_args_count = 0
|
||||||
|
for j = 1, #ev.parameters do
|
||||||
|
local param = ev.parameters[j]
|
||||||
|
local kind = param[1]
|
||||||
|
output:write(' '..kind..' arg_'..j..' = ')
|
||||||
|
if kind == 'HlAttrs' then
|
||||||
|
-- The first HlAttrs argument is rgb_attrs and second is cterm_attrs
|
||||||
|
output:write('redraw_dict2hlattrs(args.items['..(j-1)..'].data.dictionary, '..(hlattrs_args_count == 0 and 'true' or 'false')..');\n')
|
||||||
|
hlattrs_args_count = hlattrs_args_count + 1
|
||||||
|
elseif kind == 'Object' then
|
||||||
|
output:write('args.items['..(j-1)..'];\n')
|
||||||
|
else
|
||||||
|
output:write('args.items['..(j-1)..'].data.'..string.lower(kind)..';\n')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function call_ui_event_method(output, ev)
|
||||||
|
output:write(' ui_call_'..ev.name..'(')
|
||||||
|
for j = 1, #ev.parameters do
|
||||||
|
output:write('arg_'..j)
|
||||||
|
if j ~= #ev.parameters then
|
||||||
|
output:write(', ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
output:write(');\n')
|
||||||
|
end
|
||||||
|
|
||||||
for i = 1, #events do
|
for i = 1, #events do
|
||||||
local ev = events[i]
|
local ev = events[i]
|
||||||
assert(ev.return_type == 'void')
|
assert(ev.return_type == 'void')
|
||||||
@ -160,12 +190,38 @@ for i = 1, #events do
|
|||||||
call_output:write(";\n")
|
call_output:write(";\n")
|
||||||
call_output:write("}\n\n")
|
call_output:write("}\n\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (not ev.remote_only) and (not ev.noexport) and (not ev.client_impl) then
|
||||||
|
redraw_output:write('void ui_redraw_event_'..ev.name..'(Array args)\n{\n')
|
||||||
|
extract_and_write_arglist(redraw_output, ev)
|
||||||
|
call_ui_event_method(redraw_output, ev)
|
||||||
|
redraw_output:write('}\n\n')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Generate the map_init method for redraw handlers
|
||||||
|
redraw_output:write([[
|
||||||
|
void redraw_methods_table_init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
for i = 1, #events do
|
||||||
|
local fn = events[i]
|
||||||
|
if (not fn.noexport) and ((not fn.remote_only) or fn.client_impl) then
|
||||||
|
redraw_output:write(' add_redraw_event_handler('..
|
||||||
|
'(String) {.data = "'..fn.name..'", '..
|
||||||
|
'.size = sizeof("'..fn.name..'") - 1}, '..
|
||||||
|
'(ApiRedrawWrapper) ui_redraw_event_'..fn.name..');\n')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
redraw_output:write('\n}\n\n')
|
||||||
|
|
||||||
proto_output:close()
|
proto_output:close()
|
||||||
call_output:close()
|
call_output:close()
|
||||||
remote_output:close()
|
remote_output:close()
|
||||||
bridge_output:close()
|
redraw_output:close()
|
||||||
|
|
||||||
-- don't expose internal attributes like "impl_name" in public metadata
|
-- don't expose internal attributes like "impl_name" in public metadata
|
||||||
local exported_attributes = {'name', 'parameters',
|
local exported_attributes = {'name', 'parameters',
|
||||||
|
@ -179,6 +179,7 @@ MAP_IMPL(HlEntry, int, DEFAULT_INITIALIZER)
|
|||||||
MAP_IMPL(String, handle_T, 0)
|
MAP_IMPL(String, handle_T, 0)
|
||||||
MAP_IMPL(String, int, DEFAULT_INITIALIZER)
|
MAP_IMPL(String, int, DEFAULT_INITIALIZER)
|
||||||
MAP_IMPL(int, String, DEFAULT_INITIALIZER)
|
MAP_IMPL(int, String, DEFAULT_INITIALIZER)
|
||||||
|
MAP_IMPL(String, ApiRedrawWrapper, NULL)
|
||||||
|
|
||||||
MAP_IMPL(ColorKey, ColorItem, COLOR_ITEM_INITIALIZER)
|
MAP_IMPL(ColorKey, ColorItem, COLOR_ITEM_INITIALIZER)
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "nvim/extmark_defs.h"
|
#include "nvim/extmark_defs.h"
|
||||||
#include "nvim/highlight_defs.h"
|
#include "nvim/highlight_defs.h"
|
||||||
#include "nvim/map_defs.h"
|
#include "nvim/map_defs.h"
|
||||||
|
#include "nvim/ui_client.h"
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
#if defined(__NetBSD__)
|
||||||
# undef uint64_t
|
# undef uint64_t
|
||||||
@ -48,6 +49,7 @@ MAP_DECLS(HlEntry, int)
|
|||||||
MAP_DECLS(String, handle_T)
|
MAP_DECLS(String, handle_T)
|
||||||
MAP_DECLS(String, int)
|
MAP_DECLS(String, int)
|
||||||
MAP_DECLS(int, String)
|
MAP_DECLS(int, String)
|
||||||
|
MAP_DECLS(String, ApiRedrawWrapper)
|
||||||
|
|
||||||
MAP_DECLS(ColorKey, ColorItem)
|
MAP_DECLS(ColorKey, ColorItem)
|
||||||
|
|
||||||
|
@ -6,11 +6,22 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
#include "nvim/log.h"
|
||||||
|
#include "nvim/map.h"
|
||||||
#include "nvim/ui_client.h"
|
#include "nvim/ui_client.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/msgpack_rpc/channel.h"
|
#include "nvim/msgpack_rpc/channel.h"
|
||||||
#include "nvim/api/private/dispatch.h"
|
#include "nvim/api/private/dispatch.h"
|
||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
|
#include "nvim/highlight.h"
|
||||||
|
#include "nvim/screen.h"
|
||||||
|
|
||||||
|
static Map(String, ApiRedrawWrapper) redraw_methods = MAP_INIT;
|
||||||
|
|
||||||
|
static void add_redraw_event_handler(String method, ApiRedrawWrapper handler)
|
||||||
|
{
|
||||||
|
map_put(String, ApiRedrawWrapper)(&redraw_methods, method, handler);
|
||||||
|
}
|
||||||
|
|
||||||
void ui_client_init(uint64_t chan)
|
void ui_client_init(uint64_t chan)
|
||||||
{
|
{
|
||||||
@ -68,3 +79,106 @@ void ui_client_execute(uint64_t chan)
|
|||||||
|
|
||||||
getout(0);
|
getout(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @param name Redraw method name
|
||||||
|
/// @param name_len name size (includes terminating NUL)
|
||||||
|
ApiRedrawWrapper get_redraw_event_handler(const char *name, size_t name_len, Error *error)
|
||||||
|
{
|
||||||
|
String m = { .data = (char *)name, .size = name_len };
|
||||||
|
ApiRedrawWrapper rv =
|
||||||
|
map_get(String, ApiRedrawWrapper)(&redraw_methods, m);
|
||||||
|
|
||||||
|
if (!rv) {
|
||||||
|
api_set_error(error, kErrorTypeException, "Invalid method: %.*s",
|
||||||
|
m.size > 0 ? (int)m.size : (int)sizeof("<empty>"),
|
||||||
|
m.size > 0 ? m.data : "<empty>");
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HlAttrs redraw_dict2hlattrs(Dictionary redraw_dict, bool rgb)
|
||||||
|
{
|
||||||
|
Error err = ERROR_INIT;
|
||||||
|
Dict(highlight) dict = { 0 };
|
||||||
|
if (!api_dict_to_keydict(&dict, KeyDict_highlight_get_field, redraw_dict, &err)) {
|
||||||
|
// TODO(bfredl): log "err"
|
||||||
|
return HLATTRS_INIT;
|
||||||
|
}
|
||||||
|
return dict2hlattrs(&dict, true, NULL, &err);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
#include "ui_events_redraw.generated.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ui_redraw_event_grid_line(Array args)
|
||||||
|
{
|
||||||
|
Integer grid = args.items[0].data.integer;
|
||||||
|
Integer row = args.items[1].data.integer;
|
||||||
|
Integer startcol = args.items[2].data.integer;
|
||||||
|
Array cells = args.items[3].data.array;
|
||||||
|
Integer endcol, clearcol, clearattr;
|
||||||
|
// TODO(hlpr98): Accomodate other LineFlags when included in grid_line
|
||||||
|
LineFlags lineflags = 0;
|
||||||
|
schar_T *chunk;
|
||||||
|
sattr_T *attrs;
|
||||||
|
size_t size_of_cells = cells.size;
|
||||||
|
size_t no_of_cells = size_of_cells;
|
||||||
|
endcol = startcol;
|
||||||
|
|
||||||
|
// checking if clearcol > endcol
|
||||||
|
if (!STRCMP(cells.items[size_of_cells-1].data.array
|
||||||
|
.items[0].data.string.data, " ")
|
||||||
|
&& cells.items[size_of_cells-1].data.array.size == 3) {
|
||||||
|
no_of_cells = size_of_cells - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getting endcol
|
||||||
|
for (size_t i = 0; i < no_of_cells; i++) {
|
||||||
|
endcol++;
|
||||||
|
if (cells.items[i].data.array.size == 3) {
|
||||||
|
endcol += cells.items[i].data.array.items[2].data.integer - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!STRCMP(cells.items[size_of_cells-1].data.array
|
||||||
|
.items[0].data.string.data, " ")
|
||||||
|
&& cells.items[size_of_cells-1].data.array.size == 3) {
|
||||||
|
clearattr = cells.items[size_of_cells-1].data.array.items[1].data.integer;
|
||||||
|
clearcol = endcol + cells.items[size_of_cells-1].data.array
|
||||||
|
.items[2].data.integer;
|
||||||
|
} else {
|
||||||
|
clearattr = 0;
|
||||||
|
clearcol = endcol;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ncells = (size_t)(endcol - startcol);
|
||||||
|
chunk = xmalloc(ncells * sizeof(schar_T) + 1);
|
||||||
|
attrs = xmalloc(ncells * sizeof(sattr_T) + 1);
|
||||||
|
|
||||||
|
size_t j = 0;
|
||||||
|
size_t k = 0;
|
||||||
|
for (size_t i = 0; i < no_of_cells; i++) {
|
||||||
|
STRCPY(chunk[j++], cells.items[i].data.array.items[0].data.string.data);
|
||||||
|
if (cells.items[i].data.array.size == 3) {
|
||||||
|
// repeat present
|
||||||
|
for (size_t i_intr = 1;
|
||||||
|
i_intr < (size_t)cells.items[i].data.array.items[2].data.integer;
|
||||||
|
i_intr++) {
|
||||||
|
STRCPY(chunk[j++], cells.items[i].data.array.items[0].data.string.data);
|
||||||
|
attrs[k++] = (sattr_T)cells.items[i].data.array.items[1].data.integer;
|
||||||
|
}
|
||||||
|
} else if (cells.items[i].data.array.size == 2) {
|
||||||
|
// repeat = 1 but attrs != last_hl
|
||||||
|
attrs[k++] = (sattr_T)cells.items[i].data.array.items[1].data.integer;
|
||||||
|
}
|
||||||
|
if (j > k) {
|
||||||
|
// attrs == last_hl
|
||||||
|
attrs[k] = attrs[k-1];
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_call_raw_line(grid, row, startcol, endcol, clearcol, clearattr, lineflags,
|
||||||
|
(const schar_T *)chunk, (const sattr_T *)attrs);
|
||||||
|
}
|
||||||
|
@ -3,7 +3,11 @@
|
|||||||
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
|
|
||||||
|
typedef void (*ApiRedrawWrapper)(Array args);
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
#include "ui_client.h.generated.h"
|
#include "ui_client.h.generated.h"
|
||||||
|
#include "ui_events_redraw.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // NVIM_UI_CLIENT_H
|
#endif // NVIM_UI_CLIENT_H
|
||||||
|
Loading…
Reference in New Issue
Block a user