diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/api/private/helpers.h | 14 | ||||
| -rw-r--r-- | src/nvim/buffer_updates.c | 29 | ||||
| -rw-r--r-- | src/nvim/eval.c | 29 | ||||
| -rw-r--r-- | src/nvim/eval/userfunc.c | 3 | ||||
| -rw-r--r-- | src/nvim/eval/vars.c | 4 | ||||
| -rw-r--r-- | src/nvim/getchar.c | 20 |
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 |