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

d4dbf822dc

Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
zeertzjq
2025-04-16 07:29:44 +08:00
parent 1c723b2e6f
commit 6e5671b00d
8 changed files with 23 additions and 11 deletions

View File

@ -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 "")

View File

@ -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 = ""

View File

@ -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.

View File

@ -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',

View File

@ -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;

View File

@ -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(' ');
}

View File

@ -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({

View File

@ -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>")