mirror of
https://github.com/neovim/neovim.git
synced 2025-09-20 10:18:18 +00:00
vim-patch:8.0.1570: can't use :popup for a menu in the terminal
Problem: Can't use :popup for a menu in the terminal. (Wei Zhang)
Solution: Make :popup work in the terminal. Also fix that entries were
included that don't work in the current state.
29a2c08d79
This commit is contained in:
@@ -577,8 +577,8 @@ a menu item - you don't need to do a :tunmenu as well.
|
|||||||
|
|
||||||
5.9 Popup Menus
|
5.9 Popup Menus
|
||||||
|
|
||||||
In the Win32 GUI, you can cause a menu to popup at the cursor. This behaves
|
You can cause a menu to popup at the cursor. This behaves similarly to the
|
||||||
similarly to the PopUp menus except that any menu tree can be popped up.
|
PopUp menus except that any menu tree can be popped up.
|
||||||
|
|
||||||
This command is for backwards compatibility, using it is discouraged, because
|
This command is for backwards compatibility, using it is discouraged, because
|
||||||
it behaves in a strange way.
|
it behaves in a strange way.
|
||||||
@@ -587,7 +587,6 @@ it behaves in a strange way.
|
|||||||
:popu[p] {name} Popup the menu {name}. The menu named must
|
:popu[p] {name} Popup the menu {name}. The menu named must
|
||||||
have at least one subentry, but need not
|
have at least one subentry, but need not
|
||||||
appear on the menu-bar (see |hidden-menus|).
|
appear on the menu-bar (see |hidden-menus|).
|
||||||
{only available for Win32 GUI}
|
|
||||||
|
|
||||||
:popu[p]! {name} Like above, but use the position of the mouse
|
:popu[p]! {name} Like above, but use the position of the mouse
|
||||||
pointer instead of the cursor.
|
pointer instead of the cursor.
|
||||||
|
@@ -1991,7 +1991,7 @@ module.cmds = {
|
|||||||
command='popup',
|
command='popup',
|
||||||
flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN),
|
flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN),
|
||||||
addr_type='ADDR_NONE',
|
addr_type='ADDR_NONE',
|
||||||
func='ex_ni',
|
func='ex_popup',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
command='ppop',
|
command='ppop',
|
||||||
|
@@ -62,6 +62,7 @@
|
|||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/os_unix.h"
|
#include "nvim/os_unix.h"
|
||||||
#include "nvim/path.h"
|
#include "nvim/path.h"
|
||||||
|
#include "nvim/popupmnu.h"
|
||||||
#include "nvim/quickfix.h"
|
#include "nvim/quickfix.h"
|
||||||
#include "nvim/regexp.h"
|
#include "nvim/regexp.h"
|
||||||
#include "nvim/screen.h"
|
#include "nvim/screen.h"
|
||||||
@@ -7985,6 +7986,11 @@ static void ex_nogui(exarg_T *eap)
|
|||||||
eap->errmsg = N_("E25: Nvim does not have a built-in GUI");
|
eap->errmsg = N_("E25: Nvim does not have a built-in GUI");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ex_popup(exarg_T *eap)
|
||||||
|
{
|
||||||
|
pum_make_popup(eap->arg, eap->forceit);
|
||||||
|
}
|
||||||
|
|
||||||
static void ex_swapname(exarg_T *eap)
|
static void ex_swapname(exarg_T *eap)
|
||||||
{
|
{
|
||||||
if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL) {
|
if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL) {
|
||||||
|
@@ -1382,6 +1382,16 @@ static int get_menu_mode(void)
|
|||||||
return MENU_INDEX_INVALID;
|
return MENU_INDEX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_menu_mode_flag(void)
|
||||||
|
{
|
||||||
|
int mode = get_menu_mode();
|
||||||
|
|
||||||
|
if (mode == MENU_INDEX_INVALID) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1 << mode;
|
||||||
|
}
|
||||||
|
|
||||||
/// Display the Special "PopUp" menu as a pop-up at the current mouse
|
/// 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,
|
/// position. The "PopUpn" menu is for Normal mode, "PopUpi" for Insert mode,
|
||||||
/// etc.
|
/// etc.
|
||||||
@@ -1545,6 +1555,52 @@ void ex_emenu(exarg_T *eap)
|
|||||||
execute_menu(eap, menu);
|
execute_menu(eap, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy.
|
||||||
|
vimmenu_T *menu_find(const char *path_name)
|
||||||
|
{
|
||||||
|
vimmenu_T *menu = *get_root_menu(path_name);
|
||||||
|
char *saved_name = xstrdup(path_name);
|
||||||
|
char *name = saved_name;
|
||||||
|
while (*name) {
|
||||||
|
// find the end of one dot-separated name and put a NUL at the dot
|
||||||
|
char *p = menu_name_skip(name);
|
||||||
|
|
||||||
|
while (menu != NULL) {
|
||||||
|
if (menu_name_equal(name, menu)) {
|
||||||
|
if (menu->children == NULL) {
|
||||||
|
// found a menu item instead of a sub-menu
|
||||||
|
if (*p == NUL) {
|
||||||
|
emsg(_("E336: Menu path must lead to a sub-menu"));
|
||||||
|
} else {
|
||||||
|
emsg(_(e_notsubmenu));
|
||||||
|
}
|
||||||
|
menu = NULL;
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
if (*p == NUL) { // found a full match
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
menu = menu->next;
|
||||||
|
}
|
||||||
|
if (menu == NULL) { // didn't find it
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found a match, search the sub-menu.
|
||||||
|
menu = menu->children;
|
||||||
|
name = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menu == NULL) {
|
||||||
|
emsg(_("E337: Menu not found - check menu names"));
|
||||||
|
}
|
||||||
|
theend:
|
||||||
|
xfree(saved_name);
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translation of menu names. Just a simple lookup table.
|
* Translation of menu names. Just a simple lookup table.
|
||||||
*/
|
*/
|
||||||
|
@@ -1000,10 +1000,13 @@ void pum_show_popupmenu(vimmenu_T *menu)
|
|||||||
{
|
{
|
||||||
pum_undisplay(true);
|
pum_undisplay(true);
|
||||||
pum_size = 0;
|
pum_size = 0;
|
||||||
|
int mode = get_menu_mode_flag();
|
||||||
|
|
||||||
for (vimmenu_T *mp = menu->children; mp != NULL; mp = mp->next) {
|
for (vimmenu_T *mp = menu->children; mp != NULL; mp = mp->next) {
|
||||||
|
if (menu_is_separator(mp->dname) || (mp->modes & mp->enabled & mode)) {
|
||||||
pum_size++;
|
pum_size++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
pumitem_T *array = (pumitem_T *)xcalloc((size_t)pum_size, sizeof(pumitem_T));
|
pumitem_T *array = (pumitem_T *)xcalloc((size_t)pum_size, sizeof(pumitem_T));
|
||||||
@@ -1011,7 +1014,7 @@ void pum_show_popupmenu(vimmenu_T *menu)
|
|||||||
for (vimmenu_T *mp = menu->children; mp != NULL; mp = mp->next) {
|
for (vimmenu_T *mp = menu->children; mp != NULL; mp = mp->next) {
|
||||||
if (menu_is_separator(mp->dname)) {
|
if (menu_is_separator(mp->dname)) {
|
||||||
array[idx++].pum_text = (char_u *)"";
|
array[idx++].pum_text = (char_u *)"";
|
||||||
} else {
|
} else if (mp->modes & mp->enabled & mode) {
|
||||||
array[idx++].pum_text = (char_u *)mp->dname;
|
array[idx++].pum_text = (char_u *)mp->dname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1079,3 +1082,18 @@ void pum_show_popupmenu(vimmenu_T *menu)
|
|||||||
xfree(array);
|
xfree(array);
|
||||||
pum_undisplay(true);
|
pum_undisplay(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pum_make_popup(const char *path_name, int use_mouse_pos)
|
||||||
|
{
|
||||||
|
if (!use_mouse_pos) {
|
||||||
|
// Hack: set mouse position at the cursor so that the menu pops up
|
||||||
|
// around there.
|
||||||
|
mouse_row = curwin->w_winrow + curwin->w_wrow;
|
||||||
|
mouse_col = curwin->w_wincol + curwin->w_wcol;
|
||||||
|
}
|
||||||
|
|
||||||
|
vimmenu_T *menu = menu_find(path_name);
|
||||||
|
if (menu != NULL) {
|
||||||
|
pum_show_popupmenu(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3748,7 +3748,7 @@ describe('API', function()
|
|||||||
eq("foo", meths.cmd({ cmd = "Foo" }, { output = true }))
|
eq("foo", meths.cmd({ cmd = "Foo" }, { output = true }))
|
||||||
end)
|
end)
|
||||||
it('errors if command is not implemented', function()
|
it('errors if command is not implemented', function()
|
||||||
eq("Command not implemented: popup", pcall_err(meths.cmd, { cmd = "popup" }, {}))
|
eq("Command not implemented: winpos", pcall_err(meths.cmd, { cmd = "winpos" }, {}))
|
||||||
end)
|
end)
|
||||||
it('works with empty arguments list', function()
|
it('works with empty arguments list', function()
|
||||||
meths.cmd({ cmd = "update" }, {})
|
meths.cmd({ cmd = "update" }, {})
|
||||||
|
Reference in New Issue
Block a user