0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

updated for version 7.3.456

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)
This commit is contained in:
Bram Moolenaar
2012-02-22 19:13:08 +01:00
parent b549a731fb
commit 52379eadfb
4 changed files with 108 additions and 24 deletions

View File

@@ -4405,7 +4405,12 @@ do_arg_all(count, forceit, keep_tabs)
{ {
int i; int i;
win_T *wp, *wpnext; 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 opened_len; /* length of opened[] */
int use_firstwin = FALSE; /* use first window for arglist */ int use_firstwin = FALSE; /* use first window for arglist */
int split_ret = OK; int split_ret = OK;
@@ -4414,6 +4419,8 @@ do_arg_all(count, forceit, keep_tabs)
buf_T *buf; buf_T *buf;
tabpage_T *tpnext; tabpage_T *tpnext;
int had_tab = cmdmod.tab; int had_tab = cmdmod.tab;
win_T *old_curwin, *last_curwin;
tabpage_T *old_curtab, *last_curtab;
win_T *new_curwin = NULL; win_T *new_curwin = NULL;
tabpage_T *new_curtab = NULL; tabpage_T *new_curtab = NULL;
@@ -4430,6 +4437,15 @@ do_arg_all(count, forceit, keep_tabs)
if (opened == NULL) if (opened == NULL)
return; 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 #ifdef FEAT_GUI
need_mouse_correct = TRUE; need_mouse_correct = TRUE;
#endif #endif
@@ -4451,36 +4467,51 @@ do_arg_all(count, forceit, keep_tabs)
wpnext = wp->w_next; wpnext = wp->w_next;
buf = wp->w_buffer; buf = wp->w_buffer;
if (buf->b_ffname == NULL if (buf->b_ffname == NULL
|| buf->b_nwindows > 1 || (!keep_tabs && buf->b_nwindows > 1)
#ifdef FEAT_VERTSPLIT #ifdef FEAT_VERTSPLIT
|| wp->w_width != Columns || wp->w_width != Columns
#endif #endif
) )
i = ARGCOUNT; i = opened_len;
else else
{ {
/* check if the buffer in this window is in the arglist */ /* 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 if (i < alist->al_ga.ga_len
|| fullpathcmp(alist_name(&ARGLIST[i]), && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum
buf->b_ffname, TRUE) & FPC_SAME) || fullpathcmp(alist_name(&AARGLIST(alist)[i]),
buf->b_ffname, TRUE) & FPC_SAME))
{ {
if (i < opened_len) int weight = 1;
if (old_curtab == curtab)
{ {
opened[i] = TRUE; ++weight;
if (old_curwin == wp)
++weight;
}
if (weight > (int)opened[i])
{
opened[i] = (char_u)weight;
if (i == 0) if (i == 0)
{ {
if (new_curwin != NULL)
new_curwin->w_arg_idx = opened_len;
new_curwin = wp; new_curwin = wp;
new_curtab = curtab; 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 /* Use the current argument list for all windows
* containing a file from it. */ * containing a file from it. */
alist_unlink(wp->w_alist); alist_unlink(wp->w_alist);
wp->w_alist = curwin->w_alist; wp->w_alist = alist;
++wp->w_alist->al_refcount; ++wp->w_alist->al_refcount;
} }
break; break;
@@ -4489,7 +4520,7 @@ do_arg_all(count, forceit, keep_tabs)
} }
wp->w_arg_idx = i; 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 if (P_HID(buf) || forceit || buf->b_nwindows > 1
|| !bufIsChanged(buf)) || !bufIsChanged(buf))
@@ -4511,7 +4542,8 @@ do_arg_all(count, forceit, keep_tabs)
} }
#ifdef FEAT_WINDOWS #ifdef FEAT_WINDOWS
/* don't close last window */ /* don't close last window */
if (firstwin == lastwin && first_tabpage->tp_next == NULL) if (firstwin == lastwin
&& (first_tabpage->tp_next == NULL || !had_tab))
#endif #endif
use_firstwin = TRUE; use_firstwin = TRUE;
#ifdef FEAT_WINDOWS #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. * Open a window for files in the argument list that don't have one.
* ARGCOUNT may change while doing this, because of autocommands. * ARGCOUNT may change while doing this, because of autocommands.
*/ */
if (count > ARGCOUNT || count <= 0) if (count > opened_len || count <= 0)
count = ARGCOUNT; count = opened_len;
/* 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;
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
/* Don't execute Win/Buf Enter/Leave autocommands here. */ /* Don't execute Win/Buf Enter/Leave autocommands here. */
++autocmd_no_enter; ++autocmd_no_enter;
++autocmd_no_leave; ++autocmd_no_leave;
#endif #endif
last_curwin = curwin;
last_curtab = curtab;
win_enter(lastwin, FALSE); win_enter(lastwin, FALSE);
#ifdef FEAT_WINDOWS #ifdef FEAT_WINDOWS
/* ":drop all" should re-use an empty window to avoid "--remote-tab" /* ":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; use_firstwin = TRUE;
#endif #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) if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1)
arg_had_last = TRUE; arg_had_last = TRUE;
if (i < opened_len && opened[i]) if (opened[i] > 0)
{ {
/* Move the already present window to below the current window */ /* Move the already present window to below the current window */
if (curwin->w_arg_idx != i) if (curwin->w_arg_idx != i)
@@ -4581,6 +4609,12 @@ do_arg_all(count, forceit, keep_tabs)
{ {
if (wpnext->w_arg_idx == i) if (wpnext->w_arg_idx == i)
{ {
if (keep_tabs)
{
new_curwin = wpnext;
new_curtab = curtab;
}
else
win_move_after(wpnext, curwin); win_move_after(wpnext, curwin);
break; break;
} }
@@ -4636,6 +4670,14 @@ do_arg_all(count, forceit, keep_tabs)
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
--autocmd_no_enter; --autocmd_no_enter;
#endif #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 */ /* to window with first arg */
if (valid_tabpage(new_curtab)) if (valid_tabpage(new_curtab))
goto_tabpage_tp(new_curtab); goto_tabpage_tp(new_curtab);

View File

@@ -50,6 +50,43 @@ STARTTEST
:call append(line('$'), test_status) :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 :/^Results/,$w! test.out
:qa! :qa!
ENDTEST ENDTEST

View File

@@ -5,3 +5,6 @@ this is tab page 1
this is tab page 4 this is tab page 4
gettabvar: pass gettabvar: pass
settabvar: pass settabvar: pass
tab drop 1: pass
tab drop 2: pass
tab drop 3: pass

View File

@@ -714,6 +714,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
456,
/**/ /**/
455, 455,
/**/ /**/