mirror of
https://github.com/vim/vim.git
synced 2025-10-02 05:04:20 -04:00
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.
This commit is contained in:
@@ -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.
|
||||
@@ -137,6 +135,21 @@ skip_string(char_u *p)
|
||||
return 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.
|
||||
@@ -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)
|
||||
|
@@ -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);
|
||||
|
12
src/search.c
12
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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -749,6 +749,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3938,
|
||||
/**/
|
||||
3937,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user