Mercurial > vim
comparison src/window.c @ 3570:e7ff3251dfa1 v7.3.545
updated for version 7.3.545
Problem: When closing a window or buffer autocommands may close it too,
causing problems for where the autocommand was invoked from.
Solution: Add the w_closing and b_closing flags. When set disallow ":q" and
":close" to prevent recursive closing.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 06 Jun 2012 19:02:45 +0200 |
parents | fa17c8646feb |
children | e83c5dcea112 |
comparison
equal
deleted
inserted
replaced
3569:6707a6a1ff9c | 3570:e7ff3251dfa1 |
---|---|
2032 | 2032 |
2033 ++RedrawingDisabled; | 2033 ++RedrawingDisabled; |
2034 | 2034 |
2035 for (wp = firstwin; wp != NULL && lastwin != firstwin; ) | 2035 for (wp = firstwin; wp != NULL && lastwin != firstwin; ) |
2036 { | 2036 { |
2037 if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)) | 2037 if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) |
2038 #ifdef FEAT_AUTOCMD | |
2039 && !(wp->w_closing || wp->w_buffer->b_closing) | |
2040 #endif | |
2041 ) | |
2038 { | 2042 { |
2039 win_close(wp, FALSE); | 2043 win_close(wp, FALSE); |
2040 | 2044 |
2041 /* Start all over, autocommands may change the window layout. */ | 2045 /* Start all over, autocommands may change the window layout. */ |
2042 wp = firstwin; | 2046 wp = firstwin; |
2049 for (tp = first_tabpage; tp != NULL; tp = nexttp) | 2053 for (tp = first_tabpage; tp != NULL; tp = nexttp) |
2050 { | 2054 { |
2051 nexttp = tp->tp_next; | 2055 nexttp = tp->tp_next; |
2052 if (tp != curtab) | 2056 if (tp != curtab) |
2053 for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next) | 2057 for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next) |
2054 if (wp->w_buffer == buf) | 2058 if (wp->w_buffer == buf |
2059 #ifdef FEAT_AUTOCMD | |
2060 && !(wp->w_closing || wp->w_buffer->b_closing) | |
2061 #endif | |
2062 ) | |
2055 { | 2063 { |
2056 win_close_othertab(wp, FALSE, tp); | 2064 win_close_othertab(wp, FALSE, tp); |
2057 | 2065 |
2058 /* Start all over, the tab page may be closed and | 2066 /* Start all over, the tab page may be closed and |
2059 * autocommands may change the window layout. */ | 2067 * autocommands may change the window layout. */ |
2166 EMSG(_("E444: Cannot close last window")); | 2174 EMSG(_("E444: Cannot close last window")); |
2167 return; | 2175 return; |
2168 } | 2176 } |
2169 | 2177 |
2170 #ifdef FEAT_AUTOCMD | 2178 #ifdef FEAT_AUTOCMD |
2179 if (win->w_closing || win->w_buffer->b_closing) | |
2180 return; /* window is already being closed */ | |
2171 if (win == aucmd_win) | 2181 if (win == aucmd_win) |
2172 { | 2182 { |
2173 EMSG(_("E813: Cannot close autocmd window")); | 2183 EMSG(_("E813: Cannot close autocmd window")); |
2174 return; | 2184 return; |
2175 } | 2185 } |
2201 * This may change because of the autocommands (sigh). | 2211 * This may change because of the autocommands (sigh). |
2202 */ | 2212 */ |
2203 wp = frame2win(win_altframe(win, NULL)); | 2213 wp = frame2win(win_altframe(win, NULL)); |
2204 | 2214 |
2205 /* | 2215 /* |
2206 * Be careful: If autocommands delete the window, return now. | 2216 * Be careful: If autocommands delete the window or cause this window |
2217 * to be the last one left, return now. | |
2207 */ | 2218 */ |
2208 if (wp->w_buffer != curbuf) | 2219 if (wp->w_buffer != curbuf) |
2209 { | 2220 { |
2210 other_buffer = TRUE; | 2221 other_buffer = TRUE; |
2222 win->w_closing = TRUE; | |
2211 apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); | 2223 apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); |
2212 if (!win_valid(win) || last_window()) | 2224 if (!win_valid(win)) |
2213 return; | 2225 return; |
2214 } | 2226 win->w_closing = FALSE; |
2227 if (last_window()) | |
2228 return; | |
2229 } | |
2230 win->w_closing = TRUE; | |
2215 apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); | 2231 apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); |
2216 if (!win_valid(win) || last_window()) | 2232 if (!win_valid(win)) |
2233 return; | |
2234 win->w_closing = FALSE; | |
2235 if (last_window()) | |
2217 return; | 2236 return; |
2218 # ifdef FEAT_EVAL | 2237 # ifdef FEAT_EVAL |
2219 /* autocmds may abort script processing */ | 2238 /* autocmds may abort script processing */ |
2220 if (aborting()) | 2239 if (aborting()) |
2221 return; | 2240 return; |
2238 | 2257 |
2239 /* | 2258 /* |
2240 * Close the link to the buffer. | 2259 * Close the link to the buffer. |
2241 */ | 2260 */ |
2242 if (win->w_buffer != NULL) | 2261 if (win->w_buffer != NULL) |
2243 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE); | 2262 { |
2263 #ifdef FEAT_AUTOCMD | |
2264 win->w_closing = TRUE; | |
2265 #endif | |
2266 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE); | |
2267 #ifdef FEAT_AUTOCMD | |
2268 if (win_valid(win)) | |
2269 win->w_closing = FALSE; | |
2270 #endif | |
2271 } | |
2244 | 2272 |
2245 /* Autocommands may have closed the window already, or closed the only | 2273 /* Autocommands may have closed the window already, or closed the only |
2246 * other window or moved to another tab page. */ | 2274 * other window or moved to another tab page. */ |
2247 if (!win_valid(win) || last_window() || curtab != prev_curtab | 2275 if (!win_valid(win) || last_window() || curtab != prev_curtab |
2248 || close_last_window_tabpage(win, free_buf, prev_curtab)) | 2276 || close_last_window_tabpage(win, free_buf, prev_curtab)) |
2343 { | 2371 { |
2344 win_T *wp; | 2372 win_T *wp; |
2345 int dir; | 2373 int dir; |
2346 tabpage_T *ptp = NULL; | 2374 tabpage_T *ptp = NULL; |
2347 int free_tp = FALSE; | 2375 int free_tp = FALSE; |
2376 | |
2377 #ifdef FEAT_AUTOCMD | |
2378 if (win->w_closing || win->w_buffer->b_closing) | |
2379 return; /* window is already being closed */ | |
2380 #endif | |
2348 | 2381 |
2349 /* Close the link to the buffer. */ | 2382 /* Close the link to the buffer. */ |
2350 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE); | 2383 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE); |
2351 | 2384 |
2352 /* Careful: Autocommands may have closed the tab page or made it the | 2385 /* Careful: Autocommands may have closed the tab page or made it the |