summaryrefslogtreecommitdiff
path: root/src/misc1.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2012-06-06 16:12:59 +0200
committerBram Moolenaar <Bram@vim.org>2012-06-06 16:12:59 +0200
commit8134039744ffa581f7c217df58131b709317c1c8 (patch)
treef8fd1cddb2359407b77c3b9a494a27a451e6378c /src/misc1.c
parentbc256d91eadb8f32d6a5833c1878684d3c75fb2d (diff)
downloadvim-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.c166
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