mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.0.1558: no right-click menu in a terminal
Problem: No right-click menu in a terminal. Solution: Implement the right click menu for the terminal.
This commit is contained in:
parent
c71807db9c
commit
aef8c3da2b
@ -726,6 +726,13 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* popup menu in a terminal
|
||||||
|
*/
|
||||||
|
#if defined(FEAT_MENU) && !defined(ALWAYS_USE_GUI) && defined(FEAT_INS_EXPAND)
|
||||||
|
# define FEAT_TERM_POPUP_MENU
|
||||||
|
#endif
|
||||||
|
|
||||||
/* There are two ways to use XPM. */
|
/* There are two ways to use XPM. */
|
||||||
#if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \
|
#if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \
|
||||||
|| defined(HAVE_X11_XPM_H)
|
|| defined(HAVE_X11_XPM_H)
|
||||||
|
124
src/menu.c
124
src/menu.c
@ -34,10 +34,6 @@ static int menu_namecmp(char_u *name, char_u *mname);
|
|||||||
static int get_menu_cmd_modes(char_u *, int, int *, int *);
|
static int get_menu_cmd_modes(char_u *, int, int *, int *);
|
||||||
static char_u *popup_mode_name(char_u *name, int idx);
|
static char_u *popup_mode_name(char_u *name, int idx);
|
||||||
static char_u *menu_text(char_u *text, int *mnemonic, char_u **actext);
|
static char_u *menu_text(char_u *text, int *mnemonic, char_u **actext);
|
||||||
#ifdef FEAT_GUI
|
|
||||||
static int get_menu_mode(void);
|
|
||||||
static void gui_update_menus_recurse(vimmenu_T *, int);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
|
#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
|
||||||
static void gui_create_tearoffs_recurse(vimmenu_T *menu, const char_u *pname, int *pri_tab, int pri_idx);
|
static void gui_create_tearoffs_recurse(vimmenu_T *menu, const char_u *pname, int *pri_tab, int pri_idx);
|
||||||
@ -1871,7 +1867,7 @@ menu_is_tearoff(char_u *name UNUSED)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_GUI
|
#if defined(FEAT_GUI) || defined(FEAT_TERM_POPUP_MENU) || defined(PROTO)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_menu_mode(void)
|
get_menu_mode(void)
|
||||||
@ -1895,6 +1891,60 @@ get_menu_mode(void)
|
|||||||
return MENU_INDEX_INVALID;
|
return MENU_INDEX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display the Special "PopUp" menu as a pop-up at the current mouse
|
||||||
|
* position. The "PopUpn" menu is for Normal mode, "PopUpi" for Insert mode,
|
||||||
|
* etc.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
show_popupmenu(void)
|
||||||
|
{
|
||||||
|
vimmenu_T *menu;
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
mode = get_menu_mode();
|
||||||
|
if (mode == MENU_INDEX_INVALID)
|
||||||
|
return;
|
||||||
|
mode = menu_mode_chars[mode];
|
||||||
|
|
||||||
|
# ifdef FEAT_AUTOCMD
|
||||||
|
{
|
||||||
|
char_u ename[2];
|
||||||
|
|
||||||
|
ename[0] = mode;
|
||||||
|
ename[1] = NUL;
|
||||||
|
apply_autocmds(EVENT_MENUPOPUP, ename, NULL, FALSE, curbuf);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
for (menu = root_menu; menu != NULL; menu = menu->next)
|
||||||
|
if (STRNCMP("PopUp", menu->name, 5) == 0 && menu->name[5] == mode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Only show a popup when it is defined and has entries */
|
||||||
|
if (menu != NULL && menu->children != NULL)
|
||||||
|
{
|
||||||
|
# if defined(FEAT_GUI)
|
||||||
|
if (gui.in_use)
|
||||||
|
{
|
||||||
|
/* Update the menus now, in case the MenuPopup autocommand did
|
||||||
|
* anything. */
|
||||||
|
gui_update_menus(0);
|
||||||
|
gui_mch_show_popupmenu(menu);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# if defined(FEAT_GUI) && defined(FEAT_TERM_POPUP_MENU)
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
# if defined(FEAT_TERM_POPUP_MENU)
|
||||||
|
pum_show_popupmenu(menu);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FEAT_GUI) || defined(PROTO)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that a pointer appears in the menu tree. Used to protect from using
|
* Check that a pointer appears in the menu tree. Used to protect from using
|
||||||
* a menu that was deleted after it was selected but before the event was
|
* a menu that was deleted after it was selected but before the event was
|
||||||
@ -1955,28 +2005,28 @@ gui_update_menus_recurse(vimmenu_T *menu, int mode)
|
|||||||
while (menu)
|
while (menu)
|
||||||
{
|
{
|
||||||
if ((menu->modes & menu->enabled & mode)
|
if ((menu->modes & menu->enabled & mode)
|
||||||
#if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
|
# if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)
|
||||||
|| menu_is_tearoff(menu->dname)
|
|| menu_is_tearoff(menu->dname)
|
||||||
#endif
|
# endif
|
||||||
)
|
)
|
||||||
grey = FALSE;
|
grey = FALSE;
|
||||||
else
|
else
|
||||||
grey = TRUE;
|
grey = TRUE;
|
||||||
#ifdef FEAT_GUI_ATHENA
|
# ifdef FEAT_GUI_ATHENA
|
||||||
/* Hiding menus doesn't work for Athena, it can cause a crash. */
|
/* Hiding menus doesn't work for Athena, it can cause a crash. */
|
||||||
gui_mch_menu_grey(menu, grey);
|
gui_mch_menu_grey(menu, grey);
|
||||||
#else
|
# else
|
||||||
/* Never hide a toplevel menu, it may make the menubar resize or
|
/* Never hide a toplevel menu, it may make the menubar resize or
|
||||||
* disappear. Same problem for ToolBar items. */
|
* disappear. Same problem for ToolBar items. */
|
||||||
if (vim_strchr(p_go, GO_GREY) != NULL || menu->parent == NULL
|
if (vim_strchr(p_go, GO_GREY) != NULL || menu->parent == NULL
|
||||||
# ifdef FEAT_TOOLBAR
|
# ifdef FEAT_TOOLBAR
|
||||||
|| menu_is_toolbar(menu->parent->name)
|
|| menu_is_toolbar(menu->parent->name)
|
||||||
# endif
|
# endif
|
||||||
)
|
)
|
||||||
gui_mch_menu_grey(menu, grey);
|
gui_mch_menu_grey(menu, grey);
|
||||||
else
|
else
|
||||||
gui_mch_menu_hidden(menu, grey);
|
gui_mch_menu_hidden(menu, grey);
|
||||||
#endif
|
# endif
|
||||||
gui_update_menus_recurse(menu->children, mode);
|
gui_update_menus_recurse(menu->children, mode);
|
||||||
menu = menu->next;
|
menu = menu->next;
|
||||||
}
|
}
|
||||||
@ -2010,15 +2060,15 @@ gui_update_menus(int modes)
|
|||||||
gui_mch_draw_menubar();
|
gui_mch_draw_menubar();
|
||||||
prev_mode = mode;
|
prev_mode = mode;
|
||||||
force_menu_update = FALSE;
|
force_menu_update = FALSE;
|
||||||
#ifdef FEAT_GUI_W32
|
# ifdef FEAT_GUI_W32
|
||||||
/* This can leave a tearoff as active window - make sure we
|
/* This can leave a tearoff as active window - make sure we
|
||||||
* have the focus <negri>*/
|
* have the focus <negri>*/
|
||||||
gui_mch_activate_window();
|
gui_mch_activate_window();
|
||||||
#endif
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \
|
# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \
|
||||||
|| defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(PROTO)
|
|| defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(PROTO)
|
||||||
/*
|
/*
|
||||||
* Check if a key is used as a mnemonic for a toplevel menu.
|
* Check if a key is used as a mnemonic for a toplevel menu.
|
||||||
@ -2037,47 +2087,7 @@ gui_is_menu_shortcut(int key)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Display the Special "PopUp" menu as a pop-up at the current mouse
|
|
||||||
* position. The "PopUpn" menu is for Normal mode, "PopUpi" for Insert mode,
|
|
||||||
* etc.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gui_show_popupmenu(void)
|
|
||||||
{
|
|
||||||
vimmenu_T *menu;
|
|
||||||
int mode;
|
|
||||||
|
|
||||||
mode = get_menu_mode();
|
|
||||||
if (mode == MENU_INDEX_INVALID)
|
|
||||||
return;
|
|
||||||
mode = menu_mode_chars[mode];
|
|
||||||
|
|
||||||
#ifdef FEAT_AUTOCMD
|
|
||||||
{
|
|
||||||
char_u ename[2];
|
|
||||||
|
|
||||||
ename[0] = mode;
|
|
||||||
ename[1] = NUL;
|
|
||||||
apply_autocmds(EVENT_MENUPOPUP, ename, NULL, FALSE, curbuf);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (menu = root_menu; menu != NULL; menu = menu->next)
|
|
||||||
if (STRNCMP("PopUp", menu->name, 5) == 0 && menu->name[5] == mode)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Only show a popup when it is defined and has entries */
|
|
||||||
if (menu != NULL && menu->children != NULL)
|
|
||||||
{
|
|
||||||
/* Update the menus now, in case the MenuPopup autocommand did
|
|
||||||
* anything. */
|
|
||||||
gui_update_menus(0);
|
|
||||||
gui_mch_show_popupmenu(menu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* FEAT_GUI */
|
#endif /* FEAT_GUI */
|
||||||
|
|
||||||
#if (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)) || defined(PROTO)
|
#if (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)) || defined(PROTO)
|
||||||
@ -2238,7 +2248,7 @@ gui_destroy_tearoffs_recurse(vimmenu_T *menu)
|
|||||||
* Execute "menu". Use by ":emenu" and the window toolbar.
|
* Execute "menu". Use by ":emenu" and the window toolbar.
|
||||||
* "eap" is NULL for the window toolbar.
|
* "eap" is NULL for the window toolbar.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
execute_menu(exarg_T *eap, vimmenu_T *menu)
|
execute_menu(exarg_T *eap, vimmenu_T *menu)
|
||||||
{
|
{
|
||||||
char_u *mode;
|
char_u *mode;
|
||||||
|
146
src/normal.c
146
src/normal.c
@ -2286,12 +2286,12 @@ op_function(oparg_T *oap UNUSED)
|
|||||||
* Do the appropriate action for the current mouse click in the current mode.
|
* Do the appropriate action for the current mouse click in the current mode.
|
||||||
* Not used for Command-line mode.
|
* Not used for Command-line mode.
|
||||||
*
|
*
|
||||||
* Normal Mode:
|
* Normal and Visual Mode:
|
||||||
* event modi- position visual change action
|
* event modi- position visual change action
|
||||||
* fier cursor window
|
* fier cursor window
|
||||||
* left press - yes end yes
|
* left press - yes end yes
|
||||||
* left press C yes end yes "^]" (2)
|
* left press C yes end yes "^]" (2)
|
||||||
* left press S yes end yes "*" (2)
|
* left press S yes end (popup: extend) yes "*" (2)
|
||||||
* left drag - yes start if moved no
|
* left drag - yes start if moved no
|
||||||
* left relse - yes start if moved no
|
* left relse - yes start if moved no
|
||||||
* middle press - yes if not active no put register
|
* middle press - yes if not active no put register
|
||||||
@ -2670,82 +2670,94 @@ do_mouse(
|
|||||||
if (which_button == MOUSE_RIGHT
|
if (which_button == MOUSE_RIGHT
|
||||||
&& !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)))
|
&& !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)))
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* NOTE: Ignore right button down and drag mouse events.
|
|
||||||
* Windows only shows the popup menu on the button up event.
|
|
||||||
*/
|
|
||||||
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
|
|
||||||
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
|
|
||||||
if (!is_click)
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
#if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN)
|
|
||||||
if (is_click || is_drag)
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
|
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
|
||||||
|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
|
|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
|
||||||
|| defined(FEAT_GUI_MAC) || defined(FEAT_GUI_PHOTON)
|
|| defined(FEAT_GUI_MAC) || defined(FEAT_GUI_PHOTON) \
|
||||||
|
|| defined(FEAT_TERM_POPUP_MENU)
|
||||||
|
# ifdef FEAT_GUI
|
||||||
if (gui.in_use)
|
if (gui.in_use)
|
||||||
{
|
{
|
||||||
jump_flags = 0;
|
# if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
|
||||||
if (STRCMP(p_mousem, "popup_setpos") == 0)
|
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
|
||||||
{
|
if (!is_click)
|
||||||
/* First set the cursor position before showing the popup
|
/* Ignore right button release events, only shows the popup
|
||||||
* menu. */
|
* menu on the button down event. */
|
||||||
if (VIsual_active)
|
return FALSE;
|
||||||
{
|
# endif
|
||||||
pos_T m_pos;
|
# if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN)
|
||||||
|
if (is_click || is_drag)
|
||||||
|
/* Ignore right button down and drag mouse events. Windows
|
||||||
|
* only shows the popup menu on the button up event. */
|
||||||
|
return FALSE;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# if defined(FEAT_GUI) && defined(FEAT_TERM_POPUP_MENU)
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
# if defined(FEAT_TERM_POPUP_MENU)
|
||||||
|
if (!is_click)
|
||||||
|
/* Ignore right button release events, only shows the popup
|
||||||
|
* menu on the button down event. */
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
jump_flags = 0;
|
||||||
* set MOUSE_MAY_STOP_VIS if we are outside the
|
if (STRCMP(p_mousem, "popup_setpos") == 0)
|
||||||
* selection or the current window (might have false
|
{
|
||||||
* negative here)
|
/* First set the cursor position before showing the popup
|
||||||
*/
|
* menu. */
|
||||||
if (mouse_row < curwin->w_winrow
|
if (VIsual_active)
|
||||||
|| mouse_row
|
{
|
||||||
> (curwin->w_winrow + curwin->w_height))
|
pos_T m_pos;
|
||||||
jump_flags = MOUSE_MAY_STOP_VIS;
|
|
||||||
else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER)
|
/*
|
||||||
jump_flags = MOUSE_MAY_STOP_VIS;
|
* set MOUSE_MAY_STOP_VIS if we are outside the
|
||||||
else
|
* selection or the current window (might have false
|
||||||
|
* negative here)
|
||||||
|
*/
|
||||||
|
if (mouse_row < curwin->w_winrow
|
||||||
|
|| mouse_row
|
||||||
|
> (curwin->w_winrow + curwin->w_height))
|
||||||
|
jump_flags = MOUSE_MAY_STOP_VIS;
|
||||||
|
else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER)
|
||||||
|
jump_flags = MOUSE_MAY_STOP_VIS;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((LT_POS(curwin->w_cursor, VIsual)
|
||||||
|
&& (LT_POS(m_pos, curwin->w_cursor)
|
||||||
|
|| LT_POS(VIsual, m_pos)))
|
||||||
|
|| (LT_POS(VIsual, curwin->w_cursor)
|
||||||
|
&& (LT_POS(m_pos, VIsual)
|
||||||
|
|| LT_POS(curwin->w_cursor, m_pos))))
|
||||||
{
|
{
|
||||||
if ((LT_POS(curwin->w_cursor, VIsual)
|
jump_flags = MOUSE_MAY_STOP_VIS;
|
||||||
&& (LT_POS(m_pos, curwin->w_cursor)
|
}
|
||||||
|| LT_POS(VIsual, m_pos)))
|
else if (VIsual_mode == Ctrl_V)
|
||||||
|| (LT_POS(VIsual, curwin->w_cursor)
|
{
|
||||||
&& (LT_POS(m_pos, VIsual)
|
getvcols(curwin, &curwin->w_cursor, &VIsual,
|
||||||
|| LT_POS(curwin->w_cursor, m_pos))))
|
&leftcol, &rightcol);
|
||||||
{
|
getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
|
||||||
|
if (m_pos.col < leftcol || m_pos.col > rightcol)
|
||||||
jump_flags = MOUSE_MAY_STOP_VIS;
|
jump_flags = MOUSE_MAY_STOP_VIS;
|
||||||
}
|
|
||||||
else if (VIsual_mode == Ctrl_V)
|
|
||||||
{
|
|
||||||
getvcols(curwin, &curwin->w_cursor, &VIsual,
|
|
||||||
&leftcol, &rightcol);
|
|
||||||
getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
|
|
||||||
if (m_pos.col < leftcol || m_pos.col > rightcol)
|
|
||||||
jump_flags = MOUSE_MAY_STOP_VIS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
jump_flags = MOUSE_MAY_STOP_VIS;
|
|
||||||
}
|
}
|
||||||
if (jump_flags)
|
else
|
||||||
{
|
jump_flags = MOUSE_MAY_STOP_VIS;
|
||||||
jump_flags = jump_to_mouse(jump_flags, NULL, which_button);
|
|
||||||
update_curbuf(VIsual_active ? INVERTED : VALID);
|
|
||||||
setcursor();
|
|
||||||
out_flush(); /* Update before showing popup menu */
|
|
||||||
}
|
|
||||||
# ifdef FEAT_MENU
|
|
||||||
gui_show_popupmenu();
|
|
||||||
# endif
|
|
||||||
return (jump_flags & CURSOR_MOVED) != 0;
|
|
||||||
}
|
}
|
||||||
else
|
if (jump_flags)
|
||||||
return FALSE;
|
{
|
||||||
|
jump_flags = jump_to_mouse(jump_flags, NULL, which_button);
|
||||||
|
update_curbuf(VIsual_active ? INVERTED : VALID);
|
||||||
|
setcursor();
|
||||||
|
out_flush(); /* Update before showing popup menu */
|
||||||
|
}
|
||||||
|
# ifdef FEAT_MENU
|
||||||
|
show_popupmenu();
|
||||||
|
got_click = FALSE; /* ignore release events */
|
||||||
|
# endif
|
||||||
|
return (jump_flags & CURSOR_MOVED) != 0;
|
||||||
#else
|
#else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
223
src/popupmnu.c
223
src/popupmnu.c
@ -422,9 +422,11 @@ pum_redraw(void)
|
|||||||
char_u *st;
|
char_u *st;
|
||||||
int saved = *p;
|
int saved = *p;
|
||||||
|
|
||||||
*p = NUL;
|
if (saved != NUL)
|
||||||
|
*p = NUL;
|
||||||
st = transstr(s);
|
st = transstr(s);
|
||||||
*p = saved;
|
if (saved != NUL)
|
||||||
|
*p = saved;
|
||||||
#ifdef FEAT_RIGHTLEFT
|
#ifdef FEAT_RIGHTLEFT
|
||||||
if (curwin->w_p_rl)
|
if (curwin->w_p_rl)
|
||||||
{
|
{
|
||||||
@ -830,6 +832,43 @@ pum_get_height(void)
|
|||||||
return pum_height;
|
return pum_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if defined(FEAT_BEVAL_TERM) || defined(FEAT_TERM_POPUP_MENU) || defined(PROTO)
|
||||||
|
static void
|
||||||
|
pum_position_at_mouse(int min_width)
|
||||||
|
{
|
||||||
|
if (Rows - mouse_row > pum_size)
|
||||||
|
{
|
||||||
|
/* Enough space below the mouse row. */
|
||||||
|
pum_row = mouse_row + 1;
|
||||||
|
if (pum_height > Rows - pum_row)
|
||||||
|
pum_height = Rows - pum_row;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Show above the mouse row, reduce height if it does not fit. */
|
||||||
|
pum_row = mouse_row - pum_size;
|
||||||
|
if (pum_row < 0)
|
||||||
|
{
|
||||||
|
pum_height += pum_row;
|
||||||
|
pum_row = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Columns - mouse_col >= pum_base_width
|
||||||
|
|| Columns - mouse_col > min_width)
|
||||||
|
/* Enough space to show at mouse column. */
|
||||||
|
pum_col = mouse_col;
|
||||||
|
else
|
||||||
|
/* Not enough space, right align with window. */
|
||||||
|
pum_col = Columns - (pum_base_width > min_width
|
||||||
|
? min_width : pum_base_width);
|
||||||
|
|
||||||
|
pum_width = Columns - pum_col;
|
||||||
|
if (pum_width > pum_base_width + 1)
|
||||||
|
pum_width = pum_base_width + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
# if defined(FEAT_BEVAL_TERM) || defined(PROTO)
|
# if defined(FEAT_BEVAL_TERM) || defined(PROTO)
|
||||||
static pumitem_T *balloon_array = NULL;
|
static pumitem_T *balloon_array = NULL;
|
||||||
static int balloon_arraysize;
|
static int balloon_arraysize;
|
||||||
@ -1028,36 +1067,7 @@ ui_post_balloon(char_u *mesg, list_T *list)
|
|||||||
pum_scrollbar = 0;
|
pum_scrollbar = 0;
|
||||||
pum_height = balloon_arraysize;
|
pum_height = balloon_arraysize;
|
||||||
|
|
||||||
if (Rows - mouse_row > pum_size)
|
pum_position_at_mouse(BALLOON_MIN_WIDTH);
|
||||||
{
|
|
||||||
/* Enough space below the mouse row. */
|
|
||||||
pum_row = mouse_row + 1;
|
|
||||||
if (pum_height > Rows - pum_row)
|
|
||||||
pum_height = Rows - pum_row;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Show above the mouse row, reduce height if it does not fit. */
|
|
||||||
pum_row = mouse_row - pum_size;
|
|
||||||
if (pum_row < 0)
|
|
||||||
{
|
|
||||||
pum_height += pum_row;
|
|
||||||
pum_row = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Columns - mouse_col >= pum_base_width
|
|
||||||
|| Columns - mouse_col > BALLOON_MIN_WIDTH)
|
|
||||||
/* Enough space to show at mouse column. */
|
|
||||||
pum_col = mouse_col;
|
|
||||||
else
|
|
||||||
/* Not enough space, right align with window. */
|
|
||||||
pum_col = Columns - (pum_base_width > BALLOON_MIN_WIDTH
|
|
||||||
? BALLOON_MIN_WIDTH : pum_base_width);
|
|
||||||
|
|
||||||
pum_width = Columns - pum_col;
|
|
||||||
if (pum_width > pum_base_width + 1)
|
|
||||||
pum_width = pum_base_width + 1;
|
|
||||||
|
|
||||||
pum_selected = -1;
|
pum_selected = -1;
|
||||||
pum_first = 0;
|
pum_first = 0;
|
||||||
pum_redraw();
|
pum_redraw();
|
||||||
@ -1075,4 +1085,153 @@ ui_may_remove_balloon(void)
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if defined(FEAT_TERM_POPUP_MENU) || defined(PROTO)
|
||||||
|
/*
|
||||||
|
* Select the pum entry at the mouse position.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pum_select_mouse_pos(void)
|
||||||
|
{
|
||||||
|
int idx = mouse_row - pum_row;
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= pum_size)
|
||||||
|
pum_selected = -1;
|
||||||
|
else if (*pum_array[idx].pum_text != NUL)
|
||||||
|
pum_selected = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute the currently selected popup menu item.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pum_execute_menu(vimmenu_T *menu)
|
||||||
|
{
|
||||||
|
vimmenu_T *mp;
|
||||||
|
int idx = 0;
|
||||||
|
exarg_T ea;
|
||||||
|
|
||||||
|
for (mp = menu->children; mp != NULL; mp = mp->next)
|
||||||
|
if (idx++ == pum_selected)
|
||||||
|
{
|
||||||
|
vim_memset(&ea, 0, sizeof(ea));
|
||||||
|
execute_menu(&ea, mp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the terminal version of the popup menu and don't return until it is
|
||||||
|
* closed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
pum_show_popupmenu(vimmenu_T *menu)
|
||||||
|
{
|
||||||
|
vimmenu_T *mp;
|
||||||
|
int idx = 0;
|
||||||
|
pumitem_T *array;
|
||||||
|
#ifdef FEAT_BEVAL_TERM
|
||||||
|
int save_bevalterm = p_bevalterm;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pum_undisplay();
|
||||||
|
pum_size = 0;
|
||||||
|
|
||||||
|
for (mp = menu->children; mp != NULL; mp = mp->next)
|
||||||
|
++pum_size;
|
||||||
|
|
||||||
|
array = (pumitem_T *)alloc_clear((unsigned)sizeof(pumitem_T) * pum_size);
|
||||||
|
if (array == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (mp = menu->children; mp != NULL; mp = mp->next)
|
||||||
|
if (menu_is_separator(mp->dname))
|
||||||
|
array[idx++].pum_text = (char_u *)"";
|
||||||
|
else
|
||||||
|
array[idx++].pum_text = mp->dname;
|
||||||
|
|
||||||
|
pum_array = array;
|
||||||
|
pum_compute_size();
|
||||||
|
pum_scrollbar = 0;
|
||||||
|
pum_height = pum_size;
|
||||||
|
pum_position_at_mouse(20);
|
||||||
|
|
||||||
|
pum_selected = -1;
|
||||||
|
pum_first = 0;
|
||||||
|
# ifdef FEAT_BEVAL_TERM
|
||||||
|
p_bevalterm = TRUE; /* track mouse movement */
|
||||||
|
mch_setmouse(TRUE);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
pum_redraw();
|
||||||
|
setcursor();
|
||||||
|
out_flush();
|
||||||
|
|
||||||
|
c = vgetc();
|
||||||
|
if (c == ESC)
|
||||||
|
break;
|
||||||
|
else if (c == CAR || c == NL)
|
||||||
|
{
|
||||||
|
/* enter: select current item, if any, and close */
|
||||||
|
pum_execute_menu(menu);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c == 'k' || c == K_UP || c == K_MOUSEUP)
|
||||||
|
{
|
||||||
|
/* cursor up: select previous item */
|
||||||
|
while (pum_selected > 0)
|
||||||
|
{
|
||||||
|
--pum_selected;
|
||||||
|
if (*array[pum_selected].pum_text != NUL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 'j' || c == K_DOWN || c == K_MOUSEDOWN)
|
||||||
|
{
|
||||||
|
/* cursor down: select next item */
|
||||||
|
while (pum_selected < pum_size - 1)
|
||||||
|
{
|
||||||
|
++pum_selected;
|
||||||
|
if (*array[pum_selected].pum_text != NUL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == K_RIGHTMOUSE)
|
||||||
|
{
|
||||||
|
/* Right mouse down: reposition the menu. */
|
||||||
|
vungetc(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c == K_LEFTDRAG || c == K_RIGHTDRAG || c == K_MOUSEMOVE)
|
||||||
|
{
|
||||||
|
/* mouse moved: selec item in the mouse row */
|
||||||
|
pum_select_mouse_pos();
|
||||||
|
}
|
||||||
|
else if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM || c == K_RIGHTRELEASE)
|
||||||
|
{
|
||||||
|
/* left mouse click: select clicked item, if any, and close;
|
||||||
|
* right mouse release: select clicked item, close if any */
|
||||||
|
pum_select_mouse_pos();
|
||||||
|
if (pum_selected >= 0)
|
||||||
|
{
|
||||||
|
pum_execute_menu(menu);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vim_free(array);
|
||||||
|
pum_undisplay();
|
||||||
|
# ifdef FEAT_BEVAL_TERM
|
||||||
|
p_bevalterm = save_bevalterm;
|
||||||
|
mch_setmouse(TRUE);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,12 +12,13 @@ int menu_is_popup(char_u *name);
|
|||||||
int menu_is_child_of_popup(vimmenu_T *menu);
|
int menu_is_child_of_popup(vimmenu_T *menu);
|
||||||
int menu_is_toolbar(char_u *name);
|
int menu_is_toolbar(char_u *name);
|
||||||
int menu_is_separator(char_u *name);
|
int menu_is_separator(char_u *name);
|
||||||
|
void show_popupmenu(void);
|
||||||
int check_menu_pointer(vimmenu_T *root, vimmenu_T *menu_to_check);
|
int check_menu_pointer(vimmenu_T *root, vimmenu_T *menu_to_check);
|
||||||
void gui_create_initial_menus(vimmenu_T *menu);
|
void gui_create_initial_menus(vimmenu_T *menu);
|
||||||
void gui_update_menus(int modes);
|
void gui_update_menus(int modes);
|
||||||
int gui_is_menu_shortcut(int key);
|
int gui_is_menu_shortcut(int key);
|
||||||
void gui_show_popupmenu(void);
|
|
||||||
void gui_mch_toggle_tearoffs(int enable);
|
void gui_mch_toggle_tearoffs(int enable);
|
||||||
|
void execute_menu(exarg_T *eap, vimmenu_T *menu);
|
||||||
void ex_emenu(exarg_T *eap);
|
void ex_emenu(exarg_T *eap);
|
||||||
void winbar_click(win_T *wp, int col);
|
void winbar_click(win_T *wp, int col);
|
||||||
vimmenu_T *gui_find_menu(char_u *path_name);
|
vimmenu_T *gui_find_menu(char_u *path_name);
|
||||||
|
@ -9,4 +9,5 @@ int split_message(char_u *mesg, pumitem_T **array);
|
|||||||
void ui_remove_balloon(void);
|
void ui_remove_balloon(void);
|
||||||
void ui_post_balloon(char_u *mesg, list_T *list);
|
void ui_post_balloon(char_u *mesg, list_T *list);
|
||||||
void ui_may_remove_balloon(void);
|
void ui_may_remove_balloon(void);
|
||||||
|
void pum_show_popupmenu(vimmenu_T *menu);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@ -778,6 +778,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 */
|
||||||
|
/**/
|
||||||
|
1558,
|
||||||
/**/
|
/**/
|
||||||
1557,
|
1557,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user