mirror of
https://github.com/neovim/neovim.git
synced 2025-11-09 12:05:14 +00:00
feat(ui): overlay scrollbar on 'pumborder' #36273
Problem: When pumborder is set, the scrollbar still occupies a column on the screen, wasting a 1 column of space. Solution: Render the scrollbar on the right/left (rl mode) side of the border when pumborder is set.
This commit is contained in:
@@ -175,7 +175,6 @@ static const char *highlight_init_both[] = {
|
|||||||
"default link PmenuKindSel PmenuSel",
|
"default link PmenuKindSel PmenuSel",
|
||||||
"default link PmenuSbar Pmenu",
|
"default link PmenuSbar Pmenu",
|
||||||
"default link PmenuBorder Pmenu",
|
"default link PmenuBorder Pmenu",
|
||||||
"default link PmenuShadow FloatShadow",
|
|
||||||
"default link PmenuShadowThrough FloatShadowThrough",
|
"default link PmenuShadowThrough FloatShadowThrough",
|
||||||
"default link PreInsert Added",
|
"default link PreInsert Added",
|
||||||
"default link ComplMatchIns NONE",
|
"default link ComplMatchIns NONE",
|
||||||
@@ -382,6 +381,7 @@ static const char *highlight_init_light[] = {
|
|||||||
"OkMsg guifg=NvimDarkGreen ctermfg=2",
|
"OkMsg guifg=NvimDarkGreen ctermfg=2",
|
||||||
"Pmenu guibg=NvimLightGrey3 cterm=reverse",
|
"Pmenu guibg=NvimLightGrey3 cterm=reverse",
|
||||||
"PmenuThumb guibg=NvimLightGrey4",
|
"PmenuThumb guibg=NvimLightGrey4",
|
||||||
|
"PmenuShadow guibg=NvimLightGrey4 ctermbg=0 blend=100",
|
||||||
"Question guifg=NvimDarkCyan ctermfg=6",
|
"Question guifg=NvimDarkCyan ctermfg=6",
|
||||||
"QuickFixLine guifg=NvimDarkCyan ctermfg=6",
|
"QuickFixLine guifg=NvimDarkCyan ctermfg=6",
|
||||||
"RedrawDebugClear guibg=NvimLightYellow ctermfg=15 ctermbg=3",
|
"RedrawDebugClear guibg=NvimLightYellow ctermfg=15 ctermbg=3",
|
||||||
@@ -467,6 +467,7 @@ static const char *highlight_init_dark[] = {
|
|||||||
"OkMsg guifg=NvimLightGreen ctermfg=10",
|
"OkMsg guifg=NvimLightGreen ctermfg=10",
|
||||||
"Pmenu guibg=NvimDarkGrey3 cterm=reverse",
|
"Pmenu guibg=NvimDarkGrey3 cterm=reverse",
|
||||||
"PmenuThumb guibg=NvimDarkGrey4",
|
"PmenuThumb guibg=NvimDarkGrey4",
|
||||||
|
"PmenuShadow guibg=NvimDarkGrey4 ctermbg=0 blend=100",
|
||||||
"Question guifg=NvimLightCyan ctermfg=14",
|
"Question guifg=NvimLightCyan ctermfg=14",
|
||||||
"QuickFixLine guifg=NvimLightCyan ctermfg=14",
|
"QuickFixLine guifg=NvimLightCyan ctermfg=14",
|
||||||
"RedrawDebugClear guibg=NvimDarkYellow ctermfg=0 ctermbg=11",
|
"RedrawDebugClear guibg=NvimDarkYellow ctermfg=0 ctermbg=11",
|
||||||
|
|||||||
@@ -599,18 +599,14 @@ void pum_redraw(void)
|
|||||||
extra_space = true;
|
extra_space = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pum_scrollbar > 0) {
|
|
||||||
grid_width++;
|
|
||||||
if (pum_rl) {
|
|
||||||
col_off++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WinConfig fconfig = WIN_CONFIG_INIT;
|
WinConfig fconfig = WIN_CONFIG_INIT;
|
||||||
int border_width = pum_border_width();
|
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
|
// setup popup menu border if 'pumborder' option is set
|
||||||
if (border_width > 0) {
|
if (border_width > 0) {
|
||||||
fconfig.border = true;
|
|
||||||
Error err = ERROR_INIT;
|
Error err = ERROR_INIT;
|
||||||
if (!parse_winborder(&fconfig, p_pumborder, &err)) {
|
if (!parse_winborder(&fconfig, p_pumborder, &err)) {
|
||||||
if (ERROR_SET(&err)) {
|
if (ERROR_SET(&err)) {
|
||||||
@@ -641,6 +637,17 @@ void pum_redraw(void)
|
|||||||
fconfig.border_attr[i] = attr;
|
fconfig.border_attr[i] = attr;
|
||||||
}
|
}
|
||||||
api_clear_error(&err);
|
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);
|
grid_assign_handle(&pum_grid);
|
||||||
|
|
||||||
@@ -889,13 +896,10 @@ void pum_redraw(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pum_scrollbar > 0) {
|
if (pum_scrollbar > 0) {
|
||||||
if (pum_rl) {
|
bool thumb = i >= thumb_pos && i < thumb_pos + thumb_height;
|
||||||
grid_line_puts(col_off - pum_width, " ", 1,
|
int scrollbar_col = col_off + (pum_rl ? -pum_width : pum_width);
|
||||||
i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll);
|
grid_line_put_schar(scrollbar_col, (has_border && !thumb) ? border_char : fill_char,
|
||||||
} else {
|
thumb ? attr_thumb : (has_border ? border_attr : attr_scroll));
|
||||||
grid_line_puts(col_off + pum_width, " ", 1,
|
|
||||||
i >= thumb_pos && i < thumb_pos + thumb_height ? attr_thumb : attr_scroll);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
grid_line_flush();
|
grid_line_flush();
|
||||||
row++;
|
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)
|
static void pum_adjust_info_position(win_T *wp, int width)
|
||||||
{
|
{
|
||||||
int border_width = pum_border_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
|
// TODO(glepnir): support config align border by using completepopup
|
||||||
// align menu
|
// align menu
|
||||||
int right_extra = Columns - col;
|
int right_extra = Columns - col;
|
||||||
|
|||||||
@@ -1064,6 +1064,7 @@ describe('builtin popupmenu', function()
|
|||||||
[113] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black },
|
[113] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black },
|
||||||
[114] = { background = Screen.colors.Grey0, blend = 100 },
|
[114] = { background = Screen.colors.Grey0, blend = 100 },
|
||||||
[115] = { background = Screen.colors.Grey0, blend = 80 },
|
[115] = { background = Screen.colors.Grey0, blend = 80 },
|
||||||
|
[116] = { blend = 100, background = Screen.colors.NvimLightGrey4 },
|
||||||
-- popup non-selected item
|
-- popup non-selected item
|
||||||
n = { background = Screen.colors.Plum1 },
|
n = { background = Screen.colors.Plum1 },
|
||||||
-- popup scrollbar knob
|
-- popup scrollbar knob
|
||||||
@@ -8738,11 +8739,12 @@ describe('builtin popupmenu', function()
|
|||||||
before_each(function()
|
before_each(function()
|
||||||
screen:try_resize(30, 11)
|
screen:try_resize(30, 11)
|
||||||
exec([[
|
exec([[
|
||||||
|
let g:list = [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}]
|
||||||
funct Omni_test(findstart, base)
|
funct Omni_test(findstart, base)
|
||||||
if a:findstart
|
if a:findstart
|
||||||
return col(".") - 1
|
return col(".") - 1
|
||||||
endif
|
endif
|
||||||
return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}]
|
return g:list
|
||||||
endfunc
|
endfunc
|
||||||
hi link PmenuBorder FloatBorder
|
hi link PmenuBorder FloatBorder
|
||||||
set omnifunc=Omni_test
|
set omnifunc=Omni_test
|
||||||
@@ -8992,9 +8994,9 @@ describe('builtin popupmenu', function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('pum border on cmdline', function()
|
it("'pumborder' on cmdline and scrollbar rendering", function()
|
||||||
command('set wildoptions=pum')
|
command('set wildoptions=pum')
|
||||||
feed(':<TAB>')
|
feed(':t<TAB>')
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect({
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
@@ -9005,18 +9007,18 @@ describe('builtin popupmenu', function()
|
|||||||
|
|
|
|
||||||
{1:~ }|*9
|
{1:~ }|*9
|
||||||
## grid 3
|
## grid 3
|
||||||
:!^ |
|
:t^ |
|
||||||
## grid 4
|
## grid 4
|
||||||
╭─────────────────╮|
|
╭────────────────╮|
|
||||||
│{12: ! }{c: }│|
|
│{12: t }{c: }|
|
||||||
│{n: # }{12: }│|
|
│{n: tNext }│|
|
||||||
│{n: & }{12: }│|
|
│{n: tab }│|
|
||||||
│{n: < }{12: }│|
|
│{n: tabNext }│|
|
||||||
│{n: = }{12: }│|
|
│{n: tabclose }│|
|
||||||
│{n: > }{12: }│|
|
│{n: tabdo }│|
|
||||||
│{n: @ }{12: }│|
|
│{n: tabedit }│|
|
||||||
│{n: Next }{12: }│|
|
│{n: tabfind }│|
|
||||||
╰─────────────────╯|
|
╰────────────────╯|
|
||||||
]],
|
]],
|
||||||
win_pos = {
|
win_pos = {
|
||||||
[2] = {
|
[2] = {
|
||||||
@@ -9053,17 +9055,50 @@ describe('builtin popupmenu', function()
|
|||||||
})
|
})
|
||||||
else
|
else
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
╭─────────────────╮ |
|
╭────────────────╮ |
|
||||||
│{12: ! }{c: }│{1: }|
|
│{12: t }{c: }{1: }|
|
||||||
│{n: # }{12: }│{1: }|
|
│{n: tNext }│{1: }|
|
||||||
│{n: & }{12: }│{1: }|
|
│{n: tab }│{1: }|
|
||||||
│{n: < }{12: }│{1: }|
|
│{n: tabNext }│{1: }|
|
||||||
│{n: = }{12: }│{1: }|
|
│{n: tabclose }│{1: }|
|
||||||
│{n: > }{12: }│{1: }|
|
│{n: tabdo }│{1: }|
|
||||||
│{n: @ }{12: }│{1: }|
|
│{n: tabedit }│{1: }|
|
||||||
│{n: Next }{12: }│{1: }|
|
│{n: tabfind }│{1: }|
|
||||||
╰─────────────────╯{1: }|
|
╰────────────────╯{1: }|
|
||||||
:!^ |
|
:t^ |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
|
||||||
|
feed(('<C-N>'):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(('<C-P>'):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
|
||||||
end)
|
end)
|
||||||
@@ -9084,9 +9119,9 @@ describe('builtin popupmenu', function()
|
|||||||
## grid 3
|
## grid 3
|
||||||
{5:-- }{6:match 1 of 3} |
|
{5:-- }{6:match 1 of 3} |
|
||||||
## grid 4
|
## grid 4
|
||||||
╭────────────────╮|
|
╭───────────────╮|
|
||||||
│{12:one }{c: }│|
|
│{12:one }{c: }|
|
||||||
╰────────────────╯|
|
╰───────────────╯|
|
||||||
]],
|
]],
|
||||||
win_pos = {
|
win_pos = {
|
||||||
[2] = {
|
[2] = {
|
||||||
@@ -9124,9 +9159,9 @@ describe('builtin popupmenu', function()
|
|||||||
else
|
else
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
one^ |
|
one^ |
|
||||||
╭────────────────╮{1: }|
|
╭───────────────╮{1: }|
|
||||||
│{12:one }{c: }│{1: }|
|
│{12:one }{c: }{1: }|
|
||||||
╰────────────────╯{1: }|
|
╰───────────────╯{1: }|
|
||||||
{1:~ }|
|
{1:~ }|
|
||||||
{3:[No Name] [+] }|
|
{3:[No Name] [+] }|
|
||||||
{5:-- }{6:match 1 of 3} |
|
{5:-- }{6:match 1 of 3} |
|
||||||
@@ -9167,9 +9202,9 @@ describe('builtin popupmenu', function()
|
|||||||
{n:1info}|
|
{n:1info}|
|
||||||
## grid 5
|
## grid 5
|
||||||
{12:one }{114: }|
|
{12:one }{114: }|
|
||||||
{n:two }{115: }|
|
{n:two }{116: }|
|
||||||
{n:three }{115: }|
|
{n:three }{116: }|
|
||||||
{114: }{115: }|
|
{114: }{116: }|
|
||||||
]],
|
]],
|
||||||
win_pos = {
|
win_pos = {
|
||||||
[2] = {
|
[2] = {
|
||||||
@@ -9225,9 +9260,9 @@ describe('builtin popupmenu', function()
|
|||||||
screen:expect([[
|
screen:expect([[
|
||||||
one^ |
|
one^ |
|
||||||
{12:one }{114: }{n:1info}{1: }|
|
{12:one }{114: }{n:1info}{1: }|
|
||||||
{n:two }{115: }{1: }|
|
{n:two }{116: }{1: }|
|
||||||
{n:three }{115: }{1: }|
|
{n:three }{116: }{1: }|
|
||||||
{114: }{115: }{1: }|
|
{114: }{116: }{1: }|
|
||||||
{1:~ }|*5
|
{1:~ }|*5
|
||||||
{5:-- }{6:match 1 of 3} |
|
{5:-- }{6:match 1 of 3} |
|
||||||
]])
|
]])
|
||||||
|
|||||||
Reference in New Issue
Block a user