commit 54d60550982812f32df76bb69dc4e44ac81a645e
parent 6e5671b00df14d2848b157beb42dae01205a6455
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 16 Apr 2025 07:38:57 +0800
vim-patch:9.1.1306: completion menu rendering can be improved
Problem: Parts of the popup menu were rendered twice when the popup was
at maximum width because the truncation flag was being set too
liberally.
Solution: Make the truncation condition more precise by only setting it
when there's exactly one character of space remaining
(glepnir).
closes: vim/vim#17108
https://github.com/vim/vim/commit/32f2bb6e1e672f52d736579d9752473b14a5744d
Co-authored-by: glepnir <glephunter@gmail.com>
Diffstat:
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
@@ -688,6 +688,9 @@ void pum_redraw(void)
int width = 0;
char *s = NULL;
p = pum_get_item(idx, item_type);
+
+ const bool next_isempty = j + 1 < 3 && pum_get_item(idx, order[j + 1]) == NULL;
+
if (p != NULL) {
for (;; MB_PTR_ADV(p)) {
if (s == NULL) {
@@ -721,12 +724,12 @@ void pum_redraw(void)
char *rt = reverse_text(st);
char *rt_start = rt;
int cells = (int)mb_string2cells(rt);
- if (pum_width == p_pmw
- && (pum_width - totwidth < cells
- || (j + 1 < 3 && pum_get_item(idx, order[j + 1]) != NULL))) {
+ int pad = next_isempty ? 0 : 2;
+ if (pum_width == p_pmw && pum_width - totwidth < cells + pad) {
need_fcs_trunc = true;
}
+ // only draw the text that fits
if (grid_col - cells < col_off - pum_width) {
do {
cells -= utf_ptr2cells(rt);
@@ -752,9 +755,8 @@ void pum_redraw(void)
grid_col -= width;
} else {
int cells = (int)mb_string2cells(st);
- if (pum_width == p_pmw
- && (pum_width - totwidth < cells
- || (j + 1 < 3 && pum_get_item(idx, order[j + 1]) != NULL))) {
+ int pad = next_isempty ? 0 : 2;
+ if (pum_width == p_pmw && pum_width - totwidth < cells + pad) {
need_fcs_trunc = true;
}
@@ -796,10 +798,6 @@ void pum_redraw(void)
n = order[j] == CPT_ABBR ? 1 : 0;
}
- bool next_isempty = false;
- if (j + 1 < 3) {
- next_isempty = pum_get_item(idx, order[j + 1]) == NULL;
- }
// Stop when there is nothing more to display.
if ((j == 2)
|| (next_isempty && (j == 1 || (j == 0 && pum_get_item(idx, order[j + 2]) == NULL)))