mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
patch 9.2.0447: cindent does not ignore comments
Problem: When find_start_brace() scans backwards for the enclosing
block, '{' and '}' inside // and /* */ comments are counted,
producing wrong indent for code following such comments
(rendcrx).
Solution: Implement FM_SKIPCOMM in findmatchlimit() to track block-
comment state and skip matches inside comments. Pass
FM_SKIPCOMM from cindent's call sites
(find_start_brace, find_match_char, cin_iswhileofdo,
get_c_indent).
fixes: #4
fixes: #648
fixes: #19578
closes: #19581
closes: #20111
Signed-off-by: magnus-rattlehead <guranjakustivi@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
7ccc273a4c
commit
c06002f3cb
@@ -1,4 +1,4 @@
|
||||
*version9.txt* For Vim version 9.2. Last change: 2026 May 02
|
||||
*version9.txt* For Vim version 9.2. Last change: 2026 May 05
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -52625,6 +52625,7 @@ Other ~
|
||||
- Added the "u" flag to 'shortmess' to silence undo/redo messages: |shm-u|
|
||||
- |:command-completion-customlist| can return a list of dictionaries with
|
||||
kind/menu/info/abbr for the popup menu.
|
||||
- |C-indenting| detects comments better.
|
||||
|
||||
Platform specific ~
|
||||
-----------------
|
||||
|
||||
+4
-4
@@ -1153,7 +1153,7 @@ find_match_char(int c, int ind_maxparen) // XXX
|
||||
cursor_save = curwin->w_cursor;
|
||||
ind_maxp_wk = ind_maxparen;
|
||||
retry:
|
||||
if ((trypos = findmatchlimit(NULL, c, 0, ind_maxp_wk)) != NULL)
|
||||
if ((trypos = findmatchlimit(NULL, c, FM_SKIPCOMM, ind_maxp_wk)) != NULL)
|
||||
{
|
||||
// check if the ( is in a // comment
|
||||
if ((colnr_T)cin_skip2pos(trypos) > trypos->col)
|
||||
@@ -1396,7 +1396,7 @@ cin_iswhileofdo (char_u *p, linenr_T lnum) // XXX
|
||||
++p;
|
||||
++curwin->w_cursor.col;
|
||||
}
|
||||
if ((trypos = findmatchlimit(NULL, 0, 0,
|
||||
if ((trypos = findmatchlimit(NULL, 0, FM_SKIPCOMM,
|
||||
curbuf->b_ind_maxparen)) != NULL
|
||||
&& *cin_skipcomment(ml_get_pos(trypos) + 1) == ';')
|
||||
retval = TRUE;
|
||||
@@ -1732,7 +1732,7 @@ find_start_brace(void) // XXX
|
||||
static pos_T pos_copy;
|
||||
|
||||
cursor_save = curwin->w_cursor;
|
||||
while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL)
|
||||
while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP | FM_SKIPCOMM, 0)) != NULL)
|
||||
{
|
||||
pos_copy = *trypos; // copy pos_T, next findmatch will change it
|
||||
trypos = &pos_copy;
|
||||
@@ -2547,7 +2547,7 @@ get_c_indent(void)
|
||||
line = ml_get_curline();
|
||||
look_col = (int)(look - line);
|
||||
curwin->w_cursor.col = look_col + 1;
|
||||
if ((trypos = findmatchlimit(NULL, ')', 0,
|
||||
if ((trypos = findmatchlimit(NULL, ')', FM_SKIPCOMM,
|
||||
curbuf->b_ind_maxparen))
|
||||
!= NULL
|
||||
&& trypos->lnum == our_paren_pos.lnum
|
||||
|
||||
+50
-4
@@ -2165,7 +2165,7 @@ find_mps_values(
|
||||
* flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#')
|
||||
* FM_FORWARD search forwards (when initc is '/', '*' or '#')
|
||||
* FM_BLOCKSTOP stop at start/end of block ({ or } in column 0)
|
||||
* FM_SKIPCOMM skip comments (not implemented yet!)
|
||||
* FM_SKIPCOMM skip over comments (cursor must start outside a block comment)
|
||||
*
|
||||
* "oap" is only used to set oap->motion_type for a linewise motion, it can be
|
||||
* NULL
|
||||
@@ -2201,6 +2201,8 @@ findmatchlimit(
|
||||
int comment_col = MAXCOL; // start of / / comment
|
||||
int lispcomm = FALSE; // inside of Lisp-style comment
|
||||
int lisp = curbuf->b_p_lisp; // engage Lisp-specific hacks ;)
|
||||
int skip_comments = (flags & FM_SKIPCOMM) != 0;
|
||||
int in_block_comment = FALSE; // inside /* */ block comment
|
||||
|
||||
pos = curwin->w_cursor;
|
||||
pos.coladd = 0;
|
||||
@@ -2429,10 +2431,14 @@ findmatchlimit(
|
||||
CLEAR_POS(&match_pos);
|
||||
|
||||
// backward search: Check if this line contains a single-line comment
|
||||
if ((backwards && comment_dir) || lisp)
|
||||
if ((backwards && comment_dir) || lisp || skip_comments)
|
||||
comment_col = check_linecomment(linep);
|
||||
if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col)
|
||||
lispcomm = TRUE; // find match inside this comment
|
||||
// skip // comment portion at starting position
|
||||
if (skip_comments && !in_block_comment && comment_col != MAXCOL
|
||||
&& backwards && pos.col > (colnr_T)comment_col)
|
||||
pos.col = comment_col;
|
||||
|
||||
while (!got_int)
|
||||
{
|
||||
@@ -2460,11 +2466,15 @@ findmatchlimit(
|
||||
line_breakcheck();
|
||||
|
||||
// Check if this line contains a single-line comment
|
||||
if (comment_dir || lisp)
|
||||
if (comment_dir || lisp || skip_comments)
|
||||
comment_col = check_linecomment(linep);
|
||||
// skip comment
|
||||
if (lisp && comment_col != MAXCOL)
|
||||
pos.col = comment_col;
|
||||
else if (skip_comments && !in_block_comment
|
||||
&& comment_col != MAXCOL
|
||||
&& pos.col > (colnr_T)comment_col)
|
||||
pos.col = comment_col;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2495,7 +2505,7 @@ findmatchlimit(
|
||||
pos.col = 0;
|
||||
do_quotes = -1;
|
||||
line_breakcheck();
|
||||
if (lisp) // find comment pos in new line
|
||||
if (lisp || skip_comments) // find comment pos in new line
|
||||
comment_col = check_linecomment(linep);
|
||||
}
|
||||
else
|
||||
@@ -2507,6 +2517,37 @@ findmatchlimit(
|
||||
}
|
||||
}
|
||||
|
||||
// Track block comment state when FM_SKIPCOMM is set.
|
||||
// Backward: '/' of end-marker enters comment; '*' of start-marker exits.
|
||||
// Forward: '/' of start-marker enters comment; '/' of end-marker exits.
|
||||
if (skip_comments && !comment_dir)
|
||||
{
|
||||
if (backwards)
|
||||
{
|
||||
// Guard pos.col < comment_col: don't misread '*/' at the '//'
|
||||
// position as a block-comment end-marker.
|
||||
if (!in_block_comment && pos.col > 0
|
||||
&& linep[pos.col - 1] == '*' && linep[pos.col] == '/'
|
||||
&& (comment_col == MAXCOL || (int)pos.col < comment_col))
|
||||
in_block_comment = TRUE;
|
||||
else if (in_block_comment && pos.col > 0
|
||||
&& linep[pos.col - 1] == '/' && linep[pos.col] == '*')
|
||||
in_block_comment = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Guard pos.col < comment_col: don't treat '/*' inside a '//'
|
||||
// comment as a block-comment start-marker.
|
||||
if (!in_block_comment && linep[pos.col] == '/'
|
||||
&& linep[pos.col + 1] == '*'
|
||||
&& (comment_col == MAXCOL || (int)pos.col < comment_col))
|
||||
in_block_comment = TRUE;
|
||||
else if (in_block_comment && pos.col > 0
|
||||
&& linep[pos.col - 1] == '*' && linep[pos.col] == '/')
|
||||
in_block_comment = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If FM_BLOCKSTOP given, stop at a '{' or '}' in column 0.
|
||||
*/
|
||||
@@ -2750,6 +2791,11 @@ findmatchlimit(
|
||||
&& check_prevcol(linep, pos.col - 1, '#', NULL))
|
||||
break;
|
||||
|
||||
// Skip matches inside comments when FM_SKIPCOMM is set.
|
||||
if (skip_comments && (in_block_comment
|
||||
|| (comment_col != MAXCOL && (int)pos.col >= comment_col)))
|
||||
break;
|
||||
|
||||
// Check for match outside of quotes, and inside of
|
||||
// quotes when the start is also inside of quotes.
|
||||
if ((!inquote || start_in_quotes == TRUE)
|
||||
|
||||
@@ -5526,5 +5526,85 @@ def Test_find_brace_backwards()
|
||||
bwipe!
|
||||
enddef
|
||||
|
||||
" Brackets inside comments must not affect C indent calculation (FM_SKIPCOMM)
|
||||
def Test_cindent_comment_brackets()
|
||||
# stray } in inline block comment must not confuse enclosing-brace search
|
||||
new
|
||||
setl cindent sw=4
|
||||
var code =<< trim [CODE]
|
||||
int foo() {
|
||||
/* } */
|
||||
int bar;
|
||||
}
|
||||
[CODE]
|
||||
setline(1, code)
|
||||
cursor(3, 1)
|
||||
normal ==
|
||||
assert_equal(' int bar;', getline(3))
|
||||
bwipe!
|
||||
|
||||
# stray } in // line comment: same
|
||||
new
|
||||
setl cindent sw=4
|
||||
var code2 =<< trim [CODE]
|
||||
int foo() {
|
||||
// }
|
||||
int bar;
|
||||
}
|
||||
[CODE]
|
||||
setline(1, code2)
|
||||
cursor(3, 1)
|
||||
normal ==
|
||||
assert_equal(' int bar;', getline(3))
|
||||
bwipe!
|
||||
|
||||
# stray } on continuation line inside multi-line block comment
|
||||
new
|
||||
setl cindent sw=4
|
||||
var code3 =<< trim [CODE]
|
||||
int foo() {
|
||||
/*
|
||||
}
|
||||
*/
|
||||
int bar;
|
||||
}
|
||||
[CODE]
|
||||
setline(1, code3)
|
||||
cursor(5, 1)
|
||||
normal ==
|
||||
assert_equal(' int bar;', getline(5))
|
||||
bwipe!
|
||||
|
||||
# { in inline block comment must not be treated as enclosing brace
|
||||
new
|
||||
setl cindent sw=4
|
||||
var code4 =<< trim [CODE]
|
||||
int foo() {
|
||||
/* { */
|
||||
int bar;
|
||||
}
|
||||
[CODE]
|
||||
setline(1, code4)
|
||||
cursor(3, 1)
|
||||
normal ==
|
||||
assert_equal(' int bar;', getline(3))
|
||||
bwipe!
|
||||
|
||||
# ) in inline block comment must not be treated as enclosing brace
|
||||
new
|
||||
setl cindent sw=4
|
||||
var code5 =<< trim [CODE]
|
||||
some_func(arg1,
|
||||
/* ) */ arg2,
|
||||
arg3);
|
||||
[CODE]
|
||||
setline(1, code5)
|
||||
cursor(3, 1)
|
||||
normal ==
|
||||
assert_equal(' arg3);', getline(3))
|
||||
bwipe!
|
||||
|
||||
enddef
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -729,6 +729,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
447,
|
||||
/**/
|
||||
446,
|
||||
/**/
|
||||
|
||||
@@ -1095,7 +1095,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
||||
#define FM_BACKWARD 0x01 // search backwards
|
||||
#define FM_FORWARD 0x02 // search forwards
|
||||
#define FM_BLOCKSTOP 0x04 // stop at start/end of block
|
||||
#define FM_SKIPCOMM 0x08 // skip comments
|
||||
#define FM_SKIPCOMM 0x08 // skip comments (cursor must start outside)
|
||||
|
||||
// Values for action argument for do_buffer() and close_buffer()
|
||||
#define DOBUF_GOTO 0 // go to specified buffer
|
||||
|
||||
Reference in New Issue
Block a user