Merge #8913 'popupmenu placement'

close #8913
This commit is contained in:
Justin M. Keyes 2018-09-13 00:28:04 +02:00
commit 656648d855
5 changed files with 367 additions and 195 deletions

View File

@ -81,7 +81,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed)
pum_external = ui_is_external(kUIPopupmenu); pum_external = ui_is_external(kUIPopupmenu);
} }
redo: do {
// Mark the pum as visible already here, // Mark the pum as visible already here,
// to avoid that must_redraw is set when 'cursorcolumn' is on. // to avoid that must_redraw is set when 'cursorcolumn' is on.
pum_is_visible = true; pum_is_visible = true;
@ -129,10 +129,10 @@ redo:
} }
if (pvwin != NULL) { if (pvwin != NULL) {
if (pvwin->w_wrow < curwin->w_wrow) { if (pvwin->w_winrow < curwin->w_winrow) {
above_row = pvwin->w_wrow + pvwin->w_height; above_row = pvwin->w_winrow + pvwin->w_height;
} else if (pvwin->w_wrow > pvwin->w_wrow + curwin->w_height) { } else if (pvwin->w_winrow > curwin->w_winrow + curwin->w_height) {
below_row = pvwin->w_wrow; below_row = pvwin->w_winrow;
} }
} }
@ -200,14 +200,14 @@ redo:
return; return;
} }
// If there is a preview window at the above avoid drawing over it. // If there is a preview window above, avoid drawing over it.
if (pvwin != NULL && pum_row < above_row && pum_height > above_row) { if (pvwin != NULL && pum_row < above_row && pum_height > above_row) {
pum_row += above_row; pum_row += above_row;
pum_height -= above_row; pum_height -= above_row;
} }
// Compute the width of the widest match and the widest extra. // Compute the width of the widest match and the widest extra.
for (i = 0; i < size; ++i) { for (i = 0; i < size; i++) {
w = vim_strsize(array[i].pum_text); w = vim_strsize(array[i].pum_text);
if (max_width < w) { if (max_width < w) {
@ -285,7 +285,8 @@ redo:
if (curwin->w_p_rl) { if (curwin->w_p_rl) {
pum_col = max_width - 1; pum_col = max_width - 1;
} else { } else {
assert(Columns - max_width >= INT_MIN && Columns - max_width <= INT_MAX); assert(Columns - max_width >= INT_MIN
&& Columns - max_width <= INT_MAX);
pum_col = (int)(Columns - max_width); pum_col = (int)(Columns - max_width);
} }
pum_width = max_width - pum_scrollbar; pum_width = max_width - pum_scrollbar;
@ -297,9 +298,7 @@ redo:
// Set selected item and redraw. If the window size changed need to redo // Set selected item and redraw. If the window size changed need to redo
// the positioning. Limit this to two times, when there is not much // the positioning. Limit this to two times, when there is not much
// room the window size will keep changing. // room the window size will keep changing.
if (pum_set_selected(selected, redo_count) && (++redo_count <= 2)) { } while (pum_set_selected(selected, redo_count) && (++redo_count <= 2));
goto redo;
}
} }
/// Redraw the popup menu, using "pum_first" and "pum_selected". /// Redraw the popup menu, using "pum_first" and "pum_selected".

View File

@ -7090,14 +7090,15 @@ void screen_resize(int width, int height)
update_topline(); update_topline();
if (pum_drawn()) { if (pum_drawn()) {
redraw_later(NOT_VALID); redraw_later(NOT_VALID);
ins_compl_show_pum(); /* This includes the redraw. */ ins_compl_show_pum();
} else }
update_screen(NOT_VALID); update_screen(NOT_VALID);
if (redrawing()) if (redrawing()) {
setcursor(); setcursor();
} }
} }
} }
}
ui_flush(); ui_flush();
--busy; --busy;
} }

View File

@ -1,5 +1,10 @@
" Functions shared by several tests. " Functions shared by several tests.
" Only load this script once.
if exists('*WaitFor')
finish
endif
" {Nvim} " {Nvim}
" Filepath captured from output may be truncated, like this: " Filepath captured from output may be truncated, like this:
" /home/va...estdir/Xtest-tmpdir/nvimxbXN4i/10 " /home/va...estdir/Xtest-tmpdir/nvimxbXN4i/10

View File

