]>
Commit | Line | Data |
---|---|---|
c6060300 MT |
1 | To: vim_dev@googlegroups.com |
2 | Subject: Patch 7.3.541 | |
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.541 | |
11 | Problem: When joining lines comment leaders need to be removed manually. | |
12 | Solution: Add the 'j' flag to 'formatoptions'. (Lech Lorens) | |
13 | Files: runtime/doc/change.txt, src/edit.c, src/ex_docmd.c, src/misc1.c, | |
14 | src/normal.c, src/ops.c, src/option.h, src/proto/misc1.pro, | |
15 | src/proto/ops.pro, src/search.c, src/testdir/test29.in, | |
16 | src/testdir/test29.ok | |
17 | ||
18 | ||
19 | *** ../vim-7.3.540/runtime/doc/change.txt 2011-05-05 14:26:37.000000000 +0200 | |
20 | --- runtime/doc/change.txt 2012-06-06 13:05:04.000000000 +0200 | |
21 | *************** | |
22 | *** 1495,1500 **** | |
23 | --- 1522,1533 ---- | |
24 | characters. Overruled by the 'M' flag. | |
25 | 1 Don't break a line after a one-letter word. It's broken before it | |
26 | instead (if possible). | |
27 | + j Where it makes sense, remove a comment leader when joining lines. For | |
28 | + example, joining: | |
29 | + int i; // the index ~ | |
30 | + // in the list ~ | |
31 | + Becomes: | |
32 | + int i; // the index in the list ~ | |
33 | ||
34 | ||
35 | With 't' and 'c' you can specify when Vim performs auto-wrapping: | |
36 | *** ../vim-7.3.540/src/edit.c 2012-06-01 15:20:49.000000000 +0200 | |
37 | --- src/edit.c 2012-06-06 13:00:29.000000000 +0200 | |
38 | *************** | |
39 | *** 5847,5853 **** | |
40 | * Need to remove existing (middle) comment leader and insert end | |
41 | * comment leader. First, check what comment leader we can find. | |
42 | */ | |
43 | ! i = get_leader_len(line = ml_get_curline(), &p, FALSE); | |
44 | if (i > 0 && vim_strchr(p, COM_MIDDLE) != NULL) /* Just checking */ | |
45 | { | |
46 | /* Skip middle-comment string */ | |
47 | --- 5847,5853 ---- | |
48 | * Need to remove existing (middle) comment leader and insert end | |
49 | * comment leader. First, check what comment leader we can find. | |
50 | */ | |
51 | ! i = get_leader_len(line = ml_get_curline(), &p, FALSE, TRUE); | |
52 | if (i > 0 && vim_strchr(p, COM_MIDDLE) != NULL) /* Just checking */ | |
53 | { | |
54 | /* Skip middle-comment string */ | |
55 | *************** | |
56 | *** 6085,6091 **** | |
57 | ||
58 | /* Don't break until after the comment leader */ | |
59 | if (do_comments) | |
60 | ! leader_len = get_leader_len(ml_get_curline(), NULL, FALSE); | |
61 | else | |
62 | leader_len = 0; | |
63 | ||
64 | --- 6085,6091 ---- | |
65 | ||
66 | /* Don't break until after the comment leader */ | |
67 | if (do_comments) | |
68 | ! leader_len = get_leader_len(ml_get_curline(), NULL, FALSE, TRUE); | |
69 | else | |
70 | leader_len = 0; | |
71 | ||
72 | *************** | |
73 | *** 6411,6417 **** | |
74 | /* With the 'c' flag in 'formatoptions' and 't' missing: only format | |
75 | * comments. */ | |
76 | if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP) | |
77 | ! && get_leader_len(old, NULL, FALSE) == 0) | |
78 | return; | |
79 | #endif | |
80 | ||
81 | --- 6411,6417 ---- | |
82 | /* With the 'c' flag in 'formatoptions' and 't' missing: only format | |
83 | * comments. */ | |
84 | if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP) | |
85 | ! && get_leader_len(old, NULL, FALSE, TRUE) == 0) | |
86 | return; | |
87 | #endif | |
88 | ||
89 | *************** | |
90 | *** 8565,8571 **** | |
91 | { | |
92 | temp = curwin->w_cursor.col; | |
93 | if (!can_bs(BS_EOL) /* only if "eol" included */ | |
94 | ! || do_join(2, FALSE, TRUE) == FAIL) | |
95 | vim_beep(); | |
96 | else | |
97 | curwin->w_cursor.col = temp; | |
98 | --- 8565,8571 ---- | |
99 | { | |
100 | temp = curwin->w_cursor.col; | |
101 | if (!can_bs(BS_EOL) /* only if "eol" included */ | |
102 | ! || do_join(2, FALSE, TRUE, FALSE) == FAIL) | |
103 | vim_beep(); | |
104 | else | |
105 | curwin->w_cursor.col = temp; | |
106 | *************** | |
107 | *** 8746,8752 **** | |
108 | ptr[len - 1] = NUL; | |
109 | } | |
110 | ||
111 | ! (void)do_join(2, FALSE, FALSE); | |
112 | if (temp == NUL && gchar_cursor() != NUL) | |
113 | inc_cursor(); | |
114 | } | |
115 | --- 8746,8752 ---- | |
116 | ptr[len - 1] = NUL; | |
117 | } | |
118 | ||
119 | ! (void)do_join(2, FALSE, FALSE, FALSE); | |
120 | if (temp == NUL && gchar_cursor() != NUL) | |
121 | inc_cursor(); | |
122 | } | |
123 | *** ../vim-7.3.540/src/ex_docmd.c 2012-04-30 18:48:38.000000000 +0200 | |
124 | --- src/ex_docmd.c 2012-06-06 13:00:29.000000000 +0200 | |
125 | *************** | |
126 | *** 8545,8551 **** | |
127 | } | |
128 | ++eap->line2; | |
129 | } | |
130 | ! (void)do_join(eap->line2 - eap->line1 + 1, !eap->forceit, TRUE); | |
131 | beginline(BL_WHITE | BL_FIX); | |
132 | ex_may_print(eap); | |
133 | } | |
134 | --- 8545,8551 ---- | |
135 | } | |
136 | ++eap->line2; | |
137 | } | |
138 | ! (void)do_join(eap->line2 - eap->line1 + 1, !eap->forceit, TRUE, TRUE); | |
139 | beginline(BL_WHITE | BL_FIX); | |
140 | ex_may_print(eap); | |
141 | } | |
142 | *** ../vim-7.3.540/src/misc1.c 2012-06-01 15:20:49.000000000 +0200 | |
143 | --- src/misc1.c 2012-06-06 13:27:32.000000000 +0200 | |
144 | *************** | |
145 | *** 671,677 **** | |
146 | ptr = saved_line; | |
147 | # ifdef FEAT_COMMENTS | |
148 | if (flags & OPENLINE_DO_COM) | |
149 | ! lead_len = get_leader_len(ptr, NULL, FALSE); | |
150 | else | |
151 | lead_len = 0; | |
152 | # endif | |
153 | --- 671,677 ---- | |
154 | ptr = saved_line; | |
155 | # ifdef FEAT_COMMENTS | |
156 | if (flags & OPENLINE_DO_COM) | |
157 | ! lead_len = get_leader_len(ptr, NULL, FALSE, TRUE); | |
158 | else | |
159 | lead_len = 0; | |
160 | # endif | |
161 | *************** | |
162 | *** 693,699 **** | |
163 | } | |
164 | # ifdef FEAT_COMMENTS | |
165 | if (flags & OPENLINE_DO_COM) | |
166 | ! lead_len = get_leader_len(ptr, NULL, FALSE); | |
167 | else | |
168 | lead_len = 0; | |
169 | if (lead_len > 0) | |
170 | --- 693,699 ---- | |
171 | } | |
172 | # ifdef FEAT_COMMENTS | |
173 | if (flags & OPENLINE_DO_COM) | |
174 | ! lead_len = get_leader_len(ptr, NULL, FALSE, TRUE); | |
175 | else | |
176 | lead_len = 0; | |
177 | if (lead_len > 0) | |
178 | *************** | |
179 | *** 836,842 **** | |
180 | */ | |
181 | end_comment_pending = NUL; | |
182 | if (flags & OPENLINE_DO_COM) | |
183 | ! lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD); | |
184 | else | |
185 | lead_len = 0; | |
186 | if (lead_len > 0) | |
187 | --- 836,842 ---- | |
188 | */ | |
189 | end_comment_pending = NUL; | |
190 | if (flags & OPENLINE_DO_COM) | |
191 | ! lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD, TRUE); | |
192 | else | |
193 | lead_len = 0; | |
194 | if (lead_len > 0) | |
195 | *************** | |
196 | *** 1548,1561 **** | |
197 | * When "flags" is not NULL, it is set to point to the flags of the recognized | |
198 | * comment leader. | |
199 | * "backward" must be true for the "O" command. | |
200 | */ | |
201 | int | |
202 | ! get_leader_len(line, flags, backward) | |
203 | char_u *line; | |
204 | char_u **flags; | |
205 | int backward; | |
206 | { | |
207 | int i, j; | |
208 | int got_com = FALSE; | |
209 | int found_one; | |
210 | char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */ | |
211 | --- 1548,1565 ---- | |
212 | * When "flags" is not NULL, it is set to point to the flags of the recognized | |
213 | * comment leader. | |
214 | * "backward" must be true for the "O" command. | |
215 | + * If "include_space" is set, include trailing whitespace while calculating the | |
216 | + * length. | |
217 | */ | |
218 | int | |
219 | ! get_leader_len(line, flags, backward, include_space) | |
220 | char_u *line; | |
221 | char_u **flags; | |
222 | int backward; | |
223 | + int include_space; | |
224 | { | |
225 | int i, j; | |
226 | + int result; | |
227 | int got_com = FALSE; | |
228 | int found_one; | |
229 | char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */ | |
230 | *************** | |
231 | *** 1565,1571 **** | |
232 | char_u *prev_list; | |
233 | char_u *saved_flags = NULL; | |
234 | ||
235 | ! i = 0; | |
236 | while (vim_iswhite(line[i])) /* leading white space is ignored */ | |
237 | ++i; | |
238 | ||
239 | --- 1569,1575 ---- | |
240 | char_u *prev_list; | |
241 | char_u *saved_flags = NULL; | |
242 | ||
243 | ! result = i = 0; | |
244 | while (vim_iswhite(line[i])) /* leading white space is ignored */ | |
245 | ++i; | |
246 | ||
247 | *************** | |
248 | *** 1668,1684 **** | |
249 | if (!found_one) | |
250 | break; | |
251 | ||
252 | /* Include any trailing white space. */ | |
253 | while (vim_iswhite(line[i])) | |
254 | ++i; | |
255 | ||
256 | /* If this comment doesn't nest, stop here. */ | |
257 | got_com = TRUE; | |
258 | if (vim_strchr(part_buf, COM_NEST) == NULL) | |
259 | break; | |
260 | } | |
261 | ||
262 | ! return (got_com ? i : 0); | |
263 | } | |
264 | #endif | |
265 | ||
266 | --- 1672,1838 ---- | |
267 | if (!found_one) | |
268 | break; | |
269 | ||
270 | + result = i; | |
271 | + | |
272 | /* Include any trailing white space. */ | |
273 | while (vim_iswhite(line[i])) | |
274 | ++i; | |
275 | ||
276 | + if (include_space) | |
277 | + result = i; | |
278 | + | |
279 | /* If this comment doesn't nest, stop here. */ | |
280 | got_com = TRUE; | |
281 | if (vim_strchr(part_buf, COM_NEST) == NULL) | |
282 | break; | |
283 | } | |
284 | + return result; | |
285 | + } | |
286 | + | |
287 | + /* | |
288 | + * Return the offset at which the last comment in line starts. If there is no | |
289 | + * comment in the whole line, -1 is returned. | |
290 | + * | |
291 | + * When "flags" is not null, it is set to point to the flags describing the | |
292 | + * recognized comment leader. | |
293 | + */ | |
294 | + int | |
295 | + get_last_leader_offset(line, flags) | |
296 | + char_u *line; | |
297 | + char_u **flags; | |
298 | + { | |
299 | + int result = -1; | |
300 | + int i, j; | |
301 | + int lower_check_bound = 0; | |
302 | + char_u *string; | |
303 | + char_u *com_leader; | |
304 | + char_u *com_flags; | |
305 | + char_u *list; | |
306 | + int found_one; | |
307 | + char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */ | |
308 | + | |
309 | + /* | |
310 | + * Repeat to match several nested comment strings. | |
311 | + */ | |
312 | + i = (int)STRLEN(line); | |
313 | + while (--i >= lower_check_bound) | |
314 | + { | |
315 | + /* | |
316 | + * scan through the 'comments' option for a match | |
317 | + */ | |
318 | + found_one = FALSE; | |
319 | + for (list = curbuf->b_p_com; *list; ) | |
320 | + { | |
321 | + char_u *flags_save = list; | |
322 | + | |
323 | + /* | |
324 | + * Get one option part into part_buf[]. Advance list to next one. | |
325 | + * put string at start of string. | |
326 | + */ | |
327 | + (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ","); | |
328 | + string = vim_strchr(part_buf, ':'); | |
329 | + if (string == NULL) /* If everything is fine, this cannot actually | |
330 | + * happen. */ | |
331 | + { | |
332 | + continue; | |
333 | + } | |
334 | + *string++ = NUL; /* Isolate flags from string. */ | |
335 | + com_leader = string; | |
336 | + | |
337 | + /* | |
338 | + * Line contents and string must match. | |
339 | + * When string starts with white space, must have some white space | |
340 | + * (but the amount does not need to match, there might be a mix of | |
341 | + * TABs and spaces). | |
342 | + */ | |
343 | + if (vim_iswhite(string[0])) | |
344 | + { | |
345 | + if (i == 0 || !vim_iswhite(line[i - 1])) | |
346 | + continue; | |
347 | + while (vim_iswhite(string[0])) | |
348 | + ++string; | |
349 | + } | |
350 | + for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) | |
351 | + /* do nothing */; | |
352 | + if (string[j] != NUL) | |
353 | + continue; | |
354 | + | |
355 | + /* | |
356 | + * When 'b' flag used, there must be white space or an | |
357 | + * end-of-line after the string in the line. | |
358 | + */ | |
359 | + if (vim_strchr(part_buf, COM_BLANK) != NULL | |
360 | + && !vim_iswhite(line[i + j]) && line[i + j] != NUL) | |
361 | + { | |
362 | + continue; | |
363 | + } | |
364 | + | |
365 | + /* | |
366 | + * We have found a match, stop searching. | |
367 | + */ | |
368 | + found_one = TRUE; | |
369 | + | |
370 | + if (flags) | |
371 | + *flags = flags_save; | |
372 | + com_flags = flags_save; | |
373 | + | |
374 | + break; | |
375 | + } | |
376 | ||
377 | ! if (found_one) | |
378 | ! { | |
379 | ! char_u part_buf2[COM_MAX_LEN]; /* buffer for one option part */ | |
380 | ! int len1, len2, off; | |
381 | ! | |
382 | ! result = i; | |
383 | ! /* | |
384 | ! * If this comment nests, continue searching. | |
385 | ! */ | |
386 | ! if (vim_strchr(part_buf, COM_NEST) != NULL) | |
387 | ! continue; | |
388 | ! | |
389 | ! lower_check_bound = i; | |
390 | ! | |
391 | ! /* Let's verify whether the comment leader found is a substring | |
392 | ! * of other comment leaders. If it is, let's adjust the | |
393 | ! * lower_check_bound so that we make sure that we have determined | |
394 | ! * the comment leader correctly. | |
395 | ! */ | |
396 | ! | |
397 | ! while (vim_iswhite(*com_leader)) | |
398 | ! ++com_leader; | |
399 | ! len1 = (int)STRLEN(com_leader); | |
400 | ! | |
401 | ! for (list = curbuf->b_p_com; *list; ) | |
402 | ! { | |
403 | ! char_u *flags_save = list; | |
404 | ! | |
405 | ! (void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ","); | |
406 | ! if (flags_save == com_flags) | |
407 | ! continue; | |
408 | ! string = vim_strchr(part_buf2, ':'); | |
409 | ! ++string; | |
410 | ! while (vim_iswhite(*string)) | |
411 | ! ++string; | |
412 | ! len2 = (int)STRLEN(string); | |
413 | ! if (len2 == 0) | |
414 | ! continue; | |
415 | ! | |
416 | ! /* Now we have to verify whether string ends with a substring | |
417 | ! * beginning the com_leader. */ | |
418 | ! for (off = (len2 > i ? i : len2); off > 0 && off + len1 > len2;) | |
419 | ! { | |
420 | ! --off; | |
421 | ! if (!STRNCMP(string + off, com_leader, len2 - off)) | |
422 | ! { | |
423 | ! if (i - off < lower_check_bound) | |
424 | ! lower_check_bound = i - off; | |
425 | ! } | |
426 | ! } | |
427 | ! } | |
428 | ! } | |
429 | ! } | |
430 | ! return result; | |
431 | } | |
432 | #endif | |
433 | ||
434 | *** ../vim-7.3.540/src/normal.c 2012-05-25 13:12:33.000000000 +0200 | |
435 | --- src/normal.c 2012-06-06 13:00:29.000000000 +0200 | |
436 | *************** | |
437 | *** 1968,1974 **** | |
438 | beep_flush(); | |
439 | else | |
440 | { | |
441 | ! (void)do_join(oap->line_count, oap->op_type == OP_JOIN, TRUE); | |
442 | auto_format(FALSE, TRUE); | |
443 | } | |
444 | break; | |
445 | --- 1968,1974 ---- | |
446 | beep_flush(); | |
447 | else | |
448 | { | |
449 | ! (void)do_join(oap->line_count, oap->op_type == OP_JOIN, TRUE, TRUE); | |
450 | auto_format(FALSE, TRUE); | |
451 | } | |
452 | break; | |
453 | *************** | |
454 | *** 4426,4432 **** | |
455 | break; | |
456 | } | |
457 | #ifdef FEAT_COMMENTS | |
458 | ! if (get_leader_len(ml_get_curline(), NULL, FALSE) > 0) | |
459 | { | |
460 | /* Ignore this line, continue at start of next line. */ | |
461 | ++curwin->w_cursor.lnum; | |
462 | --- 4426,4432 ---- | |
463 | break; | |
464 | } | |
465 | #ifdef FEAT_COMMENTS | |
466 | ! if (get_leader_len(ml_get_curline(), NULL, FALSE, TRUE) > 0) | |
467 | { | |
468 | /* Ignore this line, continue at start of next line. */ | |
469 | ++curwin->w_cursor.lnum; | |
470 | *************** | |
471 | *** 9324,9330 **** | |
472 | { | |
473 | prep_redo(cap->oap->regname, cap->count0, | |
474 | NUL, cap->cmdchar, NUL, NUL, cap->nchar); | |
475 | ! (void)do_join(cap->count0, cap->nchar == NUL, TRUE); | |
476 | } | |
477 | } | |
478 | } | |
479 | --- 9324,9330 ---- | |
480 | { | |
481 | prep_redo(cap->oap->regname, cap->count0, | |
482 | NUL, cap->cmdchar, NUL, NUL, cap->nchar); | |
483 | ! (void)do_join(cap->count0, cap->nchar == NUL, TRUE, TRUE); | |
484 | } | |
485 | } | |
486 | } | |
487 | *** ../vim-7.3.540/src/ops.c 2012-05-18 12:49:33.000000000 +0200 | |
488 | --- src/ops.c 2012-06-06 15:43:31.000000000 +0200 | |
489 | *************** | |
490 | *** 112,117 **** | |
491 | --- 112,120 ---- | |
492 | # endif | |
493 | #endif | |
494 | static void dis_msg __ARGS((char_u *p, int skip_esc)); | |
495 | + #if defined(FEAT_COMMENTS) || defined(PROTO) | |
496 | + static char_u *skip_comment __ARGS((char_u *line, int process, int include_space, int *is_comment)); | |
497 | + #endif | |
498 | #ifdef FEAT_VISUAL | |
499 | static void block_prep __ARGS((oparg_T *oap, struct block_def *, linenr_T, int)); | |
500 | #endif | |
501 | *************** | |
502 | *** 1987,1993 **** | |
503 | curwin->w_cursor = curpos; /* restore curwin->w_cursor */ | |
504 | } | |
505 | if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) | |
506 | ! (void)do_join(2, FALSE, FALSE); | |
507 | } | |
508 | } | |
509 | ||
510 | --- 1990,1996 ---- | |
511 | curwin->w_cursor = curpos; /* restore curwin->w_cursor */ | |
512 | } | |
513 | if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) | |
514 | ! (void)do_join(2, FALSE, FALSE, FALSE); | |
515 | } | |
516 | } | |
517 | ||
518 | *************** | |
519 | *** 4197,4213 **** | |
520 | ui_breakcheck(); | |
521 | } | |
522 | ||
523 | /* | |
524 | * Join 'count' lines (minimal 2) at cursor position. | |
525 | * When "save_undo" is TRUE save lines for undo first. | |
526 | * | |
527 | * return FAIL for failure, OK otherwise | |
528 | */ | |
529 | int | |
530 | ! do_join(count, insert_space, save_undo) | |
531 | long count; | |
532 | int insert_space; | |
533 | int save_undo; | |
534 | { | |
535 | char_u *curr = NULL; | |
536 | char_u *curr_start = NULL; | |
537 | --- 4200,4297 ---- | |
538 | ui_breakcheck(); | |
539 | } | |
540 | ||
541 | + #if defined(FEAT_COMMENTS) || defined(PROTO) | |
542 | + /* | |
543 | + * If "process" is TRUE and the line begins with a comment leader (possibly | |
544 | + * after some white space), return a pointer to the text after it. Put a boolean | |
545 | + * value indicating whether the line ends with an unclosed comment in | |
546 | + * "is_comment". | |
547 | + * line - line to be processed, | |
548 | + * process - if FALSE, will only check whether the line ends with an unclosed | |
549 | + * comment, | |
550 | + * include_space - whether to also skip space following the comment leader, | |
551 | + * is_comment - will indicate whether the current line ends with an unclosed | |
552 | + * comment. | |
553 | + */ | |
554 | + static char_u * | |
555 | + skip_comment(line, process, include_space, is_comment) | |
556 | + char_u *line; | |
557 | + int process; | |
558 | + int include_space; | |
559 | + int *is_comment; | |
560 | + { | |
561 | + char_u *comment_flags = NULL; | |
562 | + int lead_len; | |
563 | + int leader_offset = get_last_leader_offset(line, &comment_flags); | |
564 | + | |
565 | + *is_comment = FALSE; | |
566 | + if (leader_offset != -1) | |
567 | + { | |
568 | + /* Let's check whether the line ends with an unclosed comment. | |
569 | + * If the last comment leader has COM_END in flags, there's no comment. | |
570 | + */ | |
571 | + while (*comment_flags) | |
572 | + { | |
573 | + if (*comment_flags == COM_END | |
574 | + || *comment_flags == ':') | |
575 | + break; | |
576 | + ++comment_flags; | |
577 | + } | |
578 | + if (*comment_flags != COM_END) | |
579 | + *is_comment = TRUE; | |
580 | + } | |
581 | + | |
582 | + if (process == FALSE) | |
583 | + return line; | |
584 | + | |
585 | + lead_len = get_leader_len(line, &comment_flags, FALSE, include_space); | |
586 | + | |
587 | + if (lead_len == 0) | |
588 | + return line; | |
589 | + | |
590 | + /* Find: | |
591 | + * - COM_START, | |
592 | + * - COM_END, | |
593 | + * - colon, | |
594 | + * whichever comes first. | |
595 | + */ | |
596 | + while (*comment_flags) | |
597 | + { | |
598 | + if (*comment_flags == COM_START | |
599 | + || *comment_flags == COM_END | |
600 | + || *comment_flags == ':') | |
601 | + { | |
602 | + break; | |
603 | + } | |
604 | + ++comment_flags; | |
605 | + } | |
606 | + | |
607 | + /* If we found a colon, it means that we are not processing a line | |
608 | + * starting with an opening or a closing part of a three-part | |
609 | + * comment. That's good, because we don't want to remove those as | |
610 | + * this would be annoying. | |
611 | + */ | |
612 | + if (*comment_flags == ':' || *comment_flags == NUL) | |
613 | + line += lead_len; | |
614 | + | |
615 | + return line; | |
616 | + } | |
617 | + #endif | |
618 | + | |
619 | /* | |
620 | * Join 'count' lines (minimal 2) at cursor position. | |
621 | * When "save_undo" is TRUE save lines for undo first. | |
622 | + * Set "use_formatoptions" to FALSE when e.g. processing | |
623 | + * backspace and comment leaders should not be removed. | |
624 | * | |
625 | * return FAIL for failure, OK otherwise | |
626 | */ | |
627 | int | |
628 | ! do_join(count, insert_space, save_undo, use_formatoptions) | |
629 | long count; | |
630 | int insert_space; | |
631 | int save_undo; | |
632 | + int use_formatoptions UNUSED; | |
633 | { | |
634 | char_u *curr = NULL; | |
635 | char_u *curr_start = NULL; | |
636 | *************** | |
637 | *** 4221,4226 **** | |
638 | --- 4305,4317 ---- | |
639 | linenr_T t; | |
640 | colnr_T col = 0; | |
641 | int ret = OK; | |
642 | + #if defined(FEAT_COMMENTS) || defined(PROTO) | |
643 | + int *comments; | |
644 | + int remove_comments = (use_formatoptions == TRUE) | |
645 | + && has_format_option(FO_REMOVE_COMS); | |
646 | + int prev_was_comment; | |
647 | + #endif | |
648 | + | |
649 | ||
650 | if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1), | |
651 | (linenr_T)(curwin->w_cursor.lnum + count)) == FAIL) | |
652 | *************** | |
653 | *** 4232,4237 **** | |
654 | --- 4323,4339 ---- | |
655 | spaces = lalloc_clear((long_u)count, TRUE); | |
656 | if (spaces == NULL) | |
657 | return FAIL; | |
658 | + #if defined(FEAT_COMMENTS) || defined(PROTO) | |
659 | + if (remove_comments) | |
660 | + { | |
661 | + comments = (int *)lalloc_clear((long_u)count * sizeof(int), TRUE); | |
662 | + if (comments == NULL) | |
663 | + { | |
664 | + vim_free(spaces); | |
665 | + return FAIL; | |
666 | + } | |
667 | + } | |
668 | + #endif | |
669 | ||
670 | /* | |
671 | * Don't move anything, just compute the final line length | |
672 | *************** | |
673 | *** 4240,4245 **** | |
674 | --- 4342,4366 ---- | |
675 | for (t = 0; t < count; ++t) | |
676 | { | |
677 | curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); | |
678 | + #if defined(FEAT_COMMENTS) || defined(PROTO) | |
679 | + if (remove_comments) | |
680 | + { | |
681 | + /* We don't want to remove the comment leader if the | |
682 | + * previous line is not a comment. */ | |
683 | + if (t > 0 && prev_was_comment) | |
684 | + { | |
685 | + | |
686 | + char_u *new_curr = skip_comment(curr, TRUE, insert_space, | |
687 | + &prev_was_comment); | |
688 | + comments[t] = new_curr - curr; | |
689 | + curr = new_curr; | |
690 | + } | |
691 | + else | |
692 | + curr = skip_comment(curr, FALSE, insert_space, | |
693 | + &prev_was_comment); | |
694 | + } | |
695 | + #endif | |
696 | + | |
697 | if (insert_space && t > 0) | |
698 | { | |
699 | curr = skipwhite(curr); | |
700 | *************** | |
701 | *** 4327,4332 **** | |
702 | --- 4448,4457 ---- | |
703 | if (t == 0) | |
704 | break; | |
705 | curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1)); | |
706 | + #if defined(FEAT_COMMENTS) || defined(PROTO) | |
707 | + if (remove_comments) | |
708 | + curr += comments[t - 1]; | |
709 | + #endif | |
710 | if (insert_space && t > 1) | |
711 | curr = skipwhite(curr); | |
712 | currsize = (int)STRLEN(curr); | |
713 | *************** | |
714 | *** 4364,4369 **** | |
715 | --- 4489,4498 ---- | |
716 | ||
717 | theend: | |
718 | vim_free(spaces); | |
719 | + #if defined(FEAT_COMMENTS) || defined(PROTO) | |
720 | + if (remove_comments) | |
721 | + vim_free(comments); | |
722 | + #endif | |
723 | return ret; | |
724 | } | |
725 | ||
726 | *************** | |
727 | *** 4788,4794 **** | |
728 | (long)-next_leader_len); | |
729 | #endif | |
730 | curwin->w_cursor.lnum--; | |
731 | ! if (do_join(2, TRUE, FALSE) == FAIL) | |
732 | { | |
733 | beep_flush(); | |
734 | break; | |
735 | --- 4917,4923 ---- | |
736 | (long)-next_leader_len); | |
737 | #endif | |
738 | curwin->w_cursor.lnum--; | |
739 | ! if (do_join(2, TRUE, FALSE, FALSE) == FAIL) | |
740 | { | |
741 | beep_flush(); | |
742 | break; | |
743 | *************** | |
744 | *** 4844,4850 **** | |
745 | ||
746 | ptr = ml_get(lnum); | |
747 | if (do_comments) | |
748 | ! *leader_len = get_leader_len(ptr, leader_flags, FALSE); | |
749 | else | |
750 | *leader_len = 0; | |
751 | ||
752 | --- 4973,4979 ---- | |
753 | ||
754 | ptr = ml_get(lnum); | |
755 | if (do_comments) | |
756 | ! *leader_len = get_leader_len(ptr, leader_flags, FALSE, TRUE); | |
757 | else | |
758 | *leader_len = 0; | |
759 | ||
760 | *** ../vim-7.3.540/src/option.h 2012-02-20 22:18:22.000000000 +0100 | |
761 | --- src/option.h 2012-06-06 13:00:29.000000000 +0200 | |
762 | *************** | |
763 | *** 104,113 **** | |
764 | #define FO_ONE_LETTER '1' | |
765 | #define FO_WHITE_PAR 'w' /* trailing white space continues paragr. */ | |
766 | #define FO_AUTO 'a' /* automatic formatting */ | |
767 | ||
768 | #define DFLT_FO_VI "vt" | |
769 | #define DFLT_FO_VIM "tcq" | |
770 | ! #define FO_ALL "tcroq2vlb1mMBn,aw" /* for do_set() */ | |
771 | ||
772 | /* characters for the p_cpo option: */ | |
773 | #define CPO_ALTREAD 'a' /* ":read" sets alternate file name */ | |
774 | --- 104,114 ---- | |
775 | #define FO_ONE_LETTER '1' | |
776 | #define FO_WHITE_PAR 'w' /* trailing white space continues paragr. */ | |
777 | #define FO_AUTO 'a' /* automatic formatting */ | |
778 | + #define FO_REMOVE_COMS 'j' /* remove comment leaders when joining lines */ | |
779 | ||
780 | #define DFLT_FO_VI "vt" | |
781 | #define DFLT_FO_VIM "tcq" | |
782 | ! #define FO_ALL "tcroq2vlb1mMBn,awj" /* for do_set() */ | |
783 | ||
784 | /* characters for the p_cpo option: */ | |
785 | #define CPO_ALTREAD 'a' /* ":read" sets alternate file name */ | |
786 | *** ../vim-7.3.540/src/proto/misc1.pro 2010-08-15 21:57:28.000000000 +0200 | |
787 | --- src/proto/misc1.pro 2012-06-06 13:00:29.000000000 +0200 | |
788 | *************** | |
789 | *** 6,12 **** | |
790 | int set_indent __ARGS((int size, int flags)); | |
791 | int get_number_indent __ARGS((linenr_T lnum)); | |
792 | int open_line __ARGS((int dir, int flags, int old_indent)); | |
793 | ! int get_leader_len __ARGS((char_u *line, char_u **flags, int backward)); | |
794 | int plines __ARGS((linenr_T lnum)); | |
795 | int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight)); | |
796 | int plines_nofill __ARGS((linenr_T lnum)); | |
797 | --- 6,13 ---- | |
798 | int set_indent __ARGS((int size, int flags)); | |
799 | int get_number_indent __ARGS((linenr_T lnum)); | |
800 | int open_line __ARGS((int dir, int flags, int old_indent)); | |
801 | ! int get_leader_len __ARGS((char_u *line, char_u **flags, int backward, int do_skip_space)); | |
802 | ! int get_last_leader_offset __ARGS((char_u *line, char_u **flags)); | |
803 | int plines __ARGS((linenr_T lnum)); | |
804 | int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight)); | |
805 | int plines_nofill __ARGS((linenr_T lnum)); | |
806 | *** ../vim-7.3.540/src/proto/ops.pro 2010-08-15 21:57:28.000000000 +0200 | |
807 | --- src/proto/ops.pro 2012-06-06 13:00:29.000000000 +0200 | |
808 | *************** | |
809 | *** 36,42 **** | |
810 | int preprocs_left __ARGS((void)); | |
811 | int get_register_name __ARGS((int num)); | |
812 | void ex_display __ARGS((exarg_T *eap)); | |
813 | ! int do_join __ARGS((long count, int insert_space, int save_undo)); | |
814 | void op_format __ARGS((oparg_T *oap, int keep_cursor)); | |
815 | void op_formatexpr __ARGS((oparg_T *oap)); | |
816 | int fex_format __ARGS((linenr_T lnum, long count, int c)); | |
817 | --- 36,42 ---- | |
818 | int preprocs_left __ARGS((void)); | |
819 | int get_register_name __ARGS((int num)); | |
820 | void ex_display __ARGS((exarg_T *eap)); | |
821 | ! int do_join __ARGS((long count, int insert_space, int save_undo, int use_formatoptions)); | |
822 | void op_format __ARGS((oparg_T *oap, int keep_cursor)); | |
823 | void op_formatexpr __ARGS((oparg_T *oap)); | |
824 | int fex_format __ARGS((linenr_T lnum, long count, int c)); | |
825 | *** ../vim-7.3.540/src/search.c 2012-02-04 23:34:57.000000000 +0100 | |
826 | --- src/search.c 2012-06-06 13:00:29.000000000 +0200 | |
827 | *************** | |
828 | *** 1548,1554 **** | |
829 | int len; | |
830 | int stop = TRUE; | |
831 | #ifdef FEAT_MBYTE | |
832 | ! static char_u bytes[MB_MAXBYTES]; | |
833 | static int bytelen = 1; /* >1 for multi-byte char */ | |
834 | #endif | |
835 | ||
836 | --- 1548,1554 ---- | |
837 | int len; | |
838 | int stop = TRUE; | |
839 | #ifdef FEAT_MBYTE | |
840 | ! static char_u bytes[MB_MAXBYTES + 1]; | |
841 | static int bytelen = 1; /* >1 for multi-byte char */ | |
842 | #endif | |
843 | ||
844 | *************** | |
845 | *** 4901,4907 **** | |
846 | #ifdef FEAT_COMMENTS | |
847 | if ((*line != '#' || | |
848 | STRNCMP(skipwhite(line + 1), "define", 6) != 0) | |
849 | ! && get_leader_len(line, NULL, FALSE)) | |
850 | matched = FALSE; | |
851 | ||
852 | /* | |
853 | --- 4901,4907 ---- | |
854 | #ifdef FEAT_COMMENTS | |
855 | if ((*line != '#' || | |
856 | STRNCMP(skipwhite(line + 1), "define", 6) != 0) | |
857 | ! && get_leader_len(line, NULL, FALSE, TRUE)) | |
858 | matched = FALSE; | |
859 | ||
860 | /* | |
861 | *** ../vim-7.3.540/src/testdir/test29.in 2010-08-15 21:57:29.000000000 +0200 | |
862 | --- src/testdir/test29.in 2012-06-06 15:44:38.000000000 +0200 | |
863 | *************** | |
864 | *** 4,19 **** | |
865 | and with 'cpoptions' flag 'j' set or not | |
866 | ||
867 | STARTTEST | |
868 | :set nocompatible viminfo+=nviminfo | |
869 | :set nojoinspaces | |
870 | :set cpoptions-=j | |
871 | /firstline/ | |
872 | ! j"tdGpJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j | |
873 | j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j joinspaces | |
874 | j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j | |
875 | j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j nojoinspaces compatible | |
876 | ! j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj4Jy3l$pjdG:?firstline?+1,$w! test.out | |
877 | ! :qa! | |
878 | ENDTEST | |
879 | ||
880 | firstline | |
881 | --- 4,20 ---- | |
882 | and with 'cpoptions' flag 'j' set or not | |
883 | ||
884 | STARTTEST | |
885 | + :so small.vim | |
886 | :set nocompatible viminfo+=nviminfo | |
887 | :set nojoinspaces | |
888 | :set cpoptions-=j | |
889 | /firstline/ | |
890 | ! j"td/^STARTTEST/-1 | |
891 | ! PJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j | |
892 | j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j joinspaces | |
893 | j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j | |
894 | j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j nojoinspaces compatible | |
895 | ! j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj4Jy3l$pjd/STARTTEST/-2 | |
896 | ENDTEST | |
897 | ||
898 | firstline | |
899 | *************** | |
900 | *** 54,56 **** | |
901 | --- 55,181 ---- | |
902 | hjkl iop! | |
903 | ert | |
904 | ||
905 | + STARTTEST | |
906 | + /^{/+1 | |
907 | + :set comments=s1:/*,mb:*,ex:*/,:// | |
908 | + :set nojoinspaces fo=j | |
909 | + :set backspace=eol,start | |
910 | + :.,+3join | |
911 | + j4J | |
912 | + :.,+2join | |
913 | + j3J | |
914 | + :.,+2join | |
915 | + j3J | |
916 | + :.,+2join | |
917 | + jj3J | |
918 | + ENDTEST | |
919 | + | |
920 | + { | |
921 | + | |
922 | + /* | |
923 | + * Make sure the previous comment leader is not removed. | |
924 | + */ | |
925 | + | |
926 | + /* | |
927 | + * Make sure the previous comment leader is not removed. | |
928 | + */ | |
929 | + | |
930 | + // Should the next comment leader be left alone? | |
931 | + // Yes. | |
932 | + | |
933 | + // Should the next comment leader be left alone? | |
934 | + // Yes. | |
935 | + | |
936 | + /* Here the comment leader should be left intact. */ | |
937 | + // And so should this one. | |
938 | + | |
939 | + /* Here the comment leader should be left intact. */ | |
940 | + // And so should this one. | |
941 | + | |
942 | + if (condition) // Remove the next comment leader! | |
943 | + // OK, I will. | |
944 | + action(); | |
945 | + | |
946 | + if (condition) // Remove the next comment leader! | |
947 | + // OK, I will. | |
948 | + action(); | |
949 | + } | |
950 | + | |
951 | + STARTTEST | |
952 | + /^{/+1 | |
953 | + :set comments=s1:/*,mb:*,ex:*/,:// | |
954 | + :set comments+=s1:>#,mb:#,ex:#<,:< | |
955 | + :set cpoptions-=j joinspaces fo=j | |
956 | + :set backspace=eol,start | |
957 | + :.,+3join | |
958 | + j4J | |
959 | + :.,+2join | |
960 | + j3J | |
961 | + :.,+2join | |
962 | + j3J | |
963 | + :.,+2join | |
964 | + jj3J | |
965 | + j:.,+2join | |
966 | + jj3J | |
967 | + j:.,+5join | |
968 | + j6J | |
969 | + oSome code!\r// Make sure backspacing does not remove this comment leader.\e0i\b\e | |
970 | + ENDTEST | |
971 | + | |
972 | + { | |
973 | + | |
974 | + /* | |
975 | + * Make sure the previous comment leader is not removed. | |
976 | + */ | |
977 | + | |
978 | + /* | |
979 | + * Make sure the previous comment leader is not removed. | |
980 | + */ | |
981 | + | |
982 | + // Should the next comment leader be left alone? | |
983 | + // Yes. | |
984 | + | |
985 | + // Should the next comment leader be left alone? | |
986 | + // Yes. | |
987 | + | |
988 | + /* Here the comment leader should be left intact. */ | |
989 | + // And so should this one. | |
990 | + | |
991 | + /* Here the comment leader should be left intact. */ | |
992 | + // And so should this one. | |
993 | + | |
994 | + if (condition) // Remove the next comment leader! | |
995 | + // OK, I will. | |
996 | + action(); | |
997 | + | |
998 | + if (condition) // Remove the next comment leader! | |
999 | + // OK, I will. | |
1000 | + action(); | |
1001 | + | |
1002 | + int i = 7 /* foo *// 3 | |
1003 | + // comment | |
1004 | + ; | |
1005 | + | |
1006 | + int i = 7 /* foo *// 3 | |
1007 | + // comment | |
1008 | + ; | |
1009 | + | |
1010 | + ># Note that the last character of the ending comment leader (left angle | |
1011 | + # bracket) is a comment leader itself. Make sure that this comment leader is | |
1012 | + # not removed from the next line #< | |
1013 | + < On this line a new comment is opened which spans 2 lines. This comment should | |
1014 | + < retain its comment leader. | |
1015 | + | |
1016 | + ># Note that the last character of the ending comment leader (left angle | |
1017 | + # bracket) is a comment leader itself. Make sure that this comment leader is | |
1018 | + # not removed from the next line #< | |
1019 | + < On this line a new comment is opened which spans 2 lines. This comment should | |
1020 | + < retain its comment leader. | |
1021 | + | |
1022 | + } | |
1023 | + | |
1024 | + STARTTEST | |
1025 | + :g/^STARTTEST/.,/^ENDTEST/d | |
1026 | + :?firstline?+1,$w! test.out | |
1027 | + :qa! | |
1028 | + ENDTEST | |
1029 | *** ../vim-7.3.540/src/testdir/test29.ok 2010-08-15 21:57:29.000000000 +0200 | |
1030 | --- src/testdir/test29.ok 2012-06-06 13:00:29.000000000 +0200 | |
1031 | *************** | |
1032 | *** 47,49 **** | |
1033 | --- 47,86 ---- | |
1034 | asdfasdf asdf | |
1035 | asdfasdf asdf | |
1036 | zx cvn. as dfg? hjkl iop! ert a | |
1037 | + | |
1038 | + | |
1039 | + { | |
1040 | + /* Make sure the previous comment leader is not removed. */ | |
1041 | + /* Make sure the previous comment leader is not removed. */ | |
1042 | + // Should the next comment leader be left alone? Yes. | |
1043 | + // Should the next comment leader be left alone? Yes. | |
1044 | + /* Here the comment leader should be left intact. */ // And so should this one. | |
1045 | + /* Here the comment leader should be left intact. */ // And so should this one. | |
1046 | + if (condition) // Remove the next comment leader! OK, I will. | |
1047 | + action(); | |
1048 | + if (condition) // Remove the next comment leader! OK, I will. | |
1049 | + action(); | |
1050 | + } | |
1051 | + | |
1052 | + | |
1053 | + { | |
1054 | + /* Make sure the previous comment leader is not removed. */ | |
1055 | + /* Make sure the previous comment leader is not removed. */ | |
1056 | + // Should the next comment leader be left alone? Yes. | |
1057 | + // Should the next comment leader be left alone? Yes. | |
1058 | + /* Here the comment leader should be left intact. */ // And so should this one. | |
1059 | + /* Here the comment leader should be left intact. */ // And so should this one. | |
1060 | + if (condition) // Remove the next comment leader! OK, I will. | |
1061 | + action(); | |
1062 | + if (condition) // Remove the next comment leader! OK, I will. | |
1063 | + action(); | |
1064 | + int i = 7 /* foo *// 3 // comment | |
1065 | + ; | |
1066 | + int i = 7 /* foo *// 3 // comment | |
1067 | + ; | |
1068 | + ># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader. | |
1069 | + ># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader. | |
1070 | + | |
1071 | + Some code!// Make sure backspacing does not remove this comment leader. | |
1072 | + } | |
1073 | + | |
1074 | *** ../vim-7.3.540/src/version.c 2012-06-06 12:06:10.000000000 +0200 | |
1075 | --- src/version.c 2012-06-06 16:10:03.000000000 +0200 | |
1076 | *************** | |
1077 | *** 716,717 **** | |
1078 | --- 716,719 ---- | |
1079 | { /* Add new patch number below this line */ | |
1080 | + /**/ | |
1081 | + 541, | |
1082 | /**/ | |
1083 | ||
1084 | -- | |
1085 | I have a drinking problem -- I don't have a drink! | |
1086 | ||
1087 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
1088 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
1089 | \\\ an exciting new programming language -- http://www.Zimbu.org /// | |
1090 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |