aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c4
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/edit.c28
-rw-r--r--src/nvim/eval.c16
-rw-r--r--src/nvim/eval_defs.h2
-rw-r--r--src/nvim/ex_cmds.c6
-rw-r--r--src/nvim/fileio.c21
-rw-r--r--src/nvim/indent_c.c728
-rw-r--r--src/nvim/memline.c6
-rw-r--r--src/nvim/memline_defs.h2
-rw-r--r--src/nvim/normal.c7
-rw-r--r--src/nvim/ops.c12
-rw-r--r--src/nvim/option.c24
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/options.lua8
-rw-r--r--src/nvim/os/env.c12
-rw-r--r--src/nvim/os/shell.c3
-rw-r--r--src/nvim/os/win_defs.h6
-rw-r--r--src/nvim/po/it.po46
-rw-r--r--src/nvim/screen.c25
-rw-r--r--src/nvim/search.c116
-rw-r--r--src/nvim/testdir/test53.in4
-rw-r--r--src/nvim/testdir/test53.ok1
-rw-r--r--src/nvim/version.c34
24 files changed, 695 insertions, 418 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index fae8e9ecd0..762cd3efd3 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1414,7 +1414,6 @@ buflist_new (
return NULL;
if (aborting()) /* autocmds may abort script processing */
return NULL;
- /* buf->b_nwindows = 0; why was this here? */
free_buffer_stuff(buf, FALSE); /* delete local variables et al. */
/* Init the options. */
@@ -1475,6 +1474,9 @@ buflist_new (
fmarks_check_names(buf); /* check file marks for this file */
buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE; /* init 'buflisted' */
if (!(flags & BLN_DUMMY)) {
+ // Tricky: these autocommands may change the buffer list. They could also
+ // split the window with re-using the one empty buffer. This may result in
+ // unexpectedly losing the empty buffer.
apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
if (!buf_valid(buf)) {
return NULL;
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 3eabb7ee43..6b5bbe3b00 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -612,6 +612,7 @@ struct file_buffer {
char_u *b_p_cfu; /* 'completefunc' */
char_u *b_p_ofu; /* 'omnifunc' */
int b_p_eol; /* 'endofline' */
+ int b_p_fixeol; /* 'fixendofline' */
int b_p_et; /* 'expandtab' */
int b_p_et_nobin; /* b_p_et saved for binary mode */
char_u *b_p_fenc; /* 'fileencoding' */
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 8dc2844d8e..b3222b0781 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -5017,8 +5017,9 @@ insertchar (
int textwidth;
char_u *p;
int fo_ins_blank;
+ int force_format = flags & INSCHAR_FORMAT;
- textwidth = comp_textwidth(flags & INSCHAR_FORMAT);
+ textwidth = comp_textwidth(force_format);
fo_ins_blank = has_format_option(FO_INS_BLANK);
/*
@@ -5037,7 +5038,7 @@ insertchar (
* before 'textwidth'
*/
if (textwidth > 0
- && ((flags & INSCHAR_FORMAT)
+ && (force_format
|| (!ascii_iswhite(c)
&& !((State & REPLACE_FLAG)
&& !(State & VREPLACE_FLAG)
@@ -5051,8 +5052,11 @@ insertchar (
/* Format with 'formatexpr' when it's set. Use internal formatting
* when 'formatexpr' isn't set or it returns non-zero. */
int do_internal = TRUE;
+ colnr_T virtcol = get_nolist_virtcol()
+ + char2cells(c != NUL ? c : gchar_cursor());
- if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0) {
+ if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0
+ && (force_format || virtcol > (colnr_T)textwidth)) {
do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
/* It may be required to save for undo again, e.g. when setline()
* was called. */
@@ -6580,9 +6584,14 @@ static int cindent_on(void) {
*/
void fixthisline(IndentGetter get_the_indent)
{
- change_indent(INDENT_SET, get_the_indent(), FALSE, 0, TRUE);
- if (linewhite(curwin->w_cursor.lnum))
- did_ai = TRUE; /* delete the indent if the line stays empty */
+ int amount = get_the_indent();
+
+ if (amount >= 0) {
+ change_indent(INDENT_SET, amount, false, 0, true);
+ if (linewhite(curwin->w_cursor.lnum)) {
+ did_ai = true; // delete the indent if the line stays empty
+ }
+ }
}
void fix_indent(void) {
@@ -7427,15 +7436,14 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
* delete newline!
*/
if (curwin->w_cursor.col == 0) {
- lnum = Insstart_orig.lnum;
+ lnum = Insstart.lnum;
if (curwin->w_cursor.lnum == lnum || revins_on) {
if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
(linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) {
return FALSE;
}
- --Insstart_orig.lnum;
- Insstart_orig.col = MAXCOL;
- Insstart = Insstart_orig;
+ --Insstart.lnum;
+ Insstart.col = MAXCOL;
}
/*
* In replace mode:
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 4a2bf2ac7a..b60886704e 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5651,6 +5651,14 @@ bool garbage_collect(void)
ABORTING(set_ref_in_ht)(&fc->l_avars.dv_hashtab, copyID, NULL);
}
+ // Jobs
+ {
+ TerminalJobData *data;
+ map_foreach_value(jobs, data, {
+ ABORTING(set_ref_dict)(data->self, copyID);
+ })
+ }
+
// v: vars
ABORTING(set_ref_in_ht)(&vimvarht, copyID, NULL);
@@ -5728,8 +5736,7 @@ static int free_unref_items(int copyID)
// Go through the list of dicts and free items without the copyID.
// Don't free dicts that are referenced internally.
for (dict_T *dd = first_dict; dd != NULL; ) {
- if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
- && !dd->internal_refcount) {
+ if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
// Free the Dictionary and ordinary items it contains, but don't
// recurse into Lists and Dictionaries, they will be in the list
// of dicts or list of lists. */
@@ -5970,7 +5977,6 @@ dict_T *dict_alloc(void) FUNC_ATTR_NONNULL_RET
d->dv_scope = 0;
d->dv_refcount = 0;
d->dv_copyID = 0;
- d->internal_refcount = 0;
QUEUE_INIT(&d->watchers);
return d;
@@ -21620,7 +21626,6 @@ static inline bool common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout,
if (get_dict_callback(vopts, "on_stdout", on_stdout)
&& get_dict_callback(vopts, "on_stderr", on_stderr)
&& get_dict_callback(vopts, "on_exit", on_exit)) {
- vopts->internal_refcount++;
vopts->dv_refcount++;
return true;
}
@@ -21682,7 +21687,6 @@ static inline void free_term_job_data_event(void **argv)
}
if (data->self) {
- data->self->internal_refcount--;
dict_unref(data->self);
}
queue_free(data->events);
@@ -21933,7 +21937,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
true,
NULL);
- arguments->lv_refcount--;
+ list_unref(arguments);
// Restore caller scope information
restore_funccal(provider_caller_scope.funccalp);
provider_caller_scope = saved_provider_caller_scope;
diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h
index bd50d6b829..ed419268d2 100644
--- a/src/nvim/eval_defs.h
+++ b/src/nvim/eval_defs.h
@@ -118,8 +118,6 @@ struct dictvar_S {
dict_T *dv_copydict; /* copied dict used by deepcopy() */
dict_T *dv_used_next; /* next dict in used dicts list */
dict_T *dv_used_prev; /* previous dict in used dicts list */
- int internal_refcount; // number of internal references to
- // prevent garbage collection
QUEUE watchers; // dictionary key watchers set by user code
};
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 3f19421a75..d902234ef7 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2112,7 +2112,6 @@ do_ecmd (
goto theend;
if (buf->b_ml.ml_mfp == NULL) { /* no memfile yet */
oldbuf = FALSE;
- buf->b_nwindows = 0;
} else { /* existing memfile */
oldbuf = TRUE;
(void)buf_check_timestamp(buf, FALSE);
@@ -2138,7 +2137,7 @@ do_ecmd (
* Make the (new) buffer the one used by the current window.
* If the old buffer becomes unused, free it if ECMD_HIDE is FALSE.
* If the current buffer was empty and has no file name, curbuf
- * is returned by buflist_new().
+ * is returned by buflist_new(), nothing to do here.
*/
if (buf != curbuf) {
/*
@@ -2225,8 +2224,7 @@ do_ecmd (
}
xfree(new_name);
au_new_curbuf = NULL;
- } else
- ++curbuf->b_nwindows;
+ }
curwin->w_pcmark.lnum = 1;
curwin->w_pcmark.col = 0;
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index bc5b08ef24..1a6c85abaa 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1544,6 +1544,11 @@ rewind_retry:
/* First try finding a NL, for Dos and Unix */
if (try_dos || try_unix) {
for (p = ptr; p < ptr + size; ++p) {
+ // Reset the carriage return counter.
+ if (try_mac) {
+ try_mac = 1;
+ }
+
if (*p == NL) {
if (!try_unix
|| (try_dos && p > ptr && p[-1] == CAR))
@@ -1551,6 +1556,8 @@ rewind_retry:
else
fileformat = EOL_UNIX;
break;
+ } else if (*p == CAR && try_mac) {
+ try_mac++;
}
}
@@ -1571,6 +1578,10 @@ rewind_retry:
if (try_mac > try_unix)
fileformat = EOL_MAC;
}
+ } else if (fileformat == EOL_UNKNOWN && try_mac == 1) {
+ // Looking for CR but found no end-of-line markers at all:
+ // use the default format.
+ fileformat = default_fileformat();
}
}
@@ -1922,10 +1933,10 @@ failed:
check_marks_read();
/*
- * Trick: We remember if the last line of the read didn't have
- * an eol even when 'binary' is off, for when writing it again with
- * 'binary' on. This is required for
- * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
+ * We remember if the last line of the read didn't have
+ * an eol even when 'binary' is off, to support turning 'fixeol' off,
+ * or writing the read again with 'binary' on. The latter is required
+ * for ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
*/
curbuf->b_no_eol_lnum = read_no_eol_lnum;
@@ -3310,7 +3321,7 @@ restore_backup:
/* write failed or last line has no EOL: stop here */
if (end == 0
|| (lnum == end
- && write_bin
+ && (write_bin || !buf->b_p_fixeol)
&& (lnum == buf->b_no_eol_lnum
|| (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol)))) {
++lnum; /* written the line, count it */
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index d62e7aad03..340287499e 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -17,7 +17,11 @@
#include "nvim/search.h"
#include "nvim/strings.h"
-
+// Find result cache for cpp_baseclass
+typedef struct {
+ int found;
+ lpos_T lpos;
+} cpp_baseclass_cache_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "indent_c.c.generated.h"
@@ -25,6 +29,7 @@
/*
* 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.
+ * Return NULL when not inside a comment.
*/
static pos_T *ind_find_start_comment(void)
{ /* XXX */
@@ -65,6 +70,62 @@ find_start_comment ( /* XXX */
}
/*
+ * Find the start of a comment or raw string, not knowing if we are in a
+ * comment or raw string right now.
+ * Search starts at w_cursor.lnum and goes backwards.
+ * Return NULL when not inside a comment or raw string.
+ * "CORS" -> Comment Or Raw String
+ */
+static pos_T *ind_find_start_CORS(void)
+{ /* XXX */
+ pos_T *comment_pos = find_start_comment(curbuf->b_ind_maxcomment);
+ pos_T *rs_pos = find_start_rawstring(curbuf->b_ind_maxcomment);
+
+ /* If comment_pos is before rs_pos the raw string is inside the comment.
+ * If rs_pos is before comment_pos the comment is inside the raw string. */
+ if (comment_pos == NULL || (rs_pos != NULL && lt(*rs_pos, *comment_pos)))
+ return rs_pos;
+ return comment_pos;
+}
+
+/*
+ * Find the start of a raw string, not knowing if we are in one right now.
+ * Search starts at w_cursor.lnum and goes backwards.
+ * Return NULL when not inside a raw string.
+ */
+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 (;;)
+ {
+ pos = findmatchlimit(NULL, 'R', FM_BACKWARD, cur_maxcomment);
+ if (pos == NULL)
+ break;
+
+ /*
+ * 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;
+ cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
+ if (cur_maxcomment <= 0)
+ {
+ pos = NULL;
+ break;
+ }
+ }
+ return pos;
+}
+
+/*
* Skip to the end of a "string" and a 'c' character.
* If there is no string or character, return argument unmodified.
*/
@@ -97,7 +158,26 @@ static char_u *skip_string(char_u *p)
break;
}
if (p[0] == '"')
- continue;
+ 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, '(');
+
+ if (paren != NULL)
+ {
+ long 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 */
+ }
}
break; /* no string found */
}
@@ -288,10 +368,11 @@ int cin_islabel(void)
--curwin->w_cursor.lnum;
/*
- * If we're in a comment now, skip to the start of the comment.
+ * If we're in a comment or raw string now, skip to the start of
+ * it.
*/
curwin->w_cursor.col = 0;
- if ((trypos = ind_find_start_comment()) != NULL) /* XXX */
+ if ((trypos = ind_find_start_CORS()) != NULL) /* XXX */
curwin->w_cursor = *trypos;
line = get_cursor_line_ptr();
@@ -986,17 +1067,18 @@ static int cin_isbreak(char_u *p)
*
* This is a lot of guessing. Watch out for "cond ? func() : foo".
*/
-static int
-cin_is_cpp_baseclass (
- colnr_T *col /* return: column to align with */
-)
-{
+static int cin_is_cpp_baseclass(cpp_baseclass_cache_T *cached) {
+ lpos_T *pos = &cached->lpos; // find position
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();
- *col = 0;
+ if (pos->lnum <= lnum) {
+ return cached->found; // Use the cached result
+ }
+
+ pos->col = 0;
s = skipwhite(line);
if (*s == '#') /* skip #define FOO x ? (x) : x */
@@ -1038,6 +1120,7 @@ cin_is_cpp_baseclass (
--lnum;
}
+ pos->lnum = lnum;
line = ml_get(lnum);
s = cin_skipcomment(line);
for (;; ) {
@@ -1051,7 +1134,7 @@ cin_is_cpp_baseclass (
continue;
}
- if (s[0] == '"')
+ if (s[0] == '"' || (s[0] == 'R' && s[1] == '"'))
s = skip_string(s) + 1;
else if (s[0] == ':') {
if (s[1] == ':') {
@@ -1062,9 +1145,9 @@ cin_is_cpp_baseclass (
} else if (lookfor_ctor_init || class_or_struct) {
/* we have something found, that looks like the start of
* cpp-base-class-declaration or constructor-initialization */
- cpp_base_class = TRUE;
- lookfor_ctor_init = class_or_struct = FALSE;
- *col = 0;
+ cpp_base_class = true;
+ lookfor_ctor_init = class_or_struct = false;
+ pos->col = 0;
s = cin_skipcomment(s + 1);
} else
s = cin_skipcomment(s + 1);
@@ -1090,25 +1173,31 @@ cin_is_cpp_baseclass (
return FALSE;
} else if (!vim_isIDc(s[0])) {
/* if it is not an identifier, we are wrong */
- class_or_struct = FALSE;
- lookfor_ctor_init = FALSE;
- } else if (*col == 0) {
+ class_or_struct = false;
+ lookfor_ctor_init = false;
+ } else if (pos->col == 0) {
/* it can't be a constructor-initialization any more */
lookfor_ctor_init = FALSE;
/* the first statement starts here: lineup with this one... */
- if (cpp_base_class)
- *col = (colnr_T)(s - line);
+ if (cpp_base_class) {
+ pos->col = (colnr_T)(s - line);
+ }
}
/* When the line ends in a comma don't align with it. */
- if (lnum == curwin->w_cursor.lnum && *s == ',' && cin_nocode(s + 1))
- *col = 0;
+ if (lnum == curwin->w_cursor.lnum && *s == ',' && cin_nocode(s + 1)) {
+ pos->col = 0;
+ }
s = cin_skipcomment(s + 1);
}
}
+ cached->found = cpp_base_class;
+ if (cpp_base_class) {
+ pos->lnum = lnum;
+ }
return cpp_base_class;
}
@@ -1216,7 +1305,7 @@ static pos_T *find_start_brace(void)
pos = NULL;
/* ignore the { if it's in a // or / * * / comment */
if ((colnr_T)cin_skip2pos(trypos) == trypos->col
- && (pos = ind_find_start_comment()) == NULL) /* XXX */
+ && (pos = ind_find_start_CORS()) == NULL) /* XXX */
break;
if (pos != NULL)
curwin->w_cursor.lnum = pos->lnum;
@@ -1237,18 +1326,36 @@ static pos_T * find_match_char(char_u c, int ind_maxparen)
pos_T cursor_save;
pos_T *trypos;
static pos_T pos_copy;
+ int ind_maxp_wk;
cursor_save = curwin->w_cursor;
- if ((trypos = findmatchlimit(NULL, c, 0, ind_maxparen)) != NULL) {
- /* check if the ( is in a // comment */
- if ((colnr_T)cin_skip2pos(trypos) > trypos->col)
+ ind_maxp_wk = ind_maxparen;
+retry:
+ if ((trypos = findmatchlimit(NULL, c, 0, ind_maxp_wk)) != NULL) {
+ // check if the ( is in a // comment
+ if ((colnr_T)cin_skip2pos(trypos) > trypos->col) {
+ ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum - trypos->lnum);
+ if (ind_maxp_wk > 0) {
+ curwin->w_cursor = *trypos;
+ curwin->w_cursor.col = 0; // XXX
+ goto retry;
+ }
trypos = NULL;
- else {
+ } else {
+ pos_T *trypos_wk;
+
pos_copy = *trypos; /* copy trypos, findmatch will change it */
trypos = &pos_copy;
curwin->w_cursor = *trypos;
- if (ind_find_start_comment() != NULL)
+ if ((trypos_wk = ind_find_start_CORS()) != NULL) { /* XXX */
+ ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum
+ - trypos_wk->lnum);
+ if (ind_maxp_wk > 0) {
+ curwin->w_cursor = *trypos_wk;
+ goto retry;
+ }
trypos = NULL;
+ }
}
}
curwin->w_cursor = cursor_save;
@@ -1532,6 +1639,10 @@ void parse_cino(buf_T *buf)
}
}
+/*
+ * Return the desired indent for C code.
+ * Return -1 if the indent should be left alone (inside a raw string).
+ */
int get_c_indent(void)
{
pos_T cur_curpos;
@@ -1542,8 +1653,9 @@ int get_c_indent(void)
char_u *theline;
char_u *linecopy;
pos_T *trypos;
+ pos_T *comment_pos;
pos_T *tryposBrace = NULL;
- pos_T tryposBraceCopy;
+ pos_T tryposCopy;
pos_T our_paren_pos;
char_u *start;
int start_brace;
@@ -1567,7 +1679,7 @@ int get_c_indent(void)
#define LOOKFOR_CPP_BASECLASS 9
#define LOOKFOR_ENUM_OR_INIT 10
#define LOOKFOR_JS_KEY 11
-#define LOOKFOR_NO_COMMA 12
+#define LOOKFOR_COMMA 12
int whilelevel;
linenr_T lnum;
@@ -1578,6 +1690,7 @@ int get_c_indent(void)
int cont_amount = 0; /* amount for continuation line */
int original_line_islabel;
int added_to_amount = 0;
+ cpp_baseclass_cache_T cache_cpp_baseclass = { false, { MAXLNUM, 0 } };
/* make a copy, value is changed below */
int ind_continuation = curbuf->b_ind_continuation;
@@ -1585,7 +1698,7 @@ int get_c_indent(void)
/* remember where the cursor was when we started */
cur_curpos = curwin->w_cursor;
- /* if we are at line 1 0 is fine, right? */
+ /* if we are at line 1 zero indent is fine, right? */
if (cur_curpos.lnum == 1)
return 0;
@@ -1615,37 +1728,55 @@ int get_c_indent(void)
original_line_islabel = cin_islabel(); /* XXX */
/*
+ * If we are inside a raw string don't change the indent.
+ * Ignore a raw string inside a comment.
+ */
+ comment_pos = ind_find_start_comment();
+ if (comment_pos != NULL) {
+ /* findmatchlimit() static pos is overwritten, make a copy */
+ tryposCopy = *comment_pos;
+ comment_pos = &tryposCopy;
+ }
+ trypos = find_start_rawstring(curbuf->b_ind_maxcomment);
+ if (trypos != NULL && (comment_pos == NULL || lt(*trypos, *comment_pos))) {
+ amount = -1;
+ goto laterend;
+ }
+
+ /*
* #defines and so on always go at the left when included in 'cinkeys'.
*/
- if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE)))
+ if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', true))) {
amount = curbuf->b_ind_hash_comment;
+ goto theend;
+ }
/*
* Is it a non-case label? Then that goes at the left margin too unless:
* - JS flag is set.
* - 'L' item has a positive value.
*/
- else if (original_line_islabel && !curbuf->b_ind_js
+ if (original_line_islabel && !curbuf->b_ind_js
&& curbuf->b_ind_jump_label < 0) {
amount = 0;
+ goto theend;
}
/*
* If we're inside a "//" comment and there is a "//" comment in a
* previous line, lineup with that one.
*/
- else if (cin_islinecomment(theline)
+ 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 we're inside a comment and not looking at the start of the
* comment, try using the 'comments' option.
*/
- else if (!cin_iscomment(theline)
- && (trypos = ind_find_start_comment()) != NULL) {
- /* XXX */
+ if (!cin_iscomment(theline) && comment_pos != NULL) { /* XXX */
int lead_start_len = 2;
int lead_middle_len = 1;
char_u lead_start[COM_MAX_LEN]; /* start-comment string */
@@ -1657,7 +1788,7 @@ int get_c_indent(void)
int done = FALSE;
/* find how indented the line beginning the comment is */
- getvcol(curwin, trypos, &col, NULL, NULL);
+ getvcol(curwin, comment_pos, &col, NULL, NULL);
amount = col;
*lead_start = NUL;
*lead_middle = NUL;
@@ -1709,12 +1840,12 @@ int get_c_indent(void)
lead_middle_len) == 0) {
amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
break;
- }
- /* If the start comment string doesn't match with the
- * start of the comment, skip this entry. XXX */
- else if (STRNCMP(ml_get(trypos->lnum) + trypos->col,
- lead_start, lead_start_len) != 0)
+ } else if (STRNCMP(ml_get(comment_pos->lnum) + comment_pos->col,
+ lead_start, lead_start_len) != 0) {
+ /* If the start comment string doesn't match with the
+ * start of the comment, skip this entry. XXX */
continue;
+ }
}
if (start_off != 0)
amount += start_off;
@@ -1758,7 +1889,7 @@ int get_c_indent(void)
* otherwise, add the amount specified by "c" in 'cino'
*/
amount = -1;
- for (lnum = cur_curpos.lnum - 1; lnum > trypos->lnum; --lnum) {
+ for (lnum = cur_curpos.lnum - 1; lnum > comment_pos->lnum; --lnum) {
if (linewhite(lnum)) /* skip blank lines */
continue;
amount = get_indent_lnum(lnum); /* XXX */
@@ -1766,28 +1897,30 @@ int get_c_indent(void)
}
if (amount == -1) { /* use the comment opener */
if (!curbuf->b_ind_in_comment2) {
- start = ml_get(trypos->lnum);
- look = start + trypos->col + 2; /* skip / and * */
+ start = ml_get(comment_pos->lnum);
+ look = start + comment_pos->col + 2; /* skip / and * */
if (*look != NUL) /* if something after it */
- trypos->col = (colnr_T)(skipwhite(look) - start);
+ comment_pos->col = (colnr_T)(skipwhite(look) - start);
}
- getvcol(curwin, trypos, &col, NULL, NULL);
+ getvcol(curwin, comment_pos, &col, NULL, NULL);
amount = col;
if (curbuf->b_ind_in_comment2 || *look == NUL)
amount += curbuf->b_ind_in_comment;
}
}
+ goto theend;
}
// Are we looking at a ']' that has a match?
- else if (*skipwhite(theline) == ']'
+ if (*skipwhite(theline) == ']'
&& (trypos = find_match_char('[', curbuf->b_ind_maxparen)) != NULL) {
// align with the line containing the '['.
amount = get_indent_lnum(trypos->lnum);
+ goto theend;
}
/*
* Are we inside parentheses or braces?
*/ /* XXX */
- else if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL
+ if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL
&& curbuf->b_ind_java == 0)
|| (tryposBrace = find_start_brace()) != NULL
|| trypos != NULL) {
@@ -1821,8 +1954,8 @@ int get_c_indent(void)
continue; /* ignore #define, #if, etc. */
curwin->w_cursor.lnum = lnum;
- /* Skip a comment. XXX */
- if ((trypos = ind_find_start_comment()) != NULL) {
+ /* Skip a comment or raw string. XXX */
+ if ((trypos = ind_find_start_CORS()) != NULL) {
lnum = trypos->lnum + 1;
continue;
}
@@ -2023,8 +2156,8 @@ int get_c_indent(void)
// stored in tryposBrace.
// Make a copy of tryposBrace, it may point to pos_copy inside
// find_start_brace(), which may be changed somewhere.
- tryposBraceCopy = *tryposBrace;
- tryposBrace = &tryposBraceCopy;
+ tryposCopy = *tryposBrace;
+ tryposBrace = &tryposCopy;
trypos = tryposBrace;
ourscope = trypos->lnum;
start = ml_get(ourscope);
@@ -2201,10 +2334,10 @@ int get_c_indent(void)
l = get_cursor_line_ptr();
/*
- * If we're in a comment now, skip to the start of the
- * comment.
+ * If we're in a comment or raw string now, skip to
+ * the start of it.
*/
- trypos = ind_find_start_comment();
+ trypos = ind_find_start_CORS();
if (trypos != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
@@ -2286,7 +2419,8 @@ int get_c_indent(void)
amount += ind_continuation;
} else {
if (lookfor != LOOKFOR_TERM
- && lookfor != LOOKFOR_CPP_BASECLASS) {
+ && lookfor != LOOKFOR_CPP_BASECLASS
+ && lookfor != LOOKFOR_COMMA) {
amount = scope_amount;
if (theline[0] == '{') {
amount += curbuf->b_ind_open_extra;
@@ -2309,9 +2443,9 @@ int get_c_indent(void)
l = get_cursor_line_ptr();
- /* If we're in a comment now, skip to the start of
- * the comment. */
- trypos = ind_find_start_comment();
+ /* If we're in a comment or raw string now, skip
+ * to the start of it. */
+ trypos = ind_find_start_CORS();
if (trypos != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
@@ -2337,9 +2471,10 @@ int get_c_indent(void)
}
/*
- * If we're in a comment now, skip to the start of the comment.
+ * If we're in a comment or raw string now, skip to the start
+ * of it.
*/ /* XXX */
- if ((trypos = ind_find_start_comment()) != NULL) {
+ if ((trypos = ind_find_start_CORS()) != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
continue;
@@ -2492,7 +2627,7 @@ int get_c_indent(void)
*/ /* XXX */
n = FALSE;
if (lookfor != LOOKFOR_TERM && curbuf->b_ind_cpp_baseclass > 0) {
- n = cin_is_cpp_baseclass(&col);
+ n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
l = get_cursor_line_ptr();
}
if (n) {
@@ -2508,7 +2643,7 @@ int get_c_indent(void)
continue;
} else
/* XXX */
- amount = get_baseclass_amount(col);
+ amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col);
break;
} else if (lookfor == LOOKFOR_CPP_BASECLASS) {
/* only look, whether there is a cpp base class
@@ -2550,23 +2685,31 @@ int get_c_indent(void)
amount = get_indent();
break;
}
- if (lookfor == LOOKFOR_NO_COMMA) {
- if (terminated != ',') {
- // Line below current line is the one that starts a
- // (possibly broken) line ending in a comma.
+ if (lookfor == LOOKFOR_COMMA) {
+ if (tryposBrace != NULL && tryposBrace->lnum
+ >= curwin->w_cursor.lnum) {
break;
}
- amount = get_indent();
- if (curwin->w_cursor.lnum - 1 == ourscope) {
- // line above is start of the scope, thus current line
- // is the one that stars a (possibly broken) line
- // ending in a comma.
+ if (terminated == ',') {
+ // Line below current line is the one that starts a
+ // (possibly broken) line ending in a comma.
break;
+ } else {
+ amount = get_indent();
+ if (curwin->w_cursor.lnum - 1 == ourscope) {
+ // line above is start of the scope, thus current
+ // line is the one that stars a (possibly broken)
+ // line ending in a comma.
+ break;
+ }
}
}
if (terminated == 0 || (lookfor != LOOKFOR_UNTERM
&& terminated == ',')) {
+ if (*skipwhite(l) == '[' || l[STRLEN(l) - 1] == '[') {
+ amount += ind_continuation;
+ }
// If we're in the middle of a paren thing, Go back to the line
// that starts it so we can get the right prevailing indent
// if ( foo &&
@@ -2783,7 +2926,11 @@ int get_c_indent(void)
* 100 +
* -> here;
*/
+ l = get_cursor_line_ptr();
amount = cur_amount;
+ if (*skipwhite(l) == ']' || l[STRLEN(l) - 1] == ']') {
+ break;
+ }
/*
* If previous line ends in ',', check whether we
@@ -2809,8 +2956,10 @@ int get_c_indent(void)
// 4 *
// 5,
// 6,
- lookfor = LOOKFOR_NO_COMMA;
- amount = get_indent(); // XXX
+ if (cin_iscomment(skipwhite(l))) {
+ break;
+ }
+ lookfor = LOOKFOR_COMMA;
trypos = find_match_char('[', curbuf->b_ind_maxparen);
if (trypos != NULL) {
if (trypos->lnum == curwin->w_cursor.lnum - 1) {
@@ -2831,7 +2980,9 @@ int get_c_indent(void)
// XXX
cont_amount = cin_get_equal_amount( curwin->w_cursor.lnum);
}
- if (lookfor != LOOKFOR_TERM && lookfor != LOOKFOR_JS_KEY) {
+ if (lookfor != LOOKFOR_TERM
+ && lookfor != LOOKFOR_JS_KEY
+ && lookfor != LOOKFOR_COMMA) {
lookfor = LOOKFOR_UNTERM;
}
}
@@ -3038,252 +3189,257 @@ term_again:
/* subtract extra left-shift for jump labels */
if (curbuf->b_ind_jump_label > 0 && original_line_islabel)
amount -= curbuf->b_ind_jump_label;
+
+ goto theend;
}
- else {
- // Ok -- we're not inside any sort of structure at all!
- //
- // this means we're at the top level, and everything should
- // basically just match where the previous line is, except
- // for the lines immediately following a function declaration,
- // which are K&R-style parameters and need to be indented.
-
- // if our line starts with an open brace, forget about any
- // prevailing indent and make sure it looks like the start
- // of a function
- if (theline[0] == '{') {
- amount = curbuf->b_ind_first_open;
- }
- /*
- * If the NEXT line is a function declaration, the current
- * line needs to be indented as a function type spec.
- * Don't do this if the current line looks like a comment or if the
- * current line is terminated, ie. ends in ';', or if the current line
- * contains { or }: "void f() {\n if (1)"
- */
- else if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
- && !cin_nocode(theline)
- && vim_strchr(theline, '{') == NULL
- && vim_strchr(theline, '}') == NULL
- && !cin_ends_in(theline, (char_u *)":", NULL)
- && !cin_ends_in(theline, (char_u *)",", NULL)
- && cin_isfuncdecl(NULL, cur_curpos.lnum + 1,
- cur_curpos.lnum + 1)
- && !cin_isterminated(theline, FALSE, TRUE)) {
- amount = curbuf->b_ind_func_type;
- } else {
- amount = 0;
- curwin->w_cursor = cur_curpos;
- /* search backwards until we find something we recognize */
+ // Ok -- we're not inside any sort of structure at all!
+ //
+ // this means we're at the top level, and everything should
+ // basically just match where the previous line is, except
+ // for the lines immediately following a function declaration,
+ // which are K&R-style parameters and need to be indented.
- while (curwin->w_cursor.lnum > 1) {
- curwin->w_cursor.lnum--;
- curwin->w_cursor.col = 0;
+ // if our line starts with an open brace, forget about any
+ // prevailing indent and make sure it looks like the start
+ // of a function
- l = get_cursor_line_ptr();
+ if (theline[0] == '{') {
+ amount = curbuf->b_ind_first_open;
+ goto theend;
+ }
+ /*
+ * If the NEXT line is a function declaration, the current
+ * line needs to be indented as a function type spec.
+ * Don't do this if the current line looks like a comment or if the
+ * current line is terminated, ie. ends in ';', or if the current line
+ * contains { or }: "void f() {\n if (1)"
+ */
+ if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
+ && !cin_nocode(theline)
+ && vim_strchr(theline, '{') == NULL
+ && vim_strchr(theline, '}') == NULL
+ && !cin_ends_in(theline, (char_u *)":", NULL)
+ && !cin_ends_in(theline, (char_u *)",", NULL)
+ && cin_isfuncdecl(NULL, cur_curpos.lnum + 1,
+ cur_curpos.lnum + 1)
+ && !cin_isterminated(theline, false, true)) {
+ amount = curbuf->b_ind_func_type;
+ goto theend;
+ }
- /*
- * If we're in a comment now, skip to the start of the comment.
- */ /* XXX */
- if ((trypos = ind_find_start_comment()) != NULL) {
- curwin->w_cursor.lnum = trypos->lnum + 1;
- curwin->w_cursor.col = 0;
- continue;
- }
+ /* search backwards until we find something we recognize */
+ amount = 0;
+ curwin->w_cursor = cur_curpos;
+ while (curwin->w_cursor.lnum > 1) {
+ curwin->w_cursor.lnum--;
+ curwin->w_cursor.col = 0;
- /*
- * Are we at the start of a cpp base class declaration or
- * constructor initialization?
- */ /* XXX */
- n = FALSE;
- if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{') {
- n = cin_is_cpp_baseclass(&col);
- l = get_cursor_line_ptr();
- }
- if (n) {
- /* XXX */
- amount = get_baseclass_amount(col);
- break;
- }
+ l = get_cursor_line_ptr();
- /*
- * Skip preprocessor directives and blank lines.
- */
- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
- continue;
+ /*
+ * If we're in a comment or raw string now, skip to the start
+ * of it.
+ */ /* XXX */
+ if ((trypos = ind_find_start_CORS()) != NULL) {
+ curwin->w_cursor.lnum = trypos->lnum + 1;
+ curwin->w_cursor.col = 0;
+ continue;
+ }
- if (cin_nocode(l))
- continue;
+ /*
+ * Are we at the start of a cpp base class declaration or
+ * constructor initialization?
+ */ /* XXX */
+ n = false;
+ if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{') {
+ n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
+ l = get_cursor_line_ptr();
+ }
+ if (n) {
+ /* XXX */
+ amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col);
+ break;
+ }
- /*
- * If the previous line ends in ',', use one level of
- * indentation:
- * int foo,
- * bar;
- * do this before checking for '}' in case of eg.
- * enum foobar
- * {
- * ...
- * } foo,
- * bar;
- */
- n = 0;
- if (cin_ends_in(l, (char_u *)",", NULL)
- || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\')) {
- /* take us back to opening paren */
- if (find_last_paren(l, '(', ')')
- && (trypos = find_match_paren(
- curbuf->b_ind_maxparen)) != NULL)
- curwin->w_cursor = *trypos;
-
- /* For a line ending in ',' that is a continuation line go
- * back to the first line with a backslash:
- * char *foo = "bla\
- * bla",
- * here;
- */
- while (n == 0 && curwin->w_cursor.lnum > 1) {
- l = ml_get(curwin->w_cursor.lnum - 1);
- if (*l == NUL || l[STRLEN(l) - 1] != '\\')
- break;
- --curwin->w_cursor.lnum;
- curwin->w_cursor.col = 0;
- }
+ /*
+ * Skip preprocessor directives and blank lines.
+ */
+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+ continue;
- amount = get_indent(); /* XXX */
+ if (cin_nocode(l))
+ continue;
- if (amount == 0)
- amount = cin_first_id_amount();
- if (amount == 0)
- amount = ind_continuation;
+ /*
+ * If the previous line ends in ',', use one level of
+ * indentation:
+ * int foo,
+ * bar;
+ * do this before checking for '}' in case of eg.
+ * enum foobar
+ * {
+ * ...
+ * } foo,
+ * bar;
+ */
+ n = 0;
+ if (cin_ends_in(l, (char_u *)",", NULL)
+ || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\')) {
+ /* take us back to opening paren */
+ if (find_last_paren(l, '(', ')')
+ && (trypos = find_match_paren(
+ curbuf->b_ind_maxparen)) != NULL)
+ curwin->w_cursor = *trypos;
+
+ /* For a line ending in ',' that is a continuation line go
+ * back to the first line with a backslash:
+ * char *foo = "bla\
+ * bla",
+ * here;
+ */
+ while (n == 0 && curwin->w_cursor.lnum > 1) {
+ l = ml_get(curwin->w_cursor.lnum - 1);
+ if (*l == NUL || l[STRLEN(l) - 1] != '\\')
break;
- }
+ --curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ }
- /*
- * If the line looks like a function declaration, and we're
- * not in a comment, put it the left margin.
- */
- if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */
- break;
- l = get_cursor_line_ptr();
+ amount = get_indent(); /* XXX */
- /*
- * Finding the closing '}' of a previous function. Put
- * current line at the left margin. For when 'cino' has "fs".
- */
- if (*skipwhite(l) == '}')
- break;
+ if (amount == 0)
+ amount = cin_first_id_amount();
+ if (amount == 0)
+ amount = ind_continuation;
+ break;
+ }
- /* (matching {)
- * If the previous line ends on '};' (maybe followed by
- * comments) align at column 0. For example:
- * char *string_array[] = { "foo",
- * / * x * / "b};ar" }; / * foobar * /
- */
- if (cin_ends_in(l, (char_u *)"};", NULL))
- break;
+ /*
+ * If the line looks like a function declaration, and we're
+ * not in a comment, put it the left margin.
+ */
+ if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */
+ break;
+ l = get_cursor_line_ptr();
- // If the previous line ends on '[' we are probably in an
- // array constant:
- // something = [
- // 234, <- extra indent
- if (cin_ends_in(l, (char_u *)"[", NULL)) {
- amount = get_indent() + ind_continuation;
- break;
- }
+ /*
+ * Finding the closing '}' of a previous function. Put
+ * current line at the left margin. For when 'cino' has "fs".
+ */
+ if (*skipwhite(l) == '}')
+ break;
- /*
- * Find a line only has a semicolon that belongs to a previous
- * line ending in '}', e.g. before an #endif. Don't increase
- * indent then.
- */
- if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1)) {
- pos_T curpos_save = curwin->w_cursor;
+ /* (matching {)
+ * If the previous line ends on '};' (maybe followed by
+ * comments) align at column 0. For example:
+ * char *string_array[] = { "foo",
+ * / * x * / "b};ar" }; / * foobar * /
+ */
+ if (cin_ends_in(l, (char_u *)"};", NULL))
+ break;
- while (curwin->w_cursor.lnum > 1) {
- look = ml_get(--curwin->w_cursor.lnum);
- if (!(cin_nocode(look) || cin_ispreproc_cont(
- &look, &curwin->w_cursor.lnum)))
- break;
- }
- if (curwin->w_cursor.lnum > 0
- && cin_ends_in(look, (char_u *)"}", NULL))
- break;
+ // If the previous line ends on '[' we are probably in an
+ // array constant:
+ // something = [
+ // 234, <- extra indent
+ if (cin_ends_in(l, (char_u *)"[", NULL)) {
+ amount = get_indent() + ind_continuation;
+ break;
+ }
- curwin->w_cursor = curpos_save;
- }
+ /*
+ * Find a line only has a semicolon that belongs to a previous
+ * line ending in '}', e.g. before an #endif. Don't increase
+ * indent then.
+ */
+ if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1)) {
+ pos_T curpos_save = curwin->w_cursor;
- /*
- * If the PREVIOUS line is a function declaration, the current
- * line (and the ones that follow) needs to be indented as
- * parameters.
- */
- if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) {
- amount = curbuf->b_ind_param;
+ while (curwin->w_cursor.lnum > 1) {
+ look = ml_get(--curwin->w_cursor.lnum);
+ if (!(cin_nocode(look) || cin_ispreproc_cont(
+ &look, &curwin->w_cursor.lnum)))
break;
- }
+ }
+ if (curwin->w_cursor.lnum > 0
+ && cin_ends_in(look, (char_u *)"}", NULL))
+ break;
- /*
- * If the previous line ends in ';' and the line before the
- * previous line ends in ',' or '\', ident to column zero:
- * int foo,
- * bar;
- * indent_to_0 here;
- */
- if (cin_ends_in(l, (char_u *)";", NULL)) {
- l = ml_get(curwin->w_cursor.lnum - 1);
- if (cin_ends_in(l, (char_u *)",", NULL)
- || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
- break;
- l = get_cursor_line_ptr();
- }
+ curwin->w_cursor = curpos_save;
+ }
- /*
- * Doesn't look like anything interesting -- so just
- * use the indent of this line.
- *
- * Position the cursor over the rightmost paren, so that
- * matching it will take us back to the start of the line.
- */
- find_last_paren(l, '(', ')');
+ /*
+ * If the PREVIOUS line is a function declaration, the current
+ * line (and the ones that follow) needs to be indented as
+ * parameters.
+ */
+ if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) {
+ amount = curbuf->b_ind_param;
+ break;
+ }
- if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
- curwin->w_cursor = *trypos;
- amount = get_indent(); /* XXX */
+ /*
+ * If the previous line ends in ';' and the line before the
+ * previous line ends in ',' or '\', ident to column zero:
+ * int foo,
+ * bar;
+ * indent_to_0 here;
+ */
+ if (cin_ends_in(l, (char_u *)";", NULL)) {
+ l = ml_get(curwin->w_cursor.lnum - 1);
+ if (cin_ends_in(l, (char_u *)",", NULL)
+ || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
break;
- }
+ l = get_cursor_line_ptr();
+ }
- /* add extra indent for a comment */
- if (cin_iscomment(theline))
- amount += curbuf->b_ind_comment;
+ /*
+ * Doesn't look like anything interesting -- so just
+ * use the indent of this line.
+ *
+ * Position the cursor over the rightmost paren, so that
+ * matching it will take us back to the start of the line.
+ */
+ find_last_paren(l, '(', ')');
- /* add extra indent if the previous line ended in a backslash:
- * "asdfasdf\
- * here";
- * char *foo = "asdf\
- * here";
- */
- if (cur_curpos.lnum > 1) {
- l = ml_get(cur_curpos.lnum - 1);
- if (*l != NUL && l[STRLEN(l) - 1] == '\\') {
- cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
- if (cur_amount > 0)
- amount = cur_amount;
- else if (cur_amount == 0)
- amount += ind_continuation;
- }
- }
+ if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
+ curwin->w_cursor = *trypos;
+ amount = get_indent(); /* XXX */
+ break;
+ }
+
+ /* add extra indent for a comment */
+ if (cin_iscomment(theline))
+ amount += curbuf->b_ind_comment;
+
+ /* add extra indent if the previous line ended in a backslash:
+ * "asdfasdf\
+ * here";
+ * char *foo = "asdf\
+ * here";
+ */
+ if (cur_curpos.lnum > 1) {
+ l = ml_get(cur_curpos.lnum - 1);
+ if (*l != NUL && l[STRLEN(l) - 1] == '\\') {
+ cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
+ if (cur_amount > 0)
+ amount = cur_amount;
+ else if (cur_amount == 0)
+ amount += ind_continuation;
}
}
theend:
+ if (amount < 0)
+ amount = 0;
+
+laterend:
/* put the cursor back where it belongs */
curwin->w_cursor = cur_curpos;
xfree(linecopy);
- if (amount < 0)
- return 0;
return amount;
}
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 0ba8dd98d0..c91a25df6e 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -3954,8 +3954,10 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
if (ffdos)
size += lnum - 1;
- /* Don't count the last line break if 'bin' and 'noeol'. */
- if (buf->b_p_bin && !buf->b_p_eol && buf->b_ml.ml_line_count == lnum) {
+ /* Don't count the last line break if 'noeol' and ('bin' or
+ * 'nofixeol'). */
+ if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
+ && buf->b_ml.ml_line_count == lnum) {
size -= ffdos + 1;
}
}
diff --git a/src/nvim/memline_defs.h b/src/nvim/memline_defs.h
index bcc1c673d2..34a002af5d 100644
--- a/src/nvim/memline_defs.h
+++ b/src/nvim/memline_defs.h
@@ -41,7 +41,7 @@ typedef struct memline {
int ml_flags;
infoptr_T *ml_stack; /* stack of pointer blocks (array of IPTRs) */
- int ml_stack_top; /* current top if ml_stack */
+ int ml_stack_top; /* current top of ml_stack */
int ml_stack_size; /* total number of entries in ml_stack */
linenr_T ml_line_lnum; /* line number of cached line, 0 if not valid */
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index ad53e9bf24..a2e473fcb8 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -7466,6 +7466,13 @@ static void nv_object(cmdarg_T *cap)
flag = current_block(cap->oap, cap->count1, include, '<', '>');
break;
case 't': /* "at" = a tag block (xml and html) */
+ // Do not adjust oap->end in do_pending_operator()
+ // otherwise there are different results for 'dit'
+ // (note leading whitespace in last line):
+ // 1) <b> 2) <b>
+ // foobar foobar
+ // </b> </b>
+ cap->retval |= CA_NO_ADJ_OP_END;
flag = current_tagblock(cap->oap, cap->count1, include);
break;
case 'p': /* "ap" = a paragraph */
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 956b9c7758..52b4fed9d7 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -554,7 +554,7 @@ void op_reindent(oparg_T *oap, Indenter how)
{
long i;
char_u *l;
- int count;
+ int amount;
linenr_T first_changed = 0;
linenr_T last_changed = 0;
linenr_T start_lnum = curwin->w_cursor.lnum;
@@ -582,11 +582,11 @@ void op_reindent(oparg_T *oap, Indenter how)
|| how != get_lisp_indent) {
l = skipwhite(get_cursor_line_ptr());
if (*l == NUL) /* empty or blank line */
- count = 0;
+ amount = 0;
else
- count = how(); /* get the indent for this line */
+ amount = how(); /* get the indent for this line */
- if (set_indent(count, SIN_UNDO)) {
+ if (amount >= 0 && set_indent(amount, SIN_UNDO)) {
/* did change the indent, call changed_lines() later */
if (first_changed == 0)
first_changed = curwin->w_cursor.lnum;
@@ -4964,7 +4964,7 @@ void cursor_pos_info(void)
&char_count_cursor, len, eol_size);
if (lnum == curbuf->b_ml.ml_line_count
&& !curbuf->b_p_eol
- && curbuf->b_p_bin
+ && (curbuf->b_p_bin || !curbuf->b_p_fixeol)
&& (long)STRLEN(s) < len)
byte_count_cursor -= eol_size;
}
@@ -4985,7 +4985,7 @@ void cursor_pos_info(void)
}
/* Correction for when last line doesn't have an EOL. */
- if (!curbuf->b_p_eol && curbuf->b_p_bin)
+ if (!curbuf->b_p_eol && (curbuf->b_p_bin || !curbuf->b_p_fixeol))
byte_count -= eol_size;
if (l_VIsual_active) {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index dbcd230186..486f2083a6 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -122,6 +122,7 @@ static char_u *p_cpt;
static char_u *p_cfu;
static char_u *p_ofu;
static int p_eol;
+static int p_fixeol;
static int p_et;
static char_u *p_fenc;
static char_u *p_ff;
@@ -1018,12 +1019,9 @@ void set_init_2(void)
*/
void set_init_3(void)
{
-#if defined(UNIX) || defined(WIN3264)
- /*
- * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
- * This is done after other initializations, where 'shell' might have been
- * set, but only if they have not been set before.
- */
+ // Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
+ // This is done after other initializations, where 'shell' might have been
+ // set, but only if they have not been set before.
int idx_srr;
int do_srr;
int idx_sp;
@@ -1080,8 +1078,6 @@ void set_init_3(void)
}
xfree(p);
}
-#endif
-
set_title_defaults();
}
@@ -3592,6 +3588,9 @@ set_bool_option (
/* when 'endofline' is changed, redraw the window title */
else if ((int *)varp == &curbuf->b_p_eol) {
redraw_titles();
+ } else if ((int *)varp == &curbuf->b_p_fixeol) {
+ // when 'fixeol' is changed, redraw the window title
+ redraw_titles();
}
/* when 'bomb' is changed, redraw the window title and tab page text */
else if ((int *)varp == &curbuf->b_p_bomb) {
@@ -5304,6 +5303,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
+ case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol);
case PV_ET: return (char_u *)&(curbuf->b_p_et);
case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
case PV_FF: return (char_u *)&(curbuf->b_p_ff);
@@ -5548,6 +5548,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_bin = p_bin;
buf->b_p_bomb = p_bomb;
buf->b_p_et = p_et;
+ buf->b_p_fixeol = p_fixeol;
buf->b_p_et_nobin = p_et_nobin;
buf->b_p_ml = p_ml;
buf->b_p_ml_nobin = p_ml_nobin;
@@ -6483,6 +6484,7 @@ void save_file_ff(buf_T *buf)
* from when editing started (save_file_ff() called).
* Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
* changed and 'binary' is not set.
+ * Also when 'endofline' was changed and 'fixeol' is not set.
* When "ignore_empty" is true don't consider a new, empty buffer to be
* changed.
*/
@@ -6497,9 +6499,9 @@ bool file_ff_differs(buf_T *buf, bool ignore_empty)
&& *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
return FALSE;
if (buf->b_start_ffc != *buf->b_p_ff)
- return TRUE;
- if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
- return TRUE;
+ return true;
+ if ((buf->b_p_bin || !buf->b_p_fixeol) && buf->b_start_eol != buf->b_p_eol)
+ return true;
if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
return TRUE;
if (buf->b_start_fenc == NULL)
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index d4d3410d5c..c72e1cf0bb 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -665,6 +665,7 @@ enum {
, BV_DEF
, BV_INC
, BV_EOL
+ , BV_FIXEOL
, BV_EP
, BV_ET
, BV_FENC
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index b22e994efe..5187340629 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -799,6 +799,14 @@ return {
defaults={if_true={vi="vert:|,fold:-"}}
},
{
+ full_name='fixendofline', abbreviation='fixeol',
+ type='bool', scope={'buffer'},
+ vi_def=true,
+ redraw={'statuslines'},
+ varname='p_fixeol',
+ defaults={if_true={vi=true}}
+ },
+ {
full_name='fkmap', abbreviation='fk',
type='bool', scope={'global'},
vi_def=true,
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 0e052ced55..a791dca39c 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -46,7 +46,19 @@ bool os_env_exists(const char *name)
int os_setenv(const char *name, const char *value, int overwrite)
FUNC_ATTR_NONNULL_ALL
{
+#ifdef HAVE_SETENV
return setenv(name, value, overwrite);
+#elif defined(HAVE_PUTENV_S)
+ if (!overwrite && os_getenv(name) != NULL) {
+ return 0;
+ }
+ if (_putenv_s(name, value) == 0) {
+ return 0;
+ }
+ return -1;
+#else
+# error "This system has no implementation available for os_setenv()"
+#endif
}
/// Unset environment variable
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 57e25560de..3813c45726 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -418,7 +418,8 @@ static void read_input(DynamicBuffer *buf)
// Finished a line, add a NL, unless this line should not have one.
// FIXME need to make this more readable
if (lnum != curbuf->b_op_end.lnum
- || !curbuf->b_p_bin
+ || (!curbuf->b_p_bin
+ && curbuf->b_p_fixeol)
|| (lnum != curbuf->b_no_eol_lnum
&& (lnum !=
curbuf->b_ml.ml_line_count
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index 32960dfbe9..aad9672ba7 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -2,10 +2,13 @@
#define NVIM_OS_WIN_DEFS_H
#include <windows.h>
+#include <sys/stat.h>
#define TEMP_DIR_NAMES {"$TMP", "$TEMP", "$USERPROFILE", ""}
#define TEMP_FILE_PATH_MAXLEN _MAX_PATH
+#define FNAME_ILLEGAL "\"*?><|"
+
#define USE_CRNL
#ifdef _MSC_VER
@@ -15,6 +18,9 @@
# ifndef restrict
# define restrict __restrict
# endif
+# ifndef S_IXUSR
+# define S_IXUSR S_IEXEC
+# endif
#endif
#ifdef _MSC_VER
diff --git a/src/nvim/po/it.po b/src/nvim/po/it.po
index 7fe61c45bc..729697eee3 100644
--- a/src/nvim/po/it.po
+++ b/src/nvim/po/it.po
@@ -25,9 +25,8 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
#: ../api/private/helpers.c:201
-#, fuzzy
msgid "Unable to get option value"
-msgstr "impossibile ottenere il valore di opzione"
+msgstr "Impossibile ottenere il valore di opzione"
#: ../api/private/helpers.c:204
msgid "internal error: unknown option type"
@@ -827,18 +826,16 @@ msgid "sort() argument"
msgstr "argomento di sort()"
#: ../eval.c:13721
-#, fuzzy
msgid "uniq() argument"
-msgstr "argomento di add()"
+msgstr "argomento di uniq()"
#: ../eval.c:13776
msgid "E702: Sort compare function failed"
msgstr "E702: Funzione confronto nel sort non riuscita"
#: ../eval.c:13806
-#, fuzzy
msgid "E882: Uniq compare function failed"
-msgstr "E702: Funzione confronto nel sort non riuscita"
+msgstr "E882: Funzione di comparazione 'uniq' fallita"
#: ../eval.c:14085
msgid "(Invalid)"
@@ -963,16 +960,12 @@ msgid "E129: Function name required"
msgstr "E129: Nome funzione necessario"
#: ../eval.c:17824
-#, fuzzy, c-format
msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Il nome funzione deve iniziare con una maiuscola o contenere ':': %s"
+msgstr "E128: Il nome funzione deve iniziare con una maiuscola o \"s:\": %s"
#: ../eval.c:17833
-#, fuzzy, c-format
msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Il nome funzione deve iniziare con una maiuscola o contenere ':': %s"
+msgstr "E884: Il nome funzione non può contenere una virgola: %s"
#: ../eval.c:18336
#, c-format
@@ -2667,18 +2660,17 @@ msgid "E17: \"%s\" is a directory"
msgstr "E17: \"%s\" è una directory"
#: ../globals.h:1020
-#, fuzzy
msgid "E900: Invalid job id"
-msgstr "E49: Quantità di 'scroll' non valida"
+msgstr "E900: 'Job id' non valido"
#: ../globals.h:1021
msgid "E901: Job table is full"
-msgstr ""
+msgstr "E901: Job table piena"
#: ../globals.h:1022
#, c-format
msgid "E902: \"%s\" is not an executable"
-msgstr ""
+msgstr "E902: \"%s\" non è un esegubile"
#: ../globals.h:1024
#, c-format
@@ -2703,7 +2695,7 @@ msgstr "E22: Script troppo nidificati"
#: ../globals.h:1031
msgid "E23: No alternate file"
-msgstr "E23: Nessun file alternato"
+msgstr "E23: Nessun file alternativo"
#: ../globals.h:1032
msgid "E24: No such abbreviation"
@@ -2791,9 +2783,8 @@ msgid "E37: No write since last change (add ! to override)"
msgstr "E37: Non salvato dopo modifica (aggiungi ! per eseguire comunque)"
#: ../globals.h:1055
-#, fuzzy
msgid "E37: No write since last change"
-msgstr "[Non salvato dopo l'ultima modifica]\n"
+msgstr "E37: Non salvato dall'ultima modifica"
#: ../globals.h:1056
msgid "E38: Null argument"
@@ -2857,8 +2848,7 @@ msgstr "E46: Non posso cambiare la variabile read-only \"%s\""
#: ../globals.h:1075
#, c-format
msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr ""
-"E794: Non posso impostare la variabile read-only in ambiente protetto: \"%s\""
+msgstr "E794: Non posso impostare la variabile read-only in ambiente protetto: \"%s\""
#: ../globals.h:1076
msgid "E47: Error while reading errorfile"
@@ -4869,9 +4859,8 @@ msgid "E777: String or List expected"
msgstr "E777: aspettavo Stringa o Lista"
#: ../regexp.c:359
-#, fuzzy, c-format
msgid "E369: invalid item in %s%%[]"
-msgstr "E239: Testo 'sign' non valido: %s"
+msgstr "E369: elemento non valido in %s%%[]"
#: ../regexp.c:374
#, c-format
@@ -5004,7 +4993,7 @@ msgstr "E866: (NFA regexp) %c fuori posto"
#: ../regexp_nfa.c:242
#, c-format
msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
+msgstr "E877: (NFA regexp) Classe di caratteri non valida: %<PRId64>"
#: ../regexp_nfa.c:1261
#, c-format
@@ -5611,14 +5600,12 @@ msgid "E765: 'spellfile' does not have %<PRId64> entries"
msgstr "E765: 'spellfile' non ha %<PRId64> elementi"
#: ../spell.c:8074
-#, fuzzy, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Parola rimossa da %s"
+msgstr "Parola '%.*s' rimossa da %s"
#: ../spell.c:8117
-#, fuzzy, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Parola aggiunta a %s"
+msgstr "Parola '%.*s' aggiunta a %s"
#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
@@ -6100,9 +6087,8 @@ msgstr "Vim: Errore leggendo l'input, esco...\n"
#. This happens when the FileChangedRO autocommand changes the
#. * file in a way it becomes shorter.
#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Il conteggio delle righe è inaspettatamente cambiato"
+msgstr "E881: Il conteggio delle righe è inaspettatamente cambiato"
#: ../undo.c:627
#, c-format
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 9fdb476748..c4264cbcee 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -2934,14 +2934,16 @@ win_line (
}
}
- /* Decide which of the highlight attributes to use. */
- attr_pri = TRUE;
- if (area_attr != 0)
- char_attr = area_attr;
- else if (search_attr != 0)
- char_attr = search_attr;
- /* Use line_attr when not in the Visual or 'incsearch' area
- * (area_attr may be 0 when "noinvcur" is set). */
+ // Decide which of the highlight attributes to use.
+ attr_pri = true;
+
+ if (area_attr != 0) {
+ char_attr = hl_combine_attr(line_attr, area_attr);
+ } else if (search_attr != 0) {
+ char_attr = hl_combine_attr(line_attr, search_attr);
+ }
+ // Use line_attr when not in the Visual or 'incsearch' area
+ // (area_attr may be 0 when "noinvcur" is set).
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|| vcol < fromcol || vcol_prev < fromcol_prev
|| vcol >= tocol))
@@ -3323,16 +3325,15 @@ win_line (
* Found last space before word: check for line break.
*/
if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)) {
- char_u *p = ptr - (
- has_mbyte ? mb_l :
- 1);
+ int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0;
+ char_u *p = ptr - (mb_off + 1);
// TODO: is passing p for start of the line OK?
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1;
if (c == TAB && n_extra + col > wp->w_width) {
n_extra = (int)wp->w_buffer->b_p_ts
- vcol % (int)wp->w_buffer->b_p_ts - 1;
}
- c_extra = ' ';
+ c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' ';
if (ascii_iswhite(c)) {
if (c == TAB)
/* See "Tab alignment" below. */
diff --git a/src/nvim/search.c b/src/nvim/search.c
index cb461c9ef2..18a72524cb 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -918,7 +918,7 @@ static int first_submatch(regmmatch_T *rp)
* Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this
* makes the movement linewise without moving the match position.
*
- * return 0 for failure, 1 for found, 2 for found and line offset added
+ * Return 0 for failure, 1 for found, 2 for found and line offset added.
*/
int do_search(
oparg_T *oap, /* can be NULL */
@@ -1443,19 +1443,64 @@ static int check_prevcol(char_u *linep, int col, int ch, int *prevcol)
}
/*
+ * Raw string start is found at linep[startpos.col - 1].
+ * Return true if the matching end can be found between startpos and endpos.
+ */
+static int find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
+{
+ char_u *p;
+ char_u *delim_copy;
+ size_t delim_len;
+ linenr_T lnum;
+ int found = false;
+
+ for (p = linep + startpos->col + 1; *p && *p != '('; ++p) {}
+
+ delim_len = (p - linep) - startpos->col - 1;
+ delim_copy = vim_strnsave(linep + startpos->col + 1, delim_len);
+ if (delim_copy == NULL)
+ return false;
+ for (lnum = startpos->lnum; lnum <= endpos->lnum; ++lnum)
+ {
+ char_u *line = ml_get(lnum);
+
+ for (p = line + (lnum == startpos->lnum
+ ? startpos->col + 1 : 0); *p; ++p)
+ {
+ if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col)
+ break;
+ if (*p == ')' && p[delim_len + 1] == '"'
+ && STRNCMP(delim_copy, p + 1, delim_len) == 0)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ xfree(delim_copy);
+ return found;
+}
+
+/*
* findmatchlimit -- find the matching paren or brace, if it exists within
- * maxtravel lines of here. A maxtravel of 0 means search until falling off
- * the edge of the file.
+ * maxtravel lines of the cursor. A maxtravel of 0 means search until falling
+ * off the edge of the file.
*
* "initc" is the character to find a match for. NUL means to find the
- * character at or after the cursor.
+ * character at or after the cursor. Special values:
+ * '*' look for C-style comment / *
+ * '/' look for C-style comment / *, ignoring comment-end
+ * '#' look for preprocessor directives
+ * 'R' look for raw string start: R"delim(text)delim" (only backwards)
*
* 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!)
*
- * "oap" is only used to set oap->motion_type for a linewise motion, it be
+ * "oap" is only used to set oap->motion_type for a linewise motion, it can be
* NULL
*/
@@ -1465,8 +1510,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
int findc = 0; /* matching brace */
int c;
int count = 0; /* cumulative number of braces */
- int backwards = FALSE; /* init for gcc */
- int inquote = FALSE; /* TRUE when inside quotes */
+ int backwards = false; /* init for gcc */
+ int raw_string = false; /* search for raw string */
+ int inquote = false; /* true when inside quotes */
char_u *linep; /* pointer to current line */
char_u *ptr;
int do_quotes; /* check for quotes in current line */
@@ -1506,22 +1552,22 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* When '/' is used, we ignore running backwards into a star-slash, for
* "[*" command, we just want to find any comment.
*/
- if (initc == '/' || initc == '*') {
+ if (initc == '/' || initc == '*' || initc == 'R') {
comment_dir = dir;
if (initc == '/')
- ignore_cend = TRUE;
- backwards = (dir == FORWARD) ? FALSE : TRUE;
+ ignore_cend = true;
+ backwards = (dir == FORWARD) ? false : true;
+ raw_string = (initc == 'R');
initc = NUL;
} else if (initc != '#' && initc != NUL) {
find_mps_values(&initc, &findc, &backwards, TRUE);
if (findc == NUL)
return NULL;
- }
- /*
- * Either initc is '#', or no initc was given and we need to look under the
- * cursor.
- */
- else {
+ } else {
+ /*
+ * Either initc is '#', or no initc was given and we need to look
+ * under the cursor.
+ */
if (initc == '#') {
hash_dir = dir;
} else {
@@ -1766,7 +1812,26 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
*/
if (pos.col == 0)
continue;
- else if ( linep[pos.col - 1] == '/'
+ else if (raw_string)
+ {
+ if (linep[pos.col - 1] == 'R'
+ && linep[pos.col] == '"'
+ && vim_strchr(linep + pos.col + 1, '(') != NULL)
+ {
+ /* Possible start of raw string. Now that we have the
+ * delimiter we can check if it ends before where we
+ * started searching, or before the previously found
+ * raw string start. */
+ if (!find_rawstring_end(linep, &pos,
+ count > 0 ? &match_pos : &curwin->w_cursor))
+ {
+ count++;
+ match_pos = pos;
+ match_pos.col--;
+ }
+ linep = ml_get(pos.lnum); /* may have been released */
+ }
+ } else if ( linep[pos.col - 1] == '/'
&& linep[pos.col] == '*'
&& (int)pos.col < comment_col) {
count++;
@@ -3193,6 +3258,7 @@ current_tagblock (
int do_include = include;
bool save_p_ws = p_ws;
int retval = FAIL;
+ int is_inclusive = true;
p_ws = false;
@@ -3287,9 +3353,16 @@ again:
if (inc_cursor() < 0)
break;
} else {
- /* Exclude the '<' of the end tag. */
- if (*get_cursor_pos_ptr() == '<')
+ char_u *c = get_cursor_pos_ptr();
+ // Exclude the '<' of the end tag.
+ // If the closing tag is on new line, do not decrement cursor, but make
+ // operation exclusive, so that the linefeed will be selected
+ if (*c == '<' && !VIsual_active && curwin->w_cursor.col == 0) {
+ // do not decrement cursor
+ is_inclusive = false;
+ } else if (*c == '<') {
dec_cursor();
+ }
}
end_pos = curwin->w_cursor;
@@ -3334,8 +3407,9 @@ again:
* on an empty area. */
curwin->w_cursor = start_pos;
oap->inclusive = false;
- } else
- oap->inclusive = true;
+ } else {
+ oap->inclusive = is_inclusive;
+ }
}
retval = OK;
diff --git a/src/nvim/testdir/test53.in b/src/nvim/testdir/test53.in
index 8ca9c9ed29..7c35b2e853 100644
--- a/src/nvim/testdir/test53.in
+++ b/src/nvim/testdir/test53.in
@@ -23,6 +23,7 @@ jfXdit
0fXdit
fXdat
0fXdat
+dit
:"
:put =matchstr(\"abcd\", \".\", 0, 2) " b
:put =matchstr(\"abcd\", \"..\", 0, 2) " bc
@@ -97,6 +98,9 @@ voo "nah" sdf " asdf" sdf " sdf" sd
-<b>asdX<i>a<i />sdf</i>asdf</b>-
-<b>asdf<i>Xasdf</i>asdf</b>-
-<b>asdX<i>as<b />df</i>asdf</b>-
+-<b>
+innertext object
+</b>
</begin>
SEARCH:
foobar
diff --git a/src/nvim/testdir/test53.ok b/src/nvim/testdir/test53.ok
index 0c0b9ded16..05206972a4 100644
--- a/src/nvim/testdir/test53.ok
+++ b/src/nvim/testdir/test53.ok
@@ -11,6 +11,7 @@ voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd
-<b></b>-
-<b>asdfasdf</b>-
--
+-<b></b>
</begin>
b
bc
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 2b0d6f22f2..33c310a8b2 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -37,9 +37,6 @@ char *Version = VIM_VERSION_SHORT;
char *longVersion = NVIM_VERSION_LONG;
char *longVersionWithDate = NVIM_VERSION_LONG \
" (compiled " __DATE__ " " __TIME__ ")";
-#ifdef NVIM_VERSION_COMMIT
-char *version_commit = "Commit: " NVIM_VERSION_COMMIT;
-#endif
char *version_buildtype = "Build type: " NVIM_VERSION_BUILD_TYPE;
char *version_cflags = "Compilation: " NVIM_VERSION_CFLAGS;
@@ -98,7 +95,7 @@ static int included_patches[] = {
// 901,
// 900 NA
// 899 NA
- // 898,
+ 898,
// 897,
// 896,
// 895,
@@ -193,7 +190,7 @@ static int included_patches[] = {
// 806,
// 805,
// 804,
- // 803,
+ 803,
802,
// 801,
// 800,
@@ -201,7 +198,7 @@ static int included_patches[] = {
// 798,
// 797,
// 796 NA
- // 795,
+ 795,
// 794 NA
793,
// 792,
@@ -211,7 +208,7 @@ static int included_patches[] = {
// 788 NA
787,
786,
- // 785,
+ 785,
784,
// 783 NA
// 782,
@@ -273,7 +270,7 @@ static int included_patches[] = {
// 726 NA
// 725,
// 724 NA
- // 723,
+ 723,
// 722,
// 721,
// 720 NA
@@ -314,7 +311,7 @@ static int included_patches[] = {
// 685,
// 684,
// 683 NA
- // 682,
+ 682,
// 681 NA
// 680,
// 679 NA
@@ -325,23 +322,23 @@ static int included_patches[] = {
// 674 NA
673,
// 672,
- // 671,
- // 670,
+ 671,
+ 670,
// 669 NA
668,
667,
// 666 NA
- // 665,
+ 665,
// 664 NA
// 663 NA
// 662,
// 661,
660,
659,
- // 658,
+ 658,
// 657 NA
// 656,
- // 655,
+ 655,
// 654,
653,
// 652 NA
@@ -351,17 +348,17 @@ static int included_patches[] = {
// 648 NA
// 647 NA
646,
- // 645,
+ 645,
// 644 NA
// 643,
// 642,
// 641,
- // 640,
+ 640,
// 639,
// 638 NA
637,
636,
- // 635,
+ 635,
// 634,
633,
// 632 NA
@@ -1099,9 +1096,6 @@ void list_version(void)
// When adding features here, don't forget to update the list of
// internal variables in eval.c!
MSG(longVersionWithDate);
-#ifdef NVIM_VERSION_COMMIT
- MSG(version_commit);
-#endif
MSG(version_buildtype);
MSG(version_cflags);