Open JoseConseco opened 2 years ago
Great, how to do this with custom key maping?
You can use the following wrapper to conveniently wrap a rhs
to be passed to vim.keymap.set
:
---Register a global internal keymap that wraps `rhs` to be repeatable.
---@param mode string|table keymap mode, see vim.keymap.set()
---@param lhs string lhs of the internal keymap to be created, should be in the form `<Plug>(...)`
---@param rhs string|function rhs of the keymap, see vim.keymap.set()
---@return string The name of a registered internal `<Plug>(name)` keymap. Make sure you use { remap = true }.
local make_repeatable_keymap = function (mode, lhs, rhs)
vim.validate {
mode = { mode, { 'string', 'table' } },
rhs = { rhs, { 'string', 'function' },
lhs = { name = 'string' } }
}
if not vim.startswith(lhs, "<Plug>") then
error("`lhs` should start with `<Plug>`, given: " .. lhs)
end
vim.keymap.set(mode, lhs, function()
rhs()
vim.fn['repeat#set'](vim.api.nvim_replace_termcodes(lhs, true, true, true))
end)
return lhs
end
(Note: this does not implement opts
for such as buffer
, nowait
, silent
, etc., but it should be straightforward to extend)
Example: If you want to make a keymap <leader>tc
mapped to a lua function (or any keymap sequence string) repeatable:
vim.keymap.set('n', '<leader>tc', make_repeatable_keymap('n', '<Plug>(ToggleComment)', function()
-- the actual body (rhs) goes here: some complex logic that you want to repeat
end, { remap = true })
This will:
<Plug>(ToggleComment)
that does the job to make the internal keymap repeatable.<leader>tc
to <Plug>(ToggleComment)
, which will execute the desired body (rhs).{ remap = true }
.To see a working example in the wild, please see my dotfiles: https://github.com/wookayin/dotfiles/commit/3fe6e68563d13c7f40a5a5870f087c99692e3c13. See how complicated it was to write things in vimscript with dirty string manipulation; in Lua, functional programming makes config more concise!
So in order to make vim-repeat work, in general one should have a keymap (or a command) like:
<Plug>(MyKeymap)
.repeat#set("<Plug>(MyKeymap)")
to mark the keymap sequence to repeat by .
.
feedkeys
under the hood -- so need to use nvim_replace_termcodes
; also an anonymous function cannot be used.For keymap, it is very recommended (although not mandatory) to use <Plug>
to create an internal mapping, because this will make key repeat much, much easier to write and understand.
I had trouble to make vim-repeat work in neovim with lua, but finally here it is:
t() function is just nvim helper:
All you have to do is to write your custom : get_big_word('i') - function - in my case I wanted to write custom big WORD text object. I guess it should work for any custom lua functions, not just
o
. Hopefully people will find this useful.