aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/popupmenu.c13
-rw-r--r--src/nvim/testdir/test_popup.vim28
2 files changed, 37 insertions, 4 deletions
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index db22d50d66..234ce5fcba 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -1043,10 +1043,16 @@ void pum_show_popupmenu(vimmenu_T *menu)
pumitem_T *array = (pumitem_T *)xcalloc((size_t)pum_size, sizeof(pumitem_T));
for (vimmenu_T *mp = menu->children; mp != NULL; mp = mp->next) {
+ char *s = NULL;
+ // Make a copy of the text, the menu may be redefined in a callback.
if (menu_is_separator(mp->dname)) {
- array[idx++].pum_text = (char_u *)"";
+ s = "";
} else if (mp->modes & mp->enabled & mode) {
- array[idx++].pum_text = (char_u *)mp->dname;
+ s = mp->dname;
+ }
+ if (s != NULL) {
+ s = xstrdup(s);
+ array[idx++].pum_text = (char_u *)s;
}
}
@@ -1117,6 +1123,9 @@ void pum_show_popupmenu(vimmenu_T *menu)
}
}
+ for (idx = 0; idx < pum_size; idx++) {
+ xfree(array[idx].pum_text);
+ }
xfree(array);
pum_undisplay(true);
if (!p_mousemev) {
diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim
index 0981329320..a9b258c5f5 100644
--- a/src/nvim/testdir/test_popup.vim
+++ b/src/nvim/testdir/test_popup.vim
@@ -871,18 +871,30 @@ func Test_popup_command()
call assert_fails('popup Foo', 'E337:')
unmenu Test.Foo
+ let script =<< trim END
+ func StartTimer()
+ call timer_start(100, {-> ChangeMenu()})
+ endfunc
+ func ChangeMenu()
+ nunmenu PopUp.&Paste
+ nnoremenu 1.40 PopUp.&Paste :echomsg "pasted"<CR>
+ echomsg 'changed'
+ endfunc
+ END
+ call writefile(script, 'XtimerScript')
+
let lines =<< trim END
one two three four five
and one two Xthree four five
one more two three four five
END
call writefile(lines, 'Xtest')
- let buf = RunVimInTerminal('Xtest', {})
+ let buf = RunVimInTerminal('-S XtimerScript Xtest', {})
call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>")
call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
call VerifyScreenDump(buf, 'Test_popup_command_01', {})
- " Select a word
+ " go to the Paste entry in the menu
call term_sendkeys(buf, "jj")
call VerifyScreenDump(buf, 'Test_popup_command_02', {})
@@ -891,8 +903,20 @@ func Test_popup_command()
call VerifyScreenDump(buf, 'Test_popup_command_03', {})
call term_sendkeys(buf, "\<Esc>")
+
+ " Set a timer to change a menu entry while it's displayed. The text should
+ " not change but the command does. Making the screendump also verifies that
+ " "changed" shows up, which means the timer triggered
+ call term_sendkeys(buf, "/X\<CR>:call StartTimer() | popup PopUp\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_command_04', {})
+
+ " Select the Paste entry, executes the changed menu item.
+ call term_sendkeys(buf, "jj\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_command_05', {})
+
call StopVimInTerminal(buf)
call delete('Xtest')
+ call delete('XtimerScript')
endfunc
func Test_popup_complete_backwards()