Parameter.outer grabs too much in Ruby
Describe the bug
I have this code and with the cursor on the b in abc I execute the function:
This is what is selected:
Expected behavior
I would expect abc, to be selected instead of all the parameters.
Output of :checkhealth nvim-treesitter
nvim-treesitter: require("nvim-treesitter.health").check()
Installation ~
- WARNING
tree-sitter executable not found (parser generator, only needed for :TSInstallFromGrammar, not required for :TSInstall)
- OK
node found v20.7.0 (only needed for :TSInstallFromGrammar)
- OK
git executable found.
- OK
cc executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
Version: cc (GCC) 13.2.1 20230801
- OK Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.
OS Info:
{
machine = "x86_64",
release = "5.15.90.1-microsoft-standard-WSL2",
sysname = "Linux",
version = "#1 SMP Fri Jan 27 02:56:13 UTC 2023"
} ~
Parser/Features H L F I J
- bash ✓ ✓ ✓ . ✓
- c ✓ ✓ ✓ ✓ ✓
- eex ✓ . . . ✓
- elixir ✓ ✓ ✓ ✓ ✓
- elm ✓ . . . ✓
- heex ✓ ✓ ✓ ✓ ✓
- json ✓ ✓ ✓ ✓ .
- kdl ✓ ✓ ✓ ✓ ✓
- lua ✓ ✓ ✓ ✓ ✓
- make ✓ . ✓ . ✓
- markdown ✓ . ✓ ✓ ✓
- query ✓ ✓ ✓ ✓ ✓
- ruby ✓ ✓ ✓ ✓ ✓
- vim ✓ ✓ ✓ . ✓
- vimdoc ✓ . . . ✓
- yaml ✓ ✓ ✓ ✓ ✓
Output of nvim --version
NVIM v0.9.2
Build type: Release
LuaJIT 2.1.1694285958
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Additional context
I've disabled all plugins except for nvim-treesitter/nvim-treesitter and nvim-treesitter/nvimtreesitter-textobjects.
In a nutshell
Change @parameter.outer to @parameter.inner
Explanation
This isn't a bug, it actually the expected behavior.
You can check that by runnig :TSEditQuery textobjects in a ruby file. which will open the corresponding textobjects.scm file
If you search for @parameter.outer you'll see that its actually capturing (method_parameters) which essentially grab all the parameters of the method including the opening and closing parenthesis.
If your search for @parameter.inner you'll see that its actually capturing (method_parameters (_)) which essentially grab the node inside the (method_parameters) i.e all the identifiers (it will match the parameter under the cursor)
@parameter.inner doesn't select the characters I want. As an example I might want to remove an argument from the argument list. I should be able to do this with "delete outer argument".
It might be that Treesitter text objects are implemented in a specific way, but it goes against regular vim conventions.
By convention the difference between inner and outer is not the difference between one element in a list and all the elements but rather between just the element or the element and some surrounding "padding".
Well in that case you'll have to make a custom query to select the characters you want
I managed to make a simple one based on the textobjects.scm of java
- open a ruby file with nvim i.e
nvim frog.ruby - type
:TSEditQueryUserAfter textobjects, which will open the file.config/nvim/after/queries/ruby/textobjects.scm. If the file doesn't exist it will ask to create it. Choose yes - paste the following query in the file
;; extends
(method_parameters
"," @_start .
(identifier) @parameter.inner
(#make-range! "parameter.outer" @_start @parameter.inner))
(method_parameters
. (identifier) @parameter.inner
. ","? @_end
(#make-range! "parameter.outer" @parameter.inner @_end))
- save & quit then open the file again
This should at least work for the methods, but it's pretty straightforward to make it work for the other one as well
By convention the difference between inner and outer is not the difference between one element in a list and all the elements but rather between just the element or the element and some surrounding "padding".
Absolutely agreed. Usually all parameters are enclosed in a character that is already easily capturable with vanilla Neovim (like () in function arguments, or "" in HTML properties), and having @parameter.outer do the same thing as vanilla, whilst not following vanilla's convention, sounds really unintuitive to me.
For most languages, the current behaviour of @parameter.outer seems redundant, correct me if I'm wrong.