]>
Commit | Line | Data |
---|---|---|
03d4279c AM |
1 | To: vim_dev@googlegroups.com |
2 | Subject: Patch 7.3.456 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.3.456 | |
11 | Problem: ":tab drop file" has several problems, including moving the | |
12 | current window and opening a new tab for a file that already has a | |
13 | window. | |
14 | Solution: Refactor ":tab drop" handling. (Hirohito Higashi) | |
15 | Files: src/buffer.c, src/testdir/test62.in, src/testdir/test62.ok | |
16 | ||
17 | ||
18 | *** ../vim-7.3.455/src/buffer.c 2012-02-22 14:58:24.000000000 +0100 | |
19 | --- src/buffer.c 2012-02-22 19:08:34.000000000 +0100 | |
20 | *************** | |
21 | *** 4405,4411 **** | |
22 | { | |
23 | int i; | |
24 | win_T *wp, *wpnext; | |
25 | ! char_u *opened; /* array of flags for which args are open */ | |
26 | int opened_len; /* length of opened[] */ | |
27 | int use_firstwin = FALSE; /* use first window for arglist */ | |
28 | int split_ret = OK; | |
29 | --- 4405,4416 ---- | |
30 | { | |
31 | int i; | |
32 | win_T *wp, *wpnext; | |
33 | ! char_u *opened; /* Array of weight for which args are open: | |
34 | ! * 0: not opened | |
35 | ! * 1: opened in other tab | |
36 | ! * 2: opened in curtab | |
37 | ! * 3: opened in curtab and curwin | |
38 | ! */ | |
39 | int opened_len; /* length of opened[] */ | |
40 | int use_firstwin = FALSE; /* use first window for arglist */ | |
41 | int split_ret = OK; | |
42 | *************** | |
43 | *** 4414,4419 **** | |
44 | --- 4419,4426 ---- | |
45 | buf_T *buf; | |
46 | tabpage_T *tpnext; | |
47 | int had_tab = cmdmod.tab; | |
48 | + win_T *old_curwin, *last_curwin; | |
49 | + tabpage_T *old_curtab, *last_curtab; | |
50 | win_T *new_curwin = NULL; | |
51 | tabpage_T *new_curtab = NULL; | |
52 | ||
53 | *************** | |
54 | *** 4430,4435 **** | |
55 | --- 4437,4451 ---- | |
56 | if (opened == NULL) | |
57 | return; | |
58 | ||
59 | + /* Autocommands may do anything to the argument list. Make sure it's not | |
60 | + * freed while we are working here by "locking" it. We still have to | |
61 | + * watch out for its size to be changed. */ | |
62 | + alist = curwin->w_alist; | |
63 | + ++alist->al_refcount; | |
64 | + | |
65 | + old_curwin = curwin; | |
66 | + old_curtab = curtab; | |
67 | + | |
68 | #ifdef FEAT_GUI | |
69 | need_mouse_correct = TRUE; | |
70 | #endif | |
71 | *************** | |
72 | *** 4451,4486 **** | |
73 | wpnext = wp->w_next; | |
74 | buf = wp->w_buffer; | |
75 | if (buf->b_ffname == NULL | |
76 | ! || buf->b_nwindows > 1 | |
77 | #ifdef FEAT_VERTSPLIT | |
78 | || wp->w_width != Columns | |
79 | #endif | |
80 | ) | |
81 | ! i = ARGCOUNT; | |
82 | else | |
83 | { | |
84 | /* check if the buffer in this window is in the arglist */ | |
85 | ! for (i = 0; i < ARGCOUNT; ++i) | |
86 | { | |
87 | ! if (ARGLIST[i].ae_fnum == buf->b_fnum | |
88 | ! || fullpathcmp(alist_name(&ARGLIST[i]), | |
89 | ! buf->b_ffname, TRUE) & FPC_SAME) | |
90 | { | |
91 | ! if (i < opened_len) | |
92 | { | |
93 | ! opened[i] = TRUE; | |
94 | if (i == 0) | |
95 | { | |
96 | new_curwin = wp; | |
97 | new_curtab = curtab; | |
98 | } | |
99 | } | |
100 | ! if (wp->w_alist != curwin->w_alist) | |
101 | { | |
102 | /* Use the current argument list for all windows | |
103 | * containing a file from it. */ | |
104 | alist_unlink(wp->w_alist); | |
105 | ! wp->w_alist = curwin->w_alist; | |
106 | ++wp->w_alist->al_refcount; | |
107 | } | |
108 | break; | |
109 | --- 4467,4517 ---- | |
110 | wpnext = wp->w_next; | |
111 | buf = wp->w_buffer; | |
112 | if (buf->b_ffname == NULL | |
113 | ! || (!keep_tabs && buf->b_nwindows > 1) | |
114 | #ifdef FEAT_VERTSPLIT | |
115 | || wp->w_width != Columns | |
116 | #endif | |
117 | ) | |
118 | ! i = opened_len; | |
119 | else | |
120 | { | |
121 | /* check if the buffer in this window is in the arglist */ | |
122 | ! for (i = 0; i < opened_len; ++i) | |
123 | { | |
124 | ! if (i < alist->al_ga.ga_len | |
125 | ! && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum | |
126 | ! || fullpathcmp(alist_name(&AARGLIST(alist)[i]), | |
127 | ! buf->b_ffname, TRUE) & FPC_SAME)) | |
128 | { | |
129 | ! int weight = 1; | |
130 | ! | |
131 | ! if (old_curtab == curtab) | |
132 | ! { | |
133 | ! ++weight; | |
134 | ! if (old_curwin == wp) | |
135 | ! ++weight; | |
136 | ! } | |
137 | ! | |
138 | ! if (weight > (int)opened[i]) | |
139 | { | |
140 | ! opened[i] = (char_u)weight; | |
141 | if (i == 0) | |
142 | { | |
143 | + if (new_curwin != NULL) | |
144 | + new_curwin->w_arg_idx = opened_len; | |
145 | new_curwin = wp; | |
146 | new_curtab = curtab; | |
147 | } | |
148 | } | |
149 | ! else if (keep_tabs) | |
150 | ! i = opened_len; | |
151 | ! | |
152 | ! if (wp->w_alist != alist) | |
153 | { | |
154 | /* Use the current argument list for all windows | |
155 | * containing a file from it. */ | |
156 | alist_unlink(wp->w_alist); | |
157 | ! wp->w_alist = alist; | |
158 | ++wp->w_alist->al_refcount; | |
159 | } | |
160 | break; | |
161 | *************** | |
162 | *** 4489,4495 **** | |
163 | } | |
164 | wp->w_arg_idx = i; | |
165 | ||
166 | ! if (i == ARGCOUNT && !keep_tabs) /* close this window */ | |
167 | { | |
168 | if (P_HID(buf) || forceit || buf->b_nwindows > 1 | |
169 | || !bufIsChanged(buf)) | |
170 | --- 4520,4526 ---- | |
171 | } | |
172 | wp->w_arg_idx = i; | |
173 | ||
174 | ! if (i == opened_len && !keep_tabs)/* close this window */ | |
175 | { | |
176 | if (P_HID(buf) || forceit || buf->b_nwindows > 1 | |
177 | || !bufIsChanged(buf)) | |
178 | *************** | |
179 | *** 4511,4517 **** | |
180 | } | |
181 | #ifdef FEAT_WINDOWS | |
182 | /* don't close last window */ | |
183 | ! if (firstwin == lastwin && first_tabpage->tp_next == NULL) | |
184 | #endif | |
185 | use_firstwin = TRUE; | |
186 | #ifdef FEAT_WINDOWS | |
187 | --- 4542,4549 ---- | |
188 | } | |
189 | #ifdef FEAT_WINDOWS | |
190 | /* don't close last window */ | |
191 | ! if (firstwin == lastwin | |
192 | ! && (first_tabpage->tp_next == NULL || !had_tab)) | |
193 | #endif | |
194 | use_firstwin = TRUE; | |
195 | #ifdef FEAT_WINDOWS | |
196 | *************** | |
197 | *** 4545,4564 **** | |
198 | * Open a window for files in the argument list that don't have one. | |
199 | * ARGCOUNT may change while doing this, because of autocommands. | |
200 | */ | |
201 | ! if (count > ARGCOUNT || count <= 0) | |
202 | ! count = ARGCOUNT; | |
203 | ! | |
204 | ! /* Autocommands may do anything to the argument list. Make sure it's not | |
205 | ! * freed while we are working here by "locking" it. We still have to | |
206 | ! * watch out for its size to be changed. */ | |
207 | ! alist = curwin->w_alist; | |
208 | ! ++alist->al_refcount; | |
209 | ||
210 | #ifdef FEAT_AUTOCMD | |
211 | /* Don't execute Win/Buf Enter/Leave autocommands here. */ | |
212 | ++autocmd_no_enter; | |
213 | ++autocmd_no_leave; | |
214 | #endif | |
215 | win_enter(lastwin, FALSE); | |
216 | #ifdef FEAT_WINDOWS | |
217 | /* ":drop all" should re-use an empty window to avoid "--remote-tab" | |
218 | --- 4577,4592 ---- | |
219 | * Open a window for files in the argument list that don't have one. | |
220 | * ARGCOUNT may change while doing this, because of autocommands. | |
221 | */ | |
222 | ! if (count > opened_len || count <= 0) | |
223 | ! count = opened_len; | |
224 | ||
225 | #ifdef FEAT_AUTOCMD | |
226 | /* Don't execute Win/Buf Enter/Leave autocommands here. */ | |
227 | ++autocmd_no_enter; | |
228 | ++autocmd_no_leave; | |
229 | #endif | |
230 | + last_curwin = curwin; | |
231 | + last_curtab = curtab; | |
232 | win_enter(lastwin, FALSE); | |
233 | #ifdef FEAT_WINDOWS | |
234 | /* ":drop all" should re-use an empty window to avoid "--remote-tab" | |
235 | *************** | |
236 | *** 4568,4578 **** | |
237 | use_firstwin = TRUE; | |
238 | #endif | |
239 | ||
240 | ! for (i = 0; i < count && i < alist->al_ga.ga_len && !got_int; ++i) | |
241 | { | |
242 | if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1) | |
243 | arg_had_last = TRUE; | |
244 | ! if (i < opened_len && opened[i]) | |
245 | { | |
246 | /* Move the already present window to below the current window */ | |
247 | if (curwin->w_arg_idx != i) | |
248 | --- 4596,4606 ---- | |
249 | use_firstwin = TRUE; | |
250 | #endif | |
251 | ||
252 | ! for (i = 0; i < count && i < opened_len && !got_int; ++i) | |
253 | { | |
254 | if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1) | |
255 | arg_had_last = TRUE; | |
256 | ! if (opened[i] > 0) | |
257 | { | |
258 | /* Move the already present window to below the current window */ | |
259 | if (curwin->w_arg_idx != i) | |
260 | *************** | |
261 | *** 4581,4587 **** | |
262 | { | |
263 | if (wpnext->w_arg_idx == i) | |
264 | { | |
265 | ! win_move_after(wpnext, curwin); | |
266 | break; | |
267 | } | |
268 | } | |
269 | --- 4609,4621 ---- | |
270 | { | |
271 | if (wpnext->w_arg_idx == i) | |
272 | { | |
273 | ! if (keep_tabs) | |
274 | ! { | |
275 | ! new_curwin = wpnext; | |
276 | ! new_curtab = curtab; | |
277 | ! } | |
278 | ! else | |
279 | ! win_move_after(wpnext, curwin); | |
280 | break; | |
281 | } | |
282 | } | |
283 | *************** | |
284 | *** 4636,4641 **** | |
285 | --- 4670,4683 ---- | |
286 | #ifdef FEAT_AUTOCMD | |
287 | --autocmd_no_enter; | |
288 | #endif | |
289 | + /* restore last referenced tabpage's curwin */ | |
290 | + if (last_curtab != new_curtab) | |
291 | + { | |
292 | + if (valid_tabpage(last_curtab)) | |
293 | + goto_tabpage_tp(last_curtab); | |
294 | + if (win_valid(last_curwin)) | |
295 | + win_enter(last_curwin, FALSE); | |
296 | + } | |
297 | /* to window with first arg */ | |
298 | if (valid_tabpage(new_curtab)) | |
299 | goto_tabpage_tp(new_curtab); | |
300 | *** ../vim-7.3.455/src/testdir/test62.in 2010-08-15 21:57:29.000000000 +0200 | |
301 | --- src/testdir/test62.in 2012-02-22 18:45:10.000000000 +0100 | |
302 | *************** | |
303 | *** 50,55 **** | |
304 | --- 50,92 ---- | |
305 | :call append(line('$'), test_status) | |
306 | :" | |
307 | :" | |
308 | + :" Test for ":tab drop exist-file" to keep current window. | |
309 | + :sp test1 | |
310 | + :tab drop test1 | |
311 | + :let test_status = 'tab drop 1: fail' | |
312 | + :if tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1 | |
313 | + : let test_status = 'tab drop 1: pass' | |
314 | + :endif | |
315 | + :close | |
316 | + :call append(line('$'), test_status) | |
317 | + :" | |
318 | + :" | |
319 | + :" Test for ":tab drop new-file" to keep current window of tabpage 1. | |
320 | + :split | |
321 | + :tab drop newfile | |
322 | + :let test_status = 'tab drop 2: fail' | |
323 | + :if tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1 | |
324 | + : let test_status = 'tab drop 2: pass' | |
325 | + :endif | |
326 | + :tabclose | |
327 | + :q | |
328 | + :call append(line('$'), test_status) | |
329 | + :" | |
330 | + :" | |
331 | + :" Test for ":tab drop multi-opend-file" to keep current tabpage and window. | |
332 | + :new test1 | |
333 | + :tabnew | |
334 | + :new test1 | |
335 | + :tab drop test1 | |
336 | + :let test_status = 'tab drop 3: fail' | |
337 | + :if tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1 | |
338 | + : let test_status = 'tab drop 3: pass' | |
339 | + :endif | |
340 | + :tabclose | |
341 | + :q | |
342 | + :call append(line('$'), test_status) | |
343 | + :" | |
344 | + :" | |
345 | :/^Results/,$w! test.out | |
346 | :qa! | |
347 | ENDTEST | |
348 | *** ../vim-7.3.455/src/testdir/test62.ok 2010-08-15 21:57:29.000000000 +0200 | |
349 | --- src/testdir/test62.ok 2012-02-22 18:45:10.000000000 +0100 | |
350 | *************** | |
351 | *** 5,7 **** | |
352 | --- 5,10 ---- | |
353 | this is tab page 4 | |
354 | gettabvar: pass | |
355 | settabvar: pass | |
356 | + tab drop 1: pass | |
357 | + tab drop 2: pass | |
358 | + tab drop 3: pass | |
359 | *** ../vim-7.3.455/src/version.c 2012-02-22 18:29:29.000000000 +0100 | |
360 | --- src/version.c 2012-02-22 19:11:52.000000000 +0100 | |
361 | *************** | |
362 | *** 716,717 **** | |
363 | --- 716,719 ---- | |
364 | { /* Add new patch number below this line */ | |
365 | + /**/ | |
366 | + 456, | |
367 | /**/ | |
368 | ||
369 | -- | |
370 | % cat /usr/include/life.h | |
371 | void life(void); | |
372 | ||
373 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
374 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
375 | \\\ an exciting new programming language -- http://www.Zimbu.org /// | |
376 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |