aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/popupmenu.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2025-01-13 15:18:47 +0800
committerGitHub <noreply@github.com>2025-01-13 15:18:47 +0800
commit2c16c849986794682a4776ff4ec100d00eeba5ca (patch)
treea62c94d13e0d37230de1f2897555c900ca229fdb /src/nvim/popupmenu.c
parent99c4bd2f698345fd5706e0ff5d6221b8d3848cfb (diff)
downloadrneovim-2c16c849986794682a4776ff4ec100d00eeba5ca.tar.gz
rneovim-2c16c849986794682a4776ff4ec100d00eeba5ca.tar.bz2
rneovim-2c16c849986794682a4776ff4ec100d00eeba5ca.zip
vim-patch:9.1.1011: popupmenu internal error with some abbr in completion item (#31988)
Problem: Popup menu internal error with some abbr in completion item. Solution: Don't compute attributes when there is no corresponding text. Reduce indent in pum_redraw() while at it (zeertzjq). fixes: vim/vim#16427 closes: vim/vim#16435 https://github.com/vim/vim/commit/3a0cc36c69744a7727ce34311d39d2d9d8ddc6f9
Diffstat (limited to 'src/nvim/popupmenu.c')
-rw-r--r--src/nvim/popupmenu.c138
1 files changed, 68 insertions, 70 deletions
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index 2b1dd22b1a..d1c6f647fd 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -412,7 +412,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
/// Returns attributes for every cell, or NULL if all attributes are the same.
static int *pum_compute_text_attrs(char *text, hlf_T hlf, int user_hlattr)
{
- if ((hlf != HLF_PSI && hlf != HLF_PNI)
+ if (*text == NUL || (hlf != HLF_PSI && hlf != HLF_PNI)
|| (win_hl_attr(curwin, HLF_PMSI) == win_hl_attr(curwin, HLF_PSI)
&& win_hl_attr(curwin, HLF_PMNI) == win_hl_attr(curwin, HLF_PNI))) {
return NULL;
@@ -654,89 +654,87 @@ void pum_redraw(void)
s = p;
}
int w = ptr2cells(p);
+ if (*p != NUL && *p != TAB && totwidth + w <= pum_width) {
+ width += w;
+ continue;
+ }
- if ((*p == NUL) || (*p == TAB) || (totwidth + w > pum_width)) {
- // Display the text that fits or comes before a Tab.
- // First convert it to printable characters.
- char *st;
- char saved = *p;
+ // Display the text that fits or comes before a Tab.
+ // First convert it to printable characters.
+ char saved = *p;
- if (saved != NUL) {
- *p = NUL;
- }
- st = transstr(s, true);
- if (saved != NUL) {
- *p = saved;
- }
-
- int *attrs = NULL;
- if (item_type == CPT_ABBR) {
- attrs = pum_compute_text_attrs(st, hlf, pum_array[idx].pum_user_abbr_hlattr);
- }
+ if (saved != NUL) {
+ *p = NUL;
+ }
+ char *st = transstr(s, true);
+ if (saved != NUL) {
+ *p = saved;
+ }
- if (pum_rl) {
- char *rt = reverse_text(st);
- char *rt_start = rt;
- int cells = vim_strsize(rt);
-
- if (cells > pum_width) {
- do {
- cells -= utf_ptr2cells(rt);
- MB_PTR_ADV(rt);
- } while (cells > pum_width);
-
- if (cells < pum_width) {
- // Most left character requires 2-cells but only 1 cell
- // is available on screen. Put a '<' on the left of the
- // pum item
- *(--rt) = '<';
- cells++;
- }
- }
+ int *attrs = NULL;
+ if (item_type == CPT_ABBR) {
+ attrs = pum_compute_text_attrs(st, hlf,
+ pum_array[idx].pum_user_abbr_hlattr);
+ }
- if (attrs == NULL) {
- grid_line_puts(grid_col - cells + 1, rt, -1, attr);
- } else {
- pum_grid_puts_with_attrs(grid_col - cells + 1, cells, rt, -1, attrs);
+ if (pum_rl) {
+ char *rt = reverse_text(st);
+ char *rt_start = rt;
+ int cells = vim_strsize(rt);
+
+ if (cells > pum_width) {
+ do {
+ cells -= utf_ptr2cells(rt);
+ MB_PTR_ADV(rt);
+ } while (cells > pum_width);
+
+ if (cells < pum_width) {
+ // Most left character requires 2-cells but only 1 cell is available on
+ // screen. Put a '<' on the left of the pum item.
+ *(--rt) = '<';
+ cells++;
}
+ }
- xfree(rt_start);
- xfree(st);
- grid_col -= width;
+ if (attrs == NULL) {
+ grid_line_puts(grid_col - cells + 1, rt, -1, attr);
} else {
- if (attrs == NULL) {
- grid_line_puts(grid_col, st, -1, attr);
- } else {
- pum_grid_puts_with_attrs(grid_col, vim_strsize(st), st, -1, attrs);
- }
-
- xfree(st);
- grid_col += width;
+ pum_grid_puts_with_attrs(grid_col - cells + 1, cells, rt, -1, attrs);
}
- if (attrs != NULL) {
- XFREE_CLEAR(attrs);
+ xfree(rt_start);
+ xfree(st);
+ grid_col -= width;
+ } else {
+ if (attrs == NULL) {
+ grid_line_puts(grid_col, st, -1, attr);
+ } else {
+ pum_grid_puts_with_attrs(grid_col, vim_strsize(st), st, -1, attrs);
}
- if (*p != TAB) {
- break;
- }
+ xfree(st);
+ grid_col += width;
+ }
- // Display two spaces for a Tab.
- if (pum_rl) {
- grid_line_puts(grid_col - 1, " ", 2, attr);
- grid_col -= 2;
- } else {
- grid_line_puts(grid_col, " ", 2, attr);
- grid_col += 2;
- }
- totwidth += 2;
- // start text at next char
- s = NULL;
- width = 0;
+ if (attrs != NULL) {
+ XFREE_CLEAR(attrs);
+ }
+
+ if (*p != TAB) {
+ break;
+ }
+
+ // Display two spaces for a Tab.
+ if (pum_rl) {
+ grid_line_puts(grid_col - 1, " ", 2, attr);
+ grid_col -= 2;
} else {
- width += w;
+ grid_line_puts(grid_col, " ", 2, attr);
+ grid_col += 2;
}
+ totwidth += 2;
+ s = NULL; // start text at next char
+ width = 0;
}
}