diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-01-31 15:44:54 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-01-31 15:44:54 +0800 |
commit | ae649650de3509e22ee6fad5cfa72998d40f2a92 (patch) | |
tree | d20ee547a92c0840e829bdcdc6209f3388f89abc | |
parent | f7801fe138d9677c9333650b4d5581489d4b0613 (diff) | |
download | rneovim-ae649650de3509e22ee6fad5cfa72998d40f2a92.tar.gz rneovim-ae649650de3509e22ee6fad5cfa72998d40f2a92.tar.bz2 rneovim-ae649650de3509e22ee6fad5cfa72998d40f2a92.zip |
vim-patch:8.2.3938: line comment start is also found in a string
Problem: Line comment start is also found in a string.
Solution: Skip line comments in a string.
https://github.com/vim/vim/commit/ba26367fea3b63df49d274f3d5cca0af38402add
-rw-r--r-- | src/nvim/indent_c.c | 30 | ||||
-rw-r--r-- | src/nvim/search.c | 19 | ||||
-rw-r--r-- | src/nvim/testdir/test_textformat.vim | 15 |
3 files changed, 41 insertions, 23 deletions
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 5ccf322b76..bfc2ad4dd2 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -41,9 +41,7 @@ static pos_T *ind_find_start_comment(void) // XXX pos_T *find_start_comment(int ind_maxcomment) // XXX { - pos_T *pos; - char_u *line; - char_u *p; + pos_T *pos; int64_t cur_maxcomment = ind_maxcomment; for (;; ) { @@ -55,11 +53,9 @@ pos_T *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) { pos = NULL; @@ -110,8 +106,6 @@ static pos_T *ind_find_start_CORS(linenr_T *is_raw) static pos_T *find_start_rawstring(int ind_maxcomment) // XXX { pos_T *pos; - char_u *line; - char_u *p; long cur_maxcomment = ind_maxcomment; for (;;) @@ -124,11 +118,9 @@ static pos_T *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) - break; + 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) { @@ -205,6 +197,16 @@ static char_u *skip_string(char_u *p) return p; } +/// @returns 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); +} /* * Functions for C-indenting. diff --git a/src/nvim/search.c b/src/nvim/search.c index 6195be42ba..93180f97fe 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -26,6 +26,7 @@ #include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/indent.h" +#include "nvim/indent_c.h" #include "nvim/main.h" #include "nvim/mark.h" #include "nvim/mbyte.h" @@ -2313,11 +2314,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) return (pos_T *)NULL; // never found it } -/* - * Check if line[] contains a / / comment. - * Return MAXCOL if not, otherwise return the column. - * TODO: skip strings. - */ +/// Check if line[] contains a / / comment. +/// @returns MAXCOL if not, otherwise return the column. int check_linecomment(const char_u *line) { const char_u *p = line; // scan from start @@ -2338,7 +2336,8 @@ int check_linecomment(const 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++; @@ -2348,9 +2347,11 @@ int check_linecomment(const char_u *line) } } else { 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/nvim/testdir/test_textformat.vim b/src/nvim/testdir/test_textformat.vim index e1d155eba7..052c32214d 100644 --- a/src/nvim/testdir/test_textformat.vim +++ b/src/nvim/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 |