]>
Commit | Line | Data |
---|---|---|
478508cd ER |
1 | To: vim-dev@vim.org |
2 | Subject: Patch 7.2.137 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
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 | + \164jI \ej<<11|D | |
288 | + 7|a \e | |
289 | + 7|a \e | |
290 | + 7|a \e4k13|\164j< | |
291 | + :$-4,$w! test.out | |
292 | + :$-4,$s/\s\+//g | |
293 | + \164kI \ej<< | |
294 | + 7|a \e | |
295 | + 7|a \e | |
296 | + 7|a \e4k13|\164j3< | |
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 -- Bram@Moolenaar.net -- 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 /// |