# HG changeset patch # User Christian Brabandt # Date 1496672103 -7200 # Node ID c45fb081391c2f2cf48665570820e7d7c80c46c7 # Parent 53a8f79670ee6d34f68e9c458c2d80d05b30d58a patch 8.0.0621: :stag does not respect 'switchbuf' commit https://github.com/vim/vim/commit/8ad80dea089ffeb1a845199c013e9bb4be1cd22e Author: Bram Moolenaar Date: Mon Jun 5 16:01:59 2017 +0200 patch 8.0.0621: :stag does not respect 'switchbuf' Problem: The ":stag" command does not respect 'switchbuf'. Solution: Check 'switchbuf' for tag commands that may open a new window. (Ingo Karkat, closes #1681) Define macros for the return values of getfile(). diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -2352,8 +2352,8 @@ buflist_getfile( #endif ++RedrawingDisabled; - if (getfile(buf->b_fnum, NULL, NULL, (options & GETF_SETMARK), - lnum, forceit) <= 0) + if (GETFILE_SUCCESS(getfile(buf->b_fnum, NULL, NULL, + (options & GETF_SETMARK), lnum, forceit))) { --RedrawingDisabled; diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3520,11 +3520,14 @@ check_readonly(int *forceit, buf_T *buf) /* * Try to abandon current file and edit a new or existing file. - * 'fnum' is the number of the file, if zero use ffname/sfname. + * "fnum" is the number of the file, if zero use ffname/sfname. + * "lnum" is the line number for the cursor in the new file (if non-zero). * - * Return 1 for "normal" error, 2 for "not written" error, 0 for success - * -1 for successfully opening another file. - * 'lnum' is the line number for the cursor in the new file (if non-zero). + * Return: + * GETFILE_ERROR for "normal" error, + * GETFILE_NOT_WRITTEN for "not written" error, + * GETFILE_SAME_FILE for success + * GETFILE_OPEN_OTHER for successfully opening another file. */ int getfile( @@ -3540,10 +3543,10 @@ getfile( char_u *free_me = NULL; if (text_locked()) - return 1; + return GETFILE_ERROR; #ifdef FEAT_AUTOCMD if (curbuf_locked()) - return 1; + return GETFILE_ERROR; #endif if (fnum == 0) @@ -3570,7 +3573,7 @@ getfile( if (other) --no_wait_return; EMSG(_(e_nowrtmsg)); - retval = 2; /* file has been changed */ + retval = GETFILE_NOT_WRITTEN; /* file has been changed */ goto theend; } } @@ -3584,14 +3587,14 @@ getfile( curwin->w_cursor.lnum = lnum; check_cursor_lnum(); beginline(BL_SOL | BL_FIX); - retval = 0; /* it's in the same file */ + retval = GETFILE_SAME_FILE; /* it's in the same file */ } else if (do_ecmd(fnum, ffname, sfname, NULL, lnum, (P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0), curwin) == OK) - retval = -1; /* opened another file */ + retval = GETFILE_OPEN_OTHER; /* opened another file */ else - retval = 1; /* error encountered */ + retval = GETFILE_ERROR; /* error encountered */ theend: vim_free(free_me); diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -1524,9 +1524,9 @@ end_do_search: * search_for_exact_line(buf, pos, dir, pat) * * Search for a line starting with the given pattern (ignoring leading - * white-space), starting from pos and going in direction dir. pos will + * white-space), starting from pos and going in direction "dir". "pos" will * contain the position of the match found. Blank lines match only if - * ADDING is set. if p_ic is set then the pattern must be in lowercase. + * ADDING is set. If p_ic is set then the pattern must be in lowercase. * Return OK for success, or FAIL if no line found. */ int @@ -5397,8 +5397,9 @@ search_line: #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0) { - if (getfile(0, curwin_save->w_buffer->b_fname, - NULL, TRUE, lnum, FALSE) > 0) + if (!GETFILE_SUCCESS(getfile( + 0, curwin_save->w_buffer->b_fname, + NULL, TRUE, lnum, FALSE))) break; /* failed to jump to file */ } else @@ -5408,8 +5409,9 @@ search_line: } else { - if (getfile(0, files[depth].name, NULL, TRUE, - files[depth].lnum, FALSE) > 0) + if (!GETFILE_SUCCESS(getfile( + 0, files[depth].name, NULL, TRUE, + files[depth].lnum, FALSE))) break; /* failed to jump to file */ /* autocommands may have changed the lnum, we don't * want that here */ diff --git a/src/tag.c b/src/tag.c --- a/src/tag.c +++ b/src/tag.c @@ -3088,7 +3088,7 @@ jumpto_tag( char_u *fname; tagptrs_T tagp; int retval = FAIL; - int getfile_result; + int getfile_result = GETFILE_UNUSED; int search_options; #ifdef FEAT_SEARCH_EXTRA int save_no_hlsearch; @@ -3202,7 +3202,29 @@ jumpto_tag( /* If it was a CTRL-W CTRL-] command split window now. For ":tab tag" * open a new tab page. */ - if (postponed_split || cmdmod.tab != 0) + if (postponed_split && (swb_flags & (SWB_USEOPEN | SWB_USETAB))) + { + buf_T *existing_buf = buflist_findname_exp(fname); + + if (existing_buf != NULL) + { + win_T *wp = NULL; + + if (swb_flags & SWB_USEOPEN) + wp = buf_jump_open_win(existing_buf); + + /* If 'switchbuf' contains "usetab": jump to first window in any tab + * page containing "existing_buf" if one exists */ + if (wp == NULL && (swb_flags & SWB_USETAB)) + wp = buf_jump_open_tab(existing_buf); + /* We've switched to the buffer, the usual loading of the file must + * be skipped. */ + if (wp != NULL) + getfile_result = GETFILE_SAME_FILE; + } + } + if (getfile_result == GETFILE_UNUSED + && (postponed_split || cmdmod.tab != 0)) { if (win_split(postponed_split > 0 ? postponed_split : 0, postponed_split_flags) == FAIL) @@ -3225,10 +3247,11 @@ jumpto_tag( #endif keep_help_flag = curbuf->b_help; } - getfile_result = getfile(0, fname, NULL, TRUE, (linenr_T)0, forceit); + if (getfile_result == GETFILE_UNUSED) + getfile_result = getfile(0, fname, NULL, TRUE, (linenr_T)0, forceit); keep_help_flag = FALSE; - if (getfile_result <= 0) /* got to the right file */ + if (GETFILE_SUCCESS(getfile_result)) /* got to the right file */ { curwin->w_set_curswant = TRUE; #ifdef FEAT_WINDOWS @@ -3377,7 +3400,7 @@ jumpto_tag( #endif /* Return OK if jumped to another file (at least we found the file!). */ - if (getfile_result == -1) + if (getfile_result == GETFILE_OPEN_OTHER) retval = OK; if (retval == OK) diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim --- a/src/testdir/test_tagjump.vim +++ b/src/testdir/test_tagjump.vim @@ -65,6 +65,48 @@ func Test_duplicate_tagjump() call delete('Xfile1') endfunc +func Test_tagjump_switchbuf() + set tags=Xtags + call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", + \ "second\tXfile1\t2", + \ "third\tXfile1\t3",], + \ 'Xtags') + call writefile(['first', 'second', 'third'], 'Xfile1') + + enew | only + set switchbuf= + stag second + call assert_equal(2, winnr('$')) + call assert_equal(2, line('.')) + stag third + call assert_equal(3, winnr('$')) + call assert_equal(3, line('.')) + + enew | only + set switchbuf=useopen + stag second + call assert_equal(2, winnr('$')) + call assert_equal(2, line('.')) + stag third + call assert_equal(2, winnr('$')) + call assert_equal(3, line('.')) + + enew | only + set switchbuf=usetab + tab stag second + call assert_equal(2, tabpagenr('$')) + call assert_equal(2, line('.')) + 1tabnext | stag third + call assert_equal(2, tabpagenr('$')) + call assert_equal(3, line('.')) + + tabclose! + enew | only + call delete('Xfile1') + call delete('Xtags') + set switchbuf&vim +endfunc + " Tests for [ CTRL-I and CTRL-W CTRL-I commands function Test_keyword_jump() call writefile(["#include Xinclude", "", diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 621, +/**/ 620, /**/ 619, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -958,6 +958,14 @@ extern int (*dyn_libintl_putenv)(const c #define GETF_ALT 0x02 /* jumping to alternate file (not buf num) */ #define GETF_SWITCH 0x04 /* respect 'switchbuf' settings when jumping */ +/* Return values of getfile() */ +#define GETFILE_ERROR 1 /* normal error */ +#define GETFILE_NOT_WRITTEN 2 /* "not written" error */ +#define GETFILE_SAME_FILE 0 /* success, same file */ +#define GETFILE_OPEN_OTHER -1 /* success, opened another file */ +#define GETFILE_UNUSED 8 +#define GETFILE_SUCCESS(x) ((x) <= 0) + /* Values for buflist_new() flags */ #define BLN_CURBUF 1 /* may re-use curbuf for new buffer */ #define BLN_LISTED 2 /* put new buffer in buffer list */