{"id":13338387,"url":"https://github.com/meain/evil-textobj-tree-sitter","last_synced_at":"2025-08-12T05:03:54.891Z","repository":{"id":39706774,"uuid":"393126640","full_name":"meain/evil-textobj-tree-sitter","owner":"meain","description":"Tree-sitter powered textobjects for evil mode in Emacs","archived":false,"fork":false,"pushed_at":"2025-07-11T15:32:55.000Z","size":280,"stargazers_count":214,"open_issues_count":7,"forks_count":14,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-07-11T17:45:11.066Z","etag":null,"topics":["emacs","evil","tree-sitter","vim-textobject"],"latest_commit_sha":null,"homepage":"","language":"Tree-sitter Query","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-08-05T17:40:25.000Z","updated_at":"2025-07-11T15:32:58.000Z","dependencies_parsed_at":"2023-12-22T16:52:01.400Z","dependency_job_id":"72c63949-5c68-4149-9836-7c51f51f7855","html_url":"https://github.com/meain/evil-textobj-tree-sitter","commit_stats":{"total_commits":207,"total_committers":12,"mean_commits":17.25,"dds":0.5748792270531401,"last_synced_commit":"b4ef204ff80ed00b03cf8839ee29101ed867dd58"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/meain/evil-textobj-tree-sitter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meain%2Fevil-textobj-tree-sitter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meain%2Fevil-textobj-tree-sitter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meain%2Fevil-textobj-tree-sitter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meain%2Fevil-textobj-tree-sitter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meain","download_url":"https://codeload.github.com/meain/evil-textobj-tree-sitter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meain%2Fevil-textobj-tree-sitter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270005557,"owners_count":24510934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["emacs","evil","tree-sitter","vim-textobject"],"created_at":"2024-07-29T19:16:18.415Z","updated_at":"2025-08-12T05:03:54.883Z","avatar_url":"https://github.com/meain.png","language":"Tree-sitter Query","funding_links":[],"categories":[],"sub_categories":[],"readme":"# evil-textobj-tree-sitter\n\n[![MELPA](https://melpa.org/packages/evil-textobj-tree-sitter-badge.svg)](https://melpa.org/#/evil-textobj-tree-sitter)\n[![test](https://github.com/meain/evil-textobj-tree-sitter/actions/workflows/test.yaml/badge.svg)](https://github.com/meain/evil-textobj-tree-sitter/actions/workflows/test.yaml)\n\nTree-sitter powered textobjects for Emacs. You can use them with `evil-mode` or with `thing-at-point`.\n\n![gif](https://meain.io/blog-videos/gifs/evil-textobj-treesitter.gif)\n\nThis package will let you create evil textobjects using tree-sitter\ngrammars. You can easily create function,class,comment etc textobjects\nin multiple languages. It also make additional `things` available in\n`thing-at-point` like `function`, `class`, `loop`, `comment` etc.\n\n\u003e It can work with either elisp-tree-sitter or the builtin treesit library.\n\n# Installation\n\nYou can install `evil-textobj-tree-sitter` from melpa. Here is how you would do it using `use-package` and `package.el`:\n\n```emacs-lisp\n(use-package evil-textobj-tree-sitter :ensure t)\n```\n\nOr you can use `straight.el`:\n\n```emacs-lisp\n(use-package evil-textobj-tree-sitter :straight t)\n```\n\nOr using `straight.el` and `el-get` to pull from source:\n\n```emacs-lisp\n(use-package evil-textobj-tree-sitter\n  :straight (evil-textobj-tree-sitter :type git\n                      :host github\n                      :repo \"meain/evil-textobj-tree-sitter\"\n                      :files (:defaults \"queries\" \"treesit-queries\")))\n```\n\n\u003e You will also have to setup [`tree-sitter`](https://github.com/emacs-tree-sitter/elisp-tree-sitter).\n\n# Usage\n\n## `thing-at-point` additions\n\nThe package adds more \"things\" to `thing-at-point`. You can find all\nthe things that it adds in the\n[source](https://github.com/meain/evil-textobj-tree-sitter/blob/master/evil-textobj-tree-sitter-thing-at-point.el).\n\nYou can use these like any other `thing-at-point` entries. For example\nin case of functions, we make the following available:\n\n- `(thing-at-point 'function)`\n- `(function-at-point)`\n\n## Mapping textobjects\n\nBy default, the library does not provide any keybindings, but it\nshould be relatively easy to add them.\n\n```emacs-lisp\n;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf`\n(define-key evil-outer-text-objects-map \"f\" (evil-textobj-tree-sitter-get-textobj \"function.outer\"))\n;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif`\n(define-key evil-inner-text-objects-map \"f\" (evil-textobj-tree-sitter-get-textobj \"function.inner\"))\n\n;; You can also bind multiple items and we will match the first one we can find\n(define-key evil-outer-text-objects-map \"a\" (evil-textobj-tree-sitter-get-textobj (\"conditional.outer\" \"loop.outer\")))\n```\n\n## Custom textobjects\n\nIf you are not able to find the text object that you are looking for\nin the builtin list, you can create custom text objects by passing the\na custom query with captures.\n\nFor example if you want to create text object to select `import`\nstatements, you can write something like below. _You will have to\nprovide the tree-sitter queries for all the languages that you want it\nto work for_\n\n```emacs-lisp\n;; The first arguemnt to `evil-textobj-tree-sitter-get-textobj' will be the capture group to use\n;; and the second arg will be an alist mapping major-mode to the corresponding query to use.\n(define-key evil-outer-text-objects-map \"m\" (evil-textobj-tree-sitter-get-textobj \"import\"\n                                              '((python-mode . ((import_statement) @import)) ;; default modes (using tree-sitter)\n                                                (python-ts-mode . ((import_statement) @import)) ;; treesit modes\n                                                (rust-mode . ((use_declaration) @import)))))\n```\n\n## Goto\n\nWe have also added support for for a fancier version of\n`goto-char`. You can use this to go to the next function, previous\nclass or do any motions like that.\n\nYou can use the `evil-textobj-tree-sitter-goto-textobj` function to\ninvoke goto. You can either use this in other function or just bound\nto a key. The first argument is the textobj that you want to use, the\nsecond one specifies if you want to search forward or backward and the\nlast one is for specifying weather to go to the start or end of the\ntextobj.\n\nBelow are some sample binding that you can do. You can use any textobj\nthat is available here.\n\n```emacs-lisp\n;; Goto start of next function\n(define-key evil-normal-state-map\n            (kbd \"]f\")\n            (lambda ()\n              (interactive)\n              (evil-textobj-tree-sitter-goto-textobj \"function.outer\")))\n\n;; Goto start of previous function\n(define-key evil-normal-state-map\n            (kbd \"[f\")\n            (lambda ()\n              (interactive)\n              (evil-textobj-tree-sitter-goto-textobj \"function.outer\" t)))\n\n;; Goto end of next function\n(define-key evil-normal-state-map\n            (kbd \"]F\")\n            (lambda ()\n              (interactive)\n              (evil-textobj-tree-sitter-goto-textobj \"function.outer\" nil t)))\n\n;; Goto end of previous function\n(define-key evil-normal-state-map\n            (kbd \"[F\")\n            (lambda ()\n              (interactive)\n              (evil-textobj-tree-sitter-goto-textobj \"function.outer\" t t)))\n```\n\n# Finding and contributing to textobjects\n\n`evil-textobj-tree-sitter` work with both builtin `treesit` and\n`elisp-tree-sitter`. The queries in use are a bit different in both\ncases with the `elisp-tree-sitter` version currently being more feature\ncomplete. In both cases we pull the queries from external sources. For\n`elisp-tree-sitter`, we source them from\n[nvim-treesitter/nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects#built-in-textobjects)\nand is places into\n[queries](https://github.com/meain/evil-textobj-tree-sitter/tree/master/queries)\ndirectory. And for `treesit` queries, it is sourced from\n[helix](https://github.com/helix-editor/helix/tree/master/runtime/queries)\nand placed in\n[treesit-queries](https://github.com/meain/evil-textobj-tree-sitter/tree/master/treesit-queries).\nYou can check these files to see what all is available. If you are\ninteresting in contributing additional textobjects, you can do so by\nsubmitting to the respective projects. If there is enough interest, I\ndon't mind starting to manage queries ourselves.\n\nIf you are adding a completely new language, there is two other things\nthat you will have to do to make sure everything will work well.\n\n1. Make sure the lang is available in [emacs-tree-sitter/tree-sitter-langs](https://github.com/emacs-tree-sitter/tree-sitter-langs/tree/master/queries) or `treesit`.\n2. Make sure we have a `major-mode` mapping in [evil-textobj-tree-sitter-major-mode-language-alist](https://github.com/meain/evil-textobj-tree-sitter/blob/d416b3ab8610f179defadd58f5c20fdc65bf21e5/evil-textobj-tree-sitter.el#L40)\n\n*If you would like to test out new textobjects, I would suggest using\n[custom textobjects](#custom-textobjects). If you want to edit the\nquery files, you can edit them in\n`evil-textobj-tree-sitter--queries-dir` or by forking the repo, and\nusing the forked version with your edits.*\n\n\u003e For cases where upstream does not consider the queries (only in case\n\u003e of treesit queries, ie the ones from helix), you can add them to\n\u003e `additional-queries` directory. They will get appended with the\n\u003e treesit queries during the build step(`./scripts/get-helix-queries`).\n\n# License\n\nThe primary codebase is licensed under `Apache-2.0`. The queries have\nbe taken from\n[nvim-treesitter/nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects)\nwhich is also licensed under the same license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeain%2Fevil-textobj-tree-sitter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeain%2Fevil-textobj-tree-sitter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeain%2Fevil-textobj-tree-sitter/lists"}