changeset 11476:c45fb081391c v8.0.0621

patch 8.0.0621: :stag does not respect 'switchbuf' commit https://github.com/vim/vim/commit/8ad80dea089ffeb1a845199c013e9bb4be1cd22e Author: Bram Moolenaar <Bram@vim.org> 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().
author Christian Brabandt <cb@256bit.org>
date Mon, 05 Jun 2017 16:15:03 +0200
parents 53a8f79670ee
children 9b3085226911
files src/buffer.c src/ex_cmds.c src/search.c src/tag.c src/testdir/test_tagjump.vim src/version.c src/vim.h
diffstat 7 files changed, 103 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- 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;
 
--- 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);
--- 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 */
--- 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)
--- 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", "",
--- 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,
--- 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 */