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:
90
src/buffer.c
90
src/buffer.c
@@ -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,7 +4609,13 @@ do_arg_all(count, forceit, keep_tabs)
|
|||||||
{
|
{
|
||||||
if (wpnext->w_arg_idx == i)
|
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;
|
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);
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user