aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/api.txt16
-rw-r--r--src/nvim/api/ui.c67
-rw-r--r--src/nvim/popupmnu.c16
-rw-r--r--src/nvim/ui.c26
-rw-r--r--src/nvim/ui.h5
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