diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-12-29 18:09:13 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-12-29 18:09:13 +0000 |
commit | ba26367fea3b63df49d274f3d5cca0af38402add (patch) | |
tree | 85eb39195c89d138f835691791818bc41593fc0b | |
parent | edc6f103907a004b9e2265e232dc8be8bc594601 (diff) |
patch 8.2.3938: line comment start is also found in a stringv8.2.3938
Problem: Line comment start is also found in a string.
Solution: Skip line comments in a string.
-rw-r--r-- | src/cindent.c | 31 | ||||
-rw-r--r-- | src/proto/cindent.pro | 1 | ||||
-rw-r--r-- | src/search.c | 12 | ||||
-rw-r--r-- | src/testdir/test_textformat.vim | 15 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 42 insertions, 19 deletions
diff --git a/src/cindent.c b/src/cindent.c index 9f1db03c59..747b5093e9 100644 --- a/src/cindent.c +++ b/src/cindent.c @@ -66,8 +66,6 @@ cin_is_cinword(char_u *line) } #endif -#if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL) - /* * Skip to the end of a "string" and a 'c' character. * If there is no string or character, return argument unmodified. @@ -138,6 +136,21 @@ skip_string(char_u *p) } /* + * Return TRUE if "line[col]" is inside a C string. + */ + int +is_pos_in_string(char_u *line, colnr_T col) +{ + char_u *p; + + for (p = line; *p && (colnr_T)(p - line) < col; ++p) + p = skip_string(p); + return !((colnr_T)(p - line) <= col); +} + +#if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL) + +/* * Find the start of a comment, not knowing if we are in a comment right now. * Search starts at w_cursor.lnum and goes backwards. * Return NULL when not inside a comment. @@ -152,8 +165,6 @@ ind_find_start_comment(void) // XXX find_start_comment(int ind_maxcomment) // XXX { pos_T *pos; - char_u *line; - char_u *p; int cur_maxcomment = ind_maxcomment; for (;;) @@ -164,10 +175,7 @@ find_start_comment(int ind_maxcomment) // XXX // Check if the comment start we found is inside a string. // If it is then restrict the search to below this line and try again. - line = ml_get(pos->lnum); - for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p) - p = skip_string(p); - if ((colnr_T)(p - line) <= pos->col) + if (!is_pos_in_string(ml_get(pos->lnum), pos->col)) break; cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1; if (cur_maxcomment <= 0) @@ -188,8 +196,6 @@ find_start_comment(int ind_maxcomment) // XXX find_start_rawstring(int ind_maxcomment) // XXX { pos_T *pos; - char_u *line; - char_u *p; int cur_maxcomment = ind_maxcomment; for (;;) @@ -200,10 +206,7 @@ find_start_rawstring(int ind_maxcomment) // XXX // Check if the raw string start we found is inside a string. // If it is then restrict the search to below this line and try again. - line = ml_get(pos->lnum); - for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p) - p = skip_string(p); - if ((colnr_T)(p - line) <= pos->col) + if (!is_pos_in_string(ml_get(pos->lnum), pos->col)) break; cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1; if (cur_maxcomment <= 0) diff --git a/src/proto/cindent.pro b/src/proto/cindent.pro index 7de2ab3e1f..80a6add550 100644 --- a/src/proto/cindent.pro +++ b/src/proto/cindent.pro @@ -1,5 +1,6 @@ /* cindent.c */ int cin_is_cinword(char_u *line); +int is_pos_in_string(char_u *line, colnr_T col); pos_T *find_start_comment(int ind_maxcomment); int cindent_on(void); void parse_cino(buf_T *buf); diff --git a/src/search.c b/src/search.c index c5810ed0e7..5851d52362 100644 --- a/src/search.c +++ b/src/search.c @@ -2714,7 +2714,6 @@ findmatchlimit( /* * Check if line[] contains a / / comment. * Return MAXCOL if not, otherwise return the column. - * TODO: skip strings. */ int check_linecomment(char_u *line) @@ -2746,7 +2745,8 @@ check_linecomment(char_u *line) in_str = TRUE; } else if (!in_str && ((p - line) < 2 - || (*(p - 1) != '\\' && *(p - 2) != '#'))) + || (*(p - 1) != '\\' && *(p - 2) != '#')) + && !is_pos_in_string(line, (colnr_T)(p - line))) break; // found! ++p; } @@ -2758,9 +2758,11 @@ check_linecomment(char_u *line) #endif while ((p = vim_strchr(p, '/')) != NULL) { - // accept a double /, unless it's preceded with * and followed by *, - // because * / / * is an end and start of a C comment - if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')) + // Accept a double /, unless it's preceded with * and followed by *, + // because * / / * is an end and start of a C comment. + // Only accept the position if it is not inside a string. + if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*') + && !is_pos_in_string(line, (colnr_T)(p - line))) break; ++p; } diff --git a/src/testdir/test_textformat.vim b/src/testdir/test_textformat.vim index ccfd36f753..6402989297 100644 --- a/src/testdir/test_textformat.vim +++ b/src/testdir/test_textformat.vim @@ -261,6 +261,21 @@ func Test_format_c_comment() END call assert_equal(expected, getline(1, '$')) + " Using "o" does not repeat a comment in a string + %del + let text =<< trim END + nop; + val = " // This is not a comment"; + END + call setline(1, text) + normal 2Gox + let expected =<< trim END + nop; + val = " // This is not a comment"; + x + END + call assert_equal(expected, getline(1, '$')) + " Using CTRL-U after "o" fixes the indent %del let text =<< trim END diff --git a/src/version.c b/src/version.c index 68ce1c5946..15df8606f7 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3938, +/**/ 3937, /**/ 3936, |