Skip to content

Commit

Permalink
patch 8.0.0431: 'cinoptions' cannot set indent for extern block
Browse files Browse the repository at this point in the history
Problem:    'cinoptions' cannot set indent for extern block.
Solution:   Add the "E" flag in 'cinoptions'. (Hirohito Higashi)
  • Loading branch information
brammool committed Mar 8, 2017
1 parent bb96226 commit 7720ba8
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 3 deletions.
17 changes: 16 additions & 1 deletion runtime/doc/indent.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -324,6 +324,21 @@ The examples below assume a 'shiftwidth' of 4.
{ { { {
void function(); void function(); void function(); void function();
} } } }
<
*cino-E*
EN Indent inside C++ linkage specifications (extern "C" or
extern "C++") N characters extra compared to a normal block.
(default 0).

cino= cino=E-s >
extern "C" { extern "C" {
void function(); void function();
} }
extern "C" extern "C"
{ {
void function(); void function();
} }
< <
*cino-p* *cino-p*
pN Parameter declarations for K&R-style function declarations will pN Parameter declarations for K&R-style function declarations will
Expand Down Expand Up @@ -554,7 +569,7 @@ The examples below assume a 'shiftwidth' of 4.




The defaults, spelled out in full, are: The defaults, spelled out in full, are:
cinoptions=>s,e0,n0,f0,{0,}0,^0,L-1,:s,=s,l0,b0,gs,hs,N0,ps,ts,is,+s, cinoptions=>s,e0,n0,f0,{0,}0,^0,L-1,:s,=s,l0,b0,gs,hs,N0,E0,ps,ts,is,+s,
c3,C0,/0,(2s,us,U0,w0,W0,k0,m0,j0,J0,)20,*70,#0 c3,C0,/0,(2s,us,U0,w0,W0,k0,m0,j0,J0,)20,*70,#0


Vim puts a line in column 1 if: Vim puts a line in column 1 if:
Expand Down
68 changes: 66 additions & 2 deletions src/misc1.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5809,6 +5809,54 @@ cin_is_cpp_namespace(char_u *s)
return FALSE; return FALSE;
} }


/*
* Recognize a `extern "C"` or `extern "C++"` linkage specifications.
*/
static int
cin_is_cpp_extern_c(char_u *s)
{
char_u *p;
int has_string_literal = FALSE;

s = cin_skipcomment(s);
if (STRNCMP(s, "extern", 6) == 0 && (s[6] == NUL || !vim_iswordc(s[6])))
{
p = cin_skipcomment(skipwhite(s + 6));
while (*p != NUL)
{
if (vim_iswhite(*p))
{
p = cin_skipcomment(skipwhite(p));
}
else if (*p == '{')
{
break;
}
else if (p[0] == '"' && p[1] == 'C' && p[2] == '"')
{
if (has_string_literal)
return FALSE;
has_string_literal = TRUE;
p += 3;
}
else if (p[0] == '"' && p[1] == 'C' && p[2] == '+' && p[3] == '+'
&& p[4] == '"')
{
if (has_string_literal)
return FALSE;
has_string_literal = TRUE;
p += 5;
}
else
{
return FALSE;
}
}
return has_string_literal ? TRUE : FALSE;
}
return FALSE;
}

/* /*
* Return a pointer to the first non-empty non-comment character after a ':'. * Return a pointer to the first non-empty non-comment character after a ':'.
* Return NULL if not found. * Return NULL if not found.
Expand Down Expand Up @@ -6652,6 +6700,7 @@ cin_skip2pos(pos_T *trypos)
{ {
char_u *line; char_u *line;
char_u *p; char_u *p;
char_u *new_p;


p = line = ml_get(trypos->lnum); p = line = ml_get(trypos->lnum);
while (*p && (colnr_T)(p - line) < trypos->col) while (*p && (colnr_T)(p - line) < trypos->col)
Expand All @@ -6660,8 +6709,11 @@ cin_skip2pos(pos_T *trypos)
p = cin_skipcomment(p); p = cin_skipcomment(p);
else else
{ {
p = skip_string(p); new_p = skip_string(p);
++p; if (new_p == p)
++p;
else
p = new_p;
} }
} }
return (int)(p - line); return (int)(p - line);
Expand Down Expand Up @@ -6977,6 +7029,9 @@ parse_cino(buf_T *buf)
/* indentation for # comments */ /* indentation for # comments */
buf->b_ind_hash_comment = 0; buf->b_ind_hash_comment = 0;


/* Handle C++ extern "C" or "C++" */
buf->b_ind_cpp_extern_c = 0;

