aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/ui.c')
-rw-r--r--src/nvim/api/ui.c79
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