mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #17254 from zeertzjq/vim-8.2.3787
vim-patch:8.2.{3787,3932,3934,3935,3938}: text formatting patches
This commit is contained in:
commit
5205bcc904
@ -952,11 +952,13 @@ int copy_indent(int size, char_u *src)
|
||||
///
|
||||
/// "second_line_indent": indent for after ^^D in Insert mode or if flag
|
||||
/// OPENLINE_COM_LIST
|
||||
/// "did_do_comment" is set to true when intentionally putting the comment
|
||||
/// leader in fromt of the new line.
|
||||
///
|
||||
/// @param dir FORWARD or BACKWARD
|
||||
///
|
||||
/// @return true on success, false on failure
|
||||
int open_line(int dir, int flags, int second_line_indent)
|
||||
int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
|
||||
{
|
||||
char_u *next_line = NULL; // copy of the next line
|
||||
char_u *p_extra = NULL; // what goes to next line
|
||||
@ -969,6 +971,7 @@ int open_line(int dir, int flags, int second_line_indent)
|
||||
bool retval = false; // return value
|
||||
int extra_len = 0; // length of p_extra string
|
||||
int lead_len; // length of comment leader
|
||||
int comment_start = 0; // start index of the comment leader
|
||||
char_u *lead_flags; // position in 'comments' for comment leader
|
||||
char_u *leader = NULL; // copy of comment leader
|
||||
char_u *allocated = NULL; // allocated memory
|
||||
@ -977,6 +980,7 @@ int open_line(int dir, int flags, int second_line_indent)
|
||||
pos_T *pos;
|
||||
bool do_si = (!p_paste && curbuf->b_p_si && !curbuf->b_p_cin
|
||||
&& *curbuf->b_p_inde == NUL);
|
||||
bool do_cindent;
|
||||
bool no_si = false; // reset did_si afterwards
|
||||
int first_char = NUL; // init for GCC
|
||||
int vreplace_mode;
|
||||
@ -1189,11 +1193,30 @@ int open_line(int dir, int flags, int second_line_indent)
|
||||
did_ai = true;
|
||||
}
|
||||
|
||||
// May do indenting after opening a new line.
|
||||
do_cindent = !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL)
|
||||
&& in_cinkeys(dir == FORWARD ? KEY_OPEN_FORW : KEY_OPEN_BACK,
|
||||
' ', linewhite(curwin->w_cursor.lnum));
|
||||
|
||||
// Find out if the current line starts with a comment leader.
|
||||
// This may then be inserted in front of the new line.
|
||||
end_comment_pending = NUL;
|
||||
if (flags & OPENLINE_DO_COM) {
|
||||
if (flags & OPENLINE_DO_COM && dir == FORWARD) {
|
||||
// Check for a line comment after code.
|
||||
lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD, true);
|
||||
if (lead_len == 0 && do_cindent) {
|
||||
comment_start = check_linecomment(saved_line);
|
||||
if (comment_start != MAXCOL) {
|
||||
lead_len = get_leader_len(saved_line + comment_start,
|
||||
&lead_flags, false, true);
|
||||
if (lead_len != 0) {
|
||||
lead_len += comment_start;
|
||||
if (did_do_comment != NULL) {
|
||||
*did_do_comment = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lead_len = 0;
|
||||
}
|
||||
@ -1349,6 +1372,13 @@ int open_line(int dir, int flags, int second_line_indent)
|
||||
|
||||
STRLCPY(leader, saved_line, lead_len + 1);
|
||||
|
||||
// TODO(vim): handle multi-byte and double width chars
|
||||
for (int li = 0; li < comment_start; li++) {
|
||||
if (!ascii_iswhite(leader[li])) {
|
||||
leader[li] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
// Replace leader with lead_repl, right or left adjusted
|
||||
if (lead_repl != NULL) {
|
||||
int c = 0;
|
||||
@ -1758,13 +1788,7 @@ int open_line(int dir, int flags, int second_line_indent)
|
||||
ai_col = (colnr_T)getwhitecols_curline();
|
||||
}
|
||||
// May do indenting after opening a new line.
|
||||
if (!p_paste
|
||||
&& (curbuf->b_p_cin
|
||||
|| *curbuf->b_p_inde != NUL
|
||||
)
|
||||
&& in_cinkeys(dir == FORWARD
|
||||
? KEY_OPEN_FORW
|
||||
: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum))) {
|
||||
if (do_cindent) {
|
||||
do_c_expr_indent();
|
||||
ai_col = (colnr_T)getwhitecols_curline();
|
||||
}
|
||||
|
@ -6021,6 +6021,7 @@ static void internal_format(int textwidth, int second_indent, int flags, int for
|
||||
char_u *saved_text = NULL;
|
||||
colnr_T col;
|
||||
colnr_T end_col;
|
||||
bool did_do_comment = false;
|
||||
|
||||
virtcol = get_nolist_virtcol()
|
||||
+ char2cells(c != NUL ? c : gchar_cursor());
|
||||
@ -6136,8 +6137,7 @@ static void internal_format(int textwidth, int second_indent, int flags, int for
|
||||
if (curwin->w_cursor.col <= (colnr_T)wantcol) {
|
||||
break;
|
||||
}
|
||||
} else if ((cc >= 0x100 || !utf_allow_break_before(cc))
|
||||
&& fo_multibyte) {
|
||||
} else if ((cc >= 0x100 || !utf_allow_break_before(cc)) && fo_multibyte) {
|
||||
int ncc;
|
||||
bool allow_break;
|
||||
|
||||
@ -6294,11 +6294,18 @@ static void internal_format(int textwidth, int second_indent, int flags, int for
|
||||
+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
|
||||
+ (do_comments ? OPENLINE_DO_COM : 0)
|
||||
+ ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0),
|
||||
((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
|
||||
((flags & INSCHAR_COM_LIST) ? second_indent : old_indent),
|
||||
&did_do_comment);
|
||||
if (!(flags & INSCHAR_COM_LIST)) {
|
||||
old_indent = 0;
|
||||
}
|
||||
|
||||
// If a comment leader was inserted, may also do this on a following
|
||||
// line.
|
||||
if (did_do_comment) {
|
||||
no_leader = false;
|
||||
}
|
||||
|
||||
replace_offset = 0;
|
||||
if (first_line) {
|
||||
if (!(flags & INSCHAR_COM_LIST)) {
|
||||
@ -8292,6 +8299,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
||||
int in_indent;
|
||||
int oldState;
|
||||
int cpc[MAX_MCO]; // composing characters
|
||||
bool call_fix_indent = false;
|
||||
|
||||
// can't delete anything in an empty file
|
||||
// can't backup past first character in buffer
|
||||
@ -8435,6 +8443,8 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
||||
beginline(BL_WHITE);
|
||||
if (curwin->w_cursor.col < save_col) {
|
||||
mincol = curwin->w_cursor.col;
|
||||
// should now fix the indent to match with the previous line
|
||||
call_fix_indent = true;
|
||||
}
|
||||
curwin->w_cursor.col = save_col;
|
||||
}
|
||||
@ -8569,6 +8579,11 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
||||
if (curwin->w_cursor.col <= 1) {
|
||||
did_ai = false;
|
||||
}
|
||||
|
||||
if (call_fix_indent) {
|
||||
fix_indent();
|
||||
}
|
||||
|
||||
// It's a little strange to put backspaces into the redo
|
||||
// buffer, but it makes auto-indent a lot easier to deal
|
||||
// with.
|
||||
@ -9183,7 +9198,7 @@ static bool ins_eol(int c)
|
||||
AppendToRedobuff(NL_STR);
|
||||
bool i = open_line(FORWARD,
|
||||
has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0,
|
||||
old_indent);
|
||||
old_indent, NULL);
|
||||
old_indent = 0;
|
||||
can_cindent = true;
|
||||
// When inserting a line the cursor line must never be in a closed fold.
|
||||
|
@ -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)
|
||||
{
|
||||
@ -143,7 +135,7 @@ static pos_T *find_start_rawstring(int ind_maxcomment) // XXX
|
||||
* Skip to the end of a "string" and a 'c' character.
|
||||
* If there is no string or character, return argument unmodified.
|
||||
*/
|
||||
static char_u *skip_string(char_u *p)
|
||||
static const char_u *skip_string(const char_u *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -178,24 +170,24 @@ static char_u *skip_string(char_u *p)
|
||||
continue; // continue for another string
|
||||
}
|
||||
} else if (p[0] == 'R' && p[1] == '"') {
|
||||
// Raw string: R"[delim](...)[delim]"
|
||||
char_u *delim = p + 2;
|
||||
char_u *paren = vim_strchr(delim, '(');
|
||||
// Raw string: R"[delim](...)[delim]"
|
||||
const char_u *delim = p + 2;
|
||||
const char_u *paren = vim_strchr(delim, '(');
|
||||
|
||||
if (paren != NULL) {
|
||||
const ptrdiff_t delim_len = paren - delim;
|
||||
if (paren != NULL) {
|
||||
const ptrdiff_t delim_len = paren - delim;
|
||||
|
||||
for (p += 3; *p; ++p)
|
||||
if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0
|
||||
&& p[delim_len + 1] == '"')
|
||||
{
|
||||
p += delim_len + 1;
|
||||
break;
|
||||
}
|
||||
if (p[0] == '"') {
|
||||
continue; // continue for another string
|
||||
}
|
||||
for (p += 3; *p; p++) {
|
||||
if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0
|
||||
&& p[delim_len + 1] == '"') {
|
||||
p += delim_len + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p[0] == '"') {
|
||||
continue; // continue for another string
|
||||
}
|
||||
}
|
||||
}
|
||||
break; // no string found
|
||||
}
|
||||
@ -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(const char_u *line, colnr_T col)
|
||||
{
|
||||
const 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.
|
||||
@ -218,7 +220,7 @@ static char_u *skip_string(char_u *p)
|
||||
/*
|
||||
* Return true if the string "line" starts with a word from 'cinwords'.
|
||||
*/
|
||||
bool cin_is_cinword(char_u *line)
|
||||
bool cin_is_cinword(const char_u *line)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
@ -246,10 +248,10 @@ bool cin_is_cinword(char_u *line)
|
||||
* Skip over white space and C comments within the line.
|
||||
* Also skip over Perl/shell comments if desired.
|
||||
*/
|
||||
static char_u *cin_skipcomment(char_u *s)
|
||||
static const char_u *cin_skipcomment(const char_u *s)
|
||||
{
|
||||
while (*s) {
|
||||
char_u *prev_s = s;
|
||||
const char_u *prev_s = s;
|
||||
|
||||
s = skipwhite(s);
|
||||
|
||||
@ -283,7 +285,7 @@ static char_u *cin_skipcomment(char_u *s)
|
||||
* Return TRUE if there is no code at *s. White space and comments are
|
||||
* not considered code.
|
||||
*/
|
||||
static int cin_nocode(char_u *s)
|
||||
static int cin_nocode(const char_u *s)
|
||||
{
|
||||
return *cin_skipcomment(s) == NUL;
|
||||
}
|
||||
@ -312,9 +314,9 @@ static pos_T *find_line_comment(void) // XXX
|
||||
}
|
||||
|
||||
/// Checks if `text` starts with "key:".
|
||||
static bool cin_has_js_key(char_u *text)
|
||||
static bool cin_has_js_key(const char_u *text)
|
||||
{
|
||||
char_u *s = skipwhite(text);
|
||||
const char_u *s = skipwhite(text);
|
||||
|
||||
char_u quote = 0;
|
||||
if (*s == '\'' || *s == '"') {
|
||||
@ -341,7 +343,7 @@ static bool cin_has_js_key(char_u *text)
|
||||
|
||||
/// Checks if string matches "label:"; move to character after ':' if true.
|
||||
/// "*s" must point to the start of the label, if there is one.
|
||||
static bool cin_islabel_skip(char_u **s)
|
||||
static bool cin_islabel_skip(const char_u **s)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
if (!vim_isIDc(**s)) { // need at least one ID character
|
||||
@ -361,7 +363,7 @@ static bool cin_islabel_skip(char_u **s)
|
||||
// Note: curwin->w_cursor must be where we are looking for the label.
|
||||
bool cin_islabel(void) // XXX
|
||||
{
|
||||
char_u *s = cin_skipcomment(get_cursor_line_ptr());
|
||||
const char_u *s = cin_skipcomment(get_cursor_line_ptr());
|
||||
|
||||
// Exclude "default" from labels, since it should be indented
|
||||
// like a switch label. Same for C++ scope declarations.
|
||||
@ -380,8 +382,8 @@ bool cin_islabel(void) // XXX
|
||||
* label.
|
||||
*/
|
||||
pos_T cursor_save;
|
||||
pos_T *trypos;
|
||||
char_u *line;
|
||||
pos_T *trypos;
|
||||
const char_u *line;
|
||||
|
||||
cursor_save = curwin->w_cursor;
|
||||
while (curwin->w_cursor.lnum > 1) {
|
||||
@ -424,8 +426,8 @@ bool cin_islabel(void) // XXX
|
||||
*/
|
||||
static int cin_isinit(void)
|
||||
{
|
||||
char_u *s;
|
||||
static char *skip[] = {"static", "public", "protected", "private"};
|
||||
const char_u *s;
|
||||
static char *skip[] = { "static", "public", "protected", "private" };
|
||||
|
||||
s = cin_skipcomment(get_cursor_line_ptr());
|
||||
|
||||
@ -460,7 +462,7 @@ static int cin_isinit(void)
|
||||
* Recognize a switch label: "case .*:" or "default:".
|
||||
*/
|
||||
bool cin_iscase(
|
||||
char_u *s,
|
||||
const char_u *s,
|
||||
bool strict // Allow relaxed check of case statement for JS
|
||||
)
|
||||
{
|
||||
@ -503,7 +505,7 @@ bool cin_iscase(
|
||||
/*
|
||||
* Recognize a "default" switch label.
|
||||
*/
|
||||
static int cin_isdefault(char_u *s)
|
||||
static int cin_isdefault(const char_u *s)
|
||||
{
|
||||
return STRNCMP(s, "default", 7) == 0
|
||||
&& *(s = cin_skipcomment(s + 7)) == ':'
|
||||
@ -513,7 +515,7 @@ static int cin_isdefault(char_u *s)
|
||||
/*
|
||||
* Recognize a "public/private/protected" scope declaration label.
|
||||
*/
|
||||
bool cin_isscopedecl(char_u *s)
|
||||
bool cin_isscopedecl(const char_u *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -534,9 +536,9 @@ bool cin_isscopedecl(char_u *s)
|
||||
#define FIND_NAMESPACE_LIM 20
|
||||
|
||||
// Recognize a "namespace" scope declaration.
|
||||
static bool cin_is_cpp_namespace(char_u *s)
|
||||
static bool cin_is_cpp_namespace(const char_u *s)
|
||||
{
|
||||
char_u *p;
|
||||
const char_u *p;
|
||||
bool has_name = false;
|
||||
bool has_name_start = false;
|
||||
|
||||
@ -581,7 +583,7 @@ static bool cin_is_cpp_namespace(char_u *s)
|
||||
* case 234: a = b;
|
||||
* ^
|
||||
*/
|
||||
static char_u *after_label(char_u *l)
|
||||
static const char_u *after_label(const char_u *l)
|
||||
{
|
||||
for (; *l; ++l) {
|
||||
if (*l == ':') {
|
||||
@ -608,10 +610,10 @@ static char_u *after_label(char_u *l)
|
||||
*/
|
||||
static int get_indent_nolabel(linenr_T lnum) // XXX
|
||||
{
|
||||
char_u *l;
|
||||
const char_u *l;
|
||||
pos_T fp;
|
||||
colnr_T col;
|
||||
char_u *p;
|
||||
const char_u *p;
|
||||
|
||||
l = ml_get(lnum);
|
||||
p = after_label(l);
|
||||
@ -630,9 +632,9 @@ static int get_indent_nolabel(linenr_T lnum) // XXX
|
||||
* label: if (asdf && asdfasdf)
|
||||
* ^
|
||||
*/
|
||||
static int skip_label(linenr_T lnum, char_u **pp)
|
||||
static int skip_label(linenr_T lnum, const char_u **pp)
|
||||
{
|
||||
char_u *l;
|
||||
const char_u *l;
|
||||
int amount;
|
||||
pos_T cursor_save;
|
||||
|
||||
@ -713,8 +715,8 @@ static int cin_first_id_amount(void)
|
||||
*/
|
||||
static int cin_get_equal_amount(linenr_T lnum)
|
||||
{
|
||||
char_u *line;
|
||||
char_u *s;
|
||||
const char_u *line;
|
||||
const char_u *s;
|
||||
colnr_T col;
|
||||
pos_T fp;
|
||||
|
||||
@ -752,7 +754,7 @@ static int cin_get_equal_amount(linenr_T lnum)
|
||||
/*
|
||||
* Recognize a preprocessor statement: Any line that starts with '#'.
|
||||
*/
|
||||
static int cin_ispreproc(char_u *s)
|
||||
static int cin_ispreproc(const char_u *s)
|
||||
{
|
||||
if (*skipwhite(s) == '#')
|
||||
return TRUE;
|
||||
@ -763,9 +765,9 @@ static int cin_ispreproc(char_u *s)
|
||||
/// continuation line of a preprocessor statement. Decrease "*lnump" to the
|
||||
/// start and return the line in "*pp".
|
||||
/// Put the amount of indent in "*amount".
|
||||
static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
|
||||
static int cin_ispreproc_cont(const char_u **pp, linenr_T *lnump, int *amount)
|
||||
{
|
||||
char_u *line = *pp;
|
||||
const char_u *line = *pp;
|
||||
linenr_T lnum = *lnump;
|
||||
int retval = false;
|
||||
int candidate_amount = *amount;
|
||||
@ -799,7 +801,7 @@ static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
|
||||
/*
|
||||
* Recognize the start of a C or C++ comment.
|
||||
*/
|
||||
static int cin_iscomment(char_u *p)
|
||||
static int cin_iscomment(const char_u *p)
|
||||
{
|
||||
return p[0] == '/' && (p[1] == '*' || p[1] == '/');
|
||||
}
|
||||
@ -807,7 +809,7 @@ static int cin_iscomment(char_u *p)
|
||||
/*
|
||||
* Recognize the start of a "//" comment.
|
||||
*/
|
||||
static int cin_islinecomment(char_u *p)
|
||||
static int cin_islinecomment(const char_u *p)
|
||||
{
|
||||
return p[0] == '/' && p[1] == '/';
|
||||
}
|
||||
@ -822,8 +824,8 @@ static int cin_islinecomment(char_u *p)
|
||||
* both apply in order to determine initializations).
|
||||
*/
|
||||
static char_u
|
||||
cin_isterminated (
|
||||
char_u *s,
|
||||
cin_isterminated(
|
||||
const char_u *s,
|
||||
int incl_open, // include '{' at the end as terminator
|
||||
int incl_comma // recognize a trailing comma
|
||||
)
|
||||
@ -872,9 +874,9 @@ cin_isterminated (
|
||||
/// lines here.
|
||||
/// @param[in] first_lnum Where to start looking.
|
||||
/// @param[in] min_lnum The line before which we will not be looking.
|
||||
static int cin_isfuncdecl(char_u **sp, linenr_T first_lnum, linenr_T min_lnum)
|
||||
static int cin_isfuncdecl(const char_u **sp, linenr_T first_lnum, linenr_T min_lnum)
|
||||
{
|
||||
char_u *s;
|
||||
const char_u *s;
|
||||
linenr_T lnum = first_lnum;
|
||||
linenr_T save_lnum = curwin->w_cursor.lnum;
|
||||
int retval = false;
|
||||
@ -975,12 +977,12 @@ done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cin_isif(char_u *p)
|
||||
static int cin_isif(const char_u *p)
|
||||
{
|
||||
return STRNCMP(p, "if", 2) == 0 && !vim_isIDc(p[2]);
|
||||
}
|
||||
|
||||
static int cin_iselse(char_u *p)
|
||||
static int cin_iselse(const char_u *p)
|
||||
{
|
||||
if (*p == '}') { // accept "} else"
|
||||
p = cin_skipcomment(p + 1);
|
||||
@ -988,7 +990,7 @@ static int cin_iselse(char_u *p)
|
||||
return STRNCMP(p, "else", 4) == 0 && !vim_isIDc(p[4]);
|
||||
}
|
||||
|
||||
static int cin_isdo(char_u *p)
|
||||
static int cin_isdo(const char_u *p)
|
||||
{
|
||||
return STRNCMP(p, "do", 2) == 0 && !vim_isIDc(p[2]);
|
||||
}
|
||||
@ -998,7 +1000,7 @@ static int cin_isdo(char_u *p)
|
||||
* We only accept a "while (condition) ;", with only white space between the
|
||||
* ')' and ';'. The condition may be spread over several lines.
|
||||
*/
|
||||
static int cin_iswhileofdo(char_u *p, linenr_T lnum) // XXX
|
||||
static int cin_iswhileofdo(const char_u *p, linenr_T lnum) // XXX
|
||||
{
|
||||
pos_T cursor_save;
|
||||
pos_T *trypos;
|
||||
@ -1032,7 +1034,7 @@ static int cin_iswhileofdo(char_u *p, linenr_T lnum) // XXX
|
||||
* Otherwise return !0 and update "*poffset" to point to the place where the
|
||||
* string was found.
|
||||
*/
|
||||
static int cin_is_if_for_while_before_offset(char_u *line, int *poffset)
|
||||
static int cin_is_if_for_while_before_offset(const char_u *line, int *poffset)
|
||||
{
|
||||
int offset = *poffset;
|
||||
|
||||
@ -1076,10 +1078,10 @@ probablyFound:
|
||||
*/
|
||||
static int cin_iswhileofdo_end(int terminated)
|
||||
{
|
||||
char_u *line;
|
||||
char_u *p;
|
||||
char_u *s;
|
||||
pos_T *trypos;
|
||||
const char_u *line;
|
||||
const char_u *p;
|
||||
const char_u *s;
|
||||
pos_T *trypos;
|
||||
int i;
|
||||
|
||||
if (terminated != ';') { // there must be a ';' at the end
|
||||
@ -1119,7 +1121,7 @@ static int cin_iswhileofdo_end(int terminated)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int cin_isbreak(char_u *p)
|
||||
static int cin_isbreak(const char_u *p)
|
||||
{
|
||||
return STRNCMP(p, "break", 5) == 0 && !vim_isIDc(p[5]);
|
||||
}
|
||||
@ -1139,10 +1141,10 @@ static int cin_isbreak(char_u *p)
|
||||
*/
|
||||
static int cin_is_cpp_baseclass(cpp_baseclass_cache_T *cached) {
|
||||
lpos_T *pos = &cached->lpos; // find position
|
||||
char_u *s;
|
||||
const char_u *s;
|
||||
int class_or_struct, lookfor_ctor_init, cpp_base_class;
|
||||
linenr_T lnum = curwin->w_cursor.lnum;
|
||||
char_u *line = get_cursor_line_ptr();
|
||||
const char_u *line = get_cursor_line_ptr();
|
||||
|
||||
if (pos->lnum <= lnum) {
|
||||
return cached->found; // Use the cached result
|
||||
@ -1310,10 +1312,10 @@ static int get_baseclass_amount(int col)
|
||||
* white space and comments. Skip strings and comments.
|
||||
* Ignore "ignore" after "find" if it's not NULL.
|
||||
*/
|
||||
static int cin_ends_in(char_u *s, char_u *find, char_u *ignore)
|
||||
static int cin_ends_in(const char_u *s, const char_u *find, const char_u *ignore)
|
||||
{
|
||||
char_u *p = s;
|
||||
char_u *r;
|
||||
const char_u *p = s;
|
||||
const char_u *r;
|
||||
int len = (int)STRLEN(find);
|
||||
|
||||
while (*p != NUL) {
|
||||
@ -1334,7 +1336,7 @@ static int cin_ends_in(char_u *s, char_u *find, char_u *ignore)
|
||||
/*
|
||||
* Return TRUE when "s" starts with "word" and then a non-ID character.
|
||||
*/
|
||||
static int cin_starts_with(char_u *s, char *word)
|
||||
static int cin_starts_with(const char_u *s, const char *word)
|
||||
{
|
||||
int l = (int)STRLEN(word);
|
||||
|
||||
@ -1342,10 +1344,10 @@ static int cin_starts_with(char_u *s, char *word)
|
||||
}
|
||||
|
||||
/// Recognize a `extern "C"` or `extern "C++"` linkage specifications.
|
||||
static int cin_is_cpp_extern_c(char_u *s)
|
||||
static int cin_is_cpp_extern_c(const char_u *s)
|
||||
{
|
||||
char_u *p;
|
||||
int has_string_literal = false;
|
||||
const 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]))) {
|
||||
@ -1384,9 +1386,9 @@ static int cin_is_cpp_extern_c(char_u *s)
|
||||
*/
|
||||
static int cin_skip2pos(pos_T *trypos)
|
||||
{
|
||||
char_u *line;
|
||||
char_u *p;
|
||||
char_u *new_p;
|
||||
const char_u *line;
|
||||
const char_u *p;
|
||||
const char_u *new_p;
|
||||
|
||||
p = line = ml_get(trypos->lnum);
|
||||
while (*p && (colnr_T)(p - line) < trypos->col) {
|
||||
@ -1529,7 +1531,7 @@ static int corr_ind_maxparen(pos_T *startpos)
|
||||
* Set w_cursor.col to the column number of the last unmatched ')' or '{' in
|
||||
* line "l". "l" must point to the start of the line.
|
||||
*/
|
||||
static int find_last_paren(char_u *l, int start, int end)
|
||||
static int find_last_paren(const char_u *l, int start, int end)
|
||||
{
|
||||
int i;
|
||||
int retval = FALSE;
|
||||
@ -1801,8 +1803,8 @@ int get_c_indent(void)
|
||||
#define BRACE_AT_START 2 // '{' is at start of line
|
||||
#define BRACE_AT_END 3 // '{' is at end of line
|
||||
linenr_T ourscope;
|
||||
char_u *l;
|
||||
char_u *look;
|
||||
const char_u *l;
|
||||
const char_u *look;
|
||||
char_u terminated;
|
||||
int lookfor;
|
||||
#define LOOKFOR_INITIAL 0
|
||||
@ -1906,12 +1908,25 @@ int get_c_indent(void)
|
||||
* If we're inside a "//" comment and there is a "//" comment in a
|
||||
* previous line, lineup with that one.
|
||||
*/
|
||||
if (cin_islinecomment(theline)
|
||||
&& (trypos = find_line_comment()) != NULL) { // XXX
|
||||
// find how indented the line beginning the comment is
|
||||
getvcol(curwin, trypos, &col, NULL, NULL);
|
||||
amount = col;
|
||||
goto theend;
|
||||
if (cin_islinecomment(theline)) {
|
||||
pos_T linecomment_pos;
|
||||
|
||||
trypos = find_line_comment(); // XXX
|
||||
if (trypos == NULL && curwin->w_cursor.lnum > 1) {
|
||||
// There may be a statement before the comment, search from the end
|
||||
// of the line for a comment start.
|
||||
linecomment_pos.col = check_linecomment(ml_get(curwin->w_cursor.lnum - 1));
|
||||
if (linecomment_pos.col != MAXCOL) {
|
||||
trypos = &linecomment_pos;
|
||||
trypos->lnum = curwin->w_cursor.lnum - 1;
|
||||
}
|
||||
}
|
||||
if (trypos != NULL) {
|
||||
// find how indented the line beginning the comment is
|
||||
getvcol(curwin, trypos, &col, NULL, NULL);
|
||||
amount = col;
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If we're inside a comment and not looking at the start of the
|
||||
@ -3602,9 +3617,9 @@ laterend:
|
||||
|
||||
static int find_match(int lookfor, linenr_T ourscope)
|
||||
{
|
||||
char_u *look;
|
||||
pos_T *theirscope;
|
||||
char_u *mightbeif;
|
||||
const char_u *look;
|
||||
pos_T *theirscope;
|
||||
const char_u *mightbeif;
|
||||
int elselevel;
|
||||
int whilelevel;
|
||||
|
||||
|
@ -6685,9 +6685,8 @@ static void n_opencmd(cmdarg_T *cap)
|
||||
(cap->cmdchar == 'o' ? 1 : 0))
|
||||
)
|
||||
&& open_line(cap->cmdchar == 'O' ? BACKWARD : FORWARD,
|
||||
has_format_option(FO_OPEN_COMS)
|
||||
? OPENLINE_DO_COM : 0,
|
||||
0)) {
|
||||
has_format_option(FO_OPEN_COMS) ? OPENLINE_DO_COM : 0,
|
||||
0, NULL)) {
|
||||
if (win_cursorline_standout(curwin)) {
|
||||
// force redraw of cursorline
|
||||
curwin->w_valid &= ~VALID_CROW;
|
||||
|
@ -4350,7 +4350,7 @@ void format_lines(linenr_T line_count, int avoid_fex)
|
||||
int leader_len = 0; // leader len of current line
|
||||
int next_leader_len; // leader len of next line
|
||||
char_u *leader_flags = NULL; // flags for leader of current line
|
||||
char_u *next_leader_flags; // flags for leader of next line
|
||||
char_u *next_leader_flags = NULL; // flags for leader of next line
|
||||
bool advance = true;
|
||||
int second_indent = -1; // indent for second line (comment aware)
|
||||
bool first_par_line = true;
|
||||
@ -4467,7 +4467,14 @@ void format_lines(linenr_T line_count, int avoid_fex)
|
||||
leader_len, leader_flags,
|
||||
next_leader_len,
|
||||
next_leader_flags)) {
|
||||
is_end_par = true;
|
||||
// Special case: If the next line starts with a line comment
|
||||
// and this line has a line comment after some text, the
|
||||
// paragraph doesn't really end.
|
||||
if (next_leader_flags == NULL
|
||||
|| STRNCMP(next_leader_flags, "://", 3) != 0
|
||||
|| check_linecomment(get_cursor_line_ptr()) == MAXCOL) {
|
||||
is_end_par = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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,12 +2314,9 @@ 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.
|
||||
*/
|
||||
static int check_linecomment(const char_u *line)
|
||||
/// 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
|
||||
// skip Lispish one-line comments
|
||||
@ -2338,7 +2336,8 @@ static 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 @@ static 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;
|
||||
|
@ -1707,9 +1707,9 @@ func Test_cindent_1()
|
||||
#endif
|
||||
|
||||
int y; // comment
|
||||
// comment
|
||||
// comment
|
||||
|
||||
// comment
|
||||
// comment
|
||||
|
||||
{
|
||||
Constructor(int a,
|
||||
|
@ -196,6 +196,104 @@ func Test_text_format()
|
||||
enew!
|
||||
endfunc
|
||||
|
||||
func Test_format_c_comment()
|
||||
new
|
||||
setl ai cindent tw=40 et fo=croql
|
||||
let text =<< trim END
|
||||
var = 2345; // asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
|
||||
END
|
||||
call setline(1, text)
|
||||
normal gql
|
||||
let expected =<< trim END
|
||||
var = 2345; // asdf asdf asdf asdf asdf
|
||||
// asdf asdf asdf asdf asdf
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
|
||||
%del
|
||||
let text =<< trim END
|
||||
var = 2345; // asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
|
||||
END
|
||||
call setline(1, text)
|
||||
normal gql
|
||||
let expected =<< trim END
|
||||
var = 2345; // asdf asdf asdf asdf asdf
|
||||
// asdf asdf asdf asdf asdf
|
||||
// asdf asdf
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
|
||||
%del
|
||||
let text =<< trim END
|
||||
#if 0 // This is another long end of
|
||||
// line comment that
|
||||
// wraps.
|
||||
END
|
||||
call setline(1, text)
|
||||
normal gq2j
|
||||
let expected =<< trim END
|
||||
#if 0 // This is another long
|
||||
// end of line comment
|
||||
// that wraps.
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
|
||||
" Using "o" repeats the line comment, "O" does not.
|
||||
%del
|
||||
let text =<< trim END
|
||||
nop;
|
||||
val = val; // This is a comment
|
||||
END
|
||||
call setline(1, text)
|
||||
normal 2Go
|
||||
let expected =<< trim END
|
||||
nop;
|
||||
val = val; // This is a comment
|
||||
//
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
normal 2GO
|
||||
let expected =<< trim END
|
||||
nop;
|
||||
|
||||
val = val; // This is a 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
|
||||
{
|
||||
val = val; // This is a comment
|
||||
END
|
||||
call setline(1, text)
|
||||
exe "normal! 2Go\<C-U>x\<Esc>"
|
||||
let expected =<< trim END
|
||||
{
|
||||
val = val; // This is a comment
|
||||
x
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Tests for :right, :center and :left on text with embedded TAB.
|
||||
func Test_format_align()
|
||||
enew!
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user