mirror of
https://github.com/vim/vim
synced 2025-07-16 01:01:58 +00:00
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: #17081 Signed-off-by: glepnir <glephunter@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
cf665ccd37
commit
d4dbf822dc
@ -3621,6 +3621,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.
|
||||
|
||||
@ -3645,6 +3646,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 empty)
|
||||
|
@ -1,4 +1,4 @@
|
||||
*version9.txt* For Vim version 9.1. Last change: 2025 Apr 08
|
||||
*version9.txt* For Vim version 9.1. Last change: 2025 Apr 12
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -41631,6 +41631,7 @@ Options: ~
|
||||
and CTRL-D / CTRL-U for half-pagewise scrolling
|
||||
- New option value for 'fillchars':
|
||||
"trunc" - configure truncation indicator, 'pummaxwidth'
|
||||
"truncrl" - like "trunc" but in 'rl' mode, 'pummaxwidth'
|
||||
|
||||
Ex commands: ~
|
||||
- allow to specify a priority when defining a new sign |:sign-define|
|
||||
|
114
src/popupmenu.c
114
src/popupmenu.c
@ -604,10 +604,15 @@ pum_redraw(void)
|
||||
int last_isabbr = FALSE;
|
||||
int orig_attr = -1;
|
||||
int scroll_range = pum_size - pum_height;
|
||||
char_u *new_str = NULL;
|
||||
char_u *ptr = NULL;
|
||||
int remaining = 0;
|
||||
int fcs_trunc = curwin->w_fill_chars.trunc;
|
||||
int fcs_trunc;
|
||||
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (pum_rl)
|
||||
fcs_trunc = curwin->w_fill_chars.truncrl;
|
||||
else
|
||||
#endif
|
||||
fcs_trunc = curwin->w_fill_chars.trunc;
|
||||
|
||||
hlf_T hlfsNorm[3];
|
||||
hlf_T hlfsSel[3];
|
||||
@ -722,10 +727,19 @@ pum_redraw(void)
|
||||
|
||||
if (rt != NULL)
|
||||
{
|
||||
char_u *rt_start = rt;
|
||||
int cells;
|
||||
char_u *rt_start = rt;
|
||||
int cells;
|
||||
int over_cell = 0;
|
||||
int truncated = FALSE;
|
||||
|
||||
cells = mb_string2cells(rt , -1);
|
||||
truncated = pum_width == p_pmw
|
||||
&& pum_width - totwidth < cells;
|
||||
|
||||
if (pum_width == p_pmw && !truncated
|
||||
&& (j + 1 < 3 && pum_get_item(idx, order[j + 1]) != NULL))
|
||||
truncated = TRUE;
|
||||
|
||||
if (cells > pum_width)
|
||||
{
|
||||
do
|
||||
@ -746,13 +760,9 @@ pum_redraw(void)
|
||||
}
|
||||
}
|
||||
|
||||
// truncated
|
||||
if (pum_width == p_pmw
|
||||
&& totwidth + 1 + cells >= pum_width)
|
||||
if (truncated)
|
||||
{
|
||||
char_u *orig_rt = rt;
|
||||
char_u *old_rt = NULL;
|
||||
int over_cell = 0;
|
||||
int size = 0;
|
||||
|
||||
remaining = pum_width - totwidth - 1;
|
||||
@ -768,26 +778,19 @@ pum_redraw(void)
|
||||
size = (int)STRLEN(orig_rt);
|
||||
if (cells < remaining)
|
||||
over_cell = remaining - cells;
|
||||
new_str = alloc(size + over_cell + 1 + utf_char2len(fcs_trunc));
|
||||
if (!new_str)
|
||||
return;
|
||||
ptr = new_str;
|
||||
if (fcs_trunc != NUL && fcs_trunc != '>')
|
||||
ptr += (*mb_char2bytes)(fcs_trunc, ptr);
|
||||
|
||||
cells = mb_string2cells(orig_rt, size);
|
||||
width = cells + over_cell + 1;
|
||||
rt = orig_rt;
|
||||
|
||||
if (fcs_trunc != NUL)
|
||||
screen_putchar(fcs_trunc, row, col - width + 1, attr);
|
||||
else
|
||||
*ptr++ = '<';
|
||||
if (over_cell)
|
||||
{
|
||||
vim_memset(ptr, ' ', over_cell);
|
||||
ptr += over_cell;
|
||||
}
|
||||
memcpy(ptr, orig_rt, size);
|
||||
ptr[size] = NUL;
|
||||
old_rt = rt_start;
|
||||
rt = rt_start = new_str;
|
||||
vim_free(old_rt);
|
||||
cells = mb_string2cells(rt, -1);
|
||||
width = cells;
|
||||
screen_putchar('<', row, col - width + 1, attr);
|
||||
|
||||
if (over_cell > 0)
|
||||
screen_fill(row, row + 1, col - width + 2,
|
||||
col - width + 2 + over_cell, ' ', ' ', attr);
|
||||
}
|
||||
|
||||
if (attrs == NULL)
|
||||
@ -809,10 +812,16 @@ pum_redraw(void)
|
||||
{
|
||||
if (st != NULL)
|
||||
{
|
||||
int size = (int)STRLEN(st);
|
||||
int cells = (*mb_string2cells)(st, size);
|
||||
char_u *st_end = NULL;
|
||||
int over_cell = 0;
|
||||
int size = (int)STRLEN(st);
|
||||
int cells = (*mb_string2cells)(st, size);
|
||||
char_u *st_end = NULL;
|
||||
int over_cell = 0;
|
||||
int truncated = pum_width == p_pmw
|
||||
&& pum_width - totwidth < cells;
|
||||
|
||||
if (pum_width == p_pmw && !truncated
|
||||
&& (j + 1 < 3 && pum_get_item(idx, order[j + 1]) != NULL))
|
||||
truncated = TRUE;
|
||||
|
||||
// only draw the text that fits
|
||||
while (size > 0
|
||||
@ -829,8 +838,7 @@ pum_redraw(void)
|
||||
}
|
||||
|
||||
// truncated
|
||||
if (pum_width == p_pmw
|
||||
&& totwidth + 1 + cells >= pum_width)
|
||||
if (truncated)
|
||||
{
|
||||
remaining = pum_width - totwidth - 1;
|
||||
if (cells > remaining)
|
||||
@ -846,28 +854,8 @@ pum_redraw(void)
|
||||
|
||||
if (cells < remaining)
|
||||
over_cell = remaining - cells;
|
||||
new_str = alloc(size + over_cell + 1 + utf_char2len(fcs_trunc));
|
||||
if (!new_str)
|
||||
return;
|
||||
memcpy(new_str, st, size);
|
||||
ptr = new_str + size;
|
||||
if (over_cell > 0)
|
||||
{
|
||||
vim_memset(ptr, ' ', over_cell);
|
||||
ptr += over_cell;
|
||||
}
|
||||
|
||||
if (fcs_trunc != NUL)
|
||||
ptr += (*mb_char2bytes)(fcs_trunc, ptr);
|
||||
else
|
||||
*ptr++ = '>';
|
||||
|
||||
*ptr = NUL;
|
||||
vim_free(st);
|
||||
st = new_str;
|
||||
cells = mb_string2cells(st, -1);
|
||||
size = (int)STRLEN(st);
|
||||
width = cells;
|
||||
cells = mb_string2cells(st, size);
|
||||
width = cells + over_cell + 1;
|
||||
}
|
||||
|
||||
if (attrs == NULL)
|
||||
@ -875,6 +863,18 @@ pum_redraw(void)
|
||||
else
|
||||
pum_screen_puts_with_attrs(row, col, cells,
|
||||
st, size, attrs);
|
||||
if (truncated)
|
||||
{
|
||||
if (over_cell > 0)
|
||||
screen_fill(row, row + 1, col + cells,
|
||||
col + cells + over_cell, ' ', ' ', attr);
|
||||
if (fcs_trunc != NUL)
|
||||
screen_putchar(fcs_trunc, row,
|
||||
col + cells + over_cell, attr);
|
||||
else
|
||||
screen_putchar('>', row,
|
||||
col + cells + over_cell, attr);
|
||||
}
|
||||
|
||||
vim_free(st);
|
||||
}
|
||||
|
@ -4714,6 +4714,7 @@ static struct charstab filltab[] =
|
||||
CHARSTAB_ENTRY(&fill_chars.eob, "eob"),
|
||||
CHARSTAB_ENTRY(&fill_chars.lastline, "lastline"),
|
||||
CHARSTAB_ENTRY(&fill_chars.trunc, "trunc"),
|
||||
CHARSTAB_ENTRY(&fill_chars.truncrl, "truncrl"),
|
||||
};
|
||||
static lcs_chars_T lcs_chars;
|
||||
static struct charstab lcstab[] =
|
||||
@ -4828,6 +4829,7 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply,
|
||||
fill_chars.eob = '~';
|
||||
fill_chars.lastline = '@';
|
||||
fill_chars.trunc = '>';
|
||||
fill_chars.truncrl = '<';
|
||||
}
|
||||
}
|
||||
p = value;
|
||||
|
@ -3851,6 +3851,7 @@ typedef struct
|
||||
int eob;
|
||||
int lastline;
|
||||
int trunc;
|
||||
int truncrl;
|
||||
} fill_chars_T;
|
||||
|
||||
/*
|
||||
|
@ -1,7 +1,7 @@
|
||||
|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_> @44
|
||||
|1+0#0000001#e0e0e08|2|3|4|5|6|7|8|9|>| +0#4040ff13#ffffff0@64
|
||||
|一*0#0000001#ffd7ff255|二|三|四| +&|>| +0#4040ff13#ffffff0@64
|
||||
|a+0#0000001#ffd7ff255|b|c|d|e|f|g|h|i|>| +0#4040ff13#ffffff0@64
|
||||
|a+0#0000001#ffd7ff255|b|c|d|e|f|g|h|i|j| +0#4040ff13#ffffff0@64
|
||||
|上*0#0000001#ffd7ff255|下|左|右| +&@1| +0#4040ff13#ffffff0@64
|
||||
|~| @73
|
||||
|~| @73
|
||||
|
@ -1,7 +1,7 @@
|
||||
| +0&#ffffff0@43> |_|9|8|7|6|5|4|3|2|1|_|9|8|7|6|5|4|3|2|1|_|9|8|7|6|5|4|3|2|1
|
||||
| +0#4040ff13&@64|<+0#0000001#e0e0e08|9|8|7|6|5|4|3|2|1
|
||||
| +0#4040ff13#ffffff0@64|<+0#0000001#ffd7ff255| |四*&|三|二|一
|
||||
| +0#4040ff13#ffffff0@64|<+0#0000001#ffd7ff255|i|h|g|f|e|d|c|b|a
|
||||
| +0#4040ff13#ffffff0@64|j+0#0000001#ffd7ff255|i|h|g|f|e|d|c|b|a
|
||||
| +0#4040ff13#ffffff0@64| +0#0000001#ffd7ff255@1|右*&|左|下|上
|
||||
| +0#4040ff13#ffffff0@73|~
|
||||
| @73|~
|
||||
|
@ -2126,7 +2126,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>")
|
||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1296,
|
||||
/**/
|
||||
1295,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user