Skip to content

Commit

Permalink
feat(completion): add text matched highlight in candidate words
Browse files Browse the repository at this point in the history
  • Loading branch information
glepnir committed May 1, 2024
1 parent 83d3b3b commit 09d8f9c
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/highlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ static char *(highlight_init_both[]) = {
"default link CursorLineFold FoldColumn",
"default link CurSearch Search",
"default link PmenuKind Pmenu",
"default link PmenuMatch Pmenu",
"default link PmenuMatchSel PmenuSel",
"default link PmenuKindSel PmenuSel",
"default link PmenuExtra Pmenu",
"default link PmenuExtraSel PmenuSel",
Expand Down
9 changes: 9 additions & 0 deletions src/insexpand.c
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,15 @@ ins_compl_show_pum(void)
#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_u *
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.
Expand Down
2 changes: 1 addition & 1 deletion src/optiondefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ struct vimoption
# define ISP_LATIN1 (char_u *)"@,161-255"
#endif

# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@: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,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea"
# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@: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,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"

// Default python version for pyx* commands
#if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
Expand Down
44 changes: 41 additions & 3 deletions src/popupmenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,44 @@ pum_under_menu(int row, int col, int only_redrawing)
&& col < pum_col + pum_width + pum_scrollbar;
}

/*
* displays text on the popup menu with specific attributes.
*/
static void
pum_screen_put_with_attr(int row, int col, char_u *text, int textlen, int attr)
{
int i;
int match_start = 0;
int match_end = 0;
char_u *leader = ins_compl_leader();
char_u *rt_leader = NULL;
char_u *match_leader = NULL;
int is_select = attr == highlight_attr[HLF_PSI];

#ifdef FEAT_RIGHTLEFT
if (leader != NULL && curwin->w_p_rl)
rt_leader = reverse_text(leader);

Check warning on line 435 in src/popupmenu.c

View check run for this annotation

Codecov / codecov/patch

src/popupmenu.c#L435

Added line #L435 was not covered by tests
#endif
match_leader = rt_leader != NULL ? rt_leader : leader;
if (match_leader != NULL)
{
char *result = strstr((char *)text, (char *)match_leader);
match_start = (int)(result - (char *)text);
match_end = match_start + (int)STRLEN(match_leader);
}

for (i = 0; i < textlen; i++)
{
int new_attr = attr;
if (match_end > 0 && i >= match_start && i < match_end)
new_attr = highlight_attr[(is_select ? HLF_PMSI : HLF_PMNI)];
screen_putchar(text[i], row, col, new_attr);
col++;
}
if (rt_leader)
vim_free(rt_leader);

Check warning on line 454 in src/popupmenu.c

View check run for this annotation

Codecov / codecov/patch

src/popupmenu.c#L454

Added line #L454 was not covered by tests
}

/*
* Redraw the popup menu, using "pum_first" and "pum_selected".
*/
Expand Down Expand Up @@ -567,8 +605,7 @@ pum_redraw(void)
size++;
}
}
screen_puts_len(rt, (int)STRLEN(rt),
row, col - size + 1, attr);
pum_screen_put_with_attr(row, col -size + 1, rt, (int)STRLEN(rt), attr);
vim_free(rt_start);
}
vim_free(st);
Expand Down Expand Up @@ -596,7 +633,8 @@ pum_redraw(void)
else
--cells;
}
screen_puts_len(st, size, row, col, attr);
pum_screen_put_with_attr(row, col, st, size, attr);
//screen_puts_len(st, size, row, col, attr);
vim_free(st);
}
col += width;
Expand Down
1 change: 1 addition & 0 deletions src/proto/insexpand.pro
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ int ins_compl_long_shown_match(void);
void completeopt_was_set(void);
int pum_wanted(void);
void ins_compl_show_pum(void);
char_u *ins_compl_leader(void);
char_u *find_word_start(char_u *ptr);
char_u *find_word_end(char_u *ptr);
void ins_compl_clear(void);
Expand Down
20 changes: 20 additions & 0 deletions src/testdir/dumps/Test_pum_highlights_03.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
|f+0&#ffffff0> @73
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|2| @10|A|l@1|
26 changes: 26 additions & 0 deletions src/testdir/test_popup.vim
Original file line number Diff line number Diff line change
Expand Up @@ -1339,4 +1339,30 @@ 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 [#{word: "fit"}, #{word: "five"}, #{word: "first"}]
endfunc
set omnifunc=Omni_test
set completeopt=menu,menuone
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>\<BS>\<BS>\<BS>f")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_pum_highlights_03', {})
call term_sendkeys(buf, "\<C-E>\<Esc>u")
call TermWait(buf)
call StopVimInTerminal(buf)
endfunc

" vim: shiftwidth=2 sts=2 expandtab
4 changes: 3 additions & 1 deletion src/vim.h
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,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 mathced 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)
Expand All @@ -1525,7 +1527,7 @@ typedef enum
'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', 't', 'v', 'V', \
'w', 'W', 'f', 'F', 'A', 'C', 'D', 'T', '-', '>', \
'B', 'P', 'R', 'L', \
'+', '=', '[', ']', '{', '}', 'x', 'X', \
'+', '=', 'k', '<','[', ']', '{', '}', 'x', 'X', \
'*', '#', '_', '!', '.', 'o', 'q', \
'z', 'Z', 'g'}

Expand Down

0 comments on commit 09d8f9c

Please sign in to comment.