aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/private/helpers.h14
-rw-r--r--src/nvim/buffer_updates.c29
-rw-r--r--src/nvim/eval.c29
-rw-r--r--src/nvim/eval/userfunc.c3
-rw-r--r--src/nvim/eval/vars.c4
-rw-r--r--src/nvim/getchar.c20
6 files changed, 60 insertions, 39 deletions
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index b70452d7cb..1b82aeac34 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -155,8 +155,18 @@ typedef struct {
msglist_T *private_msg_list; \
msg_list = &private_msg_list; \
private_msg_list = NULL; \
- code \
- msg_list = saved_msg_list; /* Restore the exception context. */ \
+ code; \
+ msg_list = saved_msg_list; /* Restore the exception context. */ \
+ } while (0)
+
+// Execute code with cursor position saved and restored and textlock active.
+#define TEXTLOCK_WRAP(code) \
+ do { \
+ const pos_T save_cursor = curwin->w_cursor; \
+ textlock++; \
+ code; \
+ textlock--; \
+ curwin->w_cursor = save_cursor; \
} while (0)
// Useful macro for executing some `code` for each item in an array.
diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c
index 075ac2adbf..9543731c9b 100644
--- a/src/nvim/buffer_updates.c
+++ b/src/nvim/buffer_updates.c
@@ -188,9 +188,9 @@ void buf_updates_unload(buf_T *buf, bool can_reload)
// the first argument is always the buffer handle
args.items[0] = BUFFER_OBJ(buf->handle);
- textlock++;
- nlua_call_ref(thecb, keep ? "reload" : "detach", args, false, NULL);
- textlock--;
+ TEXTLOCK_WRAP({
+ nlua_call_ref(thecb, keep ? "reload" : "detach", args, false, NULL);
+ });
}
if (keep) {
@@ -305,9 +305,11 @@ void buf_updates_send_changes(buf_T *buf, linenr_T firstline, int64_t num_added,
args.items[6] = INTEGER_OBJ((Integer)deleted_codepoints);
args.items[7] = INTEGER_OBJ((Integer)deleted_codeunits);
}
- textlock++;
- Object res = nlua_call_ref(cb.on_lines, "lines", args, false, NULL);
- textlock--;
+
+ Object res;
+ TEXTLOCK_WRAP({
+ res = nlua_call_ref(cb.on_lines, "lines", args, false, NULL);
+ });
if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
buffer_update_callbacks_free(cb);
@@ -354,9 +356,10 @@ void buf_updates_send_splice(buf_T *buf, int start_row, colnr_T start_col, bcoun
ADD_C(args, INTEGER_OBJ(new_col));
ADD_C(args, INTEGER_OBJ(new_byte));
- textlock++;
- Object res = nlua_call_ref(cb.on_bytes, "bytes", args, false, NULL);
- textlock--;
+ Object res;
+ TEXTLOCK_WRAP({
+ res = nlua_call_ref(cb.on_bytes, "bytes", args, false, NULL);
+ });
if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
buffer_update_callbacks_free(cb);
@@ -389,10 +392,10 @@ void buf_updates_changedtick(buf_T *buf)
// next argument is b:changedtick
ADD_C(args, INTEGER_OBJ(buf_get_changedtick(buf)));
- textlock++;
- Object res = nlua_call_ref(cb.on_changedtick, "changedtick",
- args, false, NULL);
- textlock--;
+ Object res;
+ TEXTLOCK_WRAP({
+ res = nlua_call_ref(cb.on_changedtick, "changedtick", args, false, NULL);
+ });
if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
buffer_update_callbacks_free(cb);
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index cbad5d04ff..9b42375120 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -2906,6 +2906,12 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string)
case '8':
case '9':
ret = get_number_tv(arg, rettv, evaluate, want_string);
+
+ // Apply prefixed "-" and "+" now. Matters especially when
+ // "->" follows.
+ if (ret == OK && evaluate && end_leader > start_leader) {
+ ret = eval7_leader(rettv, true, start_leader, &end_leader);
+ }
break;
// String constant: "string".
@@ -3011,13 +3017,12 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string)
// Handle following '[', '(' and '.' for expr[expr], expr.name,
// expr(expr), expr->name(expr)
if (ret == OK) {
- ret = handle_subscript((const char **)arg, rettv, evaluate, true,
- (char *)start_leader, &end_leader);
+ ret = handle_subscript((const char **)arg, rettv, evaluate, true);
}
// Apply logical NOT and unary '-', from right to left, ignore '+'.
if (ret == OK && evaluate && end_leader > start_leader) {
- ret = eval7_leader(rettv, (char *)start_leader, &end_leader);
+ ret = eval7_leader(rettv, false, start_leader, &end_leader);
}
recurse--;
@@ -3027,9 +3032,11 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string)
/// Apply the leading "!" and "-" before an eval7 expression to "rettv".
/// Adjusts "end_leaderp" until it is at "start_leader".
///
+/// @param numeric_only if true only handle "+" and "-".
+///
/// @return OK on success, FAIL on failure.
-static int eval7_leader(typval_T *const rettv, const char *const start_leader,
- const char **const end_leaderp)
+static int eval7_leader(typval_T *const rettv, const bool numeric_only,
+ const char *const start_leader, const char **const end_leaderp)
FUNC_ATTR_NONNULL_ALL
{
const char *end_leader = (char *)(*end_leaderp);
@@ -3050,6 +3057,10 @@ static int eval7_leader(typval_T *const rettv, const char *const start_leader,
while (end_leader > start_leader) {
end_leader--;
if (*end_leader == '!') {
+ if (numeric_only) {
+ end_leader++;
+ break;
+ }
if (rettv->v_type == VAR_FLOAT) {
f = !(bool)f;
} else {
@@ -6899,8 +6910,7 @@ int check_luafunc_name(const char *const str, const bool paren)
/// @param verbose give error messages
/// @param start_leader start of '!' and '-' prefixes
/// @param end_leaderp end of '!' and '-' prefixes
-int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int verbose,
- const char *const start_leader, const char **const end_leaderp)
+int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int verbose)
{
int ret = OK;
dict_T *selfdict = NULL;
@@ -6944,11 +6954,6 @@ int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int
tv_dict_unref(selfdict);
selfdict = NULL;
} else if (**arg == '-') {
- // Expression "-1.0->method()" applies the leader "-" before
- // applying ->.
- if (evaluate && *end_leaderp > start_leader) {
- ret = eval7_leader(rettv, (char *)start_leader, end_leaderp);
- }
if (ret == OK) {
if ((*arg)[2] == '{') {
// expr->{lambda}()
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 3c4cc34464..13779f4173 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -3075,8 +3075,7 @@ void ex_call(exarg_T *eap)
}
// Handle a function returning a Funcref, Dictionary or List.
- if (handle_subscript((const char **)&arg, &rettv, true, true,
- (const char *)name, (const char **)&name)
+ if (handle_subscript((const char **)&arg, &rettv, true, true)
== FAIL) {
failed = true;
break;
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c
index d80bdc70f6..ed2453bd59 100644
--- a/src/nvim/eval/vars.c
+++ b/src/nvim/eval/vars.c
@@ -508,7 +508,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
} else {
// handle d.key, l[idx], f(expr)
const char *const arg_subsc = arg;
- if (handle_subscript(&arg, &tv, true, true, name, &name) == FAIL) {
+ if (handle_subscript(&arg, &tv, true, true) == FAIL) {
error = true;
} else {
if (arg == arg_subsc && len == 2 && name[1] == ':') {
@@ -1715,7 +1715,7 @@ bool var_exists(const char *var)
n = get_var_tv(name, len, &tv, NULL, false, true) == OK;
if (n) {
// Handle d.key, l[idx], f(expr).
- n = handle_subscript(&var, &tv, true, false, name, &name) == OK;
+ n = handle_subscript(&var, &tv, true, false) == OK;
if (n) {
tv_clear(&tv);
}
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 183fd5e19f..ea541dbca4 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -2345,7 +2345,7 @@ void check_end_reg_executing(bool advance)
/// K_SPECIAL may be escaped, need to get two more bytes then.
static int vgetorpeek(bool advance)
{
- int c, c1;
+ int c;
bool timedout = false; // waited for more than 'timeoutlen'
// for mapping to complete or
// 'ttimeoutlen' for complete key code
@@ -2639,7 +2639,7 @@ static int vgetorpeek(bool advance)
// input from the user), show the partially matched characters
// to the user with showcmd.
int showcmd_idx = 0;
- c1 = 0;
+ bool showing_partial = false;
if (typebuf.tb_len > 0 && advance && !exmode_active) {
if (((State & (MODE_NORMAL | MODE_INSERT)) || State == MODE_LANGMAP)
&& State != MODE_HITRETURN) {
@@ -2648,7 +2648,7 @@ static int vgetorpeek(bool advance)
&& ptr2cells((char *)typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len - 1) == 1) {
edit_putchar(typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1], false);
setcursor(); // put cursor back where it belongs
- c1 = 1;
+ showing_partial = true;
}
// need to use the col and row from above here
old_wcol = curwin->w_wcol;
@@ -2666,12 +2666,15 @@ static int vgetorpeek(bool advance)
curwin->w_wrow = old_wrow;
}
- // this looks nice when typing a dead character map
- if ((State & MODE_CMDLINE) && cmdline_star == 0) {
+ // This looks nice when typing a dead character map.
+ // There is no actual command line for get_number().
+ if ((State & MODE_CMDLINE)
+ && get_cmdline_info()->cmdbuff != NULL
+ && cmdline_star == 0) {
char *p = (char *)typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len - 1;
if (ptr2cells(p) == 1 && (uint8_t)(*p) < 128) {
putcmdline(*p, false);
- c1 = 1;
+ showing_partial = true;
}
}
}
@@ -2704,11 +2707,12 @@ static int vgetorpeek(bool advance)
if (showcmd_idx != 0) {
pop_showcmd();
}
- if (c1 == 1) {
+ if (showing_partial == 1) {
if (State & MODE_INSERT) {
edit_unputchar();
}
- if (State & MODE_CMDLINE) {
+ if ((State & MODE_CMDLINE)
+ && get_cmdline_info()->cmdbuff != NULL) {
unputcmdline();
} else {
setcursor(); // put cursor back where it belongs