Tree-sitter powered textobjects for evil mode in Emacs.
This is an Emacs port of nvim-treesitter/nvim-treesitter-textobjects.
This package will let you create evil textobjects using tree-sitter grammars. You can easily create function,class,comment etc textobjects in multiple languages.
You can install evil-textobj-tree-sitter
from melpa. Here is how you would do it using use-package
and package.el
:
(use-package evil-textobj-tree-sitter :ensure t)
Or you can use straight.el
:
(use-package evil-textobj-tree-sitter :straight t)
Or using straight.el
and el-get
to pull from source:
(use-package evil-textobj-tree-sitter
:straight (evil-textobj-tree-sitter :type git
:host github
:repo "meain/evil-textobj-tree-sitter"
:files (:defaults "queries")))
You will also have to setup
tree-sitter
.
By default, the library does not provide any keybindings, but it should be relatively easy to add them.
;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf`
(define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer"))
;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif`
(define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner"))
We support quite a few textobjects. You can find a list of available
textobjects at
nvim-treesitter/nvim-treesitter-textobjects.
We might not have support for all of them as
emacs-tree-sitter
does not yet support all the languages as of now. As for the list of
languages that we support you can check the value of
evil-textobj-tree-sitter-major-mode-language-alist
.
If you are not able to find the text object that you are looking for in the builtin list, you can create custom text objects by passing the a custom query with captures.
For example if you want to create text object to select import
statements, you can write something like below. You will have to
provide the tree-sitter queries for all the languages that you want it
to work for
;; The first arguemnt to `evil-textobj-tree-sitter-get-textobj' will be the capture group to use
;; and the second arg will be an alist mapping major-mode to the corresponding query to use.
(define-key evil-outer-text-objects-map "m" (evil-textobj-tree-sitter-get-textobj "import"
'((python-mode . [(import_statement) @import])
(rust-mode . [(use_declaration) @import]))))
As I have already mentioned, I pull the text objects from nvim-treesitter/nvim-treesitter-textobjects project. This right now automatically happens every friday using a Github Action which will create a new PR on the repo. So if you would like to update/add the builtin tree-sitter objects, feel free to update them in the neovim project repository. Unless there is something Emacs specific I recommend everyone to just submit the new queries to that project.
If you are adding a completely new language, there is two other things that you will have to do to make sure everything will work well.
- Make sure the lang is available in emacs-tree-sitter/tree-sitter-langs
- Make sure we have a
major-mode
mapping in evil-textobj-tree-sitter-major-mode-language-alist
The primary codebase is licensed under Apache-2.0
. The queries have
be taken from
nvim-treesitter/nvim-treesitter-textobjects
which is also licensed under the same license.