mirror of
https://github.com/vim/vim.git
synced 2025-07-04 23:07:33 -04:00
Merge bc8b161ddc8814beffd5edf38ebc6a06ba3e4f93 into a494ce1c64a2637719a5c1339abf19ec7c48089c
This commit is contained in:
commit
c905f41961
@ -4583,7 +4583,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
A:DiffAdd,C:DiffChange,D:DiffDelete,
|
||||
T:DiffText,E:DiffTextAdd,>:SignColumn,
|
||||
-:Conceal,B:SpellBad,P:SpellCap,
|
||||
R:SpellRare, L:SpellLocal,+:Pmenu,
|
||||
R:SpellRare, L:SpellLocal,
|
||||
+:Pmenu,I:PmenuBorder,
|
||||
=:PmenuSel, k:PmenuMatch,<:PmenuMatchSel,
|
||||
[:PmenuKind,]:PmenuKindSel,
|
||||
{:PmenuExtra,}:PmenuExtraSel,
|
||||
@ -6674,6 +6675,29 @@ 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.
|
||||
|
||||
*'pumborder'* *'pbr'*
|
||||
'pumborder' 'pbr' string (default "")
|
||||
global
|
||||
When non-empty, specifies the border style used for the
|
||||
|ins-completion-menu| during completion. This affects how the border
|
||||
around the popup menu is drawn.
|
||||
Possible values are:
|
||||
"single" a single-line border
|
||||
"double" a double-line border
|
||||
"rounded" a rounded border using box-drawing characters
|
||||
"solid" a solid block-style border
|
||||
"shadow" a shadow-like border style
|
||||
|
||||
Alternatively, a custom border style can be defined by specifying
|
||||
a comma-separated list of eight border characters. The expected
|
||||
order is as follows:
|
||||
Top-left corner, Top border, Top-right corner, Right border
|
||||
Bot-right corner, Bot border, Bot-left corner, Left border
|
||||
|
||||
Example: >
|
||||
:set pumborder=rounded
|
||||
:set pumborder=+,-,+,\|,+,-,+,\|
|
||||
<
|
||||
*'pumheight'* *'ph'*
|
||||
'pumheight' 'ph' number (default 0)
|
||||
global
|
||||
|
@ -5915,6 +5915,8 @@ NonText '@' at the end of the window, "<<<" at the start of the window
|
||||
Normal Normal text.
|
||||
*hl-Pmenu*
|
||||
Pmenu Popup menu: Normal item.
|
||||
*hl-PmenuBorder*
|
||||
PmenuBorder Popup menu: Border character.
|
||||
*hl-PmenuSel*
|
||||
PmenuSel Popup menu: Selected item.
|
||||
*hl-PmenuKind*
|
||||
|
@ -841,6 +841,7 @@ $quote eval.txt /*$quote*
|
||||
'patchexpr' options.txt /*'patchexpr'*
|
||||
'patchmode' options.txt /*'patchmode'*
|
||||
'path' options.txt /*'path'*
|
||||
'pbr' options.txt /*'pbr'*
|
||||
'pdev' options.txt /*'pdev'*
|
||||
'penc' options.txt /*'penc'*
|
||||
'perldll' options.txt /*'perldll'*
|
||||
@ -870,6 +871,7 @@ $quote eval.txt /*$quote*
|
||||
'printoptions' options.txt /*'printoptions'*
|
||||
'prompt' options.txt /*'prompt'*
|
||||
'pt' options.txt /*'pt'*
|
||||
'pumborder' options.txt /*'pumborder'*
|
||||
'pumheight' options.txt /*'pumheight'*
|
||||
'pummaxwidth' options.txt /*'pummaxwidth'*
|
||||
'pumwidth' options.txt /*'pumwidth'*
|
||||
@ -8280,6 +8282,7 @@ hl-MsgArea syntax.txt /*hl-MsgArea*
|
||||
hl-NonText syntax.txt /*hl-NonText*
|
||||
hl-Normal syntax.txt /*hl-Normal*
|
||||
hl-Pmenu syntax.txt /*hl-Pmenu*
|
||||
hl-PmenuBorder syntax.txt /*hl-PmenuBorder*
|
||||
hl-PmenuExtra syntax.txt /*hl-PmenuExtra*
|
||||
hl-PmenuExtraSel syntax.txt /*hl-PmenuExtraSel*
|
||||
hl-PmenuKind syntax.txt /*hl-PmenuKind*
|
||||
|
@ -260,6 +260,7 @@ static char *(highlight_init_both[]) = {
|
||||
"default link CursorLineSign SignColumn",
|
||||
"default link CursorLineFold FoldColumn",
|
||||
"default link CurSearch Search",
|
||||
"default link PmenuBorder Pmenu",
|
||||
"default link PmenuKind Pmenu",
|
||||
"default link PmenuKindSel PmenuSel",
|
||||
"default link PmenuMatch Pmenu",
|
||||
|
@ -521,6 +521,7 @@ EXTERN unsigned cfc_flags; // flags from "completefuzzycollect"
|
||||
EXTERN char_u *p_cia; // 'completeitemalign'
|
||||
EXTERN unsigned cia_flags; // order flags of 'completeitemalign'
|
||||
EXTERN char_u *p_cot; // 'completeopt'
|
||||
EXTERN char_u *p_pbr; // 'pumborder'
|
||||
EXTERN unsigned cot_flags; // flags from 'completeopt'
|
||||
// Keep in sync with p_cot_values in optionstr.c
|
||||
#define COT_MENU 0x001
|
||||
|
@ -2058,6 +2058,9 @@ static struct vimoption options[] =
|
||||
{"prompt", NULL, P_BOOL|P_VI_DEF,
|
||||
(char_u *)&p_prompt, PV_NONE, NULL, NULL,
|
||||
{(char_u *)TRUE, (char_u *)0L} SCTX_INIT},
|
||||
{"pumborder", "pbr", P_STRING|P_VI_DEF,
|
||||
(char_u *)&p_pbr, PV_NONE, did_set_pumborder, NULL,
|
||||
{(char_u *)"", (char_u *)0L} SCTX_INIT},
|
||||
{"pumheight", "ph", P_NUM|P_VI_DEF,
|
||||
(char_u *)&p_ph, PV_NONE, NULL, NULL,
|
||||
{(char_u *)0L, (char_u *)0L} SCTX_INIT},
|
||||
|
@ -3338,6 +3338,17 @@ did_set_optexpr(optset_T *args)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The 'pumborder' option is changed
|
||||
*/
|
||||
char *
|
||||
did_set_pumborder(optset_T *args UNUSED)
|
||||
{
|
||||
if (!pum_parse_border())
|
||||
return e_invalid_argument;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The 'pastetoggle' option is changed.
|
||||
*/
|
||||
|
205
src/popupmenu.c
205
src/popupmenu.c
@ -39,6 +39,8 @@ static int pum_win_height;
|
||||
static int pum_win_col;
|
||||
static int pum_win_wcol;
|
||||
static int pum_win_width;
|
||||
static int pum_border_chars[8];
|
||||
static int pum_has_border = FALSE;
|
||||
|
||||
// Some parts are not updated when a popup menu is visible. Setting this flag
|
||||
// makes pum_visible() return FALSE even when there is a popup menu.
|
||||
@ -104,6 +106,7 @@ pum_display(
|
||||
int content_width;
|
||||
int right_edge_col;
|
||||
int redo_count = 0;
|
||||
int border_cells = pum_has_border ? 2 : 0;
|
||||
#if defined(FEAT_QUICKFIX)
|
||||
win_T *pvwin;
|
||||
#endif
|
||||
@ -161,7 +164,7 @@ pum_display(
|
||||
|
||||
// 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
|
||||
if (pum_win_row + 2 + border_cells >= below_row - pum_height
|
||||
&& pum_win_row - above_row > (below_row - above_row) / 2)
|
||||
{
|
||||
// pum above "pum_win_row"
|
||||
@ -187,6 +190,14 @@ pum_display(
|
||||
pum_row += pum_height - p_ph;
|
||||
pum_height = p_ph;
|
||||
}
|
||||
|
||||
if (pum_has_border && border_cells + pum_row + pum_height > pum_win_row)
|
||||
{
|
||||
if (pum_row < 2)
|
||||
pum_height -= border_cells;
|
||||
else
|
||||
pum_row -= border_cells;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -207,6 +218,10 @@ pum_display(
|
||||
pum_height = MIN(below_row - pum_row, size);
|
||||
if (p_ph > 0 && pum_height > p_ph)
|
||||
pum_height = p_ph;
|
||||
|
||||
if ((State == MODE_CMDLINE)
|
||||
&& pum_row + pum_height + border_cells >= cmdline_row)
|
||||
pum_height -= border_cells;
|
||||
}
|
||||
|
||||
// don't display when we only have room for one line
|
||||
@ -375,6 +390,9 @@ pum_display(
|
||||
pum_width = max_width - pum_scrollbar;
|
||||
}
|
||||
|
||||
if (pum_col + border_cells + pum_width > Columns)
|
||||
pum_col -= border_cells;
|
||||
|
||||
// Set selected item and redraw. If the window size changed need to
|
||||
// redo the positioning. Limit this to two times, when there is not
|
||||
// much room the window size will keep changing.
|
||||
@ -872,6 +890,148 @@ pum_draw_scrollbar(
|
||||
screen_putchar(' ', row, pum_col + pum_width, attr);
|
||||
}
|
||||
|
||||
int
|
||||
pum_parse_border(void)
|
||||
{
|
||||
int i;
|
||||
char_u *p = p_pbr;
|
||||
char_u *next = NULL;
|
||||
int this_char;
|
||||
int comb[MAX_MCO];
|
||||
char_u buf[10];
|
||||
int len;
|
||||
int tmp[8];
|
||||
|
||||
struct {
|
||||
char_u *name;
|
||||
int c[8];
|
||||
} defaults[] = {
|
||||
{ (char_u *)"double", { 0x2554, 0x2550, 0x2557, 0x2551,
|
||||
0x255D, 0x2550, 0x255A, 0x2551 } },
|
||||
{ (char_u *)"single", { 0x250C, 0x2500, 0x2510, 0x2502,
|
||||
0x2518, 0x2500, 0x2514, 0x2502 } },
|
||||
{ (char_u *)"rounded", { 0x256D, 0x2500, 0x256E, 0x2502,
|
||||
0x256F, 0x2500, 0x2570, 0x2502 } },
|
||||
{ (char_u *)"bold", { 0x250F, 0x2501, 0x2513, 0x2503,
|
||||
0x251B, 0x2501, 0x2517, 0x2503 } },
|
||||
{ (char_u *)"solid", { 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20 } },
|
||||
};
|
||||
|
||||
if (*p_pbr == NUL)
|
||||
{
|
||||
pum_has_border = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (STRCMP(p_pbr, defaults[i].name) == 0)
|
||||
{
|
||||
memcpy(pum_border_chars, defaults[i].c, 8 * sizeof(int));
|
||||
pum_has_border = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
next = vim_strchr(p, ',');
|
||||
if (next)
|
||||
{
|
||||
len = (int)(next - p);
|
||||
if (len > 9)
|
||||
len = 9;
|
||||
vim_strncpy(buf, p, len);
|
||||
buf[len] = NUL;
|
||||
p = next + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_strncpy(buf, p, 9);
|
||||
buf[9] = NUL;
|
||||
p += STRLEN(buf);
|
||||
}
|
||||
this_char = utfc_ptr2char(buf, comb);
|
||||
if (!vim_isprintc(this_char))
|
||||
{
|
||||
pum_has_border = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
tmp[i] = this_char;
|
||||
}
|
||||
|
||||
if (*p != NUL)
|
||||
{
|
||||
pum_has_border = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(pum_border_chars, tmp, 8 * sizeof(int));
|
||||
pum_has_border = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pum_draw_border(int *border_char, int thumb_pos, int thumb_height)
|
||||
{
|
||||
int i;
|
||||
int row = pum_row;
|
||||
int col = pum_col;
|
||||
int attr = syn_name2attr((char_u *)"PmenuBorder");
|
||||
int width = pum_width - (State & MODE_CMDLINE ? 1 : 0);
|
||||
int height = pum_height;
|
||||
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (pum_rl)
|
||||
{
|
||||
// topright leftright botright botleft
|
||||
screen_putchar(border_char[2], row, col + 1, attr);
|
||||
screen_putchar(border_char[0], row, col - width, attr);
|
||||
screen_putchar(border_char[4], row + height + 1, col + 1, attr);
|
||||
screen_putchar(border_char[6], row + height + 1, col - width, attr);
|
||||
|
||||
// top bot
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
screen_putchar(border_char[1], row, col - i, attr);
|
||||
screen_putchar(border_char[5], row + height + 1, col - i, attr);
|
||||
}
|
||||
|
||||
// left right
|
||||
for (i = 1; i < height + 1; i++)
|
||||
{
|
||||
screen_putchar(border_char[3], row + i, col + 1, attr);
|
||||
if (!pum_scrollbar || i < thumb_pos || i >= thumb_pos + thumb_height)
|
||||
screen_putchar(border_char[7], row + i, col - width, attr);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// topleft topright botleft botright
|
||||
screen_putchar(border_char[0], row, col, attr);
|
||||
screen_putchar(border_char[2], row, col + width, attr);
|
||||
screen_putchar(border_char[6], row + height + 1, col, attr);
|
||||
screen_putchar(border_char[4], row + height + 1, col + width, attr);
|
||||
|
||||
// top bot
|
||||
for (i = 1; i < width; i++)
|
||||
{
|
||||
screen_putchar(border_char[1], row, col + i, attr);
|
||||
screen_putchar(border_char[5], row + height + 1, col + i, attr);
|
||||
}
|
||||
|
||||
// left right
|
||||
for (i = 1; i < height + 1; i++)
|
||||
{
|
||||
screen_putchar(border_char[7], row + i, col, attr);
|
||||
if (!pum_scrollbar || i - 1 < thumb_pos || i - 1 >= thumb_pos + thumb_height)
|
||||
screen_putchar(border_char[3], row + i, col + width, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Redraw the popup menu, using "pum_first" and "pum_selected".
|
||||
*/
|
||||
@ -898,7 +1058,9 @@ pum_redraw(void)
|
||||
int basic_width; // first item width
|
||||
int last_isabbr = FALSE;
|
||||
int orig_attr = -1;
|
||||
int scroll_range = pum_size - pum_height;
|
||||
int border_cells = pum_has_border ? 2 : 0;
|
||||
int scroll_range = pum_size - pum_height + border_cells;
|
||||
int col_off = pum_has_border > 0 ? 1 : 0;
|
||||
|
||||
hlf_T hlfsNorm[3];
|
||||
hlf_T hlfsSel[3];
|
||||
@ -940,6 +1102,9 @@ pum_redraw(void)
|
||||
screen_zindex = POPUPMENU_ZINDEX;
|
||||
#endif
|
||||
|
||||
if (pum_has_border > 0)
|
||||
++row;
|
||||
|
||||
for (i = 0; i < pum_height; ++i)
|
||||
{
|
||||
idx = i + pum_first;
|
||||
@ -947,21 +1112,31 @@ pum_redraw(void)
|
||||
hlf = hlfs[0]; // start with "word" highlight
|
||||
attr = highlight_attr[hlf];
|
||||
|
||||
// prepend a space if there is room
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (pum_rl)
|
||||
if (!pum_has_border)
|
||||
{
|
||||
if (pum_col < curwin->w_wincol + curwin->w_width - 1)
|
||||
screen_putchar(' ', row, pum_col + 1, attr);
|
||||
}
|
||||
else
|
||||
// prepend a space if there is room
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (pum_rl)
|
||||
{
|
||||
if (pum_col < curwin->w_wincol + curwin->w_width - 1)
|
||||
screen_putchar(' ', row, pum_col + 1, attr);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (pum_col > 0)
|
||||
screen_putchar(' ', row, pum_col - 1, attr);
|
||||
if (pum_col > 0)
|
||||
screen_putchar(' ', row, pum_col - 1, attr);
|
||||
}
|
||||
|
||||
// Display each entry, use two spaces for a Tab.
|
||||
// Do this 3 times and order from p_cia
|
||||
col = pum_col;
|
||||
if (pum_has_border > 0)
|
||||
{
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (!pum_rl)
|
||||
#endif
|
||||
++col;
|
||||
}
|
||||
totwidth = 0;
|
||||
pum_align_order(order);
|
||||
basic_width = items_width_array[order[0]];
|
||||
@ -1005,9 +1180,9 @@ pum_redraw(void)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
screen_fill(row, row + 1, col, pum_col + basic_width + n,
|
||||
screen_fill(row, row + 1, col, pum_col + basic_width + n + col_off,
|
||||
' ', ' ', orig_attr);
|
||||
col = pum_col + basic_width + n;
|
||||
col = pum_col + basic_width + n + col_off;
|
||||
}
|
||||
totwidth = basic_width + n;
|
||||
}
|
||||
@ -1021,10 +1196,12 @@ pum_redraw(void)
|
||||
screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ',
|
||||
orig_attr);
|
||||
pum_draw_scrollbar(row, i, thumb_pos, thumb_height);
|
||||
|
||||
++row;
|
||||
}
|
||||
|
||||
if (pum_has_border && pum_window != NULL)
|
||||
pum_draw_border(pum_border_chars, thumb_pos, thumb_height);
|
||||
|
||||
#ifdef FEAT_PROP_POPUP
|
||||
screen_zindex = 0;
|
||||
#endif
|
||||
|
@ -208,4 +208,5 @@ int check_ff_value(char_u *p);
|
||||
void save_clear_shm_value(void);
|
||||
void restore_shm_value(void);
|
||||
void export_myvimdir(void);
|
||||
char *did_set_pumborder(optset_T *args);
|
||||
/* vim: set ft=c : */
|
||||
|
@ -17,4 +17,5 @@ void ui_post_balloon(char_u *mesg, list_T *list);
|
||||
void ui_may_remove_balloon(void);
|
||||
void pum_show_popupmenu(vimmenu_T *menu);
|
||||
void pum_make_popup(char_u *path_name, int use_mouse_pos);
|
||||
int pum_parse_border(void);
|
||||
/* vim: set ft=c : */
|
||||
|
@ -275,6 +275,8 @@ let test_values = {
|
||||
\ ['xxx', 'xxx,c:yes', 'xxx:', 'xxx:,c:yes']],
|
||||
\ 'printoptions': [['', 'header:0', 'left:10pc,top:5pc'],
|
||||
\ ['xxx', 'header:-1']],
|
||||
\ 'pumborder': [['', 'single', 'rounded', '+,-,+,\|,+,-,+,\|'],
|
||||
\ ['xxx', '+,-,+,\|,+,-,+,']],
|
||||
\ 'scrollopt': [['', 'ver', 'hor', 'jump', 'ver,hor'], ['xxx']],
|
||||
\ 'renderoptions': [[''], ['xxx']],
|
||||
\ 'rightleftcmd': [['search'], ['xxx']],
|
||||
|
Loading…
x
Reference in New Issue
Block a user