aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/options.txt7
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/options.lua7
-rw-r--r--src/nvim/popupmnu.c68
-rw-r--r--src/nvim/screen.c2
-rw-r--r--src/nvim/screen.h3
-rw-r--r--test/functional/ui/popupmenu_spec.lua24
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:~ }|