summaryrefslogtreecommitdiffstats
path: root/patches/source/vim/patches/7.4.140
blob: e493828e7b8ea90c0df3b2db4f02fb52bb08311e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
To: vim_dev@googlegroups.com
Subject: Patch 7.4.140
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.4.140
Problem:    Crash when wiping out buffer triggers autocommand that wipes out
	    only other buffer.
Solution:   Do not delete the last buffer, make it empty. (Hirohito Higashi)
Files:	    src/buffer.c


*** ../vim-7.4.139/src/buffer.c	2013-11-06 05:26:08.000000000 +0100
--- src/buffer.c	2014-01-10 16:41:22.000000000 +0100
***************
*** 994,999 ****
--- 994,1043 ----
  #if defined(FEAT_LISTCMDS) || defined(FEAT_PYTHON) \
  	|| defined(FEAT_PYTHON3) || defined(PROTO)
  
+ static int	empty_curbuf __ARGS((int close_others, int forceit, int action));
+ 
+ /*
+  * Make the current buffer empty.
+  * Used when it is wiped out and it's the last buffer.
+  */
+     static int
+ empty_curbuf(close_others, forceit, action)
+     int close_others;
+     int forceit;
+     int action;
+ {
+     int	    retval;
+     buf_T   *buf = curbuf;
+ 
+     if (action == DOBUF_UNLOAD)
+     {
+ 	EMSG(_("E90: Cannot unload last buffer"));
+ 	return FAIL;
+     }
+ 
+     if (close_others)
+     {
+ 	/* Close any other windows on this buffer, then make it empty. */
+ #ifdef FEAT_WINDOWS
+ 	close_windows(buf, TRUE);
+ #endif
+     }
+ 
+     setpcmark();
+     retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
+ 					  forceit ? ECMD_FORCEIT : 0, curwin);
+ 
+     /*
+      * do_ecmd() may create a new buffer, then we have to delete
+      * the old one.  But do_ecmd() may have done that already, check
+      * if the buffer still exists.
+      */
+     if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
+ 	close_buffer(NULL, buf, action, FALSE);
+     if (!close_others)
+ 	need_fileinfo = FALSE;
+     return retval;
+ }
  /*
   * Implementation of the commands for the buffer list.
   *
***************
*** 1114,1120 ****
      if (unload)
      {
  	int	forward;
- 	int	retval;
  
  	/* When unloading or deleting a buffer that's already unloaded and
  	 * unlisted: fail silently. */
--- 1158,1163 ----
***************
*** 1155,1184 ****
  	    if (bp->b_p_bl && bp != buf)
  		break;
  	if (bp == NULL && buf == curbuf)
! 	{
! 	    if (action == DOBUF_UNLOAD)
! 	    {
! 		EMSG(_("E90: Cannot unload last buffer"));
! 		return FAIL;
! 	    }
! 
! 	    /* Close any other windows on this buffer, then make it empty. */
! #ifdef FEAT_WINDOWS
! 	    close_windows(buf, TRUE);
! #endif
! 	    setpcmark();
! 	    retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
! 					  forceit ? ECMD_FORCEIT : 0, curwin);
! 
! 	    /*
! 	     * do_ecmd() may create a new buffer, then we have to delete
! 	     * the old one.  But do_ecmd() may have done that already, check
! 	     * if the buffer still exists.
! 	     */
! 	    if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
! 		close_buffer(NULL, buf, action, FALSE);
! 	    return retval;
! 	}
  
  #ifdef FEAT_WINDOWS
  	/*
--- 1198,1204 ----
  	    if (bp->b_p_bl && bp != buf)
  		break;
  	if (bp == NULL && buf == curbuf)
! 	    return empty_curbuf(TRUE, forceit, action);
  
  #ifdef FEAT_WINDOWS
  	/*
***************
*** 1212,1218 ****
  
  	/*
  	 * Deleting the current buffer: Need to find another buffer to go to.
! 	 * There must be another, otherwise it would have been handled above.
  	 * First use au_new_curbuf, if it is valid.
  	 * Then prefer the buffer we most recently visited.
  	 * Else try to find one that is loaded, after the current buffer,
--- 1232,1239 ----
  
  	/*
  	 * Deleting the current buffer: Need to find another buffer to go to.
! 	 * There should be another, otherwise it would have been handled
! 	 * above.  However, autocommands may have deleted all buffers.
  	 * First use au_new_curbuf, if it is valid.
  	 * Then prefer the buffer we most recently visited.
  	 * Else try to find one that is loaded, after the current buffer,
***************
*** 1311,1316 ****
--- 1332,1344 ----
  	}
      }
  
+     if (buf == NULL)
+     {
+ 	/* Autocommands must have wiped out all other buffers.  Only option
+ 	 * now is to make the current buffer empty. */
+ 	return empty_curbuf(FALSE, forceit, action);
+     }
+ 
      /*
       * make buf current buffer
       */
*** ../vim-7.4.139/src/version.c	2014-01-10 15:53:09.000000000 +0100
--- src/version.c	2014-01-10 16:36:03.000000000 +0100
***************
*** 740,741 ****
--- 740,743 ----
  {   /* Add new patch number below this line */
+ /**/
+     140,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
133. You communicate with people on other continents more than you
     do with your own neighbors.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///