To: vim-dev@vim.org Subject: Patch 6.2.504 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.504 Problem: Various problems with 'cindent', among which that a list of variable declarations is not indented properly. Solution: Fix the wrong indenting. Improve indenting of C++ methods. Add the 'i', 'b' and 'W' options to 'cinoptions'. (mostly by Helmut Stiegler) Improve indenting of preprocessor-continuation lines. Files: runtime/doc/indent.txt, src/misc1.c, src/testdir/test3.in, src/testdir/test3.ok *** ../vim-6.2.503/runtime/doc/indent.txt Sun Jun 1 12:20:33 2003 --- runtime/doc/indent.txt Sun Apr 25 11:57:22 2004 *************** *** 1,4 **** ! *indent.txt* For Vim version 6.2. Last change: 2003 May 04 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *indent.txt* For Vim version 6.2. Last change: 2004 Apr 25 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 228,234 **** a = a + 1; b = b + 1; < lN If N != 0 Vim will align with a case label instead of the ! statement after it. cino= cino=l1 > switch (a) { switch (a) { --- 228,234 ---- a = a + 1; b = b + 1; < lN If N != 0 Vim will align with a case label instead of the ! statement after it in the same line. cino= cino=l1 > switch (a) { switch (a) { *************** *** 236,241 **** --- 236,256 ---- break; break; } } < + bN If N != 0 Vim will align a final "break" with the case label, + so that case..break looks like a sort of block. (default: 0). + + cino= cino=b1 > + switch (x) switch(x) + { { + case 1: case 1: + a = b; a = b; + break; break; + + default: default: + a = 0; a = 0; + break; break; + } } + < gN Place C++ scope declarations N characters from the indent of the block they are in. (default 'shiftwidth'). A scope declaration can be "public:", "protected:" or "private:". *************** *** 271,276 **** --- 286,304 ---- int int int func() func() func() < + iN Indent C++ base class declarations and contructor + initializations, if they start in a new line (otherwise they + are aligned at the right side of the ':'). + (default 'shiftwidth'). + + cino= cino=i0 > + class MyClass : class MyClass : + public BaseClass public BaseClass + {} {} + MyClass::MyClass() : MyClass::MyClass() : + BaseClass(3) BaseClass(3) + {} {} + < +N Indent a continuation line (a line that spills onto the next) N additional characters. (default 'shiftwidth'). *************** *** 347,352 **** --- 375,394 ---- && ( c2 && ( c2 || c3)) || c3)) foo; foo; + < + WN When in unclosed parentheses and N is non-zero and either + using "(0" or "u0", respectively and the unclosed parentheses is + the last non-white character in its line and it is not the + closing parentheses, indent the following line N characters + relative to the outer context (i.e. start of the line or the + next unclosed parentheses). (default: 0). + + cino=(0 cino=(0,W4 > + a_long_line( a_long_line( + argument, argument, + argument); argument); + a_short_line(argument, a_short_line(argument, + argument); argument); < mN When N is non-zero, line up a line starting with a closing parentheses with the first character of the line with the *** ../vim-6.2.503/src/misc1.c Mon Apr 19 20:26:43 2004 --- src/misc1.c Mon Apr 26 18:58:23 2004 *************** *** 4351,4370 **** static char_u *after_label __ARGS((char_u *l)); static int get_indent_nolabel __ARGS((linenr_T lnum)); static int skip_label __ARGS((linenr_T, char_u **pp, int ind_maxcomment)); static int cin_ispreproc __ARGS((char_u *)); static int cin_iscomment __ARGS((char_u *)); static int cin_islinecomment __ARGS((char_u *)); ! static int cin_isterminated __ARGS((char_u *, int)); ! static int cin_isfuncdecl __ARGS((char_u *)); static int cin_isif __ARGS((char_u *)); static int cin_iselse __ARGS((char_u *)); static int cin_isdo __ARGS((char_u *)); static int cin_iswhileofdo __ARGS((char_u *, linenr_T, int)); ! static int cin_ends_in __ARGS((char_u *, char_u *)); static int cin_skip2pos __ARGS((pos_T *trypos)); static pos_T *find_start_brace __ARGS((int)); static pos_T *find_match_paren __ARGS((int, int)); ! static int find_last_paren __ARGS((char_u *l)); static int find_match __ARGS((int lookfor, linenr_T ourscope, int ind_maxparen, int ind_maxcomment)); /* --- 4351,4377 ---- static char_u *after_label __ARGS((char_u *l)); static int get_indent_nolabel __ARGS((linenr_T lnum)); static int skip_label __ARGS((linenr_T, char_u **pp, int ind_maxcomment)); + static int cin_first_id_amount __ARGS((void)); + static int cin_get_equal_amount __ARGS((linenr_T lnum)); static int cin_ispreproc __ARGS((char_u *)); + static int cin_ispreproc_cont __ARGS((char_u **pp, linenr_T *lnump)); static int cin_iscomment __ARGS((char_u *)); static int cin_islinecomment __ARGS((char_u *)); ! static int cin_isterminated __ARGS((char_u *, int, int)); ! static int cin_isinit __ARGS((void)); ! static int cin_isfuncdecl __ARGS((char_u **, linenr_T)); static int cin_isif __ARGS((char_u *)); static int cin_iselse __ARGS((char_u *)); static int cin_isdo __ARGS((char_u *)); static int cin_iswhileofdo __ARGS((char_u *, linenr_T, int)); ! static int cin_isbreak __ARGS((char_u *)); ! static int cin_is_cpp_baseclass __ARGS((char_u *line, colnr_T *col)); ! static int cin_ends_in __ARGS((char_u *, char_u *, char_u *)); static int cin_skip2pos __ARGS((pos_T *trypos)); static pos_T *find_start_brace __ARGS((int)); static pos_T *find_match_paren __ARGS((int, int)); ! static int corr_ind_maxparen __ARGS((int ind_maxparen, pos_T *startpos)); ! static int find_last_paren __ARGS((char_u *l, int start, int end)); static int find_match __ARGS((int lookfor, linenr_T ourscope, int ind_maxparen, int ind_maxcomment)); /* *************** *** 4503,4509 **** continue; curwin->w_cursor = cursor_save; ! if (cin_isterminated(line, TRUE) || cin_isscopedecl(line) || cin_iscase(line) || (cin_islabel_skip(&line) && cin_nocode(line))) --- 4510,4516 ---- continue; curwin->w_cursor = cursor_save; ! if (cin_isterminated(line, TRUE, FALSE) || cin_isscopedecl(line) || cin_iscase(line) || (cin_islabel_skip(&line) && cin_nocode(line))) *************** *** 4517,4522 **** --- 4524,4550 ---- } /* + * Recognize structure initialization and enumerations. + * Q&D-Implementation: + * check for "=" at end or "enum" at beginning of line. + */ + int + cin_isinit(void) + { + char_u *s; + + s = cin_skipcomment(ml_get_curline()); + + if (STRNCMP(s, "enum", 4) == 0 && !vim_isIDc(s[4])) + return TRUE; + + if (cin_ends_in(s, (char_u *)"=", (char_u *)"{")) + return TRUE; + + return FALSE; + } + + /* * Recognize a switch label: "case .*:" or "default:". */ int *************** *** 4677,4682 **** --- 4705,4808 ---- } /* + * Return the indent of the first variable name after a type in a declaration. + * int a, indent of "a" + * static struct foo b, indent of "b" + * enum bla c, indent of "c" + * Returns zero when it doesn't look like a declaration. + */ + static int + cin_first_id_amount() + { + char_u *line, *p, *s; + int len; + pos_T fp; + colnr_T col; + + line = ml_get_curline(); + p = skipwhite(line); + len = skiptowhite(p) - p; + if (len == 6 && STRNCMP(p, "static", 6) == 0) + { + p = skipwhite(p + 6); + len = skiptowhite(p) - p; + } + if (len == 6 && STRNCMP(p, "struct", 6) == 0) + p = skipwhite(p + 6); + else if (len == 4 && STRNCMP(p, "enum", 4) == 0) + p = skipwhite(p + 4); + else if ((len == 8 && STRNCMP(p, "unsigned", 8) == 0) + || (len == 6 && STRNCMP(p, "signed", 6) == 0)) + { + s = skipwhite(p + len); + if ((STRNCMP(s, "int", 3) == 0 && vim_iswhite(s[3])) + || (STRNCMP(s, "long", 4) == 0 && vim_iswhite(s[4])) + || (STRNCMP(s, "short", 5) == 0 && vim_iswhite(s[5])) + || (STRNCMP(s, "char", 4) == 0 && vim_iswhite(s[4]))) + p = s; + } + for (len = 0; vim_isIDc(p[len]); ++len) + ; + if (len == 0 || !vim_iswhite(p[len]) || cin_nocode(p)) + return 0; + + p = skipwhite(p + len); + fp.lnum = curwin->w_cursor.lnum; + fp.col = (colnr_T)(p - line); + getvcol(curwin, &fp, &col, NULL, NULL); + return (int)col; + } + + /* + * Return the indent of the first non-blank after an equal sign. + * char *foo = "here"; + * Return zero if no (useful) equal sign found. + * Return -1 if the line above "lnum" ends in a backslash. + * foo = "asdf\ + * asdf\ + * here"; + */ + static int + cin_get_equal_amount(lnum) + linenr_T lnum; + { + char_u *line; + char_u *s; + colnr_T col; + pos_T fp; + + if (lnum > 1) + { + line = ml_get(lnum - 1); + if (*line != NUL && line[STRLEN(line) - 1] == '\\') + return -1; + } + + line = s = ml_get(lnum); + while (*s != NUL && vim_strchr((char_u *)"=;{}\"'", *s) == NULL) + { + if (cin_iscomment(s)) /* ignore comments */ + s = cin_skipcomment(s); + else + ++s; + } + if (*s != '=') + return 0; + + s = skipwhite(s + 1); + if (cin_nocode(s)) + return 0; + + if (*s == '"') /* nice alignment for continued strings */ + ++s; + + fp.lnum = lnum; + fp.col = (colnr_T)(s - line); + getvcol(curwin, &fp, &col, NULL, NULL); + return (int)col; + } + + /* * Recognize a preprocessor statement: Any line that starts with '#'. */ static int *************** *** 4690,4695 **** --- 4816,4855 ---- } /* + * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a + * continuation line of a preprocessor statement. Decrease "*lnump" to the + * start and return the line in "*pp". + */ + static int + cin_ispreproc_cont(pp, lnump) + char_u **pp; + linenr_T *lnump; + { + char_u *line = *pp; + linenr_T lnum = *lnump; + int retval = FALSE; + + while (1) + { + if (cin_ispreproc(line)) + { + retval = TRUE; + *lnump = lnum; + break; + } + if (lnum == 1) + break; + line = ml_get(--lnum); + if (*line == NUL || line[STRLEN(line) - 1] != '\\') + break; + } + + if (lnum != *lnump) + *pp = ml_get(*lnump); + return retval; + } + + /* * Recognize the start of a C or C++ comment. */ static int *************** *** 4712,4752 **** /* * Recognize a line that starts with '{' or '}', or ends with ';', '{' or '}'. * Don't consider "} else" a terminated line. ! * Also consider a line terminated if it ends in ','. This is not 100% ! * correct, but this mostly means we are in initializations and then it's OK. */ static int ! cin_isterminated(s, incl_open) char_u *s; int incl_open; /* include '{' at the end as terminator */ { s = cin_skipcomment(s); if (*s == '{' || (*s == '}' && !cin_iselse(s))) ! return TRUE; while (*s) { /* skip over comments, "" strings and 'c'haracters */ s = skip_string(cin_skipcomment(s)); ! if ((*s == ';' || (incl_open && *s == '{') || *s == '}' || *s == ',') ! && cin_nocode(s + 1)) ! return TRUE; if (*s) s++; } ! return FALSE; } /* * Recognize the basic picture of a function declaration -- it needs to * have an open paren somewhere and a close paren at the end of the line and * no semicolons anywhere. */ static int ! cin_isfuncdecl(s) ! char_u *s; { while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"') { if (cin_iscomment(s)) /* ignore comments */ --- 4872,4931 ---- /* * Recognize a line that starts with '{' or '}', or ends with ';', '{' or '}'. * Don't consider "} else" a terminated line. ! * Return the character terminating the line (ending char's have precedence if ! * both apply in order to determine initializations). */ static int ! cin_isterminated(s, incl_open, incl_comma) char_u *s; int incl_open; /* include '{' at the end as terminator */ + int incl_comma; /* recognize a trailing comma */ { + char_u found_start = 0; + s = cin_skipcomment(s); if (*s == '{' || (*s == '}' && !cin_iselse(s))) ! found_start = *s; while (*s) { /* skip over comments, "" strings and 'c'haracters */ s = skip_string(cin_skipcomment(s)); ! if ((*s == ';' || (incl_open && *s == '{') || *s == '}' ! || (incl_comma && *s == ',')) ! && cin_nocode(s + 1)) ! return *s; ! if (*s) s++; } ! return found_start; } /* * Recognize the basic picture of a function declaration -- it needs to * have an open paren somewhere and a close paren at the end of the line and * no semicolons anywhere. + * When a line ends in a comma we continue looking in the next line. + * "sp" points to a string with the line. When looking at other lines it must + * be restored to the line. When it's NULL fetch lines here. + * "lnum" is where we start looking. */ static int ! cin_isfuncdecl(sp, first_lnum) ! char_u **sp; ! linenr_T first_lnum; { + char_u *s; + linenr_T lnum = first_lnum; + int retval = FALSE; + + if (sp == NULL) + s = ml_get(lnum); + else + s = *sp; + while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"') { if (cin_iscomment(s)) /* ignore comments */ *************** *** 4760,4772 **** while (*s && *s != ';' && *s != '\'' && *s != '"') { if (*s == ')' && cin_nocode(s + 1)) ! return TRUE; ! if (cin_iscomment(s)) /* ignore comments */ s = cin_skipcomment(s); else ++s; } ! return FALSE; } static int --- 4939,4975 ---- while (*s && *s != ';' && *s != '\'' && *s != '"') { if (*s == ')' && cin_nocode(s + 1)) ! { ! /* ')' at the end: may have found a match ! * Check for he previous line not to end in a backslash: ! * #if defined(x) && \ ! * defined(y) ! */ ! lnum = first_lnum - 1; ! s = ml_get(lnum); ! if (*s == NUL || s[STRLEN(s) - 1] != '\\') ! retval = TRUE; ! goto done; ! } ! if (*s == ',' && cin_nocode(s + 1)) ! { ! /* ',' at the end: continue looking in the next line */ ! if (lnum >= curbuf->b_ml.ml_line_count) ! break; ! ! s = ml_get(++lnum); ! } ! else if (cin_iscomment(s)) /* ignore comments */ s = cin_skipcomment(s); else ++s; } ! ! done: ! if (lnum != first_lnum && sp != NULL) ! *sp = ml_get(first_lnum); ! ! return retval; } static int *************** *** 4829,4842 **** return retval; } /* * Return TRUE if string "s" ends with the string "find", possibly followed by * white space and comments. Skip strings and comments. */ static int ! cin_ends_in(s, find) char_u *s; char_u *find; { char_u *p = s; char_u *r; --- 5032,5150 ---- return retval; } + static int + cin_isbreak(p) + char_u *p; + { + return (STRNCMP(p, "break", 5) == 0 && !vim_isIDc(p[5])); + } + + /* Find the position of a C++ base-class declaration or + * constructor-initialization. eg: + * + * class MyClass : + * baseClass <-- here + * class MyClass : public baseClass, + * anotherBaseClass <-- here (should probably lineup ??) + * MyClass::MyClass(...) : + * baseClass(...) <-- here (constructor-initialization) + */ + static int + cin_is_cpp_baseclass(line, col) + char_u *line; + colnr_T *col; + { + char_u *s; + int class_or_struct, lookfor_ctor_init, cpp_base_class; + + *col = 0; + + s = cin_skipcomment(line); + if (*s == NUL) + return FALSE; + + cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE; + + while(*s != NUL) + { + if (s[0] == ':') + { + if (s[1] == ':') + { + /* skip double colon. It can't be a constructor + * initialization any more */ + lookfor_ctor_init = FALSE; + s = cin_skipcomment(s + 2); + } + else if (lookfor_ctor_init || class_or_struct) + { + /* we have something found, that looks like the start of + * cpp-base-class-declaration or contructor-initialization */ + cpp_base_class = TRUE; + lookfor_ctor_init = class_or_struct = FALSE; + *col = 0; + s = cin_skipcomment(s + 1); + } + else + s = cin_skipcomment(s + 1); + } + else if ((STRNCMP(s, "class", 5) == 0 && !vim_isIDc(s[5])) + || (STRNCMP(s, "struct", 6) == 0 && !vim_isIDc(s[6]))) + { + class_or_struct = TRUE; + lookfor_ctor_init = FALSE; + + if (*s == 'c') + s = cin_skipcomment(s + 5); + else + s = cin_skipcomment(s + 6); + } + else + { + if (s[0] == '{' || s[0] == '}' || s[0] == ';') + { + cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE; + } + else if (s[0] == ')') + { + /* Constructor-initialization is assumed if we come across + * something like "):" */ + class_or_struct = FALSE; + lookfor_ctor_init = TRUE; + } + else if (!vim_isIDc(s[0])) + { + /* if it is not an identifier, we are wrong */ + class_or_struct = FALSE; + lookfor_ctor_init = FALSE; + } + else if (*col == 0) + { + /* it can't be a constructor-initialization any more */ + lookfor_ctor_init = FALSE; + + /* the first statement starts here: lineup with this one... */ + if (cpp_base_class && *col == 0) + *col = (colnr_T)(s - line); + } + + s = cin_skipcomment(s + 1); + } + } + + return cpp_base_class; + } + /* * Return TRUE if string "s" ends with the string "find", possibly followed by * white space and comments. Skip strings and comments. + * Ignore "ignore" after "find" if it's not NULL. */ static int ! cin_ends_in(s, find, ignore) char_u *s; char_u *find; + char_u *ignore; { char_u *p = s; char_u *r; *************** *** 4848,4854 **** if (STRNCMP(p, find, len) == 0) { r = skipwhite(p + len); ! if (*r == NUL || cin_iscomment(r)) return TRUE; } if (*p != NUL) --- 5156,5164 ---- if (STRNCMP(p, find, len) == 0) { r = skipwhite(p + len); ! if (ignore != NULL && STRNCMP(r, ignore, STRLEN(ignore)) == 0) ! r = skipwhite(r + STRLEN(ignore)); ! if (cin_nocode(r)) return TRUE; } if (*p != NUL) *************** *** 4951,4974 **** } /* ! * Set w_cursor.col to the column number of the last ')' in line "l". */ static int ! find_last_paren(l) ! char_u *l; { ! int i; ! int retval = FALSE; curwin->w_cursor.col = 0; /* default is start of line */ for (i = 0; l[i]; i++) { i = (int)(skip_string(l + i) - l); /* ignore parens in quotes */ ! if (l[i] == ')') { ! curwin->w_cursor.col = i; ! retval = TRUE; } } return retval; --- 5261,5313 ---- } /* ! * Return ind_maxparen corrected for the difference in line number between the ! * cursor position and "startpos". This makes sure that searching for a ! * matching paren above the cursor line doesn't find a match because of ! * looking a few lines further. */ static int ! corr_ind_maxparen(ind_maxparen, startpos) ! int ind_maxparen; ! pos_T *startpos; { ! long n = (long)startpos->lnum - (long)curwin->w_cursor.lnum; ! ! if (n > 0 && n < ind_maxparen / 2) ! return ind_maxparen - (int)n; ! return ind_maxparen; ! } ! ! /* ! * Set w_cursor.col to the column number of the last unmatched ')' or '{' in ! * line "l". ! */ ! static int ! find_last_paren(l, start, end) ! char_u *l; ! int start, end; ! { ! int i; ! int retval = FALSE; ! int open_count = 0; curwin->w_cursor.col = 0; /* default is start of line */ for (i = 0; l[i]; i++) { + i = (int)(cin_skipcomment(l + i) - l); /* ignore parens in comments */ i = (int)(skip_string(l + i) - l); /* ignore parens in quotes */ ! if (l[i] == start) ! ++open_count; ! else if (l[i] == end) { ! if (open_count > 0) ! --open_count; ! else ! { ! curwin->w_cursor.col = i; ! retval = TRUE; ! } } } return retval; *************** *** 5030,5035 **** --- 5369,5379 ---- int ind_case_code = curbuf->b_p_sw; /* + * lineup break at end of case in switch() with case label + */ + int ind_case_break = 0; + + /* * spaces from the class declaration indent a scope declaration label * should be located */ *************** *** 5051,5056 **** --- 5395,5406 ---- int ind_func_type = curbuf->b_p_sw; /* + * amount a cpp base class declaration or constructor initialization + * should be indented + */ + int ind_cpp_baseclass = curbuf->b_p_sw; + + /* * additional spaces beyond the prevailing indent a continuation line * should be located */ *************** *** 5074,5079 **** --- 5424,5436 ---- int ind_unclosed_noignore = 0; /* + * If the opening paren is the last nonwhite character on the line, and + * ind_unclosed_wrapped is nonzero, use this indent relative to the outer + * context (for very long lines). + */ + int ind_unclosed_wrapped = 0; + + /* * suppress ignoring white space when lining up with the character after * an unclosed parentheses. */ *************** *** 5139,5145 **** --- 5496,5504 ---- linenr_T ourscope; char_u *l; char_u *look; + char_u terminated; int lookfor; + #define LOOKFOR_INITIAL 0 #define LOOKFOR_IF 1 #define LOOKFOR_DO 2 #define LOOKFOR_CASE 3 *************** *** 5147,5152 **** --- 5506,5515 ---- #define LOOKFOR_TERM 5 #define LOOKFOR_UNTERM 6 #define LOOKFOR_SCOPEDECL 7 + #define LOOKFOR_NOBREAK 8 + #define LOOKFOR_CPP_BASECLASS 9 + #define LOOKFOR_ENUM_OR_INIT 10 + int whilelevel; linenr_T lnum; char_u *options; *************** *** 5154,5159 **** --- 5517,5524 ---- int divider; int n; int iscase; + int lookfor_break; + int cont_amount = 0; /* amount for continuation line */ for (options = curbuf->b_p_cino; *options; ) { *************** *** 5201,5215 **** --- 5566,5583 ---- case '^': ind_open_left_imag = n; break; case ':': ind_case = n; break; case '=': ind_case_code = n; break; + case 'b': ind_case_break = n; break; case 'p': ind_param = n; break; case 't': ind_func_type = n; break; case '/': ind_comment = n; break; case 'c': ind_in_comment = n; break; case 'C': ind_in_comment2 = n; break; + case 'i': ind_cpp_baseclass = n; break; case '+': ind_continuation = n; break; case '(': ind_unclosed = n; break; case 'u': ind_unclosed2 = n; break; case 'U': ind_unclosed_noignore = n; break; + case 'W': ind_unclosed_wrapped = n; break; case 'w': ind_unclosed_whiteok = n; break; case 'm': ind_matching_paren = n; break; case ')': ind_maxparen = n; break; *************** *** 5454,5487 **** * a previous non-empty line that matches the same paren. */ amount = -1; our_paren_pos = *trypos; ! if (theline[0] != ')') { ! for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum) ! { ! l = skipwhite(ml_get(lnum)); ! if (cin_nocode(l)) /* skip comment lines */ ! continue; ! if (cin_ispreproc(l)) /* ignore #defines, #if, etc. */ ! continue; ! curwin->w_cursor.lnum = lnum; ! /* Skip a comment. XXX */ ! if ((trypos = find_start_comment(ind_maxcomment)) != NULL) ! { ! lnum = trypos->lnum + 1; ! continue; ! } ! /* XXX */ ! if ((trypos = find_match_paren(ind_maxparen, ! ind_maxcomment)) != NULL && ! trypos->lnum == our_paren_pos.lnum && ! trypos->col == our_paren_pos.col) ! { amount = get_indent_lnum(lnum); /* XXX */ ! break; ! } } } --- 5822,5861 ---- * a previous non-empty line that matches the same paren. */ amount = -1; + cur_amount = MAXCOL; our_paren_pos = *trypos; ! for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum) { ! l = skipwhite(ml_get(lnum)); ! if (cin_nocode(l)) /* skip comment lines */ ! continue; ! if (cin_ispreproc_cont(&l, &lnum)) /* ignore #defines, #if, etc. */ ! continue; ! curwin->w_cursor.lnum = lnum; ! /* Skip a comment. XXX */ ! if ((trypos = find_start_comment(ind_maxcomment)) != NULL) ! { ! lnum = trypos->lnum + 1; ! continue; ! } ! /* XXX */ ! if ((trypos = find_match_paren( ! corr_ind_maxparen(ind_maxparen, &cur_curpos), ! ind_maxcomment)) != NULL ! && trypos->lnum == our_paren_pos.lnum ! && trypos->col == our_paren_pos.col) ! { amount = get_indent_lnum(lnum); /* XXX */ ! ! if (theline[0] == ')') ! { ! if (our_paren_pos.lnum != lnum && cur_amount > amount) ! cur_amount = amount; ! amount = -1; ! } ! break; } } *************** *** 5493,5514 **** if (amount == -1) { amount = skip_label(our_paren_pos.lnum, &look, ind_maxcomment); - cur_amount = MAXCOL; if (theline[0] == ')' || ind_unclosed == 0 || (!ind_unclosed_noignore && *skipwhite(look) == '(')) { /* * If we're looking at a close paren, line up right there; * otherwise, line up with the next (non-white) character. */ if (theline[0] != ')') { ! if (ind_unclosed_whiteok) our_paren_pos.col++; else { col = our_paren_pos.col + 1; - l = ml_get(our_paren_pos.lnum); while (vim_iswhite(l[col])) col++; if (l[col] != NUL) /* In case of trailing space */ --- 5867,5917 ---- if (amount == -1) { amount = skip_label(our_paren_pos.lnum, &look, ind_maxcomment); if (theline[0] == ')' || ind_unclosed == 0 || (!ind_unclosed_noignore && *skipwhite(look) == '(')) { /* * If we're looking at a close paren, line up right there; * otherwise, line up with the next (non-white) character. + * When ind_unclosed_wrapped is set and the matching paren is + * the last nonwhite character of the line, use either the + * indent of the current line or the indentation of the next + * outer paren and add ind_unclosed_wrapped (for very long + * lines). */ if (theline[0] != ')') { ! cur_amount = MAXCOL; ! l = ml_get(our_paren_pos.lnum); ! if (ind_unclosed_wrapped ! && cin_ends_in(l, (char_u *)"(", NULL)) ! { ! /* look for opening unmatched paren, indent one level ! * for each additional level */ ! n = 1; ! for (col = 0; col < our_paren_pos.col; ++col) ! { ! switch (l[col]) ! { ! case '(': ! case '{': ++n; ! break; ! ! case ')': ! case '}': if (n > 1) ! --n; ! break; ! } ! } ! ! our_paren_pos.col = 0; ! amount += n * ind_unclosed_wrapped; ! } ! else if (ind_unclosed_whiteok) our_paren_pos.col++; else { col = our_paren_pos.col + 1; while (vim_iswhite(l[col])) col++; if (l[col] != NUL) /* In case of trailing space */ *************** *** 5522,5529 **** * Find how indented the paren is, or the character after it * if we did the above "if". */ ! getvcol(curwin, &our_paren_pos, &col, NULL, NULL); ! cur_amount = col; } if (theline[0] == ')' && ind_matching_paren) --- 5925,5936 ---- * Find how indented the paren is, or the character after it * if we did the above "if". */ ! if (our_paren_pos.col > 0) ! { ! getvcol(curwin, &our_paren_pos, &col, NULL, NULL); ! if (cur_amount > (int)col) ! cur_amount = col; ! } } if (theline[0] == ')' && ind_matching_paren) *************** *** 5532,5538 **** } else if (ind_unclosed == 0 || (!ind_unclosed_noignore && *skipwhite(look) == '(')) ! amount = cur_amount; else { /* add ind_unclosed2 for each '(' before our matching one */ --- 5939,5948 ---- } else if (ind_unclosed == 0 || (!ind_unclosed_noignore && *skipwhite(look) == '(')) ! { ! if (cur_amount != MAXCOL) ! amount = cur_amount; ! } else { /* add ind_unclosed2 for each '(' before our matching one */ *************** *** 5622,5629 **** * matching it will take us back to the start of the line. */ lnum = ourscope; ! if (find_last_paren(start) && ! (trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL) lnum = trypos->lnum; --- 6032,6039 ---- * matching it will take us back to the start of the line. */ lnum = ourscope; ! if (find_last_paren(start, '(', ')') ! && (trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL) lnum = trypos->lnum; *************** *** 5662,5674 **** * If we're looking at a "while", try to find a "do" * to match it with. */ ! lookfor = 0; if (cin_iselse(theline)) lookfor = LOOKFOR_IF; else if (cin_iswhileofdo(theline, cur_curpos.lnum, ind_maxparen)) /* XXX */ lookfor = LOOKFOR_DO; ! if (lookfor) { curwin->w_cursor.lnum = cur_curpos.lnum; if (find_match(lookfor, ourscope, ind_maxparen, --- 6072,6084 ---- * If we're looking at a "while", try to find a "do" * to match it with. */ ! lookfor = LOOKFOR_INITIAL; if (cin_iselse(theline)) lookfor = LOOKFOR_IF; else if (cin_iswhileofdo(theline, cur_curpos.lnum, ind_maxparen)) /* XXX */ lookfor = LOOKFOR_DO; ! if (lookfor != LOOKFOR_INITIAL) { curwin->w_cursor.lnum = cur_curpos.lnum; if (find_match(lookfor, ourscope, ind_maxparen, *************** *** 5709,5714 **** --- 6119,6126 ---- } } + lookfor_break = FALSE; + if (cin_iscase(theline)) /* it's a switch() label */ { lookfor = LOOKFOR_CASE; /* find a previous switch() label */ *************** *** 5721,5727 **** } else { ! lookfor = LOOKFOR_ANY; amount += ind_level; /* ind_level from start of block */ } scope_amount = amount; --- 6133,6142 ---- } else { ! if (ind_case_break && cin_isbreak(theline)) /* break; ... */ ! lookfor_break = TRUE; ! ! lookfor = LOOKFOR_INITIAL; amount += ind_level; /* ind_level from start of block */ } scope_amount = amount; *************** *** 5747,5755 **** */ if (curwin->w_cursor.lnum <= ourscope) { ! if (lookfor == LOOKFOR_UNTERM) ! amount += ind_continuation; ! else if (lookfor != LOOKFOR_TERM) { amount = scope_amount; if (theline[0] == '{') --- 6162,6282 ---- */ if (curwin->w_cursor.lnum <= ourscope) { ! /* we reached end of scope: ! * if looking for a enum or structure initialization ! * go further back: ! * if it is an initializer (enum xxx or xxx =), then ! * don't add ind_continuation, otherwise it is a variable ! * declaration: ! * int x, ! * here; <-- add ind_continuation ! */ ! if (lookfor == LOOKFOR_ENUM_OR_INIT) ! { ! if (curwin->w_cursor.lnum == 0 ! || curwin->w_cursor.lnum ! < ourscope - ind_maxparen) ! { ! /* nothing found (abuse ind_maxparen as limit) ! * assume terminated line (i.e. a variable ! * initialization) */ ! if (cont_amount > 0) ! amount = cont_amount; ! else ! amount += ind_continuation; ! break; ! } ! ! l = ml_get_curline(); ! ! /* ! * If we're in a comment now, skip to the start of the ! * comment. ! */ ! trypos = find_start_comment(ind_maxcomment); ! if (trypos != NULL) ! { ! curwin->w_cursor.lnum = trypos->lnum + 1; ! continue; ! } ! ! /* ! * Skip preprocessor directives and blank lines. ! */ ! if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) ! continue; ! ! if (cin_nocode(l)) ! continue; ! ! /* ! * If we are at top level and the line looks like a ! * function declaration, we are done ! * (it's a variable declaration). ! */ ! if (start_brace != BRACE_IN_COL0 ! || !cin_isfuncdecl(&l, curwin->w_cursor.lnum)) ! { ! terminated = cin_isterminated(l, FALSE, TRUE); ! ! /* if the line is terminated with another ',' ! * it is a continued variable initialization. ! * don't add extra indent. ! * TODO: does not work, if a function ! * declaration is split over multiple lines: ! * cin_isfuncdecl returns FALSE then. ! */ ! if (terminated == ',') ! break; ! ! /* if it es a enum declaration or an assignment, ! * we are done. ! */ ! if (terminated != ';' && cin_isinit()) ! break; ! ! /* nothing useful found */ ! if (terminated == 0 || terminated == '{') ! continue; ! } ! ! /* Skip parens and braces. Position the cursor over ! * the rightmost paren, so that matching it will take ! * us back to the start of the line. ! */ /* XXX */ ! trypos = NULL; ! if (find_last_paren(l, '(', ')')) ! trypos = find_match_paren(ind_maxparen, ! ind_maxcomment); ! ! if (trypos == NULL && find_last_paren(l, '{', '}')) ! trypos = find_start_brace(ind_maxcomment); ! ! if (trypos != NULL) ! { ! curwin->w_cursor.lnum = trypos->lnum + 1; ! continue; ! } ! ! /* it's a variable declaration, add indentation ! * like in ! * int a, ! * b; ! */ ! if (cont_amount > 0) ! amount = cont_amount; ! else ! amount += ind_continuation; ! } ! else if (lookfor == LOOKFOR_UNTERM) ! { ! if (cont_amount > 0) ! amount = cont_amount; ! else ! amount += ind_continuation; ! } ! else if (lookfor != LOOKFOR_TERM ! && lookfor != LOOKFOR_CPP_BASECLASS) { amount = scope_amount; if (theline[0] == '{') *************** *** 5776,5781 **** --- 6303,6313 ---- iscase = cin_iscase(l); if (iscase || cin_isscopedecl(l)) { + /* we are only looking for cpp base class + * declaration/initialization any longer */ + if (lookfor == LOOKFOR_CPP_BASECLASS) + break; + /* When looking for a "do" we are not interested in * labels. */ if (whilelevel > 0) *************** *** 5786,5794 **** * c = 99 + <- this indent plus continuation *-> here; */ ! if (lookfor == LOOKFOR_UNTERM) { ! amount += ind_continuation; break; } --- 6318,6330 ---- * c = 99 + <- this indent plus continuation *-> here; */ ! if (lookfor == LOOKFOR_UNTERM ! || lookfor == LOOKFOR_ENUM_OR_INIT) { ! if (cont_amount > 0) ! amount = cont_amount; ! else ! amount += ind_continuation; break; } *************** *** 5798,5803 **** --- 6334,6340 ---- * case yy: */ if ( (iscase && lookfor == LOOKFOR_CASE) + || (iscase && lookfor_break) || (!iscase && lookfor == LOOKFOR_SCOPEDECL)) { /* *************** *** 5829,5835 **** { if (n) amount = n; ! break; } /* --- 6366,6374 ---- { if (n) amount = n; ! ! if (!lookfor_break) ! break; } /* *************** *** 5858,5873 **** */ scope_amount = get_indent() + (iscase /* XXX */ ? ind_case_code : ind_scopedecl_code); ! lookfor = LOOKFOR_ANY; continue; } /* * Looking for a switch() label or C++ scope declaration, ! * ignore other lines. */ if (lookfor == LOOKFOR_CASE || lookfor == LOOKFOR_SCOPEDECL) continue; /* * Ignore jump labels with nothing after them. --- 6397,6417 ---- */ scope_amount = get_indent() + (iscase /* XXX */ ? ind_case_code : ind_scopedecl_code); ! lookfor = ind_case_break ? LOOKFOR_NOBREAK : LOOKFOR_ANY; continue; } /* * Looking for a switch() label or C++ scope declaration, ! * ignore other lines, skip {}-blocks. */ if (lookfor == LOOKFOR_CASE || lookfor == LOOKFOR_SCOPEDECL) + { + if (find_last_paren(l, '{', '}') && (trypos = + find_start_brace(ind_maxcomment)) != NULL) + curwin->w_cursor.lnum = trypos->lnum + 1; continue; + } /* * Ignore jump labels with nothing after them. *************** *** 5886,5898 **** * unlocked it) */ l = ml_get_curline(); ! if (cin_ispreproc(l) || cin_nocode(l)) continue; /* * What happens next depends on the line being terminated. */ ! if (!cin_isterminated(l, FALSE)) { /* * if we're in the middle of a paren thing, --- 6430,6496 ---- * unlocked it) */ l = ml_get_curline(); ! if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum) ! || cin_nocode(l)) continue; /* + * Are we at the start of a cpp base class declaration or + * constructor initialization? + */ /* XXX */ + if (lookfor != LOOKFOR_TERM && ind_cpp_baseclass + && cin_is_cpp_baseclass(l, &col)) + { + if (lookfor == LOOKFOR_UNTERM) + { + if (cont_amount > 0) + amount = cont_amount; + else + amount += ind_continuation; + } + else if (col == 0 || theline[0] == '{') + { + amount = get_indent(); + if (find_last_paren(l, '(', ')') + && (trypos = find_match_paren(ind_maxparen, + ind_maxcomment)) != NULL) + amount = get_indent_lnum(trypos->lnum); /* XXX */ + if (theline[0] != '{') + amount += ind_cpp_baseclass; + } + else + { + curwin->w_cursor.col = col; + getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL); + amount = (int)col; + } + break; + } + else if (lookfor == LOOKFOR_CPP_BASECLASS) + { + /* only look, whether there is a cpp base class + * declaration or initialization before the opening brace. */ + if (cin_isterminated(l, TRUE, FALSE)) + break; + else + continue; + } + + /* * What happens next depends on the line being terminated. + * If terminated with a ',' only consider it terminating if + * there is anoter unterminated statement behind, eg: + * 123, + * sizeof + * here + * Otherwise check whether it is a enumeration or structure + * initialisation (not indented) or a variable declaration + * (indented). */ ! terminated = cin_isterminated(l, FALSE, TRUE); ! ! if (terminated == 0 || (lookfor != LOOKFOR_UNTERM ! && terminated == ',')) { /* * if we're in the middle of a paren thing, *************** *** 5905,5913 **** * position the cursor over the rightmost paren, so that * matching it will take us back to the start of the line. */ ! (void)find_last_paren(l); ! if ((trypos = find_match_paren(ind_maxparen, ! ind_maxcomment)) != NULL) { /* * Check if we are on a case label now. This is --- 6503,6521 ---- * position the cursor over the rightmost paren, so that * matching it will take us back to the start of the line. */ ! (void)find_last_paren(l, '(', ')'); ! trypos = find_match_paren( ! corr_ind_maxparen(ind_maxparen, &cur_curpos), ! ind_maxcomment); ! ! /* ! * If we are looking for ',', we also look for matching ! * braces. ! */ ! if (trypos == NULL && find_last_paren(l, '{', '}')) ! trypos = find_start_brace(ind_maxcomment); ! ! if (trypos != NULL) { /* * Check if we are on a case label now. This is *************** *** 5925,5930 **** --- 6533,6556 ---- } /* + * Skip over continuation lines to find the one to get the + * indent from + * char *usethis = "bla\ + * bla", + * here; + */ + if (terminated == ',') + { + while (curwin->w_cursor.lnum > 1) + { + l = ml_get(curwin->w_cursor.lnum - 1); + if (*l == NUL || l[STRLEN(l) - 1] != '\\') + break; + --curwin->w_cursor.lnum; + } + } + + /* * Get indent and pointer to text for current line, * ignoring any jump label. XXX */ *************** *** 5938,5944 **** * -> { * } */ ! if (lookfor != LOOKFOR_TERM && theline[0] == '{') { amount = cur_amount; /* --- 6564,6571 ---- * -> { * } */ ! if (terminated != ',' && lookfor != LOOKFOR_TERM ! && theline[0] == '{') { amount = cur_amount; /* *************** *** 5950,5955 **** --- 6577,6590 ---- */ if (*skipwhite(l) != '{') amount += ind_open_extra; + + if (ind_cpp_baseclass) + { + /* have to look back, whether it is a cpp base + * class declaration or initialization */ + lookfor = LOOKFOR_CPP_BASECLASS; + continue; + } break; } *************** *** 5966,5974 **** * 100 + * -> here; */ ! if (lookfor == LOOKFOR_UNTERM) { ! amount += ind_continuation; break; } --- 6601,6613 ---- * 100 + * -> here; */ ! if (lookfor == LOOKFOR_UNTERM ! || lookfor == LOOKFOR_ENUM_OR_INIT) { ! if (cont_amount > 0) ! amount = cont_amount; ! else ! amount += ind_continuation; break; } *************** *** 6040,6056 **** * -> here; */ if (lookfor == LOOKFOR_UNTERM) break; ! /* ! * Found first unterminated line on a row, may line up ! * with this line, remember its indent ! * 100 + ! * -> here; ! */ ! amount = cur_amount; ! if (lookfor != LOOKFOR_TERM) ! lookfor = LOOKFOR_UNTERM; } } --- 6679,6750 ---- * -> here; */ if (lookfor == LOOKFOR_UNTERM) + { + /* When line ends in a comma add extra indent */ + if (terminated == ',') + amount += ind_continuation; break; + } ! if (lookfor == LOOKFOR_ENUM_OR_INIT) ! { ! /* Found two lines ending in ',', lineup with the ! * lowest one, but check for cpp base class ! * declaration/initialization, if it is an ! * opening brace or we are looking just for ! * enumerations/initializations. */ ! if (terminated == ',') ! { ! if (ind_cpp_baseclass == 0) ! break; ! ! lookfor = LOOKFOR_CPP_BASECLASS; ! continue; ! } ! ! /* Ignore unterminated lines in between, but ! * reduce indent. */ ! if (amount > cur_amount) ! amount = cur_amount; ! } ! else ! { ! /* ! * Found first unterminated line on a row, may ! * line up with this line, remember its indent ! * 100 + ! * -> here; ! */ ! amount = cur_amount; ! ! /* ! * If previous line ends in ',', check whether we ! * are in an initialization or enum ! * struct xxx = ! * { ! * sizeof a, ! * 124 }; ! * or a normal possible continuation line. ! * but only, of no other statement has been found ! * yet. ! */ ! if (lookfor == LOOKFOR_INITIAL && terminated == ',') ! { ! lookfor = LOOKFOR_ENUM_OR_INIT; ! cont_amount = cin_first_id_amount(); ! } ! else ! { ! if (lookfor == LOOKFOR_INITIAL ! && *l != NUL ! && l[STRLEN(l) - 1] == '\\') ! /* XXX */ ! cont_amount = cin_get_equal_amount( ! curwin->w_cursor.lnum); ! if (lookfor != LOOKFOR_TERM) ! lookfor = LOOKFOR_UNTERM; ! } ! } } } *************** *** 6069,6077 **** * 100 + <- line up with this one * -> here; */ ! if (lookfor == LOOKFOR_UNTERM) { ! amount += ind_continuation; break; } --- 6763,6775 ---- * 100 + <- line up with this one * -> here; */ ! if (lookfor == LOOKFOR_UNTERM ! || lookfor == LOOKFOR_ENUM_OR_INIT) { ! if (cont_amount > 0) ! amount = cont_amount; ! else ! amount += ind_continuation; break; } *************** *** 6095,6100 **** --- 6793,6809 ---- else { /* + * Skip single break line, if before a switch label. It + * may be lined up with the case label. + */ + if (lookfor == LOOKFOR_NOBREAK + && cin_isbreak(skipwhite(ml_get_curline()))) + { + lookfor = LOOKFOR_ANY; + continue; + } + + /* * Handle "do {" line. */ if (whilelevel > 0) *************** *** 6114,6123 **** * x = 1; * y = foo + * -> here; */ ! if (lookfor == LOOKFOR_UNTERM) { ! amount += ind_continuation; break; } --- 6823,6840 ---- * x = 1; * y = foo + * -> here; + * or + * int x = 1; + * int foo, + * -> here; */ ! if (lookfor == LOOKFOR_UNTERM ! || lookfor == LOOKFOR_ENUM_OR_INIT) { ! if (cont_amount > 0) ! amount = cont_amount; ! else ! amount += ind_continuation; break; } *************** *** 6132,6138 **** */ if (lookfor == LOOKFOR_TERM) { ! if (whilelevel == 0) break; } --- 6849,6855 ---- */ if (lookfor == LOOKFOR_TERM) { ! if (!lookfor_break && whilelevel == 0) break; } *************** *** 6153,6160 **** */ term_again: l = ml_get_curline(); ! if (find_last_paren(l) && ! (trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL) { /* --- 6870,6877 ---- */ term_again: l = ml_get_curline(); ! if (find_last_paren(l, '(', ')') ! && (trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL) { /* *************** *** 6254,6261 **** */ else if (cur_curpos.lnum < curbuf->b_ml.ml_line_count && !cin_nocode(theline) ! && cin_isfuncdecl(ml_get(cur_curpos.lnum + 1)) ! && !cin_isterminated(theline, FALSE)) { amount = ind_func_type; } --- 6971,6980 ---- */ else if (cur_curpos.lnum < curbuf->b_ml.ml_line_count && !cin_nocode(theline) ! && !cin_ends_in(theline, (char_u *)":", NULL) ! && !cin_ends_in(theline, (char_u *)",", NULL) ! && cin_isfuncdecl(NULL, cur_curpos.lnum + 1) ! && !cin_isterminated(theline, FALSE, TRUE)) { amount = ind_func_type; } *************** *** 6283,6293 **** } /* * If the line looks like a function declaration, and we're * not in a comment, put it the left margin. */ ! if (cin_isfuncdecl(theline)) break; /* * Finding the closing '}' of a previous function. Put --- 7002,7092 ---- } /* + * Are we at the start of a cpp base class declaration or constructor + * initialization? + */ /* XXX */ + if (ind_cpp_baseclass != 0 && theline[0] != '{' + && cin_is_cpp_baseclass(l, &col)) + { + if (col == 0) + { + amount = get_indent() + ind_cpp_baseclass; /* XXX */ + if (find_last_paren(l, '(', ')') + && (trypos = find_match_paren(ind_maxparen, + ind_maxcomment)) != NULL) + amount = get_indent_lnum(trypos->lnum) + + ind_cpp_baseclass; /* XXX */ + } + else + { + curwin->w_cursor.col = col; + getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL); + amount = (int)col; + } + break; + } + + /* + * Skip preprocessor directives and blank lines. + */ + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) + continue; + + if (cin_nocode(l)) + continue; + + /* + * If the previous line ends in ',', use one level of + * indentation: + * int foo, + * bar; + * do this before checking for '}' in case of eg. + * enum foobar + * { + * ... + * } foo, + * bar; + */ + n = 0; + if (cin_ends_in(l, (char_u *)",", NULL) + || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\')) + { + /* take us back to opening paren */ + if (find_last_paren(l, '(', ')') + && (trypos = find_match_paren(ind_maxparen, + ind_maxcomment)) != NULL) + curwin->w_cursor.lnum = trypos->lnum; + + /* For a line ending in ',' that is a continuation line go + * back to the first line with a backslash: + * char *foo = "bla\ + * bla", + * here; + */ + while (n == 0 && curwin->w_cursor.lnum > 1) + { + l = ml_get(curwin->w_cursor.lnum - 1); + if (*l == NUL || l[STRLEN(l) - 1] != '\\') + break; + --curwin->w_cursor.lnum; + } + + amount = get_indent(); /* XXX */ + + if (amount == 0) + amount = cin_first_id_amount(); + if (amount == 0) + amount = ind_continuation; + break; + } + + /* * If the line looks like a function declaration, and we're * not in a comment, put it the left margin. */ ! if (cin_isfuncdecl(NULL, cur_curpos.lnum)) /* XXX */ break; + l = ml_get_curline(); /* * Finding the closing '}' of a previous function. Put *************** *** 6302,6325 **** * char *string_array[] = { "foo", * / * x * / "b};ar" }; / * foobar * / */ ! if (cin_ends_in(l, (char_u *)"};")) break; /* - * Skip preprocessor directives and blank lines. - */ - if (cin_ispreproc(l)) - continue; - - if (cin_nocode(l)) - continue; - - /* * If the PREVIOUS line is a function declaration, the current * line (and the ones that follow) needs to be indented as * parameters. */ ! if (cin_isfuncdecl(l)) { amount = ind_param; break; --- 7101,7115 ---- * char *string_array[] = { "foo", * / * x * / "b};ar" }; / * foobar * / */ ! if (cin_ends_in(l, (char_u *)"};", NULL)) break; /* * If the PREVIOUS line is a function declaration, the current * line (and the ones that follow) needs to be indented as * parameters. */ ! if (cin_isfuncdecl(&l, curwin->w_cursor.lnum)) { amount = ind_param; break; *************** *** 6332,6369 **** * bar; * indent_to_0 here; */ ! if (cin_ends_in(l, (char_u*)";")) { l = ml_get(curwin->w_cursor.lnum - 1); ! if (cin_ends_in(l, (char_u *)",") || (*l != NUL && l[STRLEN(l) - 1] == '\\')) break; l = ml_get_curline(); } /* - * If the previous line ends in ',', use one level of - * indentation: - * int foo, - * bar; - */ - if (cin_ends_in(l, (char_u *)",") - || (*l != NUL && l[STRLEN(l) - 1] == '\\')) - { - amount = get_indent(); - if (amount == 0) - amount = ind_param; - break; - } - - /* * Doesn't look like anything interesting -- so just * use the indent of this line. * * Position the cursor over the rightmost paren, so that * matching it will take us back to the start of the line. */ ! find_last_paren(l); if ((trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL) --- 7122,7144 ---- * bar; * indent_to_0 here; */ ! if (cin_ends_in(l, (char_u*)";", NULL)) { l = ml_get(curwin->w_cursor.lnum - 1); ! if (cin_ends_in(l, (char_u *)",", NULL) || (*l != NUL && l[STRLEN(l) - 1] == '\\')) break; l = ml_get_curline(); } /* * Doesn't look like anything interesting -- so just * use the indent of this line. * * Position the cursor over the rightmost paren, so that * matching it will take us back to the start of the line. */ ! find_last_paren(l, '(', ')'); if ((trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL) *************** *** 6375,6380 **** --- 7150,7174 ---- /* add extra indent for a comment */ if (cin_iscomment(theline)) amount += ind_comment; + + /* add extra indent if the previous line ended in a backslash: + * "asdfasdf\ + * here"; + * char *foo = "asdf\ + * here"; + */ + if (cur_curpos.lnum > 1) + { + l = ml_get(cur_curpos.lnum - 1); + if (*l != NUL && l[STRLEN(l) - 1] == '\\') + { + cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1); + if (cur_amount > 0) + amount = cur_amount; + else if (cur_amount == 0) + amount += ind_continuation; + } + } } } *** ../vim-6.2.503/src/testdir/test3.in Sun May 4 13:29:30 2003 --- src/testdir/test3.in Mon Apr 26 16:56:42 2004 *************** *** 504,509 **** --- 504,513 ---- int indented; {} + char *a[] = {"aaa", "bbb", + "ccc", NULL}; + // here + char *tab[] = {"aaa", "xx", /* xx */}; /* asdf */ int not_indented; *************** *** 523,538 **** --- 527,709 ---- bar; int foo; + #if defined(foo) \ + && defined(bar) char * xx = "asdf\ foo\ bor"; int x; + char *foo = "asdf\ + asdf\ + asdf", + *bar; + + void f() + { + #if defined(foo) \ + && defined(bar) + char *foo = "asdf\ + asdf\ + asdf", + *bar; + { + int i; + char *foo = "asdf\ + asdf\ + asdf", + *bar; + } + #endif + } + #endif + int y; // comment // comment // comment + { + Constructor(int a, + int b ) : BaseClass(a) + { + } + } + + void foo() + { + char one, + two; + struct bla piet, + jan; + enum foo kees, + jannie; + static unsigned sdf, + krap; + unsigned int piet, + jan; + int + kees, + jan; + } + + { + t(int f, + int d); // ) + d(); + } + + Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b), + { + } + + Constructor::Constructor(int a, + int b ) : + BaseClass(a) + { + } + + Constructor::Constructor(int a, + int b ) /*x*/ : /*x*/ BaseClass(a), + member(b) + { + } + + class CAbc : + public BaseClass1, + protected BaseClass2 + { + int Test() { return FALSE; } + int Test1() { return TRUE; } + + CAbc(int a, int b ) : + BaseClass(a) + { + switch(xxx) + { + case abc: + asdf(); + break; + + case 999: + baer(); + break; + } + } + + public: // <-- this was incoreectly indented before!! + void testfall(); + protected: + void testfall(); + }; + + class CAbc : public BaseClass1, + protected BaseClass2 + { + }; + + static struct + { + int a; + int b; + } variable[COUNT] = + { + { + 123, + 456 + }, + { + 123, + 456 + } + }; + + static struct + { + int a; + int b; + } variable[COUNT] = + { + { 123, 456 }, + { 123, 456 } + }; + + void asdf() /* ind_maxparen may cause trouble here */ + { + if ((0 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1)) break; + } + /* end of AUTO */ STARTTEST *************** *** 900,905 **** --- 1071,1195 ---- c1 && c2 ) foo; + } + + STARTTEST + :set cino=b1 + 2kdd]]=][ + ENDTEST + + void f() + { + switch (x) + { + case 1: + a = b; + break; + default: + a = 0; + break; + } + } + + STARTTEST + :set cino=(0,W5 + 2kdd]]=][ + ENDTEST + + void f() + { + invokeme( + argu, + ment); + invokeme( + argu, + ment + ); + invokeme(argu, + ment + ); + } + + STARTTEST + :set cino=/6 + 2kdd]]=][ + ENDTEST + + void f() + { + statement; + // comment 1 + // comment 2 + } + + STARTTEST + :set cino= + 2kdd]]/comment 1/+1 + == + ENDTEST + + void f() + { + statement; + // comment 1 + // comment 2 + } + + STARTTEST + :set cino=g0 + 2kdd]]=][ + ENDTEST + + class CAbc + { + int Test() { return FALSE; } + + public: // comment + void testfall(); + protected: + void testfall(); + }; + + STARTTEST + :set cino=(0,W2s + 2kdd]]=][ + ENDTEST + + { + averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd( + asdasdf, + func(asdf, + asdfadsf), + asdfasdf + ); + + /* those are ugly, but consequent */ + + func()->asd(asdasdf, + averylongfunctionname( + abc, + dec)->averylongfunctionname( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf + ), + asdasdf + ); + + averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf( + abc, + dec)->asdfasdfasdf( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf), + asdasdf + ); } STARTTEST *** ../vim-6.2.503/src/testdir/test3.ok Sun May 4 13:29:34 2003 --- src/testdir/test3.ok Mon Apr 26 16:57:16 2004 *************** *** 492,497 **** --- 492,501 ---- int indented; {} + char *a[] = {"aaa", "bbb", + "ccc", NULL}; + // here + char *tab[] = {"aaa", "xx", /* xx */}; /* asdf */ int not_indented; *************** *** 511,526 **** bar; int foo; char * xx = "asdf\ ! foo\ ! bor"; int x; int y; // comment // comment // comment /* end of AUTO */ --- 515,697 ---- bar; int foo; + #if defined(foo) \ + && defined(bar) char * xx = "asdf\ ! foo\ ! bor"; int x; + char *foo = "asdf\ + asdf\ + asdf", + *bar; + + void f() + { + #if defined(foo) \ + && defined(bar) + char *foo = "asdf\ + asdf\ + asdf", + *bar; + { + int i; + char *foo = "asdf\ + asdf\ + asdf", + *bar; + } + #endif + } + #endif + int y; // comment // comment // comment + { + Constructor(int a, + int b ) : BaseClass(a) + { + } + } + + void foo() + { + char one, + two; + struct bla piet, + jan; + enum foo kees, + jannie; + static unsigned sdf, + krap; + unsigned int piet, + jan; + int + kees, + jan; + } + + { + t(int f, + int d); // ) + d(); + } + + Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b), + { + } + + Constructor::Constructor(int a, + int b ) : + BaseClass(a) + { + } + + Constructor::Constructor(int a, + int b ) /*x*/ : /*x*/ BaseClass(a), + member(b) + { + } + + class CAbc : + public BaseClass1, + protected BaseClass2 + { + int Test() { return FALSE; } + int Test1() { return TRUE; } + + CAbc(int a, int b ) : + BaseClass(a) + { + switch(xxx) + { + case abc: + asdf(); + break; + + case 999: + baer(); + break; + } + } + + public: // <-- this was incoreectly indented before!! + void testfall(); + protected: + void testfall(); + }; + + class CAbc : public BaseClass1, + protected BaseClass2 + { + }; + + static struct + { + int a; + int b; + } variable[COUNT] = + { + { + 123, + 456 + }, + { + 123, + 456 + } + }; + + static struct + { + int a; + int b; + } variable[COUNT] = + { + { 123, 456 }, + { 123, 456 } + }; + + void asdf() /* ind_maxparen may cause trouble here */ + { + if ((0 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1)) break; + } + /* end of AUTO */ *************** *** 802,806 **** --- 973,1071 ---- c1 && c2 ) foo; + } + + + void f() + { + switch (x) + { + case 1: + a = b; + break; + default: + a = 0; + break; + } + } + + + void f() + { + invokeme( + argu, + ment); + invokeme( + argu, + ment + ); + invokeme(argu, + ment + ); + } + + + void f() + { + statement; + // comment 1 + // comment 2 + } + + + void f() + { + statement; + // comment 1 + // comment 2 + } + + + class CAbc + { + int Test() { return FALSE; } + + public: // comment + void testfall(); + protected: + void testfall(); + }; + + + { + averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd( + asdasdf, + func(asdf, + asdfadsf), + asdfasdf + ); + + /* those are ugly, but consequent */ + + func()->asd(asdasdf, + averylongfunctionname( + abc, + dec)->averylongfunctionname( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf + ), + asdasdf + ); + + averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf( + abc, + dec)->asdfasdfasdf( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf), + asdasdf + ); } *** ../vim-6.2.503/src/version.c Mon Apr 26 12:37:27 2004 --- src/version.c Mon Apr 26 18:54:36 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 504, /**/ -- `The Guide says there is an art to flying,' said Ford, `or at least a knack. The knack lies in learning how to throw yourself at the ground and miss.' He smiled weakly. -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///