Created
January 31, 2012 10:34
-
-
Save h-east/1709817 to your computer and use it in GitHub Desktop.
patch for vim-jp/Issue#127 (":tab drop file" is moved current window.)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r d3cf98aa1619 src/buffer.c | |
--- a/src/buffer.c Sat Jan 28 18:03:35 2012 +0100 | |
+++ b/src/buffer.c Tue Jan 31 18:30:50 2012 +0900 | |
@@ -4387,7 +4387,12 @@ | |
{ | |
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; | |
@@ -4396,6 +4401,8 @@ | |
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; | |
@@ -4412,6 +4419,15 @@ | |
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 | |
@@ -4433,36 +4449,50 @@ | |
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]), | |
+ if (AARGLIST(alist)[i].ae_fnum == buf->b_fnum | |
+ || fullpathcmp(alist_name(&AARGLIST(alist)[i]), | |
buf->b_ffname, TRUE) & FPC_SAME) | |
{ | |
- if (i < opened_len) | |
+ char_u weight = 1; | |
+ | |
+ if (old_curtab == curtab) | |
{ | |
- opened[i] = TRUE; | |
+ ++weight; | |
+ if (old_curwin == wp) | |
+ ++weight; | |
+ } | |
+ | |
+ if (weight > opened[i]) | |
+ { | |
+ opened[i] = 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; | |
@@ -4471,7 +4501,7 @@ | |
} | |
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)) | |
@@ -4493,7 +4523,8 @@ | |
} | |
#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 | |
@@ -4527,20 +4558,16 @@ | |
* 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" | |
@@ -4550,11 +4577,11 @@ | |
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) | |
@@ -4563,7 +4590,13 @@ | |
{ | |
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; | |
} | |
} | |
@@ -4618,6 +4651,14 @@ | |
#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); | |
diff -r d3cf98aa1619 src/testdir/test62.in | |
--- a/src/testdir/test62.in Sat Jan 28 18:03:35 2012 +0100 | |
+++ b/src/testdir/test62.in Tue Jan 31 18:30:50 2012 +0900 | |
@@ -50,6 +50,43 @@ | |
: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 | |
diff -r d3cf98aa1619 src/testdir/test62.ok | |
--- a/src/testdir/test62.ok Sat Jan 28 18:03:35 2012 +0100 | |
+++ b/src/testdir/test62.ok Tue Jan 31 18:30:50 2012 +0900 | |
@@ -5,3 +5,6 @@ | |
this is tab page 4 | |
gettabvar: pass | |
settabvar: pass | |
+tab drop 1: pass | |
+tab drop 2: pass | |
+tab drop 3: pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment