mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	api: generate ui events
This commit is contained in:
		
							
								
								
									
										183
									
								
								scripts/gen_ui_events.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								scripts/gen_ui_events.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | |||||||
|  | lpeg = require('lpeg') | ||||||
|  | mpack = require('mpack') | ||||||
|  |  | ||||||
|  | -- TODO: reduce copying | ||||||
|  | -- lpeg grammar for building api metadata from a set of header files. It | ||||||
|  | -- ignores comments and preprocessor commands and parses a very small subset | ||||||
|  | -- of C prototypes with a limited set of types | ||||||
|  | P, R, S = lpeg.P, lpeg.R, lpeg.S | ||||||
|  | C, Ct, Cc, Cg = lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg | ||||||
|  |  | ||||||
|  | any = P(1) -- (consume one character) | ||||||
|  | letter = R('az', 'AZ') + S('_$') | ||||||
|  | num = R('09') | ||||||
|  | alpha = letter + num | ||||||
|  | nl = P('\r\n') + P('\n') | ||||||
|  | not_nl = any - nl | ||||||
|  | ws = S(' \t') + nl | ||||||
|  | fill = ws ^ 0 | ||||||
|  | c_comment = P('//') * (not_nl ^ 0) | ||||||
|  | c_preproc = P('#') * (not_nl ^ 0) | ||||||
|  | typed_container = | ||||||
|  |   (P('ArrayOf(') + P('DictionaryOf(')) * ((any - P(')')) ^ 1) * P(')') | ||||||
|  | c_id = ( | ||||||
|  |   typed_container + | ||||||
|  |   (letter * (alpha ^ 0)) | ||||||
|  | ) | ||||||
|  | c_void = P('void') | ||||||
|  | c_param_type = ( | ||||||
|  |   ((P('Error') * fill * P('*') * fill) * Cc('error')) + | ||||||
|  |   (C(c_id) * (ws ^ 1)) | ||||||
|  |   ) | ||||||
|  | c_type = (C(c_void) * (ws ^ 1)) + c_param_type | ||||||
|  | c_param = Ct(c_param_type * C(c_id)) | ||||||
|  | c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0) | ||||||
|  | c_params = Ct(c_void + c_param_list) | ||||||
|  | c_proto = Ct( | ||||||
|  |   Cg(c_type, 'return_type') * Cg(c_id, 'name') * | ||||||
|  |   fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') * | ||||||
|  |   Cg(Cc(false), 'async') * | ||||||
|  |   (fill * Cg((P('FUNC_API_SINCE(') * C(num ^ 1)) * P(')'), 'since') ^ -1) * | ||||||
|  |   (fill * Cg((P('REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) * | ||||||
|  |   (fill * Cg((P('REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) * | ||||||
|  |   (fill * Cg((P('BRIDGE_IMPL') * Cc(true)), 'bridge_impl') ^ -1) * | ||||||
|  |   fill * P(';') | ||||||
|  |   ) | ||||||
|  | grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -- we need at least 4 arguments since the last two are output files | ||||||
|  | assert(#arg == 6) | ||||||
|  | input = io.open(arg[2], 'rb') | ||||||
|  | proto_output = io.open(arg[3], 'wb') | ||||||
|  | call_output = io.open(arg[4], 'wb') | ||||||
|  | remote_output = io.open(arg[5], 'wb') | ||||||
|  | bridge_output = io.open(arg[6], 'wb') | ||||||
|  |  | ||||||
|  | functions = {} | ||||||
|  |  | ||||||
|  | local events = grammar:match(input:read('*all')) | ||||||
|  |  | ||||||
|  | function write_signature(output, ev, prefix, notype) | ||||||
|  |   output:write('('..prefix) | ||||||
|  |   if prefix == "" and #ev.parameters == 0 then | ||||||
|  |     output:write('void') | ||||||
|  |   end | ||||||
|  |   for j = 1, #ev.parameters do | ||||||
|  |     if j > 1 or prefix ~= '' then | ||||||
|  |       output:write(', ') | ||||||
|  |     end | ||||||
|  |     local param = ev.parameters[j] | ||||||
|  |     if not notype then | ||||||
|  |       output:write(param[1]..' ') | ||||||
|  |     end | ||||||
|  |     output:write(param[2]) | ||||||
|  |   end | ||||||
|  |   output:write(')') | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function write_arglist(output, ev, need_copy) | ||||||
|  |   output:write('  Array args = ARRAY_DICT_INIT;\n') | ||||||
|  |   for j = 1, #ev.parameters do | ||||||
|  |     local param = ev.parameters[j] | ||||||
|  |     local kind = string.upper(param[1]) | ||||||
|  |     local do_copy = need_copy and (kind == "ARRAY" or kind == "DICTIONARY" or kind == "STRING") | ||||||
|  |     output:write('  ADD(args, ') | ||||||
|  |     if do_copy then | ||||||
|  |       output:write('copy_object(') | ||||||
|  |     end | ||||||
|  |     output:write(kind..'_OBJ('..param[2]..')') | ||||||
|  |     if do_copy then | ||||||
|  |       output:write(')') | ||||||
|  |     end | ||||||
|  |     output:write(');\n') | ||||||
|  |   end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | for i = 1, #events do | ||||||
|  |   ev = events[i] | ||||||
|  |   assert(ev.return_type == 'void') | ||||||
|  |  | ||||||
|  |   if not ev.remote_only then | ||||||
|  |     proto_output:write('  void (*'..ev.name..')') | ||||||
|  |     write_signature(proto_output, ev, 'UI *ui') | ||||||
|  |     proto_output:write(';\n') | ||||||
|  |  | ||||||
|  |     if not ev.remote_impl then | ||||||
|  |       remote_output:write('static void remote_ui_'..ev.name) | ||||||
|  |       write_signature(remote_output, ev, 'UI *ui') | ||||||
|  |       remote_output:write('\n{\n') | ||||||
|  |       write_arglist(remote_output, ev, true) | ||||||
|  |       remote_output:write('  push_call(ui, "'..ev.name..'", args);\n') | ||||||
|  |       remote_output:write('}\n\n') | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     if not ev.bridge_impl then | ||||||
|  |  | ||||||
|  |       send, argv, recv, recv_argv, recv_cleanup = '', '', '', '', '' | ||||||
|  |       argc = 1 | ||||||
|  |       for j = 1, #ev.parameters do | ||||||
|  |         local param = ev.parameters[j] | ||||||
|  |         copy = 'copy_'..param[2] | ||||||
|  |         if param[1] == 'String' then | ||||||
|  |           send = send..'  String copy_'..param[2]..' = copy_string('..param[2]..');\n' | ||||||
|  |           argv = argv..', '..copy..'.data, INT2PTR('..copy..'.size)' | ||||||
|  |           recv = (recv..'  String '..param[2].. | ||||||
|  |                           ' = (String){.data = argv['..argc..'],'.. | ||||||
|  |                           '.size = (size_t)argv['..(argc+1)..']};\n') | ||||||
|  |           recv_argv = recv_argv..', '..param[2] | ||||||
|  |           recv_cleanup = recv_cleanup..'  api_free_string('..param[2]..');\n' | ||||||
|  |           argc = argc+2 | ||||||
|  |         elseif param[1] == 'Array' then | ||||||
|  |           send = send..'  Array copy_'..param[2]..' = copy_array('..param[2]..');\n' | ||||||
|  |           argv = argv..', '..copy..'.items, INT2PTR('..copy..'.size)' | ||||||
|  |           recv = (recv..'  Array '..param[2].. | ||||||
|  |                           ' = (Array){.items = argv['..argc..'],'.. | ||||||
|  |                           '.size = (size_t)argv['..(argc+1)..']};\n') | ||||||
|  |           recv_argv = recv_argv..', '..param[2] | ||||||
|  |           recv_cleanup = recv_cleanup..'  api_free_array('..param[2]..');\n' | ||||||
|  |           argc = argc+2 | ||||||
|  |         elseif param[1] == 'Integer' or param[1] == 'Boolean' then | ||||||
|  |           argv = argv..', INT2PTR('..param[2]..')' | ||||||
|  |           recv_argv = recv_argv..', PTR2INT(argv['..argc..'])' | ||||||
|  |           argc = argc+1 | ||||||
|  |         else | ||||||
|  |           assert(false) | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |       bridge_output:write('static void ui_bridge_'..ev.name.. | ||||||
|  |                           '_event(void **argv)\n{\n') | ||||||
|  |       bridge_output:write('  UI *ui = UI(argv[0]);\n') | ||||||
|  |       bridge_output:write(recv) | ||||||
|  |       bridge_output:write('  ui->'..ev.name..'(ui'..recv_argv..');\n') | ||||||
|  |       bridge_output:write(recv_cleanup) | ||||||
|  |       bridge_output:write('}\n\n') | ||||||
|  |  | ||||||
|  |       bridge_output:write('static void ui_bridge_'..ev.name) | ||||||
|  |       write_signature(bridge_output, ev, 'UI *ui') | ||||||
|  |       bridge_output:write('\n{\n') | ||||||
|  |       bridge_output:write(send) | ||||||
|  |       bridge_output:write('  UI_CALL(ui, '..ev.name..', '..argc..', ui'..argv..');\n}\n') | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   call_output:write('void ui_call_'..ev.name) | ||||||
|  |   write_signature(call_output, ev, '') | ||||||
|  |   call_output:write('\n{\n') | ||||||
|  |   if ev.remote_only then | ||||||
|  |     write_arglist(call_output, ev, false) | ||||||
|  |     call_output:write('  ui_event("'..ev.name..'", args);\n') | ||||||
|  |   else | ||||||
|  |     call_output:write('  UI_CALL') | ||||||
|  |     write_signature(call_output, ev, ev.name, true) | ||||||
|  |     call_output:write(";\n") | ||||||
|  |   end | ||||||
|  |   call_output:write("}\n\n") | ||||||
|  |  | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | proto_output:close() | ||||||
|  | call_output:close() | ||||||
|  | remote_output:close() | ||||||
| @@ -87,6 +87,7 @@ for i = 6, #arg do | |||||||
|   headers[#headers + 1] = parts[#parts - 1]..'/'..parts[#parts] |   headers[#headers + 1] = parts[#parts - 1]..'/'..parts[#parts] | ||||||
|  |  | ||||||
|   local input = io.open(full_path, 'rb') |   local input = io.open(full_path, 'rb') | ||||||
|  |  | ||||||
|   local tmp = grammar:match(input:read('*all')) |   local tmp = grammar:match(input:read('*all')) | ||||||
|   for i = 1, #tmp do |   for i = 1, #tmp do | ||||||
|     local fn = tmp[i] |     local fn = tmp[i] | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ endif() | |||||||
| set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches) | set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches) | ||||||
| set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) | set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) | ||||||
| set(MSGPACK_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genmsgpack.lua) | set(MSGPACK_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genmsgpack.lua) | ||||||
|  | set(API_UI_EVENTS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gen_api_ui_events.lua) | ||||||
| set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack) | set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack) | ||||||
| set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack) | set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack) | ||||||
| set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c) | set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c) | ||||||
| @@ -20,6 +21,10 @@ set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua) | |||||||
| set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include) | set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include) | ||||||
| set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h) | set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h) | ||||||
| set(GENERATED_FUNCS_METADATA ${GENERATED_DIR}/api/private/funcs_metadata.generated.h) | set(GENERATED_FUNCS_METADATA ${GENERATED_DIR}/api/private/funcs_metadata.generated.h) | ||||||
|  | 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_REMOTE ${GENERATED_DIR}/ui_events_remote.generated.h) | ||||||
|  | set(GENERATED_UI_EVENTS_BRIDGE ${GENERATED_DIR}/ui_events_bridge.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) | ||||||
| set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h) | set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h) | ||||||
| @@ -49,6 +54,7 @@ set(LINT_SUPPRESSES_INSTALL_SCRIPT "${PROJECT_SOURCE_DIR}/cmake/InstallClintErro | |||||||
|  |  | ||||||
| file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt) | file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt) | ||||||
| file(GLOB API_HEADERS api/*.h) | file(GLOB API_HEADERS api/*.h) | ||||||
|  | list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h) | ||||||
| file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h) | file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h) | ||||||
|  |  | ||||||
| include_directories(${GENERATED_DIR}) | include_directories(${GENERATED_DIR}) | ||||||
| @@ -185,7 +191,11 @@ endfunction() | |||||||
| # These lists must be mutually exclusive. | # These lists must be mutually exclusive. | ||||||
| foreach(sfile ${NVIM_SOURCES} | foreach(sfile ${NVIM_SOURCES} | ||||||
|               "${CMAKE_CURRENT_LIST_DIR}/regexp_nfa.c" |               "${CMAKE_CURRENT_LIST_DIR}/regexp_nfa.c" | ||||||
|               ${GENERATED_API_DISPATCH}) |               ${GENERATED_API_DISPATCH} | ||||||
|  |               "${GENERATED_UI_EVENTS_CALL}" | ||||||
|  |               "${GENERATED_UI_EVENTS_REMOTE}" | ||||||
|  |               "${GENERATED_UI_EVENTS_BRIDGE}" | ||||||
|  |               ) | ||||||
|   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}") | ||||||
|   if(${d} MATCHES "^[.][.]|auto/") |   if(${d} MATCHES "^[.][.]|auto/") | ||||||
| @@ -253,6 +263,21 @@ list(APPEND NVIM_GENERATED_SOURCES | |||||||
|   "${MSGPACK_LUA_C_BINDINGS}" |   "${MSGPACK_LUA_C_BINDINGS}" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | add_custom_command(OUTPUT ${GENERATED_UI_EVENTS} | ||||||
|  |                           ${GENERATED_UI_EVENTS_CALL} | ||||||
|  |                           ${GENERATED_UI_EVENTS_REMOTE} | ||||||
|  |                           ${GENERATED_UI_EVENTS_BRIDGE} | ||||||
|  |   COMMAND ${LUA_PRG} ${API_UI_EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR} | ||||||
|  |                      ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h | ||||||
|  |                      ${GENERATED_UI_EVENTS} | ||||||
|  |                      ${GENERATED_UI_EVENTS_CALL} | ||||||
|  |                      ${GENERATED_UI_EVENTS_REMOTE} | ||||||
|  |                      ${GENERATED_UI_EVENTS_BRIDGE} | ||||||
|  |   DEPENDS | ||||||
|  |     ${API_UI_EVENTS_GENERATOR} | ||||||
|  |     ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h | ||||||
|  | ) | ||||||
|  |  | ||||||
| list(APPEND NVIM_GENERATED_FOR_HEADERS | list(APPEND NVIM_GENERATED_FOR_HEADERS | ||||||
|   "${GENERATED_EX_CMDS_ENUM}" |   "${GENERATED_EX_CMDS_ENUM}" | ||||||
|   "${GENERATED_EVENTS_ENUM}" |   "${GENERATED_EVENTS_ENUM}" | ||||||
| @@ -518,7 +543,7 @@ set(NO_SINGLE_CHECK_HEADERS | |||||||
| foreach(hfile ${NVIM_HEADERS}) | foreach(hfile ${NVIM_HEADERS}) | ||||||
|   get_test_target(test-includes "${hfile}" relative_path texe) |   get_test_target(test-includes "${hfile}" relative_path texe) | ||||||
|  |  | ||||||
|   if(NOT ${hfile} MATCHES "[.]c[.]h$") |   if(NOT ${hfile} MATCHES "[.](c|in)[.]h$") | ||||||
|     set(tsource "${GENERATED_DIR}/${relative_path}.test-include.c") |     set(tsource "${GENERATED_DIR}/${relative_path}.test-include.c") | ||||||
|     write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }") |     write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }") | ||||||
|     add_executable( |     add_executable( | ||||||
|   | |||||||
| @@ -885,6 +885,24 @@ static void init_type_metadata(Dictionary *metadata) | |||||||
|   PUT(*metadata, "types", DICTIONARY_OBJ(types)); |   PUT(*metadata, "types", DICTIONARY_OBJ(types)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | String copy_string(String str) | ||||||
|  | { | ||||||
|  |   if (str.data != NULL) { | ||||||
|  |     return (String){ .data = xmemdupz(str.data, str.size), .size = str.size }; | ||||||
|  |   } else { | ||||||
|  |     return (String)STRING_INIT; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Array copy_array(Array array) | ||||||
|  | { | ||||||
|  |   Array rv = ARRAY_DICT_INIT; | ||||||
|  |   for (size_t i = 0; i < array.size; i++) { | ||||||
|  |     ADD(rv, copy_object(array.items[i])); | ||||||
|  |   } | ||||||
|  |   return rv; | ||||||
|  | } | ||||||
|  |  | ||||||
| /// Creates a deep clone of an object | /// Creates a deep clone of an object | ||||||
| Object copy_object(Object obj) | Object copy_object(Object obj) | ||||||
| { | { | ||||||
| @@ -896,15 +914,10 @@ Object copy_object(Object obj) | |||||||
|       return obj; |       return obj; | ||||||
|  |  | ||||||
|     case kObjectTypeString: |     case kObjectTypeString: | ||||||
|       return STRING_OBJ(cstr_to_string(obj.data.string.data)); |       return STRING_OBJ(copy_string(obj.data.string)); | ||||||
|  |  | ||||||
|     case kObjectTypeArray: { |     case kObjectTypeArray: | ||||||
|       Array rv = ARRAY_DICT_INIT; |       return ARRAY_OBJ(copy_array(obj.data.array)); | ||||||
|       for (size_t i = 0; i < obj.data.array.size; i++) { |  | ||||||
|         ADD(rv, copy_object(obj.data.array.items[i])); |  | ||||||
|       } |  | ||||||
|       return ARRAY_OBJ(rv); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     case kObjectTypeDictionary: { |     case kObjectTypeDictionary: { | ||||||
|       Dictionary rv = ARRAY_DICT_INIT; |       Dictionary rv = ARRAY_DICT_INIT; | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #ifdef INCLUDE_GENERATED_DECLARATIONS | #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||||
| # include "api/ui.c.generated.h" | # include "api/ui.c.generated.h" | ||||||
|  | # include "ui_events_remote.generated.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
| @@ -236,100 +237,6 @@ static void push_call(UI *ui, char *name, Array args) | |||||||
|   kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call; |   kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void remote_ui_resize(UI *ui, int width, int height) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, INTEGER_OBJ(width)); |  | ||||||
|   ADD(args, INTEGER_OBJ(height)); |  | ||||||
|   push_call(ui, "resize", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_clear(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "clear", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_eol_clear(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "eol_clear", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_cursor_goto(UI *ui, int row, int col) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, INTEGER_OBJ(row)); |  | ||||||
|   ADD(args, INTEGER_OBJ(col)); |  | ||||||
|   push_call(ui, "cursor_goto", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_update_menu(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "update_menu", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_busy_start(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "busy_start", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_busy_stop(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "busy_stop", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_mouse_on(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "mouse_on", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_mouse_off(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "mouse_off", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_mode_change(UI *ui, int mode_idx) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|  |  | ||||||
|   char *full_name = shape_table[mode_idx].full_name; |  | ||||||
|   ADD(args, STRING_OBJ(cstr_to_string(full_name))); |  | ||||||
|  |  | ||||||
|   ADD(args, INTEGER_OBJ(mode_idx)); |  | ||||||
|   push_call(ui, "mode_change", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_set_scroll_region(UI *ui, int top, int bot, int left, |  | ||||||
|                                         int right) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, INTEGER_OBJ(top)); |  | ||||||
|   ADD(args, INTEGER_OBJ(bot)); |  | ||||||
|   ADD(args, INTEGER_OBJ(left)); |  | ||||||
|   ADD(args, INTEGER_OBJ(right)); |  | ||||||
|   push_call(ui, "set_scroll_region", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_scroll(UI *ui, int count) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, INTEGER_OBJ(count)); |  | ||||||
|   push_call(ui, "scroll", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_mode_info_set(UI *ui, bool guicursor_enabled, Array data) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, BOOLEAN_OBJ(guicursor_enabled)); |  | ||||||
|   ADD(args, copy_object(ARRAY_OBJ(data))); |  | ||||||
|   push_call(ui, "mode_info_set", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) | static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) | ||||||
| { | { | ||||||
| @@ -372,47 +279,6 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) | |||||||
|   push_call(ui, "highlight_set", args); |   push_call(ui, "highlight_set", args); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void remote_ui_put(UI *ui, uint8_t *data, size_t size) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   String str = { .data = xmemdupz(data, size), .size = size }; |  | ||||||
|   ADD(args, STRING_OBJ(str)); |  | ||||||
|   push_call(ui, "put", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_bell(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "bell", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_visual_bell(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "visual_bell", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_update_fg(UI *ui, int fg) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, INTEGER_OBJ(fg)); |  | ||||||
|   push_call(ui, "update_fg", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_update_bg(UI *ui, int bg) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, INTEGER_OBJ(bg)); |  | ||||||
|   push_call(ui, "update_bg", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_update_sp(UI *ui, int sp) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, INTEGER_OBJ(sp)); |  | ||||||
|   push_call(ui, "update_sp", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_flush(UI *ui) | static void remote_ui_flush(UI *ui) | ||||||
| { | { | ||||||
|   UIData *data = ui->data; |   UIData *data = ui->data; | ||||||
| @@ -422,26 +288,6 @@ static void remote_ui_flush(UI *ui) | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void remote_ui_suspend(UI *ui) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   push_call(ui, "suspend", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_set_title(UI *ui, char *title) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, STRING_OBJ(cstr_to_string(title))); |  | ||||||
|   push_call(ui, "set_title", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_set_icon(UI *ui, char *icon) |  | ||||||
| { |  | ||||||
|   Array args = ARRAY_DICT_INIT; |  | ||||||
|   ADD(args, STRING_OBJ(cstr_to_string(icon))); |  | ||||||
|   push_call(ui, "set_icon", args); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) | static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) | ||||||
| { | { | ||||||
|   Array my_args = ARRAY_DICT_INIT; |   Array my_args = ARRAY_DICT_INIT; | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								src/nvim/api/ui_events.in.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/nvim/api/ui_events.in.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | #ifndef NVIM_API_UI_EVENTS_IN_H | ||||||
|  | #define NVIM_API_UI_EVENTS_IN_H | ||||||
|  |  | ||||||
|  | // This file is not compiled, just parsed for definitons | ||||||
|  | #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||||
|  | #error "don't include this file, include nvim/ui.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "nvim/api/private/defs.h" | ||||||
|  | #include "nvim/func_attr.h" | ||||||
|  | #include "nvim/ui.h" | ||||||
|  |  | ||||||
|  | void resize(Integer rows, Integer columns); | ||||||
|  | void clear(void); | ||||||
|  | void eol_clear(void); | ||||||
|  | void cursor_goto(Integer row, Integer col); | ||||||
|  | void mode_info_set(Boolean enabled, Array cursor_styles); | ||||||
|  | void update_menu(void); | ||||||
|  | void busy_start(void); | ||||||
|  | void busy_stop(void); | ||||||
|  | void mouse_on(void); | ||||||
|  | void mouse_off(void); | ||||||
|  | void mode_change(String mode, Integer mode_idx); | ||||||
|  | void set_scroll_region(Integer top, Integer bot, Integer left, Integer right); | ||||||
|  | void scroll(Integer count); | ||||||
|  | void highlight_set(HlAttrs attrs) REMOTE_IMPL BRIDGE_IMPL; | ||||||
|  | void put(String str); | ||||||
|  | void bell(void); | ||||||
|  | void visual_bell(void); | ||||||
|  | void flush(void) REMOTE_IMPL; | ||||||
|  | void update_fg(Integer fg); | ||||||
|  | void update_bg(Integer bg); | ||||||
|  | void update_sp(Integer sp); | ||||||
|  | void suspend(void) BRIDGE_IMPL; | ||||||
|  | void set_title(String title); | ||||||
|  | void set_icon(String icon); | ||||||
|  |  | ||||||
|  | void popupmenu_show(Array items, Integer selected, Integer row, Integer col) REMOTE_ONLY; | ||||||
|  | void popupmenu_hide(void) REMOTE_ONLY; | ||||||
|  | void popupmenu_select(Integer selected) REMOTE_ONLY; | ||||||
|  |  | ||||||
|  | #endif  // NVIM_API_UI_EVENTS_IN_H | ||||||
| @@ -187,7 +187,7 @@ static void terminfo_stop(UI *ui) | |||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   // Destroy output stuff |   // Destroy output stuff | ||||||
|   tui_mode_change(ui, SHAPE_IDX_N); |   tui_mode_change(ui, (String)STRING_INIT, SHAPE_IDX_N); | ||||||
|   tui_mouse_off(ui); |   tui_mouse_off(ui); | ||||||
|   unibi_out(ui, unibi_exit_attribute_mode); |   unibi_out(ui, unibi_exit_attribute_mode); | ||||||
|   // cursor should be set to normal before exiting alternate screen |   // cursor should be set to normal before exiting alternate screen | ||||||
| @@ -417,14 +417,14 @@ static void clear_region(UI *ui, int top, int bot, int left, int right) | |||||||
|   unibi_goto(ui, grid->row, grid->col); |   unibi_goto(ui, grid->row, grid->col); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_resize(UI *ui, int width, int height) | static void tui_resize(UI *ui, Integer width, Integer height) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   ugrid_resize(&data->grid, width, height); |   ugrid_resize(&data->grid, (int)width, (int)height); | ||||||
|  |  | ||||||
|   if (!got_winch) {  // Try to resize the terminal window. |   if (!got_winch) {  // Try to resize the terminal window. | ||||||
|     char r[16];  // enough for 9999x9999 |     char r[16];  // enough for 9999x9999 | ||||||
|     snprintf(r, sizeof(r), "\x1b[8;%d;%dt", height, width); |     snprintf(r, sizeof(r), "\x1b[8;%d;%dt", (int)height, (int)width); | ||||||
|     out(ui, r, strlen(r)); |     out(ui, r, strlen(r)); | ||||||
|   } else {  // Already handled the SIGWINCH signal; avoid double-resize. |   } else {  // Already handled the SIGWINCH signal; avoid double-resize. | ||||||
|     got_winch = false; |     got_winch = false; | ||||||
| @@ -447,11 +447,11 @@ static void tui_eol_clear(UI *ui) | |||||||
|   clear_region(ui, grid->row, grid->row, grid->col, grid->right); |   clear_region(ui, grid->row, grid->row, grid->col, grid->right); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_cursor_goto(UI *ui, int row, int col) | static void tui_cursor_goto(UI *ui, Integer row, Integer col) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   ugrid_goto(&data->grid, row, col); |   ugrid_goto(&data->grid, (int)row, (int)col); | ||||||
|   unibi_goto(ui, row, col); |   unibi_goto(ui, (int)row, (int)col); | ||||||
| } | } | ||||||
|  |  | ||||||
| CursorShape tui_cursor_decode_shape(const char *shape_str) | CursorShape tui_cursor_decode_shape(const char *shape_str) | ||||||
| @@ -599,30 +599,31 @@ static void tui_set_mode(UI *ui, ModeShape mode) | |||||||
| } | } | ||||||
|  |  | ||||||
| /// @param mode editor mode | /// @param mode editor mode | ||||||
| static void tui_mode_change(UI *ui, int mode_idx) | static void tui_mode_change(UI *ui, String mode, Integer mode_idx) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   tui_set_mode(ui, (ModeShape)mode_idx); |   tui_set_mode(ui, (ModeShape)mode_idx); | ||||||
|   data->showing_mode = (ModeShape)mode_idx; |   data->showing_mode = (ModeShape)mode_idx; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_set_scroll_region(UI *ui, int top, int bot, int left, | static void tui_set_scroll_region(UI *ui, Integer top, Integer bot, | ||||||
|                                   int right) |                                   Integer left, Integer right) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   ugrid_set_scroll_region(&data->grid, top, bot, left, right); |   ugrid_set_scroll_region(&data->grid, (int)top, (int)bot, | ||||||
|  |                           (int)left, (int)right); | ||||||
|   data->can_use_terminal_scroll = |   data->can_use_terminal_scroll = | ||||||
|     left == 0 && right == ui->width - 1 |     left == 0 && right == ui->width - 1 | ||||||
|     && ((top == 0 && bot == ui->height - 1) |     && ((top == 0 && bot == ui->height - 1) | ||||||
|         || unibi_get_str(data->ut, unibi_change_scroll_region)); |         || unibi_get_str(data->ut, unibi_change_scroll_region)); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_scroll(UI *ui, int count) | static void tui_scroll(UI *ui, Integer count) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   UGrid *grid = &data->grid; |   UGrid *grid = &data->grid; | ||||||
|   int clear_top, clear_bot; |   int clear_top, clear_bot; | ||||||
|   ugrid_scroll(grid, count, &clear_top, &clear_bot); |   ugrid_scroll(grid, (int)count, &clear_top, &clear_bot); | ||||||
|  |  | ||||||
|   if (data->can_use_terminal_scroll) { |   if (data->can_use_terminal_scroll) { | ||||||
|     // Change terminal scroll region and move cursor to the top |     // Change terminal scroll region and move cursor to the top | ||||||
| @@ -642,7 +643,7 @@ static void tui_scroll(UI *ui, int count) | |||||||
|       if (count == 1) { |       if (count == 1) { | ||||||
|         unibi_out(ui, unibi_delete_line); |         unibi_out(ui, unibi_delete_line); | ||||||
|       } else { |       } else { | ||||||
|         data->params[0].i = count; |         data->params[0].i = (int)count; | ||||||
|         unibi_out(ui, unibi_parm_delete_line); |         unibi_out(ui, unibi_parm_delete_line); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -652,7 +653,7 @@ static void tui_scroll(UI *ui, int count) | |||||||
|       if (count == -1) { |       if (count == -1) { | ||||||
|         unibi_out(ui, unibi_insert_line); |         unibi_out(ui, unibi_insert_line); | ||||||
|       } else { |       } else { | ||||||
|         data->params[0].i = -count; |         data->params[0].i = -(int)count; | ||||||
|         unibi_out(ui, unibi_parm_insert_line); |         unibi_out(ui, unibi_parm_insert_line); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -683,10 +684,10 @@ static void tui_highlight_set(UI *ui, HlAttrs attrs) | |||||||
|   ((TUIData *)ui->data)->grid.attrs = attrs; |   ((TUIData *)ui->data)->grid.attrs = attrs; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_put(UI *ui, uint8_t *text, size_t size) | static void tui_put(UI *ui, String text) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   print_cell(ui, ugrid_put(&data->grid, text, size)); |   print_cell(ui, ugrid_put(&data->grid, (uint8_t *)text.data, text.size)); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_bell(UI *ui) | static void tui_bell(UI *ui) | ||||||
| @@ -699,17 +700,17 @@ static void tui_visual_bell(UI *ui) | |||||||
|   unibi_out(ui, unibi_flash_screen); |   unibi_out(ui, unibi_flash_screen); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_update_fg(UI *ui, int fg) | static void tui_update_fg(UI *ui, Integer fg) | ||||||
| { | { | ||||||
|   ((TUIData *)ui->data)->grid.fg = fg; |   ((TUIData *)ui->data)->grid.fg = (int)fg; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_update_bg(UI *ui, int bg) | static void tui_update_bg(UI *ui, Integer bg) | ||||||
| { | { | ||||||
|   ((TUIData *)ui->data)->grid.bg = bg; |   ((TUIData *)ui->data)->grid.bg = (int)bg; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_update_sp(UI *ui, int sp) | static void tui_update_sp(UI *ui, Integer sp) | ||||||
| { | { | ||||||
|   // Do nothing; 'special' color is for GUI only |   // Do nothing; 'special' color is for GUI only | ||||||
| } | } | ||||||
| @@ -784,19 +785,19 @@ static void tui_suspend(UI *ui) | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_set_title(UI *ui, char *title) | static void tui_set_title(UI *ui, String title) | ||||||
| { | { | ||||||
|   TUIData *data = ui->data; |   TUIData *data = ui->data; | ||||||
|   if (!(title && unibi_get_str(data->ut, unibi_to_status_line) |   if (!(title.data && unibi_get_str(data->ut, unibi_to_status_line) | ||||||
|         && unibi_get_str(data->ut, unibi_from_status_line))) { |         && unibi_get_str(data->ut, unibi_from_status_line))) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   unibi_out(ui, unibi_to_status_line); |   unibi_out(ui, unibi_to_status_line); | ||||||
|   out(ui, title, strlen(title)); |   out(ui, title.data, title.size); | ||||||
|   unibi_out(ui, unibi_from_status_line); |   unibi_out(ui, unibi_from_status_line); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tui_set_icon(UI *ui, char *icon) | static void tui_set_icon(UI *ui, String icon) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -89,6 +89,10 @@ static int old_mode_idx = -1; | |||||||
| #define UI_CALL_MORE(method, ...) if (ui->method) ui->method(ui, __VA_ARGS__) | #define UI_CALL_MORE(method, ...) if (ui->method) ui->method(ui, __VA_ARGS__) | ||||||
| #define UI_CALL_ZERO(method) if (ui->method) ui->method(ui) | #define UI_CALL_ZERO(method) if (ui->method) ui->method(ui) | ||||||
|  |  | ||||||
|  | #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||||
|  | # include "ui_events_call.generated.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| void ui_builtin_start(void) | void ui_builtin_start(void) | ||||||
| { | { | ||||||
| #ifdef FEAT_TUI | #ifdef FEAT_TUI | ||||||
| @@ -136,13 +140,13 @@ void ui_suspend(void) | |||||||
|  |  | ||||||
| void ui_set_title(char *title) | void ui_set_title(char *title) | ||||||
| { | { | ||||||
|   UI_CALL(set_title, title); |   ui_call_set_title(cstr_as_string(title)); | ||||||
|   UI_CALL(flush); |   UI_CALL(flush); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ui_set_icon(char *icon) | void ui_set_icon(char *icon) | ||||||
| { | { | ||||||
|   UI_CALL(set_icon, icon); |   ui_call_set_icon(cstr_as_string(icon)); | ||||||
|   UI_CALL(flush); |   UI_CALL(flush); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -390,7 +394,7 @@ void ui_mode_info_set(void) | |||||||
| { | { | ||||||
|   Array style = mode_style_array(); |   Array style = mode_style_array(); | ||||||
|   bool enabled = (*p_guicursor != NUL); |   bool enabled = (*p_guicursor != NUL); | ||||||
|   UI_CALL(mode_info_set, enabled, style); |   ui_call_mode_info_set(enabled, style); | ||||||
|   api_free_array(style); |   api_free_array(style); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -420,11 +424,11 @@ static void send_output(uint8_t **ptr) | |||||||
|  |  | ||||||
|   while (*p >= 0x20) { |   while (*p >= 0x20) { | ||||||
|     size_t clen = (size_t)mb_ptr2len(p); |     size_t clen = (size_t)mb_ptr2len(p); | ||||||
|     UI_CALL(put, p, (size_t)clen); |     ui_call_put((String){.data = (char *)p, .size = clen}); | ||||||
|     col++; |     col++; | ||||||
|     if (mb_ptr2cells(p) > 1) { |     if (mb_ptr2cells(p) > 1) { | ||||||
|       // double cell character, blank the next cell |       // double cell character, blank the next cell | ||||||
|       UI_CALL(put, NULL, 0); |       ui_call_put((String)STRING_INIT); | ||||||
|       col++; |       col++; | ||||||
|     } |     } | ||||||
|     if (utf_ambiguous_width(utf_ptr2char(p))) { |     if (utf_ambiguous_width(utf_ptr2char(p))) { | ||||||
| @@ -560,7 +564,8 @@ void ui_cursor_shape(void) | |||||||
|  |  | ||||||
|   if (old_mode_idx != mode_idx) { |   if (old_mode_idx != mode_idx) { | ||||||
|     old_mode_idx = mode_idx; |     old_mode_idx = mode_idx; | ||||||
|     UI_CALL(mode_change, mode_idx); |     char *full_name = shape_table[mode_idx].full_name; | ||||||
|  |     ui_call_mode_change(cstr_as_string(full_name), mode_idx); | ||||||
|   } |   } | ||||||
|   conceal_check_cursur_line(); |   conceal_check_cursur_line(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,35 +28,17 @@ struct ui_t { | |||||||
|   bool ui_ext[UI_WIDGETS];  ///< Externalized widgets |   bool ui_ext[UI_WIDGETS];  ///< Externalized widgets | ||||||
|   int width, height; |   int width, height; | ||||||
|   void *data; |   void *data; | ||||||
|   void (*resize)(UI *ui, int rows, int columns); |  | ||||||
|   void (*clear)(UI *ui); | #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||||
|   void (*eol_clear)(UI *ui); | # include "ui_events.generated.h" | ||||||
|   void (*cursor_goto)(UI *ui, int row, int col); | #endif | ||||||
|   void (*mode_info_set)(UI *ui, bool enabled, Array cursor_styles); |  | ||||||
|   void (*update_menu)(UI *ui); |  | ||||||
|   void (*busy_start)(UI *ui); |  | ||||||
|   void (*busy_stop)(UI *ui); |  | ||||||
|   void (*mouse_on)(UI *ui); |  | ||||||
|   void (*mouse_off)(UI *ui); |  | ||||||
|   void (*mode_change)(UI *ui, int mode_idx); |  | ||||||
|   void (*set_scroll_region)(UI *ui, int top, int bot, int left, int right); |  | ||||||
|   void (*scroll)(UI *ui, int count); |  | ||||||
|   void (*highlight_set)(UI *ui, HlAttrs attrs); |  | ||||||
|   void (*put)(UI *ui, uint8_t *str, size_t len); |  | ||||||
|   void (*bell)(UI *ui); |  | ||||||
|   void (*visual_bell)(UI *ui); |  | ||||||
|   void (*flush)(UI *ui); |  | ||||||
|   void (*update_fg)(UI *ui, int fg); |  | ||||||
|   void (*update_bg)(UI *ui, int bg); |  | ||||||
|   void (*update_sp)(UI *ui, int sp); |  | ||||||
|   void (*suspend)(UI *ui); |  | ||||||
|   void (*set_title)(UI *ui, char *title); |  | ||||||
|   void (*set_icon)(UI *ui, char *icon); |  | ||||||
|   void (*event)(UI *ui, char *name, Array args, bool *args_consumed); |   void (*event)(UI *ui, char *name, Array args, bool *args_consumed); | ||||||
|   void (*stop)(UI *ui); |   void (*stop)(UI *ui); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #ifdef INCLUDE_GENERATED_DECLARATIONS | #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||||
| # include "ui.h.generated.h" | # include "ui.h.generated.h" | ||||||
|  | # include "ui_events_call.h.generated.h" | ||||||
| #endif | #endif | ||||||
| #endif  // NVIM_UI_H | #endif  // NVIM_UI_H | ||||||
|   | |||||||
| @@ -49,8 +49,12 @@ static argv_callback uilog_event = NULL; | |||||||
|       event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) |       event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define INT2PTR(i) ((void *)(uintptr_t)i) | #define INT2PTR(i) ((void *)(intptr_t)i) | ||||||
| #define PTR2INT(p) ((int)(uintptr_t)p) | #define PTR2INT(p) ((Integer)(intptr_t)p) | ||||||
|  |  | ||||||
|  | #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||||
|  | # include "ui_events_bridge.generated.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) | UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) | ||||||
| { | { | ||||||
| @@ -146,148 +150,6 @@ static void ui_bridge_stop_event(void **argv) | |||||||
|   ui->stop(ui); |   ui->stop(ui); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ui_bridge_resize(UI *b, int width, int height) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, resize, 3, b, INT2PTR(width), INT2PTR(height)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_resize_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->resize(ui, PTR2INT(argv[1]), PTR2INT(argv[2])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_clear(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, clear, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_clear_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->clear(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_eol_clear(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, eol_clear, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_eol_clear_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->eol_clear(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_cursor_goto(UI *b, int row, int col) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, cursor_goto, 3, b, INT2PTR(row), INT2PTR(col)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_cursor_goto_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_mode_info_set(UI *b, bool enabled, Array modes) |  | ||||||
| { |  | ||||||
|   bool *enabledp = xmalloc(sizeof(*enabledp)); |  | ||||||
|   Object *modesp = xmalloc(sizeof(*modesp)); |  | ||||||
|   *enabledp = enabled; |  | ||||||
|   *modesp = copy_object(ARRAY_OBJ(modes)); |  | ||||||
|   UI_CALL(b, mode_info_set, 3, b, enabledp, modesp); |  | ||||||
| } |  | ||||||
| static void ui_bridge_mode_info_set_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   bool *enabled = argv[1]; |  | ||||||
|   Object *modes = argv[2]; |  | ||||||
|   ui->mode_info_set(ui, *enabled, modes->data.array); |  | ||||||
|   xfree(enabled); |  | ||||||
|   api_free_object(*modes); |  | ||||||
|   xfree(modes); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_update_menu(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, update_menu, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_update_menu_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->update_menu(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_busy_start(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, busy_start, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_busy_start_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->busy_start(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_busy_stop(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, busy_stop, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_busy_stop_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->busy_stop(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_mouse_on(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, mouse_on, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_mouse_on_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->mouse_on(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_mouse_off(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, mouse_off, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_mouse_off_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->mouse_off(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_mode_change(UI *b, int mode_idx) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, mode_change, 2, b, INT2PTR(mode_idx)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_mode_change_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->mode_change(ui, PTR2INT(argv[1])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_set_scroll_region(UI *b, int top, int bot, int left, |  | ||||||
|                                         int right) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, set_scroll_region, 5, b, INT2PTR(top), INT2PTR(bot), |  | ||||||
|           INT2PTR(left), INT2PTR(right)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_set_scroll_region_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->set_scroll_region(ui, PTR2INT(argv[1]), PTR2INT(argv[2]), |  | ||||||
|                         PTR2INT(argv[3]), PTR2INT(argv[4])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_scroll(UI *b, int count) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, scroll, 2, b, INT2PTR(count)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_scroll_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->scroll(ui, PTR2INT(argv[1])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_highlight_set(UI *b, HlAttrs attrs) | static void ui_bridge_highlight_set(UI *b, HlAttrs attrs) | ||||||
| { | { | ||||||
|   HlAttrs *a = xmalloc(sizeof(HlAttrs)); |   HlAttrs *a = xmalloc(sizeof(HlAttrs)); | ||||||
| @@ -301,82 +163,6 @@ static void ui_bridge_highlight_set_event(void **argv) | |||||||
|   xfree(argv[1]); |   xfree(argv[1]); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ui_bridge_put(UI *b, uint8_t *text, size_t size) |  | ||||||
| { |  | ||||||
|   uint8_t *t = NULL; |  | ||||||
|   if (text) { |  | ||||||
|     t = xmalloc(sizeof(((UCell *)0)->data)); |  | ||||||
|     memcpy(t, text, size); |  | ||||||
|   } |  | ||||||
|   UI_CALL(b, put, 3, b, t, INT2PTR(size)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_put_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->put(ui, (uint8_t *)argv[1], (size_t)(uintptr_t)argv[2]); |  | ||||||
|   xfree(argv[1]); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_bell(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, bell, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_bell_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->bell(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_visual_bell(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, visual_bell, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_visual_bell_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->visual_bell(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_update_fg(UI *b, int fg) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, update_fg, 2, b, INT2PTR(fg)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_update_fg_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->update_fg(ui, PTR2INT(argv[1])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_update_bg(UI *b, int bg) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, update_bg, 2, b, INT2PTR(bg)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_update_bg_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->update_bg(ui, PTR2INT(argv[1])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_update_sp(UI *b, int sp) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, update_sp, 2, b, INT2PTR(sp)); |  | ||||||
| } |  | ||||||
| static void ui_bridge_update_sp_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->update_sp(ui, PTR2INT(argv[1])); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_flush(UI *b) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, flush, 1, b); |  | ||||||
| } |  | ||||||
| static void ui_bridge_flush_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->flush(ui); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_suspend(UI *b) | static void ui_bridge_suspend(UI *b) | ||||||
| { | { | ||||||
|   UIBridgeData *data = (UIBridgeData *)b; |   UIBridgeData *data = (UIBridgeData *)b; | ||||||
| @@ -394,25 +180,3 @@ static void ui_bridge_suspend_event(void **argv) | |||||||
|   UI *ui = UI(argv[0]); |   UI *ui = UI(argv[0]); | ||||||
|   ui->suspend(ui); |   ui->suspend(ui); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ui_bridge_set_title(UI *b, char *title) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, set_title, 2, b, title ? xstrdup(title) : NULL); |  | ||||||
| } |  | ||||||
| static void ui_bridge_set_title_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->set_title(ui, argv[1]); |  | ||||||
|   xfree(argv[1]); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ui_bridge_set_icon(UI *b, char *icon) |  | ||||||
| { |  | ||||||
|   UI_CALL(b, set_icon, 2, b, icon ? xstrdup(icon) : NULL); |  | ||||||
| } |  | ||||||
| static void ui_bridge_set_icon_event(void **argv) |  | ||||||
| { |  | ||||||
|   UI *ui = UI(argv[0]); |  | ||||||
|   ui->set_icon(ui, argv[1]); |  | ||||||
|   xfree(argv[1]); |  | ||||||
| } |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Björn Linse
					Björn Linse