vim-patch:8.0.1161

This commit is contained in:
rpigott 2018-08-25 22:00:26 -07:00 committed by Justin M. Keyes
parent 26b2c1fe15
commit a5fe6d34a9
4 changed files with 228 additions and 195 deletions

View File

@ -81,225 +81,224 @@ 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;
validate_cursor_col(); validate_cursor_col();
above_row = 0; above_row = 0;
below_row = cmdline_row; below_row = cmdline_row;
// anchor position: the start of the completed word // anchor position: the start of the completed word
row = curwin->w_wrow + curwin->w_winrow; row = curwin->w_wrow + curwin->w_winrow;
if (curwin->w_p_rl) { if (curwin->w_p_rl) {
col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1; col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1;
} else { } else {
col = curwin->w_wincol + curwin->w_wcol; col = curwin->w_wincol + curwin->w_wcol;
} }
if (pum_external) { if (pum_external) {
if (array_changed) { if (array_changed) {
Array arr = ARRAY_DICT_INIT; Array arr = ARRAY_DICT_INIT;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
Array item = ARRAY_DICT_INIT; Array item = ARRAY_DICT_INIT;
ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_text))); ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_text)));
ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_kind))); ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_kind)));
ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_extra))); ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_extra)));
ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info))); ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info)));
ADD(arr, ARRAY_OBJ(item)); ADD(arr, ARRAY_OBJ(item));
}
ui_call_popupmenu_show(arr, selected, row, col);
} else {
ui_call_popupmenu_select(selected);
} }
ui_call_popupmenu_show(arr, selected, row, col); return;
} else {
ui_call_popupmenu_select(selected);
}
return;
}
def_width = PUM_DEF_WIDTH;
max_width = 0;
kind_width = 0;
extra_width = 0;
win_T *pvwin = NULL;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_p_pvw) {
pvwin = wp;
break;
}
}
if (pvwin != NULL) {
if (pvwin->w_winrow < curwin->w_winrow) {
above_row = pvwin->w_winrow + pvwin->w_height;
} else if (pvwin->w_winrow > curwin->w_winrow + curwin->w_height) {
below_row = pvwin->w_winrow;
}
}
// Figure out the size and position of the pum.
if (size < PUM_DEF_HEIGHT) {
pum_height = size;
} else {
pum_height = PUM_DEF_HEIGHT;
}
if ((p_ph > 0) && (pum_height > p_ph)) {
pum_height = (int)p_ph;
}
// Put the pum below "row" if possible. If there are few lines decide on
// where there is more room.
if (row + 2 >= below_row - pum_height
&& row - above_row > (below_row - above_row) / 2) {
// pum above "row"
// Leave two lines of context if possible
if (curwin->w_wrow - curwin->w_cline_row >= 2) {
context_lines = 2;
} else {
context_lines = curwin->w_wrow - curwin->w_cline_row;
} }
if (row >= size + context_lines) { def_width = PUM_DEF_WIDTH;
pum_row = row - size - context_lines; max_width = 0;
kind_width = 0;
extra_width = 0;
win_T *pvwin = NULL;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_p_pvw) {
pvwin = wp;
break;
}
}
if (pvwin != NULL) {
if (pvwin->w_winrow < curwin->w_winrow) {
above_row = pvwin->w_winrow + pvwin->w_height;
} else if (pvwin->w_winrow > curwin->w_winrow + curwin->w_height) {
below_row = pvwin->w_winrow;
}
}
// Figure out the size and position of the pum.
if (size < PUM_DEF_HEIGHT) {
pum_height = size; pum_height = size;
} else { } else {
pum_row = 0; pum_height = PUM_DEF_HEIGHT;
pum_height = row - context_lines;
}
if ((p_ph > 0) && (pum_height > p_ph)) {
pum_row += pum_height - (int)p_ph;
pum_height = (int)p_ph;
}
} else {
// pum below "row"
// Leave two lines of context if possible
if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) {
context_lines = 3;
} else {
context_lines = curwin->w_cline_row
+ curwin->w_cline_height - curwin->w_wrow;
}
pum_row = row + context_lines;
if (size > below_row - pum_row) {
pum_height = below_row - pum_row;
} else {
pum_height = size;
} }
if ((p_ph > 0) && (pum_height > p_ph)) { if ((p_ph > 0) && (pum_height > p_ph)) {
pum_height = (int)p_ph; pum_height = (int)p_ph;
} }
}
// don't display when we only have room for one line // Put the pum below "row" if possible. If there are few lines decide on
if ((pum_height < 1) || ((pum_height == 1) && (size > 1))) { // where there is more room.
return; if (row + 2 >= below_row - pum_height
} && row - above_row > (below_row - above_row) / 2) {
// pum above "row"
// If there is a preview window at the above avoid drawing over it. // Leave two lines of context if possible
if (pvwin != NULL && pum_row < above_row && pum_height > above_row) { if (curwin->w_wrow - curwin->w_cline_row >= 2) {
pum_row += above_row; context_lines = 2;
pum_height -= above_row; } else {
} context_lines = curwin->w_wrow - curwin->w_cline_row;
// Compute the width of the widest match and the widest extra.
for (i = 0; i < size; ++i) {
w = vim_strsize(array[i].pum_text);
if (max_width < w) {
max_width = w;
}
if (array[i].pum_kind != NULL) {
w = vim_strsize(array[i].pum_kind) + 1;
if (kind_width < w) {
kind_width = w;
} }
}
if (array[i].pum_extra != NULL) { if (row >= size + context_lines) {
w = vim_strsize(array[i].pum_extra) + 1; pum_row = row - size - context_lines;
pum_height = size;
if (extra_width < w) { } else {
extra_width = w; pum_row = 0;
pum_height = row - context_lines;
} }
}
}
pum_base_width = max_width;
pum_kind_width = kind_width;
// if there are more items than room we need a scrollbar if ((p_ph > 0) && (pum_height > p_ph)) {
if (pum_height < size) { pum_row += pum_height - (int)p_ph;
pum_scrollbar = 1; pum_height = (int)p_ph;
max_width++; }
} else {
pum_scrollbar = 0;
}
if (def_width < max_width) {
def_width = max_width;
}
if ((((col < Columns - PUM_DEF_WIDTH) || (col < Columns - max_width))
&& !curwin->w_p_rl)
|| (curwin->w_p_rl && ((col > PUM_DEF_WIDTH) || (col > max_width)))) {
// align pum column with "col"
pum_col = col;
if (curwin->w_p_rl) {
pum_width = pum_col - pum_scrollbar + 1;
} else { } else {
assert(Columns - pum_col - pum_scrollbar >= INT_MIN // pum below "row"
&& Columns - pum_col - pum_scrollbar <= INT_MAX);
pum_width = (int)(Columns - pum_col - pum_scrollbar);
}
if ((pum_width > max_width + kind_width + extra_width + 1) // Leave two lines of context if possible
&& (pum_width > PUM_DEF_WIDTH)) { if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) {
pum_width = max_width + kind_width + extra_width + 1; context_lines = 3;
} else {
context_lines = curwin->w_cline_row
+ curwin->w_cline_height - curwin->w_wrow;
}
if (pum_width < PUM_DEF_WIDTH) { pum_row = row + context_lines;
pum_width = PUM_DEF_WIDTH; if (size > below_row - pum_row) {
pum_height = below_row - pum_row;
} else {
pum_height = size;
}
if ((p_ph > 0) && (pum_height > p_ph)) {
pum_height = (int)p_ph;
} }
} }
} else if (Columns < def_width) {
// not enough room, will use what we have // don't display when we only have room for one line
if (curwin->w_p_rl) { if ((pum_height < 1) || ((pum_height == 1) && (size > 1))) {
return;
}
// If there is a preview window above, avoid drawing over it.
if (pvwin != NULL && pum_row < above_row && pum_height > above_row) {
pum_row += above_row;
pum_height -= above_row;
}
// Compute the width of the widest match and the widest extra.
for (i = 0; i < size; i++) {
w = vim_strsize(array[i].pum_text);
if (max_width < w) {
max_width = w;
}
if (array[i].pum_kind != NULL) {
w = vim_strsize(array[i].pum_kind) + 1;
if (kind_width < w) {
kind_width = w;
}
}
if (array[i].pum_extra != NULL) {
w = vim_strsize(array[i].pum_extra) + 1;
if (extra_width < w) {
extra_width = w;
}
}
}
pum_base_width = max_width;
pum_kind_width = kind_width;
// if there are more items than room we need a scrollbar
if (pum_height < size) {
pum_scrollbar = 1;
max_width++;
} else {
pum_scrollbar = 0;
}
if (def_width < max_width) {
def_width = max_width;
}
if ((((col < Columns - PUM_DEF_WIDTH) || (col < Columns - max_width))
&& !curwin->w_p_rl)
|| (curwin->w_p_rl && ((col > PUM_DEF_WIDTH) || (col > max_width)))) {
// align pum column with "col"
pum_col = col;
if (curwin->w_p_rl) {
pum_width = pum_col - pum_scrollbar + 1;
} else {
assert(Columns - pum_col - pum_scrollbar >= INT_MIN
&& Columns - pum_col - pum_scrollbar <= INT_MAX);
pum_width = (int)(Columns - pum_col - pum_scrollbar);
}
if ((pum_width > max_width + kind_width + extra_width + 1)
&& (pum_width > PUM_DEF_WIDTH)) {
pum_width = max_width + kind_width + extra_width + 1;
if (pum_width < PUM_DEF_WIDTH) {
pum_width = PUM_DEF_WIDTH;
}
}
} else if (Columns < def_width) {
// not enough room, will use what we have
if (curwin->w_p_rl) {
assert(Columns - 1 >= INT_MIN);
pum_col = (int)(Columns - 1);
} else {
pum_col = 0;
}
assert(Columns - 1 >= INT_MIN); assert(Columns - 1 >= INT_MIN);
pum_col = (int)(Columns - 1); pum_width = (int)(Columns - 1);
} else { } else {
pum_col = 0; if (max_width > PUM_DEF_WIDTH) {
} // truncate
assert(Columns - 1 >= INT_MIN); max_width = PUM_DEF_WIDTH;
pum_width = (int)(Columns - 1); }
} else {
if (max_width > PUM_DEF_WIDTH) { if (curwin->w_p_rl) {
// truncate pum_col = max_width - 1;
max_width = PUM_DEF_WIDTH; } else {
assert(Columns - max_width >= INT_MIN
&& Columns - max_width <= INT_MAX);
pum_col = (int)(Columns - max_width);
}
pum_width = max_width - pum_scrollbar;
} }
if (curwin->w_p_rl) { pum_array = array;
pum_col = max_width - 1; pum_size = size;
} else {
assert(Columns - max_width >= INT_MIN && Columns - max_width <= INT_MAX);
pum_col = (int)(Columns - max_width);
}
pum_width = max_width - pum_scrollbar;
}
pum_array = array; // Set selected item and redraw. If the window size changed need to redo
pum_size = size; // the positioning. Limit this to two times, when there is not much
// room the window size will keep changing.
// Set selected item and redraw. If the window size changed need to redo } while (pum_set_selected(selected, redo_count) && (++redo_count <= 2));
// the positioning. Limit this to two times, when there is not much
// room the window size will keep changing.
if (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,11 +7090,12 @@ 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();
}
} }
} }
} }

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