diff options
author | Bram Moolenaar <Bram@vim.org> | 2012-06-06 16:12:59 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2012-06-06 16:12:59 +0200 |
commit | 8134039744ffa581f7c217df58131b709317c1c8 (patch) | |
tree | f8fd1cddb2359407b77c3b9a494a27a451e6378c /src/misc1.c | |
parent | bc256d91eadb8f32d6a5833c1878684d3c75fb2d (diff) | |
download | vim-git-8134039744ffa581f7c217df58131b709317c1c8.tar.gz |
updated for version 7.3.541v7.3.541
Problem: When joining lines comment leaders need to be removed manually.
Solution: Add the 'j' flag to 'formatoptions'. (Lech Lorens)
Diffstat (limited to 'src/misc1.c')
-rw-r--r-- | src/misc1.c | 166 |
1 files changed, 160 insertions, 6 deletions
diff --git a/src/misc1.c b/src/misc1.c index 8588411df..7ba397279 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -671,7 +671,7 @@ open_line(dir, flags, old_indent) ptr = saved_line; # ifdef FEAT_COMMENTS if (flags & OPENLINE_DO_COM) - lead_len = get_leader_len(ptr, NULL, FALSE); + lead_len = get_leader_len(ptr, NULL, FALSE, TRUE); else lead_len = 0; # endif @@ -693,7 +693,7 @@ open_line(dir, flags, old_indent) } # ifdef FEAT_COMMENTS if (flags & OPENLINE_DO_COM) - lead_len = get_leader_len(ptr, NULL, FALSE); + lead_len = get_leader_len(ptr, NULL, FALSE, TRUE); else lead_len = 0; if (lead_len > 0) @@ -836,7 +836,7 @@ open_line(dir, flags, old_indent) */ end_comment_pending = NUL; if (flags & OPENLINE_DO_COM) - lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD); + lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD, TRUE); else lead_len = 0; if (lead_len > 0) @@ -1548,14 +1548,18 @@ theend: * When "flags" is not NULL, it is set to point to the flags of the recognized * comment leader. * "backward" must be true for the "O" command. + * If "include_space" is set, include trailing whitespace while calculating the + * length. */ int -get_leader_len(line, flags, backward) +get_leader_len(line, flags, backward, include_space) char_u *line; char_u **flags; int backward; + int include_space; { int i, j; + int result; int got_com = FALSE; int found_one; char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */ @@ -1565,7 +1569,7 @@ get_leader_len(line, flags, backward) char_u *prev_list; char_u *saved_flags = NULL; - i = 0; + result = i = 0; while (vim_iswhite(line[i])) /* leading white space is ignored */ ++i; @@ -1668,17 +1672,167 @@ get_leader_len(line, flags, backward) if (!found_one) break; + result = i; + /* Include any trailing white space. */ while (vim_iswhite(line[i])) ++i; + if (include_space) + result = i; + /* If this comment doesn't nest, stop here. */ got_com = TRUE; if (vim_strchr(part_buf, COM_NEST) == NULL) break; } + return result; +} + +/* + * Return the offset at which the last comment in line starts. If there is no + * comment in the whole line, -1 is returned. + * + * When "flags" is not null, it is set to point to the flags describing the + * recognized comment leader. + */ + int +get_last_leader_offset(line, flags) + char_u *line; + char_u **flags; +{ + int result = -1; + int i, j; + int lower_check_bound = 0; + char_u *string; + char_u *com_leader; + char_u *com_flags; + char_u *list; + int found_one; + char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */ + + /* + * Repeat to match several nested comment strings. + */ + i = (int)STRLEN(line); + while (--i >= lower_check_bound) + { + /* + * scan through the 'comments' option for a match + */ + found_one = FALSE; + for (list = curbuf->b_p_com; *list; ) + { + char_u *flags_save = list; + + /* + * Get one option part into part_buf[]. Advance list to next one. + * put string at start of string. + */ + (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ","); + string = vim_strchr(part_buf, ':'); + if (string == NULL) /* If everything is fine, this cannot actually + * happen. */ + { + continue; + } + *string++ = NUL; /* Isolate flags from string. */ + com_leader = string; - return (got_com ? i : 0); + /* + * Line contents and string must match. + * When string starts with white space, must have some white space + * (but the amount does not need to match, there might be a mix of + * TABs and spaces). + */ + if (vim_iswhite(string[0])) + { + if (i == 0 || !vim_iswhite(line[i - 1])) + continue; + while (vim_iswhite(string[0])) + ++string; + } + for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j) + /* do nothing */; + if (string[j] != NUL) + continue; + + /* + * When 'b' flag used, there must be white space or an + * end-of-line after the string in the line. + */ + if (vim_strchr(part_buf, COM_BLANK) != NULL + && !vim_iswhite(line[i + j]) && line[i + j] != NUL) + { + continue; + } + + /* + * We have found a match, stop searching. + */ + found_one = TRUE; + + if (flags) + *flags = flags_save; + com_flags = flags_save; + + break; + } + + if (found_one) + { + char_u part_buf2[COM_MAX_LEN]; /* buffer for one option part */ + int len1, len2, off; + + result = i; + /* + * If this comment nests, continue searching. + */ + if (vim_strchr(part_buf, COM_NEST) != NULL) + continue; + + lower_check_bound = i; + + /* Let's verify whether the comment leader found is a substring + * of other comment leaders. If it is, let's adjust the + * lower_check_bound so that we make sure that we have determined + * the comment leader correctly. + */ + + while (vim_iswhite(*com_leader)) + ++com_leader; + len1 = (int)STRLEN(com_leader); + + for (list = curbuf->b_p_com; *list; ) + { + char_u *flags_save = list; + + (void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ","); + if (flags_save == com_flags) + continue; + string = vim_strchr(part_buf2, ':'); + ++string; + while (vim_iswhite(*string)) + ++string; + len2 = (int)STRLEN(string); + if (len2 == 0) + continue; + + /* Now we have to verify whether string ends with a substring + * beginning the com_leader. */ + for (off = (len2 > i ? i : len2); off > 0 && off + len1 > len2;) + { + --off; + if (!STRNCMP(string + off, com_leader, len2 - off)) + { + if (i - off < lower_check_bound) + lower_check_bound = i - off; + } + } + } + } + } + return result; } #endif |