aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <janedmundlazo@hotmail.com>2018-08-17 20:39:43 -0400
committerJan Edmund Lazo <janedmundlazo@hotmail.com>2018-08-17 22:07:55 -0400
commitf46728c24185a28ea2a2456d483efc86a68e7927 (patch)
tree440a473f06c22f956a71081afcd631a533981de4
parent3d71366af1287f356a812a38f2c0b22230fe409c (diff)
downloadrneovim-f46728c24185a28ea2a2456d483efc86a68e7927.tar.gz
rneovim-f46728c24185a28ea2a2456d483efc86a68e7927.tar.bz2
rneovim-f46728c24185a28ea2a2456d483efc86a68e7927.zip
vim-patch:8.0.1091: test for <cexpr> fails without +balloon_eval feature
Problem: Test for <cexpr> fails without +balloon_eval feature. Solution: Remove #ifdefs. https://github.com/vim/vim/commit/95c83c64be8d4af74bfda1f283a5bcf3f110719e
-rw-r--r--src/nvim/normal.c91
1 files changed, 79 insertions, 12 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 225fe4aa9a..a9d62d0355 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2990,6 +2990,43 @@ void reset_VIsual(void)
}
}
+// Check for a balloon-eval special item to include when searching for an
+// identifier. When "dir" is BACKWARD "ptr[-1]" must be valid!
+// Returns true if the character at "*ptr" should be included.
+// "dir" is FORWARD or BACKWARD, the direction of searching.
+// "*colp" is in/decremented if "ptr[-dir]" should also be included.
+// "bnp" points to a counter for square brackets.
+static bool find_is_eval_item(
+ const char_u *const ptr,
+ int *const colp,
+ int *const bnp,
+ const int dir)
+{
+ // Accept everything inside [].
+ if ((*ptr == ']' && dir == BACKWARD) || (*ptr == '[' && dir == FORWARD)) {
+ *bnp += 1;
+ }
+ if (*bnp > 0) {
+ if ((*ptr == '[' && dir == BACKWARD) || (*ptr == ']' && dir == FORWARD)) {
+ *bnp -= 1;
+ }
+ return true;
+ }
+
+ // skip over "s.var"
+ if (*ptr == '.') {
+ return true;
+ }
+
+ // two-character item: s->var
+ if (ptr[dir == BACKWARD ? 0 : 1] == '>'
+ && ptr[dir == BACKWARD ? -1 : 0] == '-') {
+ *colp += dir;
+ return true;
+ }
+ return false;
+}
+
/*
* Find the identifier under or to the right of the cursor.
* "find_type" can have one of three values:
@@ -3030,6 +3067,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
int this_class = 0;
int prev_class;
int prevcol;
+ int bn = 0; // bracket nesting
/*
* if i == 0: try to find an identifier
@@ -3043,24 +3081,36 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
col = startcol;
if (has_mbyte) {
while (ptr[col] != NUL) {
+ // Stop at a ']' to evaluate "a[x]".
+ if ((find_type & FIND_EVAL) && ptr[col] == ']') {
+ break;
+ }
this_class = mb_get_class(ptr + col);
if (this_class != 0 && (i == 1 || this_class != 1))
break;
col += (*mb_ptr2len)(ptr + col);
}
- } else
+ } else {
while (ptr[col] != NUL
&& (i == 0 ? !vim_iswordc(ptr[col]) : ascii_iswhite(ptr[col]))
- )
- ++col;
+ && (!(find_type & FIND_EVAL) || ptr[col] != ']')) {
+ col++;
+ }
+ }
+ // When starting on a ']' count it, so that we include the '['.
+ bn = ptr[col] == ']';
/*
* 2. Back up to start of identifier/string.
*/
if (has_mbyte) {
- /* Remember class of character under cursor. */
- this_class = mb_get_class(ptr + col);
+ // Remember class of character under cursor.
+ if ((find_type & FIND_EVAL) && ptr[col] == ']') {
+ this_class = mb_get_class((char_u *)"a");
+ } else {
+ this_class = mb_get_class(ptr + col);
+ }
while (col > 0 && this_class != 0) {
prevcol = col - 1 - (*mb_head_off)(ptr, ptr + col - 1);
prev_class = mb_get_class(ptr + prevcol);
@@ -3068,8 +3118,12 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
&& (i == 0
|| prev_class == 0
|| (find_type & FIND_IDENT))
- )
+ && (!(find_type & FIND_EVAL)
+ || prevcol == 0
+ || !find_is_eval_item(ptr + prevcol, &prevcol, &bn, BACKWARD))
+ ) {
break;
+ }
col = prevcol;
}
@@ -3086,8 +3140,12 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
: (!ascii_iswhite(ptr[col - 1])
&& (!(find_type & FIND_IDENT)
|| !vim_iswordc(ptr[col - 1]))))
- ))
- --col;
+ || ((find_type & FIND_EVAL)
+ && col > 1
+ && find_is_eval_item(ptr + col - 1, &col, &bn, BACKWARD))
+ )) {
+ col--;
+ }
/* If we don't want just any old string, or we've found an
* identifier, stop searching. */
@@ -3114,6 +3172,8 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
/*
* 3. Find the end if the identifier/string.
*/
+ bn = 0;
+ startcol -= col;
col = 0;
if (has_mbyte) {
/* Search for point of changing multibyte character class. */
@@ -3121,14 +3181,21 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
while (ptr[col] != NUL
&& ((i == 0 ? mb_get_class(ptr + col) == this_class
: mb_get_class(ptr + col) != 0)
- ))
+ || ((find_type & FIND_EVAL)
+ && col <= (int)startcol
+ && find_is_eval_item(ptr + col, &col, &bn, FORWARD))
+ )) {
col += (*mb_ptr2len)(ptr + col);
- } else
+ }
+ } else {
while ((i == 0 ? vim_iswordc(ptr[col])
: (ptr[col] != NUL && !ascii_iswhite(ptr[col])))
- ) {
- ++col;
+ || ((find_type & FIND_EVAL)
+ && col <= (int)startcol
+ && find_is_eval_item(ptr + col, &col, &bn, FORWARD))) {
+ col++;
}
+ }
assert(col >= 0);
return (size_t)col;