Mercurial > vim
comparison src/misc1.c @ 6971:e859731ea1cd v7.4.803
patch 7.4.803
Problem: C indent does not support C11 raw strings. (Mark Lodato)
Solution: Do not change indent inside the raw string.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Tue, 28 Jul 2015 21:17:36 +0200 |
parents | 1e621b31948b |
children | 5f00b8d7148f |
comparison
equal
deleted
inserted
replaced
6970:589a962ecc16 | 6971:e859731ea1cd |
---|---|
5265 | 5265 |
5266 #if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL) | 5266 #if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL) |
5267 | 5267 |
5268 static char_u *skip_string __ARGS((char_u *p)); | 5268 static char_u *skip_string __ARGS((char_u *p)); |
5269 static pos_T *ind_find_start_comment __ARGS((void)); | 5269 static pos_T *ind_find_start_comment __ARGS((void)); |
5270 static pos_T *ind_find_start_CORS __ARGS((void)); | |
5271 static pos_T *find_start_rawstring __ARGS((int ind_maxcomment)); | |
5270 | 5272 |
5271 /* | 5273 /* |
5272 * Find the start of a comment, not knowing if we are in a comment right now. | 5274 * Find the start of a comment, not knowing if we are in a comment right now. |
5273 * Search starts at w_cursor.lnum and goes backwards. | 5275 * Search starts at w_cursor.lnum and goes backwards. |
5276 * Return NULL when not inside a comment. | |
5274 */ | 5277 */ |
5275 static pos_T * | 5278 static pos_T * |
5276 ind_find_start_comment() /* XXX */ | 5279 ind_find_start_comment() /* XXX */ |
5277 { | 5280 { |
5278 return find_start_comment(curbuf->b_ind_maxcomment); | 5281 return find_start_comment(curbuf->b_ind_maxcomment); |
5311 } | 5314 } |
5312 return pos; | 5315 return pos; |
5313 } | 5316 } |
5314 | 5317 |
5315 /* | 5318 /* |
5319 * Find the start of a comment or raw string, not knowing if we are in a | |
5320 * comment or raw string right now. | |
5321 * Search starts at w_cursor.lnum and goes backwards. | |
5322 * Return NULL when not inside a comment or raw string. | |
5323 * "CORS" -> Comment Or Raw String | |
5324 */ | |
5325 static pos_T * | |
5326 ind_find_start_CORS() /* XXX */ | |
5327 { | |
5328 pos_T *comment_pos = find_start_comment(curbuf->b_ind_maxcomment); | |
5329 pos_T *rs_pos = find_start_rawstring(curbuf->b_ind_maxcomment); | |
5330 | |
5331 /* If comment_pos is before rs_pos the raw string is inside the comment. | |
5332 * If rs_pos is before comment_pos the comment is inside the raw string. */ | |
5333 if (comment_pos == NULL || (rs_pos != NULL && lt(*rs_pos, *comment_pos))) | |
5334 return rs_pos; | |
5335 return comment_pos; | |
5336 } | |
5337 | |
5338 /* | |
5339 * Find the start of a raw string, not knowing if we are in one right now. | |
5340 * Search starts at w_cursor.lnum and goes backwards. | |
5341 * Return NULL when not inside a raw string. | |
5342 */ | |
5343 static pos_T * | |
5344 find_start_rawstring(ind_maxcomment) /* XXX */ | |
5345 int ind_maxcomment; | |
5346 { | |
5347 pos_T *pos; | |
5348 char_u *line; | |
5349 char_u *p; | |
5350 int cur_maxcomment = ind_maxcomment; | |
5351 | |
5352 for (;;) | |
5353 { | |
5354 pos = findmatchlimit(NULL, 'R', FM_BACKWARD, cur_maxcomment); | |
5355 if (pos == NULL) | |
5356 break; | |
5357 | |
5358 /* | |
5359 * Check if the raw string start we found is inside a string. | |
5360 * If it is then restrict the search to below this line and try again. | |
5361 */ | |
5362 line = ml_get(pos->lnum); | |
5363 for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p) | |
5364 p = skip_string(p); | |
5365 if ((colnr_T)(p - line) <= pos->col) | |
5366 break; | |
5367 cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1; | |
5368 if (cur_maxcomment <= 0) | |
5369 { | |
5370 pos = NULL; | |
5371 break; | |
5372 } | |
5373 } | |
5374 return pos; | |
5375 } | |
5376 | |
5377 /* | |
5316 * Skip to the end of a "string" and a 'c' character. | 5378 * Skip to the end of a "string" and a 'c' character. |
5317 * If there is no string or character, return argument unmodified. | 5379 * If there is no string or character, return argument unmodified. |
5318 */ | 5380 */ |
5319 static char_u * | 5381 static char_u * |
5320 skip_string(p) | 5382 skip_string(p) |
5352 ++p; | 5414 ++p; |
5353 else if (p[0] == '"') /* end of string */ | 5415 else if (p[0] == '"') /* end of string */ |
5354 break; | 5416 break; |
5355 } | 5417 } |
5356 if (p[0] == '"') | 5418 if (p[0] == '"') |
5357 continue; | 5419 continue; /* continue for another string */ |
5420 } | |
5421 else if (p[0] == 'R' && p[1] == '"') | |
5422 { | |
5423 /* Raw string: R"[delim](...)[delim]" */ | |
5424 char_u *delim = p + 2; | |
5425 char_u *paren = vim_strchr(delim, '('); | |
5426 | |
5427 if (paren != NULL) | |
5428 { | |
5429 size_t delim_len = paren - delim; | |
5430 | |
5431 for (p += 3; *p; ++p) | |
5432 if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0 | |
5433 && p[delim_len + 1] == '"') | |
5434 { | |
5435 p += delim_len + 1; | |
5436 break; | |
5437 } | |
5438 if (p[0] == '"') | |
5439 continue; /* continue for another string */ | |
5440 } | |
5358 } | 5441 } |
5359 break; /* no string found */ | 5442 break; /* no string found */ |
5360 } | 5443 } |
5361 if (!*p) | 5444 if (!*p) |
5362 --p; /* backup from NUL */ | 5445 --p; /* backup from NUL */ |
5594 while (curwin->w_cursor.lnum > 1) | 5677 while (curwin->w_cursor.lnum > 1) |
5595 { | 5678 { |
5596 --curwin->w_cursor.lnum; | 5679 --curwin->w_cursor.lnum; |
5597 | 5680 |
5598 /* | 5681 /* |
5599 * If we're in a comment now, skip to the start of the comment. | 5682 * If we're in a comment or raw string now, skip to the start of |
5683 * it. | |
5600 */ | 5684 */ |
5601 curwin->w_cursor.col = 0; | 5685 curwin->w_cursor.col = 0; |
5602 if ((trypos = ind_find_start_comment()) != NULL) /* XXX */ | 5686 if ((trypos = ind_find_start_CORS()) != NULL) /* XXX */ |
5603 curwin->w_cursor = *trypos; | 5687 curwin->w_cursor = *trypos; |
5604 | 5688 |
5605 line = ml_get_curline(); | 5689 line = ml_get_curline(); |
5606 if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */ | 5690 if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */ |
5607 continue; | 5691 continue; |
6452 s = cin_skipcomment(line); | 6536 s = cin_skipcomment(line); |
6453 if (*s == NUL) | 6537 if (*s == NUL) |
6454 continue; | 6538 continue; |
6455 } | 6539 } |
6456 | 6540 |
6457 if (s[0] == '"') | 6541 if (s[0] == '"' || (s[0] == 'R' && s[1] == '"')) |
6458 s = skip_string(s) + 1; | 6542 s = skip_string(s) + 1; |
6459 else if (s[0] == ':') | 6543 else if (s[0] == ':') |
6460 { | 6544 { |
6461 if (s[1] == ':') | 6545 if (s[1] == ':') |
6462 { | 6546 { |
6658 trypos = &pos_copy; | 6742 trypos = &pos_copy; |
6659 curwin->w_cursor = *trypos; | 6743 curwin->w_cursor = *trypos; |
6660 pos = NULL; | 6744 pos = NULL; |
6661 /* ignore the { if it's in a // or / * * / comment */ | 6745 /* ignore the { if it's in a // or / * * / comment */ |
6662 if ((colnr_T)cin_skip2pos(trypos) == trypos->col | 6746 if ((colnr_T)cin_skip2pos(trypos) == trypos->col |
6663 && (pos = ind_find_start_comment()) == NULL) /* XXX */ | 6747 && (pos = ind_find_start_CORS()) == NULL) /* XXX */ |
6664 break; | 6748 break; |
6665 if (pos != NULL) | 6749 if (pos != NULL) |
6666 curwin->w_cursor.lnum = pos->lnum; | 6750 curwin->w_cursor.lnum = pos->lnum; |
6667 } | 6751 } |
6668 curwin->w_cursor = cursor_save; | 6752 curwin->w_cursor = cursor_save; |
6712 pos_T *trypos_wk; | 6796 pos_T *trypos_wk; |
6713 | 6797 |
6714 pos_copy = *trypos; /* copy trypos, findmatch will change it */ | 6798 pos_copy = *trypos; /* copy trypos, findmatch will change it */ |
6715 trypos = &pos_copy; | 6799 trypos = &pos_copy; |
6716 curwin->w_cursor = *trypos; | 6800 curwin->w_cursor = *trypos; |
6717 if ((trypos_wk = ind_find_start_comment()) != NULL) /* XXX */ | 6801 if ((trypos_wk = ind_find_start_CORS()) != NULL) /* XXX */ |
6718 { | 6802 { |
6719 ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum | 6803 ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum |
6720 - trypos_wk->lnum); | 6804 - trypos_wk->lnum); |
6721 if (ind_maxp_wk > 0) | 6805 if (ind_maxp_wk > 0) |
6722 { | 6806 { |
7027 if (*p == ',') | 7111 if (*p == ',') |
7028 ++p; | 7112 ++p; |
7029 } | 7113 } |
7030 } | 7114 } |
7031 | 7115 |
7116 /* | |
7117 * Return the desired indent for C code. | |
7118 * Return -1 if the indent should be left alone (inside a raw string). | |
7119 */ | |
7032 int | 7120 int |
7033 get_c_indent() | 7121 get_c_indent() |
7034 { | 7122 { |
7035 pos_T cur_curpos; | 7123 pos_T cur_curpos; |
7036 int amount; | 7124 int amount; |
7038 int cur_amount = MAXCOL; | 7126 int cur_amount = MAXCOL; |
7039 colnr_T col; | 7127 colnr_T col; |
7040 char_u *theline; | 7128 char_u *theline; |
7041 char_u *linecopy; | 7129 char_u *linecopy; |
7042 pos_T *trypos; | 7130 pos_T *trypos; |
7131 pos_T *comment_pos; | |
7043 pos_T *tryposBrace = NULL; | 7132 pos_T *tryposBrace = NULL; |
7044 pos_T tryposBraceCopy; | 7133 pos_T tryposCopy; |
7045 pos_T our_paren_pos; | 7134 pos_T our_paren_pos; |
7046 char_u *start; | 7135 char_u *start; |
7047 int start_brace; | 7136 int start_brace; |
7048 #define BRACE_IN_COL0 1 /* '{' is in column 0 */ | 7137 #define BRACE_IN_COL0 1 /* '{' is in column 0 */ |
7049 #define BRACE_AT_START 2 /* '{' is at start of line */ | 7138 #define BRACE_AT_START 2 /* '{' is at start of line */ |
7083 int ind_continuation = curbuf->b_ind_continuation; | 7172 int ind_continuation = curbuf->b_ind_continuation; |
7084 | 7173 |
7085 /* remember where the cursor was when we started */ | 7174 /* remember where the cursor was when we started */ |
7086 cur_curpos = curwin->w_cursor; | 7175 cur_curpos = curwin->w_cursor; |
7087 | 7176 |
7088 /* if we are at line 1 0 is fine, right? */ | 7177 /* if we are at line 1 zero indent is fine, right? */ |
7089 if (cur_curpos.lnum == 1) | 7178 if (cur_curpos.lnum == 1) |
7090 return 0; | 7179 return 0; |
7091 | 7180 |
7092 /* Get a copy of the current contents of the line. | 7181 /* Get a copy of the current contents of the line. |
7093 * This is required, because only the most recent line obtained with | 7182 * This is required, because only the most recent line obtained with |
7115 curwin->w_cursor.col = 0; | 7204 curwin->w_cursor.col = 0; |
7116 | 7205 |
7117 original_line_islabel = cin_islabel(); /* XXX */ | 7206 original_line_islabel = cin_islabel(); /* XXX */ |
7118 | 7207 |
7119 /* | 7208 /* |
7209 * If we are inside a raw string don't change the indent. | |
7210 * Ignore a raw string inside a comment. | |
7211 */ | |
7212 comment_pos = ind_find_start_comment(); | |
7213 if (comment_pos != NULL) | |
7214 { | |
7215 /* findmatchlimit() static pos is overwritten, make a copy */ | |
7216 tryposCopy = *comment_pos; | |
7217 comment_pos = &tryposCopy; | |
7218 } | |
7219 trypos = find_start_rawstring(curbuf->b_ind_maxcomment); | |
7220 if (trypos != NULL && (comment_pos == NULL || lt(*trypos, *comment_pos))) | |
7221 { | |
7222 amount = -1; | |
7223 goto laterend; | |
7224 } | |
7225 | |
7226 /* | |
7120 * #defines and so on always go at the left when included in 'cinkeys'. | 7227 * #defines and so on always go at the left when included in 'cinkeys'. |
7121 */ | 7228 */ |
7122 if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE))) | 7229 if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE))) |
7230 { | |
7123 amount = curbuf->b_ind_hash_comment; | 7231 amount = curbuf->b_ind_hash_comment; |
7232 goto theend; | |
7233 } | |
7124 | 7234 |
7125 /* | 7235 /* |
7126 * Is it a non-case label? Then that goes at the left margin too unless: | 7236 * Is it a non-case label? Then that goes at the left margin too unless: |
7127 * - JS flag is set. | 7237 * - JS flag is set. |
7128 * - 'L' item has a positive value. | 7238 * - 'L' item has a positive value. |
7129 */ | 7239 */ |
7130 else if (original_line_islabel && !curbuf->b_ind_js | 7240 if (original_line_islabel && !curbuf->b_ind_js |
7131 && curbuf->b_ind_jump_label < 0) | 7241 && curbuf->b_ind_jump_label < 0) |
7132 { | 7242 { |
7133 amount = 0; | 7243 amount = 0; |
7244 goto theend; | |
7134 } | 7245 } |
7135 | 7246 |
7136 /* | 7247 /* |
7137 * If we're inside a "//" comment and there is a "//" comment in a | 7248 * If we're inside a "//" comment and there is a "//" comment in a |
7138 * previous line, lineup with that one. | 7249 * previous line, lineup with that one. |
7139 */ | 7250 */ |
7140 else if (cin_islinecomment(theline) | 7251 if (cin_islinecomment(theline) |
7141 && (trypos = find_line_comment()) != NULL) /* XXX */ | 7252 && (trypos = find_line_comment()) != NULL) /* XXX */ |
7142 { | 7253 { |
7143 /* find how indented the line beginning the comment is */ | 7254 /* find how indented the line beginning the comment is */ |
7144 getvcol(curwin, trypos, &col, NULL, NULL); | 7255 getvcol(curwin, trypos, &col, NULL, NULL); |
7145 amount = col; | 7256 amount = col; |
7257 goto theend; | |
7146 } | 7258 } |
7147 | 7259 |
7148 /* | 7260 /* |
7149 * If we're inside a comment and not looking at the start of the | 7261 * If we're inside a comment and not looking at the start of the |
7150 * comment, try using the 'comments' option. | 7262 * comment, try using the 'comments' option. |
7151 */ | 7263 */ |
7152 else if (!cin_iscomment(theline) | 7264 if (!cin_iscomment(theline) && comment_pos != NULL) /* XXX */ |
7153 && (trypos = ind_find_start_comment()) != NULL) | |
7154 /* XXX */ | |
7155 { | 7265 { |
7156 int lead_start_len = 2; | 7266 int lead_start_len = 2; |
7157 int lead_middle_len = 1; | 7267 int lead_middle_len = 1; |
7158 char_u lead_start[COM_MAX_LEN]; /* start-comment string */ | 7268 char_u lead_start[COM_MAX_LEN]; /* start-comment string */ |
7159 char_u lead_middle[COM_MAX_LEN]; /* middle-comment string */ | 7269 char_u lead_middle[COM_MAX_LEN]; /* middle-comment string */ |
7162 int start_align = 0; | 7272 int start_align = 0; |
7163 int start_off = 0; | 7273 int start_off = 0; |
7164 int done = FALSE; | 7274 int done = FALSE; |
7165 | 7275 |
7166 /* find how indented the line beginning the comment is */ | 7276 /* find how indented the line beginning the comment is */ |
7167 getvcol(curwin, trypos, &col, NULL, NULL); | 7277 getvcol(curwin, comment_pos, &col, NULL, NULL); |
7168 amount = col; | 7278 amount = col; |
7169 *lead_start = NUL; | 7279 *lead_start = NUL; |
7170 *lead_middle = NUL; | 7280 *lead_middle = NUL; |
7171 | 7281 |
7172 p = curbuf->b_p_com; | 7282 p = curbuf->b_p_com; |
7226 amount = get_indent_lnum(curwin->w_cursor.lnum - 1); | 7336 amount = get_indent_lnum(curwin->w_cursor.lnum - 1); |
7227 break; | 7337 break; |
7228 } | 7338 } |
7229 /* If the start comment string doesn't match with the | 7339 /* If the start comment string doesn't match with the |
7230 * start of the comment, skip this entry. XXX */ | 7340 * start of the comment, skip this entry. XXX */ |
7231 else if (STRNCMP(ml_get(trypos->lnum) + trypos->col, | 7341 else if (STRNCMP(ml_get(comment_pos->lnum) + comment_pos->col, |
7232 lead_start, lead_start_len) != 0) | 7342 lead_start, lead_start_len) != 0) |
7233 continue; | 7343 continue; |
7234 } | 7344 } |
7235 if (start_off != 0) | 7345 if (start_off != 0) |
7236 amount += start_off; | 7346 amount += start_off; |
7274 * and we are just below the comment opener and there are any | 7384 * and we are just below the comment opener and there are any |
7275 * white characters after it line up with the text after it; | 7385 * white characters after it line up with the text after it; |
7276 * otherwise, add the amount specified by "c" in 'cino' | 7386 * otherwise, add the amount specified by "c" in 'cino' |
7277 */ | 7387 */ |
7278 amount = -1; | 7388 amount = -1; |
7279 for (lnum = cur_curpos.lnum - 1; lnum > trypos->lnum; --lnum) | 7389 for (lnum = cur_curpos.lnum - 1; lnum > comment_pos->lnum; --lnum) |
7280 { | 7390 { |
7281 if (linewhite(lnum)) /* skip blank lines */ | 7391 if (linewhite(lnum)) /* skip blank lines */ |
7282 continue; | 7392 continue; |
7283 amount = get_indent_lnum(lnum); /* XXX */ | 7393 amount = get_indent_lnum(lnum); /* XXX */ |
7284 break; | 7394 break; |
7285 } | 7395 } |
7286 if (amount == -1) /* use the comment opener */ | 7396 if (amount == -1) /* use the comment opener */ |
7287 { | 7397 { |
7288 if (!curbuf->b_ind_in_comment2) | 7398 if (!curbuf->b_ind_in_comment2) |
7289 { | 7399 { |
7290 start = ml_get(trypos->lnum); | 7400 start = ml_get(comment_pos->lnum); |
7291 look = start + trypos->col + 2; /* skip / and * */ | 7401 look = start + comment_pos->col + 2; /* skip / and * */ |
7292 if (*look != NUL) /* if something after it */ | 7402 if (*look != NUL) /* if something after it */ |
7293 trypos->col = (colnr_T)(skipwhite(look) - start); | 7403 comment_pos->col = (colnr_T)(skipwhite(look) - start); |
7294 } | 7404 } |
7295 getvcol(curwin, trypos, &col, NULL, NULL); | 7405 getvcol(curwin, comment_pos, &col, NULL, NULL); |
7296 amount = col; | 7406 amount = col; |
7297 if (curbuf->b_ind_in_comment2 || *look == NUL) | 7407 if (curbuf->b_ind_in_comment2 || *look == NUL) |
7298 amount += curbuf->b_ind_in_comment; | 7408 amount += curbuf->b_ind_in_comment; |
7299 } | 7409 } |
7300 } | 7410 } |
7411 goto theend; | |
7301 } | 7412 } |
7302 | 7413 |
7303 /* | 7414 /* |
7304 * Are we looking at a ']' that has a match? | 7415 * Are we looking at a ']' that has a match? |
7305 */ | 7416 */ |
7306 else if (*skipwhite(theline) == ']' | 7417 if (*skipwhite(theline) == ']' |
7307 && (trypos = find_match_char('[', curbuf->b_ind_maxparen)) != NULL) | 7418 && (trypos = find_match_char('[', curbuf->b_ind_maxparen)) != NULL) |
7308 { | 7419 { |
7309 /* align with the line containing the '['. */ | 7420 /* align with the line containing the '['. */ |
7310 amount = get_indent_lnum(trypos->lnum); | 7421 amount = get_indent_lnum(trypos->lnum); |
7422 goto theend; | |
7311 } | 7423 } |
7312 | 7424 |
7313 /* | 7425 /* |
7314 * Are we inside parentheses or braces? | 7426 * Are we inside parentheses or braces? |
7315 */ /* XXX */ | 7427 */ /* XXX */ |
7316 else if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL | 7428 if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL |
7317 && curbuf->b_ind_java == 0) | 7429 && curbuf->b_ind_java == 0) |
7318 || (tryposBrace = find_start_brace()) != NULL | 7430 || (tryposBrace = find_start_brace()) != NULL |
7319 || trypos != NULL) | 7431 || trypos != NULL) |
7320 { | 7432 { |
7321 if (trypos != NULL && tryposBrace != NULL) | 7433 if (trypos != NULL && tryposBrace != NULL) |
7352 continue; | 7464 continue; |
7353 if (cin_ispreproc_cont(&l, &lnum)) | 7465 if (cin_ispreproc_cont(&l, &lnum)) |
7354 continue; /* ignore #define, #if, etc. */ | 7466 continue; /* ignore #define, #if, etc. */ |
7355 curwin->w_cursor.lnum = lnum; | 7467 curwin->w_cursor.lnum = lnum; |
7356 | 7468 |
7357 /* Skip a comment. XXX */ | 7469 /* Skip a comment or raw string. XXX */ |
7358 if ((trypos = ind_find_start_comment()) != NULL) | 7470 if ((trypos = ind_find_start_CORS()) != NULL) |
7359 { | 7471 { |
7360 lnum = trypos->lnum + 1; | 7472 lnum = trypos->lnum + 1; |
7361 continue; | 7473 continue; |
7362 } | 7474 } |
7363 | 7475 |
7581 * We are inside braces, there is a { before this line at the position | 7693 * We are inside braces, there is a { before this line at the position |
7582 * stored in tryposBrace. | 7694 * stored in tryposBrace. |
7583 * Make a copy of tryposBrace, it may point to pos_copy inside | 7695 * Make a copy of tryposBrace, it may point to pos_copy inside |
7584 * find_start_brace(), which may be changed somewhere. | 7696 * find_start_brace(), which may be changed somewhere. |
7585 */ | 7697 */ |
7586 tryposBraceCopy = *tryposBrace; | 7698 tryposCopy = *tryposBrace; |
7587 tryposBrace = &tryposBraceCopy; | 7699 tryposBrace = &tryposCopy; |
7588 trypos = tryposBrace; | 7700 trypos = tryposBrace; |
7589 ourscope = trypos->lnum; | 7701 ourscope = trypos->lnum; |
7590 start = ml_get(ourscope); | 7702 start = ml_get(ourscope); |
7591 | 7703 |
7592 /* | 7704 /* |
7789 } | 7901 } |
7790 | 7902 |
7791 l = ml_get_curline(); | 7903 l = ml_get_curline(); |
7792 | 7904 |
7793 /* | 7905 /* |
7794 * If we're in a comment now, skip to the start of the | 7906 * If we're in a comment or raw string now, skip to |
7795 * comment. | 7907 * the start of it. |
7796 */ | 7908 */ |
7797 trypos = ind_find_start_comment(); | 7909 trypos = ind_find_start_CORS(); |
7798 if (trypos != NULL) | 7910 if (trypos != NULL) |
7799 { | 7911 { |
7800 curwin->w_cursor.lnum = trypos->lnum + 1; | 7912 curwin->w_cursor.lnum = trypos->lnum + 1; |
7801 curwin->w_cursor.col = 0; | 7913 curwin->w_cursor.col = 0; |
7802 continue; | 7914 continue; |
7909 < ourscope - FIND_NAMESPACE_LIM) | 8021 < ourscope - FIND_NAMESPACE_LIM) |
7910 break; | 8022 break; |
7911 | 8023 |
7912 l = ml_get_curline(); | 8024 l = ml_get_curline(); |
7913 | 8025 |
7914 /* If we're in a comment now, skip to the start of | 8026 /* If we're in a comment or raw string now, skip |
7915 * the comment. */ | 8027 * to the start of it. */ |
7916 trypos = ind_find_start_comment(); | 8028 trypos = ind_find_start_CORS(); |
7917 if (trypos != NULL) | 8029 if (trypos != NULL) |
7918 { | 8030 { |
7919 curwin->w_cursor.lnum = trypos->lnum + 1; | 8031 curwin->w_cursor.lnum = trypos->lnum + 1; |
7920 curwin->w_cursor.col = 0; | 8032 curwin->w_cursor.col = 0; |
7921 continue; | 8033 continue; |
7939 } | 8051 } |
7940 break; | 8052 break; |
7941 } | 8053 } |
7942 | 8054 |
7943 /* | 8055 /* |
7944 * If we're in a comment now, skip to the start of the comment. | 8056 * If we're in a comment or raw string now, skip to the start |
8057 * of it. | |
7945 */ /* XXX */ | 8058 */ /* XXX */ |
7946 if ((trypos = ind_find_start_comment()) != NULL) | 8059 if ((trypos = ind_find_start_CORS()) != NULL) |
7947 { | 8060 { |
7948 curwin->w_cursor.lnum = trypos->lnum + 1; | 8061 curwin->w_cursor.lnum = trypos->lnum + 1; |
7949 curwin->w_cursor.col = 0; | 8062 curwin->w_cursor.col = 0; |
7950 continue; | 8063 continue; |
7951 } | 8064 } |
8727 amount += curbuf->b_ind_comment; | 8840 amount += curbuf->b_ind_comment; |
8728 | 8841 |
8729 /* subtract extra left-shift for jump labels */ | 8842 /* subtract extra left-shift for jump labels */ |
8730 if (curbuf->b_ind_jump_label > 0 && original_line_islabel) | 8843 if (curbuf->b_ind_jump_label > 0 && original_line_islabel) |
8731 amount -= curbuf->b_ind_jump_label; | 8844 amount -= curbuf->b_ind_jump_label; |
8732 } | 8845 |
8733 else | 8846 goto theend; |
8734 { | 8847 } |
8848 | |
8849 /* | |
8850 * ok -- we're not inside any sort of structure at all! | |
8851 * | |
8852 * This means we're at the top level, and everything should | |
8853 * basically just match where the previous line is, except | |
8854 * for the lines immediately following a function declaration, | |
8855 * which are K&R-style parameters and need to be indented. | |
8856 * | |
8857 * if our line starts with an open brace, forget about any | |
8858 * prevailing indent and make sure it looks like the start | |
8859 * of a function | |
8860 */ | |
8861 | |
8862 if (theline[0] == '{') | |
8863 { | |
8864 amount = curbuf->b_ind_first_open; | |
8865 goto theend; | |
8866 } | |
8867 | |
8868 /* | |
8869 * If the NEXT line is a function declaration, the current | |
8870 * line needs to be indented as a function type spec. | |
8871 * Don't do this if the current line looks like a comment or if the | |
8872 * current line is terminated, ie. ends in ';', or if the current line | |
8873 * contains { or }: "void f() {\n if (1)" | |
8874 */ | |
8875 if (cur_curpos.lnum < curbuf->b_ml.ml_line_count | |
8876 && !cin_nocode(theline) | |
8877 && vim_strchr(theline, '{') == NULL | |
8878 && vim_strchr(theline, '}') == NULL | |
8879 && !cin_ends_in(theline, (char_u *)":", NULL) | |
8880 && !cin_ends_in(theline, (char_u *)",", NULL) | |
8881 && cin_isfuncdecl(NULL, cur_curpos.lnum + 1, | |
8882 cur_curpos.lnum + 1) | |
8883 && !cin_isterminated(theline, FALSE, TRUE)) | |
8884 { | |
8885 amount = curbuf->b_ind_func_type; | |
8886 goto theend; | |
8887 } | |
8888 | |
8889 /* search backwards until we find something we recognize */ | |
8890 amount = 0; | |
8891 curwin->w_cursor = cur_curpos; | |
8892 while (curwin->w_cursor.lnum > 1) | |
8893 { | |
8894 curwin->w_cursor.lnum--; | |
8895 curwin->w_cursor.col = 0; | |
8896 | |
8897 l = ml_get_curline(); | |
8898 | |
8735 /* | 8899 /* |
8736 * ok -- we're not inside any sort of structure at all! | 8900 * If we're in a comment or raw string now, skip to the start |
8901 * of it. | |
8902 */ /* XXX */ | |
8903 if ((trypos = ind_find_start_CORS()) != NULL) | |
8904 { | |
8905 curwin->w_cursor.lnum = trypos->lnum + 1; | |
8906 curwin->w_cursor.col = 0; | |
8907 continue; | |
8908 } | |
8909 | |
8910 /* | |
8911 * Are we at the start of a cpp base class declaration or | |
8912 * constructor initialization? | |
8913 */ /* XXX */ | |
8914 n = FALSE; | |
8915 if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{') | |
8916 { | |
8917 n = cin_is_cpp_baseclass(&cache_cpp_baseclass); | |
8918 l = ml_get_curline(); | |
8919 } | |
8920 if (n) | |
8921 { | |
8922 /* XXX */ | |
8923 amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col); | |
8924 break; | |
8925 } | |
8926 | |
8927 /* | |
8928 * Skip preprocessor directives and blank lines. | |
8929 */ | |
8930 if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) | |
8931 continue; | |
8932 | |
8933 if (cin_nocode(l)) | |
8934 continue; | |
8935 | |
8936 /* | |
8937 * If the previous line ends in ',', use one level of | |
8938 * indentation: | |
8939 * int foo, | |
8940 * bar; | |
8941 * do this before checking for '}' in case of eg. | |
8942 * enum foobar | |
8943 * { | |
8944 * ... | |
8945 * } foo, | |
8946 * bar; | |
8947 */ | |
8948 n = 0; | |
8949 if (cin_ends_in(l, (char_u *)",", NULL) | |
8950 || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\')) | |
8951 { | |
8952 /* take us back to opening paren */ | |
8953 if (find_last_paren(l, '(', ')') | |
8954 && (trypos = find_match_paren( | |
8955 curbuf->b_ind_maxparen)) != NULL) | |
8956 curwin->w_cursor = *trypos; | |
8957 | |
8958 /* For a line ending in ',' that is a continuation line go | |
8959 * back to the first line with a backslash: | |
8960 * char *foo = "bla\ | |
8961 * bla", | |
8962 * here; | |
8963 */ | |
8964 while (n == 0 && curwin->w_cursor.lnum > 1) | |
8965 { | |
8966 l = ml_get(curwin->w_cursor.lnum - 1); | |
8967 if (*l == NUL || l[STRLEN(l) - 1] != '\\') | |
8968 break; | |
8969 --curwin->w_cursor.lnum; | |
8970 curwin->w_cursor.col = 0; | |
8971 } | |
8972 | |
8973 amount = get_indent(); /* XXX */ | |
8974 | |
8975 if (amount == 0) | |
8976 amount = cin_first_id_amount(); | |
8977 if (amount == 0) | |
8978 amount = ind_continuation; | |
8979 break; | |
8980 } | |
8981 | |
8982 /* | |
8983 * If the line looks like a function declaration, and we're | |
8984 * not in a comment, put it the left margin. | |
8985 */ | |
8986 if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */ | |
8987 break; | |
8988 l = ml_get_curline(); | |
8989 | |
8990 /* | |
8991 * Finding the closing '}' of a previous function. Put | |
8992 * current line at the left margin. For when 'cino' has "fs". | |
8993 */ | |
8994 if (*skipwhite(l) == '}') | |
8995 break; | |
8996 | |
8997 /* (matching {) | |
8998 * If the previous line ends on '};' (maybe followed by | |
8999 * comments) align at column 0. For example: | |
9000 * char *string_array[] = { "foo", | |
9001 * / * x * / "b};ar" }; / * foobar * / | |
9002 */ | |
9003 if (cin_ends_in(l, (char_u *)"};", NULL)) | |
9004 break; | |
9005 | |
9006 /* | |
9007 * If the previous line ends on '[' we are probably in an | |
9008 * array constant: | |
9009 * something = [ | |
9010 * 234, <- extra indent | |
9011 */ | |
9012 if (cin_ends_in(l, (char_u *)"[", NULL)) | |
9013 { | |
9014 amount = get_indent() + ind_continuation; | |
9015 break; | |
9016 } | |
9017 | |
9018 /* | |
9019 * Find a line only has a semicolon that belongs to a previous | |
9020 * line ending in '}', e.g. before an #endif. Don't increase | |
9021 * indent then. | |
9022 */ | |
9023 if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1)) | |
9024 { | |
9025 pos_T curpos_save = curwin->w_cursor; | |
9026 | |
9027 while (curwin->w_cursor.lnum > 1) | |
9028 { | |
9029 look = ml_get(--curwin->w_cursor.lnum); | |
9030 if (!(cin_nocode(look) || cin_ispreproc_cont( | |
9031 &look, &curwin->w_cursor.lnum))) | |
9032 break; | |
9033 } | |
9034 if (curwin->w_cursor.lnum > 0 | |
9035 && cin_ends_in(look, (char_u *)"}", NULL)) | |
9036 break; | |
9037 | |
9038 curwin->w_cursor = curpos_save; | |
9039 } | |
9040 | |
9041 /* | |
9042 * If the PREVIOUS line is a function declaration, the current | |
9043 * line (and the ones that follow) needs to be indented as | |
9044 * parameters. | |
9045 */ | |
9046 if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) | |
9047 { | |
9048 amount = curbuf->b_ind_param; | |
9049 break; | |
9050 } | |
9051 | |
9052 /* | |
9053 * If the previous line ends in ';' and the line before the | |
9054 * previous line ends in ',' or '\', ident to column zero: | |
9055 * int foo, | |
9056 * bar; | |
9057 * indent_to_0 here; | |
9058 */ | |
9059 if (cin_ends_in(l, (char_u *)";", NULL)) | |
9060 { | |
9061 l = ml_get(curwin->w_cursor.lnum - 1); | |
9062 if (cin_ends_in(l, (char_u *)",", NULL) | |
9063 || (*l != NUL && l[STRLEN(l) - 1] == '\\')) | |
9064 break; | |
9065 l = ml_get_curline(); | |
9066 } | |
9067 | |
9068 /* | |
9069 * Doesn't look like anything interesting -- so just | |
9070 * use the indent of this line. | |
8737 * | 9071 * |
8738 * This means we're at the top level, and everything should | 9072 * Position the cursor over the rightmost paren, so that |
8739 * basically just match where the previous line is, except | 9073 * matching it will take us back to the start of the line. |
8740 * for the lines immediately following a function declaration, | |
8741 * which are K&R-style parameters and need to be indented. | |
8742 * | |
8743 * if our line starts with an open brace, forget about any | |
8744 * prevailing indent and make sure it looks like the start | |
8745 * of a function | |
8746 */ | 9074 */ |
8747 | 9075 find_last_paren(l, '(', ')'); |
8748 if (theline[0] == '{') | 9076 |
8749 { | 9077 if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) |
8750 amount = curbuf->b_ind_first_open; | 9078 curwin->w_cursor = *trypos; |
8751 } | 9079 amount = get_indent(); /* XXX */ |
8752 | 9080 break; |
8753 /* | 9081 } |
8754 * If the NEXT line is a function declaration, the current | 9082 |
8755 * line needs to be indented as a function type spec. | 9083 /* add extra indent for a comment */ |
8756 * Don't do this if the current line looks like a comment or if the | 9084 if (cin_iscomment(theline)) |
8757 * current line is terminated, ie. ends in ';', or if the current line | 9085 amount += curbuf->b_ind_comment; |
8758 * contains { or }: "void f() {\n if (1)" | 9086 |
8759 */ | 9087 /* add extra indent if the previous line ended in a backslash: |
8760 else if (cur_curpos.lnum < curbuf->b_ml.ml_line_count | 9088 * "asdfasdf\ |
8761 && !cin_nocode(theline) | 9089 * here"; |
8762 && vim_strchr(theline, '{') == NULL | 9090 * char *foo = "asdf\ |
8763 && vim_strchr(theline, '}') == NULL | 9091 * here"; |
8764 && !cin_ends_in(theline, (char_u *)":", NULL) | 9092 */ |
8765 && !cin_ends_in(theline, (char_u *)",", NULL) | 9093 if (cur_curpos.lnum > 1) |
8766 && cin_isfuncdecl(NULL, cur_curpos.lnum + 1, | 9094 { |
8767 cur_curpos.lnum + 1) | 9095 l = ml_get(cur_curpos.lnum - 1); |
8768 && !cin_isterminated(theline, FALSE, TRUE)) | 9096 if (*l != NUL && l[STRLEN(l) - 1] == '\\') |
8769 { | 9097 { |
8770 amount = curbuf->b_ind_func_type; | 9098 cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1); |
8771 } | 9099 if (cur_amount > 0) |
8772 else | 9100 amount = cur_amount; |
8773 { | 9101 else if (cur_amount == 0) |
8774 amount = 0; | 9102 amount += ind_continuation; |
8775 curwin->w_cursor = cur_curpos; | |
8776 | |
8777 /* search backwards until we find something we recognize */ | |
8778 | |
8779 while (curwin->w_cursor.lnum > 1) | |
8780 { | |
8781 curwin->w_cursor.lnum--; | |
8782 curwin->w_cursor.col = 0; | |
8783 | |
8784 l = ml_get_curline(); | |
8785 | |
8786 /* | |
8787 * If we're in a comment now, skip to the start of the comment. | |
8788 */ /* XXX */ | |
8789 if ((trypos = ind_find_start_comment()) != NULL) | |
8790 { | |
8791 curwin->w_cursor.lnum = trypos->lnum + 1; | |
8792 curwin->w_cursor.col = 0; | |
8793 continue; | |
8794 } | |
8795 | |
8796 /* | |
8797 * Are we at the start of a cpp base class declaration or | |
8798 * constructor initialization? | |
8799 */ /* XXX */ | |
8800 n = FALSE; | |
8801 if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{') | |
8802 { | |
8803 n = cin_is_cpp_baseclass(&cache_cpp_baseclass); | |
8804 l = ml_get_curline(); | |
8805 } | |
8806 if (n) | |
8807 { | |
8808 /* XXX */ | |
8809 amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col); | |
8810 break; | |
8811 } | |
8812 | |
8813 /* | |
8814 * Skip preprocessor directives and blank lines. | |
8815 */ | |
8816 if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) | |
8817 continue; | |
8818 | |
8819 if (cin_nocode(l)) | |
8820 continue; | |
8821 | |
8822 /* | |
8823 * If the previous line ends in ',', use one level of | |
8824 * indentation: | |
8825 * int foo, | |
8826 * bar; | |
8827 * do this before checking for '}' in case of eg. | |
8828 * enum foobar | |
8829 * { | |
8830 * ... | |
8831 * } foo, | |
8832 * bar; | |
8833 */ | |
8834 n = 0; | |
8835 if (cin_ends_in(l, (char_u *)",", NULL) | |
8836 || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\')) | |
8837 { | |
8838 /* take us back to opening paren */ | |
8839 if (find_last_paren(l, '(', ')') | |
8840 && (trypos = find_match_paren( | |
8841 curbuf->b_ind_maxparen)) != NULL) | |
8842 curwin->w_cursor = *trypos; | |
8843 | |
8844 /* For a line ending in ',' that is a continuation line go | |
8845 * back to the first line with a backslash: | |
8846 * char *foo = "bla\ | |
8847 * bla", | |
8848 * here; | |
8849 */ | |
8850 while (n == 0 && curwin->w_cursor.lnum > 1) | |
8851 { | |
8852 l = ml_get(curwin->w_cursor.lnum - 1); | |
8853 if (*l == NUL || l[STRLEN(l) - 1] != '\\') | |
8854 break; | |
8855 --curwin->w_cursor.lnum; | |
8856 curwin->w_cursor.col = 0; | |
8857 } | |
8858 | |
8859 amount = get_indent(); /* XXX */ | |
8860 | |
8861 if (amount == 0) | |
8862 amount = cin_first_id_amount(); | |
8863 if (amount == 0) | |
8864 amount = ind_continuation; | |
8865 break; | |
8866 } | |
8867 | |
8868 /* | |
8869 * If the line looks like a function declaration, and we're | |
8870 * not in a comment, put it the left margin. | |
8871 */ | |
8872 if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */ | |
8873 break; | |
8874 l = ml_get_curline(); | |
8875 | |
8876 /* | |
8877 * Finding the closing '}' of a previous function. Put | |
8878 * current line at the left margin. For when 'cino' has "fs". | |
8879 */ | |
8880 if (*skipwhite(l) == '}') | |
8881 break; | |
8882 | |
8883 /* (matching {) | |
8884 * If the previous line ends on '};' (maybe followed by | |
8885 * comments) align at column 0. For example: | |
8886 * char *string_array[] = { "foo", | |
8887 * / * x * / "b};ar" }; / * foobar * / | |
8888 */ | |
8889 if (cin_ends_in(l, (char_u *)"};", NULL)) | |
8890 break; | |
8891 | |
8892 /* | |
8893 * If the previous line ends on '[' we are probably in an | |
8894 * array constant: | |
8895 * something = [ | |
8896 * 234, <- extra indent | |
8897 */ | |
8898 if (cin_ends_in(l, (char_u *)"[", NULL)) | |
8899 { | |
8900 amount = get_indent() + ind_continuation; | |
8901 break; | |
8902 } | |
8903 | |
8904 /* | |
8905 * Find a line only has a semicolon that belongs to a previous | |
8906 * line ending in '}', e.g. before an #endif. Don't increase | |
8907 * indent then. | |
8908 */ | |
8909 if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1)) | |
8910 { | |
8911 pos_T curpos_save = curwin->w_cursor; | |
8912 | |
8913 while (curwin->w_cursor.lnum > 1) | |
8914 { | |
8915 look = ml_get(--curwin->w_cursor.lnum); | |
8916 if (!(cin_nocode(look) || cin_ispreproc_cont( | |
8917 &look, &curwin->w_cursor.lnum))) | |
8918 break; | |
8919 } | |
8920 if (curwin->w_cursor.lnum > 0 | |
8921 && cin_ends_in(look, (char_u *)"}", NULL)) | |
8922 break; | |
8923 | |
8924 curwin->w_cursor = curpos_save; | |
8925 } | |
8926 | |
8927 /* | |
8928 * If the PREVIOUS line is a function declaration, the current | |
8929 * line (and the ones that follow) needs to be indented as | |
8930 * parameters. | |
8931 */ | |
8932 if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) | |
8933 { | |
8934 amount = curbuf->b_ind_param; | |
8935 break; | |
8936 } | |
8937 | |
8938 /* | |
8939 * If the previous line ends in ';' and the line before the | |
8940 * previous line ends in ',' or '\', ident to column zero: | |
8941 * int foo, | |
8942 * bar; | |
8943 * indent_to_0 here; | |
8944 */ | |
8945 if (cin_ends_in(l, (char_u *)";", NULL)) | |
8946 { | |
8947 l = ml_get(curwin->w_cursor.lnum - 1); | |
8948 if (cin_ends_in(l, (char_u *)",", NULL) | |
8949 || (*l != NUL && l[STRLEN(l) - 1] == '\\')) | |
8950 break; | |
8951 l = ml_get_curline(); | |
8952 } | |
8953 | |
8954 /* | |
8955 * Doesn't look like anything interesting -- so just | |
8956 * use the indent of this line. | |
8957 * | |
8958 * Position the cursor over the rightmost paren, so that | |
8959 * matching it will take us back to the start of the line. | |
8960 */ | |
8961 find_last_paren(l, '(', ')'); | |
8962 | |
8963 if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) | |
8964 curwin->w_cursor = *trypos; | |
8965 amount = get_indent(); /* XXX */ | |
8966 break; | |
8967 } | |
8968 | |
8969 /* add extra indent for a comment */ | |
8970 if (cin_iscomment(theline)) | |
8971 amount += curbuf->b_ind_comment; | |
8972 | |
8973 /* add extra indent if the previous line ended in a backslash: | |
8974 * "asdfasdf\ | |
8975 * here"; | |
8976 * char *foo = "asdf\ | |
8977 * here"; | |
8978 */ | |
8979 if (cur_curpos.lnum > 1) | |
8980 { | |
8981 l = ml_get(cur_curpos.lnum - 1); | |
8982 if (*l != NUL && l[STRLEN(l) - 1] == '\\') | |
8983 { | |
8984 cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1); | |
8985 if (cur_amount > 0) | |
8986 amount = cur_amount; | |
8987 else if (cur_amount == 0) | |
8988 amount += ind_continuation; | |
8989 } | |
8990 } | |
8991 } | 9103 } |
8992 } | 9104 } |
8993 | 9105 |
8994 theend: | 9106 theend: |
9107 if (amount < 0) | |
9108 amount = 0; | |
9109 | |
9110 laterend: | |
8995 /* put the cursor back where it belongs */ | 9111 /* put the cursor back where it belongs */ |
8996 curwin->w_cursor = cur_curpos; | 9112 curwin->w_cursor = cur_curpos; |
8997 | 9113 |
8998 vim_free(linecopy); | 9114 vim_free(linecopy); |
8999 | 9115 |
9000 if (amount < 0) | |
9001 return 0; | |
9002 return amount; | 9116 return amount; |
9003 } | 9117 } |
9004 | 9118 |
9005 static int | 9119 static int |
9006 find_match(lookfor, ourscope) | 9120 find_match(lookfor, ourscope) |