Mercurial > vim
comparison src/window.c @ 4354:c80838526eeb v7.3.926
updated for version 7.3.926
Problem: Autocommands are triggered by setwinvar() et al. Missing BufEnter
on :tabclose. Duplicate WinEnter on :tabclose. Wrong order of
events for :tablose and :tabnew.
Solution: Fix these autocommand events. (Zyx)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Mon, 06 May 2013 04:50:35 +0200 |
parents | 04736b4030ec |
children | a2f03b41dca7 |
comparison
equal
deleted
inserted
replaced
4353:1ab21898454f | 4354:c80838526eeb |
---|---|
42 #endif | 42 #endif |
43 static int win_alloc_firstwin __ARGS((win_T *oldwin)); | 43 static int win_alloc_firstwin __ARGS((win_T *oldwin)); |
44 static void new_frame __ARGS((win_T *wp)); | 44 static void new_frame __ARGS((win_T *wp)); |
45 #if defined(FEAT_WINDOWS) || defined(PROTO) | 45 #if defined(FEAT_WINDOWS) || defined(PROTO) |
46 static tabpage_T *alloc_tabpage __ARGS((void)); | 46 static tabpage_T *alloc_tabpage __ARGS((void)); |
47 static int leave_tabpage __ARGS((buf_T *new_curbuf)); | 47 static int leave_tabpage __ARGS((buf_T *new_curbuf, int trigger_leave_autocmds)); |
48 static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf, int trigger_autocmds)); | 48 static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_autocmds, int trigger_leave_autocmds)); |
49 static void frame_fix_height __ARGS((win_T *wp)); | 49 static void frame_fix_height __ARGS((win_T *wp)); |
50 static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin)); | 50 static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin)); |
51 static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin)); | 51 static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin, int trigger_enter_autocmds, int trigger_leave_autocmds)); |
52 static void win_free __ARGS((win_T *wp, tabpage_T *tp)); | 52 static void win_free __ARGS((win_T *wp, tabpage_T *tp)); |
53 static void frame_append __ARGS((frame_T *after, frame_T *frp)); | 53 static void frame_append __ARGS((frame_T *after, frame_T *frp)); |
54 static void frame_insert __ARGS((frame_T *before, frame_T *frp)); | 54 static void frame_insert __ARGS((frame_T *before, frame_T *frp)); |
55 static void frame_remove __ARGS((frame_T *frp)); | 55 static void frame_remove __ARGS((frame_T *frp)); |
56 #ifdef FEAT_VERTSPLIT | 56 #ifdef FEAT_VERTSPLIT |
351 wp = curwin; | 351 wp = curwin; |
352 if (win_new_tabpage((int)Prenum) == OK | 352 if (win_new_tabpage((int)Prenum) == OK |
353 && valid_tabpage(oldtab)) | 353 && valid_tabpage(oldtab)) |
354 { | 354 { |
355 newtab = curtab; | 355 newtab = curtab; |
356 goto_tabpage_tp(oldtab, TRUE); | 356 goto_tabpage_tp(oldtab, TRUE, TRUE); |
357 if (curwin == wp) | 357 if (curwin == wp) |
358 win_close(curwin, FALSE); | 358 win_close(curwin, FALSE); |
359 if (valid_tabpage(newtab)) | 359 if (valid_tabpage(newtab)) |
360 goto_tabpage_tp(newtab, TRUE); | 360 goto_tabpage_tp(newtab, TRUE, TRUE); |
361 } | 361 } |
362 } | 362 } |
363 break; | 363 break; |
364 | 364 |
365 /* cursor to top-left window */ | 365 /* cursor to top-left window */ |
2122 int free_buf; | 2122 int free_buf; |
2123 tabpage_T *prev_curtab; | 2123 tabpage_T *prev_curtab; |
2124 { | 2124 { |
2125 if (firstwin == lastwin) | 2125 if (firstwin == lastwin) |
2126 { | 2126 { |
2127 buf_T *old_curbuf = curbuf; | |
2128 | |
2127 /* | 2129 /* |
2128 * Closing the last window in a tab page. First go to another tab | 2130 * Closing the last window in a tab page. First go to another tab |
2129 * page and then close the window and the tab page. This avoids that | 2131 * page and then close the window and the tab page. This avoids that |
2130 * curwin and curtab are invalid while we are freeing memory, they may | 2132 * curwin and curtab are invalid while we are freeing memory, they may |
2131 * be used in GUI events. | 2133 * be used in GUI events. |
2132 * Don't trigger autocommands yet, they may use wrong values, so do | 2134 * Don't trigger autocommands yet, they may use wrong values, so do |
2133 * that below. | 2135 * that below. |
2134 */ | 2136 */ |
2135 goto_tabpage_tp(alt_tabpage(), FALSE); | 2137 goto_tabpage_tp(alt_tabpage(), FALSE, TRUE); |
2136 redraw_tabline = TRUE; | 2138 redraw_tabline = TRUE; |
2137 | 2139 |
2138 /* Safety check: Autocommands may have closed the window when jumping | 2140 /* Safety check: Autocommands may have closed the window when jumping |
2139 * to the other tab page. */ | 2141 * to the other tab page. */ |
2140 if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) | 2142 if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) |
2146 shell_new_rows(); | 2148 shell_new_rows(); |
2147 } | 2149 } |
2148 /* Since goto_tabpage_tp above did not trigger *Enter autocommands, do | 2150 /* Since goto_tabpage_tp above did not trigger *Enter autocommands, do |
2149 * that now. */ | 2151 * that now. */ |
2150 #ifdef FEAT_AUTOCMD | 2152 #ifdef FEAT_AUTOCMD |
2153 apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf); | |
2151 apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf); | 2154 apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf); |
2152 apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf); | 2155 if (old_curbuf != curbuf) |
2156 apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); | |
2153 #endif | 2157 #endif |
2154 return TRUE; | 2158 return TRUE; |
2155 } | 2159 } |
2156 return FALSE; | 2160 return FALSE; |
2157 } | 2161 } |
2339 ); | 2343 ); |
2340 else | 2344 else |
2341 win_comp_pos(); | 2345 win_comp_pos(); |
2342 if (close_curwin) | 2346 if (close_curwin) |
2343 { | 2347 { |
2344 win_enter_ext(wp, FALSE, TRUE); | 2348 win_enter_ext(wp, FALSE, TRUE, TRUE, TRUE); |
2345 #ifdef FEAT_AUTOCMD | 2349 #ifdef FEAT_AUTOCMD |
2346 if (other_buffer) | 2350 if (other_buffer) |
2347 /* careful: after this wp and win may be invalid! */ | 2351 /* careful: after this wp and win may be invalid! */ |
2348 apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); | 2352 apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); |
2349 #endif | 2353 #endif |
3527 newtp = alloc_tabpage(); | 3531 newtp = alloc_tabpage(); |
3528 if (newtp == NULL) | 3532 if (newtp == NULL) |
3529 return FAIL; | 3533 return FAIL; |
3530 | 3534 |
3531 /* Remember the current windows in this Tab page. */ | 3535 /* Remember the current windows in this Tab page. */ |
3532 if (leave_tabpage(curbuf) == FAIL) | 3536 if (leave_tabpage(curbuf, TRUE) == FAIL) |
3533 { | 3537 { |
3534 vim_free(newtp); | 3538 vim_free(newtp); |
3535 return FAIL; | 3539 return FAIL; |
3536 } | 3540 } |
3537 curtab = newtp; | 3541 curtab = newtp; |
3572 gui_may_update_scrollbars(); | 3576 gui_may_update_scrollbars(); |
3573 #endif | 3577 #endif |
3574 | 3578 |
3575 redraw_all_later(CLEAR); | 3579 redraw_all_later(CLEAR); |
3576 #ifdef FEAT_AUTOCMD | 3580 #ifdef FEAT_AUTOCMD |
3581 apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf); | |
3577 apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf); | 3582 apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf); |
3578 apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf); | |
3579 #endif | 3583 #endif |
3580 return OK; | 3584 return OK; |
3581 } | 3585 } |
3582 | 3586 |
3583 /* Failed, get back the previous Tab page */ | 3587 /* Failed, get back the previous Tab page */ |
3584 enter_tabpage(curtab, curbuf, TRUE); | 3588 enter_tabpage(curtab, curbuf, TRUE, TRUE); |
3585 return FAIL; | 3589 return FAIL; |
3586 } | 3590 } |
3587 | 3591 |
3588 /* | 3592 /* |
3589 * Open a new tab page if ":tab cmd" was used. It will edit the same buffer, | 3593 * Open a new tab page if ":tab cmd" was used. It will edit the same buffer, |
3690 * When autocommands change "curtab" we don't leave the tab page and return | 3694 * When autocommands change "curtab" we don't leave the tab page and return |
3691 * FAIL. | 3695 * FAIL. |
3692 * Careful: When OK is returned need to get a new tab page very very soon! | 3696 * Careful: When OK is returned need to get a new tab page very very soon! |
3693 */ | 3697 */ |
3694 static int | 3698 static int |
3695 leave_tabpage(new_curbuf) | 3699 leave_tabpage(new_curbuf, trigger_leave_autocmds) |
3696 buf_T *new_curbuf UNUSED; /* what is going to be the new curbuf, | 3700 buf_T *new_curbuf UNUSED; /* what is going to be the new curbuf, |
3697 NULL if unknown */ | 3701 NULL if unknown */ |
3702 int trigger_leave_autocmds UNUSED; | |
3698 { | 3703 { |
3699 tabpage_T *tp = curtab; | 3704 tabpage_T *tp = curtab; |
3700 | 3705 |
3701 #ifdef FEAT_VISUAL | 3706 #ifdef FEAT_VISUAL |
3702 reset_VIsual_and_resel(); /* stop Visual mode */ | 3707 reset_VIsual_and_resel(); /* stop Visual mode */ |
3703 #endif | 3708 #endif |
3704 #ifdef FEAT_AUTOCMD | 3709 #ifdef FEAT_AUTOCMD |
3705 if (new_curbuf != curbuf) | 3710 if (trigger_leave_autocmds) |
3706 { | 3711 { |
3707 apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); | 3712 if (new_curbuf != curbuf) |
3713 { | |
3714 apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); | |
3715 if (curtab != tp) | |
3716 return FAIL; | |
3717 } | |
3718 apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); | |
3708 if (curtab != tp) | 3719 if (curtab != tp) |
3709 return FAIL; | 3720 return FAIL; |
3710 } | 3721 apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf); |
3711 apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); | 3722 if (curtab != tp) |
3712 if (curtab != tp) | 3723 return FAIL; |
3713 return FAIL; | 3724 } |
3714 apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf); | |
3715 if (curtab != tp) | |
3716 return FAIL; | |
3717 #endif | 3725 #endif |
3718 #if defined(FEAT_GUI) | 3726 #if defined(FEAT_GUI) |
3719 /* Remove the scrollbars. They may be added back later. */ | 3727 /* Remove the scrollbars. They may be added back later. */ |
3720 if (gui.in_use) | 3728 if (gui.in_use) |
3721 gui_remove_scrollbars(); | 3729 gui_remove_scrollbars(); |
3732 } | 3740 } |
3733 | 3741 |
3734 /* | 3742 /* |
3735 * Start using tab page "tp". | 3743 * Start using tab page "tp". |
3736 * Only to be used after leave_tabpage() or freeing the current tab page. | 3744 * Only to be used after leave_tabpage() or freeing the current tab page. |
3737 * Only trigger *Enter autocommands when trigger_autocmds is TRUE. | 3745 * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE. |
3746 * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE. | |
3738 */ | 3747 */ |
3739 static void | 3748 static void |
3740 enter_tabpage(tp, old_curbuf, trigger_autocmds) | 3749 enter_tabpage(tp, old_curbuf, trigger_enter_autocmds, trigger_leave_autocmds) |
3741 tabpage_T *tp; | 3750 tabpage_T *tp; |
3742 buf_T *old_curbuf UNUSED; | 3751 buf_T *old_curbuf UNUSED; |
3743 int trigger_autocmds UNUSED; | 3752 int trigger_enter_autocmds UNUSED; |
3753 int trigger_leave_autocmds UNUSED; | |
3744 { | 3754 { |
3745 int old_off = tp->tp_firstwin->w_winrow; | 3755 int old_off = tp->tp_firstwin->w_winrow; |
3746 win_T *next_prevwin = tp->tp_prevwin; | 3756 win_T *next_prevwin = tp->tp_prevwin; |
3747 | 3757 |
3748 curtab = tp; | 3758 curtab = tp; |
3751 topframe = tp->tp_topframe; | 3761 topframe = tp->tp_topframe; |
3752 | 3762 |
3753 /* We would like doing the TabEnter event first, but we don't have a | 3763 /* We would like doing the TabEnter event first, but we don't have a |
3754 * valid current window yet, which may break some commands. | 3764 * valid current window yet, which may break some commands. |
3755 * This triggers autocommands, thus may make "tp" invalid. */ | 3765 * This triggers autocommands, thus may make "tp" invalid. */ |
3756 win_enter_ext(tp->tp_curwin, FALSE, TRUE); | 3766 win_enter_ext(tp->tp_curwin, FALSE, TRUE, trigger_enter_autocmds, trigger_leave_autocmds); |
3757 prevwin = next_prevwin; | 3767 prevwin = next_prevwin; |
3758 | 3768 |
3759 last_status(FALSE); /* status line may appear or disappear */ | 3769 last_status(FALSE); /* status line may appear or disappear */ |
3760 (void)win_comp_pos(); /* recompute w_winrow for all windows */ | 3770 (void)win_comp_pos(); /* recompute w_winrow for all windows */ |
3761 must_redraw = CLEAR; /* need to redraw everything */ | 3771 must_redraw = CLEAR; /* need to redraw everything */ |
3786 #endif | 3796 #endif |
3787 | 3797 |
3788 #ifdef FEAT_AUTOCMD | 3798 #ifdef FEAT_AUTOCMD |
3789 /* Apply autocommands after updating the display, when 'rows' and | 3799 /* Apply autocommands after updating the display, when 'rows' and |
3790 * 'columns' have been set correctly. */ | 3800 * 'columns' have been set correctly. */ |
3791 if (trigger_autocmds) | 3801 if (trigger_enter_autocmds) |
3792 { | 3802 { |
3793 apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf); | 3803 apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf); |
3794 if (old_curbuf != curbuf) | 3804 if (old_curbuf != curbuf) |
3795 apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); | 3805 apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); |
3796 } | 3806 } |
3867 beep_flush(); | 3877 beep_flush(); |
3868 return; | 3878 return; |
3869 } | 3879 } |
3870 } | 3880 } |
3871 | 3881 |
3872 goto_tabpage_tp(tp, TRUE); | 3882 goto_tabpage_tp(tp, TRUE, TRUE); |
3873 | 3883 |
3874 #ifdef FEAT_GUI_TABLINE | 3884 #ifdef FEAT_GUI_TABLINE |
3875 if (gui_use_tabline()) | 3885 if (gui_use_tabline()) |
3876 gui_mch_set_curtab(tabpage_index(curtab)); | 3886 gui_mch_set_curtab(tabpage_index(curtab)); |
3877 #endif | 3887 #endif |
3878 } | 3888 } |
3879 | 3889 |
3880 /* | 3890 /* |
3881 * Go to tabpage "tp". | 3891 * Go to tabpage "tp". |
3882 * Only trigger *Enter autocommands when trigger_autocmds is TRUE. | 3892 * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE. |
3893 * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE. | |
3883 * Note: doesn't update the GUI tab. | 3894 * Note: doesn't update the GUI tab. |
3884 */ | 3895 */ |
3885 void | 3896 void |
3886 goto_tabpage_tp(tp, trigger_autocmds) | 3897 goto_tabpage_tp(tp, trigger_enter_autocmds, trigger_leave_autocmds) |
3887 tabpage_T *tp; | 3898 tabpage_T *tp; |
3888 int trigger_autocmds; | 3899 int trigger_enter_autocmds; |
3900 int trigger_leave_autocmds; | |
3889 { | 3901 { |
3890 /* Don't repeat a message in another tab page. */ | 3902 /* Don't repeat a message in another tab page. */ |
3891 set_keep_msg(NULL, 0); | 3903 set_keep_msg(NULL, 0); |
3892 | 3904 |
3893 if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer) == OK) | 3905 if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer, |
3906 trigger_leave_autocmds) == OK) | |
3894 { | 3907 { |
3895 if (valid_tabpage(tp)) | 3908 if (valid_tabpage(tp)) |
3896 enter_tabpage(tp, curbuf, trigger_autocmds); | 3909 enter_tabpage(tp, curbuf, trigger_enter_autocmds, |
3910 trigger_leave_autocmds); | |
3897 else | 3911 else |
3898 enter_tabpage(curtab, curbuf, trigger_autocmds); | 3912 enter_tabpage(curtab, curbuf, trigger_enter_autocmds, |
3913 trigger_leave_autocmds); | |
3899 } | 3914 } |
3900 } | 3915 } |
3901 | 3916 |
3902 /* | 3917 /* |
3903 * Enter window "wp" in tab page "tp". | 3918 * Enter window "wp" in tab page "tp". |
3906 void | 3921 void |
3907 goto_tabpage_win(tp, wp) | 3922 goto_tabpage_win(tp, wp) |
3908 tabpage_T *tp; | 3923 tabpage_T *tp; |
3909 win_T *wp; | 3924 win_T *wp; |
3910 { | 3925 { |
3911 goto_tabpage_tp(tp, TRUE); | 3926 goto_tabpage_tp(tp, TRUE, TRUE); |
3912 if (curtab == tp && win_valid(wp)) | 3927 if (curtab == tp && win_valid(wp)) |
3913 { | 3928 { |
3914 win_enter(wp, TRUE); | 3929 win_enter(wp, TRUE); |
3915 # ifdef FEAT_GUI_TABLINE | 3930 # ifdef FEAT_GUI_TABLINE |
3916 if (gui_use_tabline()) | 3931 if (gui_use_tabline()) |
4166 void | 4181 void |
4167 win_enter(wp, undo_sync) | 4182 win_enter(wp, undo_sync) |
4168 win_T *wp; | 4183 win_T *wp; |
4169 int undo_sync; | 4184 int undo_sync; |
4170 { | 4185 { |
4171 win_enter_ext(wp, undo_sync, FALSE); | 4186 win_enter_ext(wp, undo_sync, FALSE, TRUE, TRUE); |
4172 } | 4187 } |
4173 | 4188 |
4174 /* | 4189 /* |
4175 * Make window wp the current window. | 4190 * Make window wp the current window. |
4176 * Can be called with "curwin_invalid" TRUE, which means that curwin has just | 4191 * Can be called with "curwin_invalid" TRUE, which means that curwin has just |
4177 * been closed and isn't valid. | 4192 * been closed and isn't valid. |
4178 */ | 4193 */ |
4179 static void | 4194 static void |
4180 win_enter_ext(wp, undo_sync, curwin_invalid) | 4195 win_enter_ext(wp, undo_sync, curwin_invalid, trigger_enter_autocmds, trigger_leave_autocmds) |
4181 win_T *wp; | 4196 win_T *wp; |
4182 int undo_sync; | 4197 int undo_sync; |
4183 int curwin_invalid; | 4198 int curwin_invalid; |
4199 int trigger_enter_autocmds UNUSED; | |
4200 int trigger_leave_autocmds UNUSED; | |
4184 { | 4201 { |
4185 #ifdef FEAT_AUTOCMD | 4202 #ifdef FEAT_AUTOCMD |
4186 int other_buffer = FALSE; | 4203 int other_buffer = FALSE; |
4187 #endif | 4204 #endif |
4188 | 4205 |
4189 if (wp == curwin && !curwin_invalid) /* nothing to do */ | 4206 if (wp == curwin && !curwin_invalid) /* nothing to do */ |
4190 return; | 4207 return; |
4191 | 4208 |
4192 #ifdef FEAT_AUTOCMD | 4209 #ifdef FEAT_AUTOCMD |
4193 if (!curwin_invalid) | 4210 if (!curwin_invalid && trigger_leave_autocmds) |
4194 { | 4211 { |
4195 /* | 4212 /* |
4196 * Be careful: If autocommands delete the window, return now. | 4213 * Be careful: If autocommands delete the window, return now. |
4197 */ | 4214 */ |
4198 if (wp->w_buffer != curbuf) | 4215 if (wp->w_buffer != curbuf) |
4257 globaldir = NULL; | 4274 globaldir = NULL; |
4258 shorten_fnames(TRUE); | 4275 shorten_fnames(TRUE); |
4259 } | 4276 } |
4260 | 4277 |
4261 #ifdef FEAT_AUTOCMD | 4278 #ifdef FEAT_AUTOCMD |
4262 apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf); | 4279 if (trigger_enter_autocmds) |
4263 if (other_buffer) | 4280 { |
4264 apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); | 4281 apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf); |
4282 if (other_buffer) | |
4283 apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); | |
4284 } | |
4265 #endif | 4285 #endif |
4266 | 4286 |
4267 #ifdef FEAT_TITLE | 4287 #ifdef FEAT_TITLE |
4268 maketitle(); | 4288 maketitle(); |
4269 #endif | 4289 #endif |