diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-05-10 17:42:14 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-10 17:42:14 +0800 |
commit | 5ac2e47acc999472042df4f10f8f7b5ffa72ba3e (patch) | |
tree | c0b61348936f80ade94d24db5932fc05ffb7ef36 | |
parent | 4e5061dba765df2a74ac4a8182f6e7fe21da125d (diff) | |
download | rneovim-5ac2e47acc999472042df4f10f8f7b5ffa72ba3e.tar.gz rneovim-5ac2e47acc999472042df4f10f8f7b5ffa72ba3e.tar.bz2 rneovim-5ac2e47acc999472042df4f10f8f7b5ffa72ba3e.zip |
fix(redo): make redo of Lua mappings in op-pending mode work (#23566)
-rw-r--r-- | src/nvim/edit.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 2 | ||||
-rw-r--r-- | src/nvim/getchar.c | 11 | ||||
-rw-r--r-- | src/nvim/normal.c | 2 | ||||
-rw-r--r-- | src/nvim/ops.c | 14 | ||||
-rw-r--r-- | src/nvim/ops.h | 4 | ||||
-rw-r--r-- | src/nvim/terminal.c | 2 | ||||
-rw-r--r-- | test/functional/api/keymap_spec.lua | 45 |
8 files changed, 57 insertions, 25 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index c544daee08..8fbc5fb2ab 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -881,7 +881,7 @@ static int insert_handle_key(InsertState *s) goto check_pum; case K_LUA: - map_execute_lua(); + map_execute_lua(false); check_pum: // nvim_select_popupmenu_item() can be called from the handling of diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index af2ec3356f..1345a29a21 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1140,7 +1140,7 @@ static int command_line_execute(VimState *state, int key) } else if (s->c == K_COMMAND) { do_cmdline(NULL, getcmdkeycmd, NULL, DOCMD_NOWAIT); } else { - map_execute_lua(); + map_execute_lua(false); } // nvim_select_popupmenu_item() can be called from the handling of diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index ca555937ab..5c1366c5b2 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -2986,7 +2986,12 @@ char *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat) return line_ga.ga_data; } -bool map_execute_lua(void) +/// Handle a Lua mapping: get its LuaRef from typeahead and execute it. +/// +/// @param may_repeat save the LuaRef for redoing with "." later +/// +/// @return false if getting the LuaRef was aborted, true otherwise +bool map_execute_lua(bool may_repeat) { garray_T line_ga; int c1 = -1; @@ -3018,6 +3023,10 @@ bool map_execute_lua(void) } LuaRef ref = (LuaRef)atoi(line_ga.ga_data); + if (may_repeat) { + repeat_luaref = ref; + } + Error err = ERROR_INIT; Array args = ARRAY_DICT_INIT; nlua_call_ref(ref, NULL, args, false, &err); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 890fa0f80a..fa6cdb0ad8 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3232,7 +3232,7 @@ static void nv_colon(cmdarg_T *cap) } if (is_lua) { - cmd_result = map_execute_lua(); + cmd_result = map_execute_lua(true); } else { // get a command line and execute it cmd_result = do_cmdline(NULL, is_cmdkey ? getcmdkeycmd : getexline, NULL, diff --git a/src/nvim/ops.c b/src/nvim/ops.c index c1511ab8da..de77cdd238 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5777,6 +5777,11 @@ typedef struct { int rv_arg; ///< extra argument } redo_VIsual_T; +static bool is_ex_cmdchar(cmdarg_T *cap) +{ + return cap->cmdchar == ':' || cap->cmdchar == K_COMMAND; +} + /// Handle an operator after Visual mode or when the movement is finished. /// "gui_yank" is true when yanking text for the clipboard. void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) @@ -5831,7 +5836,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) if ((redo_yank || oap->op_type != OP_YANK) && ((!VIsual_active || oap->motion_force) // Also redo Operator-pending Visual mode mappings. - || ((cap->cmdchar == ':' || cap->cmdchar == K_COMMAND) + || ((is_ex_cmdchar(cap) || cap->cmdchar == K_LUA) && oap->op_type != OP_COLON)) && cap->cmdchar != 'D' && oap->op_type != OP_FOLD @@ -5851,7 +5856,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) AppendToRedobuffLit(cap->searchbuf, -1); } AppendToRedobuff(NL_STR); - } else if (cap->cmdchar == ':' || cap->cmdchar == K_COMMAND) { + } else if (is_ex_cmdchar(cap)) { // do_cmdline() has stored the first typed line in // "repeat_cmdline". When several lines are typed repeating // won't be possible. @@ -5866,6 +5871,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) AppendToRedobuff(NL_STR); XFREE_CLEAR(repeat_cmdline); } + } else if (cap->cmdchar == K_LUA) { + AppendNumberToRedobuff(repeat_luaref); + AppendToRedobuff(NL_STR); } } @@ -6021,7 +6029,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) prep_redo(oap->regname, cap->count0, get_op_char(oap->op_type), get_extra_op_char(oap->op_type), oap->motion_force, cap->cmdchar, cap->nchar); - } else if (cap->cmdchar != ':' && cap->cmdchar != K_COMMAND) { + } else if (!is_ex_cmdchar(cap) && cap->cmdchar != K_LUA) { int opchar = get_op_char(oap->op_type); int extra_opchar = get_extra_op_char(oap->op_type); int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL; diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 75ea1853a0..4c5c6bafce 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -4,6 +4,7 @@ #include <stdbool.h> #include <stddef.h> +#include "lauxlib.h" #include "nvim/ascii.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" @@ -126,4 +127,7 @@ static inline int op_reg_index(const int regname) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ops.h.generated.h" #endif + +EXTERN LuaRef repeat_luaref INIT(= LUA_NOREF); ///< LuaRef for "." + #endif // NVIM_OPS_H diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 0686305d02..0b0e321d8c 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -596,7 +596,7 @@ static int terminal_execute(VimState *state, int key) break; case K_LUA: - map_execute_lua(); + map_execute_lua(false); break; case Ctrl_N: diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index f2817ff627..e239717d3a 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -813,19 +813,18 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('can make lua mappings', function() eq(0, exec_lua [[ GlobalCount = 0 - vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) + vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount ]]) feed('asdf\n') eq(1, exec_lua[[return GlobalCount]]) - end) it (':map command shows lua mapping correctly', function() exec_lua [[ - vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end }) + vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() print('jkl;') end }) ]] assert.truthy( string.match( @@ -837,7 +836,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it ('mapcheck() returns lua mapping correctly', function() exec_lua [[ - vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end }) + vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() print('jkl;') end }) ]] assert.truthy(string.match(funcs.mapcheck('asdf', 'n'), "^<Lua %d+>")) @@ -871,7 +870,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('can make lua expr mappings replacing keycodes', function() exec_lua [[ - vim.api.nvim_set_keymap ('n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true }) + vim.api.nvim_set_keymap('n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true }) ]] feed('aa') @@ -881,7 +880,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('can make lua expr mappings without replacing keycodes', function() exec_lua [[ - vim.api.nvim_set_keymap ('i', 'aa', '', {callback = function() return '<space>' end, expr = true }) + vim.api.nvim_set_keymap('i', 'aa', '', {callback = function() return '<space>' end, expr = true }) ]] feed('iaa<esc>') @@ -891,7 +890,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('lua expr mapping returning nil is equivalent to returning an empty string', function() exec_lua [[ - vim.api.nvim_set_keymap ('i', 'aa', '', {callback = function() return nil end, expr = true }) + vim.api.nvim_set_keymap('i', 'aa', '', {callback = function() return nil end, expr = true }) ]] feed('iaa<esc>') @@ -902,17 +901,29 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('does not reset pum in lua mapping', function() eq(0, exec_lua [[ VisibleCount = 0 - vim.api.nvim_set_keymap ('i', '<F2>', '', {callback = function() VisibleCount = VisibleCount + vim.fn.pumvisible() end}) + vim.api.nvim_set_keymap('i', '<F2>', '', {callback = function() VisibleCount = VisibleCount + vim.fn.pumvisible() end}) return VisibleCount ]]) feed('i<C-X><C-V><F2><F2><esc>') eq(2, exec_lua[[return VisibleCount]]) end) + it('redo of lua mappings in op-pending mode work', function() + eq(0, exec_lua [[ + OpCount = 0 + vim.api.nvim_set_keymap('o', '<F2>', '', {callback = function() OpCount = OpCount + 1 end}) + return OpCount + ]]) + feed('d<F2>') + eq(1, exec_lua[[return OpCount]]) + feed('.') + eq(2, exec_lua[[return OpCount]]) + end) + it('can overwrite lua mappings', function() eq(0, exec_lua [[ GlobalCount = 0 - vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) + vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount ]]) @@ -921,7 +932,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() eq(1, exec_lua[[return GlobalCount]]) exec_lua [[ - vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end }) + vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end }) ]] feed('asdf\n') @@ -932,7 +943,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('can unmap lua mappings', function() eq(0, exec_lua [[ GlobalCount = 0 - vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) + vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount ]]) @@ -1078,7 +1089,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() it('can make lua mappings', function() eq(0, exec_lua [[ GlobalCount = 0 - vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) + vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount ]]) @@ -1089,7 +1100,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() it('can make lua expr mappings replacing keycodes', function() exec_lua [[ - vim.api.nvim_buf_set_keymap (0, 'n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true }) + vim.api.nvim_buf_set_keymap(0, 'n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true }) ]] feed('aa') @@ -1099,7 +1110,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() it('can make lua expr mappings without replacing keycodes', function() exec_lua [[ - vim.api.nvim_buf_set_keymap (0, 'i', 'aa', '', {callback = function() return '<space>' end, expr = true }) + vim.api.nvim_buf_set_keymap(0, 'i', 'aa', '', {callback = function() return '<space>' end, expr = true }) ]] feed('iaa<esc>') @@ -1111,7 +1122,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() it('can overwrite lua mappings', function() eq(0, exec_lua [[ GlobalCount = 0 - vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) + vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount ]]) @@ -1120,7 +1131,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() eq(1, exec_lua[[return GlobalCount]]) exec_lua [[ - vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end }) + vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end }) ]] feed('asdf\n') @@ -1131,7 +1142,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() it('can unmap lua mappings', function() eq(0, exec_lua [[ GlobalCount = 0 - vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) + vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount ]]) |