aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-01-05 10:41:14 +0100
committerGitHub <noreply@github.com>2023-01-05 10:41:14 +0100
commit85eb564bac167c63eadbd6136406ac4863ee30ee (patch)
tree79a1d81956d87986467e4da70b4f9ad53b079040 /src
parentae64772a88125153a438a0e9e43d5f6bcb4eeb28 (diff)
parent47ba78f89a1f0bba8168b4408bc55a3024d5ab97 (diff)
downloadrneovim-85eb564bac167c63eadbd6136406ac4863ee30ee.tar.gz
rneovim-85eb564bac167c63eadbd6136406ac4863ee30ee.tar.bz2
rneovim-85eb564bac167c63eadbd6136406ac4863ee30ee.zip
Merge pull request #21605 from bfredl/uidvp
The UI Devirtualization Project
Diffstat (limited to 'src')
-rwxr-xr-xsrc/nvim/CMakeLists.txt5
-rw-r--r--src/nvim/api/ui.c108
-rw-r--r--src/nvim/api/ui.h2
-rw-r--r--src/nvim/api/ui_events.in.h17
-rw-r--r--src/nvim/generators/c_grammar.lua2
-rwxr-xr-xsrc/nvim/generators/gen_api_ui_events.lua31
-rw-r--r--src/nvim/highlight.c23
-rw-r--r--src/nvim/lua/executor.c4
-rw-r--r--src/nvim/main.c8
-rw-r--r--src/nvim/memory.c1
-rw-r--r--src/nvim/tui/tui.c1469
-rw-r--r--src/nvim/ui.c168
-rw-r--r--src/nvim/ui.h43
-rw-r--r--src/nvim/ui_client.c41
-rw-r--r--src/nvim/ui_client.h2
-rw-r--r--src/nvim/ui_compositor.c133
16 files changed, 946 insertions, 1111 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 6b92d0caa8..8ac52d8b72 100755
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -36,7 +36,6 @@ set(HEADER_GENERATOR ${GENERATOR_DIR}/gen_declarations.lua)
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
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_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_CLIENT ${GENERATED_DIR}/ui_events_client.generated.h)
@@ -310,14 +309,12 @@ list(APPEND NVIM_GENERATED_SOURCES
)
add_custom_command(
- OUTPUT ${GENERATED_UI_EVENTS}
- ${GENERATED_UI_EVENTS_CALL}
+ OUTPUT ${GENERATED_UI_EVENTS_CALL}
${GENERATED_UI_EVENTS_REMOTE}
${GENERATED_UI_EVENTS_METADATA}
${GENERATED_UI_EVENTS_CLIENT}
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_METADATA}
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index e4134133ac..32b294c0ce 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -29,41 +29,6 @@
#include "nvim/vim.h"
#include "nvim/window.h"
-typedef struct {
- uint64_t channel_id;
-
-#define UI_BUF_SIZE 4096 ///< total buffer size for pending msgpack data.
- /// guaranteed size available for each new event (so packing of simple events
- /// and the header of grid_line will never fail)
-#define EVENT_BUF_SIZE 256
- char buf[UI_BUF_SIZE]; ///< buffer of packed but not yet sent msgpack data
- char *buf_wptr; ///< write head of buffer
- const char *cur_event; ///< name of current event (might get multiple arglists)
- Array call_buf; ///< buffer for constructing a single arg list (max 16 elements!)
-
- // state for write_cb, while packing a single arglist to msgpack. This
- // might fail due to buffer overflow.
- size_t pack_totlen;
- bool buf_overflow;
- char *temp_buf;
-
- // We start packing the two outermost msgpack arrays before knowing the total
- // number of elements. Thus track the location where array size will need
- // to be written in the msgpack buffer, once the specific array is finished.
- char *nevents_pos;
- char *ncalls_pos;
- uint32_t nevents; ///< number of distinct events (top-level args to "redraw"
- uint32_t ncalls; ///< number of calls made to the current event (plus one for the name!)
- bool flushed_events; ///< events where sent to client without "flush" event
-
- int hl_id; // Current highlight for legacy put event.
- Integer cursor_row, cursor_col; // Intended visible cursor position.
-
- // Position of legacy cursor, used both for drawing and visible user cursor.
- Integer client_row, client_col;
- bool wildmenu_active;
-} UIData;
-
#define BUF_POS(data) ((size_t)((data)->buf_wptr - (data)->buf))
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -143,8 +108,6 @@ void remote_ui_disconnect(uint64_t channel_id)
UIData *data = ui->data;
kv_destroy(data->call_buf);
pmap_del(uint64_t)(&connected_uis, channel_id);
- xfree(data);
- ui->data = NULL; // Flag UI as "stopped".
ui_detach_impl(ui, channel_id);
xfree(ui);
}
@@ -204,32 +167,6 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona
ui->pum_col = -1.0;
ui->rgb = true;
ui->override = false;
- ui->grid_resize = remote_ui_grid_resize;
- ui->grid_clear = remote_ui_grid_clear;
- ui->grid_cursor_goto = remote_ui_grid_cursor_goto;
- ui->mode_info_set = remote_ui_mode_info_set;
- ui->update_menu = remote_ui_update_menu;
- ui->busy_start = remote_ui_busy_start;
- ui->busy_stop = remote_ui_busy_stop;
- ui->mouse_on = remote_ui_mouse_on;
- ui->mouse_off = remote_ui_mouse_off;
- ui->mode_change = remote_ui_mode_change;
- ui->grid_scroll = remote_ui_grid_scroll;
- ui->hl_attr_define = remote_ui_hl_attr_define;
- ui->hl_group_set = remote_ui_hl_group_set;
- ui->raw_line = remote_ui_raw_line;
- ui->bell = remote_ui_bell;
- ui->visual_bell = remote_ui_visual_bell;
- ui->default_colors_set = remote_ui_default_colors_set;
- ui->flush = remote_ui_flush;
- ui->suspend = remote_ui_suspend;
- ui->set_title = remote_ui_set_title;
- ui->set_icon = remote_ui_set_icon;
- ui->option_set = remote_ui_option_set;
- ui->msg_set_pos = remote_ui_msg_set_pos;
- ui->event = remote_ui_event;
- ui->inspect = remote_ui_inspect;
- ui->win_viewport = remote_ui_win_viewport;
CLEAR_FIELD(ui->ui_ext);
@@ -252,7 +189,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona
ui->ui_ext[kUICmdline] = true;
}
- UIData *data = xmalloc(sizeof(UIData));
+ UIData *data = ui->data;
data->channel_id = channel_id;
data->cur_event = NULL;
data->hl_id = 0;
@@ -267,7 +204,6 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona
data->wildmenu_active = false;
data->call_buf = (Array)ARRAY_DICT_INIT;
kv_ensure_space(data->call_buf, 16);
- ui->data = data;
pmap_put(uint64_t)(&connected_uis, channel_id, ui);
ui_attach_impl(ui, channel_id);
@@ -313,6 +249,10 @@ void nvim_ui_detach(uint64_t channel_id, Error *err)
remote_ui_disconnect(channel_id);
}
+// TODO(bfredl): use me to detach a specifc ui from the server
+void remote_ui_stop(UI *ui)
+{}
+
void nvim_ui_try_resize(uint64_t channel_id, Integer width, Integer height, Error *err)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
@@ -684,7 +624,7 @@ static void push_call(UI *ui, const char *name, Array args)
data->ncalls++;
}
-static void remote_ui_grid_clear(UI *ui, Integer grid)
+void remote_ui_grid_clear(UI *ui, Integer grid)
{
UIData *data = ui->data;
Array args = data->call_buf;
@@ -695,7 +635,7 @@ static void remote_ui_grid_clear(UI *ui, Integer grid)
push_call(ui, name, args);
}
-static void remote_ui_grid_resize(UI *ui, Integer grid, Integer width, Integer height)
+void remote_ui_grid_resize(UI *ui, Integer grid, Integer width, Integer height)
{
UIData *data = ui->data;
Array args = data->call_buf;
@@ -708,8 +648,8 @@ static void remote_ui_grid_resize(UI *ui, Integer grid, Integer width, Integer h
push_call(ui, name, args);
}
-static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left,
- Integer right, Integer rows, Integer cols)
+void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot, Integer left,
+ Integer right, Integer rows, Integer cols)
{
UIData *data = ui->data;
if (ui->ui_ext[kUILinegrid]) {
@@ -745,8 +685,8 @@ static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top, Integer bot
}
}
-static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
- Integer cterm_fg, Integer cterm_bg)
+void remote_ui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
+ Integer cterm_fg, Integer cterm_bg)
{
if (!ui->ui_ext[kUITermColors]) {
HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp);
@@ -776,8 +716,8 @@ static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg,
}
}
-static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
- Array info)
+void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
+ Array info)
{
if (!ui->ui_ext[kUILinegrid]) {
return;
@@ -802,7 +742,7 @@ static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAt
push_call(ui, "hl_attr_define", args);
}
-static void remote_ui_highlight_set(UI *ui, int id)
+void remote_ui_highlight_set(UI *ui, int id)
{
UIData *data = ui->data;
Array args = data->call_buf;
@@ -818,7 +758,7 @@ static void remote_ui_highlight_set(UI *ui, int id)
}
/// "true" cursor used only for input focus
-static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
+void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
{
if (ui->ui_ext[kUILinegrid]) {
UIData *data = ui->data;
@@ -836,7 +776,7 @@ static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Intege
}
/// emulated cursor used both for drawing and for input focus
-static void remote_ui_cursor_goto(UI *ui, Integer row, Integer col)
+void remote_ui_cursor_goto(UI *ui, Integer row, Integer col)
{
UIData *data = ui->data;
if (data->client_row == row && data->client_col == col) {
@@ -850,7 +790,7 @@ static void remote_ui_cursor_goto(UI *ui, Integer row, Integer col)
push_call(ui, "cursor_goto", args);
}
-static void remote_ui_put(UI *ui, const char *cell)
+void remote_ui_put(UI *ui, const char *cell)
{
UIData *data = ui->data;
data->client_col++;
@@ -859,9 +799,9 @@ static void remote_ui_put(UI *ui, const char *cell)
push_call(ui, "put", args);
}
-static void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol,
- Integer clearcol, Integer clearattr, LineFlags flags,
- const schar_T *chunk, const sattr_T *attrs)
+void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol,
+ Integer clearcol, Integer clearattr, LineFlags flags, const schar_T *chunk,
+ const sattr_T *attrs)
{
UIData *data = ui->data;
if (ui->ui_ext[kUILinegrid]) {
@@ -953,7 +893,7 @@ static void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startc
///
/// This might happen multiple times before the actual ui_flush, if the
/// total redraw size is large!
-static void remote_ui_flush_buf(UI *ui)
+void remote_ui_flush_buf(UI *ui)
{
UIData *data = ui->data;
if (!data->nevents_pos) {
@@ -980,7 +920,7 @@ static void remote_ui_flush_buf(UI *ui)
///
/// Clients can know this happened by a final "flush" event at the end of the
/// "redraw" batch.
-static void remote_ui_flush(UI *ui)
+void remote_ui_flush(UI *ui)
{
UIData *data = ui->data;
if (data->nevents > 0 || data->flushed_events) {
@@ -1025,7 +965,7 @@ static Array translate_firstarg(UI *ui, Array args, Arena *arena)
return new_args;
}
-static void remote_ui_event(UI *ui, char *name, Array args)
+void remote_ui_event(UI *ui, char *name, Array args)
{
Arena arena = ARENA_EMPTY;
UIData *data = ui->data;
@@ -1092,7 +1032,7 @@ free_ret:
arena_mem_free(arena_finish(&arena));
}
-static void remote_ui_inspect(UI *ui, Dictionary *info)
+void remote_ui_inspect(UI *ui, Dictionary *info)
{
UIData *data = ui->data;
PUT(*info, "chan", INTEGER_OBJ((Integer)data->channel_id));
diff --git a/src/nvim/api/ui.h b/src/nvim/api/ui.h
index bc70406acb..b3fe0fa2bb 100644
--- a/src/nvim/api/ui.h
+++ b/src/nvim/api/ui.h
@@ -5,8 +5,10 @@
#include "nvim/api/private/defs.h"
#include "nvim/map.h"
+#include "nvim/ui.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/ui.h.generated.h"
+# include "ui_events_remote.h.generated.h"
#endif
#endif // NVIM_API_UI_H
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index d5c79272b7..a08e8dbfeb 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -37,7 +37,7 @@ void set_title(String title)
void set_icon(String icon)
FUNC_API_SINCE(3);
void screenshot(String path)
- FUNC_API_SINCE(7) FUNC_API_REMOTE_IMPL;
+ FUNC_API_SINCE(7);
void option_set(String name, Object value)
FUNC_API_SINCE(4);
// Stop event is not exported as such, represented by EOF in the msgpack stream.
@@ -75,7 +75,7 @@ void default_colors_set(Integer rgb_fg, Integer rgb_bg, Integer rgb_sp, Integer
void hl_attr_define(Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs, Array info)
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
void hl_group_set(String name, Integer id)
- FUNC_API_SINCE(6);
+ FUNC_API_SINCE(6) FUNC_API_CLIENT_IGNORE;
void grid_resize(Integer grid, Integer width, Integer height)
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL FUNC_API_CLIENT_IMPL;
void grid_clear(Integer grid)
@@ -97,9 +97,6 @@ void raw_line(Integer grid, Integer row, Integer startcol, Integer endcol, Integ
Integer clearattr, LineFlags flags, const schar_T *chunk, const sattr_T *attrs)
FUNC_API_NOEXPORT FUNC_API_COMPOSITOR_IMPL;
-void event(char *name, Array args)
- FUNC_API_NOEXPORT FUNC_API_COMPOSITOR_IMPL;
-
void win_pos(Integer grid, Window win, Integer startrow, Integer startcol, Integer width,
Integer height)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
@@ -114,11 +111,11 @@ void win_close(Integer grid)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
void msg_set_pos(Integer grid, Integer row, Boolean scrolled, String sep_char)
- FUNC_API_SINCE(6) FUNC_API_COMPOSITOR_IMPL;
+ FUNC_API_SINCE(6) FUNC_API_COMPOSITOR_IMPL FUNC_API_CLIENT_IGNORE;
void win_viewport(Integer grid, Window win, Integer topline, Integer botline, Integer curline,
Integer curcol, Integer line_count)
- FUNC_API_SINCE(7) FUNC_API_BRIDGE_IMPL;
+ FUNC_API_SINCE(7) FUNC_API_CLIENT_IGNORE;
void win_extmark(Integer grid, Window win, Integer ns_id, Integer mark_id, Integer row, Integer col)
FUNC_API_SINCE(10) FUNC_API_REMOTE_ONLY;
@@ -150,11 +147,11 @@ void cmdline_block_hide(void)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void wildmenu_show(Array items)
- FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL;
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void wildmenu_select(Integer selected)
- FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL;
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void wildmenu_hide(void)
- FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL;
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void msg_show(String kind, Array content, Boolean replace_last)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
index 3ea5904338..3e89b60b4a 100644
--- a/src/nvim/generators/c_grammar.lua
+++ b/src/nvim/generators/c_grammar.lua
@@ -49,9 +49,9 @@ local c_proto = Ct(
(fill * Cg((P('FUNC_API_LUA_ONLY') * Cc(true)), 'lua_only') ^ -1) *
(fill * Cg((P('FUNC_API_CHECK_TEXTLOCK') * Cc(true)), 'check_textlock') ^ -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_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1) *
(fill * Cg((P('FUNC_API_CLIENT_IMPL') * Cc(true)), 'client_impl') ^ -1) *
+ (fill * Cg((P('FUNC_API_CLIENT_IGNORE') * Cc(true)), 'client_ignore') ^ -1) *
fill * P(';')
)
diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua
index c9a2e3ff66..827097f69d 100755
--- a/src/nvim/generators/gen_api_ui_events.lua
+++ b/src/nvim/generators/gen_api_ui_events.lua
@@ -3,13 +3,12 @@ local mpack = require('mpack')
local nvimdir = arg[1]
package.path = nvimdir .. '/?.lua;' .. package.path
-assert(#arg == 7)
+assert(#arg == 6)
local input = io.open(arg[2], 'rb')
-local proto_output = io.open(arg[3], 'wb')
-local call_output = io.open(arg[4], 'wb')
-local remote_output = io.open(arg[5], 'wb')
-local metadata_output = io.open(arg[6], 'wb')
-local client_output = io.open(arg[7], 'wb')
+local call_output = io.open(arg[3], 'wb')
+local remote_output = io.open(arg[4], 'wb')
+local metadata_output = io.open(arg[5], 'wb')
+local client_output = io.open(arg[6], 'wb')
local c_grammar = require('generators.c_grammar')
local events = c_grammar.grammar:match(input:read('*all'))
@@ -81,12 +80,9 @@ local function call_ui_event_method(output, ev)
end
end
- output:write(' ui_call_'..ev.name..'(')
+ output:write(' tui_'..ev.name..'(tui')
for j = 1, #ev.parameters do
- output:write('arg_'..j)
- if j ~= #ev.parameters then
- output:write(', ')
- end
+ output:write(', arg_'..j)
end
output:write(');\n')
@@ -104,12 +100,9 @@ for i = 1, #events do
ev.since = tonumber(ev.since)
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 and not ev.noexport then
- remote_output:write('static void remote_ui_'..ev.name)
+ remote_output:write('void remote_ui_'..ev.name)
write_signature(remote_output, ev, 'UI *ui')
remote_output:write('\n{\n')
remote_output:write(' UIData *data = ui->data;\n')
@@ -130,6 +123,9 @@ for i = 1, #events do
call_output:write(' UI_LOG('..ev.name..');\n')
call_output:write(' ui_call_event("'..ev.name..'", args);\n')
elseif ev.compositor_impl then
+ call_output:write(' ui_comp_'..ev.name)
+ write_signature(call_output, ev, '', true)
+ call_output:write(";\n")
call_output:write(' UI_CALL')
write_signature(call_output, ev, '!ui->composed, '..ev.name..', ui', true)
call_output:write(";\n")
@@ -151,14 +147,14 @@ for i = 1, #events do
call_output:write("}\n\n")
end
- if (not ev.remote_only) and (not ev.noexport) and (not ev.client_impl) then
+ if (not ev.remote_only) and (not ev.noexport) and (not ev.client_impl) and (not ev.client_ignore) then
call_ui_event_method(client_output, ev)
end
end
local client_events = {}
for _,ev in ipairs(events) do
- if (not ev.noexport) and ((not ev.remote_only) or ev.client_impl) then
+ if (not ev.noexport) and ((not ev.remote_only) or ev.client_impl) and (not ev.client_ignore) then
client_events[ev.name] = ev
end
end
@@ -176,7 +172,6 @@ end
client_output:write('\n};\n\n')
client_output:write(hashfun)
-proto_output:close()
call_output:close()
remote_output:close()
client_output:close()
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 2c55e840f1..c3a259c87d 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -12,6 +12,7 @@
#include "lauxlib.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/ui.h"
#include "nvim/decoration_provider.h"
#include "nvim/drawscreen.h"
#include "nvim/gettext.h"
@@ -128,19 +129,15 @@ static int get_attr_entry(HlEntry entry)
/// When a UI connects, we need to send it the table of highlights used so far.
void ui_send_all_hls(UI *ui)
{
- if (ui->hl_attr_define) {
- for (size_t i = 1; i < kv_size(attr_entries); i++) {
- Array inspect = hl_inspect((int)i);
- ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr,
- kv_A(attr_entries, i).attr, inspect);
- api_free_array(inspect);
- }
- }
- if (ui->hl_group_set) {
- for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) {
- ui->hl_group_set(ui, cstr_as_string((char *)hlf_names[hlf]),
- highlight_attr[hlf]);
- }
+ for (size_t i = 1; i < kv_size(attr_entries); i++) {
+ Array inspect = hl_inspect((int)i);
+ remote_ui_hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr,
+ kv_A(attr_entries, i).attr, inspect);
+ api_free_array(inspect);
+ }
+ for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) {
+ remote_ui_hl_group_set(ui, cstr_as_string((char *)hlf_names[hlf]),
+ highlight_attr[hlf]);
}
}
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index d4e7f3fb2c..34b572f884 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -653,7 +653,7 @@ ok:
}
LuaRef ui_event_cb = nlua_ref_global(lstate, 3);
- ui_comp_add_cb(ns_id, ui_event_cb, ext_widgets);
+ ui_add_cb(ns_id, ui_event_cb, ext_widgets);
return 0;
}
@@ -667,7 +667,7 @@ static int nlua_ui_detach(lua_State *lstate)
return luaL_error(lstate, "invalid ns_id");
}
- ui_comp_remove_cb(ns_id);
+ ui_remove_cb(ns_id);
return 0;
}
diff --git a/src/nvim/main.c b/src/nvim/main.c
index b5207f9cf6..b0da7f4500 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -627,11 +627,13 @@ void os_exit(int r)
{
exiting = true;
- if (!ui_client_channel_id) {
+ if (ui_client_channel_id) {
+ ui_client_stop();
+ } else {
ui_flush();
+ ui_call_stop();
+ ml_close_all(true); // remove all memfiles
}
- ui_call_stop();
- ml_close_all(true); // remove all memfiles
if (!event_teardown() && r == 0) {
r = 1; // Exit with error if main_loop did not teardown gracefully.
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index a65f45c012..aa8314b23d 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -834,7 +834,6 @@ void free_all_mem(void)
decor_free_all_mem();
ui_free_all_mem();
- ui_comp_free_all_mem();
nlua_free_all_mem();
// should be last, in case earlier free functions deallocates arenas
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 066567a87f..162f54b6c1 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1,7 +1,7 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-// Terminal UI functions. Invoked (by UI_CALL) on the UI process.
+// Terminal UI functions. Invoked (by ui_client.c) on the UI process.
#include <assert.h>
#include <signal.h>
@@ -89,7 +89,6 @@ typedef struct {
} Rect;
struct TUIData {
- UI *ui;
Loop *loop;
unibi_var_t params[9];
char buf[OUTBUF_SIZE];
@@ -158,6 +157,9 @@ struct TUIData {
} unibi_ext;
char *space_buf;
bool stopped;
+ int width;
+ int height;
+ bool rgb;
};
static int got_winch = 0;
@@ -166,144 +168,113 @@ static bool cursor_style_enabled = false;
# include "tui/tui.c.generated.h"
#endif
-UI *tui_start(void)
-{
- UI *ui = xcalloc(1, sizeof(UI)); // Freed by tui_data_destroy().
- ui->stop = tui_stop;
- ui->grid_resize = tui_grid_resize;
- ui->grid_clear = tui_grid_clear;
- ui->grid_cursor_goto = tui_grid_cursor_goto;
- ui->mode_info_set = tui_mode_info_set;
- ui->update_menu = tui_update_menu;
- ui->busy_start = tui_busy_start;
- ui->busy_stop = tui_busy_stop;
- ui->mouse_on = tui_mouse_on;
- ui->mouse_off = tui_mouse_off;
- ui->mode_change = tui_mode_change;
- ui->grid_scroll = tui_grid_scroll;
- ui->hl_attr_define = tui_hl_attr_define;
- ui->bell = tui_bell;
- ui->visual_bell = tui_visual_bell;
- ui->default_colors_set = tui_default_colors_set;
- ui->flush = tui_flush;
- ui->suspend = tui_suspend;
- ui->set_title = tui_set_title;
- ui->set_icon = tui_set_icon;
- ui->screenshot = tui_screenshot;
- ui->option_set = tui_option_set;
- ui->raw_line = tui_raw_line;
-
- CLEAR_FIELD(ui->ui_ext);
- ui->ui_ext[kUILinegrid] = true;
- ui->ui_ext[kUITermColors] = true;
-
- TUIData *data = xcalloc(1, sizeof(TUIData));
- ui->data = data;
- data->ui = ui;
- data->is_starting = true;
- data->screenshot = NULL;
- data->stopped = false;
- data->loop = &main_loop;
- kv_init(data->invalid_regions);
- signal_watcher_init(data->loop, &data->winch_handle, ui);
+TUIData *tui_start(int *width, int *height, char **term)
+{
+ TUIData *tui = xcalloc(1, sizeof(TUIData));
+ tui->is_starting = true;
+ tui->screenshot = NULL;
+ tui->stopped = false;
+ tui->loop = &main_loop;
+ kv_init(tui->invalid_regions);
+ signal_watcher_init(tui->loop, &tui->winch_handle, tui);
// TODO(bfredl): zero hl is empty, send this explicitly?
- kv_push(data->attrs, HLATTRS_INIT);
+ kv_push(tui->attrs, HLATTRS_INIT);
- data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
- tinput_init(&data->input, &main_loop);
- ugrid_init(&data->grid);
- tui_terminal_start(ui);
+ tui->input.tk_ti_hook_fn = tui_tk_ti_getstr;
+ tinput_init(&tui->input, &main_loop);
+ ugrid_init(&tui->grid);
+ tui_terminal_start(tui);
- uv_timer_init(&data->loop->uv, &data->startup_delay_timer);
- data->startup_delay_timer.data = ui;
- uv_timer_start(&data->startup_delay_timer, after_startup_cb,
+ uv_timer_init(&tui->loop->uv, &tui->startup_delay_timer);
+ tui->startup_delay_timer.data = tui;
+ uv_timer_start(&tui->startup_delay_timer, after_startup_cb,
100, 0);
- ui_attach_impl(ui, 0);
-
- return ui;
+ loop_poll_events(&main_loop, 1);
+ *width = tui->width;
+ *height = tui->height;
+ *term = tui->term;
+ return tui;
}
-void tui_enable_extkeys(TUIData *data)
+void tui_enable_extkeys(TUIData *tui)
{
- TermInput input = data->input;
- unibi_term *ut = data->ut;
- UI *ui = data->ui;
+ TermInput input = tui->input;
+ unibi_term *ut = tui->ut;
switch (input.extkeys_type) {
case kExtkeysCSIu:
- data->unibi_ext.enable_extended_keys = (int)unibi_add_ext_str(ut, "ext.enable_extended_keys",
- "\x1b[>1u");
- data->unibi_ext.disable_extended_keys = (int)unibi_add_ext_str(ut, "ext.disable_extended_keys",
- "\x1b[<1u");
+ tui->unibi_ext.enable_extended_keys = (int)unibi_add_ext_str(ut, "ext.enable_extended_keys",
+ "\x1b[>1u");
+ tui->unibi_ext.disable_extended_keys = (int)unibi_add_ext_str(ut, "ext.disable_extended_keys",
+ "\x1b[<1u");
break;
case kExtkeysXterm:
- data->unibi_ext.enable_extended_keys = (int)unibi_add_ext_str(ut, "ext.enable_extended_keys",
- "\x1b[>4;2m");
- data->unibi_ext.disable_extended_keys = (int)unibi_add_ext_str(ut, "ext.disable_extended_keys",
- "\x1b[>4;0m");
+ tui->unibi_ext.enable_extended_keys = (int)unibi_add_ext_str(ut, "ext.enable_extended_keys",
+ "\x1b[>4;2m");
+ tui->unibi_ext.disable_extended_keys = (int)unibi_add_ext_str(ut, "ext.disable_extended_keys",
+ "\x1b[>4;0m");
break;
default:
break;
}
- unibi_out_ext(ui, data->unibi_ext.enable_extended_keys);
+ unibi_out_ext(tui, tui->unibi_ext.enable_extended_keys);
}
-static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char *buf, size_t len)
+static size_t unibi_pre_fmt_str(TUIData *tui, unsigned int unibi_index, char *buf, size_t len)
{
- const char *str = unibi_get_str(data->ut, unibi_index);
+ const char *str = unibi_get_str(tui->ut, unibi_index);
if (!str) {
return 0U;
}
- return unibi_run(str, data->params, buf, len);
-}
-
-static void terminfo_start(UI *ui)
-{
- TUIData *data = ui->data;
- data->scroll_region_is_full_screen = true;
- data->bufpos = 0;
- data->default_attr = false;
- data->can_clear_attr = false;
- data->is_invisible = true;
- data->want_invisible = false;
- data->busy = false;
- data->cork = false;
- data->overflow = false;
- data->set_cursor_color_as_str = false;
- data->cursor_color_changed = false;
- data->showing_mode = SHAPE_IDX_N;
- data->unibi_ext.enable_mouse = -1;
- data->unibi_ext.disable_mouse = -1;
- data->unibi_ext.enable_mouse_move = -1;
- data->unibi_ext.disable_mouse_move = -1;
- data->unibi_ext.set_cursor_color = -1;
- data->unibi_ext.reset_cursor_color = -1;
- data->unibi_ext.enable_bracketed_paste = -1;
- data->unibi_ext.disable_bracketed_paste = -1;
- data->unibi_ext.enter_strikethrough_mode = -1;
- data->unibi_ext.enable_lr_margin = -1;
- data->unibi_ext.disable_lr_margin = -1;
- data->unibi_ext.enable_focus_reporting = -1;
- data->unibi_ext.disable_focus_reporting = -1;
- data->unibi_ext.resize_screen = -1;
- data->unibi_ext.reset_scroll_region = -1;
- data->unibi_ext.set_cursor_style = -1;
- data->unibi_ext.reset_cursor_style = -1;
- data->unibi_ext.get_bg = -1;
- data->unibi_ext.set_underline_color = -1;
- data->unibi_ext.enable_extended_keys = -1;
- data->unibi_ext.disable_extended_keys = -1;
- data->unibi_ext.get_extkeys = -1;
- data->out_fd = STDOUT_FILENO;
- data->out_isatty = os_isatty(data->out_fd);
- data->input.tui_data = data;
+ return unibi_run(str, tui->params, buf, len);
+}
+
+static void terminfo_start(TUIData *tui)
+{
+ tui->scroll_region_is_full_screen = true;
+ tui->bufpos = 0;
+ tui->default_attr = false;
+ tui->can_clear_attr = false;
+ tui->is_invisible = true;
+ tui->want_invisible = false;
+ tui->busy = false;
+ tui->cork = false;
+ tui->overflow = false;
+ tui->set_cursor_color_as_str = false;
+ tui->cursor_color_changed = false;
+ tui->showing_mode = SHAPE_IDX_N;
+ tui->unibi_ext.enable_mouse = -1;
+ tui->unibi_ext.disable_mouse = -1;
+ tui->unibi_ext.enable_mouse_move = -1;
+ tui->unibi_ext.disable_mouse_move = -1;
+ tui->unibi_ext.set_cursor_color = -1;
+ tui->unibi_ext.reset_cursor_color = -1;
+ tui->unibi_ext.enable_bracketed_paste = -1;
+ tui->unibi_ext.disable_bracketed_paste = -1;
+ tui->unibi_ext.enter_strikethrough_mode = -1;
+ tui->unibi_ext.enable_lr_margin = -1;
+ tui->unibi_ext.disable_lr_margin = -1;
+ tui->unibi_ext.enable_focus_reporting = -1;
+ tui->unibi_ext.disable_focus_reporting = -1;
+ tui->unibi_ext.resize_screen = -1;
+ tui->unibi_ext.reset_scroll_region = -1;
+ tui->unibi_ext.set_cursor_style = -1;
+ tui->unibi_ext.reset_cursor_style = -1;
+ tui->unibi_ext.get_bg = -1;
+ tui->unibi_ext.set_underline_color = -1;
+ tui->unibi_ext.enable_extended_keys = -1;
+ tui->unibi_ext.disable_extended_keys = -1;
+ tui->unibi_ext.get_extkeys = -1;
+ tui->out_fd = STDOUT_FILENO;
+ tui->out_isatty = os_isatty(tui->out_fd);
+ tui->input.tui_data = tui;
const char *term = os_getenv("TERM");
#ifdef MSWIN
- os_tty_guess_term(&term, data->out_fd);
+ os_tty_guess_term(&term, tui->out_fd);
os_setenv("TERM", term, 1);
// Old os_getenv() pointer is invalid after os_setenv(), fetch it again.
term = os_getenv("TERM");
@@ -311,18 +282,15 @@ static void terminfo_start(UI *ui)
// Set up unibilium/terminfo.
if (term) {
- data->ut = unibi_from_term(term);
- if (data->ut) {
- if (!ui_client_termname) {
- ui_client_termname = xstrdup(term);
- }
- if (!data->term) {
- data->term = xstrdup(term);
+ tui->ut = unibi_from_term(term);
+ if (tui->ut) {
+ if (!tui->term) {