From 703ed11c97256997aa0ce8aa5fe04b6e89e8e829 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 10 Sep 2019 00:42:59 -0400 Subject: vim-patch:8.0.1491: the minimum width of the popup menu is hard coded Problem: The minimum width of the popup menu is hard coded. Solution: Add the 'pumwidth' option. (Christian Brabandt, James McCoy, closes vim/vim#2314) https://github.com/vim/vim/commit/a8f04aa275984183bab5bb583b128f38c64abb69 --- runtime/doc/options.txt | 7 ++++ src/nvim/option_defs.h | 1 + src/nvim/options.lua | 7 ++++ src/nvim/popupmnu.c | 68 ++++++++++++++++++++++++++++++----- src/nvim/screen.c | 2 -- src/nvim/screen.h | 3 ++ test/functional/ui/popupmenu_spec.lua | 24 ++++++------- 7 files changed, 90 insertions(+), 22 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 57e3a00f89..65981ceff5 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4529,6 +4529,13 @@ A jump table for the options with a short description can be found at |Q_op|. global Determines the maximum number of items to show in the popup menu for Insert mode completion. When zero as much space as available is used. + |ins-completion-menu|. + + *'pumwidth'* *'pw'* +'pumwidth' 'pw' number (default 0) + global + Determines the minium width to use for the popup menu for Insert mode + completion. When zero the default of 15 screen cells is used. |ins-completion-menu|. *'pumblend'* *'pb'* diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 4f9f32794b..b03342b387 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -372,6 +372,7 @@ EXTERN int p_confirm; // 'confirm' EXTERN int p_cp; // 'compatible' EXTERN char_u *p_cot; // 'completeopt' EXTERN long p_ph; // 'pumheight' +EXTERN long p_pw; // 'pumwidth' EXTERN long p_pb; // 'pumblend' EXTERN char_u *p_cpo; // 'cpoptions' EXTERN char_u *p_csprg; // 'cscopeprg' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 93bfc1c0b1..e80d8e4cc2 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1822,6 +1822,13 @@ return { varname='p_ph', defaults={if_true={vi=0}} }, + { + full_name='pumwidth', abbreviation='pw', + type='number', scope={'global'}, + vi_def=true, + varname='p_pw', + defaults={if_true={vi=0}} + }, { full_name='pumblend', abbreviation='pb', type='number', scope={'global'}, diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 7a7f8a9d75..be585b78de 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -82,6 +82,13 @@ static void pum_compute_size(void) } } +// Return the minimum width of the popup menu. +static int pum_get_width(void) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + return p_pw == 0 ? PUM_DEF_WIDTH : (int)p_pw; +} + /// Show the popup menu with items "array[size]". /// "array" must remain valid until pum_undisplay() is called! /// When possible the leftmost character is aligned with screen column "col". @@ -161,7 +168,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, } } - def_width = PUM_DEF_WIDTH; + def_width = pum_get_width(); win_T *pvwin = NULL; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { @@ -277,11 +284,13 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, def_width = max_width; } - if ((((col < Columns - PUM_DEF_WIDTH) || (col < Columns - max_width)) + if ((((col < Columns - pum_get_width()) || (col < Columns - max_width)) && !curwin->w_p_rl) - || (curwin->w_p_rl && ((col > PUM_DEF_WIDTH) || (col > max_width)))) { + || (curwin->w_p_rl && ((col > pum_get_width()) || (col > max_width)))) { // align pum column with "col" pum_col = col; + + // start with the maximum space available if (curwin->w_p_rl) { pum_width = pum_col - pum_scrollbar + 1; } else { @@ -291,11 +300,54 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, } if ((pum_width > max_width + pum_kind_width + pum_extra_width + 1) - && (pum_width > PUM_DEF_WIDTH)) { + && (pum_width > pum_get_width())) { + // the width is too much, make it narrower pum_width = max_width + pum_kind_width + pum_extra_width + 1; - if (pum_width < PUM_DEF_WIDTH) { - pum_width = PUM_DEF_WIDTH; + if (pum_width < pum_get_width()) { + pum_width = pum_get_width(); + } + } + } else if (((col > pum_get_width() || col > max_width) + && !curwin->w_p_rl) + || (curwin->w_p_rl + && (col < Columns - pum_get_width() + || col < Columns - max_width))) { + // align right pum edge with "col" + if (curwin->w_p_rl) { + pum_col = col + max_width + pum_scrollbar + 1; + if (pum_col >= Columns) { + pum_col = Columns - 1; + } + } else { + pum_col = col - max_width - pum_scrollbar; + if (pum_col < 0) { + pum_col = 0; + } + } + + if (curwin->w_p_rl) { + pum_width = W_ENDCOL(curwin) - pum_col - pum_scrollbar + 1; + } else { + pum_width = pum_col - pum_scrollbar; + } + + if (pum_width < pum_get_width()) { + pum_width = pum_get_width(); + if (curwin->w_p_rl) { + if (pum_width > pum_col) { + pum_width = pum_col; + } + } else { + if (pum_width >= Columns - pum_col) { + pum_width = Columns - pum_col - 1; + } + } + } else if (pum_width > max_width + pum_kind_width + pum_extra_width + 1 + && pum_width > pum_get_width()) { + pum_width = max_width + pum_kind_width + pum_extra_width + 1; + if (pum_width < pum_get_width()) { + pum_width = pum_get_width(); } } } else if (Columns < def_width) { @@ -309,9 +361,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, assert(Columns - 1 >= INT_MIN); pum_width = (int)(Columns - 1); } else { - if (max_width > PUM_DEF_WIDTH) { + if (max_width > pum_get_width()) { // truncate - max_width = PUM_DEF_WIDTH; + max_width = pum_get_width(); } if (curwin->w_p_rl) { diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 1b7eeeecb8..bfb256a0ad 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -121,8 +121,6 @@ #define MB_FILLER_CHAR '<' /* character used when a double-width character * doesn't fit. */ -#define W_ENDCOL(wp) (wp->w_wincol + wp->w_width) -#define W_ENDROW(wp) (wp->w_winrow + wp->w_height) // temporary buffer for rendering a single screenline, so it can be diff --git a/src/nvim/screen.h b/src/nvim/screen.h index 61ed98247d..9267672cf1 100644 --- a/src/nvim/screen.h +++ b/src/nvim/screen.h @@ -56,6 +56,9 @@ extern StlClickDefinition *tab_page_click_defs; /// Size of the tab_page_click_defs array extern long tab_page_click_defs_size; +#define W_ENDCOL(wp) (wp->w_wincol + wp->w_width) +#define W_ENDROW(wp) (wp->w_winrow + wp->w_height) + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.h.generated.h" #endif diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index fabcc05ce6..ae84145934 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1156,10 +1156,10 @@ describe('builtin popupmenu', function() funcs.complete(29, {'word', 'choice', 'text', 'thing'}) screen:expect([[ some long prefix before the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice}| - {1:~ }{n: text }| - {1:~ }{n: thing }| + {1:~ }{n: word }| + {1:~ }{n: choice }| + {1:~ }{n: text }| + {1:~ }{n: thing }| {1:~ }| {1:~ }| {1:~ }| @@ -1204,10 +1204,10 @@ describe('builtin popupmenu', function() feed('') screen:expect([[ some long prefix before the text| - {1:^~ }{n: word }| - {1:~ }{n: choice}| - {1:~ }{s: text }| - {1:~ }{n: thing }| + {1:^~ }{n: word }| + {1:~ }{n: choice }| + {1:~ }{s: text }| + {1:~ }{n: thing }| {1:~ }| {1:~ }| {1:~ }| @@ -1301,10 +1301,10 @@ describe('builtin popupmenu', function() funcs.complete(29, {'word', 'choice', 'text', 'thing'}) screen:expect([[ some long prefix before the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice}| - {1:~ }{n: text }| - {1:~ }{n: thing }| + {1:~ }{n: word }| + {1:~ }{n: choice }| + {1:~ }{n: text }| + {1:~ }{n: thing }| {1:~ }| {1:~ }| {1:~ }| -- cgit From 669d675ef3f7c7ed4c8b702f53e3a77a986bc7cb Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 10 Sep 2019 18:54:31 -0400 Subject: vim-patch:8.0.1495: having 'pumwidth' default to zero has no merit Problem: Having 'pumwidth' default to zero has no merit. Solution: Make the default 15, as the actual default value. https://github.com/vim/vim/commit/42443c7d7fecc3a2a72154bb6139b028438617c2 Includes 'pumwidth' documentation changes from 8.0.1531. Sort 'pum*' option in alphabetical order. --- runtime/doc/options.txt | 27 +++++++++++++-------------- src/nvim/option_defs.h | 2 +- src/nvim/options.lua | 16 ++++++++-------- src/nvim/popupmnu.c | 38 +++++++++++++++----------------------- 4 files changed, 37 insertions(+), 46 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 65981ceff5..4b832a8606 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4524,20 +4524,6 @@ A jump table for the options with a short description can be found at |Q_op|. global When on a ":" prompt is used in Ex mode. - *'pumheight'* *'ph'* -'pumheight' 'ph' number (default 0) - global - Determines the maximum number of items to show in the popup menu for - Insert mode completion. When zero as much space as available is used. - |ins-completion-menu|. - - *'pumwidth'* *'pw'* -'pumwidth' 'pw' number (default 0) - global - Determines the minium width to use for the popup menu for Insert mode - completion. When zero the default of 15 screen cells is used. - |ins-completion-menu|. - *'pumblend'* *'pb'* 'pumblend' 'pb' number (default 0) global @@ -4554,6 +4540,19 @@ A jump table for the options with a short description can be found at |Q_op|. < UI-dependent. Works best with RGB colors. 'termguicolors' + *'pumheight'* *'ph'* +'pumheight' 'ph' number (default 0) + global + Determines the maximum number of items to show in the popup menu for + Insert mode completion. When zero as much space as available is used. + |ins-completion-menu|. + + *'pumwidth'* *'pw'* +'pumwidth' 'pw' number (default 15) + global + Determines the minium width to use for the popup menu for Insert mode + completion. |ins-completion-menu|. + *'pyxversion'* *'pyx'* 'pyxversion' 'pyx' number (default depends on the build) global diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index b03342b387..fcad6836bf 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -371,9 +371,9 @@ EXTERN long p_columns; // 'columns' EXTERN int p_confirm; // 'confirm' EXTERN int p_cp; // 'compatible' EXTERN char_u *p_cot; // 'completeopt' +EXTERN long p_pb; // 'pumblend' EXTERN long p_ph; // 'pumheight' EXTERN long p_pw; // 'pumwidth' -EXTERN long p_pb; // 'pumblend' EXTERN char_u *p_cpo; // 'cpoptions' EXTERN char_u *p_csprg; // 'cscopeprg' EXTERN int p_csre; // 'cscoperelative' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index e80d8e4cc2..7d080b8d56 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1816,26 +1816,26 @@ return { defaults={if_true={vi=true}} }, { - full_name='pumheight', abbreviation='ph', + full_name='pumblend', abbreviation='pb', type='number', scope={'global'}, vi_def=true, - varname='p_ph', + redraw={'ui_option'}, + varname='p_pb', defaults={if_true={vi=0}} }, { - full_name='pumwidth', abbreviation='pw', + full_name='pumheight', abbreviation='ph', type='number', scope={'global'}, vi_def=true, - varname='p_pw', + varname='p_ph', defaults={if_true={vi=0}} }, { - full_name='pumblend', abbreviation='pb', + full_name='pumwidth', abbreviation='pw', type='number', scope={'global'}, vi_def=true, - redraw={'ui_option'}, - varname='p_pb', - defaults={if_true={vi=0}} + varname='p_pw', + defaults={if_true={vi=15}} }, { full_name='pyxversion', abbreviation='pyx', diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index be585b78de..2ea55c0710 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -82,13 +82,6 @@ static void pum_compute_size(void) } } -// Return the minimum width of the popup menu. -static int pum_get_width(void) - FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT -{ - return p_pw == 0 ? PUM_DEF_WIDTH : (int)p_pw; -} - /// Show the popup menu with items "array[size]". /// "array" must remain valid until pum_undisplay() is called! /// When possible the leftmost character is aligned with screen column "col". @@ -104,7 +97,6 @@ static int pum_get_width(void) void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int cmd_startcol) { - int def_width; int context_lines; int above_row; int below_row; @@ -168,7 +160,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, } } - def_width = pum_get_width(); + int def_width = (int)p_pw; win_T *pvwin = NULL; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { @@ -284,9 +276,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, def_width = max_width; } - if ((((col < Columns - pum_get_width()) || (col < Columns - max_width)) + if ((((col < Columns - p_pw) || (col < Columns - max_width)) && !curwin->w_p_rl) - || (curwin->w_p_rl && ((col > pum_get_width()) || (col > max_width)))) { + || (curwin->w_p_rl && ((col > p_pw) || (col > max_width)))) { // align pum column with "col" pum_col = col; @@ -300,18 +292,18 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, } if ((pum_width > max_width + pum_kind_width + pum_extra_width + 1) - && (pum_width > pum_get_width())) { + && (pum_width > p_pw)) { // the width is too much, make it narrower pum_width = max_width + pum_kind_width + pum_extra_width + 1; - if (pum_width < pum_get_width()) { - pum_width = pum_get_width(); + if (pum_width < p_pw) { + pum_width = (int)p_pw; } } - } else if (((col > pum_get_width() || col > max_width) + } else if (((col > p_pw || col > max_width) && !curwin->w_p_rl) || (curwin->w_p_rl - && (col < Columns - pum_get_width() + && (col < Columns - p_pw || col < Columns - max_width))) { // align right pum edge with "col" if (curwin->w_p_rl) { @@ -332,8 +324,8 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, pum_width = pum_col - pum_scrollbar; } - if (pum_width < pum_get_width()) { - pum_width = pum_get_width(); + if (pum_width < p_pw) { + pum_width = (int)p_pw; if (curwin->w_p_rl) { if (pum_width > pum_col) { pum_width = pum_col; @@ -344,10 +336,10 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, } } } else if (pum_width > max_width + pum_kind_width + pum_extra_width + 1 - && pum_width > pum_get_width()) { + && pum_width > p_pw) { pum_width = max_width + pum_kind_width + pum_extra_width + 1; - if (pum_width < pum_get_width()) { - pum_width = pum_get_width(); + if (pum_width < p_pw) { + pum_width = (int)p_pw; } } } else if (Columns < def_width) { @@ -361,9 +353,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, assert(Columns - 1 >= INT_MIN); pum_width = (int)(Columns - 1); } else { - if (max_width > pum_get_width()) { + if (max_width > p_pw) { // truncate - max_width = pum_get_width(); + max_width = (int)p_pw; } if (curwin->w_p_rl) { -- cgit From ac85d1f52f0d298b03f7d0e0be3f4b7ce777cae7 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 10 Sep 2019 19:12:29 -0400 Subject: vim-patch:8.1.0670: macro for popup menu width is unused Problem: Macro for popup menu width is unused. Solution: Remove it. (Hirohito Higashi) https://github.com/vim/vim/commit/3d631cb0b34b03c7bdf45ad852d3644c7cf62743 --- src/nvim/popupmnu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 2ea55c0710..561cb846f1 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -54,7 +54,6 @@ static bool pum_invalid = false; // the screen was just cleared # include "popupmnu.c.generated.h" #endif #define PUM_DEF_HEIGHT 10 -#define PUM_DEF_WIDTH 15 static void pum_compute_size(void) { -- cgit From d56f36f46c400ead225caaef8ac2717ff1e4bfec Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 10 Sep 2019 20:47:33 -0400 Subject: vim-patch:8.0.1522: popup menu is positioned in the wrong place Problem: Popup menu is positioned in the wrong place. (Davit Samvelyan, Boris Staletic) Solution: Correct computation of the column and the conditions for that. (Hirohito Higashi, closes vim/vim#2640) https://github.com/vim/vim/commit/4287ed33ddc324d26dd05d3e19596dd74cf479d6 --- src/nvim/popupmnu.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 561cb846f1..a715129f8a 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -305,22 +305,25 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, && (col < Columns - p_pw || col < Columns - max_width))) { // align right pum edge with "col" - if (curwin->w_p_rl) { + if (curwin->w_p_rl + && col < max_width + pum_scrollbar + 1) { pum_col = col + max_width + pum_scrollbar + 1; if (pum_col >= Columns) { pum_col = Columns - 1; } - } else { - pum_col = col - max_width - pum_scrollbar; - if (pum_col < 0) { - pum_col = 0; + } else if (!curwin->w_p_rl) { + if (col > Columns - max_width - pum_scrollbar) { + pum_col = col - max_width - pum_scrollbar; + if (pum_col < 0) { + pum_col = 0; + } } } if (curwin->w_p_rl) { - pum_width = W_ENDCOL(curwin) - pum_col - pum_scrollbar + 1; + pum_width = pum_col - pum_scrollbar + 1; } else { - pum_width = pum_col - pum_scrollbar; + pum_width = Columns - pum_col - pum_scrollbar; } if (pum_width < p_pw) { -- cgit From 51c9e3c4d19f26af11a86a8f736a74a5cb6f2fa2 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 10 Sep 2019 20:53:13 -0400 Subject: vim-patch:8.0.1538: popupmenu is too far left when completion is long Problem: Popupmenu is too far left when completion is long. (Linwei) Solution: Adjust column computations. (Hirohito Higashi, closes vim/vim#2661) https://github.com/vim/vim/commit/bb008dd3239c5fe3ac04501e38e4c950fa9426c8 --- src/nvim/popupmnu.c | 4 ++-- test/functional/ui/popupmenu_spec.lua | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index a715129f8a..d53f2c2c7b 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -306,13 +306,13 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, || col < Columns - max_width))) { // align right pum edge with "col" if (curwin->w_p_rl - && col < max_width + pum_scrollbar + 1) { + && W_ENDCOL(curwin) < max_width + pum_scrollbar + 1) { pum_col = col + max_width + pum_scrollbar + 1; if (pum_col >= Columns) { pum_col = Columns - 1; } } else if (!curwin->w_p_rl) { - if (col > Columns - max_width - pum_scrollbar) { + if (curwin->w_wincol > Columns - max_width - pum_scrollbar) { pum_col = col - max_width - pum_scrollbar; if (pum_col < 0) { pum_col = 0; diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index ae84145934..13affac571 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1156,10 +1156,10 @@ describe('builtin popupmenu', function() funcs.complete(29, {'word', 'choice', 'text', 'thing'}) screen:expect([[ some long prefix before the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice }| - {1:~ }{n: text }| - {1:~ }{n: thing }| + {n:word }{1: }| + {n:choice }{1: }| + {n:text }{1: }| + {n:thing }{1: }| {1:~ }| {1:~ }| {1:~ }| @@ -1204,10 +1204,10 @@ describe('builtin popupmenu', function() feed('') screen:expect([[ some long prefix before the text| - {1:^~ }{n: word }| - {1:~ }{n: choice }| - {1:~ }{s: text }| - {1:~ }{n: thing }| + {n:^word }{1: }| + {n:choice }{1: }| + {s:text }{1: }| + {n:thing }{1: }| {1:~ }| {1:~ }| {1:~ }| @@ -1301,10 +1301,10 @@ describe('builtin popupmenu', function() funcs.complete(29, {'word', 'choice', 'text', 'thing'}) screen:expect([[ some long prefix before the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice }| - {1:~ }{n: text }| - {1:~ }{n: thing }| + {n:word }{1: }| + {n:choice }{1: }| + {n:text }{1: }| + {n:thing }{1: }| {1:~ }| {1:~ }| {1:~ }| -- cgit From 1d3d84fe818efaf47d8f818fcc44368d144443a1 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 26 Dec 2019 13:21:35 -0500 Subject: vim-patch:8.1.0554: popup menu overlaps with preview window Problem: Popup menu overlaps with preview window. Solution: Adjust the height computation. (Hirohito Higashi, closes vim/vim#3414) https://github.com/vim/vim/commit/614ab8aa00346724bfc27980d25985d482269b75 Cherry-picked "row -> pum_win_row" rename changes from patch 8.1.0062. --- src/nvim/popupmnu.c | 45 ++++++++++++++++------------------- src/nvim/testdir/test_popup.vim | 22 +++++++++++++++++ test/functional/ui/popupmenu_spec.lua | 20 ++++++++-------- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index d53f2c2c7b..c9ff49d233 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -100,7 +100,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int above_row; int below_row; int redo_count = 0; - int row; + int pum_win_row; int col; if (!pum_is_visible) { @@ -121,12 +121,12 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, // wildoptions=pum if (State == CMDLINE) { - row = ui_has(kUICmdline) ? 0 : cmdline_row; + pum_win_row = ui_has(kUICmdline) ? 0 : cmdline_row; col = cmd_startcol; pum_anchor_grid = ui_has(kUICmdline) ? -1 : DEFAULT_GRID_HANDLE; } else { // anchor position: the start of the completed word - row = curwin->w_wrow; + pum_win_row = curwin->w_wrow; if (curwin->w_p_rl) { col = curwin->w_width - curwin->w_wcol - 1; } else { @@ -136,7 +136,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, pum_anchor_grid = (int)curwin->w_grid.handle; if (!ui_has(kUIMultigrid)) { pum_anchor_grid = (int)default_grid.handle; - row += curwin->w_winrow; + pum_win_row += curwin->w_winrow; col += curwin->w_wincol; } } @@ -152,7 +152,8 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info))); ADD(arr, ARRAY_OBJ(item)); } - ui_call_popupmenu_show(arr, selected, row, col, pum_anchor_grid); + ui_call_popupmenu_show(arr, selected, pum_win_row, col, + pum_anchor_grid); } else { ui_call_popupmenu_select(selected); return; @@ -188,11 +189,11 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, 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" + // Put the pum below "pum_win_row" if possible. + // If there are few lines decide on where there is more room. + if (pum_win_row + 2 >= below_row - pum_height + && pum_win_row - above_row > (below_row - above_row) / 2) { + // pum above "pum_win_row" pum_above = true; // Leave two lines of context if possible @@ -202,12 +203,12 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, context_lines = curwin->w_wrow - curwin->w_cline_row; } - if (row >= size + context_lines) { - pum_row = row - size - context_lines; + if (pum_win_row >= size + context_lines) { + pum_row = pum_win_row - size - context_lines; pum_height = size; } else { pum_row = 0; - pum_height = row - context_lines; + pum_height = pum_win_row - context_lines; } if ((p_ph > 0) && (pum_height > p_ph)) { @@ -215,7 +216,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, pum_height = (int)p_ph; } } else { - // pum below "row" + // pum below "pum_win_row" pum_above = false; // Leave two lines of context if possible @@ -226,7 +227,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, + curwin->w_cline_height - curwin->w_wrow; } - pum_row = row + context_lines; + pum_row = pum_win_row + context_lines; if (size > below_row - pum_row) { pum_height = below_row - pum_row; } else { @@ -243,16 +244,10 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, return; } - // If there is a preview window above, avoid drawing over it. - // Do keep at least 10 entries. - if (pvwin != NULL && pum_row < above_row && pum_height > 10) { - if (row - above_row < 10) { - pum_row = row - 10; - pum_height = 10; - } else { - pum_row = above_row; - pum_height = row - above_row; - } + // 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 = pum_win_row - above_row; } if (pum_external) { return; diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 9db6112eeb..27c90f9114 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -733,6 +733,28 @@ func Test_popup_and_preview_autocommand() bw! endfunc +func Test_popup_and_previewwindow_dump() + if !CanRunVimInTerminal() + return + endif + call writefile([ + \ 'set previewheight=9', + \ 'silent! pedit', + \ 'call setline(1, map(repeat(["ab"], 10), "v:val. v:key"))', + \ 'exec "norm! G\\"', + \ ], 'Xscript') + let buf = RunVimInTerminal('-S Xscript', {}) + + " Test that popup and previewwindow do not overlap. + call term_sendkeys(buf, "o\\") + sleep 100m + call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {}) + + call term_sendkeys(buf, "\u") + call StopVimInTerminal(buf) + call delete('Xscript') +endfunc + func Test_popup_position() if !CanRunVimInTerminal() return diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 13affac571..4c7f516c43 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -739,16 +739,16 @@ describe('builtin popupmenu', function() ee | ff | gg | - {s:aa } | - {n:bb }{3:iew][+] }| - {n:cc } | - {n:dd } | - {n:ee } | - {n:ff } | - {n:gg } | - {n:hh } | - {n:ii } | - {n:jj } | + hh | + {s:aa }{c: }{3:ew][+] }| + {n:bb }{c: } | + {n:cc }{c: } | + {n:dd }{c: } | + {n:ee }{c: } | + {n:ff }{c: } | + {n:gg }{c: } | + {n:hh }{c: } | + {n:ii }{s: } | aa^ | {4:[No Name] [+] }| {2:-- }{5:match 1 of 10} | -- cgit From be4165308f072c499a1bdbf8af36a865ec29b43f Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 26 Dec 2019 21:38:41 -0500 Subject: screen: fix pvs/v1048 --- src/nvim/screen.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nvim/screen.c b/src/nvim/screen.c index bfb256a0ad..0612575e67 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2445,8 +2445,6 @@ win_line ( pos.lnum = lnum; pos.col = search_match_endcol; getvcol(curwin, &pos, (colnr_T *)&tocol, NULL, NULL); - } else { - tocol = MAXCOL; } // do at least one character; happens when past end of line if (fromcol == tocol) { -- cgit From 1e693ac97d44f0cd0edcdb31d883d2a27c9d30ce Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 26 Dec 2019 23:21:13 -0500 Subject: vim-patch:8.1.1303: not possible to hide a balloon Problem: Not possible to hide a balloon. Solution: Hide the balloon when balloon_show() is called with an empty string or list. Add balloon_gettext(). https://github.com/vim/vim/commit/be0a2597ae0d9eb0b8a8a2fc9ae1784faa929844 --- runtime/doc/eval.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 77589b732d..c376e07cff 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -3770,6 +3770,8 @@ feedkeys({string} [, {mode}]) *feedkeys()* and "\..." notation |expr-quote|. For example, feedkeys("\") simulates pressing of the key. But feedkeys('\') pushes 5 characters. + A special code that might be useful is , it exits the + wait for a character without doing anything. ** {mode} is a String, which can contain these character flags: 'm' Remap keys. This is default. If {mode} is absent, -- cgit From 81a0d10f131ddea0bd5faa50e362deb97c0abb08 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 28 Dec 2019 00:11:38 -0500 Subject: fixup! vim-patch.sh: list related missing Vim patches [ci skip] #11514 --- scripts/vim-patch.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh index b5806311c9..769f0fed58 100755 --- a/scripts/vim-patch.sh +++ b/scripts/vim-patch.sh @@ -430,9 +430,11 @@ _set_tokens_and_tags() { list_missing_vimpatches() { local -a missing_vim_patches=() _set_missing_vimpatches "$@" + set +u # Avoid "unbound variable" with bash < 4.4 below. for line in "${missing_vim_patches[@]}"; do printf '%s\n' "$line" done + set -u } # Sets / appends to missing_vim_patches (useful to avoid a subshell when -- cgit From e80f61020adfe6f2503c59cfea86f47fc6b0887d Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 28 Dec 2019 00:46:40 -0500 Subject: vim-patch:8.0.1540: popup menu positioning fails with longer string Problem: Popup menu positioning fails with longer string. Solution: Only align with right side of window when width is less than 'pumwidth' (closes vim/vim#2661) https://github.com/vim/vim/commit/2b10bcbfc1c025bf7e6358326ee70105e7d30e96 --- src/nvim/popupmnu.c | 45 +++++++++++++++++++++++------------------ src/nvim/testdir/test_popup.vim | 9 +++++++++ 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index c9ff49d233..4ba2a1032d 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -83,7 +83,7 @@ static void pum_compute_size(void) /// Show the popup menu with items "array[size]". /// "array" must remain valid until pum_undisplay() is called! -/// When possible the leftmost character is aligned with screen column "col". +/// When possible the leftmost character is aligned with cursor column. /// The menu appears above the screen line "row" or at "row" + "height" - 1. /// /// @param array @@ -101,7 +101,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int below_row; int redo_count = 0; int pum_win_row; - int col; + int cursor_col; if (!pum_is_visible) { // To keep the code simple, we only allow changing the @@ -122,22 +122,22 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, // wildoptions=pum if (State == CMDLINE) { pum_win_row = ui_has(kUICmdline) ? 0 : cmdline_row; - col = cmd_startcol; + cursor_col = cmd_startcol; pum_anchor_grid = ui_has(kUICmdline) ? -1 : DEFAULT_GRID_HANDLE; } else { // anchor position: the start of the completed word pum_win_row = curwin->w_wrow; if (curwin->w_p_rl) { - col = curwin->w_width - curwin->w_wcol - 1; + cursor_col = curwin->w_width - curwin->w_wcol - 1; } else { - col = curwin->w_wcol; + cursor_col = curwin->w_wcol; } pum_anchor_grid = (int)curwin->w_grid.handle; if (!ui_has(kUIMultigrid)) { pum_anchor_grid = (int)default_grid.handle; pum_win_row += curwin->w_winrow; - col += curwin->w_wincol; + cursor_col += curwin->w_wincol; } } @@ -152,7 +152,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info))); ADD(arr, ARRAY_OBJ(item)); } - ui_call_popupmenu_show(arr, selected, pum_win_row, col, + ui_call_popupmenu_show(arr, selected, pum_win_row, cursor_col, pum_anchor_grid); } else { ui_call_popupmenu_select(selected); @@ -270,11 +270,13 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, def_width = max_width; } - if ((((col < Columns - p_pw) || (col < Columns - max_width)) + if ((((cursor_col < Columns - p_pw) + || (cursor_col < Columns - max_width)) && !curwin->w_p_rl) - || (curwin->w_p_rl && ((col > p_pw) || (col > max_width)))) { - // align pum column with "col" - pum_col = col; + || (curwin->w_p_rl + && ((cursor_col > p_pw) || (cursor_col > max_width)))) { + // align pum with "cursor_col" + pum_col = cursor_col; // start with the maximum space available if (curwin->w_p_rl) { @@ -287,28 +289,31 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, if ((pum_width > max_width + pum_kind_width + pum_extra_width + 1) && (pum_width > p_pw)) { - // the width is too much, make it narrower + // the width is more than needed for the items, make it + // narrower pum_width = max_width + pum_kind_width + pum_extra_width + 1; if (pum_width < p_pw) { pum_width = (int)p_pw; } } - } else if (((col > p_pw || col > max_width) + } else if (((cursor_col > p_pw || cursor_col > max_width) && !curwin->w_p_rl) || (curwin->w_p_rl - && (col < Columns - p_pw - || col < Columns - max_width))) { - // align right pum edge with "col" + && (cursor_col < Columns - p_pw + || cursor_col < Columns - max_width))) { + // align pum edge with "cursor_col" if (curwin->w_p_rl && W_ENDCOL(curwin) < max_width + pum_scrollbar + 1) { - pum_col = col + max_width + pum_scrollbar + 1; + pum_col = cursor_col + max_width + pum_scrollbar + 1; if (pum_col >= Columns) { pum_col = Columns - 1; } } else if (!curwin->w_p_rl) { - if (curwin->w_wincol > Columns - max_width - pum_scrollbar) { - pum_col = col - max_width - pum_scrollbar; + if (curwin->w_wincol > Columns - max_width - pum_scrollbar + && max_width <= p_pw) { + // use full width to end of the screen + pum_col = cursor_col - max_width - pum_scrollbar; if (pum_col < 0) { pum_col = 0; } @@ -515,7 +520,7 @@ void pum_redraw(void) if (size < pum_width) { // Most left character requires 2-cells but only 1 cell - // is available on screen. Put a '<' on the left of the + // is available on screen. Put a '<' on the left of the // pum item *(--rt) = '<'; size++; diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 27c90f9114..e5696f4cbb 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -784,6 +784,15 @@ func Test_popup_position() call term_sendkeys(buf, "GA\") call VerifyScreenDump(buf, 'Test_popup_position_03', {'rows': 8}) + " completed text wider than the window and 'pumwidth' smaller than available + " space + call term_sendkeys(buf, "\u") + call term_sendkeys(buf, ":set pumwidth=20\") + call term_sendkeys(buf, "ggI123456789_\") + call term_sendkeys(buf, "jI123456789_\") + call term_sendkeys(buf, "GA\") + call VerifyScreenDump(buf, 'Test_popup_position_04', {'rows': 10}) + call term_sendkeys(buf, "\u") call StopVimInTerminal(buf) call delete('Xtest') -- cgit From 6c606c1191287752d174439874fc7e820272cc49 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 29 Dec 2019 00:44:11 -0500 Subject: vim-patch:8.1.1875: cannot get size and position of the popup menu Problem: Cannot get size and position of the popup menu. Solution: Add pum_getpos(). (Ben Jackson, closes vim/vim#4827) https://github.com/vim/vim/commit/e9bd57286a5cbb0e1ec18b5d194dc4af1bda9f3a https://github.com/neovim/neovim/pull/11562 backported the vim patch. This patch only updates the runtime/doc/ files to match Vim. --- runtime/doc/autocmd.txt | 14 +++++++------- runtime/doc/eval.txt | 5 +++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index ac61297767..97379bfa27 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -583,13 +583,6 @@ ColorSchemePre Before loading a color scheme. |:colorscheme| Useful to setup removing things added by a color scheme, before another one is loaded. - *CompleteDone* -CompleteDone After Insert mode completion is done. Either - when something was completed or abandoning - completion. |ins-completion| - The |v:completed_item| variable contains the - completed item. - CompleteChanged *CompleteChanged* After each time the Insert mode completion menu changed. Not fired on popup menu hide, @@ -610,6 +603,13 @@ CompleteChanged *CompleteChanged* The size and position of the popup are also available by calling |pum_getpos()|. + *CompleteDone* +CompleteDone After Insert mode completion is done. Either + when something was completed or abandoning + completion. |ins-completion| + The |v:completed_item| variable contains the + completed item. + *CursorHold* CursorHold When the user doesn't press a key for the time specified with 'updatetime'. Not re-triggered diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index c376e07cff..fecb8b5f74 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -3121,8 +3121,9 @@ complete_info([{what}]) the items listed in {what} are returned. Unsupported items in {what} are silently ignored. - To get the position of the popup menu, see |pum_getpos()|. It's - also available in |v:event| during the |CompleteChanged| event. + To get the position and size of the popup menu, see + |pum_getpos()|. It's also available in |v:event| during the + |CompleteChanged| event. Examples: > " Get all items -- cgit From ebd5c2cdda9a7114070021cbbc163054aa8f62da Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 29 Dec 2019 23:16:52 -0500 Subject: ui: add basic tests for pumheight,pumwidth --- test/functional/ui/popupmenu_spec.lua | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 4c7f516c43..a0e5c3ca63 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -2019,4 +2019,42 @@ describe('builtin popupmenu', function() {9:-- Keyword Local completion (^N^P) }{10:match 1 of 3} | ]]) end) + + it("'pumheight'", function() + screen:try_resize(32,8) + feed('isome long prefix before the ') + command("set completeopt+=noinsert,noselect") + command("set linebreak") + command("set pumheight=2") + funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + screen:expect([[ + some long prefix before the ^ | + {n:word }{c: }{1: }| + {n:choice }{s: }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end) + + it("'pumwidth'", function() + screen:try_resize(32,8) + feed('isome long prefix before the ') + command("set completeopt+=noinsert,noselect") + command("set linebreak") + command("set pumwidth=8") + funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + screen:expect([[ + some long prefix before the ^ | + {n:word }{1: }| + {n:choice }{1: }| + {n:text }{1: }| + {n:thing }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end) end) -- cgit From 5fc8a7ee096cf1a5cf78058a483b781c5c0c9af5 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Mon, 30 Dec 2019 00:32:42 -0500 Subject: vim-patch:8.1.1300: in a terminal 'ballooneval' does not work right away Problem: In a terminal 'ballooneval' does not work right away. Solution: Flush output after drawing the balloon. Add the key code. Add a test. https://github.com/vim/vim/commit/2f10658b06bbdd8f25c4ff152266c808234cee0a --- src/nvim/keymap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index b8b9c945b9..4b8b9992f5 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -309,6 +309,7 @@ static const struct key_name_entry { { K_ZERO, "Nul" }, { K_SNR, "SNR" }, { K_PLUG, "Plug" }, + { K_IGNORE, "Ignore" }, { K_COMMAND, "Cmd" }, { 0, NULL } // NOTE: When adding a long name update MAX_KEY_NAME_LEN. -- cgit From 78aa41354ea9b6bb2d6ce750f02f0f8b3d7d4418 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Mon, 30 Dec 2019 00:47:32 -0500 Subject: vim-patch:8.1.2377: GUI: when losing focus a pending operator is executed Problem: GUI: when losing focus a pending operator is executed. Solution: Do not execute an operator when getting K_IGNORE. (closes vim/vim#5300) https://github.com/vim/vim/commit/fa5612c7d836eb789e0f8ff4b10461b8640a14b2 --- src/nvim/normal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 9c5434a0dd..9c707a6fdc 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -874,8 +874,10 @@ static void normal_finish_command(NormalState *s) s->old_mapped_len = typebuf_maplen(); } - // If an operation is pending, handle it... - do_pending_operator(&s->ca, s->old_col, false); + // If an operation is pending, handle it. But not for K_IGNORE. + if (s->ca.cmdchar != K_IGNORE) { + do_pending_operator(&s->ca, s->old_col, false); + } // Wait for a moment when a message is displayed that will be overwritten // by the mode message. -- cgit From 5e1cad6d3378398c059e1a7144e1310b7bcb2398 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Mon, 30 Dec 2019 00:56:57 -0500 Subject: vim-patch:8.0.1356: using simalt in a GUIEnter autocommand inserts characters Problem: Using simalt in a GUIEnter autocommand inserts strange characters. (Chih-Long Chang) Solution: Ignore K_NOP in Insert mode. (closes vim/vim#2379) https://github.com/vim/vim/commit/c5aa55db7e5bc791f99fb15b0f4be0d5dd166f62 --- src/nvim/edit.c | 2 +- src/nvim/ex_getln.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvim/edit.c b/src/nvim/edit.c index eecea03a19..cb5c7023d7 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -638,7 +638,7 @@ static int insert_check(VimState *state) static int insert_execute(VimState *state, int key) { - if (key == K_IGNORE) { + if (key == K_IGNORE || key == K_NOP) { return -1; // get another key } InsertState *s = (InsertState *)state; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index e5f5e5ad87..c09a3c08ef 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -536,7 +536,7 @@ static int command_line_check(VimState *state) static int command_line_execute(VimState *state, int key) { - if (key == K_IGNORE) { + if (key == K_IGNORE || key == K_NOP) { return -1; // get another key } -- cgit