@ -1,5 +1,7 @@
" Test for completion menu " Test for completion menu
source shared.vim
let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
let g:setting = '' let g:setting = ''
@ -665,4 +667,30 @@ func Test_complete_CTRLN_startofbuffer()
bwipe! bwipe!
endfunc endfunc
func Test_popup_and_window_resize()
if !has('terminal') || has('gui_running')
return
endif
let h = winheight(0)
if h < 15
return
endif
let g:buf = term_start([$NVIM_PRG, '--clean', '-c', 'set noswapfile'], {'term_rows': h / 3})
call term_sendkeys(g:buf, (h / 3 - 1)."o\<esc>G")
call term_sendkeys(g:buf, "i\<c-x>")
call term_wait(g:buf, 100)
call term_sendkeys(g:buf, "\<c-v>")
call term_wait(g:buf, 100)
call assert_match('^!\s*$', term_getline(g:buf, 1))
exe 'resize +' . (h - 1)
call term_wait(g:buf, 100)
redraw!
call WaitFor('"" == term_getline(g:buf, 1)')
call assert_equal('', term_getline(g:buf, 1))
sleep 100m
call WaitFor('"^!" =~ term_getline(g:buf, term_getcursor(g:buf)[0] + 1)')
call assert_match('^!\s*$', term_getline(g:buf, term_getcursor(g:buf)[0] + 1))
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -12,6 +12,9 @@ describe('ui/ext_popupmenu', function()
screen:set_default_attr_ids({ screen:set_default_attr_ids({
[1] = {bold=true, foreground=Screen.colors.Blue}, [1] = {bold=true, foreground=Screen.colors.Blue},
[2] = {bold = true}, [2] = {bold = true},
[3] = {reverse = true},
[4] = {bold = true, reverse = true},
[5] = {bold = true, foreground = Screen.colors.SeaGreen}
}) })
end) end)
@ -89,3 +92,139 @@ describe('ui/ext_popupmenu', function()
]]} ]]}
end) end)
end) end)
describe('popup placement', function()
local screen
before_each(function()
clear()
screen = Screen.new(32, 20)
screen:attach()
screen:set_default_attr_ids({
-- popup selected item / scrollbar track
['s'] = {background = Screen.colors.WebGray},
-- popup non-selected item
['n'] = {background = Screen.colors.LightMagenta},
-- popup scrollbar knob
['c'] = {background = Screen.colors.Grey0},
[1] = {bold = true, foreground = Screen.colors.Blue},
[2] = {bold = true},
[3] = {reverse = true},
[4] = {bold = true, reverse = true},
[5] = {bold = true, foreground = Screen.colors.SeaGreen}
})
end)
it('works with preview-window above', function()
feed(':ped<CR><c-w>4+')
feed('iaa bb cc dd ee ff gg hh ii jj<cr>')
feed('<c-x><c-n>')
screen:expect([[
aa bb cc dd ee ff gg hh ii jj |
aa |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{3:[No Name] [Preview][+] }|
aa bb cc dd ee ff gg hh ii jj |
aa^ |
{s:aa }{c: }{1: }|
{n:bb }{c: }{1: }|
{n:cc }{c: }{1: }|
{n:dd }{c: }{1: }|
{n:ee }{c: }{1: }|
{n:ff }{c: }{1: }|
{n:gg }{s: }{1: }|
{n:hh }{s: }{4: }|
{2:-- }{5:match 1 of 10} |
]])
end)
it('works with preview-window below', function()
feed(':ped<CR><c-w>4+<c-w>r')
feed('iaa bb cc dd ee ff gg hh ii jj<cr>')
feed('<c-x><c-n>')
screen:expect([[
aa bb cc dd ee ff gg hh ii jj |
aa^ |
{s:aa }{c: }{1: }|
{n:bb }{c: }{1: }|
{n:cc }{c: }{1: }|
{n:dd }{c: }{1: }|
{n:ee }{c: }{1: }|
{n:ff }{c: }{1: }|
{n:gg }{s: }{1: }|
{n:hh }{s: }{4: }|
aa bb cc dd ee ff gg hh ii jj |
aa |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{3:[No Name] [Preview][+] }|
{2:-- }{5:match 1 of 10} |
]])
end)
it('works with preview-window above and inverted', function()
feed(':ped<CR><c-w>4+')
feed('iaa<cr>bb<cr>cc<cr>dd<cr>ee<cr>')
feed('ff<cr>gg<cr>hh<cr>ii<cr>jj<cr>')
feed('<c-x><c-n>')
screen:expect([[
aa |
bb |
cc |
dd |
ee |
ff |
gg |
hh |
{3:[No Name] [Preview][+] }|
cc |
dd |
ee |
ff |
gg |
hh |
{s:aa }{c: } |
{n:bb }{s: } |
aa^ |
{4:[No Name] [+] }|
{2:-- }{5:match 1 of 10} |
]])
end)
it('works with preview-window below and inverted', function()
feed(':ped<CR><c-w>4+<c-w>r')
feed('iaa<cr>bb<cr>cc<cr>dd<cr>ee<cr>')
feed('ff<cr>gg<cr>hh<cr>ii<cr>jj<cr>')
feed('<c-x><c-n>')
screen:expect([[
{s:aa }{c: } |
{n:bb }{c: } |
{n:cc }{c: } |
{n:dd }{c: } |
{n:ee }{c: } |
{n:ff }{c: } |
{n:gg }{s: } |
{n:hh }{s: } |
aa^ |
{4:[No Name] [+] }|
aa |
bb |
cc |
dd |
ee |
ff |
gg |
hh |
{3:[No Name] [Preview][+] }|
{2:-- }{5:match 1 of 10} |
]])
end)
end)