Vim has the concept of actions, which can act on text objects via motions.
For example diw
will delete (the action) the inner word (the motion).
I want to create a function that can be applied/executed with those motions. For example, if my function appends to certain register, I can append whatever I want by doing myFunction + motion for what I want to add
.
Asked
Active
Viewed 1,622 times
0

Danielo515
- 5,996
- 4
- 32
- 66
-
Cross-posted on https://vi.stackexchange.com/questions/37444/how-to-create-a-lua-function-that-gets-called-for-a-vim-neovim-motion. – Big McLargeHuge Sep 10 '22 at 15:38
1 Answers
0
The only way to do it is with the g@
mapping and the opfunc global variable. It is required to modify the opfunc to point to a global callable object and then call the g@
+ motion keymap. This is even suggested by the vim docs, where they create a mapping where both the opfunc is set and then the g@
motion is called on the same command.
This seems to be the closer you can get using lua until they provide a better lua integration
function format_range_operator()
local old_func = vim.go.operatorfunc -- backup previous reference
-- set a globally callable object/function
_G.op_func_formatting = function()
-- the content covered by the motion is between the [ and ] marks, so get those
local start = vim.api.nvim_buf_get_mark(0, '[')
local finish = vim.api.nvim_buf_get_mark(0, ']')
vim.lsp.buf.range_formatting({}, start, finish)
vim.go.operatorfunc = old_func -- restore previous opfunc
_G.op_func_formatting = nil -- deletes itself from global namespace
end
vim.go.operatorfunc = 'v:lua.op_func_formatting'
vim.api.nvim_feedkeys('g@', 'n', false)
end
vim.api.nvim_set_keymap("n", "gm", "<cmd>lua format_range_operator()<CR>", {noremap = true})
Picked from: https://github.com/neovim/nvim-lspconfig/wiki/User-contributed-tips#range-formatting-with-a-motion

Danielo515
- 5,996
- 4
- 32
- 66
-
why does `op_func_formatting` have to be global but `format_range_operator` does not? – theonlygusti Mar 26 '23 at 01:49