nvim-treesitter / nvim-treesitter-textobjects

Apache License 2.0
2.12k stars 190 forks source link

Text objects don't work inside of injected languages #131

Closed notpeelz closed 2 years ago

notpeelz commented 2 years ago

Describe the bug

Text objects don't work inside of injected languages.

Pressing daa here doesn't do anything. image

Related to #27

To Reproduce Steps to reproduce the behavior using the following textobjects config:

textobjects = {
  select = {
    enable = true,
    lookahead = true,
    keymaps = {
      ["aa"] = "@parameter.outer",
      ["ia"] = "@parameter.inner",
    },
  },
},
  1. Open a new buffer
  2. Type :set ft=vim
  3. Insert this code and move your cursor to the 2nd parameter:
    lua <<EOF
    test(1, 2)
    EOF
  4. Press daa (nothing happens)

Output of :checkhealth nvim_treesitter

``` nvim_treesitter: health#nvim_treesitter#check ======================================================================== ## Installation - WARNING: `tree-sitter` executable not found (parser generator, only needed for :TSInstallFromGrammar, not required for :TSInstall) - OK: `node` found v16.10.0 (only needed for :TSInstallFromGrammar) - OK: `git` executable found. - OK: `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" } Version: cc (Debian 8.3.0-6) 8.3.0 - OK: Neovim was compiled with tree-sitter runtime ABI version 13 (required >=13). Parsers must be compatible with runtime ABI. ## Parser/Features H L F I J - dart ✓ ✓ . ✓ ✓ - ruby ✓ ✓ ✓ ✓ ✓ - ocaml_interface✓ ✓ ✓ . ✓ - c_sharp ✓ ✓ ✓ . ✓ - dockerfile ✓ . . . ✓ - svelte ✓ . ✓ ✓ ✓ - typescript ✓ ✓ ✓ ✓ ✓ - regex ✓ . . . . - zig ✓ . ✓ ✓ ✓ - supercollider ✓ ✓ ✓ ✓ ✓ - r ✓ ✓ . . . - haskell ✓ . . . ✓ - hcl ✓ . ✓ ✓ ✓ - tlaplus ✓ . ✓ . ✓ - pioasm ✓ . . . ✓ - glimmer ✓ . . . . - json ✓ ✓ ✓ ✓ . - fish ✓ ✓ ✓ ✓ ✓ - llvm ✓ . . . . - jsonc ✓ ✓ ✓ ✓ ✓ - query ✓ ✓ ✓ ✓ ✓ - yang ✓ . ✓ . . - scala ✓ . ✓ . ✓ - scss ✓ . . ✓ . - rst ✓ ✓ . . ✓ - fennel ✓ ✓ . . ✓ - ql ✓ ✓ . ✓ ✓ - heex ✓ . ✓ ✓ ✓ - verilog ✓ ✓ ✓ . ✓ - c ✓ ✓ ✓ ✓ ✓ - jsdoc ✓ . . . . - sparql ✓ ✓ ✓ ✓ ✓ - html ✓ ✓ ✓ ✓ ✓ - toml ✓ ✓ ✓ ✓ ✓ - javascript ✓ ✓ ✓ ✓ ✓ - tsx ✓ ✓ ✓ ✓ ✓ - java ✓ ✓ . ✓ ✓ - turtle ✓ ✓ ✓ ✓ ✓ - vue ✓ . ✓ . ✓ - hjson ✓ ✓ ✓ ✓ ✓ - python ✓ ✓ ✓ ✓ ✓ - lua ✓ ✓ ✓ ✓ ✓ - clojure ✓ ✓ ✓ . ✓ - perl ✓ . . . . - vim ✓ ✓ . . ✓ - commonlisp ✓ ✓ ✓ . . - cmake ✓ . ✓ . . - latex ✓ . ✓ . ✓ - yaml ✓ ✓ ✓ ✓ ✓ - cuda ✓ ✓ ✓ ✓ ✓ - beancount ✓ . ✓ . . - bibtex ✓ . ✓ ✓ . - kotlin ✓ . . . ✓ - comment ✓ . . . . - glsl ✓ ✓ ✓ ✓ ✓ - fortran ✓ . ✓ ✓ . - julia ✓ ✓ ✓ ✓ ✓ - graphql ✓ . . ✓ ✓ - elm . . . . . - dot ✓ . . . ✓ - json5 ✓ . . . ✓ - nix ✓ ✓ ✓ . ✓ - rust ✓ ✓ ✓ ✓ ✓ - erlang . . . . . - ledger ✓ . ✓ ✓ ✓ - css ✓ . ✓ ✓ ✓ - elixir ✓ ✓ ✓ ✓ ✓ - go ✓ ✓ ✓ ✓ ✓ - php ✓ ✓ ✓ ✓ ✓ - surface ✓ . ✓ ✓ ✓ - bash ✓ ✓ ✓ . ✓ - gomod ✓ . . . . - cpp ✓ ✓ ✓ ✓ ✓ - ocaml ✓ ✓ ✓ . ✓ Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections +) multiple parsers found, only one will be used x) errors found in the query, try to run :TSUpdate {lang} ```

