Mercurial > vim
comparison src/buffer.c @ 3380:07fd030f89be v7.3.456
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)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 22 Feb 2012 19:13:08 +0100 |
parents | 9ccdc4a69d8f |
children | e61c3b09ae86 |
comparison
equal
deleted
inserted
replaced
3379:4a7a394e7afe | 3380:07fd030f89be |
---|---|
4403 int forceit; /* hide buffers in current windows */ | 4403 int forceit; /* hide buffers in current windows */ |
4404 int keep_tabs; /* keep current tabs, for ":tab drop file" */ | 4404 int keep_tabs; /* keep current tabs, for ":tab drop file" */ |
4405 { | 4405 { |
4406 int i; | 4406 int i; |
4407 win_T *wp, *wpnext; | 4407 win_T *wp, *wpnext; |
4408 char_u *opened; /* array of flags for which args are open */ | 4408 char_u *opened; /* Array of weight for which args are open: |
4409 * 0: not opened | |
4410 * 1: opened in other tab | |
4411 * 2: opened in curtab | |
4412 * 3: opened in curtab and curwin | |
4413 */ | |
4409 int opened_len; /* length of opened[] */ | 4414 int opened_len; /* length of opened[] */ |
4410 int use_firstwin = FALSE; /* use first window for arglist */ | 4415 int use_firstwin = FALSE; /* use first window for arglist */ |
4411 int split_ret = OK; | 4416 int split_ret = OK; |
4412 int p_ea_save; | 4417 int p_ea_save; |
4413 alist_T *alist; /* argument list to be used */ | 4418 alist_T *alist; /* argument list to be used */ |
4414 buf_T *buf; | 4419 buf_T *buf; |
4415 tabpage_T *tpnext; | 4420 tabpage_T *tpnext; |
4416 int had_tab = cmdmod.tab; | 4421 int had_tab = cmdmod.tab; |
4422 win_T *old_curwin, *last_curwin; | |
4423 tabpage_T *old_curtab, *last_curtab; | |
4417 win_T *new_curwin = NULL; | 4424 win_T *new_curwin = NULL; |
4418 tabpage_T *new_curtab = NULL; | 4425 tabpage_T *new_curtab = NULL; |
4419 | 4426 |
4420 if (ARGCOUNT <= 0) | 4427 if (ARGCOUNT <= 0) |
4421 { | 4428 { |
4427 | 4434 |
4428 opened_len = ARGCOUNT; | 4435 opened_len = ARGCOUNT; |
4429 opened = alloc_clear((unsigned)opened_len); | 4436 opened = alloc_clear((unsigned)opened_len); |
4430 if (opened == NULL) | 4437 if (opened == NULL) |
4431 return; | 4438 return; |
4439 | |
4440 /* Autocommands may do anything to the argument list. Make sure it's not | |
4441 * freed while we are working here by "locking" it. We still have to | |
4442 * watch out for its size to be changed. */ | |
4443 alist = curwin->w_alist; | |
4444 ++alist->al_refcount; | |
4445 | |
4446 old_curwin = curwin; | |
4447 old_curtab = curtab; | |
4432 | 4448 |
4433 #ifdef FEAT_GUI | 4449 #ifdef FEAT_GUI |
4434 need_mouse_correct = TRUE; | 4450 need_mouse_correct = TRUE; |
4435 #endif | 4451 #endif |
4436 | 4452 |
4449 for (wp = firstwin; wp != NULL; wp = wpnext) | 4465 for (wp = firstwin; wp != NULL; wp = wpnext) |
4450 { | 4466 { |
4451 wpnext = wp->w_next; | 4467 wpnext = wp->w_next; |
4452 buf = wp->w_buffer; | 4468 buf = wp->w_buffer; |
4453 if (buf->b_ffname == NULL | 4469 if (buf->b_ffname == NULL |
4454 || buf->b_nwindows > 1 | 4470 || (!keep_tabs && buf->b_nwindows > 1) |
4455 #ifdef FEAT_VERTSPLIT | 4471 #ifdef FEAT_VERTSPLIT |
4456 || wp->w_width != Columns | 4472 || wp->w_width != Columns |
4457 #endif | 4473 #endif |
4458 ) | 4474 ) |
4459 i = ARGCOUNT; | 4475 i = opened_len; |
4460 else | 4476 else |
4461 { | 4477 { |
4462 /* check if the buffer in this window is in the arglist */ | 4478 /* check if the buffer in this window is in the arglist */ |
4463 for (i = 0; i < ARGCOUNT; ++i) | 4479 for (i = 0; i < opened_len; ++i) |
4464 { | 4480 { |
4465 if (ARGLIST[i].ae_fnum == buf->b_fnum | 4481 if (i < alist->al_ga.ga_len |
4466 || fullpathcmp(alist_name(&ARGLIST[i]), | 4482 && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum |
4467 buf->b_ffname, TRUE) & FPC_SAME) | 4483 || fullpathcmp(alist_name(&AARGLIST(alist)[i]), |
4484 buf->b_ffname, TRUE) & FPC_SAME)) | |
4468 { | 4485 { |
4469 if (i < opened_len) | 4486 int weight = 1; |
4487 | |
4488 if (old_curtab == curtab) | |
4470 { | 4489 { |
4471 opened[i] = TRUE; | 4490 ++weight; |
4491 if (old_curwin == wp) | |
4492 ++weight; | |
4493 } | |
4494 | |
4495 if (weight > (int)opened[i]) | |
4496 { | |
4497 opened[i] = (char_u)weight; | |
4472 if (i == 0) | 4498 if (i == 0) |
4473 { | 4499 { |
4500 if (new_curwin != NULL) | |
4501 new_curwin->w_arg_idx = opened_len; | |
4474 new_curwin = wp; | 4502 new_curwin = wp; |
4475 new_curtab = curtab; | 4503 new_curtab = curtab; |
4476 } | 4504 } |
4477 } | 4505 } |
4478 if (wp->w_alist != curwin->w_alist) | 4506 else if (keep_tabs) |
4507 i = opened_len; | |
4508 | |
4509 if (wp->w_alist != alist) | |
4479 { | 4510 { |
4480 /* Use the current argument list for all windows | 4511 /* Use the current argument list for all windows |
4481 * containing a file from it. */ | 4512 * containing a file from it. */ |
4482 alist_unlink(wp->w_alist); | 4513 alist_unlink(wp->w_alist); |
4483 wp->w_alist = curwin->w_alist; | 4514 wp->w_alist = alist; |
4484 ++wp->w_alist->al_refcount; | 4515 ++wp->w_alist->al_refcount; |
4485 } | 4516 } |
4486 break; | 4517 break; |
4487 } | 4518 } |
4488 } | 4519 } |
4489 } | 4520 } |
4490 wp->w_arg_idx = i; | 4521 wp->w_arg_idx = i; |
4491 | 4522 |
4492 if (i == ARGCOUNT && !keep_tabs) /* close this window */ | 4523 if (i == opened_len && !keep_tabs)/* close this window */ |
4493 { | 4524 { |
4494 if (P_HID(buf) || forceit || buf->b_nwindows > 1 | 4525 if (P_HID(buf) || forceit || buf->b_nwindows > 1 |
4495 || !bufIsChanged(buf)) | 4526 || !bufIsChanged(buf)) |
4496 { | 4527 { |
4497 /* If the buffer was changed, and we would like to hide it, | 4528 /* If the buffer was changed, and we would like to hide it, |
4509 } | 4540 } |
4510 #endif | 4541 #endif |
4511 } | 4542 } |
4512 #ifdef FEAT_WINDOWS | 4543 #ifdef FEAT_WINDOWS |
4513 /* don't close last window */ | 4544 /* don't close last window */ |
4514 if (firstwin == lastwin && first_tabpage->tp_next == NULL) | 4545 if (firstwin == lastwin |
4546 && (first_tabpage->tp_next == NULL || !had_tab)) | |
4515 #endif | 4547 #endif |
4516 use_firstwin = TRUE; | 4548 use_firstwin = TRUE; |
4517 #ifdef FEAT_WINDOWS | 4549 #ifdef FEAT_WINDOWS |
4518 else | 4550 else |
4519 { | 4551 { |
4543 | 4575 |
4544 /* | 4576 /* |
4545 * Open a window for files in the argument list that don't have one. | 4577 * Open a window for files in the argument list that don't have one. |
4546 * ARGCOUNT may change while doing this, because of autocommands. | 4578 * ARGCOUNT may change while doing this, because of autocommands. |
4547 */ | 4579 */ |
4548 if (count > ARGCOUNT || count <= 0) | 4580 if (count > opened_len || count <= 0) |
4549 count = ARGCOUNT; | 4581 count = opened_len; |
4550 | |
4551 /* Autocommands may do anything to the argument list. Make sure it's not | |
4552 * freed while we are working here by "locking" it. We still have to | |
4553 * watch out for its size to be changed. */ | |
4554 alist = curwin->w_alist; | |
4555 ++alist->al_refcount; | |
4556 | 4582 |
4557 #ifdef FEAT_AUTOCMD | 4583 #ifdef FEAT_AUTOCMD |
4558 /* Don't execute Win/Buf Enter/Leave autocommands here. */ | 4584 /* Don't execute Win/Buf Enter/Leave autocommands here. */ |
4559 ++autocmd_no_enter; | 4585 ++autocmd_no_enter; |
4560 ++autocmd_no_leave; | 4586 ++autocmd_no_leave; |
4561 #endif | 4587 #endif |
4588 last_curwin = curwin; | |
4589 last_curtab = curtab; | |
4562 win_enter(lastwin, FALSE); | 4590 win_enter(lastwin, FALSE); |
4563 #ifdef FEAT_WINDOWS | 4591 #ifdef FEAT_WINDOWS |
4564 /* ":drop all" should re-use an empty window to avoid "--remote-tab" | 4592 /* ":drop all" should re-use an empty window to avoid "--remote-tab" |
4565 * leaving an empty tab page when executed locally. */ | 4593 * leaving an empty tab page when executed locally. */ |
4566 if (keep_tabs && bufempty() && curbuf->b_nwindows == 1 | 4594 if (keep_tabs && bufempty() && curbuf->b_nwindows == 1 |
4567 && curbuf->b_ffname == NULL && !curbuf->b_changed) | 4595 && curbuf->b_ffname == NULL && !curbuf->b_changed) |
4568 use_firstwin = TRUE; | 4596 use_firstwin = TRUE; |
4569 #endif | 4597 #endif |
4570 | 4598 |
4571 for (i = 0; i < count && i < alist->al_ga.ga_len && !got_int; ++i) | 4599 for (i = 0; i < count && i < opened_len && !got_int; ++i) |
4572 { | 4600 { |
4573 if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1) | 4601 if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1) |
4574 arg_had_last = TRUE; | 4602 arg_had_last = TRUE; |
4575 if (i < opened_len && opened[i]) | 4603 if (opened[i] > 0) |
4576 { | 4604 { |
4577 /* Move the already present window to below the current window */ | 4605 /* Move the already present window to below the current window */ |
4578 if (curwin->w_arg_idx != i) | 4606 if (curwin->w_arg_idx != i) |
4579 { | 4607 { |
4580 for (wpnext = firstwin; wpnext != NULL; wpnext = wpnext->w_next) | 4608 for (wpnext = firstwin; wpnext != NULL; wpnext = wpnext->w_next) |
4581 { | 4609 { |
4582 if (wpnext->w_arg_idx == i) | 4610 if (wpnext->w_arg_idx == i) |
4583 { | 4611 { |
4584 win_move_after(wpnext, curwin); | 4612 if (keep_tabs) |
4613 { | |
4614 new_curwin = wpnext; | |
4615 new_curtab = curtab; | |
4616 } | |
4617 else | |
4618 win_move_after(wpnext, curwin); | |
4585 break; | 4619 break; |
4586 } | 4620 } |
4587 } | 4621 } |
4588 } | 4622 } |
4589 } | 4623 } |
4634 alist_unlink(alist); | 4668 alist_unlink(alist); |
4635 | 4669 |
4636 #ifdef FEAT_AUTOCMD | 4670 #ifdef FEAT_AUTOCMD |
4637 --autocmd_no_enter; | 4671 --autocmd_no_enter; |
4638 #endif | 4672 #endif |
4673 /* restore last referenced tabpage's curwin */ | |
4674 if (last_curtab != new_curtab) | |
4675 { | |
4676 if (valid_tabpage(last_curtab)) | |
4677 goto_tabpage_tp(last_curtab); | |
4678 if (win_valid(last_curwin)) | |
4679 win_enter(last_curwin, FALSE); | |
4680 } | |
4639 /* to window with first arg */ | 4681 /* to window with first arg */ |
4640 if (valid_tabpage(new_curtab)) | 4682 if (valid_tabpage(new_curtab)) |
4641 goto_tabpage_tp(new_curtab); | 4683 goto_tabpage_tp(new_curtab); |
4642 if (win_valid(new_curwin)) | 4684 if (win_valid(new_curwin)) |
4643 win_enter(new_curwin, FALSE); | 4685 win_enter(new_curwin, FALSE); |