changeset 3454:214c7ec1c8f9 v7.3.492

updated for version 7.3.492 Problem: Can't indent conditions separately from function arguments. Solution: Add the 'k' flag in 'cino. (Lech Lorens)
author Bram Moolenaar <bram@vim.org>
date Thu, 05 Apr 2012 17:17:42 +0200
parents f2ce0c2b95b7
children 20d62dbedc0d
files runtime/doc/indent.txt src/misc1.c src/testdir/test3.in src/testdir/test3.ok src/version.c
diffstat 5 files changed, 513 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/indent.txt
+++ b/runtime/doc/indent.txt
@@ -460,6 +460,22 @@ The examples below assume a 'shiftwidth'
 		  a_short_line(argument,    a_short_line(argument,
 			       argument);		 argument);
 <
+							*cino-k*
+	kN    When in unclosed parentheses which follow "if", "for" or
+	      "while" and N is non-zero, overrides the behaviour defined by
+	      "(N": causes the indent to be N characters relative to the outer
+	      context (i.e. the line where "if", "for" or "while" is).  Has
+	      no effect on deeper levels of nesting.  Affects flags like "wN"
+	      only for the "if", "for" and "while" conditions.  If 0, defaults
+	      to behaviour defined by the "(N" flag.  (default: 0).
+
+		cino=(0			   cino=(0,ks >
+		  if (condition1	    if (condition1
+		      && condition2)		    && condition2)
+		      action();			action();
+		  function(argument1	    function(argument1
+			   && argument2);	     && argument2);
+<
 							*cino-m*
 	mN    When N is non-zero, line up a line starting with a closing
 	      parentheses with the first character of the line with the
@@ -530,14 +546,14 @@ The examples below assume a 'shiftwidth'
 
 								*cino-#*
 	#N    When N is non-zero recognize shell/Perl comments, starting with
-	      '#'.  Default N is zero: don't recognizes '#' comments.  Note
+	      '#'.  Default N is zero: don't recognize '#' comments.  Note
 	      that lines starting with # will still be seen as preprocessor
 	      lines.
 
 
 The defaults, spelled out in full, are:
 	cinoptions=>s,e0,n0,f0,{0,}0,^0,L-1,:s,=s,l0,b0,gs,hs,N0,ps,ts,is,+s,
-			c3,C0,/0,(2s,us,U0,w0,W0,m0,j0,J0,)20,*70,#0
+			c3,C0,/0,(2s,us,U0,w0,W0,k0,m0,j0,J0,)20,*70,#0
 
 Vim puts a line in column 1 if:
 - It starts with '#' (preprocessor directives), if 'cinkeys' contains '#'.
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -5771,6 +5771,52 @@ cin_iswhileofdo(p, lnum, ind_maxparen)	 
 }
 
 /*
+ * Check whether in "p" there is an "if", "for" or "while" before offset.
+ * Return 0 if there is none.
+ * Otherwise return !0 and update "*poffset" to point to the place where the
+ * string was found.
+ */
+    static int
+cin_is_if_for_while_before_offset(line, offset, poffset)
+    char_u *line;
+    size_t offset;
+    int    *poffset;
+{
+
+    if (offset-- < 2)
+	return 0;
+    while (offset > 2 && vim_iswhite(line[offset]))
+	--offset;
+
+    offset -= 1;
+    if (!STRNCMP(line + offset, "if", 2))
+	goto probablyFound;
+
+    if (offset >= 1)
+    {
+	offset -= 1;
+	if (!STRNCMP(line + offset, "for", 3))
+	    goto probablyFound;
+
+	if (offset >= 2)
+	{
+	    offset -= 2;
+	    if (!STRNCMP(line + offset, "while", 5))
+		goto probablyFound;
+	}
+    }
+
+    return 0;
+probablyFound:
+    if (!offset || !vim_isIDc(line[offset - 1]))
+    {
+	*poffset = offset;
+	return 1;
+    }
+    return 0;
+}
+
+/*
  * Return TRUE if we are at the end of a do-while.
  *    do
  *       nothing;
@@ -6124,7 +6170,7 @@ find_start_brace(ind_maxcomment)	    /* 
 
 /*
  * Find the matching '(', failing if it is in a comment.
- * Return NULL of no match found.
+ * Return NULL if no match found.
  */
     static pos_T *
 find_match_paren(ind_maxparen, ind_maxcomment)	    /* XXX */
@@ -6393,6 +6439,12 @@ get_c_indent()
      */
     int ind_cpp_namespace = 0;
 
+    /*
+     * handle continuation lines containing conditions of if(), for() and
+     * while()
+     */
+    int ind_if_for_while = 0;
+
     pos_T	cur_curpos;
     int		amount;
     int		scope_amount;
@@ -6437,6 +6489,7 @@ get_c_indent()
     int		cont_amount = 0;    /* amount for continuation line */
     int		original_line_islabel;
     int		added_to_amount = 0;
+    int		is_if_for_while = 0;
 
     for (options = curbuf->b_p_cino; *options; )
     {
@@ -6509,6 +6562,7 @@ get_c_indent()
 	    case 'l': ind_keep_case_label = n; break;
 	    case '#': ind_hash_comment = n; break;
 	    case 'N': ind_cpp_namespace = n; break;
+	    case 'k': ind_if_for_while = n; break;
 	}
 	if (*options == ',')
 	    ++options;
@@ -6812,6 +6866,35 @@ get_c_indent()
 	if (amount == -1)
 	{
 	    int	    ignore_paren_col = 0;
+	    int	    is_if_for_while = 0;
+
+	    if (ind_if_for_while)
+	    {
+		/* Look for the outermost opening parenthesis on this line
+		 * and check whether it belongs to an "if", "for" or "while". */
+
+		pos_T	    cursor_save = curwin->w_cursor;
+		pos_T	    outermost;
+		char_u	    *line;
+		int	    look_col;
+
+		trypos = &our_paren_pos;
+		do {
+		    outermost = *trypos;
+		    curwin->w_cursor.lnum = outermost.lnum;
+		    curwin->w_cursor.col = outermost.col;
+
+		    trypos = find_match_paren(ind_maxparen, ind_maxcomment);
+		} while (trypos && trypos->lnum == outermost.lnum);
+
+		curwin->w_cursor = cursor_save;
+
+		line = ml_get(outermost.lnum);
+
+		is_if_for_while =
+		    cin_is_if_for_while_before_offset(line, outermost.col,
+						      &outermost.col);
+	    }
 
 	    amount = skip_label(our_paren_pos.lnum, &look, ind_maxcomment);
 	    look = skipwhite(look);
@@ -6836,7 +6919,7 @@ get_c_indent()
 		curwin->w_cursor.lnum = save_lnum;
 		look = ml_get(our_paren_pos.lnum) + look_col;
 	    }
-	    if (theline[0] == ')' || ind_unclosed == 0
+	    if (theline[0] == ')' || (ind_unclosed == 0 && is_if_for_while == 0)
 		    || (!ind_unclosed_noignore && *look == '('
 						    && ignore_paren_col == 0))
 	    {
@@ -6907,7 +6990,8 @@ get_c_indent()
 	    {
 		/* Line up with the start of the matching paren line. */
 	    }
-	    else if (ind_unclosed == 0 || (!ind_unclosed_noignore
+	    else if ((ind_unclosed == 0 && is_if_for_while == 0)
+		     || (!ind_unclosed_noignore
 				    && *look == '(' && ignore_paren_col == 0))
 	    {
 		if (cur_amount != MAXCOL)
@@ -6943,7 +7027,12 @@ get_c_indent()
 		    if (find_match_paren(ind_maxparen, ind_maxcomment) != NULL)
 			amount += ind_unclosed2;
 		    else
-			amount += ind_unclosed;
+		    {
+			if (is_if_for_while)
+			    amount += ind_if_for_while;
+			else
+			    amount += ind_unclosed;
+		    }
 		}
 		/*
 		 * For a line starting with ')' use the minimum of the two
--- a/src/testdir/test3.in
+++ b/src/testdir/test3.in
@@ -1574,6 +1574,220 @@ baz();
 }
 
 STARTTEST
+:set cino=k2s,(0
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+	if (condition1
+	&& condition2)
+	action();
+	function(argument1
+	&& argument2);
+
+	if (c1 && (c2 ||
+	c3))
+	foo;
+	if (c1 &&
+	(c2 || c3))
+	{
+	}
+
+	if (   c1
+	&& (      c2
+	|| c3))
+	foo;
+	func( c1
+	&& (     c2
+	|| c3))
+	foo;
+}
+
+STARTTEST
+:set cino=k2s,(s
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+	if (condition1
+	&& condition2)
+	action();
+	function(argument1
+	&& argument2);
+
+	if (c1 && (c2 ||
+	c3))
+	foo;
+	if (c1 &&
+	(c2 || c3))
+	{
+	}
+
+	if (   c1
+	&& (      c2
+	|| c3))
+	foo;
+	func(   c1
+	&& (      c2
+	|| c3))
+	foo;
+}
+
+STARTTEST
+:set cino=k2s,(s,U1
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+	if (condition1
+	&& condition2)
+	action();
+	function(argument1
+	&& argument2);
+
+	if (c1 && (c2 ||
+	c3))
+	foo;
+	if (c1 &&
+	(c2 || c3))
+	{
+	}
+	if (c123456789
+	&& (c22345
+	|| c3))
+	printf("foo\n");
+
+	c = c1 &&
+	(
+	c2 ||
+	c3
+	) && c4;
+}
+
+STARTTEST
+:set cino=k2s,(0,W4
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+	if (condition1
+	&& condition2)
+	action();
+	function(argument1
+	&& argument2);
+
+	if (c1 && (c2 ||
+	c3))
+	foo;
+	if (c1 &&
+	(c2 || c3))
+	{
+	}
+	if (c123456789
+	&& (c22345
+	|| c3))
+	printf("foo\n");
+
+	if (   c1
+	&& (   c2
+	|| c3))
+	foo;
+
+	a_long_line(
+	argument,
+	argument);
+	a_short_line(argument,
+	argument);
+}
+
+STARTTEST
+:set cino=k2s,u2
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+	if (condition1
+	&& condition2)
+	action();
+	function(argument1
+	&& argument2);
+
+	if (c1 && (c2 ||
+	c3))
+	foo;
+	if (c1 &&
+	(c2 || c3))
+	{
+	}
+	if (c123456789
+	&& (c22345
+	|| c3))
+	printf("foo\n");
+}
+
+STARTTEST
+:set cino=k2s,(0,w1
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+	if (condition1
+	&& condition2)
+	action();
+	function(argument1
+	&& argument2);
+
+	if (c1 && (c2 ||
+	c3))
+	foo;
+	if (c1 &&
+	(c2 || c3))
+	{
+	}
+	if (c123456789
+	&& (c22345
+	|| c3))
+	printf("foo\n");
+
+	if (   c1
+	&& (      c2
+	|| c3))
+	foo;
+	func(   c1
+	&& (      c2
+	|| c3))
+	foo;
+}
+
+STARTTEST
+:set cino=k2,(s
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+	if (condition1
+	  && condition2)
+		action();
+	function(argument1
+		&& argument2);
+
+	if (c1 && (c2 ||
+		  c3))
+		foo;
+	if (c1 &&
+	  (c2 || c3))
+	{
+	}
+}
+
+STARTTEST
 :set cino=N-s
 /^NAMESPACESTART
 =/^NAMESPACEEND
--- a/src/testdir/test3.ok
+++ b/src/testdir/test3.ok
@@ -1411,6 +1411,192 @@ void func(void)
 }
 
 
+void func(void)
+{
+	if (condition1
+			&& condition2)
+		action();
+	function(argument1
+			 && argument2);
+
+	if (c1 && (c2 ||
+				c3))
+		foo;
+	if (c1 &&
+			(c2 || c3))
+	{
+	}
+
+	if (   c1
+			&& (      c2
+					  || c3))
+		foo;
+	func( c1
+		  && (     c2
+				   || c3))
+		foo;
+}
+
+
+void func(void)
+{
+	if (condition1
+			&& condition2)
+		action();
+	function(argument1
+		&& argument2);
+
+	if (c1 && (c2 ||
+				c3))
+		foo;
+	if (c1 &&
+			(c2 || c3))
+	{
+	}
+
+	if (   c1
+			&& (      c2
+				|| c3))
+		foo;
+	func(   c1
+		&& (      c2
+			|| c3))
+		foo;
+}
+
+
+void func(void)
+{
+	if (condition1
+			&& condition2)
+		action();
+	function(argument1
+		&& argument2);
+
+	if (c1 && (c2 ||
+				c3))
+		foo;
+	if (c1 &&
+			(c2 || c3))
+	{
+	}
+	if (c123456789
+			&& (c22345
+				|| c3))
+		printf("foo\n");
+
+	c = c1 &&
+		(
+			c2 ||
+			c3
+		) && c4;
+}
+
+
+void func(void)
+{
+	if (condition1
+			&& condition2)
+		action();
+	function(argument1
+			 && argument2);
+
+	if (c1 && (c2 ||
+				c3))
+		foo;
+	if (c1 &&
+			(c2 || c3))
+	{
+	}
+	if (c123456789
+			&& (c22345
+				|| c3))
+		printf("foo\n");
+
+	if (   c1
+			&& (   c2
+				   || c3))
+		foo;
+
+	a_long_line(
+		argument,
+		argument);
+	a_short_line(argument,
+				 argument);
+}
+
+
+void func(void)
+{
+	if (condition1
+			&& condition2)
+		action();
+	function(argument1
+			&& argument2);
+
+	if (c1 && (c2 ||
+			  c3))
+		foo;
+	if (c1 &&
+			(c2 || c3))
+	{
+	}
+	if (c123456789
+			&& (c22345
+			  || c3))
+		printf("foo\n");
+}
+
+
+void func(void)
+{
+	if (condition1
+			&& condition2)
+		action();
+	function(argument1
+			 && argument2);
+
+	if (c1 && (c2 ||
+				c3))
+		foo;
+	if (c1 &&
+			(c2 || c3))
+	{
+	}
+	if (c123456789
+			&& (c22345
+				|| c3))
+		printf("foo\n");
+
+	if (   c1
+			&& (      c2
+				|| c3))
+		foo;
+	func(   c1
+		 && (      c2
+			 || c3))
+		foo;
+}
+
+
+void func(void)
+{
+	if (condition1
+	  && condition2)
+		action();
+	function(argument1
+		&& argument2);
+
+	if (c1 && (c2 ||
+		  c3))
+		foo;
+	if (c1 &&
+	  (c2 || c3))
+	{
+	}
+}
+
+
 NAMESPACESTART
 /* valid namespaces with normal indent */
 namespace
--- 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 */
 /**/
+    492,
+/**/
     491,
 /**/
     490,