Output of nvim --version

NVIM v0.6.0-dev+479-g9086938f7
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/gcc-11 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/runner/work/neovim/neovim/build/config -I/home/runner/work/neovim/neovim/src -I/home/runner/work/neovim/neovim/.deps/usr/include -I/usr/include -I/home/runner/work/neovim/neovim/build/src/nvim/auto -I/home/runner/work/neovim/neovim/build/include
Compiled by runner@fv-az50-41

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "
/home/runner/work/neovim/neovim/build/nvim.AppDir/usr/share/nvim"

Run :checkhealth for more info
theHamsta commented 2 years ago

They only work when the parent language has a textobject of that kind. The keybindings will only be set for the parent language because language injection is dynamic which mean any language could be injected at any moment. Users requested that the keybindings should not be set when a parent language doesn't have a certain textobject but probably it should always be set which configurable fallback functions that will be executed when no textobject is found.

You could set the keybindings manually. Eg TSTexobjectSelect @paramater.outer should work.

theHamsta commented 2 years ago

Or in other words: the parent language defines which mappings will be defined: so you could just add textobjects for viml. Then, it will also work for injected languages.

notpeelz commented 2 years ago

You could set the keybindings manually. Eg TSTexobjectSelect @paramater.outer should work.

That only works in normal mode. I'd prefer to keep using operator-pending mappings.

This works but it's not super pretty:

onoremap aa <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@parameter.outer', 'o')<CR>
onoremap ia <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('@parameter.inner', 'o')<CR>

Users requested that the keybindings should not be set when a parent language doesn't have

Would it be possible to add a setting to control that behavior? What's the use case for enabling mappings on a per-language basis?

theHamsta commented 2 years ago

Would it be possible to add a setting to control that behavior? What's the use case for enabling mappings on a per-language basis?

They had their own regex-based mappings for languages that had no tree-sitter support. This is why I said that we could solve this by having fall-back actions when no tree-sitter textobject is found.

Probably the quickest fix for this concrete issue is to just add Viml textobject. A solution for the general problem can be done later.

notpeelz commented 2 years ago

Sounds good.

For anybody else who might have the same issue as me; this is what I ended up doing:

fun! s:TextobjectMapping(lhs, rhs)
  execute("onoremap " . a:lhs . " <Cmd>lua require'nvim-treesitter.textobjects.select'.select_textobject('" . a:rhs .  "', 'o')<CR>")
endfun

call s:TextobjectMapping('aa', '@parameter.outer')
call s:TextobjectMapping('ia', '@parameter.inner')
" ...
theHamsta commented 2 years ago

I'm closing this issue because nvim-treesitter-textobjects works within injected languages. There is however a problem that the mappings are only set for the parent language. Feel free to open a new issue for that one. This can however maybe not avoided since every language can be injected in any other language and we don't want to set unsupported mappings.

ribru17 commented 8 months ago

@theHamsta Would you be opposed to a PR that possibly also checks for injected languages in the injections.scm queries and then adds those potential text objects as mappings?