diff options
Diffstat (limited to 'src/nvim/api/ui.c')
-rw-r--r-- | src/nvim/api/ui.c | 79 |
1 files changed, 74 insertions, 5 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index d3cbb46dad..4f28ea5af3 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -29,11 +29,12 @@ typedef struct { uint64_t channel_id; Array buffer; - int hl_id; // current higlight for legacy put event - Integer cursor_row, cursor_col; // Intended visibule cursor position + 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; static PMap(uint64_t) *connected_uis = NULL; @@ -75,6 +76,21 @@ void remote_ui_wait_for_attach(void) pmap_has(uint64_t)(connected_uis, CHAN_STDIO)); } +/// Activates UI events on the channel. +/// +/// Entry point of all UI clients. Allows |\-\-embed| to continue startup. +/// Implies that the client is ready to show the UI. Adds the client to the +/// list of UIs. |nvim_list_uis()| +/// +/// @note If multiple UI clients are attached, the global screen dimensions +/// degrade to the smallest client. E.g. if client A requests 80x40 but +/// client B requests 200x100, the global screen has size 80x40. +/// +/// @param channel_id +/// @param width Requested screen columns +/// @param height Requested screen rows +/// @param options |ui-option| map +/// @param[out] err Error details, if any void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictionary options, Error *err) FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY @@ -94,6 +110,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->width = (int)width; ui->height = (int)height; 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; @@ -146,6 +163,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, data->buffer = (Array)ARRAY_DICT_INIT; data->hl_id = 0; data->client_col = -1; + data->wildmenu_active = false; ui->data = data; pmap_put(uint64_t)(connected_uis, channel_id, ui); @@ -162,6 +180,12 @@ void ui_attach(uint64_t channel_id, Integer width, Integer height, api_free_dictionary(opts); } +/// Deactivates UI events on the channel. +/// +/// Removes the client from the list of UIs. |nvim_list_uis()| +/// +/// @param channel_id +/// @param[out] err Error details, if any void nvim_ui_detach(uint64_t channel_id, Error *err) FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY { @@ -213,6 +237,15 @@ void nvim_ui_set_option(uint64_t channel_id, String name, static void ui_set_option(UI *ui, bool init, String name, Object value, Error *error) { + if (strequal(name.data, "override")) { + if (value.type != kObjectTypeBoolean) { + api_set_error(error, kErrorTypeValidation, "override must be a Boolean"); + return; + } + ui->override = value.data.boolean; + return; + } + if (strequal(name.data, "rgb")) { if (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean"); @@ -262,20 +295,22 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, /// /// On invalid grid handle, fails with error. /// +/// @param channel_id /// @param grid The handle of the grid to be changed. /// @param width The new requested width. /// @param height The new requested height. +/// @param[out] err Error details, if any void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, - Integer height, Error *error) + Integer height, Error *err) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(error, kErrorTypeException, + api_set_error(err, kErrorTypeException, "UI not attached to channel: %" PRId64, channel_id); return; } - ui_grid_resize((handle_T)grid, (int)width, (int)height, error); + ui_grid_resize((handle_T)grid, (int)width, (int)height, err); } /// Pushes data into UI.UIData, to be consumed later by remote_ui_flush(). @@ -586,6 +621,7 @@ static Array translate_firstarg(UI *ui, Array args) static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) { + UIData *data = ui->data; if (!ui->ui_ext[kUILinegrid]) { // the representation of highlights in cmdline changed, translate back // never consumes args @@ -611,6 +647,39 @@ static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) } } + // Back-compat: translate popupmenu_xx to legacy wildmenu_xx. + if (ui->ui_ext[kUIWildmenu]) { + if (strequal(name, "popupmenu_show")) { + data->wildmenu_active = (args.items[4].data.integer == -1) + || !ui->ui_ext[kUIPopupmenu]; + if (data->wildmenu_active) { + Array new_args = ARRAY_DICT_INIT; + Array items = args.items[0].data.array; + Array new_items = ARRAY_DICT_INIT; + for (size_t i = 0; i < items.size; i++) { + ADD(new_items, copy_object(items.items[i].data.array.items[0])); + } + ADD(new_args, ARRAY_OBJ(new_items)); + push_call(ui, "wildmenu_show", new_args); + if (args.items[1].data.integer != -1) { + Array new_args2 = ARRAY_DICT_INIT; + ADD(new_args2, args.items[1]); + push_call(ui, "wildmenu_select", new_args); + } + return; + } + } else if (strequal(name, "popupmenu_select")) { + if (data->wildmenu_active) { + name = "wildmenu_select"; + } + } else if (strequal(name, "popupmenu_hide")) { + if (data->wildmenu_active) { + name = "wildmenu_hide"; + } + } + } + + Array my_args = ARRAY_DICT_INIT; // Objects are currently single-reference // make a copy, but only if necessary |