]> granicus.if.org Git - vim/commitdiff
patch 8.2.1401: cannot jump to the last used tabpage v8.2.1401
authorBram Moolenaar <Bram@vim.org>
Sun, 9 Aug 2020 12:04:42 +0000 (14:04 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 9 Aug 2020 12:04:42 +0000 (14:04 +0200)
Problem:    Cannot jump to the last used tabpage.
Solution:   Add g<Tab> and tabpagnr('#'). (Yegappan Lakshmanan, closes #6661,
            neovim #11626)

runtime/doc/eval.txt
runtime/doc/index.txt
runtime/doc/tabpage.txt
src/evalwindow.c
src/globals.h
src/normal.c
src/proto/window.pro
src/testdir/test_tabpage.vim
src/version.c
src/window.c

index 5bb763a4a474aadc865de190c8b0ad6cc5454454..c579ed2faae8f45ede2fbc8e042606d39164c732 100644 (file)
@@ -10357,8 +10357,13 @@ tabpagebuflist([{arg}])                                        *tabpagebuflist()*
 tabpagenr([{arg}])                                     *tabpagenr()*
                The result is a Number, which is the number of the current
                tab page.  The first tab page has number 1.
-               When the optional argument is "$", the number of the last tab
-               page is returned (the tab page count).
+
+               The optional argument {arg} supports the following values:
+                       $       the number of the last tab page (the tab page
+                               count).
+                       #       the number of the last accessed tab page
+                               (where |g<Tab>| goes to). if there is no
+                               previous tab page 0 is returned.
                The number can be used with the |:tab| command.
 
 
index 83c6c176c874c87456a5f3aa12406a086a176cda..ed6916f62e1b37fb301ad74f7c1e19b35e6c6d2a 100644 (file)
@@ -440,6 +440,7 @@ tag         char          note action in Normal mode        ~
 |<C-LeftMouse>|        <C-LeftMouse>      ":ta" to the keyword at the mouse click
 |<C-Right>|    <C-Right>       1  same as "w"
 |<C-RightMouse>| <C-RightMouse>           same as "CTRL-T"
+|<C-Tab>|      <C-Tab>            same as "g<Tab>"
 |<Del>|                ["x]<Del>       2  same as "x"
 |N<Del>|       {count}<Del>       remove the last digit from {count}
 |<Down>|       <Down>          1  same as "j"
@@ -587,6 +588,8 @@ tag         command            action in Normal mode        ~
                                   following the file name.
 |CTRL-W_gt|    CTRL-W g t         same as `gt`: go to next tab page
 |CTRL-W_gT|    CTRL-W g T         same as `gT`: go to previous tab page
+|CTRL-W_g<Tab>|        CTRL-W g <Tab>     same as |g<Tab>|: go to last accessed tab
+                                  page.
 |CTRL-W_h|     CTRL-W h           go to Nth left window (stop at first window)
 |CTRL-W_i|     CTRL-W i           split window and jump to declaration of
                                   identifier under the cursor
@@ -805,6 +808,7 @@ tag         char          note action in Normal mode        ~
 |g<LeftMouse>| g<LeftMouse>       same as <C-LeftMouse>
                g<MiddleMouse>     same as <C-MiddleMouse>
 |g<RightMouse>|        g<RightMouse>      same as <C-RightMouse>
+|g<Tab>|       g<Tab>             go to the last accessed tab page.
 |g<Up>|                g<Up>           1  same as "gk"
 
 ==============================================================================
index 75070b5fe7c19d194e18d9b9a209c16f40e96498..1d8c2082f26772148f2d5a93448273826b5e1c96 100644 (file)
@@ -221,6 +221,8 @@ gT          Go to the previous tab page.  Wraps around from the first one
                                                        *:tabl* *:tablast*
 :tabl[ast]     Go to the last tab page.
 
+                                           *g<Tab>* *CTRL-W_g<Tab>* *<C-Tab>*
+g<Tab>         Go to the last accessed tab page.
 
 Other commands:
                                                        *:tabs*
index 0b3052c241ef5a8fb750d9c327be480fb76ec02c..b50776d74d8b04e90d3cd98cd3b0952c0fe26b8c 100644 (file)
@@ -616,6 +616,9 @@ f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv)
        {
            if (STRCMP(arg, "$") == 0)
                nr = tabpage_index(NULL) - 1;
+           else if (STRCMP(arg, "#") == 0)
+               nr = valid_tabpage(lastused_tabpage) ?
+                                       tabpage_index(lastused_tabpage) : 0;
            else
                semsg(_(e_invexpr2), arg);
        }
index cc01ac2508d579b2e406255fdf28bf5b89a62a5b..72b8a1e4604ebe69406961e7ff58233a5eda864f 100644 (file)
@@ -725,10 +725,12 @@ EXTERN frame_T    *topframe;      // top of the window frame tree
 
 /*
  * Tab pages are alternative topframes.  "first_tabpage" points to the first
- * one in the list, "curtab" is the current one.
+ * one in the list, "curtab" is the current one. "lastused_tabpage" is the
+ * last used one.
  */
 EXTERN tabpage_T    *first_tabpage;
 EXTERN tabpage_T    *curtab;
+EXTERN tabpage_T    *lastused_tabpage;
 EXTERN int         redraw_tabline INIT(= FALSE);  // need to redraw tabline
 
 /*
index dd79a43aac51c41e2e944ddf00141e7a2676b0b8..cb8e736368dc7e12a7534f67ca987ee081c2d4d6 100644 (file)
@@ -5442,7 +5442,7 @@ nv_gomark(cmdarg_T *cap)
 }
 
 /*
- * Handle CTRL-O, CTRL-I, "g;" and "g," commands.
+ * Handle CTRL-O, CTRL-I, "g;", "g," and "CTRL-Tab" commands.
  */
     static void
 nv_pcmark(cmdarg_T *cap)
@@ -5456,6 +5456,12 @@ nv_pcmark(cmdarg_T *cap)
 
     if (!checkclearopq(cap->oap))
     {
+       if (cap->cmdchar == TAB && mod_mask == MOD_MASK_CTRL)
+       {
+           if (goto_tabpage_lastused() == FAIL)
+               clearopbeep(cap->oap);
+           return;
+       }
        if (cap->cmdchar == 'g')
            pos = movechangelist((int)cap->count1);
        else
@@ -6310,6 +6316,11 @@ nv_g_cmd(cmdarg_T *cap)
            goto_tabpage(-(int)cap->count1);
        break;
 
+    case TAB:
+       if (!checkclearop(oap) && goto_tabpage_lastused() == FAIL)
+           clearopbeep(oap);
+       break;
+
     case '+':
     case '-': // "g+" and "g-": undo or redo along the timeline
        if (!checkclearopq(oap))
index ab62c0a096f3225097eb333f525f2b7072b17fe0..4c9bddd2814478ea269ceab87be8238d4375907d 100644 (file)
@@ -32,6 +32,7 @@ tabpage_T *find_tabpage(int n);
 int tabpage_index(tabpage_T *ftp);
 void goto_tabpage(int n);
 void goto_tabpage_tp(tabpage_T *tp, int trigger_enter_autocmds, int trigger_leave_autocmds);
+int goto_tabpage_lastused(void);
 void goto_tabpage_win(tabpage_T *tp, win_T *wp);
 void tabpage_move(int nr);
 void win_goto(win_T *wp);
index bbcafa8eb6fd343cc7fd0caed72e4dedeb6f42d7..67469718f2bb5808532ddaf6ee30415f6edbe996 100644 (file)
@@ -130,7 +130,7 @@ function Test_tabpage()
   1tabmove
   call assert_equal(2, tabpagenr())
 
-  call assert_fails('let t = tabpagenr("#")', 'E15:')
+  call assert_fails('let t = tabpagenr("@")', 'E15:')
   call assert_equal(0, tabpagewinnr(-1))
   call assert_fails("99tabmove", 'E16:')
   call assert_fails("+99tabmove", 'E16:')
@@ -777,4 +777,48 @@ func Test_tabpage_close_on_switch()
   %bw!
 endfunc
 
+" Test for jumping to last accessed tabpage
+func Test_lastused_tabpage()
+  tabonly!
+  call assert_equal(0, tabpagenr('#'))
+  call assert_beeps('call feedkeys("g\<Tab>", "xt")')
+  call assert_beeps('call feedkeys("\<C-Tab>", "xt")')
+  call assert_beeps('call feedkeys("\<C-W>g\<Tab>", "xt")')
+
+  " open four tab pages
+  tabnew
+  tabnew
+  tabnew
+
+  2tabnext
+
+  " Test for g<Tab>
+  call assert_equal(4, tabpagenr('#'))
+  call feedkeys("g\<Tab>", "xt")
+  call assert_equal(4, tabpagenr())
+  call assert_equal(2, tabpagenr('#'))
+
+  " Test for <C-Tab>
+  call feedkeys("\<C-Tab>", "xt")
+  call assert_equal(2, tabpagenr())
+  call assert_equal(4, tabpagenr('#'))
+
+  " Test for <C-W>g<Tab>
+  call feedkeys("\<C-W>g\<Tab>", "xt")
+  call assert_equal(4, tabpagenr())
+  call assert_equal(2, tabpagenr('#'))
+
+  " Try to jump to a closed tab page
+  tabclose 2
+  call assert_equal(0, tabpagenr('#'))
+  call feedkeys("g\<Tab>", "xt")
+  call assert_equal(3, tabpagenr())
+  call feedkeys("\<C-Tab>", "xt")
+  call assert_equal(3, tabpagenr())
+  call feedkeys("\<C-W>g\<Tab>", "xt")
+  call assert_equal(3, tabpagenr())
+
+  tabclose!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 20e8b36b810284b8133f51171addd0865b5f1c41..15f4c061d26f9866c6f87dfbbfc9d04f20c22fdf 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1401,
 /**/
     1400,
 /**/
index 4b2ff4b5231736acaa9a9413a82ac2b7ff2b072f..7d8122efdd00eb288f75e7d1e8a68fa9c4af4816 100644 (file)
@@ -627,6 +627,11 @@ wingotofile:
                        goto_tabpage(-(int)Prenum1);
                        break;
 
+                   case TAB:       // CTRL-W g<Tab>: go to last used tab page
+                       if (goto_tabpage_lastused() == FAIL)
+                           beep_flush();
+                       break;
+
                    default:
                        beep_flush();
                        break;
@@ -3809,6 +3814,9 @@ free_tabpage(tabpage_T *tp)
     unref_var_dict(tp->tp_vars);
 #endif
 
+    if (tp == lastused_tabpage)
+       lastused_tabpage = NULL;
+
     vim_free(tp->tp_localdir);
     vim_free(tp->tp_prevdir);
 
@@ -3883,6 +3891,8 @@ win_new_tabpage(int after)
        newtp->tp_topframe = topframe;
        last_status(FALSE);
 
+       lastused_tabpage = tp;
+
 #if defined(FEAT_GUI)
        // When 'guioptions' includes 'L' or 'R' may have to remove or add
        // scrollbars.  Have to update them anyway.
@@ -4118,6 +4128,7 @@ enter_tabpage(
     int                row;
     int                old_off = tp->tp_firstwin->w_winrow;
     win_T      *next_prevwin = tp->tp_prevwin;
+    tabpage_T  *last_tab = curtab;
 
     curtab = tp;
     firstwin = tp->tp_firstwin;
@@ -4160,6 +4171,8 @@ enter_tabpage(
     if (curtab->tp_old_Columns != Columns && starting == 0)
        shell_new_columns();    // update window widths
 
+    lastused_tabpage = last_tab;
+
 #if defined(FEAT_GUI)
     // When 'guioptions' includes 'L' or 'R' may have to remove or add
     // scrollbars.  Have to update them anyway.
@@ -4277,6 +4290,21 @@ goto_tabpage_tp(
     }
 }
 
+/*
+ * Go to the last accessed tab page, if there is one.
+ * Return OK or FAIL
+ */
+    int
+goto_tabpage_lastused(void)
+{
+    if (valid_tabpage(lastused_tabpage))
+    {
+       goto_tabpage_tp(lastused_tabpage, TRUE, TRUE);
+       return OK;
+    }
+    return FAIL;
+}
+
 /*
  * Enter window "wp" in tab page "tp".
  * Also updates the GUI tab.