From 69f4fd84aaa835f563871c761602c9b5bd5e3842 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 4 Dec 2025 08:31:06 +0800 Subject: [PATCH 1/2] vim-patch:9.1.1949: :stag does not use 'swichtbuf' option Problem: :stag does not use 'swichtbuf' option, though the documentation states differently (Christian Brabandt) Solution: Respect 'switchbuf' option (Yegappan Lakshmanan). related: vim/vim#18845 closes: vim/vim#18856 https://github.com/vim/vim/commit/efc7509be2ba38ca6d226cf59bad67e7888a537d Cherry-pick some test_tagjump.vim changes from patches 9.0.{0363,0767}. Co-authored-by: Yegappan Lakshmanan --- runtime/doc/windows.txt | 6 ++- src/nvim/tag.c | 11 +++++ test/old/testdir/test_tagjump.vim | 79 ++++++++++++++++++------------- 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 99affbce7c..1bb084b613 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -871,13 +871,15 @@ the buffer. The result is that all buffers will use the 'encoding' encoding *:sta* *:stag* :sta[g][!] [tagname] Does ":tag[!] [tagname]" and splits the window for the found - tag. See also |:tag|. + tag. Refer to 'switchbuf' to jump to a tag in a vertically + split window or a new tab page. See also |:tag|. CTRL-W ] *CTRL-W_]* *CTRL-W_CTRL-]* CTRL-W CTRL-] Split current window in two. Use identifier under cursor as a tag and jump to it in the new upper window. In Visual mode uses the Visually selected text as a tag. - Make new window N high. + Make new window N high. Refer to 'switchbuf' to jump to a tag + in a vertically split window or a new tab page. *CTRL-W_g]* CTRL-W g ] Split current window in two. Use identifier under cursor as a diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 09567d0960..36209a8db9 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2863,6 +2863,17 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, bool keep_help) } if (getfile_result == GETFILE_UNUSED && (postponed_split || cmdmod.cmod_tab != 0)) { + if (swb_flags & kOptSwbFlagVsplit) { + // If 'switchbuf' contains 'vsplit', then use a new vertically + // split window. + cmdmod.cmod_split |= WSP_VERT; + } + + if (swb_flags & kOptSwbFlagNewtab) { + // If 'switchbuf' contains 'newtab', then use a new tabpage + cmdmod.cmod_tab = tabpage_index(curtab) + 1; + } + if (win_split(postponed_split > 0 ? postponed_split : 0, postponed_split_flags) == FAIL) { RedrawingDisabled--; diff --git a/test/old/testdir/test_tagjump.vim b/test/old/testdir/test_tagjump.vim index 0432c032bb..15f5932f96 100644 --- a/test/old/testdir/test_tagjump.vim +++ b/test/old/testdir/test_tagjump.vim @@ -15,20 +15,20 @@ endfunc func Test_ptjump() CheckFeature quickfix - set tags=Xtags + set tags=Xpttags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", - \ "one\tXfile\t1", - \ "three\tXfile\t3", - \ "two\tXfile\t2"], - \ 'Xtags') - call writefile(['one', 'two', 'three'], 'Xfile') + \ "one\tXptfile\t1", + \ "three\tXptfile\t3", + \ "two\tXptfile\t2"], + \ 'Xpttags', 'D') + call writefile(['one', 'two', 'three'], 'Xptfile', 'D') %bw! ptjump two call assert_equal(2, winnr()) wincmd p call assert_equal(1, &previewwindow) - call assert_equal('Xfile', expand("%:p:t")) + call assert_equal('Xptfile', expand("%:p:t")) call assert_equal(2, line('.')) call assert_equal(2, winnr('$')) call assert_equal(1, winnr()) @@ -38,7 +38,7 @@ func Test_ptjump() call assert_equal(2, winnr()) wincmd p call assert_equal(1, &previewwindow) - call assert_equal('Xfile', expand("%:p:t")) + call assert_equal('Xptfile', expand("%:p:t")) call assert_equal(3, line('.')) call assert_equal(2, winnr('$')) call assert_equal(1, winnr()) @@ -48,8 +48,6 @@ func Test_ptjump() call assert_equal(5, winheight(0)) close - call delete('Xtags') - call delete('Xfile') set tags& endfunc @@ -60,25 +58,24 @@ func Test_cancel_ptjump() call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", \ "word\tfile1\tcmd1", \ "word\tfile2\tcmd2"], - \ 'Xtags') + \ 'Xtags', 'D') only! call feedkeys(":ptjump word\\", "xt") help call assert_equal(2, winnr('$')) - call delete('Xtags') set tags& quit endfunc func Test_static_tagjump() - set tags=Xtags + set tags=Xtjtags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", - \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)", - \ "word\tXfile2\tcmd2"], - \ 'Xtags') - new Xfile1 + \ "one\tXtjfile1\t/^one/;\"\tf\tfile:\tsignature:(void)", + \ "word\tXtjfile2\tcmd2"], + \ 'Xtjtags', 'D') + new Xtjfile1 call setline(1, ['empty', 'one()', 'empty']) write tag one @@ -86,19 +83,18 @@ func Test_static_tagjump() bwipe! set tags& - call delete('Xtags') - call delete('Xfile1') + call delete('Xtjfile1') endfunc func Test_duplicate_tagjump() - set tags=Xtags + set tags=Xdttags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", - \ "thesame\tXfile1\t1;\"\td\tfile:", - \ "thesame\tXfile1\t2;\"\td\tfile:", - \ "thesame\tXfile1\t3;\"\td\tfile:", + \ "thesame\tXdtfile1\t1;\"\td\tfile:", + \ "thesame\tXdtfile1\t2;\"\td\tfile:", + \ "thesame\tXdtfile1\t3;\"\td\tfile:", \ ], - \ 'Xtags') - new Xfile1 + \ 'Xdttags', 'D') + new Xdtfile1 call setline(1, ['thesame one', 'thesame two', 'thesame three']) write tag thesame @@ -110,19 +106,18 @@ func Test_duplicate_tagjump() bwipe! set tags& - call delete('Xtags') - call delete('Xfile1') + call delete('Xdtfile1') endfunc func Test_tagjump_switchbuf() CheckFeature quickfix - set tags=Xtags + set tags=Xswtags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", - \ "second\tXfile1\t2", - \ "third\tXfile1\t3",], - \ 'Xtags') - call writefile(['first', 'second', 'third'], 'Xfile1') + \ "second\tXsbfile1\t2", + \ "third\tXsbfile1\t3",], + \ 'Xswtags', 'D') + call writefile(['first', 'second', 'third'], 'Xsbfile1', 'D') enew | only set switchbuf= @@ -150,11 +145,27 @@ func Test_tagjump_switchbuf() 1tabnext | stag third call assert_equal(2, tabpagenr('$')) call assert_equal(3, line('.')) + tabonly + + " use a vertically split window + enew | only + set switchbuf=vsplit + stag third + call assert_equal(2, winnr('$')) + call assert_equal(1, winnr()) + call assert_equal(3, line('.')) + call assert_equal(['row', [['leaf', win_getid(1)], ['leaf', win_getid(2)]]], winlayout()) + + " jump to a tag in a new tabpage + enew | only + set switchbuf=newtab + stag second + call assert_equal(2, tabpagenr('$')) + call assert_equal(2, tabpagenr()) + call assert_equal(2, line('.')) tabclose! enew | only - call delete('Xfile1') - call delete('Xtags') set tags& set switchbuf&vim endfunc From ff90032aa5e8e943c1934d5a225243be5f1aee53 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 8 Dec 2025 08:10:22 +0800 Subject: [PATCH 2/2] vim-patch:9.1.1961: :0tab behaves like :tab for :stag when 'swb' contains "newtab" Problem: :0tab behaves like :tab for :stag when 'switchbuf' contains "newtab" (after 9.1.1949). Solution: Don't override cmod_tab if it's already non-zero (zeertzjq). closes: vim/vim#18859 https://github.com/vim/vim/commit/2b3566d89eeb3f84dad7715fff153b84177e5fbb --- src/nvim/tag.c | 2 +- test/old/testdir/test_tagjump.vim | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 36209a8db9..987d48c74a 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2869,7 +2869,7 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, bool keep_help) cmdmod.cmod_split |= WSP_VERT; } - if (swb_flags & kOptSwbFlagNewtab) { + if ((swb_flags & kOptSwbFlagNewtab) && cmdmod.cmod_tab == 0) { // If 'switchbuf' contains 'newtab', then use a new tabpage cmdmod.cmod_tab = tabpage_index(curtab) + 1; } diff --git a/test/old/testdir/test_tagjump.vim b/test/old/testdir/test_tagjump.vim index 15f5932f96..df9f7060fa 100644 --- a/test/old/testdir/test_tagjump.vim +++ b/test/old/testdir/test_tagjump.vim @@ -163,7 +163,12 @@ func Test_tagjump_switchbuf() call assert_equal(2, tabpagenr('$')) call assert_equal(2, tabpagenr()) call assert_equal(2, line('.')) + 0tab stag third + call assert_equal(3, tabpagenr('$')) + call assert_equal(1, tabpagenr()) + call assert_equal(3, line('.')) + tabclose! tabclose! enew | only set tags&