forked from aniani/vim
patch 9.1.1086: completion doesn't work with multi lines
Problem: completion doesn't work with multi lines (Łukasz Jan Niemier) Solution: handle linebreaks in completion code as expected (glepnir) fixes: #2505 closes: #15373 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
746fe54d4f
commit
76bdb82527
@@ -41638,6 +41638,7 @@ Changed~
|
|||||||
- new digraph "APPROACHES THE LIMIT" using ".="
|
- new digraph "APPROACHES THE LIMIT" using ".="
|
||||||
- Add the optional {opts} |Dict| argument to |getchar()| to control: cursor
|
- Add the optional {opts} |Dict| argument to |getchar()| to control: cursor
|
||||||
behaviour, return type and whether or not to simplify the returned key
|
behaviour, return type and whether or not to simplify the returned key
|
||||||
|
- handle multi-line completion as expected
|
||||||
|
|
||||||
*added-9.2*
|
*added-9.2*
|
||||||
Added ~
|
Added ~
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
" Vim support file to detect file types
|
" Vim support file to detect file types
|
||||||
"
|
"
|
||||||
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||||
" Last Change: 2025 Jan 21
|
" Last Change: 2025 Feb 08
|
||||||
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||||
|
|
||||||
" Listen very carefully, I will say this only once
|
" Listen very carefully, I will say this only once
|
||||||
|
@@ -1877,7 +1877,8 @@ win_line(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((State & MODE_INSERT) && in_curline && ins_compl_win_active(wp))
|
if ((State & MODE_INSERT) && ins_compl_win_active(wp)
|
||||||
|
&& (in_curline || ins_compl_lnum_in_range(lnum)))
|
||||||
area_highlighting = TRUE;
|
area_highlighting = TRUE;
|
||||||
|
|
||||||
#ifdef FEAT_SYN_HL
|
#ifdef FEAT_SYN_HL
|
||||||
@@ -2423,11 +2424,11 @@ win_line(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if ComplMatchIns highlight is needed.
|
// Check if ComplMatchIns highlight is needed.
|
||||||
if ((State & MODE_INSERT) && in_curline
|
if ((State & MODE_INSERT) && ins_compl_win_active(wp)
|
||||||
&& ins_compl_win_active(wp))
|
&& (in_curline || ins_compl_lnum_in_range(lnum)))
|
||||||
{
|
{
|
||||||
int ins_match_attr =
|
int ins_match_attr =
|
||||||
ins_compl_col_range_attr((int)(ptr - line));
|
ins_compl_col_range_attr(lnum, (int)(ptr - line));
|
||||||
if (ins_match_attr > 0)
|
if (ins_match_attr > 0)
|
||||||
search_attr =
|
search_attr =
|
||||||
hl_combine_attr(search_attr, ins_match_attr);
|
hl_combine_attr(search_attr, ins_match_attr);
|
||||||
|
137
src/insexpand.c
137
src/insexpand.c
@@ -172,6 +172,7 @@ static pos_T compl_startpos;
|
|||||||
// Length in bytes of the text being completed (this is deleted to be replaced
|
// Length in bytes of the text being completed (this is deleted to be replaced
|
||||||
// by the match.)
|
// by the match.)
|
||||||
static int compl_length = 0;
|
static int compl_length = 0;
|
||||||
|
static linenr_T compl_lnum = 0; // lnum where the completion start
|
||||||
static colnr_T compl_col = 0; // column where the text starts
|
static colnr_T compl_col = 0; // column where the text starts
|
||||||
// that is being completed
|
// that is being completed
|
||||||
static colnr_T compl_ins_end_col = 0;
|
static colnr_T compl_ins_end_col = 0;
|
||||||
@@ -226,6 +227,8 @@ static int ins_compl_pum_key(int c);
|
|||||||
static int ins_compl_key2count(int c);
|
static int ins_compl_key2count(int c);
|
||||||
static void show_pum(int prev_w_wrow, int prev_w_leftcol);
|
static void show_pum(int prev_w_wrow, int prev_w_leftcol);
|
||||||
static unsigned quote_meta(char_u *dest, char_u *str, int len);
|
static unsigned quote_meta(char_u *dest, char_u *str, int len);
|
||||||
|
static int ins_compl_has_multiple(void);
|
||||||
|
static void ins_compl_expand_multiple(char_u *str);
|
||||||
|
|
||||||
#ifdef FEAT_SPELL
|
#ifdef FEAT_SPELL
|
||||||
static void spell_back_to_badword(void);
|
static void spell_back_to_badword(void);
|
||||||
@@ -919,20 +922,54 @@ ins_compl_insert_bytes(char_u *p, int len)
|
|||||||
/*
|
/*
|
||||||
* Checks if the column is within the currently inserted completion text
|
* Checks if the column is within the currently inserted completion text
|
||||||
* column range. If it is, it returns a special highlight attribute.
|
* column range. If it is, it returns a special highlight attribute.
|
||||||
* -1 mean normal item.
|
* -1 means normal item.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ins_compl_col_range_attr(int col)
|
ins_compl_col_range_attr(linenr_T lnum, int col)
|
||||||
{
|
{
|
||||||
if ((get_cot_flags() & COT_FUZZY))
|
int start_col;
|
||||||
|
int attr;
|
||||||
|
|
||||||
|
if ((get_cot_flags() & COT_FUZZY)
|
||||||
|
|| (attr = syn_name2attr((char_u *)"ComplMatchIns")) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (col >= (compl_col + (int)ins_compl_leader_len()) && col < compl_ins_end_col)
|
start_col = compl_col + (int)ins_compl_leader_len();
|
||||||
return syn_name2attr((char_u *)"ComplMatchIns");
|
if (!ins_compl_has_multiple())
|
||||||
|
return (col >= start_col && col < compl_ins_end_col) ? attr : -1;
|
||||||
|
|
||||||
|
// Multiple lines
|
||||||
|
if ((lnum == compl_lnum && col >= start_col && col < MAXCOL) ||
|
||||||
|
(lnum > compl_lnum && lnum < curwin->w_cursor.lnum) ||
|
||||||
|
(lnum == curwin->w_cursor.lnum && col <= compl_ins_end_col))
|
||||||
|
return attr;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if the current completion string contains newline characters,
|
||||||
|
* indicating it's a multi-line completion.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ins_compl_has_multiple(void)
|
||||||
|
{
|
||||||
|
return vim_strchr(compl_shown_match->cp_str.string, '\n') != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if the given line number falls within the range of a multi-line
|
||||||
|
* completion, i.e. between the starting line (compl_lnum) and current cursor
|
||||||
|
* line. Always returns FALSE for single-line completions.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ins_compl_lnum_in_range(linenr_T lnum)
|
||||||
|
{
|
||||||
|
if (!ins_compl_has_multiple())
|
||||||
|
return FALSE;
|
||||||
|
return lnum >= compl_lnum && lnum <= curwin->w_cursor.lnum;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reduce the longest common string for match "match".
|
* Reduce the longest common string for match "match".
|
||||||
*/
|
*/
|
||||||
@@ -3123,6 +3160,7 @@ set_completion(colnr_T startcol, list_T *list)
|
|||||||
if (startcol > curwin->w_cursor.col)
|
if (startcol > curwin->w_cursor.col)
|
||||||
startcol = curwin->w_cursor.col;
|
startcol = curwin->w_cursor.col;
|
||||||
compl_col = startcol;
|
compl_col = startcol;
|
||||||
|
compl_lnum = curwin->w_cursor.lnum;
|
||||||
compl_length = (int)curwin->w_cursor.col - (int)startcol;
|
compl_length = (int)curwin->w_cursor.col - (int)startcol;
|
||||||
// compl_pattern doesn't need to be set
|
// compl_pattern doesn't need to be set
|
||||||
compl_orig_text.string = vim_strnsave(ml_get_curline() + compl_col,
|
compl_orig_text.string = vim_strnsave(ml_get_curline() + compl_col,
|
||||||
@@ -4342,6 +4380,8 @@ ins_compl_delete(void)
|
|||||||
// In insert mode: Delete the typed part.
|
// In insert mode: Delete the typed part.
|
||||||
// In replace mode: Put the old characters back, if any.
|
// In replace mode: Put the old characters back, if any.
|
||||||
int col = compl_col + (compl_status_adding() ? compl_length : 0);
|
int col = compl_col + (compl_status_adding() ? compl_length : 0);
|
||||||
|
char_u *remaining = NULL;
|
||||||
|
int orig_col;
|
||||||
int has_preinsert = ins_compl_preinsert_effect();
|
int has_preinsert = ins_compl_preinsert_effect();
|
||||||
if (has_preinsert)
|
if (has_preinsert)
|
||||||
{
|
{
|
||||||
@@ -4349,6 +4389,30 @@ ins_compl_delete(void)
|
|||||||
curwin->w_cursor.col = compl_ins_end_col;
|
curwin->w_cursor.col = compl_ins_end_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (curwin->w_cursor.lnum > compl_lnum)
|
||||||
|
{
|
||||||
|
if (curwin->w_cursor.col < ml_get_curline_len())
|
||||||
|
{
|
||||||
|
char_u *line = ml_get_curline();
|
||||||
|
remaining = vim_strnsave(line + curwin->w_cursor.col,
|
||||||
|
(size_t)STRLEN(line + curwin->w_cursor.col));
|
||||||
|
if (remaining == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (curwin->w_cursor.lnum > compl_lnum)
|
||||||
|
{
|
||||||
|
if (ml_delete(curwin->w_cursor.lnum) == FAIL)
|
||||||
|
{
|
||||||
|
if (remaining)
|
||||||
|
VIM_CLEAR(remaining);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
curwin->w_cursor.lnum--;
|
||||||
|
}
|
||||||
|
// move cursor to end of line
|
||||||
|
curwin->w_cursor.col = ml_get_curline_len();
|
||||||
|
}
|
||||||
|
|
||||||
if ((int)curwin->w_cursor.col > col)
|
if ((int)curwin->w_cursor.col > col)
|
||||||
{
|
{
|
||||||
if (stop_arrow() == FAIL)
|
if (stop_arrow() == FAIL)
|
||||||
@@ -4357,6 +4421,13 @@ ins_compl_delete(void)
|
|||||||
compl_ins_end_col = curwin->w_cursor.col;
|
compl_ins_end_col = curwin->w_cursor.col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (remaining != NULL)
|
||||||
|
{
|
||||||
|
orig_col = curwin->w_cursor.col;
|
||||||
|
ins_str(remaining);
|
||||||
|
curwin->w_cursor.col = orig_col;
|
||||||
|
vim_free(remaining);
|
||||||
|
}
|
||||||
// TODO: is this sufficient for redrawing? Redrawing everything causes
|
// TODO: is this sufficient for redrawing? Redrawing everything causes
|
||||||
// flicker, thus we can't do that.
|
// flicker, thus we can't do that.
|
||||||
changed_cline_bef_curs();
|
changed_cline_bef_curs();
|
||||||
@@ -4366,6 +4437,38 @@ ins_compl_delete(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a completion string that contains newlines.
|
||||||
|
* The string is split and inserted line by line.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ins_compl_expand_multiple(char_u *str)
|
||||||
|
{
|
||||||
|
char_u *start = str;
|
||||||
|
char_u *curr = str;
|
||||||
|
|
||||||
|
while (*curr != NUL)
|
||||||
|
{
|
||||||
|
if (*curr == '\n')
|
||||||
|
{
|
||||||
|
// Insert the text chunk before newline
|
||||||
|
if (curr > start)
|
||||||
|
ins_char_bytes(start, (int)(curr - start));
|
||||||
|
|
||||||
|
// Handle newline
|
||||||
|
open_line(FORWARD, OPENLINE_KEEPTRAIL, FALSE, NULL);
|
||||||
|
start = curr + 1;
|
||||||
|
}
|
||||||
|
curr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle remaining text after last newline (if any)
|
||||||
|
if (curr > start)
|
||||||
|
ins_char_bytes(start, (int)(curr - start));
|
||||||
|
|
||||||
|
compl_ins_end_col = curwin->w_cursor.col;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert the new text being completed.
|
* Insert the new text being completed.
|
||||||
* "in_compl_func" is TRUE when called from complete_check().
|
* "in_compl_func" is TRUE when called from complete_check().
|
||||||
@@ -4375,19 +4478,25 @@ ins_compl_delete(void)
|
|||||||
void
|
void
|
||||||
ins_compl_insert(int in_compl_func, int move_cursor)
|
ins_compl_insert(int in_compl_func, int move_cursor)
|
||||||
{
|
{
|
||||||
int compl_len = get_compl_len();
|
int compl_len = get_compl_len();
|
||||||
int preinsert = ins_compl_has_preinsert();
|
int preinsert = ins_compl_has_preinsert();
|
||||||
char_u *cp_str = compl_shown_match->cp_str.string;
|
char_u *cp_str = compl_shown_match->cp_str.string;
|
||||||
size_t cp_str_len = compl_shown_match->cp_str.length;
|
size_t cp_str_len = compl_shown_match->cp_str.length;
|
||||||
size_t leader_len = ins_compl_leader_len();
|
size_t leader_len = ins_compl_leader_len();
|
||||||
|
char_u *has_multiple = vim_strchr(cp_str, '\n');
|
||||||
|
|
||||||
// Make sure we don't go over the end of the string, this can happen with
|
// Make sure we don't go over the end of the string, this can happen with
|
||||||
// illegal bytes.
|
// illegal bytes.
|
||||||
if (compl_len < (int)cp_str_len)
|
if (compl_len < (int)cp_str_len)
|
||||||
{
|
{
|
||||||
ins_compl_insert_bytes(cp_str + compl_len, -1);
|
if (has_multiple)
|
||||||
if (preinsert && move_cursor)
|
ins_compl_expand_multiple(cp_str + compl_len);
|
||||||
curwin->w_cursor.col -= (colnr_T)(cp_str_len - leader_len);
|
else
|
||||||
|
{
|
||||||
|
ins_compl_insert_bytes(cp_str + compl_len, -1);
|
||||||
|
if (preinsert && move_cursor)
|
||||||
|
curwin->w_cursor.col -= (colnr_T)(cp_str_len - leader_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (match_at_original_text(compl_shown_match) || preinsert)
|
if (match_at_original_text(compl_shown_match) || preinsert)
|
||||||
compl_used_match = FALSE;
|
compl_used_match = FALSE;
|
||||||
@@ -5373,6 +5482,7 @@ ins_compl_start(void)
|
|||||||
line = ml_get(curwin->w_cursor.lnum);
|
line = ml_get(curwin->w_cursor.lnum);
|
||||||
curs_col = curwin->w_cursor.col;
|
curs_col = curwin->w_cursor.col;
|
||||||
compl_pending = 0;
|
compl_pending = 0;
|
||||||
|
compl_lnum = curwin->w_cursor.lnum;
|
||||||
|
|
||||||
if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT
|
if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT
|
||||||
&& compl_cont_mode == ctrl_x_mode)
|
&& compl_cont_mode == ctrl_x_mode)
|
||||||
@@ -5423,6 +5533,7 @@ ins_compl_start(void)
|
|||||||
curbuf->b_p_com = old;
|
curbuf->b_p_com = old;
|
||||||
compl_length = 0;
|
compl_length = 0;
|
||||||
compl_col = curwin->w_cursor.col;
|
compl_col = curwin->w_cursor.col;
|
||||||
|
compl_lnum = curwin->w_cursor.lnum;
|
||||||
}
|
}
|
||||||
else if (ctrl_x_mode_normal() && in_fuzzy)
|
else if (ctrl_x_mode_normal() && in_fuzzy)
|
||||||
{
|
{
|
||||||
|
@@ -61,7 +61,8 @@ void ins_compl_delete(void);
|
|||||||
void ins_compl_insert(int in_compl_func, int move_cursor);
|
void ins_compl_insert(int in_compl_func, int move_cursor);
|
||||||
void ins_compl_check_keys(int frequency, int in_compl_func);
|
void ins_compl_check_keys(int frequency, int in_compl_func);
|
||||||
int ins_complete(int c, int enable_pum);
|
int ins_complete(int c, int enable_pum);
|
||||||
int ins_compl_col_range_attr(int col);
|
int ins_compl_col_range_attr(linenr_T lnum, int col);
|
||||||
void free_insexpand_stuff(void);
|
void free_insexpand_stuff(void);
|
||||||
int ins_compl_preinsert_effect(void);
|
int ins_compl_preinsert_effect(void);
|
||||||
|
int ins_compl_lnum_in_range(linenr_T lnum);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
12
src/testdir/dumps/Test_pum_with_special_characters_01.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_01.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|f+0&#ffffff0|u|n|c| |(|)| @67
|
||||||
|
@75
|
||||||
|
|e|n|d> @71
|
||||||
|
|f+0#0000001#e0e0e08|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@59
|
||||||
|
|f+0#0000001#ffd7ff255|o@1|b|a|r| @8| +0#4040ff13#ffffff0@59
|
||||||
|
|你*0#0000001#ffd7ff255|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@59
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@34
|
12
src/testdir/dumps/Test_pum_with_special_characters_02.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_02.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|f+0&#ffffff0|o@1|b|a|r> @68
|
||||||
|
|f+0#0000001#ffd7ff255|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@59
|
||||||
|
|f+0#0000001#e0e0e08|o@1|b|a|r| @8| +0#4040ff13#ffffff0@59
|
||||||
|
|你*0#0000001#ffd7ff255|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@59
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |3| +0#0000000&@34
|
12
src/testdir/dumps/Test_pum_with_special_characters_03.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_03.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|h+0&#ffffff0|e|l@1|o| |f|u|n|c| |(|)| @61
|
||||||
|
@75
|
||||||
|
|e|n|d> |h|e|r|o| @66
|
||||||
|
|~+0#4040ff13&| @3| +0#0000001#e0e0e08|f|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#ffd7ff255|f|o@1|b|a|r| @8| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#ffd7ff255|你*&|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@34
|
12
src/testdir/dumps/Test_pum_with_special_characters_04.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_04.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|h+0&#ffffff0|e|l@1|o| |f|o@1|b|a|r> |h|e|r|o| @57
|
||||||
|
|~+0#4040ff13&| @3| +0#0000001#ffd7ff255|f|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#e0e0e08|f|o@1|b|a|r| @8| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#ffd7ff255|你*&|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |3| +0#0000000&@34
|
12
src/testdir/dumps/Test_pum_with_special_characters_05.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_05.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|h+0&#ffffff0|e|l@1|o| |你*&|好| +&@64
|
||||||
|
@75
|
||||||
|
|我*&|好> +&|h|e|r|o| @65
|
||||||
|
|~+0#4040ff13&| @1| +0#0000001#ffd7ff255|f|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@55
|
||||||
|
|~| @1| +0#0000001#ffd7ff255|f|o@1|b|a|r| @8| +0#4040ff13#ffffff0@55
|
||||||
|
|~| @1| +0#0000001#e0e0e08|你*&|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@55
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |3| |o|f| |3| +0#0000000&@34
|
12
src/testdir/dumps/Test_pum_with_special_characters_06.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_06.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|h+0&#ffffff0|e|l@1|o| > |h|e|r|o| @63
|
||||||
|
|~+0#4040ff13&| @3| +0#0000001#ffd7ff255|f|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#ffd7ff255|f|o@1|b|a|r| @8| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#ffd7ff255|你*&|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |B+0#e000002&|a|c|k| |a|t| |o|r|i|g|i|n|a|l| +0#0000000&@30
|
12
src/testdir/dumps/Test_pum_with_special_characters_07.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_07.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|f+0#ff404010#ffffff0|u|n|c| |(|)| +0#0000000&@67
|
||||||
|
| +0#ff404010&@7| +0#0000000&@66
|
||||||
|
|e+0#ff404010&|n|d> +0#0000000&@71
|
||||||
|
|f+0#0000001#e0e0e08|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@59
|
||||||
|
|f+0#0000001#ffd7ff255|o@1|b|a|r| @8| +0#4040ff13#ffffff0@59
|
||||||
|
|你*0#0000001#ffd7ff255|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@59
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@34
|
12
src/testdir/dumps/Test_pum_with_special_characters_08.dump
Normal file
12
src/testdir/dumps/Test_pum_with_special_characters_08.dump
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|h+0&#ffffff0|e|l@1|o| |f+0#ff404010&|u|n|c| |(|)| +0#0000000&@61
|
||||||
|
| +0#ff404010&@7| +0#0000000&@66
|
||||||
|
|e+0#ff404010&|n|d> |h+0#0000000&|e|r|o| @66
|
||||||
|
|~+0#4040ff13&| @3| +0#0000001#e0e0e08|f|u|n|c|t|i|o|n| |(|)| @3| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#ffd7ff255|f|o@1|b|a|r| @8| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @3| +0#0000001#ffd7ff255|你*&|好|^+&|@| @1|^|@|我*&|好| +&| +0#4040ff13#ffffff0@53
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@34
|
@@ -1894,4 +1894,59 @@ func Test_popup_completion_many_ctrlp()
|
|||||||
bw!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_pum_complete_with_special_characters()
|
||||||
|
CheckScreendump
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
func Omni_test(findstart, base)
|
||||||
|
if a:findstart
|
||||||
|
return col(".")
|
||||||
|
endif
|
||||||
|
return [#{word: "func ()\n\t\nend", abbr: "function ()",}, #{word: "foobar"}, #{word: "你好\n\t\n我好"}]
|
||||||
|
endfunc
|
||||||
|
set omnifunc=Omni_test
|
||||||
|
END
|
||||||
|
|
||||||
|
call writefile(lines, 'Xpreviewscript', 'D')
|
||||||
|
let buf = RunVimInTerminal('-S Xpreviewscript', #{rows: 12})
|
||||||
|
call term_sendkeys(buf, "S\<C-X>\<C-O>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_01', {})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "\<C-N>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_02', {})
|
||||||
|
call term_sendkeys(buf, "\<C-E>\<Esc>")
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "Shello hero\<ESC>hhhhha\<C-X>\<C-O>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_03', {})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "\<C-N>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_04', {})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "\<C-N>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_05', {})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "\<C-N>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_06', {})
|
||||||
|
call term_sendkeys(buf, "\<C-E>\<Esc>")
|
||||||
|
|
||||||
|
call term_sendkeys(buf, ":hi ComplMatchIns ctermfg=red\<CR>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call term_sendkeys(buf, "S\<C-X>\<C-O>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_07', {})
|
||||||
|
call term_sendkeys(buf, "\<C-E>\<Esc>")
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "Shello hero\<ESC>hhhhha\<C-X>\<C-O>")
|
||||||
|
call TermWait(buf, 50)
|
||||||
|
call VerifyScreenDump(buf, 'Test_pum_with_special_characters_08', {})
|
||||||
|
call term_sendkeys(buf, "\<C-E>\<Esc>")
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1086,
|
||||||
/**/
|
/**/
|
||||||
1085,
|
1085,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user