mirror of
https://github.com/vim/vim.git
synced 2025-10-16 07:24:23 -04:00
patch 9.1.1856: cannot style popup window (border, shadow, etc)
Problem: cannot style popup window (border, shadow, etc) Solution: Extend the 'completepopup' option with additional properties (Girish Palya) This patch extends the 'completepopup' option with additional settings to allow more configuration of info popup window. New values: ``` - close "on" (default) or "off" - resize "on" (default) or "off" - borderchars specify eight characters (separated by semicolons) to draw the popup border: top, right, bottom, left, topleft, topright, botright, botleft. - borderhighlight highlight group for the popup border characters - shadow pum shadow ``` closes: #18487 Signed-off-by: Girish Palya <girishji@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
e15cd0f065
commit
1a09f11f5d
@@ -1,4 +1,4 @@
|
|||||||
*insert.txt* For Vim version 9.1. Last change: 2025 Oct 12
|
*insert.txt* For Vim version 9.1. Last change: 2025 Oct 14
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -1287,26 +1287,9 @@ remove existing text in the preview window. The size of the preview window is
|
|||||||
three lines, but 'previewheight' is used when it has a value of 1 or 2.
|
three lines, but 'previewheight' is used when it has a value of 1 or 2.
|
||||||
|
|
||||||
*complete-popup*
|
*complete-popup*
|
||||||
When "popup" is in 'completeopt' a popup window is used to display the "info".
|
When "popup" is included in 'completeopt', a popup window is used to display
|
||||||
Then the 'completepopup' option specifies the properties of the popup. This
|
the completion "info" text. The appearance and behavior of this popup are
|
||||||
is used when the info popup is created. The option is a comma-separated list
|
controlled by the 'completepopup' option when the popup is created.
|
||||||
of values:
|
|
||||||
height maximum height of the popup
|
|
||||||
width maximum width of the popup
|
|
||||||
highlight highlight group of the popup (default is PmenuSel)
|
|
||||||
align "item" (default) or "menu"
|
|
||||||
border "on" (default) or "off"
|
|
||||||
Example: >
|
|
||||||
:set completepopup=height:10,width:60,highlight:InfoPopup
|
|
||||||
|
|
||||||
When `"align"` is set to `"item"`, the popup is positioned near the selected
|
|
||||||
item, and moves as the selection changes.
|
|
||||||
When set to `"menu"`, the popup aligns with the top of the menu (if the menu
|
|
||||||
appears below the text), or with the bottom (if the menu appears above).
|
|
||||||
|
|
||||||
If the 'mouse' is enabled, a close button and resize handle will appear on the
|
|
||||||
popup border.
|
|
||||||
|
|
||||||
After creation, the info popup can be located with |popup_findinfo()| and
|
After creation, the info popup can be located with |popup_findinfo()| and
|
||||||
modified using |popup_setoptions()|.
|
modified using |popup_setoptions()|.
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
*options.txt* For Vim version 9.1. Last change: 2025 Oct 12
|
*options.txt* For Vim version 9.1. Last change: 2025 Oct 14
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -2339,12 +2339,50 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
global
|
global
|
||||||
{not available when compiled without the |+textprop|
|
{not available when compiled without the |+textprop|
|
||||||
or |+quickfix| feature}
|
or |+quickfix| feature}
|
||||||
When 'completeopt' contains "popup" then this option is used for the
|
When 'completeopt' contains "popup", this option specifies the
|
||||||
properties of the info popup when it is created. If an info popup
|
properties of the info popup when it is created. If an info popup
|
||||||
window already exists it is closed, so that the option value is
|
window already exists it is closed, so that the option value is
|
||||||
applied when it is created again.
|
applied when it is created again.
|
||||||
You can also use |popup_findinfo()| and then set properties for an
|
|
||||||
existing info popup with |popup_setoptions()|. See |complete-popup|.
|
The option is a comma-separated list of values:
|
||||||
|
align "item" (default) or "menu"
|
||||||
|
border border style:
|
||||||
|
"single" thin box-drawing characters
|
||||||
|
"double" double-line
|
||||||
|
"round" rounded corners
|
||||||
|
"ascii" ASCII characters (-, |, +)
|
||||||
|
"custom:X;X;X;X;X;X;X;X"
|
||||||
|
eight characters separated by
|
||||||
|
semicolons, in the order: top,
|
||||||
|
right, bottom, left, topleft,
|
||||||
|
topright, botright, botleft
|
||||||
|
"on" same as "double" when
|
||||||
|
'encoding' is "utf-8" and
|
||||||
|
'ambiwidth' is "single", else
|
||||||
|
"ascii" (default)
|
||||||
|
"off" no border
|
||||||
|
borderhighlight highlight group for the popup border characters
|
||||||
|
close show close button: "on" (default) or "off"
|
||||||
|
height maximum height of the popup
|
||||||
|
highlight popup highlight group (default: PmenuSel)
|
||||||
|
resize show resize handle: "on" (default) or "off"
|
||||||
|
shadow "off" (default) or "on" using |hl-PmenuShadow|
|
||||||
|
width maximum width of the popup
|
||||||
|
|
||||||
|
Example: >
|
||||||
|
:set completepopup=height:10,border:single,highlight:InfoPopup
|
||||||
|
:set completepopup=width:60,border:custom:─;│;─;│;┌;┐;┘;└
|
||||||
|
<
|
||||||
|
When "align" is set to "item", the popup is positioned near the
|
||||||
|
selected item and moves as the selection changes.
|
||||||
|
When set to "menu", the popup aligns with the top of the menu (if the
|
||||||
|
menu appears below the text) or with the bottom (if it appears above).
|
||||||
|
|
||||||
|
The close button and resize handle are shown on the popup border only
|
||||||
|
when 'mouse' is enabled.
|
||||||
|
|
||||||
|
After creation, the info popup can be located with |popup_findinfo()|
|
||||||
|
and modified using |popup_setoptions()|. See also: |complete-popup|.
|
||||||
|
|
||||||
*'completeslash'* *'csl'*
|
*'completeslash'* *'csl'*
|
||||||
'completeslash' 'csl' string (default: "")
|
'completeslash' 'csl' string (default: "")
|
||||||
|
@@ -41717,6 +41717,7 @@ Options: ~
|
|||||||
to ">" by default, indicating text that extends beyond the window width.
|
to ">" by default, indicating text that extends beyond the window width.
|
||||||
- 'guioptions': New value |'go-C'| to style the title/caption bar on Windows 11
|
- 'guioptions': New value |'go-C'| to style the title/caption bar on Windows 11
|
||||||
(see also the below platform specific change).
|
(see also the below platform specific change).
|
||||||
|
- 'completepopup': Add more values to style popup windows.
|
||||||
|
|
||||||
Ex commands: ~
|
Ex commands: ~
|
||||||
- allow to specify a priority when defining a new sign |:sign-define|
|
- allow to specify a priority when defining a new sign |:sign-define|
|
||||||
|
@@ -711,7 +711,7 @@ static struct vimoption options[] =
|
|||||||
SCTX_INIT},
|
SCTX_INIT},
|
||||||
{"completepopup", "cpp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON,
|
{"completepopup", "cpp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON,
|
||||||
#if defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX)
|
#if defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX)
|
||||||
(char_u *)&p_cpp, PV_NONE, did_set_completepopup, expand_set_popupoption,
|
(char_u *)&p_cpp, PV_NONE, did_set_completepopup, expand_set_completepopup,
|
||||||
{(char_u *)"", (char_u *)0L}
|
{(char_u *)"", (char_u *)0L}
|
||||||
#else
|
#else
|
||||||
(char_u *)NULL, PV_NONE, NULL, NULL,
|
(char_u *)NULL, PV_NONE, NULL, NULL,
|
||||||
@@ -1991,7 +1991,7 @@ static struct vimoption options[] =
|
|||||||
{(char_u *)12L, (char_u *)0L} SCTX_INIT},
|
{(char_u *)12L, (char_u *)0L} SCTX_INIT},
|
||||||
{"previewpopup", "pvp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON,
|
{"previewpopup", "pvp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON,
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
(char_u *)&p_pvp, PV_NONE, did_set_previewpopup, expand_set_popupoption,
|
(char_u *)&p_pvp, PV_NONE, did_set_previewpopup, expand_set_previewpopup,
|
||||||
{(char_u *)"", (char_u *)0L}
|
{(char_u *)"", (char_u *)0L}
|
||||||
#else
|
#else
|
||||||
(char_u *)NULL, PV_NONE, NULL, NULL,
|
(char_u *)NULL, PV_NONE, NULL, NULL,
|
||||||
|
@@ -70,9 +70,14 @@ static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
|
|||||||
static char *(p_kpc_protocol_values[]) = {"none", "mok2", "kitty", NULL};
|
static char *(p_kpc_protocol_values[]) = {"none", "mok2", "kitty", NULL};
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
// Note: Keep this in sync with parse_popup_option()
|
// Note: Keep this in sync with parse_popup_option()
|
||||||
static char *(p_popup_option_values[]) = { "align:", "border:", "height:",
|
static char *(p_popup_cpp_option_values[]) = {"align:", "border:",
|
||||||
"highlight:", "shadow:", "width:", NULL};
|
"borderhighlight:", "close:", "height:", "highlight:", "resize:",
|
||||||
static char *(p_popup_option_border_values[]) = {"on", "off", NULL};
|
"shadow:", "width:", NULL};
|
||||||
|
static char *(p_popup_pvp_option_values[]) = {"height:", "highlight:",
|
||||||
|
"width:", NULL};
|
||||||
|
static char *(p_popup_option_on_off_values[]) = {"on", "off", NULL};
|
||||||
|
static char *(p_popup_cpp_border_values[]) = {"single", "double", "round",
|
||||||
|
"ascii", "on", "off", "custom:", NULL};
|
||||||
static char *(p_popup_option_align_values[]) = {"item", "menu", NULL};
|
static char *(p_popup_option_align_values[]) = {"item", "menu", NULL};
|
||||||
#endif
|
#endif
|
||||||
#if defined(FEAT_SPELL)
|
#if defined(FEAT_SPELL)
|
||||||
@@ -3408,8 +3413,9 @@ did_set_previewpopup(optset_T *args UNUSED)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches)
|
expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches,
|
||||||
|
int previewpopup)
|
||||||
{
|
{
|
||||||
expand_T *xp = args->oe_xp;
|
expand_T *xp = args->oe_xp;
|
||||||
|
|
||||||
@@ -3417,13 +3423,34 @@ expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches)
|
|||||||
{
|
{
|
||||||
// Within "highlight:"/"border:"/"align:", we have a subgroup of possible options.
|
// Within "highlight:"/"border:"/"align:", we have a subgroup of possible options.
|
||||||
int border_len = (int)STRLEN("border:");
|
int border_len = (int)STRLEN("border:");
|
||||||
if (xp->xp_pattern - args->oe_set_arg >= border_len &&
|
int close_len = (int)STRLEN("close:");
|
||||||
STRNCMP(xp->xp_pattern - border_len, "border:", border_len) == 0)
|
int resize_len = (int)STRLEN("resize:");
|
||||||
|
int shadow_len = (int)STRLEN("shadow:");
|
||||||
|
int is_border = xp->xp_pattern - args->oe_set_arg >= border_len &&
|
||||||
|
STRNCMP(xp->xp_pattern - border_len, "border:", border_len) == 0;
|
||||||
|
int is_close = xp->xp_pattern - args->oe_set_arg >= close_len &&
|
||||||
|
STRNCMP(xp->xp_pattern - close_len, "close:", close) == 0;
|
||||||
|
int is_resize = xp->xp_pattern - args->oe_set_arg >= resize_len &&
|
||||||
|
STRNCMP(xp->xp_pattern - resize_len, "resize:", resize_len) == 0;
|
||||||
|
int is_shadow = xp->xp_pattern - args->oe_set_arg >= shadow_len &&
|
||||||
|
STRNCMP(xp->xp_pattern - shadow_len, "shadow:", shadow_len) == 0;
|
||||||
|
if (is_close || is_resize || is_shadow)
|
||||||
{
|
{
|
||||||
return expand_set_opt_string(
|
return expand_set_opt_string(
|
||||||
args,
|
args,
|
||||||
p_popup_option_border_values,
|
p_popup_option_on_off_values,
|
||||||
ARRAY_LENGTH(p_popup_option_border_values) - 1,
|
ARRAY_LENGTH(p_popup_option_on_off_values) - 1,
|
||||||
|
numMatches,
|
||||||
|
matches);
|
||||||
|
}
|
||||||
|
if (is_border)
|
||||||
|
{
|
||||||
|
return expand_set_opt_string(
|
||||||
|
args,
|
||||||
|
previewpopup ? p_popup_option_on_off_values
|
||||||
|
: p_popup_cpp_border_values,
|
||||||
|
(previewpopup ? ARRAY_LENGTH(p_popup_option_on_off_values)
|
||||||
|
: ARRAY_LENGTH(p_popup_cpp_border_values)) - 1,
|
||||||
numMatches,
|
numMatches,
|
||||||
matches);
|
matches);
|
||||||
}
|
}
|
||||||
@@ -3439,8 +3466,15 @@ expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches)
|
|||||||
matches);
|
matches);
|
||||||
}
|
}
|
||||||
int highlight_len = (int)STRLEN("highlight:");
|
int highlight_len = (int)STRLEN("highlight:");
|
||||||
if (xp->xp_pattern - args->oe_set_arg >= highlight_len &&
|
int borderhighlight_len = (int)STRLEN("borderhighlight:");
|
||||||
STRNCMP(xp->xp_pattern - highlight_len, "highlight:", highlight_len) == 0)
|
int is_highlight = xp->xp_pattern - args->oe_set_arg >= highlight_len
|
||||||
|
&& STRNCMP(xp->xp_pattern - highlight_len, "highlight:",
|
||||||
|
highlight_len) == 0;
|
||||||
|
int is_borderhighlight
|
||||||
|
= xp->xp_pattern - args->oe_set_arg >= borderhighlight_len
|
||||||
|
&& STRNCMP(xp->xp_pattern - borderhighlight_len, "highlight:",
|
||||||
|
borderhighlight_len) == 0;
|
||||||
|
if (is_highlight || is_borderhighlight)
|
||||||
{
|
{
|
||||||
// Return the list of all highlight names
|
// Return the list of all highlight names
|
||||||
return expand_set_opt_generic(
|
return expand_set_opt_generic(
|
||||||
@@ -3454,11 +3488,25 @@ expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches)
|
|||||||
|
|
||||||
return expand_set_opt_string(
|
return expand_set_opt_string(
|
||||||
args,
|
args,
|
||||||
p_popup_option_values,
|
previewpopup ? p_popup_pvp_option_values
|
||||||
ARRAY_LENGTH(p_popup_option_values) - 1,
|
: p_popup_cpp_option_values,
|
||||||
|
previewpopup ? ARRAY_LENGTH(p_popup_pvp_option_values) - 1
|
||||||
|
: ARRAY_LENGTH(p_popup_cpp_option_values) - 1,
|
||||||
numMatches,
|
numMatches,
|
||||||
matches);
|
matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
expand_set_previewpopup(optexpand_T *args, int *numMatches, char_u ***matches)
|
||||||
|
{
|
||||||
|
return expand_set_popupoption(args, numMatches, matches, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
expand_set_completepopup(optexpand_T *args, int *numMatches, char_u ***matches)
|
||||||
|
{
|
||||||
|
return expand_set_popupoption(args, numMatches, matches, FALSE);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(FEAT_POSTSCRIPT)
|
#if defined(FEAT_POSTSCRIPT)
|
||||||
|
205
src/popupwin.c
205
src/popupwin.c
@@ -1219,8 +1219,10 @@ popup_adjust_position(win_T *wp)
|
|||||||
int center_hor = FALSE;
|
int center_hor = FALSE;
|
||||||
int allow_adjust_left = !wp->w_popup_fixed;
|
int allow_adjust_left = !wp->w_popup_fixed;
|
||||||
int top_extra = popup_top_extra(wp);
|
int top_extra = popup_top_extra(wp);
|
||||||
int right_extra = wp->w_popup_border[1] + wp->w_popup_padding[1];
|
int right_extra = wp->w_popup_border[1] + wp->w_popup_padding[1]
|
||||||
int bot_extra = wp->w_popup_border[2] + wp->w_popup_padding[2];
|
+ (wp->w_popup_shadow ? 2 : 0);
|
||||||
|
int bot_extra = wp->w_popup_border[2] + wp->w_popup_padding[2]
|
||||||
|
+ wp->w_popup_shadow;
|
||||||
int left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
|
int left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
|
||||||
int extra_height = top_extra + bot_extra;
|
int extra_height = top_extra + bot_extra;
|
||||||
int extra_width = left_extra + right_extra;
|
int extra_width = left_extra + right_extra;
|
||||||
@@ -1782,6 +1784,21 @@ popup_set_buffer_text(buf_T *buf, typval_T text)
|
|||||||
curbuf = curwin->w_buffer;
|
curbuf = curwin->w_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SET_BORDER_CHARS(a0, a1, a2, a3, a4, a5, a6, a7) \
|
||||||
|
do { \
|
||||||
|
if (wp != NULL) \
|
||||||
|
{ \
|
||||||
|
wp->w_border_char[0] = (a0); \
|
||||||
|
wp->w_border_char[1] = (a1); \
|
||||||
|
wp->w_border_char[2] = (a2); \
|
||||||
|
wp->w_border_char[3] = (a3); \
|
||||||
|
wp->w_border_char[4] = (a4); \
|
||||||
|
wp->w_border_char[5] = (a5); \
|
||||||
|
wp->w_border_char[6] = (a6); \
|
||||||
|
wp->w_border_char[7] = (a7); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the 'previewpopup' or 'completepopup' option and apply the values to
|
* Parse the 'previewpopup' or 'completepopup' option and apply the values to
|
||||||
* window "wp" if it is not NULL.
|
* window "wp" if it is not NULL.
|
||||||
@@ -1795,6 +1812,7 @@ parse_popup_option(win_T *wp, int is_preview)
|
|||||||
!is_preview ? p_cpp :
|
!is_preview ? p_cpp :
|
||||||
#endif
|
#endif
|
||||||
p_pvp;
|
p_pvp;
|
||||||
|
int border_enabled = FALSE;
|
||||||
|
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
wp->w_popup_flags &= ~POPF_INFO_MENU;
|
wp->w_popup_flags &= ~POPF_INFO_MENU;
|
||||||
@@ -1847,28 +1865,159 @@ parse_popup_option(win_T *wp, int is_preview)
|
|||||||
|
|
||||||
*p = NUL;
|
*p = NUL;
|
||||||
set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
|
set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
|
||||||
s + 10, OPT_FREE|OPT_LOCAL, 0);
|
s + 10, OPT_FREE|OPT_LOCAL, 0);
|
||||||
*p = c;
|
*p = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (STRNCMP(s, "borderhighlight:", 16) == 0)
|
||||||
|
{
|
||||||
|
char_u *arg = s + 16;
|
||||||
|
|
||||||
|
if (*arg == NUL || *arg == ',')
|
||||||
|
return FAIL;
|
||||||
|
if (wp != NULL)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
VIM_CLEAR(wp->w_border_highlight[i]);
|
||||||
|
wp->w_border_highlight[i] = vim_strnsave(arg, p - arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (STRNCMP(s, "border:", 7) == 0)
|
else if (STRNCMP(s, "border:", 7) == 0)
|
||||||
{
|
{
|
||||||
// Note: Keep this in sync with p_popup_option_border_values.
|
|
||||||
char_u *arg = s + 7;
|
char_u *arg = s + 7;
|
||||||
int on = STRNCMP(arg, "on", 2) == 0 && arg + 2 == p;
|
|
||||||
int off = STRNCMP(arg, "off", 3) == 0 && arg + 3 == p;
|
|
||||||
int i;
|
int i;
|
||||||
|
int token_len = p - arg;
|
||||||
|
char_u *token;
|
||||||
|
// Use box-drawing characters only when 'encoding' is "utf-8" and
|
||||||
|
// 'ambiwidth' is "single".
|
||||||
|
int can_use_box_chars = (enc_utf8 && *p_ambw == 's');
|
||||||
|
|
||||||
if (!on && !off)
|
if (token_len == 0
|
||||||
|
|| (STRNCMP(arg, "off", 3) == 0 && arg + 3 == p))
|
||||||
|
{
|
||||||
|
if (wp != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
wp->w_popup_border[i] = 0;
|
||||||
|
SET_BORDER_CHARS(0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
// only show the X for close when there is a border
|
||||||
|
wp->w_popup_close = POPCLOSE_NONE;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = vim_strnsave(arg, token_len);
|
||||||
|
if (token == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
|
if ((can_use_box_chars && (STRCMP(token, "single") == 0
|
||||||
|
|| STRCMP(token, "double") == 0
|
||||||
|
|| STRCMP(token, "on") == 0
|
||||||
|
|| STRCMP(token, "round") == 0))
|
||||||
|
|| STRCMP(token, "ascii") == 0
|
||||||
|
|| (STRNCMP(token, "custom:", 7) == 0))
|
||||||
|
{
|
||||||
|
if (STRCMP(token, "single") == 0)
|
||||||
|
SET_BORDER_CHARS(0x2500, 0x2502, 0x2500, 0x2502, // ─ │ ─ │
|
||||||
|
0x250c, 0x2510, 0x2518, 0x2514); // ┌ ┐ ┘ └
|
||||||
|
else if (STRCMP(token, "double") == 0)
|
||||||
|
SET_BORDER_CHARS(0x2550, 0x2551, 0x2550, 0x2551, // ═ ║ ═ ║
|
||||||
|
0x2554, 0x2557, 0x255D, 0x255A); // ╔ ╗ ╝ ╚
|
||||||
|
else if (STRCMP(token, "round") == 0)
|
||||||
|
SET_BORDER_CHARS(0x2500, 0x2502, 0x2500, 0x2502, // ─ │ ─ │
|
||||||
|
0x256d, 0x256e, 0x256f, 0x2570); // ╭ ╮ ╯ ╰
|
||||||
|
else if (STRCMP(token, "on") == 0)
|
||||||
|
SET_BORDER_CHARS(0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
else if (STRCMP(token, "ascii") == 0)
|
||||||
|
SET_BORDER_CHARS('-', '|', '-', '|', '+', '+', '+', '+');
|
||||||
|
else if (STRNCMP(token, "custom:", 7) == 0)
|
||||||
|
{
|
||||||
|
char_u *q = token + 7;
|
||||||
|
int out[8];
|
||||||
|
int failed = FALSE;
|
||||||
|
|
||||||
|
SET_BORDER_CHARS(0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < 8 && !failed; i++)
|
||||||
|
{
|
||||||
|
if (*q == NUL)
|
||||||
|
failed = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[i] = mb_ptr2char(q);
|
||||||
|
mb_ptr2char_adv(&q);
|
||||||
|
if (i < 7)
|
||||||
|
{
|
||||||
|
if (*q != ';')
|
||||||
|
failed = TRUE; // must be semicolon
|
||||||
|
q++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (failed || *q != NUL) // must end exactly after the 8th char
|
||||||
|
{
|
||||||
|
vim_free(token);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
SET_BORDER_CHARS(out[0], out[1], out[2], out[3], out[4],
|
||||||
|
out[5], out[6], out[7]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vim_free(token);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 4; ++i)
|
for (i = 0; i < 4; ++i)
|
||||||
wp->w_popup_border[i] = on ? 1 : 0;
|
wp->w_popup_border[i] = 1;
|
||||||
if (off)
|
|
||||||
// only show the X for close when there is a border
|
|
||||||
wp->w_popup_close = POPCLOSE_NONE;
|
|
||||||
}
|
}
|
||||||
|
border_enabled = TRUE;
|
||||||
|
|
||||||
|
vim_free(token);
|
||||||
|
}
|
||||||
|
else if (STRNCMP(s, "close:", 6) == 0)
|
||||||
|
{
|
||||||
|
char_u *arg = s + 6;
|
||||||
|
int on = STRNCMP(arg, "on", 2) == 0 && arg + 2 == p;
|
||||||
|
int off = STRNCMP(arg, "off", 3) == 0 && arg + 3 == p;
|
||||||
|
|
||||||
|
if ((!on && !off) || is_preview)
|
||||||
|
return FAIL;
|
||||||
|
on = on && mouse_has(MOUSE_INSERT) && border_enabled;
|
||||||
|
if (wp != NULL)
|
||||||
|
wp->w_popup_close = on ? POPCLOSE_BUTTON : POPCLOSE_NONE;
|
||||||
|
}
|
||||||
|
else if (STRNCMP(s, "resize:", 7) == 0)
|
||||||
|
{
|
||||||
|
char_u *arg = s + 7;
|
||||||
|
int on = STRNCMP(arg, "on", 2) == 0 && arg + 2 == p;
|
||||||
|
int off = STRNCMP(arg, "off", 3) == 0 && arg + 3 == p;
|
||||||
|
|
||||||
|
if ((!on && !off) || is_preview)
|
||||||
|
return FAIL;
|
||||||
|
if (wp != NULL)
|
||||||
|
{
|
||||||
|
if (on && mouse_has(MOUSE_INSERT))
|
||||||
|
wp->w_popup_flags |= POPF_RESIZE;
|
||||||
|
else
|
||||||
|
wp->w_popup_flags &= ~POPF_RESIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (STRNCMP(s, "shadow:", 7) == 0)
|
||||||
|
{
|
||||||
|
char_u *arg = s + 7;
|
||||||
|
int on = STRNCMP(arg, "on", 2) == 0 && arg + 2 == p;
|
||||||
|
int off = STRNCMP(arg, "off", 3) == 0 && arg + 3 == p;
|
||||||
|
|
||||||
|
if ((!on && !off) || is_preview)
|
||||||
|
return FAIL;
|
||||||
|
if (wp != NULL)
|
||||||
|
wp->w_popup_shadow = on ? 1 : 0;
|
||||||
}
|
}
|
||||||
else if (STRNCMP(s, "align:", 6) == 0)
|
else if (STRNCMP(s, "align:", 6) == 0)
|
||||||
{
|
{
|
||||||
@@ -2297,6 +2446,12 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
|
|||||||
parse_previewpopup(wp);
|
parse_previewpopup(wp);
|
||||||
popup_set_wantpos_cursor(wp, wp->w_minwidth, d);
|
popup_set_wantpos_cursor(wp, wp->w_minwidth, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
VIM_CLEAR(wp->w_border_highlight[i]);
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
wp->w_border_char[i] = 0;
|
||||||
|
|
||||||
# ifdef FEAT_QUICKFIX
|
# ifdef FEAT_QUICKFIX
|
||||||
if (type == TYPE_INFO)
|
if (type == TYPE_INFO)
|
||||||
{
|
{
|
||||||
@@ -2311,10 +2466,6 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
for (i = 0; i < 4; ++i)
|
|
||||||
VIM_CLEAR(wp->w_border_highlight[i]);
|
|
||||||
for (i = 0; i < 8; ++i)
|
|
||||||
wp->w_border_char[i] = 0;
|
|
||||||
wp->w_want_scrollbar = 1;
|
wp->w_want_scrollbar = 1;
|
||||||
wp->w_popup_fixed = 0;
|
wp->w_popup_fixed = 0;
|
||||||
wp->w_filter_mode = MODE_ALL;
|
wp->w_filter_mode = MODE_ALL;
|
||||||
@@ -4151,7 +4302,6 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
else
|
else
|
||||||
wp->w_popup_flags &= ~POPF_ON_CMDLINE;
|
wp->w_popup_flags &= ~POPF_ON_CMDLINE;
|
||||||
|
|
||||||
|
|
||||||
// We can only use these line drawing characters when 'encoding' is
|
// We can only use these line drawing characters when 'encoding' is
|
||||||
// "utf-8" and 'ambiwidth' is "single".
|
// "utf-8" and 'ambiwidth' is "single".
|
||||||
if (enc_utf8 && *p_ambw == 's')
|
if (enc_utf8 && *p_ambw == 's')
|
||||||
@@ -4374,6 +4524,18 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
popup_attr);
|
popup_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// right shadow
|
||||||
|
if (wp->w_popup_shadow)
|
||||||
|
{
|
||||||
|
int col = wincol + total_width;
|
||||||
|
for (i = 0; i < total_height; ++i)
|
||||||
|
{
|
||||||
|
row = wp->w_winrow + i + 1;
|
||||||
|
put_shadow_char(row, col);
|
||||||
|
put_shadow_char(row, col + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (wp->w_popup_padding[2] > 0)
|
if (wp->w_popup_padding[2] > 0)
|
||||||
{
|
{
|
||||||
// bottom padding
|
// bottom padding
|
||||||
@@ -4387,7 +4549,7 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
{
|
{
|
||||||
// bottom border
|
// bottom border
|
||||||
row = wp->w_winrow + total_height - 1;
|
row = wp->w_winrow + total_height - 1;
|
||||||
screen_fill(row , row + 1,
|
screen_fill(row, row + 1,
|
||||||
wincol < 0 ? 0 : wincol,
|
wincol < 0 ? 0 : wincol,
|
||||||
wincol + total_width,
|
wincol + total_width,
|
||||||
wp->w_popup_border[3] != 0 && wp->w_popup_leftoff == 0
|
wp->w_popup_border[3] != 0 && wp->w_popup_leftoff == 0
|
||||||
@@ -4400,6 +4562,15 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wp->w_popup_shadow)
|
||||||
|
{
|
||||||
|
// bottom shadow
|
||||||
|
row = wp->w_winrow + total_height;
|
||||||
|
for (int col = 2 + (wincol < 0 ? 0 : wincol);
|
||||||
|
col < wincol + total_width; col++)
|
||||||
|
put_shadow_char(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
if (wp->w_popup_close == POPCLOSE_BUTTON)
|
if (wp->w_popup_close == POPCLOSE_BUTTON)
|
||||||
{
|
{
|
||||||
// close button goes on top of anything at the top-right corner
|
// close button goes on top of anything at the top-right corner
|
||||||
|
@@ -130,7 +130,8 @@ int expand_set_nrformats(optexpand_T *args, int *numMatches, char_u ***matches);
|
|||||||
char *did_set_optexpr(optset_T *args);
|
char *did_set_optexpr(optset_T *args);
|
||||||
char *did_set_pastetoggle(optset_T *args);
|
char *did_set_pastetoggle(optset_T *args);
|
||||||
char *did_set_previewpopup(optset_T *args);
|
char *did_set_previewpopup(optset_T *args);
|
||||||
int expand_set_popupoption(optexpand_T *args, int *numMatches, char_u ***matches);
|
int expand_set_previewpopup(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||||
|
int expand_set_completepopup(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||||
char *did_set_printencoding(optset_T *args);
|
char *did_set_printencoding(optset_T *args);
|
||||||
int expand_set_printoptions(optexpand_T *args, int *numMatches, char_u ***matches);
|
int expand_set_printoptions(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||||
char *did_set_renderoptions(optset_T *args);
|
char *did_set_renderoptions(optset_T *args);
|
||||||
|
@@ -4054,6 +4054,7 @@ struct window_S
|
|||||||
int w_popup_border[4]; // popup border top/right/bot/left
|
int w_popup_border[4]; // popup border top/right/bot/left
|
||||||
char_u *w_border_highlight[4]; // popup border highlight
|
char_u *w_border_highlight[4]; // popup border highlight
|
||||||
int w_border_char[8]; // popup border characters
|
int w_border_char[8]; // popup border characters
|
||||||
|
int w_popup_shadow; // popup shadow (right and bottom edges)
|
||||||
|
|
||||||
int w_popup_leftoff; // columns left of the screen
|
int w_popup_leftoff; // columns left of the screen
|
||||||
int w_popup_rightoff; // columns right of the screen
|
int w_popup_rightoff; // columns right of the screen
|
||||||
|
14
src/testdir/dumps/Test_popupwin_infopopup_9.dump
Normal file
14
src/testdir/dumps/Test_popupwin_infopopup_9.dump
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|a+0&#ffffff0|w|o|r|d| @69
|
||||||
|
|a|w|o|r|d> @69
|
||||||
|
|w+0#0000001#e0e0e08|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| | +0#0000000#0000001| +0#0000001#e0e0e08|w|o|r|d|s| |a|r|e| |c|o@1|l| | +0#4040ff13#ffffff0@36
|
||||||
|
|a+0#0000001#ffd7ff255|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| | +0#0000000#0000001| +0#4040ff13#ffffff0@1| +0#6c6c6c255#0000001@15| +0#4040ff13#ffffff0@34
|
||||||
|
|n+0#0000001#ffd7ff255|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| | +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@52
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@26
|
@@ -637,7 +637,7 @@ func Test_set_completion_string_values()
|
|||||||
set keyprotocol&
|
set keyprotocol&
|
||||||
|
|
||||||
" previewpopup / completepopup
|
" previewpopup / completepopup
|
||||||
call assert_equal('align:', getcompletion('set previewpopup=', 'cmdline')[0])
|
call assert_equal('height:', getcompletion('set previewpopup=', 'cmdline')[0])
|
||||||
call assert_equal('EndOfBuffer', getcompletion('set previewpopup=highlight:End*Buffer', 'cmdline')[0])
|
call assert_equal('EndOfBuffer', getcompletion('set previewpopup=highlight:End*Buffer', 'cmdline')[0])
|
||||||
call feedkeys(":set previewpopup+=border:\<Tab>\<C-B>\"\<CR>", 'xt')
|
call feedkeys(":set previewpopup+=border:\<Tab>\<C-B>\"\<CR>", 'xt')
|
||||||
call assert_equal('"set previewpopup+=border:on', @:)
|
call assert_equal('"set previewpopup+=border:on', @:)
|
||||||
|
@@ -3701,6 +3701,12 @@ func Test_popupmenu_info_border()
|
|||||||
call term_sendkeys(buf, "a\<C-X>\<C-U>")
|
call term_sendkeys(buf, "a\<C-X>\<C-U>")
|
||||||
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_8', {})
|
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_8', {})
|
||||||
|
|
||||||
|
" Test shadow
|
||||||
|
call term_sendkeys(buf, "\<Esc>")
|
||||||
|
call term_sendkeys(buf, ":set completepopup=border:off,shadow:on\<CR>")
|
||||||
|
call term_sendkeys(buf, "Sa\<C-X>\<C-U>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_9', {})
|
||||||
|
|
||||||
call term_sendkeys(buf, "\<Esc>")
|
call term_sendkeys(buf, "\<Esc>")
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
endfunc
|
endfunc
|
||||||
|
@@ -729,6 +729,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1856,
|
||||||
/**/
|
/**/
|
||||||
1855,
|
1855,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user