summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/edit.c46
-rw-r--r--src/misc1.c97
-rw-r--r--src/ops.c60
-rw-r--r--src/testdir/test68.in21
-rw-r--r--src/testdir/test68.ok12
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h2
7 files changed, 198 insertions, 42 deletions
diff --git a/src/edit.c b/src/edit.c
index 82e2b3b71..013fc5abc 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1463,7 +1463,7 @@ normalchar:
* what check_abbr() expects. */
(has_mbyte && c >= 0x100) ? (c + ABBR_OFF) :
#endif
- c) && c != Ctrl_RSB))
+ c) && c != Ctrl_RSB))
{
insert_special(c, FALSE, FALSE);
#ifdef FEAT_RIGHTLEFT
@@ -5769,6 +5769,16 @@ insert_special(c, allow_modmask, ctrlv)
# define WHITECHAR(cc) vim_iswhite(cc)
#endif
+/*
+ * "flags": INSCHAR_FORMAT - force formatting
+ * INSCHAR_CTRLV - char typed just after CTRL-V
+ * INSCHAR_NO_FEX - don't use 'formatexpr'
+ *
+ * NOTE: passes the flags value straight through to internal_format() which,
+ * beside INSCHAR_FORMAT (above), is also looking for these:
+ * INSCHAR_DO_COM - format comments
+ * INSCHAR_COM_LIST - format comments with num list or 2nd line indent
+ */
void
insertchar(c, flags, second_indent)
int c; /* character to insert or NUL */
@@ -6011,6 +6021,9 @@ insertchar(c, flags, second_indent)
/*
* Format text at the current insert position.
+ *
+ * If the INSCHAR_COM_LIST flag is present, then the value of second_indent
+ * will be the comment leader length sent to open_line().
*/
static void
internal_format(textwidth, second_indent, flags, format_only, c)
@@ -6289,23 +6302,36 @@ internal_format(textwidth, second_indent, flags, format_only, c)
+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
#ifdef FEAT_COMMENTS
+ (do_comments ? OPENLINE_DO_COM : 0)
+ + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
#endif
- , old_indent);
- old_indent = 0;
+ , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
+ if (!(flags & INSCHAR_COM_LIST))
+ old_indent = 0;
replace_offset = 0;
if (first_line)
{
- if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
- second_indent = get_number_indent(curwin->w_cursor.lnum -1);
- if (second_indent >= 0)
+ if (!(flags & INSCHAR_COM_LIST))
{
+ /*
+ * This section is for numeric lists w/o comments. If comment
+ * indents are needed with numeric lists (formatoptions=nq),
+ * then the INSCHAR_COM_LIST flag will cause the corresponding
+ * OPENLINE_COM_LIST flag to be passed through to open_line()
+ * (as seen above)...
+ */
+ if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
+ second_indent = get_number_indent(curwin->w_cursor.lnum -1);
+ if (second_indent >= 0)
+ {
#ifdef FEAT_VREPLACE
- if (State & VREPLACE_FLAG)
- change_indent(INDENT_SET, second_indent, FALSE, NUL, TRUE);
- else
+ if (State & VREPLACE_FLAG)
+ change_indent(INDENT_SET, second_indent,
+ FALSE, NUL, TRUE);
+ else
#endif
- (void)set_indent(second_indent, SIN_CHANGED);
+ (void)set_indent(second_indent, SIN_CHANGED);
+ }
}
first_line = FALSE;
}
diff --git a/src/misc1.c b/src/misc1.c
index 988e368d7..8029a1f54 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -423,27 +423,70 @@ get_number_indent(lnum)
{
colnr_T col;
pos_T pos;
- regmmatch_T regmatch;
if (lnum > curbuf->b_ml.ml_line_count)
return -1;
pos.lnum = 0;
- regmatch.regprog = vim_regcomp(curbuf->b_p_flp, RE_MAGIC);
- if (regmatch.regprog != NULL)
+
+#ifdef FEAT_COMMENTS
+ if (has_format_option(FO_Q_COMS) && has_format_option(FO_Q_NUMBER))
{
- regmatch.rmm_ic = FALSE;
- regmatch.rmm_maxcol = 0;
- if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
- (colnr_T)0, NULL))
+ regmatch_T regmatch;
+ int lead_len; /* length of comment leader */
+
+ lead_len = get_leader_len(ml_get(lnum), NULL, FALSE, TRUE);
+ regmatch.regprog = vim_regcomp(curbuf->b_p_flp, RE_MAGIC);
+ if (regmatch.regprog != NULL)
{
- pos.lnum = regmatch.endpos[0].lnum + lnum;
- pos.col = regmatch.endpos[0].col;
+ regmatch.rm_ic = FALSE;
+
+ /* vim_regexec() expects a pointer to a line. This lets us
+ * start matching for the flp beyond any comment leader... */
+ if (vim_regexec(&regmatch, ml_get(lnum) + lead_len, (colnr_T)0))
+ {
+ pos.lnum = lnum;
+ pos.col = *regmatch.endp - (ml_get(lnum) + lead_len);
+ pos.col += lead_len;
#ifdef FEAT_VIRTUALEDIT
- pos.coladd = 0;
+ pos.coladd = 0;
#endif
+ }
}
vim_free(regmatch.regprog);
}
+ else
+ {
+ /*
+ * What follows is the orig code that is not "comment aware"...
+ *
+ * I'm not sure if regmmatch_T (multi-match) is needed in this case.
+ * It may be true that this section would work properly using the
+ * regmatch_T code above, in which case, these two seperate sections
+ * should be consolidated w/ FEAT_COMMENTS making lead_len > 0...
+ */
+#endif
+ regmmatch_T regmatch;
+
+ regmatch.regprog = vim_regcomp(curbuf->b_p_flp, RE_MAGIC);
+
+ if (regmatch.regprog != NULL)
+ {
+ regmatch.rmm_ic = FALSE;
+ regmatch.rmm_maxcol = 0;
+ if (vim_regexec_multi(&regmatch, curwin, curbuf,
+ lnum, (colnr_T)0, NULL))
+ {
+ pos.lnum = regmatch.endpos[0].lnum + lnum;
+ pos.col = regmatch.endpos[0].col;
+#ifdef FEAT_VIRTUALEDIT
+ pos.coladd = 0;
+#endif
+ }
+ vim_free(regmatch.regprog);
+ }
+#ifdef FEAT_COMMENTS
+ }
+#endif
if (pos.lnum == 0 || *ml_get_pos(&pos) == NUL)
return -1;
@@ -502,14 +545,18 @@ cin_is_cinword(line)
* OPENLINE_DO_COM format comments
* OPENLINE_KEEPTRAIL keep trailing spaces
* OPENLINE_MARKFIX adjust mark positions after the line break
+ * OPENLINE_COM_LIST format comments with list or 2nd line indent
+ *
+ * "second_line_indent": indent for after ^^D in Insert mode or if flag
+ * OPENLINE_COM_LIST
*
* Return TRUE for success, FALSE for failure
*/
int
-open_line(dir, flags, old_indent)
+open_line(dir, flags, second_line_indent)
int dir; /* FORWARD or BACKWARD */
int flags;
- int old_indent; /* indent for after ^^D in Insert mode */
+ int second_line_indent;
{
char_u *saved_line; /* copy of the original line */
char_u *next_line = NULL; /* copy of the next line */
@@ -650,8 +697,8 @@ open_line(dir, flags, old_indent)
* count white space on current line
*/
newindent = get_indent_str(saved_line, (int)curbuf->b_p_ts);
- if (newindent == 0)
- newindent = old_indent; /* for ^^D command in insert mode */
+ if (newindent == 0 && !(flags & OPENLINE_COM_LIST))
+ newindent = second_line_indent; /* for ^^D command in insert mode */
#ifdef FEAT_SMARTINDENT
/*
@@ -1008,8 +1055,8 @@ open_line(dir, flags, old_indent)
if (lead_len)
{
/* allocate buffer (may concatenate p_exta later) */
- leader = alloc(lead_len + lead_repl_len + extra_space +
- extra_len + 1);
+ leader = alloc(lead_len + lead_repl_len + extra_space + extra_len
+ + (second_line_indent > 0 ? second_line_indent : 0));
allocated = leader; /* remember to free it later */
if (leader == NULL)
@@ -1304,6 +1351,20 @@ open_line(dir, flags, old_indent)
/* concatenate leader and p_extra, if there is a leader */
if (lead_len)
{
+ if (flags & OPENLINE_COM_LIST && second_line_indent > 0)
+ {
+ int i;
+ int padding = second_line_indent - (newindent + STRLEN(leader));
+
+ /* Here whitespace is inserted after the comment char.
+ * Below, set_indent(newindent, SIN_INSERT) will insert the
+ * whitespace needed before the comment char. */
+ for (i = 0; i < padding; i++)
+ {
+ STRCAT(leader, " ");
+ newcol++;
+ }
+ }
STRCAT(leader, p_extra);
p_extra = leader;
did_ai = TRUE; /* So truncating blanks works with comments */
@@ -4966,8 +5027,8 @@ add_pathsep(p)
char_u *
FullName_save(fname, force)
char_u *fname;
- int force; /* force expansion, even when it already looks
- like a full path name */
+ int force; /* force expansion, even when it already looks
+ * like a full path name */
{
char_u *buf;
char_u *new_fname = NULL;
diff --git a/src/ops.c b/src/ops.c
index 5383a7c6d..845211dff 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -1727,8 +1727,8 @@ op_delete(oap)
* and the delete is within one line. */
if ((
#ifdef FEAT_CLIPBOARD
- ((clip_unnamed & CLIP_UNNAMED) && oap->regname == '*') ||
- ((clip_unnamed & CLIP_UNNAMED_PLUS) && oap->regname == '+') ||
+ ((clip_unnamed & CLIP_UNNAMED) && oap->regname == '*') ||
+ ((clip_unnamed & CLIP_UNNAMED_PLUS) && oap->regname == '+') ||
#endif
oap->regname == 0) && oap->motion_type != MLINE
&& oap->line_count == 1)
@@ -4208,10 +4208,10 @@ dis_msg(p, skip_esc)
* "is_comment".
* line - line to be processed,
* process - if FALSE, will only check whether the line ends with an unclosed
- * comment,
+ * comment,
* include_space - whether to also skip space following the comment leader,
* is_comment - will indicate whether the current line ends with an unclosed
- * comment.
+ * comment.
*/
static char_u *
skip_comment(line, process, include_space, is_comment)
@@ -4723,9 +4723,11 @@ format_lines(line_count, avoid_fex)
char_u *leader_flags = NULL; /* flags for leader of current line */
char_u *next_leader_flags; /* flags for leader of next line */
int do_comments; /* format comments */
+ int do_comments_list = 0; /* format comments with 'n' or '2' */
#endif
int advance = TRUE;
- int second_indent = -1;
+ int second_indent = -1; /* indent for second line (comment
+ * aware) */
int do_second_indent;
int do_number_indent;
int do_trail_white;
@@ -4828,18 +4830,46 @@ format_lines(line_count, avoid_fex)
if (first_par_line
&& (do_second_indent || do_number_indent)
&& prev_is_end_par
- && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+ {
+ if (do_second_indent && !lineempty(curwin->w_cursor.lnum + 1))
+ {
#ifdef FEAT_COMMENTS
- && leader_len == 0
- && next_leader_len == 0
+ if (leader_len == 0 && next_leader_len == 0)
+ {
+ /* no comment found */
#endif
- )
- {
- if (do_second_indent
- && !lineempty(curwin->w_cursor.lnum + 1))
- second_indent = get_indent_lnum(curwin->w_cursor.lnum + 1);
+ second_indent =
+ get_indent_lnum(curwin->w_cursor.lnum + 1);
+#ifdef FEAT_COMMENTS
+ }
+ else
+ {
+ second_indent = next_leader_len;
+ do_comments_list = 1;
+ }
+#endif
+ }
else if (do_number_indent)
- second_indent = get_number_indent(curwin->w_cursor.lnum);
+ {
+#ifdef FEAT_COMMENTS
+ if (leader_len == 0 && next_leader_len == 0)
+ {
+ /* no comment found */
+#endif
+ second_indent =
+ get_number_indent(curwin->w_cursor.lnum);
+#ifdef FEAT_COMMENTS
+ }
+ else
+ {
+ /* get_number_indent() is now "comment aware"... */
+ second_indent =
+ get_number_indent(curwin->w_cursor.lnum);
+ do_comments_list = 1;
+ }
+#endif
+ }
}
/*
@@ -4878,6 +4908,8 @@ format_lines(line_count, avoid_fex)
insertchar(NUL, INSCHAR_FORMAT
#ifdef FEAT_COMMENTS
+ (do_comments ? INSCHAR_DO_COM : 0)
+ + (do_comments && do_comments_list
+ ? INSCHAR_COM_LIST : 0)
#endif
+ (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
State = old_State;
diff --git a/src/testdir/test68.in b/src/testdir/test68.in
index 8d0c501e2..068d6a098 100644
--- a/src/testdir/test68.in
+++ b/src/testdir/test68.in
@@ -51,6 +51,27 @@ a b
}
STARTTEST
+/^{/+1
+:set tw=5 fo=qn comments=:#
+gwap
+ENDTEST
+
+{
+# 1 a b
+}
+
+STARTTEST
+/^{/+1
+:set tw=5 fo=q2 comments=:#
+gwap
+ENDTEST
+
+{
+# x
+# a b
+}
+
+STARTTEST
/^{/+2
:set tw& fo=a
I^^
diff --git a/src/testdir/test68.ok b/src/testdir/test68.ok
index aebe36436..6808679e9 100644
--- a/src/testdir/test68.ok
+++ b/src/testdir/test68.ok
@@ -34,5 +34,17 @@ a b
}
+{
+# 1 a
+# b
+}
+
+
+{
+# x a
+# b
+}
+
+
{ 1aa ^^2bb }
diff --git a/src/version.c b/src/version.c
index 5e08bac52..91226cb91 100644
--- a/src/version.c
+++ b/src/version.c
@@ -715,6 +715,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 552,
+/**/
551,
/**/
550,
diff --git a/src/vim.h b/src/vim.h
index 41aba5d85..562c883b1 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1072,12 +1072,14 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
#define INSCHAR_DO_COM 2 /* format comments */
#define INSCHAR_CTRLV 4 /* char typed just after CTRL-V */
#define INSCHAR_NO_FEX 8 /* don't use 'formatexpr' */
+#define INSCHAR_COM_LIST 16 /* format comments with list/2nd line indent */
/* flags for open_line() */
#define OPENLINE_DELSPACES 1 /* delete spaces after cursor */
#define OPENLINE_DO_COM 2 /* format comments */
#define OPENLINE_KEEPTRAIL 4 /* keep trailing spaces */
#define OPENLINE_MARKFIX 8 /* fix mark positions */
+#define OPENLINE_COM_LIST 16 /* format comments with list/2nd line indent */
/*
* There are four history tables: