Skip to content

Fixing buffer menu having stale items with terminal / cmdline window #1025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions runtime/menu.vim
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,11 @@ if !exists("no_buffers_menu")
" startup faster.
let s:bmenu_wait = 1

" dictionary of buffer ID to name. This helps prevent bugs where a buffer is
" somehow being renamed and we can't remove it from the menu because we are
" using the wrong menu name.
let s:bmenu_items = {}

if !exists("bmenu_priority")
let bmenu_priority = 60
endif
Expand All @@ -733,14 +738,13 @@ func! s:BMRemove()
if isdirectory(name)
return
endif
let munge = <SID>BMMunge(name, expand("<abuf>"))

if s:bmenu_short == 0
exe 'silent! aun &Buffers.' . munge
else
exe 'silent! aun &Buffers.' . <SID>BMHash2(munge) . munge
let bufnum = expand("<abuf>")
if s:bmenu_items->has_key(bufnum)
let menu_name = s:bmenu_items[bufnum]
exe 'silent! aun &Buffers.' . menu_name
let s:bmenu_count = s:bmenu_count - 1
unlet s:bmenu_items[bufnum]
endif
let s:bmenu_count = s:bmenu_count - 1
endif
endfunc

Expand All @@ -749,6 +753,7 @@ func! s:BMShow(...)
let s:bmenu_wait = 1
let s:bmenu_short = 1
let s:bmenu_count = 0
let s:bmenu_items = {}
"
" get new priority, if exists
if a:0 == 1
Expand Down Expand Up @@ -844,9 +849,12 @@ func! s:BMFilename(name, num)
let munge = <SID>BMMunge(a:name, a:num)
let hash = <SID>BMHash(munge)
if s:bmenu_short == 0
let s:bmenu_items[a:num] = munge
let name = 'an ' . g:bmenu_priority . '.' . hash . ' &Buffers.' . munge
else
let name = 'an ' . g:bmenu_priority . '.' . hash . '.' . hash . ' &Buffers.' . <SID>BMHash2(munge) . munge
let menu_name = <SID>BMHash2(munge) . munge
let s:bmenu_items[a:num] = l:menu_name
let name = 'an ' . g:bmenu_priority . '.' . hash . '.' . hash . ' &Buffers.' . menu_name
endif
" set 'cpo' to include the <CR>
let cpo_save = &cpo
Expand Down
2 changes: 2 additions & 0 deletions src/ex_getln.c
Original file line number Diff line number Diff line change
Expand Up @@ -4206,7 +4206,9 @@ open_cmdwin(void)

// Create the command-line buffer empty.
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
(void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
curbuf->b_p_ma = TRUE;
#ifdef FEAT_FOLDING
Expand Down
4 changes: 4 additions & 0 deletions src/terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ term_start(
term->tl_next = first_term;
first_term = term;

apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);

if (opt->jo_term_name != NULL)
curbuf->b_ffname = vim_strsave(opt->jo_term_name);
else if (argv != NULL)
Expand Down Expand Up @@ -571,6 +573,8 @@ term_start(
curbuf->b_sfname = vim_strsave(curbuf->b_ffname);
curbuf->b_fname = curbuf->b_ffname;

apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);

if (opt->jo_term_opencmd != NULL)
term->tl_opencmd = vim_strsave(opt->jo_term_opencmd);

Expand Down
7 changes: 0 additions & 7 deletions src/testdir/test_cmdline.vim
Original file line number Diff line number Diff line change
Expand Up @@ -1030,13 +1030,6 @@ func Test_cmdline_expand_special()
endfunc

func Test_cmdwin_jump_to_win()
if has('gui_macvim') && has('gui_running')
" Due to a mix of MacVim-specific menu behaviors (calling BMShow at start
" instead of VimEnter), and buffer menu stale item bugs in Vim, this test
" doesn't work in GUI for now. Will be re-enabled after buffer menu bugs
" are fixed.
return
endif
call assert_fails('call feedkeys("q:\<C-W>\<C-W>\<CR>", "xt")', 'E11:')
new
set modified
Expand Down
37 changes: 37 additions & 0 deletions src/testdir/test_menu.vim
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,43 @@ func Test_load_menu()
call assert_equal('', v:errmsg)
endfunc

func Test_buffer_menu_special_buffers()
" Load in runtime menus
try
source $VIMRUNTIME/menu.vim
catch
call assert_report('error while loading menus: ' . v:exception)
endtry

let v:errmsg = ''
if !has("gui_macvim")
" MacVim initializes buffer menus differently (by calling BMShow
" immediately) so this is unnecessary and would break the test.
doautocmd LoadBufferMenu VimEnter
endif
call assert_equal('', v:errmsg)

let orig_buffer_menus = execute("nmenu Buffers")

" Make a new command-line window, test that it creates a new buffer menu,
" and test that when we exits the command-line window, the menu item got removed.
call feedkeys("q::let cmdline_buffer_menus=execute('nmenu Buffers')\<CR>:q\<CR>", 'ntx')
call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(cmdline_buffer_menus, "\n")))
call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))

" Make a terminal window, and also test that it creates and removes the
" buffer menu item.
terminal
let term_buffer_menus = execute('nmenu Buffers')
call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(term_buffer_menus, "\n")))
bd!
call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))

" Remove menus to clean up
source $VIMRUNTIME/delmenu.vim
call assert_equal('', v:errmsg)
endfunc

func Test_translate_menu()
if !has('multi_lang')
return
Expand Down