diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 14dfc583bc..2f219ecc11 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -175,7 +175,6 @@ static const char *highlight_init_both[] = { "default link PmenuKindSel PmenuSel", "default link PmenuSbar Pmenu", "default link PmenuBorder Pmenu", - "default link PmenuShadow FloatShadow", "default link PmenuShadowThrough FloatShadowThrough", "default link PreInsert Added", "default link ComplMatchIns NONE", @@ -382,6 +381,7 @@ static const char *highlight_init_light[] = { "OkMsg guifg=NvimDarkGreen ctermfg=2", "Pmenu guibg=NvimLightGrey3 cterm=reverse", "PmenuThumb guibg=NvimLightGrey4", + "PmenuShadow guibg=NvimLightGrey4 ctermbg=0 blend=100", "Question guifg=NvimDarkCyan ctermfg=6", "QuickFixLine guifg=NvimDarkCyan ctermfg=6", "RedrawDebugClear guibg=NvimLightYellow ctermfg=15 ctermbg=3", @@ -467,6 +467,7 @@ static const char *highlight_init_dark[] = { "OkMsg guifg=NvimLightGreen ctermfg=10", "Pmenu guibg=NvimDarkGrey3 cterm=reverse", "PmenuThumb guibg=NvimDarkGrey4", + "PmenuShadow guibg=NvimDarkGrey4 ctermbg=0 blend=100", "Question guifg=NvimLightCyan ctermfg=14", "QuickFixLine guifg=NvimLightCyan ctermfg=14", "RedrawDebugClear guibg=NvimDarkYellow ctermfg=0 ctermbg=11", diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index e68b38baf5..f182744631 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -599,18 +599,14 @@ void pum_redraw(void) extra_space = true; } } - if (pum_scrollbar > 0) { - grid_width++; - if (pum_rl) { - col_off++; - } - } - WinConfig fconfig = WIN_CONFIG_INIT; int border_width = pum_border_width(); + int border_attr = 0; + schar_T border_char = 0; + schar_T fill_char = schar_from_ascii(' '); + bool has_border = border_width > 0; // setup popup menu border if 'pumborder' option is set if (border_width > 0) { - fconfig.border = true; Error err = ERROR_INIT; if (!parse_winborder(&fconfig, p_pumborder, &err)) { if (ERROR_SET(&err)) { @@ -641,6 +637,17 @@ void pum_redraw(void) fconfig.border_attr[i] = attr; } api_clear_error(&err); + if (pum_scrollbar) { + border_char = schar_from_str(fconfig.border_chars[3]); + border_attr = fconfig.border_attr[3]; + } + } + + if (pum_scrollbar > 0 && !fconfig.border) { + grid_width++; + if (pum_rl) { + col_off++; + } } grid_assign_handle(&pum_grid); @@ -889,13 +896,10 @@ void pum_redraw(void) } if (pum_scrollbar > 0) { - if (pum_rl) { - grid_line_puts(col_off - pum_width, " ", 1, - i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll); - } else { - grid_line_puts(col_off + pum_width, " ", 1, - i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll); - } + bool thumb = i >= thumb_pos && i < thumb_pos + thumb_height; + int scrollbar_col = col_off + (pum_rl ? -pum_width : pum_width); + grid_line_put_schar(scrollbar_col, (has_border && !thumb) ? border_char : fill_char, + thumb ? attr_thumb : (has_border ? border_attr : attr_scroll)); } grid_line_flush(); row++; @@ -954,7 +958,10 @@ static void pum_preview_set_text(buf_T *buf, char *info, linenr_T *lnum, int *ma static void pum_adjust_info_position(win_T *wp, int width) { int border_width = pum_border_width(); - int col = pum_col + pum_width + pum_scrollbar + 1 + border_width; + int col = pum_col + pum_width + 1 + border_width; + if (border_width < 0) { + col += pum_scrollbar; + } // TODO(glepnir): support config align border by using completepopup // align menu int right_extra = Columns - col; diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 0fece8049e..8f93474839 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1064,6 +1064,7 @@ describe('builtin popupmenu', function() [113] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black }, [114] = { background = Screen.colors.Grey0, blend = 100 }, [115] = { background = Screen.colors.Grey0, blend = 80 }, + [116] = { blend = 100, background = Screen.colors.NvimLightGrey4 }, -- popup non-selected item n = { background = Screen.colors.Plum1 }, -- popup scrollbar knob @@ -8738,11 +8739,12 @@ describe('builtin popupmenu', function() before_each(function() screen:try_resize(30, 11) exec([[ + let g:list = [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}] funct Omni_test(findstart, base) if a:findstart return col(".") - 1 endif - return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}] + return g:list endfunc hi link PmenuBorder FloatBorder set omnifunc=Omni_test @@ -8992,9 +8994,9 @@ describe('builtin popupmenu', function() end end) - it('pum border on cmdline', function() + it("'pumborder' on cmdline and scrollbar rendering", function() command('set wildoptions=pum') - feed(':') + feed(':t') if multigrid then screen:expect({ grid = [[ @@ -9005,18 +9007,18 @@ describe('builtin popupmenu', function() | {1:~ }|*9 ## grid 3 - :!^ | + :t^ | ## grid 4 - ╭─────────────────╮| - │{12: ! }{c: }│| - │{n: # }{12: }│| - │{n: & }{12: }│| - │{n: < }{12: }│| - │{n: = }{12: }│| - │{n: > }{12: }│| - │{n: @ }{12: }│| - │{n: Next }{12: }│| - ╰─────────────────╯| + ╭────────────────╮| + │{12: t }{c: }| + │{n: tNext }│| + │{n: tab }│| + │{n: tabNext }│| + │{n: tabclose }│| + │{n: tabdo }│| + │{n: tabedit }│| + │{n: tabfind }│| + ╰────────────────╯| ]], win_pos = { [2] = { @@ -9053,17 +9055,50 @@ describe('builtin popupmenu', function() }) else screen:expect([[ - ╭─────────────────╮ | - │{12: ! }{c: }│{1: }| - │{n: # }{12: }│{1: }| - │{n: & }{12: }│{1: }| - │{n: < }{12: }│{1: }| - │{n: = }{12: }│{1: }| - │{n: > }{12: }│{1: }| - │{n: @ }{12: }│{1: }| - │{n: Next }{12: }│{1: }| - ╰─────────────────╯{1: }| - :!^ | + ╭────────────────╮ | + │{12: t }{c: }{1: }| + │{n: tNext }│{1: }| + │{n: tab }│{1: }| + │{n: tabNext }│{1: }| + │{n: tabclose }│{1: }| + │{n: tabdo }│{1: }| + │{n: tabedit }│{1: }| + │{n: tabfind }│{1: }| + ╰────────────────╯{1: }| + :t^ | + ]]) + end + + feed((''):rep(20)) + if not multigrid then + screen:expect([[ + ╭────────────────╮ | + │{n: tabs }│{1: }| + │{n: tag }│{1: }| + │{n: tags }│{1: }| + │{n: tcd }{c: }{1: }| + │{12: tchdir }│{1: }| + │{n: tcl }│{1: }| + │{n: tcldo }│{1: }| + │{n: tclfile }│{1: }| + ╰────────────────╯{1: }| + :tchdir^ | + ]]) + end + feed((''):rep(20)) + if not multigrid then + screen:expect([[ + ╭────────────────╮ | + │{12: t }{c: }{1: }| + │{n: tNext }│{1: }| + │{n: tab }│{1: }| + │{n: tabNext }│{1: }| + │{n: tabclose }│{1: }| + │{n: tabdo }│{1: }| + │{n: tabedit }│{1: }| + │{n: tabfind }│{1: }| + ╰────────────────╯{1: }| + :t^ | ]]) end end) @@ -9084,9 +9119,9 @@ describe('builtin popupmenu', function() ## grid 3 {5:-- }{6:match 1 of 3} | ## grid 4 - ╭────────────────╮| - │{12:one }{c: }│| - ╰────────────────╯| + ╭───────────────╮| + │{12:one }{c: }| + ╰───────────────╯| ]], win_pos = { [2] = { @@ -9124,9 +9159,9 @@ describe('builtin popupmenu', function() else screen:expect([[ one^ | - ╭────────────────╮{1: }| - │{12:one }{c: }│{1: }| - ╰────────────────╯{1: }| + ╭───────────────╮{1: }| + │{12:one }{c: }{1: }| + ╰───────────────╯{1: }| {1:~ }| {3:[No Name] [+] }| {5:-- }{6:match 1 of 3} | @@ -9167,9 +9202,9 @@ describe('builtin popupmenu', function() {n:1info}| ## grid 5 {12:one }{114: }| - {n:two }{115: }| - {n:three }{115: }| - {114: }{115: }| + {n:two }{116: }| + {n:three }{116: }| + {114: }{116: }| ]], win_pos = { [2] = { @@ -9225,9 +9260,9 @@ describe('builtin popupmenu', function() screen:expect([[ one^ | {12:one }{114: }{n:1info}{1: }| - {n:two }{115: }{1: }| - {n:three }{115: }{1: }| - {114: }{115: }{1: }| + {n:two }{116: }{1: }| + {n:three }{116: }{1: }| + {114: }{116: }{1: }| {1:~ }|*5 {5:-- }{6:match 1 of 3} | ]])