diff options
-rw-r--r-- | runtime/doc/options.txt | 7 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 1 | ||||
-rw-r--r-- | src/nvim/options.lua | 7 | ||||
-rw-r--r-- | src/nvim/popupmnu.c | 68 | ||||
-rw-r--r-- | src/nvim/screen.c | 2 | ||||
-rw-r--r-- | src/nvim/screen.h | 3 | ||||
-rw-r--r-- | 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 @@ -4531,6 +4531,13 @@ A jump table for the options with a short description can be found at |Q_op|. 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 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 @@ -1823,6 +1823,13 @@ return { 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'}, vi_def=true, 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('<c-p>') 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:~ }| |