diff options
-rw-r--r-- | runtime/doc/api.txt | 16 | ||||
-rw-r--r-- | src/nvim/api/ui.c | 67 | ||||
-rw-r--r-- | src/nvim/popupmnu.c | 16 | ||||
-rw-r--r-- | src/nvim/ui.c | 26 | ||||
-rw-r--r-- | src/nvim/ui.h | 5 |
5 files changed, 126 insertions, 4 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 39b6c6417d..c5ccf35c8e 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -2341,6 +2341,22 @@ nvim_ui_pum_set_height({height}) *nvim_ui_pum_set_height()* Parameters: ~ {height} Popupmenu height, must be greater than zero. + *nvim_ui_pum_set_bounds()* +nvim_ui_pum_set_bounds({width}, {height}, {row}, {col}) + + Tells Nvim the geometry of the popumenu, to align floating + windows with an external popup menu. Note that this method + is not to be confused with |nvim_ui_pum_set_height()|, which + sets the number of visible items in the popup menu, while + this function sets the bounding box of the popup menu, + including visual decorations such as boarders and sliders. + + Parameters: ~ + {width} Popupmenu width, must be greater than zero. + {height} Popupmenu height, must be greater than zero. + {row} Popupmenu row, must be greater or equal to zero. + {height} Popupmenu height, must be greater or equal to zero. + nvim_ui_set_option({name}, {value}) *nvim_ui_set_option()* TODO: Documentation diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 75ee05761b..d2d1355207 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -109,7 +109,12 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, UI *ui = xcalloc(1, sizeof(UI)); ui->width = (int)width; ui->height = (int)height; + ui->pum_nlines = 0; + ui->pum_pos = false; + ui->pum_width = 0; ui->pum_height = 0; + ui->pum_row = -1; + ui->pum_col = -1; ui->rgb = true; ui->override = false; ui->grid_resize = remote_ui_grid_resize; @@ -340,7 +345,69 @@ void nvim_ui_pum_set_height(uint64_t channel_id, Integer height, Error *err) "It must support the ext_popupmenu option"); return; } + + ui->pum_nlines = (int)height; +} + +/// Tells Nvim the geometry of the popumenu, to align floating +/// windows with an external popup menu. Note that this method +/// is not to be confused with |nvim_ui_pum_set_height()|, which +/// sets the number of visible items in the popup menu, while +/// this function sets the bounding box of the popup menu, +/// including visual decorations such as boarders and sliders. +/// +/// @param channel_id +/// @param width Popupmenu width, must be greater than zero. +/// @param height Popupmenu height, must be greater than zero. +/// @param row Popupmenu row, must be greater or equal to zero. +/// @param col Popupmenu height, must be greater or equal to zero. +/// @param[out] err Error details, if any. On error, suspend pum position reporting for the current UI. +void nvim_ui_pum_set_bounds(uint64_t channel_id, Integer width, Integer height, + Integer row, Integer col, Error *err) + FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY +{ + if (!pmap_has(uint64_t)(connected_uis, channel_id)) { + api_set_error(err, kErrorTypeException, + "UI not attached to channel: %" PRId64, channel_id); + return; + } + + UI *ui = pmap_get(uint64_t)(connected_uis, channel_id); + if (!ui->ui_ext[kUIPopupmenu]) { + api_set_error(err, kErrorTypeValidation, + "It must support the ext_popupmenu option"); + return; + } + + if (row < 0) { + api_set_error(err, kErrorTypeValidation, "Expected pumpos row >= 0"); + ui->pum_pos = false; + return; + } + + if (col < 0) { + api_set_error(err, kErrorTypeValidation, "Expected pumpos col >= 0"); + ui->pum_pos = false; + return; + } + + if (width <= 0) { + api_set_error(err, kErrorTypeValidation, "Expected pumpos width > 0"); + ui->pum_pos = false; + return; + } + + if (height <= 0) { + api_set_error(err, kErrorTypeValidation, "Expected pumpos height > 0"); + ui->pum_pos = false; + return; + } + + ui->pum_row = (int)row; + ui->pum_col = (int)col; + ui->pum_width = (int)width; ui->pum_height = (int)height; + ui->pum_pos = true; } /// Pushes data into UI.UIData, to be consumed later by remote_ui_flush(). diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index da34d85c00..9568f319b4 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -908,10 +908,18 @@ void pum_set_event_info(dict_T *dict) if (!pum_visible()) { return; } - tv_dict_add_nr(dict, S_LEN("height"), pum_height); - tv_dict_add_nr(dict, S_LEN("width"), pum_width); - tv_dict_add_nr(dict, S_LEN("row"), pum_row); - tv_dict_add_nr(dict, S_LEN("col"), pum_col); + int w,h,r,c; + if (!ui_pum_get_pos(&w, &h, &r, &c)){ + tv_dict_add_nr(dict, S_LEN("height"), pum_height); + tv_dict_add_nr(dict, S_LEN("width"), pum_width); + tv_dict_add_nr(dict, S_LEN("row"), pum_row); + tv_dict_add_nr(dict, S_LEN("col"), pum_col); + } else { + tv_dict_add_nr(dict, S_LEN("height"), h); + tv_dict_add_nr(dict, S_LEN("width"), w); + tv_dict_add_nr(dict, S_LEN("row"), r); + tv_dict_add_nr(dict, S_LEN("col"), c); + } tv_dict_add_nr(dict, S_LEN("size"), pum_size); tv_dict_add_special(dict, S_LEN("scrollbar"), pum_scrollbar ? kSpecialVarTrue : kSpecialVarFalse); diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 3a5aa95ad3..e7cc3b4e36 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -235,6 +235,32 @@ int ui_pum_get_height(void) return pum_height; } +bool ui_pum_get_pos(int* pwidth, int *pheight, int* prow, int* pcol) +{ + int w=0,h=0,r=-1,c=-1; + bool found = false; + for (size_t i = 1; i < ui_count; i++) { + if (!uis[i]->pum_pos) continue; + if (!found) { + w = uis[i]->pum_width; + h = uis[i]->pum_height; + r = uis[i]->pum_row; + c = uis[i]->pum_col; + found = true; + } else { + w = MIN(uis[i]->pum_width, w); + h = MIN(uis[i]->pum_height, h); + r = MIN(uis[i]->pum_row, r); + c = MIN(uis[i]->pum_col, c); + } + } + *pwidth = w; + *pheight = h; + *prow = r; + *pcol = c; + return found; +} + static void ui_refresh_event(void **argv) { ui_refresh(); diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 8867b5ee24..b3a569b0df 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -53,7 +53,12 @@ struct ui_t { bool ui_ext[kUIExtCount]; ///< Externalized UI capabilities. int width; int height; + int pum_nlines; /// actual nr. lines shown in PUM + bool pum_pos; /// UI reports back pum position? + int pum_row; + int pum_col; int pum_height; + int pum_width; void *data; #ifdef INCLUDE_GENERATED_DECLARATIONS |