1 To: [email protected] |
|
2 Subject: Patch 7.2.137 |
|
3 Fcc: outbox |
|
4 From: Bram Moolenaar <[email protected]> |
|
5 Mime-Version: 1.0 |
|
6 Content-Type: text/plain; charset=ISO-8859-1 |
|
7 Content-Transfer-Encoding: 8bit |
|
8 ------------ |
|
9 |
|
10 Note: The special characters in the patch may cause problems. |
|
11 |
|
12 Patch 7.2.137 |
|
13 Problem: When 'virtualedit' is set, a left shift of a blockwise selection |
|
14 that starts and ends inside a tab shifts too much. (Helmut |
|
15 Stiegler) |
|
16 Solution: Redo the block left shift code. (Lech Lorens) |
|
17 Files: src/ops.c, src/testdir/Makefile, src/testdir/test66.in, |
|
18 src/testdir/test66.ok |
|
19 |
|
20 |
|
21 *** ../vim-7.2.136/src/ops.c Wed Dec 3 13:38:00 2008 |
|
22 --- src/ops.c Thu Mar 5 04:47:09 2009 |
|
23 *************** |
|
24 *** 72,82 **** |
|
25 */ |
|
26 struct block_def |
|
27 { |
|
28 ! int startspaces; /* 'extra' cols of first char */ |
|
29 ! int endspaces; /* 'extra' cols of first char */ |
|
30 int textlen; /* chars in block */ |
|
31 ! char_u *textstart; /* pointer to 1st char in block */ |
|
32 ! colnr_T textcol; /* cols of chars (at least part.) in block */ |
|
33 colnr_T start_vcol; /* start col of 1st char wholly inside block */ |
|
34 colnr_T end_vcol; /* start col of 1st char wholly after block */ |
|
35 #ifdef FEAT_VISUALEXTRA |
|
36 --- 72,82 ---- |
|
37 */ |
|
38 struct block_def |
|
39 { |
|
40 ! int startspaces; /* 'extra' cols before first char */ |
|
41 ! int endspaces; /* 'extra' cols after last char */ |
|
42 int textlen; /* chars in block */ |
|
43 ! char_u *textstart; /* pointer to 1st char (partially) in block */ |
|
44 ! colnr_T textcol; /* index of chars (partially) in block */ |
|
45 colnr_T start_vcol; /* start col of 1st char wholly inside block */ |
|
46 colnr_T end_vcol; /* start col of 1st char wholly after block */ |
|
47 #ifdef FEAT_VISUALEXTRA |
|
48 *************** |
|
49 *** 382,396 **** |
|
50 { |
|
51 int left = (oap->op_type == OP_LSHIFT); |
|
52 int oldstate = State; |
|
53 ! int total, split; |
|
54 ! char_u *newp, *oldp, *midp, *ptr; |
|
55 int oldcol = curwin->w_cursor.col; |
|
56 int p_sw = (int)curbuf->b_p_sw; |
|
57 int p_ts = (int)curbuf->b_p_ts; |
|
58 struct block_def bd; |
|
59 - int internal = 0; |
|
60 int incr; |
|
61 ! colnr_T vcol, col = 0, ws_vcol; |
|
62 int i = 0, j = 0; |
|
63 int len; |
|
64 |
|
65 --- 382,395 ---- |
|
66 { |
|
67 int left = (oap->op_type == OP_LSHIFT); |
|
68 int oldstate = State; |
|
69 ! int total; |
|
70 ! char_u *newp, *oldp; |
|
71 int oldcol = curwin->w_cursor.col; |
|
72 int p_sw = (int)curbuf->b_p_sw; |
|
73 int p_ts = (int)curbuf->b_p_ts; |
|
74 struct block_def bd; |
|
75 int incr; |
|
76 ! colnr_T ws_vcol; |
|
77 int i = 0, j = 0; |
|
78 int len; |
|
79 |
|
80 *************** |
|
81 *** 456,522 **** |
|
82 } |
|
83 else /* left */ |
|
84 { |
|
85 ! vcol = oap->start_vcol; |
|
86 ! /* walk vcol past ws to be removed */ |
|
87 ! for (midp = oldp + bd.textcol; |
|
88 ! vcol < (oap->start_vcol + total) && vim_iswhite(*midp); ) |
|
89 ! { |
|
90 ! incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol); |
|
91 ! vcol += incr; |
|
92 ! } |
|
93 ! /* internal is the block-internal ws replacing a split TAB */ |
|
94 ! if (vcol > (oap->start_vcol + total)) |
|
95 ! { |
|
96 ! /* we have to split the TAB *(midp-1) */ |
|
97 ! internal = vcol - (oap->start_vcol + total); |
|
98 ! } |
|
99 ! /* if 'expandtab' is not set, use TABs */ |
|
100 |
|
101 ! split = bd.startspaces + internal; |
|
102 ! if (split > 0) |
|
103 ! { |
|
104 ! if (!curbuf->b_p_et) |
|
105 ! { |
|
106 ! for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; ) |
|
107 ! col += lbr_chartabsize_adv(&ptr, (colnr_T)col); |
|
108 |
|
109 ! /* col+1 now equals the start col of the first char of the |
|
110 ! * block (may be < oap.start_vcol if we're splitting a TAB) */ |
|
111 ! i = ((col % p_ts) + split) / p_ts; /* number of tabs */ |
|
112 ! } |
|
113 ! if (i) |
|
114 ! j = ((col % p_ts) + split) % p_ts; /* number of spp */ |
|
115 ! else |
|
116 ! j = split; |
|
117 ! } |
|
118 |
|
119 ! newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1); |
|
120 ! if (newp == NULL) |
|
121 ! return; |
|
122 ! vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1)); |
|
123 |
|
124 ! /* copy first part we want to keep */ |
|
125 ! mch_memmove(newp, oldp, (size_t)bd.textcol); |
|
126 ! /* Now copy any TABS and spp to ensure correct alignment! */ |
|
127 ! while (vim_iswhite(*midp)) |
|
128 { |
|
129 ! if (*midp == TAB) |
|
130 ! i++; |
|
131 ! else /*space */ |
|
132 ! j++; |
|
133 ! midp++; |
|
134 } |
|
135 ! /* We might have an extra TAB worth of spp now! */ |
|
136 ! if (j / p_ts && !curbuf->b_p_et) |
|
137 { |
|
138 ! i++; |
|
139 ! j -= p_ts; |
|
140 } |
|
141 - copy_chars(newp + bd.textcol, (size_t)i, TAB); |
|
142 - copy_spaces(newp + bd.textcol + i, (size_t)j); |
|
143 |
|
144 ! /* the end */ |
|
145 ! STRMOVE(newp + STRLEN(newp), midp); |
|
146 } |
|
147 /* replace the line */ |
|
148 ml_replace(curwin->w_cursor.lnum, newp, FALSE); |
|
149 --- 455,543 ---- |
|
150 } |
|
151 else /* left */ |
|
152 { |
|
153 ! colnr_T destination_col; /* column to which text in block will |
|
154 ! be shifted */ |
|
155 ! char_u *verbatim_copy_end; /* end of the part of the line which is |
|
156 ! copied verbatim */ |
|
157 ! colnr_T verbatim_copy_width;/* the (displayed) width of this part |
|
158 ! of line */ |
|
159 ! unsigned fill; /* nr of spaces that replace a TAB */ |
|
160 ! unsigned new_line_len; /* the length of the line after the |
|
161 ! block shift */ |
|
162 ! size_t block_space_width; |
|
163 ! size_t shift_amount; |
|
164 ! char_u *non_white = bd.textstart; |
|
165 ! colnr_T non_white_col; |
|
166 |
|
167 ! /* |
|
168 ! * Firstly, let's find the first non-whitespace character that is |
|
169 ! * displayed after the block's start column and the character's column |
|
170 ! * number. Also, let's calculate the width of all the whitespace |
|
171 ! * characters that are displayed in the block and precede the searched |
|
172 ! * non-whitespace character. |
|
173 ! */ |
|
174 |
|
175 ! /* If "bd.startspaces" is set, "bd.textstart" points to the character, |
|
176 ! * the part of which is displayed at the block's beginning. Let's start |
|
177 ! * searching from the next character. */ |
|
178 ! if (bd.startspaces) |
|
179 ! mb_ptr_adv(non_white); |
|
180 |
|
181 ! /* The character's column is in "bd.start_vcol". */ |
|
182 ! non_white_col = bd.start_vcol; |
|
183 |
|
184 ! while (vim_iswhite(*non_white)) |
|
185 { |
|
186 ! incr = lbr_chartabsize_adv(&non_white, non_white_col); |
|
187 ! non_white_col += incr; |
|
188 } |
|
189 ! |
|
190 ! block_space_width = non_white_col - oap->start_vcol; |
|
191 ! /* We will shift by "total" or "block_space_width", whichever is less. |
|
192 ! */ |
|
193 ! shift_amount = (block_space_width < total? block_space_width: total); |
|
194 ! |
|
195 ! /* The column to which we will shift the text. */ |
|
196 ! destination_col = non_white_col - shift_amount; |
|
197 ! |
|
198 ! /* Now let's find out how much of the beginning of the line we can |
|
199 ! * reuse without modification. */ |
|
200 ! verbatim_copy_end = bd.textstart; |
|
201 ! verbatim_copy_width = bd.start_vcol; |
|
202 ! |
|
203 ! /* If "bd.startspaces" is set, "bd.textstart" points to the character |
|
204 ! * preceding the block. We have to subtract its width to obtain its |
|
205 ! * column number. */ |
|
206 ! if (bd.startspaces) |
|
207 ! verbatim_copy_width -= bd.start_char_vcols; |
|
208 ! while (verbatim_copy_width < destination_col) |
|
209 { |
|
210 ! incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width); |
|
211 ! if (verbatim_copy_width + incr > destination_col) |
|
212 ! break; |
|
213 ! verbatim_copy_width += incr; |
|
214 ! mb_ptr_adv(verbatim_copy_end); |
|
215 } |
|
216 |
|
217 ! /* If "destination_col" is different from the width of the initial |
|
218 ! * part of the line that will be copied, it means we encountered a tab |
|
219 ! * character, which we will have to partly replace with spaces. */ |
|
220 ! fill = destination_col - verbatim_copy_width; |
|
221 ! |
|
222 ! /* The replacement line will consist of: |
|
223 ! * - the beginning of the original line up to "verbatim_copy_end", |
|
224 ! * - "fill" number of spaces, |
|
225 ! * - the rest of the line, pointed to by non_white. */ |
|
226 ! new_line_len = (unsigned)(verbatim_copy_end - oldp) |
|
227 ! + fill |
|
228 ! + (unsigned)STRLEN(non_white) + 1; |
|
229 ! |
|
230 ! newp = alloc_check(new_line_len); |
|
231 ! if (newp == NULL) |
|
232 ! return; |
|
233 ! mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp)); |
|
234 ! copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill); |
|
235 ! STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white); |
|
236 } |
|
237 /* replace the line */ |
|
238 ml_replace(curwin->w_cursor.lnum, newp, FALSE); |
|
239 *************** |
|
240 *** 4851,4857 **** |
|
241 * - textlen includes the first/last char to be (partly) deleted |
|
242 * - start/endspaces is the number of columns that are taken by the |
|
243 * first/last deleted char minus the number of columns that have to be |
|
244 ! * deleted. for yank and tilde: |
|
245 * - textlen includes the first/last char to be wholly yanked |
|
246 * - start/endspaces is the number of columns of the first/last yanked char |
|
247 * that are to be yanked. |
|
248 --- 4872,4879 ---- |
|
249 * - textlen includes the first/last char to be (partly) deleted |
|
250 * - start/endspaces is the number of columns that are taken by the |
|
251 * first/last deleted char minus the number of columns that have to be |
|
252 ! * deleted. |
|
253 ! * for yank and tilde: |
|
254 * - textlen includes the first/last char to be wholly yanked |
|
255 * - start/endspaces is the number of columns of the first/last yanked char |
|
256 * that are to be yanked. |
|
257 *** ../vim-7.2.136/src/testdir/Makefile Wed Sep 10 18:25:18 2008 |
|
258 --- src/testdir/Makefile Thu Mar 5 04:53:58 2009 |
|
259 *************** |
|
260 *** 20,26 **** |
|
261 test48.out test49.out test51.out test52.out test53.out \ |
|
262 test54.out test55.out test56.out test57.out test58.out \ |
|
263 test59.out test60.out test61.out test62.out test63.out \ |
|
264 ! test64.out test65.out |
|
265 |
|
266 SCRIPTS_GUI = test16.out |
|
267 |
|
268 --- 20,26 ---- |
|
269 test48.out test49.out test51.out test52.out test53.out \ |
|
270 test54.out test55.out test56.out test57.out test58.out \ |
|
271 test59.out test60.out test61.out test62.out test63.out \ |
|
272 ! test64.out test65.out test66.out |
|
273 |
|
274 SCRIPTS_GUI = test16.out |
|
275 |
|
276 *** ../vim-7.2.136/src/testdir/test66.in Wed Mar 11 16:24:44 2009 |
|
277 --- src/testdir/test66.in Wed Mar 11 11:52:57 2009 |
|
278 *************** |
|
279 *** 0 **** |
|
280 --- 1,25 ---- |
|
281 + |
|
282 + Test for visual block shift and tab characters. |
|
283 + |
|
284 + STARTTEST |
|
285 + :so small.vim |
|
286 + /^abcdefgh |
|
287 + 4jI j<<11|D |
|
288 + 7|a |
|
289 + 7|a |
|
290 + 7|a 4k13|4j< |
|
291 + :$-4,$w! test.out |
|
292 + :$-4,$s/\s\+//g |
|
293 + 4kI j<< |
|
294 + 7|a |
|
295 + 7|a |
|
296 + 7|a 4k13|4j3< |
|
297 + :$-4,$w >> test.out |
|
298 + :qa! |
|
299 + ENDTEST |
|
300 + |
|
301 + abcdefghijklmnopqrstuvwxyz |
|
302 + abcdefghijklmnopqrstuvwxyz |
|
303 + abcdefghijklmnopqrstuvwxyz |
|
304 + abcdefghijklmnopqrstuvwxyz |
|
305 + abcdefghijklmnopqrstuvwxyz |
|
306 *** ../vim-7.2.136/src/testdir/test66.ok Wed Mar 11 16:24:44 2009 |
|
307 --- src/testdir/test66.ok Thu Mar 5 04:39:36 2009 |
|
308 *************** |
|
309 *** 0 **** |
|
310 --- 1,10 ---- |
|
311 + abcdefghijklmnopqrstuvwxyz |
|
312 + abcdefghij |
|
313 + abc defghijklmnopqrstuvwxyz |
|
314 + abc defghijklmnopqrstuvwxyz |
|
315 + abc defghijklmnopqrstuvwxyz |
|
316 + abcdefghijklmnopqrstuvwxyz |
|
317 + abcdefghij |
|
318 + abc defghijklmnopqrstuvwxyz |
|
319 + abc defghijklmnopqrstuvwxyz |
|
320 + abc defghijklmnopqrstuvwxyz |
|
321 *** ../vim-7.2.136/src/version.c Wed Mar 11 15:36:01 2009 |
|
322 --- src/version.c Wed Mar 11 16:23:07 2009 |
|
323 *************** |
|
324 *** 678,679 **** |
|
325 --- 678,681 ---- |
|
326 { /* Add new patch number below this line */ |
|
327 + /**/ |
|
328 + 137, |
|
329 /**/ |
|
330 |
|
331 -- |
|
332 % cat /usr/include/sys/errno.h |
|
333 #define EPERM 1 /* Operation not permitted */ |
|
334 #define ENOENT 2 /* No such file or directory */ |
|
335 #define ESRCH 3 /* No such process */ |
|
336 [...] |
|
337 #define EMACS 666 /* Too many macros */ |
|
338 % |
|
339 |
|
340 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\ |
|
341 /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
|
342 \\\ download, build and distribute -- http://www.A-A-P.org /// |
|
343 \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |
|