0

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.

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 Answers1

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