aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-06-13 14:08:50 +0800
committerzeertzjq <zeertzjq@outlook.com>2024-06-15 04:47:23 +0800
commitdc4037f612c6f3bbc76890adfa638d48ec238eee (patch)
tree97e79ba5672c7e6190a8379a2f7d1869f48cbf7e
parentfd950d4998a497cb4258d35af72408105900296a (diff)
downloadrneovim-dc4037f612c6f3bbc76890adfa638d48ec238eee.tar.gz
rneovim-dc4037f612c6f3bbc76890adfa638d48ec238eee.tar.bz2
rneovim-dc4037f612c6f3bbc76890adfa638d48ec238eee.zip
vim-patch:9.1.0476: Cannot see matched text in popup menu
Problem: Cannot see matched text in popup menu Solution: Introduce 2 new highlighting groups: PmenuMatch and PmenuMatchSel (glepnir) closes: vim/vim#14694 https://github.com/vim/vim/commit/40c1c3317d92f8c2adadf744fab72e4458e2a9fa Co-authored-by: glepnir <glephunter@gmail.com>
-rw-r--r--runtime/colors/vim.lua2
-rw-r--r--runtime/doc/syntax.txt5
-rw-r--r--src/nvim/highlight.h2
-rw-r--r--src/nvim/highlight_defs.h2
-rw-r--r--src/nvim/highlight_group.c2
-rw-r--r--src/nvim/insexpand.c6
-rw-r--r--src/nvim/option_vars.h14
-rw-r--r--src/nvim/popupmenu.c75
-rw-r--r--src/nvim/search.c82
-rw-r--r--test/functional/ui/cursor_spec.lua4
-rw-r--r--test/functional/ui/popupmenu_spec.lua117
-rw-r--r--test/old/testdir/test_popup.vim67
12 files changed, 365 insertions, 13 deletions
diff --git a/runtime/colors/vim.lua b/runtime/colors/vim.lua
index 76a56566a6..5b9309ab38 100644
--- a/runtime/colors/vim.lua
+++ b/runtime/colors/vim.lua
@@ -56,6 +56,8 @@ hi('CursorLineFold', { link = 'FoldColumn' })
hi('CurSearch', { link = 'Search' })
hi('PmenuKind', { link = 'Pmenu' })
hi('PmenuKindSel', { link = 'PmenuSel' })
+hi('PmenuMatch', { link = 'Pmenu' })
+hi('PmenuMatchSel', { link = 'PmenuSel' })
hi('PmenuExtra', { link = 'Pmenu' })
hi('PmenuExtraSel', { link = 'PmenuSel' })
hi('Substitute', { link = 'Search' })
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 9fc415a158..ac4dc6286c 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -5076,6 +5076,11 @@ PmenuExtraSel Popup menu: Selected item "extra text".
PmenuSbar Popup menu: Scrollbar.
*hl-PmenuThumb*
PmenuThumb Popup menu: Thumb of the scrollbar.
+ *hl-PmenuMatch*
+PmenuMatch Popup menu: Matched text in normal item
+ *hl-PmenuMatchSel*
+PmenuMatchSel Popup menu: Matched text in selected item
+
*hl-Question*
Question |hit-enter| prompt and yes/no questions.
*hl-QuickFixLine*
diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h
index 558727fc51..2ba6cf5371 100644
--- a/src/nvim/highlight.h
+++ b/src/nvim/highlight.h
@@ -54,6 +54,8 @@ EXTERN const char *hlf_names[] INIT( = {
[HLF_SPL] = "SpellLocal",
[HLF_PNI] = "Pmenu",
[HLF_PSI] = "PmenuSel",
+ [HLF_PMNI] = "PmenuMatch",
+ [HLF_PMSI] = "PmenuMatchSel",
[HLF_PNK] = "PmenuKind",
[HLF_PSK] = "PmenuKindSel",
[HLF_PNX] = "PmenuExtra",
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
index 17e3db04da..e0cce81166 100644
--- a/src/nvim/highlight_defs.h
+++ b/src/nvim/highlight_defs.h
@@ -101,6 +101,8 @@ typedef enum {
HLF_SPL, ///< SpellLocal
HLF_PNI, ///< popup menu normal item
HLF_PSI, ///< popup menu selected item
+ HLF_PMNI, ///< popup menu matched text in normal item
+ HLF_PMSI, ///< popup menu matched text in selected item
HLF_PNK, ///< popup menu normal item "kind"
HLF_PSK, ///< popup menu selected item "kind"
HLF_PNX, ///< popup menu normal item "menu" (extra text)
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index aa98983b63..3c777e7c4d 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -169,6 +169,8 @@ static const char *highlight_init_both[] = {
"default link PmenuExtraSel PmenuSel",
"default link PmenuKind Pmenu",
"default link PmenuKindSel PmenuSel",
+ "default link PmenuMatch Pmenu",
+ "default link PmenuMatchSel PmenuSel",
"default link PmenuSbar Pmenu",
"default link Substitute Search",
"default link StatusLineTerm StatusLine",
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 139637b8a1..9b6805404f 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -1388,6 +1388,12 @@ bool compl_match_curr_select(int selected)
#define DICT_FIRST (1) ///< use just first element in "dict"
#define DICT_EXACT (2) ///< "dict" is the exact name of a file
+/// Get current completion leader
+char *ins_compl_leader(void)
+{
+ return compl_leader;
+}
+
/// Add any identifiers that match the given pattern "pat" in the list of
/// dictionary files "dict_start" to the list of completions.
///
diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h
index bd0fe699d9..404e58661c 100644
--- a/src/nvim/option_vars.h
+++ b/src/nvim/option_vars.h
@@ -55,13 +55,13 @@
#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText,d:Directory,e:ErrorMsg," \
"i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow," \
- "N:CursorLineNr,G:CursorLineSign,O:CursorLineFold" \
- "r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg," \
- "W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn," \
- "-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel," \
- "[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb," \
- "*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn," \
- "q:QuickFixLine,g:MsgArea,0:Whitespace,I:NormalNC"
+ "N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC," \
+ "c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
+ "A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap," \
+ "R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,k:PmenuMatch,<:PmenuMatchSel,[:PmenuKind," \
+ "]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel," \
+ "_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm," \
+ "Z:StatusLineTermNC,g:MsgArea,0:Whitespace,I:NormalNC"
// Default values for 'errorformat'.
// The "%f|%l| %m" one is used for when the contents of the quickfix window is
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index 324254a188..a7fdd44ef0 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -25,6 +25,7 @@
#include "nvim/ex_cmds_defs.h"
#include "nvim/extmark.h"
#include "nvim/extmark_defs.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/gettext_defs.h"
#include "nvim/globals.h"
@@ -48,6 +49,7 @@
#include "nvim/plines.h"
#include "nvim/popupmenu.h"
#include "nvim/pos_defs.h"
+#include "nvim/search.h"
#include "nvim/state_defs.h"
#include "nvim/strings.h"
#include "nvim/types_defs.h"
@@ -435,6 +437,74 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
pum_redraw();
}
+/// Displays text on the popup menu with specific attributes.
+static void pum_puts_with_attr(int col, const char *text, int attr)
+{
+ char *leader = ins_compl_leader();
+
+ if ((win_hl_attr(curwin, HLF_PMSI) == win_hl_attr(curwin, HLF_PSI)
+ && win_hl_attr(curwin, HLF_PMNI) == win_hl_attr(curwin, HLF_PNI))) {
+ grid_line_puts(col, text, -1, attr);
+ return;
+ }
+
+ char *rt_leader = NULL;
+ if (leader != NULL && curwin->w_p_rl) {
+ rt_leader = reverse_text(leader);
+ }
+ char *match_leader = rt_leader != NULL ? rt_leader : leader;
+ size_t leader_len = match_leader ? strlen(match_leader) : 0;
+
+ const bool in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0;
+
+ garray_T *ga = NULL;
+ if (match_leader != NULL && leader_len > 0 && in_fuzzy) {
+ ga = fuzzy_match_str_with_pos(text, match_leader);
+ }
+
+ // Render text with proper attributes
+ const char *ptr = text;
+ while (*ptr != NUL) {
+ int char_len = utfc_ptr2len(ptr);
+ int cells = utf_ptr2cells(ptr);
+ int new_attr = attr;
+
+ if (ga != NULL) {
+ // Handle fuzzy matching
+ for (int i = 0; i < ga->ga_len; i++) {
+ int *match_pos = ((int *)ga->ga_data) + i;
+ int actual_char_pos = 0;
+ const char *temp_ptr = text;
+ while (temp_ptr < ptr) {
+ temp_ptr += utfc_ptr2len(temp_ptr);
+ actual_char_pos++;
+ }
+ if (actual_char_pos == match_pos[0]) {
+ new_attr = win_hl_attr(curwin, (attr == win_hl_attr(curwin, HLF_PSI)
+ ? HLF_PMSI : HLF_PMNI));
+ break;
+ }
+ }
+ } else if (!in_fuzzy && ptr < text + leader_len
+ && strncmp(text, match_leader, leader_len) == 0) {
+ new_attr = win_hl_attr(curwin, (attr == win_hl_attr(curwin, HLF_PSI)
+ ? HLF_PMSI : HLF_PMNI));
+ }
+
+ grid_line_puts(col, ptr, char_len, new_attr);
+ col += cells;
+ ptr += char_len;
+ }
+
+ if (ga != NULL) {
+ ga_clear(ga);
+ xfree(ga);
+ }
+ if (rt_leader) {
+ xfree(rt_leader);
+ }
+}
+
/// Redraw the popup menu, using "pum_first" and "pum_selected".
void pum_redraw(void)
{
@@ -593,13 +663,12 @@ void pum_redraw(void)
size++;
}
}
- grid_line_puts(grid_col - size + 1, rt, -1, attr);
+ pum_puts_with_attr(grid_col - size + 1, rt, attr);
xfree(rt_start);
xfree(st);
grid_col -= width;
} else {
- // use grid_line_puts() to truncate the text
- grid_line_puts(grid_col, st, -1, attr);
+ pum_puts_with_attr(grid_col, st, attr);
xfree(st);
grid_col += width;
}
diff --git a/src/nvim/search.c b/src/nvim/search.c
index bee124e305..fef27dba48 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -21,12 +21,14 @@
#include "nvim/errors.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/gettext_defs.h"
#include "nvim/globals.h"
@@ -3254,7 +3256,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat
const char *const key, Callback *const item_cb,
const bool retmatchpos, list_T *const fmatchlist,
const int max_matches)
- FUNC_ATTR_NONNULL_ARG(2, 5, 7)
+ FUNC_ATTR_NONNULL_ARG(2, 7)
{
int len = tv_list_len(l);
if (len == 0) {
@@ -3542,6 +3544,84 @@ int fuzzy_match_str(char *const str, const char *const pat)
return score;
}
+/// Fuzzy match the position of string "pat" in string "str".
+/// @returns a dynamic array of matching positions. If there is no match, returns NULL.
+garray_T *fuzzy_match_str_with_pos(const char *const str, char *const pat)
+{
+ garray_T *match_positions = xmalloc(sizeof(garray_T));
+
+ ga_init(match_positions, sizeof(int), 10);
+ if (str == NULL || pat == NULL) {
+ ga_clear(match_positions);
+ return NULL;
+ }
+ list_T *l = tv_list_alloc(1);
+
+ typval_T tv_str = {
+ .v_type = VAR_STRING,
+ .vval.v_string = xstrdup(str),
+ };
+ tv_list_append_tv(l, &tv_str);
+
+ list_T *retlist = tv_list_alloc(3);
+ list_T *match_str_list = tv_list_alloc(1);
+ list_T *match_pos_list = tv_list_alloc(1);
+ list_T *match_score_list = tv_list_alloc(1);
+
+ tv_list_append_list(retlist, match_str_list);
+ tv_list_append_list(retlist, match_pos_list);
+ tv_list_append_list(retlist, match_score_list);
+
+ fuzzy_match_in_list(l, pat, false, NULL, NULL, true, retlist, 1);
+
+ varnumber_T score = 0;
+ listitem_T *score_item = tv_list_find(retlist, 2);
+ if (score_item != NULL && TV_LIST_ITEM_TV(score_item)->v_type == VAR_LIST) {
+ list_T *score_list = TV_LIST_ITEM_TV(score_item)->vval.v_list;
+ if (tv_list_len(score_list) > 0) {
+ listitem_T *first_score_item = tv_list_first(score_list);
+ if (first_score_item != NULL && TV_LIST_ITEM_TV(first_score_item)->v_type == VAR_NUMBER) {
+ score = TV_LIST_ITEM_TV(first_score_item)->vval.v_number;
+ }
+ }
+ }
+ if (score == 0) {
+ goto cleanup;
+ }
+
+ listitem_T *positions_item = tv_list_find(retlist, 1);
+ if (positions_item != NULL && TV_LIST_ITEM_TV(positions_item)->v_type == VAR_LIST) {
+ list_T *positions_outer_list = TV_LIST_ITEM_TV(positions_item)->vval.v_list;
+ if (tv_list_len(positions_outer_list) > 0) {
+ listitem_T *outer_li = tv_list_first(positions_outer_list);
+ if (outer_li != NULL && TV_LIST_ITEM_TV(outer_li)->v_type == VAR_LIST) {
+ list_T *positions_inner_list = TV_LIST_ITEM_TV(outer_li)->vval.v_list;
+ TV_LIST_ITER_CONST(positions_inner_list, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type == VAR_NUMBER) {
+ varnumber_T pos = TV_LIST_ITEM_TV(li)->vval.v_number;
+ GA_APPEND(int, match_positions, (int)pos);
+ }
+ });
+ }
+ }
+ }
+
+ xfree(tv_str.vval.v_string);
+ tv_list_free(retlist);
+ tv_list_free(l);
+ return match_positions;
+
+cleanup:
+ xfree(tv_str.vval.v_string);
+ tv_list_free(match_str_list);
+ tv_list_free(match_pos_list);
+ tv_list_free(match_score_list);
+ tv_list_free(retlist);
+ tv_list_free(l);
+ ga_clear(match_positions);
+ return NULL;
+}
+
/// Copy a list of fuzzy matches into a string list after sorting the matches by
/// the fuzzy score. Frees the memory allocated for "fuzmatch".
void fuzzymatches_to_strmatches(fuzmatch_str_T *const fuzmatch, char ***const matches,
diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua
index f7eb8394bd..619153724b 100644
--- a/test/functional/ui/cursor_spec.lua
+++ b/test/functional/ui/cursor_spec.lua
@@ -246,11 +246,11 @@ describe('ui/cursor', function()
end
end
if m.hl_id then
- m.hl_id = 64
+ m.hl_id = 66
m.attr = { background = Screen.colors.DarkGray }
end
if m.id_lm then
- m.id_lm = 71
+ m.id_lm = 73
end
end
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index cc21a797e3..0ce0fe4eab 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -1177,6 +1177,8 @@ describe('builtin popupmenu', function()
ks = { foreground = Screen.colors.Red, background = Screen.colors.Grey },
xn = { foreground = Screen.colors.White, background = Screen.colors.Magenta },
xs = { foreground = Screen.colors.Black, background = Screen.colors.Grey },
+ mn = { foreground = Screen.colors.Blue, background = Screen.colors.White },
+ ms = { foreground = Screen.colors.Green, background = Screen.colors.White },
})
screen:attach({ ext_multigrid = multigrid })
end)
@@ -4585,6 +4587,121 @@ describe('builtin popupmenu', function()
]])
end)
end)
+
+ -- oldtest: Test_pum_highlights_match()
+ it('can highlight matched text', function()
+ exec([[
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".")
+ endif
+ return {
+ \ 'words': [
+ \ { 'word': 'foo',},
+ \ { 'word': 'foobar',},
+ \ { 'word': 'fooBaz',},
+ \ { 'word': 'foobala',},
+ \ { 'word': '你好',},
+ \ { 'word': '你好吗',},
+ \ { 'word': '你不好吗',},
+ \ { 'word': '你可好吗',},
+ \]}
+ endfunc
+ set omnifunc=Omni_test
+ set completeopt=menu,noinsert,fuzzy
+ hi PmenuMatchSel guifg=Green guibg=White
+ hi PmenuMatch guifg=Blue guibg=White
+ ]])
+ feed('i<C-X><C-O>')
+ local pum_start = [[
+ ^ |
+ {s:foo }{1: }|
+ {n:foobar }{1: }|
+ {n:fooBaz }{1: }|
+ {n:foobala }{1: }|
+ {n:你好 }{1: }|
+ {n:你好吗 }{1: }|
+ {n:你不好吗 }{1: }|
+ {n:你可好吗 }{1: }|
+ {1:~ }|*10
+ {2:-- }{5:match 1 of 8} |
+ ]]
+ screen:expect(pum_start)
+ feed('fo')
+ screen:expect([[
+ fo^ |
+ {ms:fo}{s:o }{1: }|
+ {mn:fo}{n:obar }{1: }|
+ {mn:fo}{n:oBaz }{1: }|
+ {mn:fo}{n:obala }{1: }|
+ {1:~ }|*14
+ {2:-- }{5:match 1 of 8} |
+ ]])
+ feed('<Esc>S<C-X><C-O>')
+ screen:expect(pum_start)
+ feed('你')
+ screen:expect([[
+ 你^ |
+ {ms:你}{s:好 }{1: }|
+ {mn:你}{n:好吗 }{1: }|
+ {mn:你}{n:不好吗 }{1: }|
+ {mn:你}{n:可好吗 }{1: }|
+ {1:~ }|*14
+ {2:-- }{5:match 1 of 8} |
+ ]])
+ feed('吗')
+ screen:expect([[
+ 你吗^ |
+ {ms:你}{s:好}{ms:吗}{s: }{1: }|
+ {mn:你}{n:不好}{mn:吗}{n: }{1: }|
+ {mn:你}{n:可好}{mn:吗}{n: }{1: }|
+ {1:~ }|*15
+ {2:-- }{5:match 1 of 8} |
+ ]])
+
+ feed('<C-E><Esc>')
+ command('set rightleft')
+ feed('S<C-X><C-O>')
+ screen:expect([[
+ ^ |
+ {1: }{s: oof}|
+ {1: }{n: raboof}|
+ {1: }{n: zaBoof}|
+ {1: }{n: alaboof}|
+ {1: }{n: 好你}|
+ {1: }{n: 吗好你}|
+ {1: }{n: 吗好不你}|
+ {1: }{n: 吗好可你}|
+ {1: ~}|*10
+ {2:-- }{5:match 1 of 8} |
+ ]])
+ feed('fo')
+ screen:expect([[
+ ^ of|
+ {1: }{s: o}{ms:of}|
+ {1: }{n: rabo}{mn:of}|
+ {1: }{n: zaBo}{mn:of}|
+ {1: }{n: alabo}{mn:of}|
+ {1: ~}|*14
+ {2:-- }{5:match 1 of 8} |
+ ]])
+ feed('<C-E><Esc>')
+ command('set norightleft')
+
+ command('set completeopt-=fuzzy')
+ feed('S<C-X><C-O>')
+ screen:expect(pum_start)
+ feed('fo')
+ screen:expect([[
+ fo^ |
+ {ms:fo}{s:o }{1: }|
+ {mn:fo}{n:obar }{1: }|
+ {mn:fo}{n:oBaz }{1: }|
+ {mn:fo}{n:obala }{1: }|
+ {1:~ }|*14
+ {2:-- }{5:match 1 of 8} |
+ ]])
+ end)
end
end
diff --git a/test/old/testdir/test_popup.vim b/test/old/testdir/test_popup.vim
index 5ae2ed5ed5..acebcae1dd 100644
--- a/test/old/testdir/test_popup.vim
+++ b/test/old/testdir/test_popup.vim
@@ -1348,4 +1348,71 @@ func Test_pum_highlights_custom()
call StopVimInTerminal(buf)
endfunc
+" Test match relate highlight group in pmenu
+func Test_pum_highlights_match()
+ CheckScreendump
+ let lines =<< trim END
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".")
+ endif
+ return {
+ \ 'words': [
+ \ { 'word': 'foo',},
+ \ { 'word': 'foobar',},
+ \ { 'word': 'fooBaz',},
+ \ { 'word': 'foobala',},
+ \ { 'word': '你好',},
+ \ { 'word': '你好吗',},
+ \ { 'word': '你不好吗',},
+ \ { 'word': '你可好吗',},
+ \]}
+ endfunc
+ set omnifunc=Omni_test
+ set completeopt=menu,noinsert,fuzzy
+ hi PmenuMatchSel ctermfg=6 ctermbg=225
+ hi PmenuMatch ctermfg=4 ctermbg=225
+ END
+ call writefile(lines, 'Xscript', 'D')
+ let buf = RunVimInTerminal('-S Xscript', {})
+ call TermWait(buf)
+ call term_sendkeys(buf, "i\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "fo")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_03', {})
+ call term_sendkeys(buf, "\<ESC>S\<C-x>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "你")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_04', {})
+ call term_sendkeys(buf, "吗")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_05', {})
+
+ if has('rightleft')
+ call term_sendkeys(buf, "\<C-E>\<ESC>u:set rightleft\<CR>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "i\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "fo")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_06', {})
+ call term_sendkeys(buf, "\<C-E>\<ESC>u:set norightleft\<CR>")
+ call TermWait(buf)
+ endif
+
+ call term_sendkeys(buf, ":set completeopt-=fuzzy\<CR>")
+ call TermWait(buf)
+ call term_sendkeys(buf, "\<ESC>S\<C-x>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "fo")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_07', {})
+
+ call term_sendkeys(buf, "\<C-E>\<Esc>u")
+ call TermWait(buf)
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab