]> git.pld-linux.org Git - packages/vim.git/blob - 7.3.449
- up to 7.3.600
[packages/vim.git] / 7.3.449
1 To: vim_dev@googlegroups.com
2 Subject: Patch 7.3.449
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.449
11 Problem:    Crash when a BufWinLeave autocommand closes the only other window.
12             (Daniel Hunt)
13 Solution:   Abort closing a buffer when it becomes the only one.
14 Files:      src/buffer.c, src/proto/buffer.pro, src/ex_cmds.c, src/ex_getln.c,
15             src/misc2.c, src/quickfix.c, src/window.c, src/proto/window.pro
16
17
18 *** ../vim-7.3.448/src/buffer.c 2012-01-20 20:44:38.000000000 +0100
19 --- src/buffer.c        2012-02-22 14:50:42.000000000 +0100
20 ***************
21 *** 64,69 ****
22 --- 64,72 ----
23   static char *msg_loclist = N_("[Location List]");
24   static char *msg_qflist = N_("[Quickfix List]");
25   #endif
26 + #ifdef FEAT_AUTOCMD
27 + static char *e_auabort = N_("E855: Autocommands caused command to abort");
28 + #endif
29   
30   /*
31    * Open current buffer, that is: open the memfile and read the file into
32 ***************
33 *** 96,102 ****
34          * There MUST be a memfile, otherwise we can't do anything
35          * If we can't create one for the current buffer, take another buffer
36          */
37 !       close_buffer(NULL, curbuf, 0);
38         for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
39             if (curbuf->b_ml.ml_mfp != NULL)
40                 break;
41 --- 99,105 ----
42          * There MUST be a memfile, otherwise we can't do anything
43          * If we can't create one for the current buffer, take another buffer
44          */
45 !       close_buffer(NULL, curbuf, 0, FALSE);
46         for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
47             if (curbuf->b_ml.ml_mfp != NULL)
48                 break;
49 ***************
50 *** 316,327 ****
51    * get a new buffer very soon!
52    *
53    * The 'bufhidden' option can force freeing and deleting.
54    */
55       void
56 ! close_buffer(win, buf, action)
57       win_T     *win;           /* if not NULL, set b_last_cursor */
58       buf_T     *buf;
59       int               action;
60   {
61   #ifdef FEAT_AUTOCMD
62       int               is_curbuf;
63 --- 319,335 ----
64    * get a new buffer very soon!
65    *
66    * The 'bufhidden' option can force freeing and deleting.
67 +  *
68 +  * When "abort_if_last" is TRUE then do not close the buffer if autocommands
69 +  * cause there to be only one window with this buffer.  e.g. when ":quit" is
70 +  * supposed to close the window but autocommands close all other windows.
71    */
72       void
73 ! close_buffer(win, buf, action, abort_if_last)
74       win_T     *win;           /* if not NULL, set b_last_cursor */
75       buf_T     *buf;
76       int               action;
77 +     int               abort_if_last;
78   {
79   #ifdef FEAT_AUTOCMD
80       int               is_curbuf;
81 ***************
82 *** 371,378 ****
83       {
84         apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
85                                                                   FALSE, buf);
86 !       if (!buf_valid(buf))        /* autocommands may delete the buffer */
87             return;
88   
89         /* When the buffer becomes hidden, but is not unloaded, trigger
90          * BufHidden */
91 --- 379,390 ----
92       {
93         apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
94                                                                   FALSE, buf);
95 !       /* Return if autocommands deleted the buffer or made it the only one. */
96 !       if (!buf_valid(buf) || (abort_if_last && one_window()))
97 !       {
98 !           EMSG(_(e_auabort));
99             return;
100 +       }
101   
102         /* When the buffer becomes hidden, but is not unloaded, trigger
103          * BufHidden */
104 ***************
105 *** 380,387 ****
106         {
107             apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
108                                                                   FALSE, buf);
109 !           if (!buf_valid(buf))        /* autocmds may delete the buffer */
110                 return;
111         }
112   # ifdef FEAT_EVAL
113         if (aborting())     /* autocmds may abort script processing */
114 --- 392,404 ----
115         {
116             apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
117                                                                   FALSE, buf);
118 !           /* Return if autocommands deleted the buffer or made it the only
119 !            * one. */
120 !           if (!buf_valid(buf) || (abort_if_last && one_window()))
121 !           {
122 !               EMSG(_(e_auabort));
123                 return;
124 +           }
125         }
126   # ifdef FEAT_EVAL
127         if (aborting())     /* autocmds may abort script processing */
128 ***************
129 *** 775,781 ****
130          * open a new, empty buffer. */
131         swap_exists_action = SEA_NONE;  /* don't want it again */
132         swap_exists_did_quit = TRUE;
133 !       close_buffer(curwin, curbuf, DOBUF_UNLOAD);
134         if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
135             old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
136         if (old_curbuf != NULL)
137 --- 792,798 ----
138          * open a new, empty buffer. */
139         swap_exists_action = SEA_NONE;  /* don't want it again */
140         swap_exists_did_quit = TRUE;
141 !       close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE);
142         if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
143             old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
144         if (old_curbuf != NULL)
145 ***************
146 *** 1122,1128 ****
147              * if the buffer still exists.
148              */
149             if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
150 !               close_buffer(NULL, buf, action);
151             return retval;
152         }
153   
154 --- 1139,1145 ----
155              * if the buffer still exists.
156              */
157             if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
158 !               close_buffer(NULL, buf, action, FALSE);
159             return retval;
160         }
161   
162 ***************
163 *** 1146,1152 ****
164             close_windows(buf, FALSE);
165   #endif
166             if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
167 !               close_buffer(NULL, buf, action);
168             return OK;
169         }
170   
171 --- 1163,1169 ----
172             close_windows(buf, FALSE);
173   #endif
174             if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
175 !               close_buffer(NULL, buf, action, FALSE);
176             return OK;
177         }
178   
179 ***************
180 *** 1378,1384 ****
181             close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
182                     unload ? action : (action == DOBUF_GOTO
183                         && !P_HID(prevbuf)
184 !                       && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0);
185         }
186       }
187   #ifdef FEAT_AUTOCMD
188 --- 1395,1401 ----
189             close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
190                     unload ? action : (action == DOBUF_GOTO
191                         && !P_HID(prevbuf)
192 !                       && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, FALSE);
193         }
194       }
195   #ifdef FEAT_AUTOCMD
196 ***************
197 *** 2708,2714 ****
198                 vim_free(ffname);
199                 return FAIL;
200             }
201 !           close_buffer(NULL, obuf, DOBUF_WIPE); /* delete from the list */
202         }
203         sfname = vim_strsave(sfname);
204         if (ffname == NULL || sfname == NULL)
205 --- 2725,2732 ----
206                 vim_free(ffname);
207                 return FAIL;
208             }
209 !           /* delete from the list */
210 !           close_buffer(NULL, obuf, DOBUF_WIPE, FALSE);
211         }
212         sfname = vim_strsave(sfname);
213         if (ffname == NULL || sfname == NULL)
214 ***************
215 *** 5638,5644 ****
216       if (!aucmd)                   /* Don't trigger BufDelete autocommands here. */
217         block_autocmds();
218   #endif
219 !     close_buffer(NULL, buf, DOBUF_WIPE);
220   #ifdef FEAT_AUTOCMD
221       if (!aucmd)
222         unblock_autocmds();
223 --- 5656,5662 ----
224       if (!aucmd)                   /* Don't trigger BufDelete autocommands here. */
225         block_autocmds();
226   #endif
227 !     close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
228   #ifdef FEAT_AUTOCMD
229       if (!aucmd)
230         unblock_autocmds();
231 *** ../vim-7.3.448/src/proto/buffer.pro 2010-08-15 21:57:28.000000000 +0200
232 --- src/proto/buffer.pro        2012-02-22 14:04:26.000000000 +0100
233 ***************
234 *** 1,7 ****
235   /* buffer.c */
236   int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
237   int buf_valid __ARGS((buf_T *buf));
238 ! void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
239   void buf_clear_file __ARGS((buf_T *buf));
240   void buf_freeall __ARGS((buf_T *buf, int flags));
241   void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
242 --- 1,7 ----
243   /* buffer.c */
244   int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
245   int buf_valid __ARGS((buf_T *buf));
246 ! void close_buffer __ARGS((win_T *win, buf_T *buf, int action, int abort_if_last));
247   void buf_clear_file __ARGS((buf_T *buf));
248   void buf_freeall __ARGS((buf_T *buf, int flags));
249   void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
250 *** ../vim-7.3.448/src/ex_cmds.c        2011-12-30 15:01:55.000000000 +0100
251 --- src/ex_cmds.c       2012-02-22 14:00:32.000000000 +0100
252 ***************
253 *** 3387,3393 ****
254                 /* close the link to the current buffer */
255                 u_sync(FALSE);
256                 close_buffer(oldwin, curbuf,
257 !                                     (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD);
258   
259   #ifdef FEAT_AUTOCMD
260                 /* Autocommands may open a new window and leave oldwin open
261 --- 3387,3393 ----
262                 /* close the link to the current buffer */
263                 u_sync(FALSE);
264                 close_buffer(oldwin, curbuf,
265 !                              (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD, FALSE);
266   
267   #ifdef FEAT_AUTOCMD
268                 /* Autocommands may open a new window and leave oldwin open
269 *** ../vim-7.3.448/src/ex_getln.c       2012-02-04 22:44:27.000000000 +0100
270 --- src/ex_getln.c      2012-02-22 14:01:56.000000000 +0100
271 ***************
272 *** 6443,6449 ****
273         /* win_close() may have already wiped the buffer when 'bh' is
274          * set to 'wipe' */
275         if (buf_valid(bp))
276 !           close_buffer(NULL, bp, DOBUF_WIPE);
277   
278         /* Restore window sizes. */
279         win_size_restore(&winsizes);
280 --- 6443,6449 ----
281         /* win_close() may have already wiped the buffer when 'bh' is
282          * set to 'wipe' */
283         if (buf_valid(bp))
284 !           close_buffer(NULL, bp, DOBUF_WIPE, FALSE);
285   
286         /* Restore window sizes. */
287         win_size_restore(&winsizes);
288 *** ../vim-7.3.448/src/misc2.c  2012-02-20 22:18:22.000000000 +0100
289 --- src/misc2.c 2012-02-22 14:02:12.000000000 +0100
290 ***************
291 *** 1173,1179 ****
292       for (buf = firstbuf; buf != NULL; )
293       {
294         nextbuf = buf->b_next;
295 !       close_buffer(NULL, buf, DOBUF_WIPE);
296         if (buf_valid(buf))
297             buf = nextbuf;      /* didn't work, try next one */
298         else
299 --- 1173,1179 ----
300       for (buf = firstbuf; buf != NULL; )
301       {
302         nextbuf = buf->b_next;
303 !       close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
304         if (buf_valid(buf))
305             buf = nextbuf;      /* didn't work, try next one */
306         else
307 *** ../vim-7.3.448/src/quickfix.c       2012-01-20 13:39:03.000000000 +0100
308 --- src/quickfix.c      2012-02-22 14:02:20.000000000 +0100
309 ***************
310 *** 3565,3571 ****
311       buf_T     *buf;
312   {
313       if (curbuf != buf)                /* safety check */
314 !       close_buffer(NULL, buf, DOBUF_UNLOAD);
315   }
316   
317   #if defined(FEAT_EVAL) || defined(PROTO)
318 --- 3565,3571 ----
319       buf_T     *buf;
320   {
321       if (curbuf != buf)                /* safety check */
322 !       close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE);
323   }
324   
325   #if defined(FEAT_EVAL) || defined(PROTO)
326 *** ../vim-7.3.448/src/window.c 2012-01-10 22:26:12.000000000 +0100
327 --- src/window.c        2012-02-22 14:08:13.000000000 +0100
328 ***************
329 *** 23,29 ****
330   static void win_totop __ARGS((int size, int flags));
331   static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height));
332   static int last_window __ARGS((void));
333 - static int one_window __ARGS((void));
334   static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));
335   static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));
336   static tabpage_T *alt_tabpage __ARGS((void));
337 --- 23,28 ----
338 ***************
339 *** 2083,2089 ****
340    * Return TRUE if there is only one window other than "aucmd_win" in the
341    * current tab page.
342    */
343 !     static int
344   one_window()
345   {
346   #ifdef FEAT_AUTOCMD
347 --- 2082,2088 ----
348    * Return TRUE if there is only one window other than "aucmd_win" in the
349    * current tab page.
350    */
351 !     int
352   one_window()
353   {
354   #ifdef FEAT_AUTOCMD
355 ***************
356 *** 2109,2115 ****
357    * Close window "win".  Only works for the current tab page.
358    * If "free_buf" is TRUE related buffer may be unloaded.
359    *
360 !  * called by :quit, :close, :xit, :wq and findtag()
361    */
362       void
363   win_close(win, free_buf)
364 --- 2108,2114 ----
365    * Close window "win".  Only works for the current tab page.
366    * If "free_buf" is TRUE related buffer may be unloaded.
367    *
368 !  * Called by :quit, :close, :xit, :wq and findtag().
369    */
370       void
371   win_close(win, free_buf)
372 ***************
373 *** 2222,2228 ****
374        * Close the link to the buffer.
375        */
376       if (win->w_buffer != NULL)
377 !       close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
378   
379       /* Autocommands may have closed the window already, or closed the only
380        * other window or moved to another tab page. */
381 --- 2221,2227 ----
382        * Close the link to the buffer.
383        */
384       if (win->w_buffer != NULL)
385 !       close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE);
386   
387       /* Autocommands may have closed the window already, or closed the only
388        * other window or moved to another tab page. */
389 ***************
390 *** 2328,2334 ****
391       int               free_tp = FALSE;
392   
393       /* Close the link to the buffer. */
394 !     close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
395   
396       /* Careful: Autocommands may have closed the tab page or made it the
397        * current tab page.  */
398 --- 2327,2333 ----
399       int               free_tp = FALSE;
400   
401       /* Close the link to the buffer. */
402 !     close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
403   
404       /* Careful: Autocommands may have closed the tab page or made it the
405        * current tab page.  */
406 *** ../vim-7.3.448/src/proto/window.pro 2010-08-15 21:57:28.000000000 +0200
407 --- src/proto/window.pro        2012-02-22 14:08:28.000000000 +0100
408 ***************
409 *** 1,13 ****
410   /* window.c */
411   void do_window __ARGS((int nchar, long Prenum, int xchar));
412   int win_split __ARGS((int size, int flags));
413 ! int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir));
414   int win_valid __ARGS((win_T *win));
415   int win_count __ARGS((void));
416   int make_windows __ARGS((int count, int vertical));
417   void win_move_after __ARGS((win_T *win1, win_T *win2));
418   void win_equal __ARGS((win_T *next_curwin, int current, int dir));
419   void close_windows __ARGS((buf_T *buf, int keep_curwin));
420   void win_close __ARGS((win_T *win, int free_buf));
421   void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
422   void win_free_all __ARGS((void));
423 --- 1,14 ----
424   /* window.c */
425   void do_window __ARGS((int nchar, long Prenum, int xchar));
426   int win_split __ARGS((int size, int flags));
427 ! int win_split_ins __ARGS((int size, int flags, win_T *new_wp, int dir));
428   int win_valid __ARGS((win_T *win));
429   int win_count __ARGS((void));
430   int make_windows __ARGS((int count, int vertical));
431   void win_move_after __ARGS((win_T *win1, win_T *win2));
432   void win_equal __ARGS((win_T *next_curwin, int current, int dir));
433   void close_windows __ARGS((buf_T *buf, int keep_curwin));
434 + int one_window __ARGS((void));
435   void win_close __ARGS((win_T *win, int free_buf));
436   void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
437   void win_free_all __ARGS((void));
438 *** ../vim-7.3.448/src/version.c        2012-02-22 13:07:02.000000000 +0100
439 --- src/version.c       2012-02-22 14:55:21.000000000 +0100
440 ***************
441 *** 716,717 ****
442 --- 716,719 ----
443   {   /* Add new patch number below this line */
444 + /**/
445 +     449,
446   /**/
447
448 -- 
449 From "know your smileys":
450  :-)-O  Smiling doctor with stethoscope
451
452  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
453 ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
454 \\\  an exciting new programming language -- http://www.Zimbu.org        ///
455  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
This page took 0.057368 seconds and 3 git commands to generate.