neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 6e5671b00df14d2848b157beb42dae01205a6455
parent 1c723b2e6f51634c2e2f994f016b8e70ac50c955
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Wed, 16 Apr 2025 07:29:44 +0800

vim-patch:9.1.1296: completion: incorrect truncation logic

Problem:  completion: incorrect truncation logic (after: v9.1.1284)
Solution: replace string allocation with direct screen rendering and
          fixe RTL/LTR truncation calculations (glepnir)

closes: vim/vim#17081

https://github.com/vim/vim/commit/d4dbf822dcb9fd95379bebab85def391e1179b21

Co-authored-by: glepnir <glephunter@gmail.com>

Diffstat:
Mruntime/doc/options.txt | 2++
Mruntime/lua/vim/_meta/options.lua | 2++
Msrc/nvim/buffer_defs.h | 1+
Msrc/nvim/options.lua | 2++
Msrc/nvim/optionstr.c | 1+
Msrc/nvim/popupmenu.c | 14+++++++++-----
Mtest/functional/ui/popupmenu_spec.lua | 10+++++-----
Mtest/old/testdir/test_popup.vim | 2+-
8 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt @@ -2642,6 +2642,7 @@ A jump table for the options with a short description can be found at |Q_op|. lastline '@' 'display' contains lastline/truncate trunc '>' truncated text in the |ins-completion-menu|. + truncrl '<' same as "trunc' in 'rightleft' mode Any one that is omitted will fall back to the default. @@ -2681,6 +2682,7 @@ A jump table for the options with a short description can be found at |Q_op|. lastline NonText |hl-NonText| trunc one of the many Popup menu highlighting groups like |hl-PmenuSel| + truncrl same as "trunc" *'findfunc'* *'ffu'* *E1514* 'findfunc' 'ffu' string (default "") diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua @@ -2334,6 +2334,7 @@ vim.bo.ft = vim.bo.filetype --- lastline '@' 'display' contains lastline/truncate --- trunc '>' truncated text in the --- `ins-completion-menu`. +--- truncrl '<' same as "trunc' in 'rightleft' mode --- --- Any one that is omitted will fall back to the default. --- @@ -2376,6 +2377,7 @@ vim.bo.ft = vim.bo.filetype --- lastline NonText `hl-NonText` --- trunc one of the many Popup menu highlighting groups like --- `hl-PmenuSel` +--- truncrl same as "trunc" --- --- @type string vim.o.fillchars = "" diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h @@ -1057,6 +1057,7 @@ typedef struct { schar_T eob; schar_T lastline; schar_T trunc; + schar_T truncrl; } fcs_chars_T; /// Structure which contains all information that belongs to a window. diff --git a/src/nvim/options.lua b/src/nvim/options.lua @@ -3062,6 +3062,7 @@ local options = { lastline '@' 'display' contains lastline/truncate trunc '>' truncated text in the |ins-completion-menu|. + truncrl '<' same as "trunc' in 'rightleft' mode Any one that is omitted will fall back to the default. @@ -3101,6 +3102,7 @@ local options = { lastline NonText |hl-NonText| trunc one of the many Popup menu highlighting groups like |hl-PmenuSel| + truncrl same as "trunc" ]=], expand_cb = 'expand_set_chars_option', full_name = 'fillchars', diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c @@ -2133,6 +2133,7 @@ static const struct chars_tab fcs_tab[] = { CHARSTAB_ENTRY(&fcs_chars.eob, "eob", "~", NULL), CHARSTAB_ENTRY(&fcs_chars.lastline, "lastline", "@", NULL), CHARSTAB_ENTRY(&fcs_chars.trunc, "trunc", ">", NULL), + CHARSTAB_ENTRY(&fcs_chars.truncrl, "truncrl", "<", NULL), }; static lcs_chars_T lcs_chars; diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c @@ -577,7 +577,8 @@ void pum_redraw(void) int thumb_pos = 0; int thumb_height = 1; int n; - schar_T fcs_trunc = curwin->w_p_fcs_chars.trunc; + const schar_T fcs_trunc = pum_rl ? curwin->w_p_fcs_chars.truncrl + : curwin->w_p_fcs_chars.trunc; // "word" "kind" "extra text" const hlf_T hlfsNorm[3] = { HLF_PNI, HLF_PNK, HLF_PNX }; @@ -720,7 +721,9 @@ void pum_redraw(void) char *rt = reverse_text(st); char *rt_start = rt; int cells = (int)mb_string2cells(rt); - if (pum_width == p_pmw && totwidth + 1 + cells >= pum_width) { + if (pum_width == p_pmw + && (pum_width - totwidth < cells + || (j + 1 < 3 && pum_get_item(idx, order[j + 1]) != NULL))) { need_fcs_trunc = true; } @@ -749,7 +752,9 @@ void pum_redraw(void) grid_col -= width; } else { int cells = (int)mb_string2cells(st); - if (pum_width == p_pmw && totwidth + 1 + cells >= pum_width) { + if (pum_width == p_pmw + && (pum_width - totwidth < cells + || (j + 1 < 3 && pum_get_item(idx, order[j + 1]) != NULL))) { need_fcs_trunc = true; } @@ -818,8 +823,7 @@ void pum_redraw(void) const int lcol = col_off - pum_width + 1; grid_line_fill(lcol, grid_col + 1, schar_from_ascii(' '), orig_attr); if (need_fcs_trunc) { - linebuf_char[lcol] = fcs_trunc != NUL && fcs_trunc != schar_from_ascii('>') - ? fcs_trunc : schar_from_ascii('<'); + linebuf_char[lcol] = fcs_trunc != NUL ? fcs_trunc : schar_from_ascii('<'); if (pum_width > 1 && linebuf_char[lcol + 1] == NUL) { linebuf_char[lcol + 1] = schar_from_ascii(' '); } diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua @@ -5891,7 +5891,7 @@ describe('builtin popupmenu', function() ## grid 4 {s:123456789>}| {n:一二三四 >}| - {n:abcdefghi>}| + {n:abcdefghij}| {n:上下左右 }| ]], float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, @@ -5901,7 +5901,7 @@ describe('builtin popupmenu', function() 123456789_123456789_123456789_^ | {s:123456789>}{1: }| {n:一二三四 >}{1: }| - {n:abcdefghi>}{1: }| + {n:abcdefghij}{1: }| {n:上下左右 }{1: }| {1:~ }|*2 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | @@ -5925,7 +5925,7 @@ describe('builtin popupmenu', function() ## grid 4 {s:<987654321}| {n:< 四三二一}| - {n:<ihgfedcba}| + {n:jihgfedcba}| {n: 右左下上}| ]], float_pos = { [4] = { -1, 'NW', 2, 1, 50, false, 100, 1, 1, 50 } }, @@ -5935,7 +5935,7 @@ describe('builtin popupmenu', function() ^ _987654321_987654321_987654321| {1: }{s:<987654321}| {1: }{n:< 四三二一}| - {1: }{n:<ihgfedcba}| + {1: }{n:jihgfedcba}| {1: }{n: 右左下上}| {1: ~}|*2 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | @@ -6207,7 +6207,7 @@ describe('builtin popupmenu', function() end feed('<Esc>') - command('set fcs+=trunc:…') + command('set fcs+=truncrl:…') feed('S<C-X><C-O>') if multigrid then screen:expect({ diff --git a/test/old/testdir/test_popup.vim b/test/old/testdir/test_popup.vim @@ -2132,7 +2132,7 @@ func Test_pum_maxwidth_multibyte() call VerifyScreenDump(buf, 'Test_pum_maxwidth_16', {'rows': 8}) call term_sendkeys(buf, "\<ESC>") - call term_sendkeys(buf, ":set fcs+=trunc:…\<CR>") + call term_sendkeys(buf, ":set fcs+=truncrl:…\<CR>") call term_sendkeys(buf, "S\<C-X>\<C-O>") call VerifyScreenDump(buf, 'Test_pum_maxwidth_17', {'rows': 8}) call term_sendkeys(buf, "\<ESC>")