]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.456 v7.3.456
authorBram Moolenaar <Bram@vim.org>
Wed, 22 Feb 2012 18:13:08 +0000 (19:13 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 22 Feb 2012 18:13:08 +0000 (19:13 +0100)
Problem:    ":tab drop file" has several problems, including moving the
            current window and opening a new tab for a file that already has a
            window.
Solution:   Refactor ":tab drop" handling. (Hirohito Higashi)

src/buffer.c
src/testdir/test62.in
src/testdir/test62.ok
src/version.c

index 75116a91b2ccc82c16135c7c0b9ede7ed860c70d..1b5ae9f9a2d6d913acc1d9a975027eb186359da3 100644 (file)
@@ -4405,7 +4405,12 @@ do_arg_all(count, forceit, keep_tabs)
 {
     int                i;
     win_T      *wp, *wpnext;
-    char_u     *opened;        /* array of flags for which args are open */
+    char_u     *opened;        /* Array of weight for which args are open:
+                                *  0: not opened
+                                *  1: opened in other tab
+                                *  2: opened in curtab
+                                *  3: opened in curtab and curwin
+                                */
     int                opened_len;     /* length of opened[] */
     int                use_firstwin = FALSE;   /* use first window for arglist */
     int                split_ret = OK;
@@ -4414,6 +4419,8 @@ do_arg_all(count, forceit, keep_tabs)
     buf_T      *buf;
     tabpage_T  *tpnext;
     int                had_tab = cmdmod.tab;
+    win_T      *old_curwin, *last_curwin;
+    tabpage_T  *old_curtab, *last_curtab;
     win_T      *new_curwin = NULL;
     tabpage_T  *new_curtab = NULL;
 
@@ -4430,6 +4437,15 @@ do_arg_all(count, forceit, keep_tabs)
     if (opened == NULL)
        return;
 
+    /* Autocommands may do anything to the argument list.  Make sure it's not
+     * freed while we are working here by "locking" it.  We still have to
+     * watch out for its size to be changed. */
+    alist = curwin->w_alist;
+    ++alist->al_refcount;
+
+    old_curwin = curwin;
+    old_curtab = curtab;
+
 #ifdef FEAT_GUI
     need_mouse_correct = TRUE;
 #endif
@@ -4451,36 +4467,51 @@ do_arg_all(count, forceit, keep_tabs)
            wpnext = wp->w_next;
            buf = wp->w_buffer;
            if (buf->b_ffname == NULL
-                   || buf->b_nwindows > 1
+                   || (!keep_tabs && buf->b_nwindows > 1)
 #ifdef FEAT_VERTSPLIT
                    || wp->w_width != Columns
 #endif
                    )
-               i = ARGCOUNT;
+               i = opened_len;
            else
            {
                /* check if the buffer in this window is in the arglist */
-               for (i = 0; i < ARGCOUNT; ++i)
+               for (i = 0; i < opened_len; ++i)
                {
-                   if (ARGLIST[i].ae_fnum == buf->b_fnum
-                           || fullpathcmp(alist_name(&ARGLIST[i]),
-                                             buf->b_ffname, TRUE) & FPC_SAME)
+                   if (i < alist->al_ga.ga_len
+                           && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum
+                               || fullpathcmp(alist_name(&AARGLIST(alist)[i]),
+                                             buf->b_ffname, TRUE) & FPC_SAME))
                    {
-                       if (i < opened_len)
+                       int weight = 1;
+
+                       if (old_curtab == curtab)
+                       {
+                           ++weight;
+                           if (old_curwin == wp)
+                               ++weight;
+                       }
+
+                       if (weight > (int)opened[i])
                        {
-                           opened[i] = TRUE;
+                           opened[i] = (char_u)weight;
                            if (i == 0)
                            {
+                               if (new_curwin != NULL)
+                                   new_curwin->w_arg_idx = opened_len;
                                new_curwin = wp;
                                new_curtab = curtab;
                            }
                        }
-                       if (wp->w_alist != curwin->w_alist)
+                       else if (keep_tabs)
+                           i = opened_len;
+
+                       if (wp->w_alist != alist)
                        {
                            /* Use the current argument list for all windows
                             * containing a file from it. */
                            alist_unlink(wp->w_alist);
-                           wp->w_alist = curwin->w_alist;
+                           wp->w_alist = alist;
                            ++wp->w_alist->al_refcount;
                        }
                        break;
@@ -4489,7 +4520,7 @@ do_arg_all(count, forceit, keep_tabs)
            }
            wp->w_arg_idx = i;
 
-           if (i == ARGCOUNT && !keep_tabs)    /* close this window */
+           if (i == opened_len && !keep_tabs)/* close this window */
            {
                if (P_HID(buf) || forceit || buf->b_nwindows > 1
                                                        || !bufIsChanged(buf))
@@ -4511,7 +4542,8 @@ do_arg_all(count, forceit, keep_tabs)
                    }
 #ifdef FEAT_WINDOWS
                    /* don't close last window */
-                   if (firstwin == lastwin && first_tabpage->tp_next == NULL)
+                   if (firstwin == lastwin
+                           && (first_tabpage->tp_next == NULL || !had_tab))
 #endif
                        use_firstwin = TRUE;
 #ifdef FEAT_WINDOWS
@@ -4545,20 +4577,16 @@ do_arg_all(count, forceit, keep_tabs)
      * Open a window for files in the argument list that don't have one.
      * ARGCOUNT may change while doing this, because of autocommands.
      */
-    if (count > ARGCOUNT || count <= 0)
-       count = ARGCOUNT;
-
-    /* Autocommands may do anything to the argument list.  Make sure it's not
-     * freed while we are working here by "locking" it.  We still have to
-     * watch out for its size to be changed. */
-    alist = curwin->w_alist;
-    ++alist->al_refcount;
+    if (count > opened_len || count <= 0)
+       count = opened_len;
 
 #ifdef FEAT_AUTOCMD
     /* Don't execute Win/Buf Enter/Leave autocommands here. */
     ++autocmd_no_enter;
     ++autocmd_no_leave;
 #endif
+    last_curwin = curwin;
+    last_curtab = curtab;
     win_enter(lastwin, FALSE);
 #ifdef FEAT_WINDOWS
     /* ":drop all" should re-use an empty window to avoid "--remote-tab"
@@ -4568,11 +4596,11 @@ do_arg_all(count, forceit, keep_tabs)
        use_firstwin = TRUE;
 #endif
 
-    for (i = 0; i < count && i < alist->al_ga.ga_len && !got_int; ++i)
+    for (i = 0; i < count && i < opened_len && !got_int; ++i)
     {
        if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1)
            arg_had_last = TRUE;
-       if (i < opened_len && opened[i])
+       if (opened[i] > 0)
        {
            /* Move the already present window to below the current window */
            if (curwin->w_arg_idx != i)
@@ -4581,7 +4609,13 @@ do_arg_all(count, forceit, keep_tabs)
                {
                    if (wpnext->w_arg_idx == i)
                    {
-                       win_move_after(wpnext, curwin);
+                       if (keep_tabs)
+                       {
+                           new_curwin = wpnext;
+                           new_curtab = curtab;
+                       }
+                       else
+                           win_move_after(wpnext, curwin);
                        break;
                    }
                }
@@ -4636,6 +4670,14 @@ do_arg_all(count, forceit, keep_tabs)
 #ifdef FEAT_AUTOCMD
     --autocmd_no_enter;
 #endif
+    /* restore last referenced tabpage's curwin */
+    if (last_curtab != new_curtab)
+    {
+       if (valid_tabpage(last_curtab))
+           goto_tabpage_tp(last_curtab);
+       if (win_valid(last_curwin))
+           win_enter(last_curwin, FALSE);
+    }
     /* to window with first arg */
     if (valid_tabpage(new_curtab))
        goto_tabpage_tp(new_curtab);
index b813830980fcc2e18a465921dc8c3fca1b8d795e..c549c8b43868ccf8ee9d8bcf68d1e14a7b643a71 100644 (file)
@@ -50,6 +50,43 @@ STARTTEST
 :call append(line('$'), test_status)
 :"
 :"
+:" Test for ":tab drop exist-file" to keep current window.
+:sp test1
+:tab drop test1
+:let test_status = 'tab drop 1: fail'
+:if tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1
+:    let test_status = 'tab drop 1: pass'
+:endif
+:close
+:call append(line('$'), test_status)
+:"
+:"
+:" Test for ":tab drop new-file" to keep current window of tabpage 1.
+:split
+:tab drop newfile
+:let test_status = 'tab drop 2: fail'
+:if tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1
+:    let test_status = 'tab drop 2: pass'
+:endif
+:tabclose
+:q
+:call append(line('$'), test_status)
+:"
+:"
+:" Test for ":tab drop multi-opend-file" to keep current tabpage and window.
+:new test1
+:tabnew
+:new test1
+:tab drop test1
+:let test_status = 'tab drop 3: fail'
+:if tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1
+:    let test_status = 'tab drop 3: pass'
+:endif
+:tabclose
+:q
+:call append(line('$'), test_status)
+:"
+:"
 :/^Results/,$w! test.out
 :qa!
 ENDTEST
index 9a51e44248b38a9e9f78317c13aaeb66b4be2c30..7625cd2e2c5cc88e44cce2e74fc1a1322695681e 100644 (file)
@@ -5,3 +5,6 @@ this is tab page 1
 this is tab page 4
 gettabvar: pass
 settabvar: pass
+tab drop 1: pass
+tab drop 2: pass
+tab drop 3: pass
index 7945ffee02a92923bfbcacad38fffa43372c64b1..f47e7bd16a7d9ddfdec3ff3e0c60c3aa79079cef 100644 (file)
@@ -714,6 +714,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    456,
 /**/
     455,
 /**/