for (p = buf->b_p_cino; *p; ) for (p = buf->b_p_cino; *p; )
{ {
l = p++; l = p++;
Expand Down Expand Up @@ -7051,6 +7106,7 @@ parse_cino(buf_T *buf)
case '#': buf->b_ind_hash_comment = n; break; case '#': buf->b_ind_hash_comment = n; break;
case 'N': buf->b_ind_cpp_namespace = n; break; case 'N': buf->b_ind_cpp_namespace = n; break;
case 'k': buf->b_ind_if_for_while = n; break; case 'k': buf->b_ind_if_for_while = n; break;
case 'E': buf->b_ind_cpp_extern_c = n; break;
} }
if (*p == ',') if (*p == ',')
++p; ++p;
Expand Down Expand Up @@ -7764,6 +7820,8 @@ get_c_indent(void)
l = skipwhite(ml_get_curline()); l = skipwhite(ml_get_curline());
if (cin_is_cpp_namespace(l)) if (cin_is_cpp_namespace(l))
amount += curbuf->b_ind_cpp_namespace; amount += curbuf->b_ind_cpp_namespace;
else if (cin_is_cpp_extern_c(l))
amount += curbuf->b_ind_cpp_extern_c;
} }
else else
{ {
Expand Down Expand Up @@ -7990,6 +8048,12 @@ get_c_indent(void)
- added_to_amount; - added_to_amount;
break; break;
} }
else if (cin_is_cpp_extern_c(l))
{
amount += curbuf->b_ind_cpp_extern_c
- added_to_amount;
break;
}


if (cin_nocode(l)) if (cin_nocode(l))
continue; continue;
Expand Down
1 change: 1 addition & 0 deletions src/structs.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2236,6 +2236,7 @@ struct file_buffer
int b_ind_hash_comment; int b_ind_hash_comment;
int b_ind_cpp_namespace; int b_ind_cpp_namespace;
int b_ind_if_for_while; int b_ind_if_for_while;
int b_ind_cpp_extern_c;
#endif #endif


linenr_T b_no_eol_lnum; /* non-zero lnum when last line of next binary linenr_T b_no_eol_lnum; /* non-zero lnum when last line of next binary
Expand Down
60 changes: 60 additions & 0 deletions src/testdir/test_cindent.vim
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,3 +14,63 @@ func Test_cino_hash()
call assert_equal(["#include <iostream>", "#include"], getline(1,2)) call assert_equal(["#include <iostream>", "#include"], getline(1,2))
bwipe! bwipe!
endfunc endfunc

func Test_cino_extern_c()
" Test for cino-E

let without_ind = [
\ '#ifdef __cplusplus',
\ 'extern "C" {',
\ '#endif',
\ 'int func_a(void);',
\ '#ifdef __cplusplus',
\ '}',
\ '#endif'
\ ]

let with_ind = [
\ '#ifdef __cplusplus',
\ 'extern "C" {',
\ '#endif',
\ "\tint func_a(void);",
\ '#ifdef __cplusplus',
\ '}',
\ '#endif'
\ ]
new
setlocal cindent cinoptions=E0
call setline(1, without_ind)
call feedkeys("gg=G", 'tx')
call assert_equal(with_ind, getline(1, '$'))

setlocal cinoptions=E-s
call setline(1, with_ind)
call feedkeys("gg=G", 'tx')
call assert_equal(without_ind, getline(1, '$'))

setlocal cinoptions=Es
let tests = [
\ ['recognized', ['extern "C" {'], "\t\t;"],
\ ['recognized', ['extern "C++" {'], "\t\t;"],
\ ['recognized', ['extern /* com */ "C"{'], "\t\t;"],
\ ['recognized', ['extern"C"{'], "\t\t;"],
\ ['recognized', ['extern "C"', '{'], "\t\t;"],
\ ['not recognized', ['extern {'], "\t;"],
\ ['not recognized', ['extern /*"C"*/{'], "\t;"],
\ ['not recognized', ['extern "C" //{'], ";"],
\ ['not recognized', ['extern "C" /*{*/'], ";"],
\ ]

for pair in tests
let lines = pair[1]
call setline(1, lines)
call feedkeys(len(lines) . "Go;", 'tx')
call assert_equal(pair[2], getline(len(lines) + 1), 'Failed for "' . string(lines) . '"')
endfor



bwipe!
endfunc

" vim: shiftwidth=2 sts=2 expandtab
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -764,6 +764,8 @@ static char *(features[]) =


static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
431,
/**/ /**/
430, 430,
/**/ /**/
Expand Down

0 comments on commit 7720ba8

Please sign in to comment.