5

I'm hoping to write a macro that involves jumping to a second argument of a function call and deleting it. The function arguments will sometimes include nested function calls, sometimes not, will sometimes be on multiple lines, and sometimes all on one line.

I was hoping to use nvim-treesitter-textobjects to jump to the next argument via something like this:

require'nvim-treesitter.configs'.setup {
  textobjects = {
     move = {
       enable = true,
       set_jumps = true,

       goto_previous_start = {
         ["[["] = "@parameter.inner",
       },
       goto_next_start = {
         ["]]"] = "@parameter.inner",
       },
     },
  },
}

And then for example, with a code snippet like this:

func foo(a, b int) int {
  return a * b
}

func bar(a, b int) int {
  return a + b
}

func main() {
  foo(
    bar(
      1, 
      2,
    ),
    3,
  )
}

When my cursor is on bar, and I hit ]], I'd like it to jump to 3, the next argument at the same level as the current node. However, it unfortunately jumps to 1, the next argument at the lower level of the nested function call.

Any suggestions for how to achieve this desired jump?

1 Answer 1

2

Unfortunately I did not find a suitable solution using custom queries or with treesitter-textobjects, however I found an issue in the repo which described a similar problem.

To achieve the behavior you want, I hacked up this function using ts_utils. So all we need now is just to bind it to a key.

vim.keymap.set("n", "]]", function()
  local t = require("nvim-treesitter.ts_utils")
  t.goto_node(t.get_next_node(t.get_node_at_cursor(), true, true), false, true)
end)

vim.keymap.set("n", "[[", function()
  local t = require("nvim-treesitter.ts_utils")
  t.goto_node(t.get_previous_node(t.get_node_at_cursor(), true, true), false, true)
end)

These mappings would actually work on nodes of any type, not just argument lists.

Here is each of the positions the cursor (|) visits when pressing ]] and/or [[:

foo(
  |bar|(
    1, 
    2,
  ),
  |3,
)

Example motion in lua table:

o = {
  |a = |1,
  |2,
  |c = |{ 31, 32 },
  |4,
}

Note

  • Last argument true to goto_node avoids adding the jump to jumplist
  • Arguments true, true to get_next_node allows jumping to next parent

Please see the docs for ts_utils for reference:

https://github.com/nvim-treesitter/nvim-treesitter/blob/master/doc/nvim-treesitter.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.