Repository: meain/evil-textobj-tree-sitter Branch: master Commit: 7f58008a82c7 Files: 257 Total size: 254.1 KB Directory structure: gitextract_1hjhbj7p/ ├── .github/ │ └── workflows/ │ ├── test.yaml │ └── update-queries.yaml ├── .gitignore ├── AGENTS.md ├── Cask ├── Eask ├── LICENSE ├── Makefile ├── README.md ├── additional-queries/ │ ├── README.md │ ├── c/ │ │ └── textobjects.scm │ ├── go/ │ │ └── textobjects.scm │ ├── python/ │ │ └── textobjects.scm │ └── rust/ │ └── textobjects.scm ├── converter/ │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── main_test.go ├── docs/ │ └── updating-neovim-queries.md ├── evil-textobj-tree-sitter-core.el ├── evil-textobj-tree-sitter-query-test.el ├── evil-textobj-tree-sitter-test.el ├── evil-textobj-tree-sitter-thing-at-point.el ├── evil-textobj-tree-sitter.el ├── fixtures/ │ ├── bash/ │ │ └── textobjects.scm │ ├── javascript/ │ │ └── textobjects.scm │ ├── tsx/ │ │ └── textobjects.scm │ ├── typescript/ │ │ └── textobjects.scm │ └── zig/ │ └── textobjects.scm ├── flake.nix ├── queries/ │ ├── apex/ │ │ └── textobjects.scm │ ├── astro/ │ │ └── textobjects.scm │ ├── bash/ │ │ └── textobjects.scm │ ├── bibtex/ │ │ └── textobjects.scm │ ├── c/ │ │ └── textobjects.scm │ ├── c_sharp/ │ │ └── textobjects.scm │ ├── cmake/ │ │ └── textobjects.scm │ ├── cpp/ │ │ └── textobjects.scm │ ├── css/ │ │ └── textobjects.scm │ ├── cuda/ │ │ └── textobjects.scm │ ├── dart/ │ │ └── textobjects.scm │ ├── dockerfile/ │ │ └── textobjects.scm │ ├── ecma/ │ │ └── textobjects.scm │ ├── elixir/ │ │ └── textobjects.scm │ ├── elm/ │ │ └── textobjects.scm │ ├── enforce/ │ │ └── textobjects.scm │ ├── fennel/ │ │ └── textobjects.scm │ ├── fish/ │ │ └── textobjects.scm │ ├── foam/ │ │ └── textobjects.scm │ ├── gdscript/ │ │ └── textobjects.scm │ ├── git_config/ │ │ └── textobjects.scm │ ├── gleam/ │ │ └── textobjects.scm │ ├── glimmer/ │ │ └── textobjects.scm │ ├── glsl/ │ │ └── textobjects.scm │ ├── go/ │ │ └── textobjects.scm │ ├── hack/ │ │ └── textobjects.scm │ ├── haskell/ │ │ └── textobjects.scm │ ├── hcl/ │ │ └── textobjects.scm │ ├── heex/ │ │ └── textobjects.scm │ ├── hlsl/ │ │ └── textobjects.scm │ ├── html/ │ │ └── textobjects.scm │ ├── inko/ │ │ └── textobjects.scm │ ├── java/ │ │ └── textobjects.scm │ ├── javascript/ │ │ └── textobjects.scm │ ├── json/ │ │ └── textobjects.scm │ ├── jsx/ │ │ └── textobjects.scm │ ├── julia/ │ │ └── textobjects.scm │ ├── kotlin/ │ │ └── textobjects.scm │ ├── latex/ │ │ └── textobjects.scm │ ├── lua/ │ │ └── textobjects.scm │ ├── markdown/ │ │ └── textobjects.scm │ ├── matlab/ │ │ └── textobjects.scm │ ├── nasm/ │ │ └── textobjects.scm │ ├── nim/ │ │ └── textobjects.scm │ ├── nix/ │ │ └── textobjects.scm │ ├── ocaml/ │ │ └── textobjects.scm │ ├── odin/ │ │ └── textobjects.scm │ ├── perl/ │ │ └── textobjects.scm │ ├── php/ │ │ └── textobjects.scm │ ├── php_only/ │ │ └── textobjects.scm │ ├── python/ │ │ └── textobjects.scm │ ├── ql/ │ │ └── textobjects.scm │ ├── query/ │ │ └── textobjects.scm │ ├── r/ │ │ └── textobjects.scm │ ├── readline/ │ │ └── textobjects.scm │ ├── rst/ │ │ └── textobjects.scm │ ├── ruby/ │ │ └── textobjects.scm │ ├── rust/ │ │ └── textobjects.scm │ ├── scala/ │ │ └── textobjects.scm │ ├── scss/ │ │ └── textobjects.scm │ ├── slang/ │ │ └── textobjects.scm │ ├── supercollider/ │ │ └── textobjects.scm │ ├── svelte/ │ │ └── textobjects.scm │ ├── swift/ │ │ └── textobjects.scm │ ├── systemverilog/ │ │ └── textobjects.scm │ ├── tact/ │ │ └── textobjects.scm │ ├── terraform/ │ │ └── textobjects.scm │ ├── toml/ │ │ └── textobjects.scm │ ├── tsx/ │ │ └── textobjects.scm │ ├── twig/ │ │ └── textobjects.scm │ ├── typescript/ │ │ └── textobjects.scm │ ├── v/ │ │ └── textobjects.scm │ ├── verilog/ │ │ └── textobjects.scm │ ├── vim/ │ │ └── textobjects.scm │ ├── vue/ │ │ └── textobjects.scm │ ├── wgsl/ │ │ └── textobjects.scm │ ├── wgsl_bevy/ │ │ └── textobjects.scm │ ├── yaml/ │ │ └── textobjects.scm │ ├── zig/ │ │ └── textobjects.scm │ └── zsh/ │ └── textobjects.scm ├── scripts/ │ ├── append-additional-helix-queries │ ├── check-available │ ├── fix-queries │ ├── get-helix-queries │ └── get-neovim-queries └── treesit-queries/ ├── _jsx/ │ └── textobjects.scm ├── _typescript/ │ └── textobjects.scm ├── ada/ │ └── textobjects.scm ├── adl/ │ └── textobjects.scm ├── amber/ │ └── textobjects.scm ├── awk/ │ └── textobjects.scm ├── bash/ │ └── textobjects.scm ├── basic/ │ └── textobjects.scm ├── blade/ │ └── textobjects.scm ├── c/ │ └── textobjects.scm ├── c-sharp/ │ └── textobjects.scm ├── caddyfile/ │ └── textobjects.scm ├── cairo/ │ └── textobjects.scm ├── clojure/ │ └── textobjects.scm ├── cmake/ │ └── textobjects.scm ├── codeql/ │ └── textobjects.scm ├── cpp/ │ └── textobjects.scm ├── cross-config/ │ └── textobjects.scm ├── crystal/ │ └── textobjects.scm ├── cylc/ │ └── textobjects.scm ├── d/ │ └── textobjects.scm ├── dart/ │ └── textobjects.scm ├── dhall/ │ └── textobjects.scm ├── docker-bake/ │ └── textobjects.scm ├── docker-compose/ │ └── textobjects.scm ├── dockerfile/ │ └── textobjects.scm ├── doxyfile/ │ └── textobjects.scm ├── earthfile/ │ └── textobjects.scm ├── ecma/ │ └── textobjects.scm ├── eiffel/ │ └── textobjects.scm ├── elixir/ │ └── textobjects.scm ├── elm/ │ └── textobjects.scm ├── env/ │ └── textobjects.scm ├── erlang/ │ └── textobjects.scm ├── fga/ │ └── textobjects.scm ├── fish/ │ └── textobjects.scm ├── freebasic/ │ └── textobjects.scm ├── gas/ │ └── textobjects.scm ├── gdscript/ │ └── textobjects.scm ├── git-cliff-config/ │ └── textobjects.scm ├── git-commit/ │ └── textobjects.scm ├── git-config/ │ └── textobjects.scm ├── github-action/ │ └── textobjects.scm ├── gitlab-ci/ │ └── textobjects.scm ├── gjs/ │ └── textobjects.scm ├── gleam/ │ └── textobjects.scm ├── glsl/ │ └── textobjects.scm ├── go/ │ └── textobjects.scm ├── godot-resource/ │ └── textobjects.scm ├── graphql/ │ └── textobjects.scm ├── gren/ │ └── textobjects.scm ├── gts/ │ └── textobjects.scm ├── haskell/ │ └── textobjects.scm ├── hcl/ │ └── textobjects.scm ├── heex/ │ └── textobjects.scm ├── hocon/ │ └── textobjects.scm ├── html/ │ └── textobjects.scm ├── hurl/ │ └── textobjects.scm ├── inko/ │ └── textobjects.scm ├── java/ │ └── textobjects.scm ├── javascript/ │ └── textobjects.scm ├── jjconfig/ │ └── textobjects.scm ├── jq/ │ └── textobjects.scm ├── json/ │ └── textobjects.scm ├── json-ld/ │ └── textobjects.scm ├── json5/ │ └── textobjects.scm ├── jsonc/ │ └── textobjects.scm ├── jsx/ │ └── textobjects.scm ├── julia/ │ └── textobjects.scm ├── just/ │ └── textobjects.scm ├── kdl/ │ └── textobjects.scm ├── kotlin/ │ └── textobjects.scm ├── koto/ │ └── textobjects.scm ├── latex/ │ └── textobjects.scm ├── llvm/ │ └── textobjects.scm ├── llvm-mir/ │ └── textobjects.scm ├── lua/ │ └── textobjects.scm ├── luau/ │ └── textobjects.scm ├── mail/ │ └── textobjects.scm ├── matlab/ │ └── textobjects.scm ├── miseconfig/ │ └── textobjects.scm ├── mojo/ │ └── textobjects.scm ├── nasm/ │ └── textobjects.scm ├── nestedtext/ │ └── textobjects.scm ├── nim/ │ └── textobjects.scm ├── nix/ │ └── textobjects.scm ├── nu/ │ └── textobjects.scm ├── odin/ │ └── textobjects.scm ├── ohm/ │ └── textobjects.scm ├── opencl/ │ └── textobjects.scm ├── pascal/ │ └── textobjects.scm ├── penrose/ │ └── textobjects.scm ├── perl/ │ └── textobjects.scm ├── pest/ │ └── textobjects.scm ├── php/ │ └── textobjects.scm ├── picat/ │ └── textobjects.scm ├── pkgbuild/ │ └── textobjects.scm ├── po/ │ └── textobjects.scm ├── ponylang/ │ └── textobjects.scm ├── prisma/ │ └── textobjects.scm ├── properties/ │ └── textobjects.scm ├── protobuf/ │ └── textobjects.scm ├── purescript/ │ └── textobjects.scm ├── python/ │ └── textobjects.scm ├── qml/ │ └── textobjects.scm ├── rescript/ │ └── textobjects.scm ├── robots.txt/ │ └── textobjects.scm ├── rshtml/ │ └── textobjects.scm ├── ruby/ │ └── textobjects.scm ├── rust/ │ └── textobjects.scm ├── rust-format-args-macro/ │ └── textobjects.scm ├── sage/ │ └── textobjects.scm ├── scala/ │ └── textobjects.scm ├── scheme/ │ └── textobjects.scm ├── shellcheckrc/ │ └── textobjects.scm ├── slang/ │ └── textobjects.scm ├── slint/ │ └── textobjects.scm ├── solidity/ │ └── textobjects.scm ├── sourcepawn/ │ └── textobjects.scm ├── sql/ │ └── textobjects.scm ├── starlark/ │ └── textobjects.scm ├── sway/ │ └── textobjects.scm ├── swift/ │ └── textobjects.scm ├── tablegen/ │ └── textobjects.scm ├── tact/ │ └── textobjects.scm ├── textproto/ │ └── textobjects.scm ├── tilt/ │ └── textobjects.scm ├── toml/ │ └── textobjects.scm ├── tsx/ │ └── textobjects.scm ├── typescript/ │ └── textobjects.scm ├── typespec/ │ └── textobjects.scm ├── unison/ │ └── textobjects.scm ├── v/ │ └── textobjects.scm ├── vala/ │ └── textobjects.scm ├── verilog/ │ └── textobjects.scm ├── wesl/ │ └── textobjects.scm ├── wgsl/ │ └── textobjects.scm ├── woodpecker-ci/ │ └── textobjects.scm ├── wren/ │ └── textobjects.scm ├── xml/ │ └── textobjects.scm ├── yaml/ │ └── textobjects.scm └── zig/ └── textobjects.scm ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/test.yaml ================================================ name: Run tests on: workflow_dispatch: pull_request: push: jobs: check: runs-on: ubuntu-latest strategy: fail-fast: false matrix: emacs_version: - 30.1 # - snapshot # causing issues with compat steps: - uses: actions/checkout@v4 - uses: purcell/setup-emacs@master with: version: ${{ matrix.emacs_version }} - uses: emacs-eask/setup-eask@master with: version: 'snapshot' - run: make install-deps - run: make compile - run: make lint - run: make checkdoc - run: make test - run: make test-queries - run: cd converter && go test -v ================================================ FILE: .github/workflows/update-queries.yaml ================================================ name: Update tree-siter queries on: schedule: - cron: '0 13 * * 5' workflow_dispatch: jobs: update-queries: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Update repos run: | git clone --depth 1 https://github.com/nvim-treesitter/nvim-treesitter-textobjects /tmp/nts rm -r queries && cp -r /tmp/nts/queries . ./scripts/fix-queries - name: Create Pull Request uses: peter-evans/create-pull-request@v3 with: commit-message: Update tree-sitter queries to latest title: Update tree-sitter queries body: Update tree-sitter queries to latest from nvim-treesitter/nvim-treesitter-textobjects branch: auto-update-queries base: master token: ${{ secrets.REPO_SCOPED_PAT }} # need this to trigger CI ================================================ FILE: .gitignore ================================================ __debug_bin .cask/ .eask/ *.elc ================================================ FILE: AGENTS.md ================================================ ## Project Overview An Emacs package providing tree-sitter powered text objects for `evil-mode` and `thing-at-point`. Works with both `elisp-tree-sitter` and the builtin `treesit` library (Emacs 29+). ## Build & Test Commands Dependencies are managed via Cask (`Cask` file). Install with `cask install`. - **Compile:** `make compile` - **Lint:** `make lint` (package-lint on the main .el file) - **Checkdoc:** `make checkdoc` - **Run tests:** `make test` (core functionality tests using ert) - **Run query tests:** `make test-queries` (per-language query loading tests) - **Converter tests:** `cd converter && go test -v` All make targets use `cask exec emacs` under the hood. The `elpa` target runs `cask install` automatically when needed. ## Architecture ### Elisp Modules - `evil-textobj-tree-sitter.el` — Entry point; requires core and thing-at-point modules - `evil-textobj-tree-sitter-core.el` — All core logic: query loading, node filtering, range computation, textobj/goto functions. Supports dual backends (`elisp-tree-sitter` vs builtin `treesit`) detected at runtime - `evil-textobj-tree-sitter-thing-at-point.el` — Registers tree-sitter things (function, loop, conditional, etc.) with Emacs `thing-at-point` ### Query System (Two Separate Sets) - `queries/` — For `elisp-tree-sitter`, sourced from [nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects). Uses `#make-range!` directives - `treesit-queries/` — For builtin `treesit`, sourced from [Helix editor](https://github.com/helix-editor/helix). Updated via `scripts/get-helix-queries` - `additional-queries/` — Extra queries appended to treesit-queries during the build step for cases helix doesn't cover - `fixtures/` — Test query files for unit tests The correct query directory is selected at runtime based on whether the current buffer uses a `-ts-mode` (treesit) or regular mode (elisp-tree-sitter). ### Converter (Go) `converter/` contains a Go program that transforms nvim-treesitter query format (with `#make-range!` directives) into the `_start`/`_end` capture format used by `elisp-tree-sitter`. Used by `scripts/get-neovim-queries`. ### Scripts - `scripts/get-neovim-queries` — Pulls queries from nvim-treesitter-textobjects into `queries/`. See [docs/updating-neovim-queries.md](docs/updating-neovim-queries.md) for the manual fixup process required after pulling. - `scripts/get-helix-queries` — Pulls queries from Helix into `treesit-queries/`, appending `additional-queries/` - `scripts/fix-queries` — Post-processing fixups on query files ### Key Design Details - `evil-textobj-tree-sitter-major-mode-language-alist` maps Emacs major modes to tree-sitter language names (including both regular and `-ts-mode` variants) - Query files support `;; inherits:` directives for language inheritance (e.g., typescript inherits javascript) - Node selection priority: nodes containing point (innermost first), then nodes after point - `evil-textobj-tree-sitter-use-next-if-not-within` controls whether to fall through to next match when not inside one - Tests run against both `elisp-tree-sitter` and `treesit` backends (e.g., `c-mode` and `c-ts-mode`) ### Notes - This repo is maintained using jj and not git (do not try to run any jj commands). ================================================ FILE: Cask ================================================ (source gnu) (source melpa) (package-file "evil-textobj-tree-sitter.el") (development (depends-on "ert") (depends-on "package-lint") (depends-on "evil") (depends-on "tree-sitter") (depends-on "go-mode") (depends-on "tree-sitter-langs") (depends-on "treesit-auto")) ================================================ FILE: Eask ================================================ ;; -*- mode: eask; lexical-binding: t -*- (package "evil-textobj-tree-sitter" "0.5" "Provides evil textobjects using tree-sitter") (website-url "https://github.com/meain/evil-textobj-tree-sitter") (keywords "evil" "tree-sitter" "text-object" "convenience") (package-file "evil-textobj-tree-sitter.el") (source "gnu") (source "melpa") (depends-on "emacs" "25.1") (development (depends-on "ert") (depends-on "package-lint") (depends-on "evil") (depends-on "tree-sitter") (depends-on "go-mode") (depends-on "tree-sitter-langs") (depends-on "treesit-auto")) ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2021 Abin Simon Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: Makefile ================================================ compile: eask compile lint: eask lint package evil-textobj-tree-sitter.el checkdoc: eask lint checkdoc test: install-deps eask test ert evil-textobj-tree-sitter-test.el test-queries: install-deps eask test ert evil-textobj-tree-sitter-query-test.el install-deps: eask install-deps --dev .PHONY: compile lint checkdoc test test-queries install-deps ================================================ FILE: README.md ================================================ # evil-textobj-tree-sitter [![MELPA](https://melpa.org/packages/evil-textobj-tree-sitter-badge.svg)](https://melpa.org/#/evil-textobj-tree-sitter) [![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) Tree-sitter powered textobjects for Emacs. You can use them with `evil-mode` or with `thing-at-point`. ![gif](https://meain.io/blog-videos/gifs/evil-textobj-treesitter.gif) This package will let you create evil textobjects using tree-sitter grammars. You can easily create function,class,comment etc textobjects in multiple languages. It also make additional `things` available in `thing-at-point` like `function`, `class`, `loop`, `comment` etc. > It can work with either elisp-tree-sitter or the builtin treesit library. # Installation You can install `evil-textobj-tree-sitter` from melpa. Here is how you would do it using `use-package` and `package.el`: ```emacs-lisp (use-package evil-textobj-tree-sitter :ensure t) ``` Or you can use `straight.el`: ```emacs-lisp (use-package evil-textobj-tree-sitter :straight t) ``` Or using `straight.el` and `el-get` to pull from source: ```emacs-lisp (use-package evil-textobj-tree-sitter :straight (evil-textobj-tree-sitter :type git :host github :repo "meain/evil-textobj-tree-sitter" :files (:defaults "queries" "treesit-queries"))) ``` > You will also have to setup [`tree-sitter`](https://github.com/emacs-tree-sitter/elisp-tree-sitter). # Usage ## `thing-at-point` additions The package adds more "things" to `thing-at-point`. You can find all the things that it adds in the [source](https://github.com/meain/evil-textobj-tree-sitter/blob/master/evil-textobj-tree-sitter-thing-at-point.el). You can use these like any other `thing-at-point` entries. For example in case of functions, we make the following available: - `(thing-at-point 'function)` - `(function-at-point)` ## Mapping textobjects By default, the library does not provide any keybindings, but it should be relatively easy to add them. ```emacs-lisp ;; 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")) ;; You can also bind multiple items and we will match the first one we can find (define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj ("conditional.outer" "loop.outer"))) ``` ## Custom textobjects 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_ ```emacs-lisp ;; 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)) ;; default modes (using tree-sitter) (python-ts-mode . ((import_statement) @import)) ;; treesit modes (rust-mode . ((use_declaration) @import))))) ``` ## Goto We have also added support for for a fancier version of `goto-char`. You can use this to go to the next function, previous class or do any motions like that. You can use the `evil-textobj-tree-sitter-goto-textobj` function to invoke goto. You can either use this in other function or just bound to a key. The first argument is the textobj that you want to use, the second one specifies if you want to search forward or backward and the last one is for specifying weather to go to the start or end of the textobj. Below are some sample binding that you can do. You can use any textobj that is available here. ```emacs-lisp ;; Goto start of next function (define-key evil-normal-state-map (kbd "]f") (lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer"))) ;; Goto start of previous function (define-key evil-normal-state-map (kbd "[f") (lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer" t))) ;; Goto end of next function (define-key evil-normal-state-map (kbd "]F") (lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer" nil t))) ;; Goto end of previous function (define-key evil-normal-state-map (kbd "[F") (lambda () (interactive) (evil-textobj-tree-sitter-goto-textobj "function.outer" t t))) ``` # Development A Nix flake is provided for development. Enter the dev shell with: ```sh nix develop ``` This gives you `emacs`, `eask`, `go`, and `gcc`. Then run: ```sh make install-deps # install Emacs package dependencies make test # run core tests make test-queries # run per-language query loading tests make compile # byte-compile make lint # package-lint make checkdoc # checkdoc cd converter && go test -v # converter tests ``` # Finding and contributing to textobjects `evil-textobj-tree-sitter` work with both builtin `treesit` and `elisp-tree-sitter`. The queries in use are a bit different in both cases with the `elisp-tree-sitter` version currently being more feature complete. In both cases we pull the queries from external sources. For `elisp-tree-sitter`, we source them from [nvim-treesitter/nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects#built-in-textobjects) and is places into [queries](https://github.com/meain/evil-textobj-tree-sitter/tree/master/queries) directory. And for `treesit` queries, it is sourced from [helix](https://github.com/helix-editor/helix/tree/master/runtime/queries) and placed in [treesit-queries](https://github.com/meain/evil-textobj-tree-sitter/tree/master/treesit-queries). You can check these files to see what all is available. If you are interesting in contributing additional textobjects, you can do so by submitting to the respective projects. If there is enough interest, I don't mind starting to manage queries ourselves. 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. 1. 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`. 2. 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) *If you would like to test out new textobjects, I would suggest using [custom textobjects](#custom-textobjects). If you want to edit the query files, you can edit them in `evil-textobj-tree-sitter--queries-dir` or by forking the repo, and using the forked version with your edits.* > For cases where upstream does not consider the queries (only in case > of treesit queries, ie the ones from helix), you can add them to > `additional-queries` directory. They will get appended with the > treesit queries during the build step(`./scripts/get-helix-queries`). # License The primary codebase is licensed under `Apache-2.0`. The queries have be taken from [nvim-treesitter/nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects) which is also licensed under the same license. ================================================ FILE: additional-queries/README.md ================================================ These folder contains queries that will not be accepted to upstream helix (not neovim as we are no longer maintaining it for now), for example ones like loop and conditional. Example: https://github.com/meain/evil-textobj-tree-sitter/pull/108 ================================================ FILE: additional-queries/c/textobjects.scm ================================================ (for_statement body: (_) @loop.inner) @loop.outer (while_statement body: (_) @loop.inner) @loop.outer (do_statement body: (_) @loop.inner) @loop.outer (if_statement consequence: (_) @conditional.inner) @conditional.outer ================================================ FILE: additional-queries/go/textobjects.scm ================================================ (if_statement consequence: (block) @conditional.inner) @conditional.outer (if_statement alternative: (block) @conditional.inner)? @conditional.outer (expression_switch_statement (expression_case) @conditional.inner) @conditional.outer (type_switch_statement (type_case) @conditional.inner) @conditional.outer (select_statement (communication_case) @conditional.inner) @conditional.outer (for_statement body: (block) @loop.inner) @loop.outer ================================================ FILE: additional-queries/python/textobjects.scm ================================================ (for_statement body: (_) @loop.inner) @loop.outer (while_statement body: (_) @loop.inner) @loop.outer (if_statement consequence: (_) @conditional.inner) @conditional.outer ================================================ FILE: additional-queries/rust/textobjects.scm ================================================ (loop_expression body: (_) @loop.inner) @loop.outer (while_expression body: (_) @loop.inner) @loop.outer (for_expression body: (_) @loop.inner) @loop.outer (if_expression consequence: (_) @conditional.inner) @conditional.outer ================================================ FILE: converter/go.mod ================================================ module github.com/meain/evil-texobj-treesitter-converter go 1.16 require ( github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 github.com/sergi/go-diff v1.2.0 // indirect github.com/stretchr/testify v1.5.1 // indirect ) ================================================ FILE: converter/go.sum ================================================ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= ================================================ FILE: converter/main.go ================================================ package main import ( "fmt" "io/ioutil" "log" "os" "regexp" "strings" ) func reprint(col []string, mr []string) []string { if mr != nil { ibc := 0 icol := []string{} for _, ie := range col { switch ie { case "(": ibc += 1 icol = append(icol, ie) case ")": icol = append(icol, ie) ibc -= 1 case mr[1]: if ie != "@_start" && ie != "@_end" { icol = append(icol, ie) } icol = append(icol, " ", "@"+mr[0]+"._start") case mr[2]: if ie != "@_start" && ie != "@_end" { icol = append(icol, ie) } icol = append(icol, " ", "@"+mr[0]+"._end") default: icol = append(icol, ie) } } return icol } else { return col } } func tokenize(input string) []string { // I thought of writing a full tokenizer, but lets use a hacky one reg := regexp.MustCompile("[^( )]+|[( )]") lines := strings.Split(input, "\n") split := []string{} for _, l := range lines { split = append(split, reg.FindAllString(l, -1)...) split = append(split, "\n") } msplit := []string{} ins := false s := []string{} for _, e := range split { switch e { case "\"": if ins { msplit = append(msplit, "\""+strings.Join(s, "")+"\"") s = []string{} } ins = !ins default: if ins { s = append(s, e) } else { msplit = append(msplit, e) } } } return msplit } func reformat(input string) string { split := tokenize(input) bc := 0 i := 0 var mr []string var col []string var out []string for { e := split[i] switch e { case "(": bc += 1 col = append(col, e) case ")": bc -= 1 col = append(col, e) if bc == 0 { out = append(out, reprint(col, mr)...) mr = nil col = []string{} } case "#make-range!": col = col[:len(col)-1] bc -= 1 mr = []string{split[i+2][1 : len(split[i+2])-1], split[i+4], split[i+6]} i += 7 default: if bc == 0 { out = append(out, e) } else { col = append(col, e) } } i++ if i >= len(split) { break } } return strings.Join(out, "") } func main() { // TODO: see what is with function.outer.start in the source content, err := ioutil.ReadFile(os.Args[1]) // the file is inside the local directory if err != nil { log.Fatalf("unable to read file %s", os.Args[1]) } fmt.Print(reformat(string(content))) } ================================================ FILE: converter/main_test.go ================================================ package main import ( "strings" "testing" "github.com/andreyvit/diff" ) func TestReformatExact(t *testing.T) { input := `(function_definition body: (block)? @function.inner) @function.outer` expected := `(function_definition body: (block)? @function.inner) @function.outer` actual := reformat(input) if a, e := strings.TrimSpace(actual), strings.TrimSpace(expected); a != e { t.Errorf("Result not as expected:\n%v", diff.LineDiff(e, a)) } } func TestReformatSimple(t *testing.T) { input := `((tuple "," @_start . (_) @parameter.inner ) (#make-range! "parameter.outer" @_start @parameter.inner) )` expected := `((tuple "," @parameter.outer._start . (_) @parameter.inner @parameter.outer._end ) )` actual := reformat(input) // fmt.Println(strings.ReplaceAll(actual, " ", ".")) // fmt.Println(strings.ReplaceAll(expected, " ", ".")) if a, e := strings.TrimSpace(actual), strings.TrimSpace(expected); a != e { t.Errorf("Result not as expected:\n%v", diff.LineDiff(e, a)) } } func TestReformatQuotedBracket(t *testing.T) { input := `((tuple "(" . (_) @parameter.inner . ","? @_end ) (#make-range! "parameter.outer" @parameter.inner @_end) )` expected := `((tuple "(" . (_) @parameter.inner @parameter.outer._start . ","? @parameter.outer._end ) )` actual := reformat(input) if a, e := strings.TrimSpace(actual), strings.TrimSpace(expected); a != e { t.Errorf("Result not as expected:\n%v", diff.LineDiff(e, a)) } } func TestReformatRoot(t *testing.T) { input := `(parameter_list "," @_start . (parameter_declaration) @parameter.inner (#make-range! "parameter.outer" @_start @parameter.inner))` expected := `(parameter_list "," @parameter.outer._start . (parameter_declaration) @parameter.inner @parameter.outer._end )` actual := reformat(input) if a, e := strings.TrimSpace(actual), strings.TrimSpace(expected); a != e { t.Errorf("Result not as expected:\n%v", diff.LineDiff(e, a)) } } ================================================ FILE: docs/updating-neovim-queries.md ================================================ # Doc for updating neovim queries We need to manually edit the neovim queries after pulling it down as we currently do not support all query formats that are available within Neovim in Emacs. 1. Run the `./scripts/get-neovim-queries` command to pull down the latest update of neovim queries. 2. Fix things we don't support (see below). Use previous version of same query if they are available from the diff, but skip them otherwise. 3. Grep for unsupported predicates and make sure none remain: `grep -rn '#offset!\|#any-of?\|#not-any-of?\|#not-lua-match?\|#lua-match?' queries/` 4. Verify all parentheses are balanced (see "Ensuring balanced brackets" below). 5. Run tests: `make test && make test-queries` ## Things we do not support These are Neovim-specific predicates/directives that `elisp-tree-sitter` does not handle. Queries using these need to be manually removed or rewritten using the previous version of the same query from the diff. - `#offset!` — Neovim directive to adjust capture boundaries (e.g., trimming comment markers). Not a standard tree-sitter predicate. - `#not-lua-match?` — Neovim-specific Lua pattern negation. Note: `#lua-match?` is auto-converted to `#match?` by `fix-queries`, and `#not-lua-match?` becomes `#not-match?` via the same sed rule. However, verify the conversion happened; if not, manually replace `#not-lua-match?` with `#not-match?`. - `#any-of?` — Set membership check. May be silently ignored by older versions of the tree-sitter C library bundled in `elisp-tree-sitter`, leading to false-positive matches. - `#not-any-of?` — Negated set membership. Same concern as `#any-of?`. ### How to fix each unsupported predicate **`#offset!`**: Do NOT blindly delete the `(#offset! ...)` line — it is often the last expression inside a surrounding `(...)` form, and removing it without also fixing the closing parenthesis will leave unbalanced brackets. Instead, remove the entire `(#offset! ...)` expression and make sure the enclosing pattern still has balanced parentheses. For example: ```scheme ;; Before (with #offset!): (if_statement condition: (_) @conditional.inner (#offset! @conditional.inner 0 1 0 -1)) ;; After (remove #offset! line, keep closing paren): (if_statement condition: (_) @conditional.inner) ``` **`#any-of?`**: Convert to `#match?` with regex alternation, or expand into separate patterns each using `#eq?`. ```scheme ;; Before: (#any-of? @name "foo" "bar" "baz") ;; Option 1 — #match? (preferred when there are many values): (#match? @name "^(foo|bar|baz)$") ;; Option 2 — duplicate pattern with #eq? (preferred for few values): ;; Copy the entire enclosing pattern once per value, each with: (#eq? @name "foo") ``` **`#not-any-of?`**: Convert to multiple `#not-eq?` predicates (AND semantics — all must hold). ```scheme ;; Before: (#not-any-of? @name "do" "while" "when") ;; After: (#not-eq? @name "do") (#not-eq? @name "while") (#not-eq? @name "when") ``` **`#not-lua-match?`**: Replace with `#not-match?` (adjusting the pattern from Lua pattern syntax to regex if needed). ## Ensuring balanced brackets After making edits, verify that every query file has balanced parentheses and square brackets. A quick check: ```sh # Note: must strip string literals first since queries contain "(" and # similar inside strings which would throw off a naive character count. for f in queries/*/textobjects.scm; do stripped=$(sed 's/"[^"]*"//g' "$f") opens=$(echo "$stripped" | tr -cd '(' | wc -c) closes=$(echo "$stripped" | tr -cd ')' | wc -c) if [ "$opens" -ne "$closes" ]; then echo "UNBALANCED parens in $f: (=$opens )=$closes" fi opens=$(echo "$stripped" | tr -cd '[' | wc -c) closes=$(echo "$stripped" | tr -cd ']' | wc -c) if [ "$opens" -ne "$closes" ]; then echo "UNBALANCED brackets in $f: [=$opens ]=$closes" fi done ``` If any file is reported as unbalanced, open it and fix the issue before running tests. ## Things that are supported - `#eq?` — Standard tree-sitter equality predicate, works as-is. - `#not-eq?` — Standard negated equality, works as-is. - `#match?` — Standard regex matching, works as-is. - `#not-match?` — Standard negated regex matching, works as-is. - `#make-range!` — Neovim-specific, but handled by the Go converter in `converter/` which transforms it to `_start`/`_end` captures. ================================================ FILE: evil-textobj-tree-sitter-core.el ================================================ ;;; evil-textobj-tree-sitter-core.el --- Provides evil textobjects using tree-sitter -*- lexical-binding: t; -*- ;; URL: https://github.com/meain/evil-textobj-tree-sitter ;; Keywords: evil, tree-sitter, text-object, convenience ;; SPDX-License-Identifier: Apache-2.0 ;; Package-Requires: ((emacs "25.1")) ;; Version: 0.5 ;;; Commentary: ;; This package is a port of nvim-treesitter/nvim-treesitter-textobjects. ;; This package will let you create evil textobjects using the power ;; of tree-sitter grammars. You can easily create ;; function,class,comment etc textobjects in multiple languages. ;; ;; You can do a sample map like below to create a function textobj. ;; (define-key evil-outer-text-objects-map "f" ;; (evil-textobj-tree-sitter-get-textobj "function.outer")) ;; `evil-textobj-tree-sitter-get-textobj' will return you a function ;; that you can use in a define-key map. You can pass in any of the ;; supported queries as an arg of that function. You can also pass in ;; multiple queries as a list and we will match on all of them, ranked ;; on which ones comes up first in the file. ;; You can find more info in the README.md file at ;; https://github.com/meain/evil-textobj-tree-sitter ;;; Code: (require 'cl-lib) (require 'map) (defvar evil-textobj-tree-sitter--can-use-elisp-treesitter (require 'tree-sitter nil t) "If non-nil, we are can make use of elisp-tree-sitter instead of builtin.") (defvar evil-textobj-tree-sitter--can-use-builtin-treesit (require 'treesit nil t) "If non-nil, we are can make use of builtin treesit instead of elisp-tree-sitter.") (defvar evil-textobj-tree-sitter--evil-available (require 'evil nil t) "Specifies if we have `evil-mode' available to use in package.") (defgroup evil-textobj-tree-sitter nil "Text objects based on tree-sitter for Evil." :group 'tools) ;; Ignore warnings from optionally requiring tree-sitter and treesit (defvar tree-sitter-language) (defvar tree-sitter-tree) (declare-function tsc-node-byte-range "tsc" t t) (declare-function tsc--buffer-substring-no-properties "tsc") (declare-function tsc-query-matches "tsc") (declare-function tsc-root-node "tsc" t t) (declare-function tsc-make-query "tsc") (declare-function treesit-node-end "treesit.c") (declare-function treesit-node-start "treesit.c") (declare-function treesit-query-capture "treesit.c") (declare-function treesit-buffer-root-node "treesit") (defconst evil-textobj-tree-sitter--dir (file-name-directory (locate-library "evil-textobj-tree-sitter.el")) "The directory where the library `tree-sitter-langs' is located.") (defun evil-textobj-tree-sitter--use-builtin-treesitter () "Return non-nil if we should use builtin treesitter." (and evil-textobj-tree-sitter--can-use-builtin-treesit (let ((major-mode-name (symbol-name major-mode))) (or (string-suffix-p "-ts-mode" major-mode-name) (and (bound-and-true-p rust-mode-treesitter-derive) (derived-mode-p 'rust-mode)))))) (defun evil-textobj-tree-sitter--get-queries-dir () "Get the queries directory. Currently treesit queries are different from queries for elisp-tree-sitter." (if (evil-textobj-tree-sitter--use-builtin-treesitter) (file-name-as-directory (concat evil-textobj-tree-sitter--dir "treesit-queries")) (file-name-as-directory (concat evil-textobj-tree-sitter--dir "queries")))) (defcustom evil-textobj-tree-sitter--get-queries-dir-func #'evil-textobj-tree-sitter--get-queries-dir "Function to get location for the queries." :group 'evil-textobj-tree-sitter :type 'function) (defcustom evil-textobj-tree-sitter-major-mode-language-alist nil "Alist that maps major modes to tree-sitter language names." :group 'evil-textobj-tree-sitter :type '(alist :key-type symbol :value-type string)) (pcase-dolist (`(,major-mode . ,lang-symbol) (reverse '((c++-mode . "cpp") (c++-ts-mode . "cpp") (c-mode . "c") (c-ts-mode . "c") (csharp-mode . "c_sharp") (csharp-ts-mode . "c-sharp") (elixir-mode . "elixir") (elixir-ts-mode . "elixir") (elm-mode . "elm") (elm-ts-mode . "elm") (ess-r-mode . "r") (go-mode . "go") (go-ts-mode . "go") (haskell-mode . "haskell") (haskell-ts-mode . "haskell") (html-mode . "html") (html-ts-mode . "html") (java-mode . "java") (java-ts-mode . "java") (javascript-mode . "javascript") (javascript-ts-mode . "javascript") (js-mode . "javascript") (js-ts-mode . "javascript") (js2-mode . "javascript") (js3-mode . "javascript") (julia-mode . "julia") (julia-ts-mode . "julia") (matlab-mode . "matlab") (tuareg-mode . "ocaml") (php-mode . "php") (php-ts-mode . "php") (prisma-mode . "prisma") (prisma-ts-mode . "prisma") (python-mode . "python") (python-ts-mode . "python") (rjsx-mode . "javascript") (ruby-mode . "ruby") (ruby-ts-mode . "ruby") (rust-mode . "rust") (rust-ts-mode . "rust") (rustic-mode . "rust") (sh-mode . "bash") (bash-ts-mode . "sh") (shell-script-mode . "bash") (tsx-mode . "tsx") (tsx-ts-mode . "tsx") (typescript-mode . "typescript") (typescript-ts-mode . "typescript") (verilog-mode . "verilog") (zig-mode . "zig")))) (setf (map-elt evil-textobj-tree-sitter-major-mode-language-alist major-mode) lang-symbol)) (defcustom evil-textobj-tree-sitter-use-next-if-not-within t "When non-nil, use the next match if we are not within one." :group 'evil-textobj-tree-sitter :type 'boolean) (defun evil-textobj-tree-sitter--nodes-filter-before (nodes) "NODES which contain the current after them." (sort (cl-remove-if-not (lambda (x) (< (car (last x)) (point))) nodes) (lambda (x y) (< (car (last x)) (car (last y)))))) (defun evil-textobj-tree-sitter--nodes-filter-within (nodes) "NODES which contain the current point inside them ordered inside out." (let ((byte-pos (point))) (sort (cl-remove-if-not (lambda (x) (and (<= (nth 1 x) byte-pos) (< byte-pos (car (last x))))) nodes) (lambda (x y) (< (+ (abs (- byte-pos (nth 1 x))) (abs (- byte-pos (car (last x))))) (+ (abs (- byte-pos (nth 1 y))) (abs (- byte-pos (car (last y)))))))))) (defun evil-textobj-tree-sitter--nodes-filter-after (nodes) "NODES which contain the current point before them ordered top to bottom." (sort (cl-remove-if-not (lambda (x) (> (nth 1 x) (point))) nodes) (lambda (x y) (< (nth 1 x) (nth 1 y))))) (defun evil-textobj-tree-sitter--get-inherits-line (filename) "Get the inherits line from `FILENAME'. It might not be on the fist line and so we cannot just get the first line." (with-temp-buffer (if (file-exists-p filename) (progn (insert-file-contents filename) (goto-char (point-min)) (search-forward "; inherits: " nil t) (let ((line (thing-at-point 'line t))) (if (string-match "^; inherits: \\([a-z_,()]+\\)$" line) (match-string 1 line))))))) (defun evil-textobj-tree-sitter--get-query-from-dir (language queries-dir top-level) "Get tree sitter query for `LANGUAGE' from `QUERIES-DIR'. `TOP-LEVEL' is used to mention if we should load optional inherits. https://github.com/nvim-treesitter/nvim-treesitter/pull/564" (let ((filename (concat queries-dir language "/textobjects.scm"))) (with-temp-buffer (if (file-exists-p filename) (progn (insert-file-contents filename) (goto-char (point-min)) (let ((inherits-line (evil-textobj-tree-sitter--get-inherits-line filename))) (if inherits-line (insert (string-join (mapcar (lambda (x) (if (string-prefix-p "(" x) (if top-level (evil-textobj-tree-sitter--get-query-from-dir (substring x 1 -1) queries-dir nil)) (evil-textobj-tree-sitter--get-query-from-dir x queries-dir nil))) (split-string inherits-line ",")) "\n")))) (buffer-string)))))) (defun evil-textobj-tree-sitter--get-query (language) "Get tree sitter query for `LANGUAGE'." (evil-textobj-tree-sitter--get-query-from-dir language (funcall evil-textobj-tree-sitter--get-queries-dir-func) t)) (defun evil-textobj-tree-sitter--treesit-get-nodes (query) "Get nodes for `QUERY' using builtin `treesit'." (if (not (treesit-parser-list)) (progn (message "evil-textobj-tree-sitter: treesit parser is not available in %s" major-mode) nil) (let* ((lang-name (alist-get major-mode evil-textobj-tree-sitter-major-mode-language-alist)) (user-query (alist-get major-mode query)) (f-query (if (eq user-query nil) (evil-textobj-tree-sitter--get-query lang-name) user-query)) (root-node (treesit-buffer-root-node)) (captures (treesit-query-capture root-node f-query))) (seq-map (lambda (x) (list (car x) (treesit-node-start (cdr x)) (treesit-node-end (cdr x)))) captures)))) (defun evil-textobj-tree-sitter--elisp-tree-sitter-get-nodes (query) "Get nodes for `QUERY' using `elisp-tree-sitter'." (if (not (bound-and-true-p tree-sitter-tree)) (progn (message "evil-textobj-tree-sitter: tree-sitter is not available in %s" major-mode) nil) (let* ((lang-name (alist-get major-mode evil-textobj-tree-sitter-major-mode-language-alist)) (user-query (alist-get major-mode query)) (f-query (if (eq user-query nil) (evil-textobj-tree-sitter--get-query lang-name) user-query)) (root-node (tsc-root-node tree-sitter-tree)) (query (tsc-make-query tree-sitter-language f-query)) (matches (tsc-query-matches query root-node #'tsc--buffer-substring-no-properties)) (all-captures '())) (progn (seq-map (lambda (x) (let* ((match-captures (cdr x)) (capture-start nil) (capture-end nil)) (seq-map (lambda (y) (let ((csplits (split-string (symbol-name (car y)) "\\."))) (pcase (car (last csplits)) ("_end" (setq capture-end y)) ("_start" (setq capture-start y)) (_ (push (list (car y) (car (tsc-node-byte-range (cdr y))) (cdr (tsc-node-byte-range (cdr y)))) all-captures))))) match-captures) (if (and capture-start capture-end) (push (list (intern (string-join (butlast (split-string (symbol-name (car capture-start)) "\\.") 1) ".")) (car (tsc-node-byte-range (cdr capture-start))) (cdr (tsc-node-byte-range (cdr capture-end)))) all-captures)))) matches) (mapcar (lambda (c) (list (car c) (byte-to-position (cadr c)) (byte-to-position (caddr c)))) all-captures))))) (defun evil-textobj-tree-sitter--get-nodes (group query) "Get a list of viable nodes based on `GROUP' value. They will be order with captures with point inside them first then the ones that follow. If a `QUERY' alist is provided and it contains a current `major-mode', we make use of that instead of the builtin query set." (cl-remove-duplicates (cl-remove-if-not (lambda (x) (member (car x) group)) (if (evil-textobj-tree-sitter--use-builtin-treesitter) (evil-textobj-tree-sitter--treesit-get-nodes query) (evil-textobj-tree-sitter--elisp-tree-sitter-get-nodes query))) :test (lambda (x y) (and (eq (car x) (car y)) ;; names are equal (= (nth 1 x) (nth 1 y)) (= (car (last x)) (car (last y))))))) (defun evil-textobj-tree-sitter--get-within-and-after (group count query) "Given a `GROUP' `QUERY' find `COUNT' number of nodes within in and after point." (let* ((nodes (evil-textobj-tree-sitter--get-nodes group query)) (nodes-within (evil-textobj-tree-sitter--nodes-filter-within nodes)) (nodes-after (evil-textobj-tree-sitter--nodes-filter-after nodes)) (filtered-nodes (if (and (equal 1 count) (not evil-textobj-tree-sitter-use-next-if-not-within)) nodes-within (append nodes-within nodes-after)))) (if (> (length filtered-nodes) 0) (cl-subseq filtered-nodes 0 count)))) (defun evil-textobj-tree-sitter--get-within (group count query) "Given a `GROUP' `QUERY' find `COUNT' number of nodes within point." (let* ((nodes (evil-textobj-tree-sitter--get-nodes group query)) (nodes-within (evil-textobj-tree-sitter--nodes-filter-within nodes))) (if (> (length nodes-within) 0) (cl-subseq nodes-within 0 count)))) (defun evil-textobj-tree-sitter--range (count ts-group &optional query) "Get the range of the closeset item of type `TS-GROUP'. `COUNT' is supported even thought it does not actually make sense in most cases as if we do 3-in-func the selections will not be continues, but we can only provide the start and end as of now which is what we are doing. If a `QUERY' alist is provided, we make use of that instead of the builtin query set." (let ((nodes (evil-textobj-tree-sitter--get-within-and-after ts-group count query))) (if (not (eq nodes nil)) (let ((range-min (apply #'min (seq-map (lambda (x) (nth 1 x)) nodes))) (range-max (apply #'max (seq-map (lambda (x) (car (last x))) nodes)))) ;; Have to compute min and max like this as we might have nested functions (cons range-min range-max))))) (defun evil-textobj-tree-sitter--message-not-found (groups) "Log a message that `GROUPS' are not found." (let ((not-found (mapconcat (lambda (g) (concat "'" g "'")) groups " or "))) (error (concat "No " not-found " text object found")))) ;;;###autoload (defmacro evil-textobj-tree-sitter-get-textobj (group &optional query) "Macro to create a textobj function from `GROUP'. You can pass in multiple groups as a list and in that case as long as any one of them is available, it will be picked. You can optionally pass in a alist mapping `major-mode' to their respective tree-sitter query in `QUERY' with named captures to use that instead of the default query list. If `QUERY' does not contain current `major-mode', then the default queries are used. Check the README file in the repo to see how to use it. Check this url for builtin objects https://github.com/nvim-treesitter/nvim-treesitter-textobjects#built-in-textobjects" (declare (debug t) (indent defun)) (if evil-textobj-tree-sitter--evil-available (let* ((groups (if (eq (type-of group) 'string) (list group) group)) (funsymbol (intern (concat "evil-textobj-tree-sitter-function--" (mapconcat 'identity groups "-")))) (interned-groups (mapcar #'intern groups))) `(evil-define-text-object ,funsymbol ;; rest argument is named because of compiler warning `argument _ not left unused` (count &rest unused) (let ((range (evil-textobj-tree-sitter--range count ',interned-groups ,query))) (if (not (eq range nil)) (evil-range (car range) (cdr range)) (evil-textobj-tree-sitter--message-not-found ',groups))))) (error "Cannot use `evil-textobj-tree-sitter-goto-textobj' without `evil-mode'"))) (defun evil-textobj-tree-sitter--get-goto-location (groups previous end query) "Get the start/end of the textobj of type `GROUPS'. By default it goes to the start of the textobj, but pass in `END' if you want to go to the end of the textobj instead. You can pass in `PREVIOUS' if you want to search backwards. `QUERY' for custom queries." (let* ((nodes (evil-textobj-tree-sitter--get-nodes groups query)) (usable-nodes (if previous (if end (cl-remove-if-not (lambda (x) (< (car (last x)) (point))) nodes) (cl-remove-if-not (lambda (x) (< (nth 1 x) (point))) nodes)) (if end (cl-remove-if-not (lambda (x) ;; -1 is needed as evil cannot select till end (> (- (car (last x)) 1) (point))) nodes) (cl-remove-if-not (lambda (x) (> (nth 1 x) (point))) nodes)))) (node (car (sort usable-nodes (lambda (x y) (if previous (if end (> (car(last x)) (car (last y))) (> (nth 1 x) (nth 1 y))) (if end (< (car(last x)) (car (last y))) (< (nth 1 x) (nth 1 y))))))))) (if node (let ((actual-position (if end (car (last node)) (nth 1 node)))) (if end ;; tree sitter count + 1 kinda (probably have to look in other places as well) ;; This is a mess that evil creates (not really an issue in Emacs mode) (- actual-position 1) actual-position))))) ;;;###autoload (defun evil-textobj-tree-sitter-goto-textobj (group &optional previous end query) "Got to the start/end of the textobj of type `GROUP'. By default it goes to the start of the textobj, but pass in `END' if you want to go to the end of the textobj instead. You can pass in `PREVIOUS' if you want to search backwards. Optionally pass in `QUERY' if you want to define a custom query." (let* ((groups (if (eq (type-of group) 'string) (list group) group)) (interned-groups (mapcar #'intern groups)) (goto-position (evil-textobj-tree-sitter--get-goto-location interned-groups previous end query))) (if goto-position (goto-char goto-position) (evil-textobj-tree-sitter--message-not-found groups)))) (provide 'evil-textobj-tree-sitter-core) ;;; evil-textobj-tree-sitter-core.el ends here ================================================ FILE: evil-textobj-tree-sitter-query-test.el ================================================ ;;; Code: (require 'tree-sitter-langs) (require 'evil-textobj-tree-sitter) (require 'ert) (defun evil-textobj-tree-sitter--test-loading-with-comment-prefix (lang comment-prefix) "Try loading grammar for `LANG' and test with comment using `COMMENT-PREFIX'." (evil-textobj-tree-sitter--test-loading-with-comment lang (concat comment-prefix " howdy!"))) (defun evil-textobj-tree-sitter--test-loading-with-comment (lang text &optional region) "Try loading grammar for `LANG'. And test with comment provided in `TEXT' optionally passing in `REGION'." (let* ((bufname (make-temp-name "evil-textobj-tree-sitter-test--")) (filename (concat "/tmp/" bufname))) (find-file filename) (fundamental-mode) (with-current-buffer bufname (when (null tree-sitter-major-mode-language-table) (setq tree-sitter-major-mode-language-table (make-hash-table :test 'eq))) (puthash 'fundamental-mode lang tree-sitter-major-mode-language-table) (setq-local evil-textobj-tree-sitter-major-mode-language-alist `((fundamental-mode . ,(symbol-name lang)))) (insert text) (tree-sitter-mode) (goto-char 0) (should (equal (evil-textobj-tree-sitter--range 1 (list (intern "comment.outer"))) (if region region (cons 1 (+ 1 (length text))))))) (set-buffer-modified-p nil) (kill-buffer bufname))) ;; TODO: Simplify code using macros and dolist ;; bash (ert-deftest evil-textobj-tree-sitter-try-bash () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'bash "#")) ;; c (ert-deftest evil-textobj-tree-sitter-try-c () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'c "//")) ;; cpp (ert-deftest evil-textobj-tree-sitter-try-cpp () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'cpp "//")) ;; elixir (ert-deftest evil-textobj-tree-sitter-try-elixir () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'elixir "#")) ;; elm (ert-deftest evil-textobj-tree-sitter-try-elm () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'elm "--")) ;; go (ert-deftest evil-textobj-tree-sitter-try-go () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'go "//")) ;; haskell (ert-deftest evil-textobj-tree-sitter-try-haskell () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'haskell "--")) ;; hcl (ert-deftest evil-textobj-tree-sitter-try-hcl () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'hcl "#")) ;; html ")) ;; java (ert-deftest evil-textobj-tree-sitter-try-java () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'java "//")) ;; javascript (ert-deftest evil-textobj-tree-sitter-try-javascript () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'javascript "//")) ;; julia TODO: Needs grammar update ;; (ert-deftest evil-textobj-tree-sitter-try-julia () ;; (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'julia "#")) ;; php (ert-deftest evil-textobj-tree-sitter-try-php () (evil-textobj-tree-sitter--test-loading-with-comment 'php "" (cons 7 15))) ;; python (ert-deftest evil-textobj-tree-sitter-try-python () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'python "#")) ;; r (ert-deftest evil-textobj-tree-sitter-try-r () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'r "#")) ;; ruby (ert-deftest evil-textobj-tree-sitter-try-ruby () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'ruby "#")) ;; rust (ert-deftest evil-textobj-tree-sitter-try-rust () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'rust "//")) ;; typescript (ert-deftest evil-textobj-tree-sitter-try-typescript () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'typescript "//")) ;; verilog (ert-deftest evil-textobj-tree-sitter-try-verilog () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'verilog "//")) ;; zig (ert-deftest evil-textobj-tree-sitter-try-zig () (evil-textobj-tree-sitter--test-loading-with-comment-prefix 'zig "//")) ;;; evil-textobj-tree-sitter-query-test.el ends here ================================================ FILE: evil-textobj-tree-sitter-test.el ================================================ ;;; evil-textobj-tree-sitter-test.el --- Tests for evil-textobj-tree-sitter -*- lexical-binding: t -*- ;;; Commentary: ;; We can only use statically linked files here or libstdc++ screams at you. ;; C is an ideal candidate for this as it is builtin and is statically linked. ;;; Code: (require 'tree-sitter-langs) (require 'evil-textobj-tree-sitter) (require 'go-mode) (setq treesit-language-source-alist '((c . ("https://github.com/tree-sitter/tree-sitter-c")) (cpp . ("https://github.com/tree-sitter/tree-sitter-cpp")) (python . ("https://github.com/tree-sitter/tree-sitter-python")) (go . ("https://github.com/tree-sitter/tree-sitter-go")) (gomod . ("https://github.com/camdencheek/tree-sitter-go-mod.git")))) ;; Unset GIT_DIR/GIT_WORK_TREE so treesit-install-language-grammar can git ;; clone into temp directories (these may be set for jj repo compatibility) (setenv "GIT_DIR" nil) (setenv "GIT_WORK_TREE" nil) (treesit-install-language-grammar 'c) (treesit-install-language-grammar 'cpp) (treesit-install-language-grammar 'python) (treesit-install-language-grammar 'go) (treesit-install-language-grammar 'gomod) (defvar evil-textobj-tree-sitter--test-file-content '((c-simple . "// Lukasz int main() { printf(\"hello\") }") (c-multiple-funcs . "// mango int main() { printf(\"hello\") } int main2() { printf(\"hello2\") } ") (c-unicode . "// Łukasz int main() { printf(\"hello\") }") (c-multibyte . "// Комментарий int main(int temp, int temp2) { printf(\"hello\"); }") (go-multibyte-code . "// Комментарий func main(int Комментарий, int temp2) { printf(\"hello\"); }") (go-nested . "// comment func main() { fmt.Println(\"howdy bruh!\") func() { fmt.Println(\"yo!\") } }") (py-complex . "def func (): var1 def func2(): pass def nested(): var2 def inner(): var3 var4 var5 "))) (defun evil-textobj-tree-sitter--range-test (mode treesit start textobj range content) "Check ranges of tree-sitter targets. `MODE' is the `major-mode' to be used. `TREESIT' non nil will use `treesit'. `CONTENT' is the content to be used. `START' is the starting position. `TEXTOBJ' is the textobject to check. `RANGE' is the range that should be returned." (let* ((bufname (make-temp-name "evil-textobj-tree-sitter-test--")) (buffer (get-buffer-create bufname))) (with-current-buffer buffer (insert (alist-get content evil-textobj-tree-sitter--test-file-content)) (funcall mode) (if (not treesit) (tree-sitter-mode)) (message "%s" major-mode) (goto-char start) (should (equal (evil-textobj-tree-sitter--range 1 (list (intern textobj))) range))) (kill-buffer buffer))) (ert-deftest evil-textobj-tree-sitter-within-unicode-test () "Check inner range queries within unicode buffers." ;; function.inner selects brackets in treesit queries but not in tree-sitter ones (evil-textobj-tree-sitter--range-test 'c-mode nil 31 "function.inner" (cons 28 43) 'c-unicode) (evil-textobj-tree-sitter--range-test 'c-ts-mode t 31 "function.inner" (cons 22 45) 'c-unicode)) (ert-deftest evil-textobj-tree-sitter-within-unicode-test-outer () "Check outer range queries within unicode buffers." (evil-textobj-tree-sitter--range-test 'c-mode nil 31 "function.outer" (cons 11 45) 'c-unicode) (evil-textobj-tree-sitter--range-test 'c-ts-mode t 31 "function.outer" (cons 11 45) 'c-unicode)) (ert-deftest evil-textobj-tree-sitter-within-multibyte-buffers () "Check range in multibyte comment before." (evil-textobj-tree-sitter--range-test 'c-mode nil 35 "parameter.inner" (cons 35 44) 'c-multibyte) (evil-textobj-tree-sitter--range-test 'c-ts-mode t 35 "parameter.inner" (cons 35 44) 'c-multibyte)) (ert-deftest evil-textobj-tree-sitter-within-unicode-test3 () "Check range with multibyte code." (evil-textobj-tree-sitter--range-test 'go-mode nil 31 "parameter.inner" (cons 26 41) 'go-multibyte-code) (evil-textobj-tree-sitter--range-test 'go-ts-mode t 31 "parameter.inner" (cons 26 41) 'go-multibyte-code)) (ert-deftest evil-textobj-tree-sitter-within-test () "Check range when we are within the textobj with buffer having only ASCII chars." (evil-textobj-tree-sitter--range-test 'c-mode nil 31 "function.outer" (cons 11 45) 'c-simple) (evil-textobj-tree-sitter--range-test 'c-ts-mode t 31 "function.outer" (cons 11 45) 'c-simple)) (ert-deftest evil-textobj-tree-sitter-lookahed-test () "Check range when we are before the textobj with buffer having only ASCII chars." (evil-textobj-tree-sitter--range-test 'c-mode nil 1 "function.outer" (cons 11 45) 'c-simple) (evil-textobj-tree-sitter--range-test 'c-ts-mode t 1 "function.outer" (cons 11 45) 'c-simple)) (ert-deftest evil-textobj-tree-sitter-right-at-start-test () "Checking for off by one errors at start." (evil-textobj-tree-sitter--range-test 'c-mode nil 11 "function.outer" (cons 11 45) 'c-simple) (evil-textobj-tree-sitter--range-test 'c-ts-mode t 11 "function.outer" (cons 11 45) 'c-simple)) ;;; Reading query files (ert-deftest evil-textoj-tree-sitter-check-query-read-simple () "Simple query read check." (let ((evil-textobj-tree-sitter--get-queries-dir-func (lambda () "fixtures/"))) (should (string-prefix-p ";; \"Classes\"" (evil-textobj-tree-sitter--get-query "zig"))))) (ert-deftest evil-textoj-tree-sitter-check-query-read-nocomment () "Check a query file with no comment." (let ((evil-textobj-tree-sitter--get-queries-dir-func (lambda () "fixtures/"))) (should (string-prefix-p "(function_definition" (evil-textobj-tree-sitter--get-query "bash"))))) (ert-deftest evil-textoj-tree-sitter-check-query-read-nested () "Check a query with nested files to be loaded." (let ((evil-textobj-tree-sitter--get-queries-dir-func (lambda () "fixtures/"))) (should (string-prefix-p "; inherits: (jsx)" (evil-textobj-tree-sitter--get-query "typescript"))))) (ert-deftest evil-textoj-tree-sitter-check-query-read-nested-nofile () "Check a file pointing to a non existent file." (let ((evil-textobj-tree-sitter--get-queries-dir-func (lambda () "fixtures/"))) (should (string-prefix-p "; inherits: (jsx)" (evil-textobj-tree-sitter--get-query "javascript"))))) (ert-deftest evil-textoj-tree-sitter-check-query-read-nested-multi () "Check a query with multiple nesting items." (let ((evil-textobj-tree-sitter--get-queries-dir-func (lambda () "fixtures/"))) (should (string-prefix-p "; inherits: (javascript)" (evil-textobj-tree-sitter--get-query "tsx"))))) (ert-deftest evil-textoj-tree-sitter-check-query-read-non-top-level () "Check a non top level direct query." (should (string-prefix-p "; inherits: (javascript)" (evil-textobj-tree-sitter--get-query-from-dir "typescript" "fixtures/" nil)))) (defun evil-textobj-tree-sitter--goto-test (mode treesit start textobj pos prev end content) "Check for location of goto actions. `MODE' is the `major-mode' to be used. `TREESIT' non nil will use `treesit'. `CONTENT' is the content to be used. `START' is the starting position. `TEXTOBJ' is the textobject to check. `PREV' goes to previous textobj. `END' goes to end of textobj. `POS' is the position that should be returned." (let* ((bufname (make-temp-name "evil-textobj-tree-sitter-test--")) (buffer (get-buffer-create bufname))) (with-current-buffer buffer (insert (alist-get content evil-textobj-tree-sitter--test-file-content)) (funcall mode) (if (not treesit) (tree-sitter-mode)) (goto-char start) (should (equal (evil-textobj-tree-sitter--get-goto-location (list (intern textobj)) prev end nil) pos))) (kill-buffer bufname))) (ert-deftest evil-textobj-tree-sitter-goto-next-start-simple () "Go to next start in ASCII buffers." (evil-textobj-tree-sitter--goto-test 'c-mode nil 1 "function.outer" 11 nil nil 'c-simple) (evil-textobj-tree-sitter--goto-test 'c-ts-mode t 1 "function.outer" 11 nil nil 'c-simple)) (ert-deftest evil-textobj-tree-sitter-goto-next-start-multiple-textobjects () "Check to see if we are able to find first one when we have multiple textobjects." (evil-textobj-tree-sitter--goto-test 'c-mode nil 1 "parameter.outer" 25 nil nil 'c-multibyte) (evil-textobj-tree-sitter--goto-test 'c-ts-mode t 1 "parameter.outer" 25 nil nil 'c-multibyte)) (ert-deftest evil-textobj-tree-sitter-goto-next-end-simple () "Check if we can navigate to end of a textobj." (evil-textobj-tree-sitter--goto-test 'c-mode nil 1 "function.outer" 69 nil t 'c-multibyte) (evil-textobj-tree-sitter--goto-test 'c-ts-mode t 1 "function.outer" 69 nil t 'c-multibyte)) (ert-deftest evil-textobj-tree-sitter-goto-next-end-multi () "Goto end when we have multiple functions." (evil-textobj-tree-sitter--goto-test 'c-mode nil 1 "function.outer" 43 nil t 'c-multiple-funcs) (evil-textobj-tree-sitter--goto-test 'c-ts-mode t 1 "function.outer" 43 nil t 'c-multiple-funcs)) (ert-deftest evil-textobj-tree-sitter-goto-previous-end-multi () "Goto end of previous textobj." (evil-textobj-tree-sitter--goto-test 'c-mode nil 69 "function.outer" 43 t t 'c-multiple-funcs) (evil-textobj-tree-sitter--goto-test 'c-ts-mode t 69 "function.outer" 43 t t 'c-multiple-funcs)) (ert-deftest evil-textobj-tree-sitter-goto-previous-end-multi-on-end () "Testing going to end of previous one while on end of current one." (evil-textobj-tree-sitter--goto-test 'c-mode nil 82 "function.outer" 43 t t 'c-multiple-funcs) (evil-textobj-tree-sitter--goto-test 'c-ts-mode t 82 "function.outer" 43 t t 'c-multiple-funcs)) (ert-deftest evil-textobj-tree-sitter-goto-previous-start-nested () "Goto the start of the previous textobj in a nested scenario." (evil-textobj-tree-sitter--goto-test 'go-mode nil 66 "function.outer" 55 t nil 'go-nested) (evil-textobj-tree-sitter--goto-test 'go-ts-mode t 66 "function.outer" 55 t nil 'go-nested)) (ert-deftest evil-textobj-tree-sitter-goto-previous-start-nested-3 () "Go to previous nested complex test." (evil-textobj-tree-sitter--goto-test 'python-mode nil 71 "function.outer" 49 t nil 'py-complex) (evil-textobj-tree-sitter--goto-test 'python-ts-mode t 71 "function.outer" 49 t nil 'py-complex)) ;;; `thing-at-point' tests (defun evil-textobj-tree-sitter--thing-at-point-test (mode treesit start thing content selection range) "Check ranges of tree-sitter targets. `MODE' is the `major-mode' to be used. `TREESIT' non nil will use `treesit'. `CONTENT' is the content to be used. `START' is the starting position. `THING' is the thing to select. `SELECTION' is the selection that `thing-at-point' will return." (let* ((bufname (make-temp-name "evil-textobj-tree-sitter-test--")) (buffer (get-buffer-create bufname))) (with-current-buffer buffer (insert (alist-get content evil-textobj-tree-sitter--test-file-content)) (funcall mode) (if (not treesit) (tree-sitter-mode)) (goto-char start) (should (equal (thing-at-point thing t) selection)) (should (equal (bounds-of-thing-at-point thing) range))) (kill-buffer bufname))) (ert-deftest evil-textobj-tree-sitter-thing-at-point () "Check if `thing-at-point' returns correct result." (let ((selection "int main() { printf(\"hello\") }")) (evil-textobj-tree-sitter--thing-at-point-test 'c-mode nil 31 'function 'c-unicode selection (cons 11 45)) (evil-textobj-tree-sitter--thing-at-point-test 'c-ts-mode t 31 'function 'c-unicode selection (cons 11 45)))) (ert-deftest evil-textobj-tree-sitter-no-error-without-parser () "Check that operations gracefully return nil when tree-sitter is unavailable." (let* ((bufname (make-temp-name "evil-textobj-tree-sitter-test--")) (buffer (get-buffer-create bufname))) (with-current-buffer buffer (insert "some text without a tree-sitter parser") (fundamental-mode) ;; Should not error, just return nil (goto-char 1) (should (equal (evil-textobj-tree-sitter--range 1 '(function.outer)) nil)) (should (equal (evil-textobj-tree-sitter--get-goto-location '(function.outer) nil nil nil) nil))) (kill-buffer buffer))) (ert-deftest evil-textobj-tree-sitter-within-leaf-selects-smallest () "Check that leaf text object selects smallest node when multiple overlap. Uses the treesit path where the bug manifests: treesit returns nodes outermost-first, so the buggy comparator (which ignored end positions) preserved the wrong order and selected the block (71,126) instead of the identifier (71,75)." (let* ((bufname (make-temp-name "evil-textobj-tree-sitter-test--")) (buffer (get-buffer-create bufname)) (leaf-query '((python-ts-mode . "(_) @leaf")))) (with-current-buffer buffer (insert (alist-get 'py-complex evil-textobj-tree-sitter--test-file-content)) (python-ts-mode) ;; Position 71 is the start of `var2` inside `nested()`. Both the ;; identifier node (71,75) and the enclosing block node (71,126) share ;; the same start position, which exercises the sort comparator bug ;; where (car (last x)) was used for both operands. The expected ;; range (71 . 75) is the smallest node — the `var2` identifier. (goto-char 71) (should (equal (evil-textobj-tree-sitter--range 1 '(leaf) leaf-query) (cons 71 75)))) (kill-buffer buffer))) ;;; evil-textobj-tree-sitter-test.el ends here ================================================ FILE: evil-textobj-tree-sitter-thing-at-point.el ================================================ ;;; evil-textobj-tree-sitter-thing-at-point.el --- Provides thing-at-point integration for tree-sitter textobjects -*- lexical-binding: t; -*- ;; URL: https://github.com/meain/evil-textobj-tree-sitter ;; Keywords: evil, tree-sitter, text-object, convenience ;; SPDX-License-Identifier: Apache-2.0 ;; Package-Requires: ((emacs "25.1")) ;; Version: 0.5 ;;; Commentary: ;; This adds `thing-at-point' things powered by tree-sitter. ;; Suggestion for package which could help improve the use for this ;; https://github.com/plandes/mark-thing-at ;;; Code: (require 'thingatpt) (require 'evil-textobj-tree-sitter-core) (defun evil-textobj-tree-sitter--thing-at-point-bounds (group) "Return the bounds of the `GROUP' at point." (when-let* ((entity (evil-textobj-tree-sitter--get-within (list (intern group)) 1 nil)) (pos (cdr (car entity)))) (cons (car pos) (cadr pos)))) (put 'function 'bounds-of-thing-at-point (lambda () (evil-textobj-tree-sitter--thing-at-point-bounds "function.outer"))) (put 'loop 'bounds-of-thing-at-point (lambda () (evil-textobj-tree-sitter--thing-at-point-bounds "loop.outer"))) (put 'conditional 'bounds-of-thing-at-point (lambda () (evil-textobj-tree-sitter--thing-at-point-bounds "conditional.outer"))) (put 'assignment 'bounds-of-thing-at-point (lambda () (evil-textobj-tree-sitter--thing-at-point-bounds "assignment.outer"))) (put 'class 'bounds-of-thing-at-point (lambda () (evil-textobj-tree-sitter--thing-at-point-bounds "class.outer"))) (put 'comment 'bounds-of-thing-at-point (lambda () (evil-textobj-tree-sitter--thing-at-point-bounds "comment.outer"))) (put 'parameter 'bounds-of-thing-at-point (lambda () (evil-textobj-tree-sitter--thing-at-point-bounds "parameter.outer"))) ;;;###autoload (defun function-at-point () "Return the function at point, or nil if none is found." (thing-at-point 'function)) ;;;###autoload (defun loop-at-point () "Return the loop at point, or nil if none is found." (thing-at-point 'loop)) ;;;###autoload (defun conditional-at-point () "Return the conditional at point, or nil if none is found." (thing-at-point 'conditional)) ;;;###autoload (defun assignment-at-point () "Return the assignment at point, or nil if none is found." (thing-at-point 'assignment)) ;;;###autoload (defun class-at-point () "Return the class at point, or nil if none is found." (thing-at-point 'class)) ;;;###autoload (defun comment-at-point () "Return the comment at point, or nil if none is found." (thing-at-point 'comment)) ;;;###autoload (defun parameter-at-point () "Return the parameter at point, or nil if none is found." (thing-at-point 'parameter)) (provide 'evil-textobj-tree-sitter-thing-at-point) ;;; evil-textobj-tree-sitter-thing-at-point.el ends here ================================================ FILE: evil-textobj-tree-sitter.el ================================================ ;;; evil-textobj-tree-sitter.el --- Provides evil textobjects using tree-sitter -*- lexical-binding: t; -*- ;; URL: https://github.com/meain/evil-textobj-tree-sitter ;; Keywords: evil, tree-sitter, text-object, convenience ;; SPDX-License-Identifier: Apache-2.0 ;; Package-Requires: ((emacs "25.1")) ;; Version: 0.5 ;;; Commentary: ;; This package is a port of nvim-treesitter/nvim-treesitter-textobjects. ;; This package will let you create evil textobjects using the power ;; of tree-sitter grammars. You can easily create ;; function,class,comment etc textobjects in multiple languages. ;; ;; You can do a sample map like below to create a function textobj. ;; (define-key evil-outer-text-objects-map "f" ;; (evil-textobj-tree-sitter-get-textobj "function.outer")) ;; `evil-textobj-tree-sitter-get-textobj' will return you a function ;; that you can use in a define-key map. You can pass in any of the ;; supported queries as an arg of that function. You can also pass in ;; multiple queries as a list and we will match on all of them, ranked ;; on which ones comes up first in the file. ;; You can find more info in the README.md file at ;; https://github.com/meain/evil-textobj-tree-sitter ;; This package also provides with thing-at-point functions for common ;; textobjects like functions, loops, conditionals etc. ;; You need to either have elisp-tree-sitter installed or have Emacs ;; version >=29 for this package to work. ;;; Code: (require 'evil-textobj-tree-sitter-core) (require 'evil-textobj-tree-sitter-thing-at-point) (provide 'evil-textobj-tree-sitter) ;;; evil-textobj-tree-sitter.el ends here ================================================ FILE: fixtures/bash/textobjects.scm ================================================ (function_definition (_) @function.inner ) @function.outer (case_statement) @conditional.outer (if_statement (_) @conditional.inner ) @conditional.outer (for_statement (_) @loop.inner ) @loop.outer (while_statement (_) @loop.inner ) @loop.outer (comment) @comment.outer ================================================ FILE: fixtures/javascript/textobjects.scm ================================================ ; inherits: (jsx) (function_declaration body: (statement_block) @function.inner) @function.outer (export_statement (function_declaration) @function.outer) @function.outer.start ================================================ FILE: fixtures/tsx/textobjects.scm ================================================ ; inherits: typescript,jsx ================================================ FILE: fixtures/typescript/textobjects.scm ================================================ ; inherits: (javascript) ================================================ FILE: fixtures/zig/textobjects.scm ================================================ ;; "Classes" (VarDecl (_ (_ (ContainerDecl (ContainerMembers)? @class.inner)))) @class.outer ;; functions (_ (FnProto) (Block) @function.inner) @function.outer ================================================ FILE: flake.nix ================================================ { description = "evil-textobj-tree-sitter development environment"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; }; outputs = { self, nixpkgs }: let forAllSystems = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; in { devShells = forAllSystems (system: let pkgs = nixpkgs.legacyPackages.${system}; # Wrapper that sets GIT_DIR/GIT_WORK_TREE for jj repos so # tree-sitter-langs can find the git repo during eask install-deps eask-jj = pkgs.writeShellScriptBin "eask" '' if [ -z "''${GIT_DIR:-}" ] && command -v jj >/dev/null 2>&1 && jj root >/dev/null 2>&1; then export GIT_DIR="$(jj root)/.jj/repo/store/git" export GIT_WORK_TREE="$(jj root)" fi exec ${pkgs.eask-cli}/bin/eask "$@" ''; in { default = pkgs.mkShell { buildInputs = [ pkgs.emacs eask-jj pkgs.go pkgs.gcc ]; }; }); }; } ================================================ FILE: queries/apex/textobjects.scm ================================================ (class_declaration body: (class_body) @class.inner) @class.outer (method_declaration) @function.outer (method_declaration body: (block . "{" _+ @function.inner "}")) (constructor_declaration) @function.outer (constructor_declaration body: (constructor_body . "{" _+ @function.inner "}")) (for_statement body: (_)? @loop.inner) @loop.outer (enhanced_for_statement body: (_)? @loop.inner) @loop.outer (while_statement body: (_)? @loop.inner) @loop.outer (do_statement body: (_)? @loop.inner) @loop.outer (if_statement condition: (_ (parenthesized_expression) @conditional.inner) @conditional.outer) (if_statement consequence: (_)? @conditional.inner alternative: (_)? @conditional.inner) @conditional.outer (switch_expression body: (_)? @conditional.inner) @conditional.outer ; blocks (block) @block.outer (method_invocation) @call.outer (method_invocation arguments: (argument_list . "(" _+ @call.inner ")")) ; parameters (formal_parameters "," @parameter.outer . (formal_parameter) @parameter.inner @parameter.outer) (formal_parameters . (formal_parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) [ (line_comment) (block_comment) ] @comment.outer ; assignment (variable_declarator name: (identifier) @assignment.lhs value: (_) @assignment.rhs) @assignment.inner @assignment.outer ================================================ FILE: queries/astro/textobjects.scm ================================================ ; inherits: html ================================================ FILE: queries/bash/textobjects.scm ================================================ (function_definition) @function.outer (function_definition body: (compound_statement . "{" _+ @function.inner "}")) (case_statement) @conditional.outer (if_statement (_) @conditional.inner) @conditional.outer (for_statement (_) @loop.inner) @loop.outer (while_statement (_) @loop.inner) @loop.outer (comment) @comment.outer (regex) @regex.inner ((word) @number.inner (#match? @number.inner "^[0-9]+$")) (variable_assignment) @assignment.outer (variable_assignment name: (_) @assignment.inner @assignment.lhs) (variable_assignment value: (_) @assignment.inner @assignment.rhs) (command argument: (word) @parameter.inner) ================================================ FILE: queries/bibtex/textobjects.scm ================================================ (entry) @block.outer (field) @statement.outer ================================================ FILE: queries/c/textobjects.scm ================================================ (declaration declarator: (function_declarator)) @function.outer (function_definition body: (compound_statement)) @function.outer (function_definition body: (compound_statement . "{" _+ @function.inner "}")) (struct_specifier body: (_) @class.inner) @class.outer (enum_specifier body: (_) @class.inner) @class.outer ; conditionals (if_statement consequence: (compound_statement . "{" _+ @conditional.inner "}")) @conditional.outer (if_statement alternative: (else_clause (compound_statement . "{" _+ @conditional.inner "}"))) @conditional.outer (if_statement) @conditional.outer (if_statement condition: (_) @conditional.inner) (while_statement condition: (_) @conditional.inner) (do_statement condition: (_) @conditional.inner) (for_statement condition: (_) @conditional.inner) ; loops (while_statement) @loop.outer (while_statement body: (compound_statement . "{" _+ @loop.inner "}")) @loop.outer (for_statement) @loop.outer (for_statement body: (compound_statement . "{" _+ @loop.inner "}")) @loop.outer (do_statement) @loop.outer (do_statement body: (compound_statement . "{" _+ @loop.inner "}")) @loop.outer (compound_statement) @block.outer (comment) @comment.outer (call_expression) @call.outer (call_expression arguments: (argument_list . "(" _+ @call.inner ")")) (return_statement (_)? @return.inner) @return.outer ; Statements ;(expression_statement ;; this is what we actually want to capture in most cases (";" is missing) probably ;(_) @statement.inner) ;; the other statement like node type is declaration but declaration has a ";" (compound_statement (_) @statement.outer) (field_declaration_list (_) @statement.outer) (preproc_if (_) @statement.outer) (preproc_elif (_) @statement.outer) (preproc_else (_) @statement.outer) (parameter_list "," @parameter.outer . (parameter_declaration) @parameter.inner @parameter.outer) (parameter_list . (parameter_declaration) @parameter.inner @parameter.outer . ","? @parameter.outer) (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (number_literal) @number.inner (declaration declarator: (init_declarator declarator: (_) @assignment.lhs value: (_) @assignment.rhs) @assignment.inner) @assignment.outer (declaration type: (primitive_type) declarator: (_) @assignment.inner) (expression_statement (assignment_expression left: (_) @assignment.lhs right: (_) @assignment.rhs) @assignment.inner) @assignment.outer ================================================ FILE: queries/c_sharp/textobjects.scm ================================================ (class_declaration body: (declaration_list . "{" _* @class.inner "}")) @class.outer (struct_declaration body: (declaration_list . "{" _* @class.inner "}")) @class.outer (record_declaration body: (declaration_list . "{" _* @class.inner "}")) @class.outer (interface_declaration body: (declaration_list . "{" _+ @class.inner "}")) @class.outer (enum_declaration body: (enum_member_declaration_list . "{" _* @class.inner "}")) @class.outer (method_declaration body: (block . "{" _* @function.inner "}")) @function.outer (method_declaration body: (arrow_expression_clause "=>" _+ @function.inner)) @function.outer ; method without body(abstract method/decompiled metadata) (method_declaration _+ ";") @function.outer (property_declaration accessors: (accessor_list (accessor_declaration body: (block . "{" _* @function.inner "}")) @function.outer)) (property_declaration accessors: (accessor_list (accessor_declaration body: (arrow_expression_clause "=>" _* @function.inner)) @function.outer)) (indexer_declaration accessors: (accessor_list (accessor_declaration body: (arrow_expression_clause "=>" _+ @function.inner)) @function.outer)) (indexer_declaration accessors: (accessor_list (accessor_declaration body: (block . "{" _* @function.inner "}")) @function.outer)) (conversion_operator_declaration body: (block . "{" _* @function.inner "}")) @function.outer (conversion_operator_declaration body: (arrow_expression_clause "=>" _+ @function.inner)) @function.outer (operator_declaration body: (block . "{" _* @function.inner "}")) @function.outer ; operator without body(abstract/decompiled metadata) (operator_declaration _+ ";") @function.outer (operator_declaration body: (arrow_expression_clause "=>" _+ @function.inner)) @function.outer (constructor_declaration body: (block . "{" _* @function.inner "}")) @function.outer ; constructor without body(metadata) (constructor_declaration _+ ";") @function.outer (local_function_statement body: (block . "{" _* @function.inner "}")) @function.outer (local_function_statement body: (arrow_expression_clause "=>" _+ @function.inner)) @function.outer (anonymous_method_expression (block . "{" _* @function.inner "}")) @function.outer (lambda_expression body: (block . "{" _+ @function.inner "}")) @function.outer ; loops (for_statement body: (_) @loop.inner) @loop.outer (foreach_statement body: (_) @loop.inner) @loop.outer (do_statement (block) @loop.inner) @loop.outer (while_statement (block) @loop.inner) @loop.outer ; conditionals (if_statement consequence: (_)? @conditional.inner alternative: (_)? @conditional.inner) @conditional.outer (switch_statement body: (switch_body) @conditional.inner) @conditional.outer ; calls (invocation_expression) @call.outer (invocation_expression arguments: (argument_list . "(" _+ @call.inner ")")) ; blocks (_ (block) @block.inner) @block.outer ; parameters (parameter_list "," @parameter.outer . (parameter) @parameter.inner @parameter.outer) (parameter_list . (parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (argument_list "," @parameter.outer . (argument) @parameter.inner @parameter.outer) (argument_list . (argument) @parameter.inner @parameter.outer . ","? @parameter.outer) ; comments (comment) @comment.outer ================================================ FILE: queries/cmake/textobjects.scm ================================================ (function_def) @function.outer (function_def . (function_command) _+ @function.inner (endfunction_command) .) (if_condition) @conditional.outer (if_condition . (if_command) _+ @conditional.inner (endif_command) .) (foreach_loop) @loop.outer (foreach_loop . (foreach_command) _+ @loop.inner (endforeach_command) .) (normal_command) @call.outer (normal_command "(" _+ @call.inner ")") (line_comment) @comment.outer ================================================ FILE: queries/cpp/textobjects.scm ================================================ ; inherits: c (class_specifier body: (_) @class.inner) @class.outer (field_declaration type: (enum_specifier) default_value: (initializer_list) @class.inner) @class.outer (for_range_loop) @loop.outer (for_range_loop body: (compound_statement . "{" _+ @loop.inner "}")) (template_declaration (function_definition)) @function.outer (template_declaration (struct_specifier)) @class.outer (template_declaration (class_specifier)) @class.outer (lambda_capture_specifier "," @parameter.outer . (_) @parameter.inner @parameter.outer) (lambda_capture_specifier . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (template_argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (template_argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (template_parameter_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (template_parameter_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (parameter_list "," @parameter.outer . (optional_parameter_declaration) @parameter.inner @parameter.outer) (parameter_list . (optional_parameter_declaration) @parameter.inner @parameter.outer . ","? @parameter.outer) (initializer_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (initializer_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (new_expression (argument_list) @call.inner) @call.outer ================================================ FILE: queries/css/textobjects.scm ================================================ [ (integer_value) (float_value) (color_value) ] @number.inner (declaration (property_name) @assignment.lhs . ":" _+ @assignment.inner @assignment.rhs ";") @assignment.outer (declaration (property_name) @assignment.inner) (comment) @comment.outer ================================================ FILE: queries/cuda/textobjects.scm ================================================ ; inherits: cpp ================================================ FILE: queries/dart/textobjects.scm ================================================ ; class ((annotation)? @class.outer . (class_definition body: (class_body) @class.inner) @class.outer) (mixin_declaration (class_body) @class.inner) @class.outer (enum_declaration body: (enum_body) @class.inner) @class.outer (extension_declaration body: (extension_body) @class.inner) @class.outer ; function/method ((annotation)? @function.outer . [ (method_signature) (function_signature) ] @function.outer . (function_body) @function.outer) (function_body (block . "{" _+ @function.inner "}")) (type_alias (function_type)? @function.inner) @function.outer ; parameter [ (formal_parameter) (normal_parameter_type) (type_parameter) ] @parameter.inner ("," @parameter.outer . [ (formal_parameter) (normal_parameter_type) (type_parameter) ] @parameter.outer) ([ (formal_parameter) (normal_parameter_type) (type_parameter) ] @parameter.outer . "," @parameter.outer) ; TODO: (_)* not supported yet -> for now this works correctly only with simple arguments (arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) ; call ((identifier) @call.outer . (selector (argument_part) @call.outer)) ((identifier) . (selector (argument_part (arguments . "(" _+ @call.inner ")")))) ; block (block) @block.outer ; conditional (if_statement [ condition: (_) consequence: (_) alternative: (_)? ] @conditional.inner) @conditional.outer (switch_statement body: (switch_block) @conditional.inner) @conditional.outer (conditional_expression [ consequence: (_) alternative: (_) ] @conditional.inner) @conditional.outer ; loop (for_statement body: (block) @loop.inner) @loop.outer (while_statement body: (block) @loop.inner) @loop.outer (do_statement body: (block) @loop.inner) @loop.outer ; comment [ (comment) (documentation_comment) ] @comment.outer ; statement [ (break_statement) (do_statement) (expression_statement) (for_statement) (if_statement) (return_statement) (switch_statement) (while_statement) (assert_statement) ;(labeled_statement) (yield_statement) (yield_each_statement) (continue_statement) (try_statement) ] @statement.outer ================================================ FILE: queries/dockerfile/textobjects.scm ================================================ (expose_instruction (expose_port) @number.inner) ================================================ FILE: queries/ecma/textobjects.scm ================================================ (function_declaration body: (statement_block)) @function.outer (generator_function_declaration body: (statement_block)) @function.outer (function_expression body: (statement_block)) @function.outer (function_declaration body: (statement_block . "{" _+ @function.inner "}")) (generator_function_declaration body: (statement_block . "{" _+ @function.inner "}")) (function_expression body: (statement_block . "{" _+ @function.inner "}")) (export_statement (function_declaration)) @function.outer (arrow_function body: (_) @function.inner) @function.outer (arrow_function body: (statement_block . "{" _+ @function.inner "}")) (method_definition body: (statement_block)) @function.outer (method_definition body: (statement_block . "{" _+ @function.inner "}")) (class_declaration body: (class_body)) @class.outer (class_declaration body: (class_body . "{" _+ @class.inner "}")) (export_statement (class_declaration)) @class.outer (for_in_statement body: (statement_block . "{" _+ @loop.inner "}")) @loop.outer (for_statement body: (statement_block . "{" _+ @loop.inner "}")) @loop.outer (while_statement body: (statement_block . "{" _+ @loop.inner "}")) @loop.outer (do_statement body: (statement_block . "{" _+ @loop.inner "}")) @loop.outer (if_statement consequence: (statement_block . "{" _+ @conditional.inner "}")) @conditional.outer (if_statement alternative: (else_clause (statement_block . "{" _+ @conditional.inner "}"))) @conditional.outer (if_statement) @conditional.outer (switch_statement body: (_)? @conditional.inner) @conditional.outer (call_expression) @call.outer (call_expression arguments: (arguments . "(" _+ @call.inner ")")) (new_expression constructor: (identifier) @call.outer arguments: (arguments . "(" _+ @call.inner ")") @call.outer) ; blocks (statement_block (_)* @block.inner) @block.outer ; parameters ; function ({ x }) ... ; function ([ x ]) ... ; function (v = default_value) (formal_parameters "," @parameter.outer . (_) @parameter.inner @parameter.outer) (formal_parameters . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element with trailing comma (formal_parameters (_) @parameter.outer . "," @parameter.outer .) ; If the array/object pattern is the first parameter, treat its elements as the argument list (formal_parameters . (_ [ (object_pattern "," @parameter.outer . (_) @parameter.inner @parameter.outer) (array_pattern "," @parameter.outer . (_) @parameter.inner @parameter.outer) ])) (formal_parameters . (_ [ (object_pattern . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (array_pattern . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ])) ; last element with trailing comma (formal_parameters . (_ [ (object_pattern (_) @parameter.outer . "," @parameter.outer .) (array_pattern (_) @parameter.outer . "," @parameter.outer .) ])) ; arguments (arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element with trailing comma (arguments (_) @parameter.outer . "," @parameter.outer .) ; comment (comment) @comment.outer ; regex (regex (regex_pattern) @regex.inner) @regex.outer ; number (number) @number.inner (lexical_declaration (variable_declarator name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs)) @assignment.outer (variable_declarator name: (_) @assignment.inner) (object (pair key: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer) (return_statement (_) @return.inner) @return.outer (return_statement) @statement.outer [ (if_statement) (expression_statement) (for_statement) (while_statement) (do_statement) (for_in_statement) (export_statement) (lexical_declaration) ] @statement.outer ; 1. default import (import_statement (import_clause (identifier) @parameter.inner @parameter.outer)) ; 2. namespace import e.g. `* as React` (import_statement (import_clause (namespace_import (identifier) @parameter.inner) @parameter.outer)) ; 3. named import e.g. `import { Bar, Baz } from ...` (import_statement (import_clause (named_imports (import_specifier) @parameter.inner))) ; 3‑A. named import followed by a comma (import_statement (import_clause (named_imports (import_specifier) @parameter.outer . "," @parameter.outer))) ; 3‑B. comma followed by named import (import_statement (import_clause (named_imports "," @parameter.outer . (import_specifier) @parameter.outer))) ; 3-C. only one named import without a comma (import_statement (import_clause (named_imports . (import_specifier) @parameter.outer .))) ; Treat list or object elements as @parameter ; 1. parameter.inner (object (_) @parameter.inner) (array (_) @parameter.inner) (object_pattern (_) @parameter.inner) (array_pattern (_) @parameter.inner) ; 2. parameter.outer: Only one element, no comma (object . (_) @parameter.outer .) (array . (_) @parameter.outer .) (object_pattern . (_) @parameter.outer .) (array_pattern . (_) @parameter.outer .) ; 3. parameter.outer: Comma before or after [ (object "," @parameter.outer . (_) @parameter.outer) (array "," @parameter.outer . (_) @parameter.outer) (object_pattern "," @parameter.outer . (_) @parameter.outer) (array_pattern "," @parameter.outer . (_) @parameter.outer) ] [ (object . (_) @parameter.outer . "," @parameter.outer) (array . (_) @parameter.outer . "," @parameter.outer) (object_pattern . (_) @parameter.outer . "," @parameter.outer) (array_pattern . (_) @parameter.outer . "," @parameter.outer) ] ================================================ FILE: queries/elixir/textobjects.scm ================================================ ; Block Objects ([ (do_block "do" _+ @block.inner "end") (do_block "do" . ((_) @block.inner) @block.inner . "end") ]) @block.outer ; Class Objects (Modules, Protocols) ; multiple children (call target: ((identifier) @_identifier (#match? @_identifier "^(defmodule|defprotocol|defimpl)$")) (arguments (alias)) (do_block "do" _+ @class.inner "end")) @class.outer ; single child match (call target: ((identifier) @_identifier (#match? @_identifier "^(defmodule|defprotocol|defimpl)$")) (arguments (alias)) (do_block "do" . (_) @class.inner . "end")) @class.outer ; Function, Parameter, and Call Objects (anonymous_function (stab_clause right: (body) @function.inner)) @function.outer (call target: ((identifier) @_identifier (#match? @_identifier "^(def|defmacro|defmacrop|defn|defnp|defp)$")) (arguments [ (call [ (arguments (_) @parameter.inner @parameter.outer . "," @parameter.outer) (arguments ((_) @parameter.inner @parameter.outer) @parameter.outer .) ]) (binary_operator left: (call [ (arguments (_) @parameter.inner @parameter.outer . "," @parameter.outer) (arguments ((_) @parameter.inner @parameter.outer) @parameter.outer .) ])) ]) [ (do_block "do" _+ @function.inner "end") (do_block "do" . ((_) @function.inner) @function.inner . "end") ]) @function.outer (call target: ((identifier) @_identifier (#match? @_identifier "^(def|defmacro|defmacrop|defn|defnp|defp)$")) (arguments [ (identifier) (binary_operator (identifier)) ]) [ (do_block "do" _+ @function.inner "end") (do_block "do" . ((_) @function.inner) @function.inner . "end") ]) @function.outer (call target: ((identifier) @_identifier (#match? @_identifier "^(def|defmacro|defmacrop|defn|defnp|defp)$")) (arguments [ (call [ (arguments (_) @parameter.inner @parameter.outer . "," @parameter.outer) (arguments ((_) @parameter.inner @parameter.outer) @parameter.outer .) ]) (binary_operator left: (call [ (arguments (_) @parameter.inner @parameter.outer . "," @parameter.outer) (arguments ((_) @parameter.inner @parameter.outer) @parameter.outer .) ])) ] (keywords (pair value: (_) @function.inner)))) @function.outer (call target: ((identifier) @_identifier (#match? @_identifier "^(def|defmacro|defmacrop|defn|defnp|defp)$")) (arguments [ (identifier) (binary_operator (identifier)) ] (keywords (pair value: (_) @function.inner)))) @function.outer ; Comment Objects (comment) @comment.outer ; Documentation Objects (unary_operator operator: "@" operand: (call target: ((identifier) @_identifier (#match? @_identifier "^(moduledoc|typedoc|shortdoc|doc)$")) (arguments [ ; attributes style documentation ; @doc deprecated: "...." (keywords) @comment.inner ; heredoc style documentation ; @moduledoc """""" (string (quoted_content) @comment.inner) ]))) @comment.outer ; Regex Objects (sigil (quoted_content) @regex.inner) @regex.outer ================================================ FILE: queries/elm/textobjects.scm ================================================ ; Functions ; top level function with type annotation and doc comment ((module_declaration) (block_comment) @function.outer . (type_annotation) . (value_declaration body: (_)? @function.inner) @function.outer) ; top level function with type annotation ((module_declaration) (type_annotation) @function.outer . (value_declaration body: (_)? @function.inner) @function.outer) ; top level function without type annotation ((module_declaration) (value_declaration body: (_)? @function.inner) @function.outer) ; Comments [ (block_comment) (line_comment) ] @comment.outer ; Conditionals (if_else_expr exprList: (_) exprList: (_) @conditional.inner) @conditional.outer (case_of_expr branch: (case_of_branch) @conditional.inner) @conditional.outer ; Parameters ; type annotations (type_expression (arrow) @parameter.outer . (type_ref) @parameter.inner @parameter.outer) (type_expression . (type_ref) @parameter.inner @parameter.outer . (arrow)? @parameter.outer) ; list items (list_expr "," @parameter.outer . exprList: (_) @parameter.inner @parameter.outer) (list_expr . exprList: (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; tuple items (tuple_expr "," @parameter.outer . expr: (_) @parameter.inner @parameter.outer) (tuple_expr . expr: (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ================================================ FILE: queries/enforce/textobjects.scm ================================================ [ (comment_line) (comment_block) (doc_line) (doc_block) ] @comment.outer [ (literal_int) (literal_float) ] @number.inner ; TODO: capture inside braces (decl_class body: (_) @class.inner) @class.outer (decl_method body: (_) @function.inner) @function.outer (for body: (_) @loop.inner) @loop.outer (while body: (_) @loop.inner) @loop.outer (return (_)? @return.inner) @return.outer ; blocks (block) @block.outer (invokation) @call.outer (formal_parameters "," @parameter.outer . (formal_parameter) @parameter.inner @parameter.outer) (formal_parameters . (formal_parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (actual_parameters "," @parameter.outer . (actual_parameter) @parameter.inner @parameter.outer) (actual_parameters . (actual_parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) ================================================ FILE: queries/fennel/textobjects.scm ================================================ ; https://fennel-lang.org/reference (comment body: (comment_body) @comment.inner) @comment.outer (_ . "(" ")" .) @statement.outer ; functions ; NOTE: Doesn't capture the comments before the first `item` field (fn_form [ (table_metadata) (docstring) ] . item: (_) @function.inner (_)? @function.inner . close: _ .) (fn_form args: (_) . item: (_) @function.inner (_)? @function.inner . close: _ .) (lambda_form [ (table_metadata) (docstring) ] . item: (_) @function.inner (_)? @function.inner . close: _ .) (lambda_form args: (_) . item: (_) @function.inner (_)? @function.inner . close: _ .) (macro_form [ (table_metadata) (docstring) ] . item: (_) @function.inner (_)? @function.inner . close: _ .) (macro_form args: (_) . item: (_) @function.inner (_)? @function.inner . close: _ .) [ (fn_form) (lambda_form) (macro_form) ] @function.outer ; function arguments (sequence_arguments item: (_) @parameter.inner) @parameter.outer ; call (list call: (symbol) @_fn_name item: (_) @call.inner (_) @call.inner . close: _ (#not-eq? @_fn_name "do") (#not-eq? @_fn_name "while") (#not-eq? @_fn_name "when")) @call.outer ; assignment (local_form (binding_pair lhs: (_) @assignment.lhs rhs: (_) @assignment.rhs) @assignment.inner) @assignment.outer (var_form (binding_pair lhs: (_) @assignment.lhs rhs: (_) @assignment.rhs) @assignment.inner) @assignment.outer (global_form (binding_pair lhs: (_) @assignment.lhs rhs: (_) @assignment.rhs) @assignment.inner) @assignment.outer (set_form lhs: (_) @assignment.lhs @assignment.inner rhs: (_) @assignment.rhs @assignment.inner) @assignment.outer (let_vars (binding_pair lhs: (_) @assignment.lhs rhs: (_) @assignment.rhs) @assignment.inner) @assignment.outer ; conditionals (if_form (if_pair expression: (_) @conditional.inner)) @conditional.outer (if_form else: (_) @conditional.inner) @conditional.outer (list call: (symbol) @_cond . item: (_) item: (_)* @conditional.inner (#eq? @_cond "when")) @conditional.outer ; loops (each_form iter_body: (_) _+ @loop.inner close: _) (each_form) @loop.outer (collect_form iter_body: (_) _+ @loop.inner close: _) (collect_form) @loop.outer (icollect_form iter_body: (_) _+ @loop.inner close: _) (icollect_form) @loop.outer (accumulate_form iter_body: (_) _+ @loop.inner close: _) (accumulate_form) @loop.outer (for_form iter_body: (_) _+ @loop.inner close: _) (for_form) @loop.outer (fcollect_form iter_body: (_) _+ @loop.inner close: _) (fcollect_form) @loop.outer (faccumulate_form iter_body: (_) _+ @loop.inner close: _) (faccumulate_form) @loop.outer (list call: (symbol) @_sym . item: (_) item: (_)* @loop.inner (#eq? @_sym "while")) (list call: (symbol) @_sym (#eq? @_sym "while")) @loop.outer ================================================ FILE: queries/fish/textobjects.scm ================================================ ; assignment (command name: (word) @_command argument: (word) @_varname @assignment.lhs @assignment.inner argument: (_)* @assignment.rhs (#not-match? @_varname "^[-].*") (#eq? @_command "set")) @assignment.outer (command name: (word) @_name argument: (_)* @assignment.inner (#eq? @_name "set")) ; block ([ (case_clause) (if_statement) (switch_statement) (else_clause) (for_statement) (while_statement) ]) @block.outer ; call ; call.inner doesn't work because it can't select *all* arguments (command) @call.outer ; comment ; leave space after comment marker if there is one ((comment) @comment.inner @comment.outer (#match? @comment.outer "# .*")) ; else remove everything accept comment marker ((comment) @comment.inner @comment.outer) ; conditional (if_statement (command) @conditional.inner) @conditional.outer (switch_statement (_) @conditional.inner) @conditional.outer ; function ((function_definition) @function.inner @function.outer) ; loop (for_statement (_) @loop.inner) @loop.outer (while_statement condition: (command) (command) @loop.inner) @loop.outer ; number [ (integer) (float) ] @number.inner ; parameter (command argument: (_) @parameter.outer) ; return (return (_) @return.inner) @return.outer ; statement (command) @statement.outer ================================================ FILE: queries/foam/textobjects.scm ================================================ (dict) @class.outer (dict_core) @class.inner (key_value value: _? @function.inner (_)* @function.inner _? @parameter.inner @function.inner) @function.outer (code (_)* @class.inner) @class.outer (comment)+ @comment.outer (comment) @comment.inner ================================================ FILE: queries/gdscript/textobjects.scm ================================================ (function_definition body: (_) @function.inner) @function.outer (constructor_definition body: (_) @function.inner) @function.outer (class_definition body: (_) @class.inner) @class.outer (if_statement body: (_) @conditional.inner) @conditional.outer (if_statement alternative: (_ (_) @conditional.inner)?) @conditional.outer (if_statement condition: (_) @conditional.inner) [ (for_statement) (while_statement) ] @loop.outer (while_statement body: (_) @loop.inner) (for_statement body: (_) @loop.inner) (comment) @comment.outer (parameters "," @parameter.outer . (_) @parameter.inner @parameter.outer) (parameters . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (array "," @parameter.outer . (_) @parameter.inner @parameter.outer) (array . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ================================================ FILE: queries/git_config/textobjects.scm ================================================ ; assignments (variable (_) @assignment.lhs @assignment.inner value: (_) @assignment.rhs) @assignment.outer (variable value: (_) @assignment.inner) ; blocks (section (section_header) (_)+ @block.inner) @block.outer ; comments (comment) @comment.outer ; statements (section (section_header) (_) @statement.outer) ================================================ FILE: queries/gleam/textobjects.scm ================================================ ; assignments (let pattern: (_) @assignment.lhs @assignment.inner value: (_) @assignment.rhs) @assignment.outer (let value: (_) @assignment.inner) (let_assert pattern: (_) @assignment.lhs @assignment.inner value: (_) @assignment.rhs) @assignment.outer (let_assert value: (_) @assignment.inner) (use assignments: (use_assignments) @assignment.lhs @assignment.inner value: (_) @assignment.rhs) @assignment.outer (use value: (_) @assignment.inner) ; block (block "{" . _+ @block.inner . "}") @block.outer ; calls (function_call arguments: (arguments . "(" _+ @call.inner ")")) @call.outer (record arguments: (arguments . "(" _+ @call.inner ")")) @call.outer (record_update ".." @call.inner . spread: (_) @call.inner . "," @call.inner arguments: (record_update_arguments) @call.inner) @call.outer ; class (type_definition (data_constructors) @class.inner) @class.outer ; comment (comment) @comment.outer ; conditionals (case clauses: (case_clauses (case_clause) @conditional.inner)) @conditional.outer ; numbers [ (integer) (float) ] @number.inner ; parameters in functions declarations (function_parameters "," @parameter.outer . (function_parameter) @parameter.inner @parameter.outer) (function_parameters . ; first parameter (function_parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (function_parameters (function_parameter) @parameter.inner @parameter.outer . ; trailing comma "," @parameter.outer .) ; parameters in calls (arguments "," @parameter.outer . (argument) @parameter.inner @parameter.outer) (arguments . ; first parameter (argument) @parameter.inner @parameter.outer . ","? @parameter.outer) (arguments (argument) @parameter.inner @parameter.outer . ; trailing comma "," @parameter.outer .) ; parameters for types and records (data_constructor_arguments "," @parameter.outer . (data_constructor_argument) @parameter.inner @parameter.outer) (data_constructor_arguments . ; first parameter (data_constructor_argument) @parameter.inner @parameter.outer . ","? @parameter.outer) (data_constructor_arguments (data_constructor_argument) @parameter.inner @parameter.outer . ; trailing comma "," @parameter.outer .) (type_parameters "," @parameter.outer . (type_parameter) @parameter.inner @parameter.outer) (type_parameters . ; first parameter (type_parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (type_parameters (type_parameter) @parameter.inner @parameter.outer . ; trailing comma "," @parameter.outer .) (type_arguments "," @parameter.outer . (type_argument) @parameter.inner @parameter.outer) (type_arguments . ; first parameter (type_argument) @parameter.inner @parameter.outer . ","? @parameter.outer) (type_arguments (type_argument) @parameter.inner @parameter.outer . ; trailing comma "," @parameter.outer .) (record_pattern_arguments "," @parameter.outer . (record_pattern_argument) @parameter.inner @parameter.outer) (record_pattern_arguments . ; first parameter (record_pattern_argument) @parameter.inner @parameter.outer . ","? @parameter.outer) (record_pattern_arguments (record_pattern_argument) @parameter.inner @parameter.outer . ; trailing comma "," @parameter.outer .) (record_update ".." @parameter.inner @parameter.outer . spread: (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (record_update "," @parameter.outer arguments: (record_update_arguments . ; first parameter after spread (record_update_argument) @parameter.inner @parameter.outer)) (record_update arguments: (record_update_arguments "," @parameter.outer . (record_update_argument) @parameter.inner @parameter.outer)) (record_update arguments: (record_update_arguments (record_update_argument) @parameter.inner @parameter.outer . ; trailing comma "," @parameter.outer .)) ; parameters in lists (list "," @parameter.outer (_) @parameter.inner @parameter.outer) (list . ; first parameter (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (list (_) @parameter.inner @parameter.outer . ;trailing comma "," @parameter.outer .) (list_pattern "," @parameter.outer (_) @parameter.inner @parameter.outer) (list_pattern . ; first parameter (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (list_pattern (_) @parameter.inner @parameter.outer . ;trailing comma "," @parameter.outer .) ; parameters in tuples (tuple "," @parameter.outer (_) @parameter.inner @parameter.outer) (tuple . ; first parameter (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (tuple (_) @parameter.inner @parameter.outer . ;trailing comma "," @parameter.outer .) ; parameters in bit arrays (bit_array "," @parameter.outer (_) @parameter.inner @parameter.outer) (bit_array . ; first parameter (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (bit_array (_) @parameter.inner @parameter.outer . ;trailing comma "," @parameter.outer .) ; functions (function body: (block "{" . _+ @function.inner . "}")) @function.outer (anonymous_function body: (block "{" . _+ @function.inner . "}")) @function.outer ; returns (function body: (block (_) @return.inner @return.outer .)) (anonymous_function body: (block (_) @return.inner @return.outer .)) ; statements (block (_) @statement.outer) ================================================ FILE: queries/glimmer/textobjects.scm ================================================ [ (element_node) (block_statement) ] @function.outer [ (mustache_statement) (block_statement_start) ] @block.outer (attribute_node) @attribute.outer (attribute_node [ (concat_statement) (mustache_statement) ] @attribute.inner) (element_node (element_node_start) . (_) @function.inner . (element_node_end)) (block_statement (block_statement_start) . (_) @function.inner . (block_statement_end)) (element_node (element_node_start) _+ @function.inner (element_node_end)) (block_statement (block_statement_start) _+ @function.inner (block_statement_end)) (mustache_statement . "{{" (_) @block.inner . "}}") (block_statement_start . "{{#" (_) @block.inner . "}}") (comment_statement) @comment.outer ================================================ FILE: queries/glsl/textobjects.scm ================================================ ; inherits: c ================================================ FILE: queries/go/textobjects.scm ================================================ ; inner function textobject (function_declaration body: (block . "{" _+ @function.inner "}")) ; inner function literals (func_literal body: (block . "{" _+ @function.inner "}")) ; method as inner function textobject (method_declaration body: (block . "{" _+ @function.inner "}")) ; outer function textobject (function_declaration) @function.outer ; outer function literals (func_literal (_)?) @function.outer ; method as outer function textobject (method_declaration body: (block)?) @function.outer ; struct and interface declaration as class textobject? (type_declaration (type_spec (type_identifier) (struct_type (field_declaration_list (_)?) @class.inner))) @class.outer (type_declaration (type_spec (type_identifier) (interface_type) @class.inner)) @class.outer ; struct literals as class textobject (composite_literal (type_identifier)? (struct_type (_))? (literal_value (_)) @class.inner) @class.outer ; conditionals (if_statement alternative: (_ (_) @conditional.inner)?) @conditional.outer (if_statement consequence: (block)? @conditional.inner) (if_statement condition: (_) @conditional.inner) ; loops (for_statement body: (block)? @loop.inner) @loop.outer ; blocks (_ (block) @block.inner) @block.outer ; statements (block (_) @statement.outer) ; comments (comment) @comment.outer ; calls (call_expression) @call.outer (call_expression arguments: (argument_list . "(" _+ @call.inner ")")) ; parameters (parameter_list "," @parameter.outer . (parameter_declaration) @parameter.inner @parameter.outer) (parameter_list . (parameter_declaration) @parameter.inner @parameter.outer . ","? @parameter.outer) (parameter_declaration name: (identifier) type: (_)) @parameter.inner (parameter_declaration name: (identifier) type: (_)) @parameter.inner (parameter_list "," @parameter.outer . (variadic_parameter_declaration) @parameter.inner @parameter.outer) ; arguments (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; assignments (short_var_declaration left: (_) @assignment.lhs right: (_) @assignment.rhs @assignment.inner) @assignment.outer (assignment_statement left: (_) @assignment.lhs right: (_) @assignment.rhs @assignment.inner) @assignment.outer (var_spec name: (_) @assignment.lhs value: (_) @assignment.rhs @assignment.inner) @assignment.outer (var_spec name: (_) @assignment.inner type: (_)) @assignment.outer (const_spec name: (_) @assignment.lhs value: (_) @assignment.rhs @assignment.inner) @assignment.outer (const_spec name: (_) @assignment.inner type: (_)) @assignment.outer ================================================ FILE: queries/hack/textobjects.scm ================================================ (method_declaration) @function.outer ================================================ FILE: queries/haskell/textobjects.scm ================================================ (apply . function: (_) _+ @call.inner) @call.outer (infix (_) [ (infix_id (variable)) ; x `plus` y (operator) ; x + y ] (_)) @call.outer (decl/function) @function.outer (decl/function patterns: (_) match: _+ @function.inner) ; also treat function signature as @function.outer (signature) @function.outer ; treat signature with function as @function.outer (((decl/signature name: (_) @_sig_name) @function.outer . (decl/function name: (_) @_func_name) @function.outer) (#eq? @_sig_name @_func_name)) (class) @class.outer (class "where" _ @class.inner) (instance "where"? . _ @class.inner) @class.outer (comment) @comment.outer (haddock) @comment.outer (expression/conditional) @conditional.outer (expression/conditional (_) @conditional.inner) ; e.g. forM [1..10] $ \i -> do... (infix (apply (name) @_name (#eq? @_name "for")) (operator) @_op (#eq? @_op "$") (lambda (_) (_) @loop.inner)) @loop.outer (infix (apply (name) @_name (#eq? @_name "for_")) (operator) @_op (#eq? @_op "$") (lambda (_) (_) @loop.inner)) @loop.outer (infix (apply (name) @_name (#eq? @_name "forM")) (operator) @_op (#eq? @_op "$") (lambda (_) (_) @loop.inner)) @loop.outer (infix (apply (name) @_name (#eq? @_name "forM_")) (operator) @_op (#eq? @_op "$") (lambda (_) (_) @loop.inner)) @loop.outer ; e.g. forM [1..10] print (apply (name) @_name (#eq? @_name "for") (_) (_) @loop.inner) @loop.outer (apply (name) @_name (#eq? @_name "for_") (_) (_) @loop.inner) @loop.outer (apply (name) @_name (#eq? @_name "forM") (_) (_) @loop.inner) @loop.outer (apply (name) @_name (#eq? @_name "forM_") (_) (_) @loop.inner) @loop.outer ; e.g. func x (function (patterns (_) @parameter.outer)) ; e.g. func mb@(Just x) (function (patterns (parens (_) @parameter.inner))) (function (patterns (as (parens (_) @parameter.inner)))) (signature (context (function (type/apply) @parameter.inner))) (signature (context (function (type/name) @parameter.inner))) (signature (function (type/apply) @parameter.inner)) (signature (function (type/name) @parameter.inner)) (signature (type/apply) @parameter.inner) (signature (type/name) @parameter.inner) ================================================ FILE: queries/hcl/textobjects.scm ================================================ (attribute (identifier) @assignment.lhs (expression) @assignment.inner @assignment.rhs) @assignment.outer (attribute (identifier) @assignment.inner) (block (body)? @block.inner) @block.outer (block (body (_) @statement.outer)) (function_call (function_arguments) @call.inner) @call.outer (comment) @comment.outer (conditional (expression) @conditional.inner) @conditional.outer (for_cond (expression) @conditional.inner) @conditional.outer (for_expr (for_object_expr (for_intro) @loop.inner (expression) @loop.inner (expression) @loop.inner (for_cond)? @loop.inner)) @loop.outer (for_expr (for_object_expr (for_intro) @loop.inner)) (for_expr (for_object_expr (expression) @loop.inner)) (for_expr (for_tuple_expr (for_intro) @loop.inner (expression) @loop.inner (for_cond)? @loop.inner)) @loop.outer (for_expr (for_tuple_expr (for_intro) @loop.inner)) (for_expr (for_tuple_expr (expression) @loop.inner)) (numeric_lit) @number.inner (function_arguments "," @parameter.outer . (expression) @parameter.inner @parameter.outer) (function_arguments . (expression) @parameter.inner @parameter.outer . ","? @parameter.outer) ================================================ FILE: queries/heex/textobjects.scm ================================================ (tag) @function.outer (tag (start_tag) . (_) @function.inner . (end_tag)) (attribute_value) @attribute.inner (attribute) @attribute.outer (tag (start_tag) _+ @function.inner (end_tag)) ================================================ FILE: queries/hlsl/textobjects.scm ================================================ ; inherits: cpp ================================================ FILE: queries/html/textobjects.scm ================================================ (element) @function.outer (element (start_tag) . (_) @function.inner . (end_tag)) (attribute_value) @attribute.inner (attribute) @attribute.outer (element (start_tag) _+ @function.inner (end_tag)) (script_element) @function.outer (script_element (start_tag) . (_) @function.inner . (end_tag)) (style_element) @function.outer (style_element (start_tag) . (_) @function.inner . (end_tag)) ((element (start_tag (tag_name) @_tag)) @class.outer (#match? @_tag "^(html|section|h[0-9]|header|title|head|body)$")) ((element (start_tag (tag_name) @_tag) . (_) @class.inner . (end_tag)) (#match? @_tag "^(html|section|h[0-9]|header|title|head|body)$")) ((element (start_tag (tag_name) @_tag) _+ @class.inner (end_tag)) (#match? @_tag "^(html|section|h[0-9]|header|title|head|body)$")) (comment) @comment.outer ================================================ FILE: queries/inko/textobjects.scm ================================================ ; Classes (class) @class.outer (class body: (class_body . "{" _+ @class.inner "}")) ; Traits (trait) @class.outer (trait body: (trait_body . "{" _+ @class.inner "}")) ; Implementations (implement_trait) @class.outer (implement_trait body: (implement_trait_body . "{" _+ @class.inner "}")) (reopen_class) @class.outer (reopen_class body: (reopen_class_body . "{" _+ @class.inner "}")) ; Methods and closures (method) @function.outer (method body: (block . "{" _+ @function.inner "}")) (closure) @function.outer (closure body: (block . "{" _+ @function.inner "}")) ; Loops (while body: (block . "{" _+ @loop.inner "}")) @loop.outer (while condition: (_) @conditional.inner) (loop body: (block . "{" _+ @loop.inner "}")) @loop.outer ; Conditionals (if alternative: (_ (_) @conditional.inner)?) @conditional.outer (if consequence: (block) @conditional.inner) (if condition: (_) @conditional.inner) (case) @conditional.inner (match) @conditional.outer ; Method calls (call) @call.outer (call arguments: (arguments . "(" _+ @call.inner ")")) (return (_)? @return.inner) @return.outer ; Call and type arguments (arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (type_arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (type_arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; Patterns (class_pattern "," @parameter.outer . (_) @parameter.inner @parameter.outer) (class_pattern . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (tuple_pattern "," @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple_pattern . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; Sequence types (tuple "," @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (array "," @parameter.outer . (_) @parameter.inner @parameter.outer) (array . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; Blocks (block (_)? @block.inner) @block.outer ; Comments (line_comment) @comment.outer ; Numbers [ (integer) (float) ] @number.inner ; Variable definitions and assignments (identifier_pattern name: (_) @assignment.lhs type: (_) @assignment.inner @assignment.rhs) @assignment.outer (define_constant name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (assign_local name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (assign_field name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (assign_receiver_field name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (replace_local name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (replace_field name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (compound_assign_local name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (compound_assign_field name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (compound_assign_receiver_field name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer ================================================ FILE: queries/java/textobjects.scm ================================================ (class_declaration body: (class_body) @class.inner) @class.outer (method_declaration) @function.outer (method_declaration body: (block . "{" _+ @function.inner "}")) (constructor_declaration) @function.outer (constructor_declaration body: (constructor_body . "{" _+ @function.inner "}")) (return_statement (_)? @return.inner) @return.outer (for_statement body: (_)? @loop.inner) @loop.outer (enhanced_for_statement body: (_)? @loop.inner) @loop.outer (while_statement body: (_)? @loop.inner) @loop.outer (do_statement body: (_)? @loop.inner) @loop.outer (if_statement condition: (_ (parenthesized_expression) @conditional.inner) @conditional.outer) (if_statement consequence: (_)? @conditional.inner alternative: (_)? @conditional.inner) @conditional.outer (switch_expression body: (_)? @conditional.inner) @conditional.outer ; blocks (block) @block.outer (method_invocation) @call.outer (method_invocation arguments: (argument_list . "(" _+ @call.inner ")")) ; parameters (formal_parameters "," @parameter.outer . (formal_parameter) @parameter.inner @parameter.outer) (formal_parameters . (formal_parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) [ (line_comment) (block_comment) ] @comment.outer [ (decimal_integer_literal) (decimal_floating_point_literal) (hex_integer_literal) (binary_integer_literal) (octal_integer_literal) ] @number.inner ; scopename ; statement (statement) @statement.outer (return_statement) @statement.outer ================================================ FILE: queries/javascript/textobjects.scm ================================================ ; inherits: ecma,jsx ================================================ FILE: queries/json/textobjects.scm ================================================ (comment) @comment.outer ================================================ FILE: queries/jsx/textobjects.scm ================================================ ; inherits: ecma (jsx_attribute) @attribute.outer (jsx_attribute (property_identifier) (_ (_) @attribute.inner)) ================================================ FILE: queries/julia/textobjects.scm ================================================ ; Blocks (compound_statement) @block.outer (compound_statement . (_) @block.inner (_)? @block.inner .) (quote_statement) @block.outer (quote_statement . (_) @block.inner (_)? @block.inner .) (let_statement) @block.outer (let_statement . (_) @block.inner (_)? @block.inner .) ; Conditionals (if_statement condition: (_) @conditional.inner) @conditional.outer (if_statement alternative: (elseif_clause condition: (_) @conditional.inner)) ((if_statement condition: (_) . (_) @conditional.inner (_)? @conditional.inner . [ "end" (elseif_clause) (else_clause) ]) @conditional.outer (elseif_clause condition: (_) . (_) @conditional.inner (_)? @conditional.inner .)) (else_clause . (_) @conditional.inner (_)? @conditional.inner .) ; Loops (for_statement) @loop.outer (for_statement . (_) @loop.inner (_)? @loop.inner .) (while_statement condition: (_) @loop.inner) @loop.outer (while_statement condition: (_) . (_) @loop.inner (_)? @loop.inner .) ; Type definitions (struct_definition) @class.outer (struct_definition (type_head) . (_) @class.inner (_)? @class.inner .) ; Function definitions (function_definition) @function.outer (function_definition (signature) . (_) @function.inner (_)? @function.inner .) (assignment (call_expression) (operator) (_) @function.inner) @function.outer (arrow_function_expression [ (identifier) (argument_list) ] "->" (_) @function.inner) @function.outer (macro_definition) @function.outer (macro_definition (signature) . (_) @function.inner (_)? @function.inner .) ; Calls (call_expression) @call.outer (call_expression (argument_list . "(" . (_) @call.inner (_)? @call.inner . ")")) (macrocall_expression) @call.outer (macrocall_expression (argument_list . "(" . (_) @call.inner (_)? @call.inner . ")")) (broadcast_call_expression) @call.outer (broadcast_call_expression (argument_list . "(" . (_) @call.inner (_)? @call.inner . ")")) ; Parameters ((argument_list [ "," ";" ] @parameter.outer . (_) @parameter.inner @parameter.outer) (argument_list (_) @parameter.inner @parameter.outer . [ "," ";" ] @parameter.outer)) (tuple_expression [ "," ";" ] @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple_expression "(" . (_) @parameter.inner @parameter.outer . [ "," ";" ]? @parameter.outer) (vector_expression [ "," ";" ] @parameter.outer . (_) @parameter.inner @parameter.outer) (vector_expression . (_) @parameter.inner @parameter.outer . [ "," ";" ]? @parameter.outer) ; Assignment (assignment . (_) @assignment.lhs (_) @assignment.inner @assignment.rhs .) @assignment.outer (assignment . (_) @assignment.inner) (compound_assignment_expression . (_) @assignment.lhs (_) @assignment.inner @assignment.rhs .) @assignment.outer (compound_assignment_expression . (_) @assignment.inner) ; Comments [ (line_comment) (block_comment) ] @comment.outer ; Regex ((prefixed_string_literal prefix: (identifier) @_prefix) @regex.inner @regex.outer (#eq? @_prefix "r")) ================================================ FILE: queries/kotlin/textobjects.scm ================================================ (class_declaration [ (class_body) (enum_class_body) ]? @class.inner) @class.outer [ (function_declaration (function_body) @function.inner) (getter (function_body) @function.inner) (setter (function_body) @function.inner) (primary_constructor) ] @function.outer (primary_constructor) @function.inner [ (parameter (simple_identifier) @parameter.inner) (class_parameter (simple_identifier) @parameter.inner) ] @parameter.outer (value_arguments "," @parameter.outer . (value_argument) @parameter.inner @parameter.outer) (value_arguments . (value_argument) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (value_arguments (value_argument) @parameter.outer . "," @parameter.outer .) [ (line_comment) (multiline_comment) ] @comment.outer (if_expression (control_structure_body) @conditional.inner) @conditional.outer (when_expression (when_entry) @conditional.inner) @conditional.outer [ (for_statement (control_structure_body) @loop.inner) (while_statement (control_structure_body) @loop.inner) ] @loop.outer [ (integer_literal) (real_literal) ] @number.inner ================================================ FILE: queries/latex/textobjects.scm ================================================ (generic_environment . (_) _+ @block.inner (_) .) @block.outer ((generic_environment (begin name: (curly_group_text (text) @_frame)) _+ @frame.inner (_) .) @frame.outer (#eq? @_frame "frame")) [ (generic_command) (text_mode) ] @call.outer (text_mode (curly_group "{" _+ @call.inner "}")) (generic_command (curly_group "{" _+ @call.inner "}")) (part text: (_) _+ @class.inner) (part text: (_)) @class.outer (chapter text: (_) _+ @class.inner) (chapter text: (_)) @class.outer (section text: (_) _+ @class.inner) (section text: (_)) @class.outer (subsection text: (_) _+ @class.inner) (subsection text: (_)) @class.outer (subsubsection text: (_) _+ @class.inner) (subsubsection text: (_)) @class.outer (paragraph text: (_) _+ @class.inner) (paragraph text: (_)) @class.outer (subparagraph text: (_) _+ @class.inner) (subparagraph text: (_)) @class.outer ================================================ FILE: queries/lua/textobjects.scm ================================================ ; block (_ (block) @block.inner) @block.outer ; call (function_call) @call.outer ================================================ FILE: queries/markdown/textobjects.scm ================================================ (atx_heading heading_content: (_) @class.inner) @class.outer (setext_heading heading_content: (_) @class.inner) @class.outer (thematic_break) @class.outer (fenced_code_block (code_fence_content) @block.inner) @block.outer [ (paragraph) (list) ] @block.outer ================================================ FILE: queries/matlab/textobjects.scm ================================================ (_ (block) @block.inner) @block.outer (block (_) @statement.outer) (source_file (_) @statement.outer) (function_call (arguments)? @call.inner) @call.outer (arguments ","? @parameter.outer . (_) @parameter.inner @parameter.outer .) (arguments (_) @parameter.inner @parameter.outer . "," @parameter.outer) (command) @call.outer (command (command_argument) @parameter.inner @parameter.outer) (command (command_argument)+ @call.inner) (if_statement (block) @conditional.inner) @conditional.outer (if_statement (elseif_clause (block) @conditional.inner)) (if_statement (else_clause (block) @conditional.inner)) (switch_statement (case_clause (block) @conditional.inner)) @conditional.outer (switch_statement (otherwise_clause (block) @conditional.inner)) (for_statement (block) @loop.inner) @loop.outer (while_statement (block) @loop.inner) @loop.outer (lambda expression: (_) @function.inner) @function.outer (global_operator (identifier) @parameter.inner) (persistent_operator (identifier) @parameter.inner) (function_definition (block) @function.inner) @function.outer (function_output (identifier) @parameter.inner @parameter.outer) (function_arguments ","? @parameter.outer . (_) @parameter.inner @parameter.outer .) (function_arguments (_) @parameter.inner @parameter.outer . "," @parameter.outer) (multioutput_variable ","? @parameter.outer . (_) @parameter.inner @parameter.outer .) (multioutput_variable (_) @parameter.inner @parameter.outer . "," @parameter.outer) (try_statement (block) @conditional.inner) @conditional.outer (catch_clause (identifier) @parameter.inner @parameter.outer) (catch_clause (block) @conditional.inner) (class_definition) @class.outer (number) @number.inner (_ (return_statement) @return.inner @return.outer) (comment) @comment.outer (matrix (row) @parameter.outer) (cell (row) @parameter.outer) (row (_) @parameter.inner) (assignment left: (_) @assignment.lhs (_) @assignment.rhs) @assignment.outer (superclasses "&"? @parameter.outer . (_) @parameter.inner @parameter.outer .) (superclasses (_) @parameter.inner @parameter.outer . "&" @parameter.outer) (enum (identifier) @parameter.inner @parameter.outer) (property name: (_) @parameter.outer @parameter.inner) (enum ","? @parameter.outer . (_) @parameter.inner @parameter.outer .) (enum (_) @parameter.inner @parameter.outer . "," @parameter.outer) (validation_functions ","? @parameter.outer . (_) @parameter.inner @parameter.outer .) (validation_functions (_) @parameter.inner @parameter.outer . "," @parameter.outer) (dimensions ","? @parameter.outer . (_) @parameter.inner @parameter.outer .) (dimensions (_) @parameter.inner @parameter.outer . "," @parameter.outer) (attributes ","? @parameter.outer . (_) @parameter.inner @parameter.outer .) (attributes (_) @parameter.inner @parameter.outer . "," @parameter.outer) ================================================ FILE: queries/nasm/textobjects.scm ================================================ ; adapted from https://github.com/naclsn/tree-sitter-nasm/blob/main/queries/textobjects.scm (preproc_multiline_macro body: (body) @function.inner) @function.outer (struc_declaration body: (struc_declaration_body) @class.inner) @class.outer (struc_instance body: (struc_instance_body) @class.inner) @class.outer (preproc_function_def_parameters (word) @parameter.inner) (call_syntax_arguments (_) @parameter.inner) (operand) @parameter.inner (comment) @comment.outer ================================================ FILE: queries/nim/textobjects.scm ================================================ ; ============================================================================== ; @attribute.inner ; @attribute.outer ; ============================================================================== ; @function.inner ; @function.outer (proc_declaration body: (statement_list) @function.inner) @function.outer (func_declaration body: (statement_list) @function.inner) @function.outer (method_declaration body: (statement_list) @function.inner) @function.outer (iterator_declaration body: (statement_list) @function.inner) @function.outer (converter_declaration body: (statement_list) @function.inner) @function.outer (template_declaration body: (statement_list) @function.inner) @function.outer (macro_declaration body: (statement_list) @function.inner) @function.outer (proc_expression body: (statement_list) @function.inner) @function.outer (func_expression body: (statement_list) @function.inner) @function.outer (iterator_expression body: (statement_list) @function.inner) @function.outer ; ============================================================================== ; @class.inner ; @class.outer ; NOTE: seems pointless to handle just object declarations differently ; ============================================================================== ; @conditional.inner ; @conditional.outer [ (if) (when) (conditional_declaration) (case) (variant_declaration) (elif_branch) (else_branch) (of_branch) ] @conditional.outer (if condition: (_) @conditional.inner) (if consequence: (statement_list) @conditional.inner) (when condition: (_) @conditional.inner) (when consequence: (statement_list) @conditional.inner) (conditional_declaration condition: (_) @conditional.inner) (conditional_declaration consequence: (field_declaration_list) @conditional.inner) (elif_branch condition: (_) @conditional.inner) (elif_branch consequence: [ (statement_list) (field_declaration_list) ] @conditional.inner) (else_branch consequence: [ (statement_list) (field_declaration_list) ] @conditional.inner) (case value: (_) @conditional.inner) (variant_declaration (variant_discriminator_declaration) @conditional.inner) (of_branch values: (expression_list) @conditional.inner) (of_branch consequence: [ (statement_list) (field_declaration_list) ] @conditional.inner) ; ============================================================================== ; @loop.inner ; @loop.outer [ (for) (while) ] @loop.outer (for left: (_) @loop.inner right: (_) @loop.inner) (for body: (statement_list) @loop.inner) (while condition: (_) @loop.inner) (while body: (statement_list) @loop.inner) ; ============================================================================== ; @call.inner ; @call.outer (call (argument_list) @call.inner) @call.outer ; NOTE: parenthesis are included in @call.inner ; ============================================================================== ; @block.inner ; @block.outer (case ":" _+ @block.inner) @block.outer (object_declaration (field_declaration_list) @block.inner) @block.outer (tuple_type (field_declaration_list . "[" _+ @block.inner "]" .)) @block.outer (enum_declaration . "enum" _+ @block.inner) @block.outer (using_section . "using" _+ @block.inner) @block.outer (const_section . "const" _+ @block.inner) @block.outer (let_section . "let" _+ @block.inner) @block.outer (var_section . "var" _+ @block.inner) @block.outer (type_section . "type" _+ @block.inner) (_ (statement_list) @block.inner) @block.outer ; ============================================================================== ; @parameter.inner ; @parameter.outer ; parameters when declaring (parameter_declaration_list [ "," ";" ] @parameter.outer . (parameter_declaration) @parameter.inner @parameter.outer) (parameter_declaration_list . (parameter_declaration) @parameter.inner @parameter.outer . [ "," ";" ]? @parameter.outer) ; generic parameters when declaring (generic_parameter_list "," @parameter.outer . (parameter_declaration) @parameter.inner @parameter.outer) (generic_parameter_list . (parameter_declaration) @parameter.inner @parameter.outer . ","? @parameter.outer) ; arguments when calling (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; containers (array_construction "," @parameter.outer . (_) @parameter.inner @parameter.outer) (array_construction . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (tuple_construction "," @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple_construction . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (curly_construction "," @parameter.outer . (_) @parameter.inner @parameter.outer) (curly_construction . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; generic arguments when calling ; subscript operator ; generic types (bracket_expression right: (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer)) (bracket_expression right: (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer)) ; import x,x ; import except x,x ; include x,x ; from import x,x ; bind x,x ; mixin x,x ; case of x,x ; try except x,x (expression_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (expression_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; pragmas (pragma_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (pragma_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; variable_declaration ; for ; identifier_declaration `x,y: type = value` (symbol_declaration_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (symbol_declaration_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; infix_expression (infix_expression operator: (_) @parameter.outer right: (_) @parameter.inner @parameter.outer) (infix_expression left: (_) @parameter.inner @parameter.outer operator: (_) @parameter.outer) ; tuple_type inline (field_declaration_list [ "," ";" ] @parameter.outer . (field_declaration) @parameter.inner @parameter.outer) (field_declaration_list . (field_declaration) @parameter.inner @parameter.outer . [ "," ";" ]? @parameter.outer) ; enum (enum_declaration "," @parameter.outer . (enum_field_declaration) @parameter.inner @parameter.outer) (enum_declaration . (enum_field_declaration) @parameter.inner @parameter.outer . ","? @parameter.outer) ; tuple_deconstruct_declaration (tuple_deconstruct_declaration "," @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple_deconstruct_declaration . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; concept parameter list ; concept refinement list (parameter_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (parameter_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (refinement_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (refinement_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; dot_generic_call `v.call[:type, type]() (generic_argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (generic_argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; ============================================================================== ; @regex.inner ; @regex.outer ; ============================================================================== ; @comment.inner ; @comment.outer (comment (comment_content) @comment.inner) @comment.outer (block_comment (comment_content) @comment.inner) @comment.outer (documentation_comment (comment_content) @comment.inner) @comment.outer (block_documentation_comment (comment_content) @comment.inner) @comment.outer ; ============================================================================== ; @assignment.inner ; @assignment.outer ; @assignment.lhs ; @assignment.rhs (variable_declaration (symbol_declaration_list) @assignment.lhs type: (type_expression)? @assignment.lhs value: (_) @assignment.rhs @assignment.inner) @assignment.outer (type_declaration (type_symbol_declaration) @assignment.lhs . "=" . (_) @assignment.rhs @assignment.inner) @assignment.outer (assignment left: (_) @assignment.lhs right: (_) @assignment.rhs @assignment.inner) @assignment.outer ; default parameter in proc decl ; keyword argument in call ; array construction (colon_expression left: (_) @assignment.lhs right: (_) @assignment.rhs @assignment.inner) @assignment.outer ; object construction ; tuple construction ; table construction (equal_expression left: (_) @assignment.lhs right: (_) @assignment.rhs @assignment.inner) @assignment.outer ; object declaration fields ; tuple declaration fields (field_declaration (symbol_declaration_list) @assignment.lhs type: (type_expression)? @assignment.lhs value: (_)? @assignment.rhs @assignment.inner) @assignment.outer ; enum types (enum_field_declaration (symbol_declaration) @assignment.lhs "="? value: (_)? @assignment.rhs @assignment.inner) @assignment.outer ; ============================================================================== ; @return.inner ; @return.outer (return_statement (_) @return.inner) @return.outer ; ============================================================================== ; @statement.outer [ ; simple (import_statement) (import_from_statement) (export_statement) (include_statement) (discard_statement) (return_statement) (raise_statement) (yield_statement) (break_statement) (continue_statement) (assembly_statement) (bind_statement) (mixin_statement) (pragma_statement) ; complex (while) (static_statement) (defer) ; declarations (proc_declaration) (func_declaration) (method_declaration) (iterator_declaration) (macro_declaration) (template_declaration) (converter_declaration) (using_section) (const_section) (let_section) (var_section) (type_section) ; expression statements (block) (if) (when) (case) (try) (for) (assignment) ; NOTE: not including ; simple_expression, call, infix_expression, prefix_expression ; because it would confusing ] @statement.outer ; ============================================================================== ; @scopename.inner ; ============================================================================== ; @number.inner [ (integer_literal) (float_literal) ] @number.inner ================================================ FILE: queries/nix/textobjects.scm ================================================ ; named function (binding (function_expression)) @function.outer ; anonymous function (function_expression (_) ; argument (_) @function.inner) @function.outer (function_expression (formals (formal) @parameter.inner)) (function_expression (_) @parameter.outer (_)) (comment) @comment.outer (if_expression (_) @conditional.inner) @conditional.outer [ (integer_expression) (float_expression) ] @number.inner ================================================ FILE: queries/ocaml/textobjects.scm ================================================ (value_definition (let_binding ; let f x = 1 but not let x = 1 (parameter)+ body: (_) @function.inner)) @function.outer (value_definition (let_binding ; let f = function | A | B -> body body: (function_expression) @function.inner)) @function.outer (value_definition (let_binding ; let f = fun x -> body body: (fun_expression) @function.inner)) @function.outer ; standalone function expression, e.g. List.iter ~f:(function | A | B -> body) (parenthesized_expression (function_expression) @function.inner) @function.outer ; standalone function expression, e.g. List.iter ~f:(fun x -> body) (parenthesized_expression (fun_expression) @function.inner) @function.outer (method_definition body: (_) @function.inner) @function.outer ; let pattern = body (also matches let f x = expr due to grammar limits) ; Since we want @assignment.inner to match both pattern and body we have to split it into two: (value_definition (let_binding pattern: (_) @assignment.lhs @assignment.inner)) @assignment.outer (value_definition (let_binding body: (_) @assignment.rhs @assignment.inner)) ; module M = struct ... end (module_definition (module_binding body: (structure) @class.inner)) @class.outer ; struct ... end (structure (_structure_item)+ @block.inner) @block.outer (class_definition (class_binding body: (_) @class.inner)) @class.outer (for_expression (do_clause (_) @loop.inner)) @loop.outer (while_expression (do_clause (_) @loop.inner)) @loop.outer (if_expression condition: (_) (then_clause (_) @conditional.inner) (else_clause (_) @conditional.inner)) @conditional.outer (if_expression condition: (_) (then_clause (_) @conditional.inner)) @conditional.outer (function_expression (match_case)+ @conditional.inner) @conditional.outer (match_expression (match_case)+ @conditional.inner) @conditional.outer (comment) @comment.outer (parameter) @parameter.outer (application_expression argument: (_) @parameter.outer) @call.outer (application_expression argument: (_)+ @call.inner) ; parenthesized selections are handled well by vi ================================================ FILE: queries/odin/textobjects.scm ================================================ ; procedures (procedure_declaration (_ (block . "{" _+ @function.inner "}"))) @function.outer ; returns (return_statement (_)? @return.inner) @return.outer ; call function in module (member_expression (call_expression)) @call.outer ; call arguments (call_expression function: (_) . argument: (_) @call.inner argument: (_) @call.inner .) ; block (block . "{" _+ @block.inner "}") @block.outer ; classes (struct_declaration "{" _+ @class.inner "}") @class.outer (union_declaration "{" _+ @class.inner "}") @class.outer (enum_declaration "{" _+ @class.inner "}") @class.outer ; comments (comment) @comment.outer (block_comment) @comment.outer ; assignment ; works also for multiple targets in lhs. ex. 'res, ok := get_res()' (assignment_statement . (_) @assignment.lhs (_) @assignment.lhs . (_) @assignment.rhs @assignment.inner .) @assignment.outer ; attribute (attribute (_) @attribute.inner) @attribute.outer ; number (number) @number.inner ; parameters (parameters "," @parameter.outer . (parameter) @parameter.inner @parameter.outer) (parameters . (parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (call_expression function: (_) "," @parameter.outer . argument: (_) @parameter.inner @parameter.outer) (call_expression function: (_) . argument: (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ================================================ FILE: queries/perl/textobjects.scm ================================================ (comment) @comment.outer (quoted_regexp) @regex.outer (match_regexp) @regex.outer ================================================ FILE: queries/php/textobjects.scm ================================================ ; functions (function_definition body: (compound_statement . "{" _+ @function.inner "}")) (function_definition) @function.outer (anonymous_function body: (compound_statement . "{" _+ @function.inner "}")) (anonymous_function) @function.outer ; methods (method_declaration body: (compound_statement . "{" _+ @function.inner "}")) (method_declaration) @function.outer ; traits (trait_declaration body: (declaration_list . "{" _+ @class.inner "}")) (trait_declaration) @class.outer ; interfaces (interface_declaration body: (declaration_list . "{" _+ @class.inner "}")) (interface_declaration) @class.outer ; enums (enum_declaration body: (enum_declaration_list . "{" _+ @class.inner "}")) (enum_declaration) @class.outer ; classes (class_declaration body: (declaration_list . "{" _+ @class.inner "}")) (class_declaration) @class.outer ; loops (for_statement (compound_statement . "{" _+ @loop.inner "}")) (for_statement) @loop.outer (foreach_statement body: (compound_statement . "{" _+ @loop.inner "}")) (foreach_statement) @loop.outer (while_statement body: (compound_statement . "{" _+ @loop.inner "}")) (while_statement) @loop.outer (do_statement body: (compound_statement . "{" _+ @loop.inner "}")) (do_statement) @loop.outer ; conditionals (switch_statement body: (switch_block . "{" _+ @conditional.inner "}")) (switch_statement) @conditional.outer (if_statement body: (compound_statement . "{" _+ @conditional.inner "}")) (if_statement) @conditional.outer (else_clause body: (compound_statement . "{" _+ @conditional.inner "}")) (else_if_clause body: (compound_statement . "{" _+ @conditional.inner "}")) ; blocks (_ (switch_block) @block.inner) @block.outer ; parameters (arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (formal_parameters "," @parameter.outer . (_) @parameter.inner @parameter.outer) (formal_parameters . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; comments (comment) @comment.outer ; call (function_call_expression) @call.outer (member_call_expression) @call.outer (nullsafe_member_call_expression) @call.outer (scoped_call_expression) @call.outer (function_call_expression arguments: (arguments . "(" _+ @call.inner ")")) (member_call_expression arguments: (arguments . "(" _+ @call.inner ")")) (nullsafe_member_call_expression arguments: (arguments . "(" _+ @call.inner ")")) (scoped_call_expression arguments: (arguments . "(" _+ @call.inner ")")) ; statement [ (expression_statement) (declare_statement) (return_statement) (namespace_use_declaration) (namespace_definition) (if_statement) (empty_statement) (switch_statement) (while_statement) (do_statement) (for_statement) (foreach_statement) (goto_statement) (continue_statement) (break_statement) (try_statement) (echo_statement) (unset_statement) (const_declaration) (function_definition) (class_declaration) (interface_declaration) (trait_declaration) (enum_declaration) (global_declaration) (function_static_declaration) ] @statement.outer ================================================ FILE: queries/php_only/textobjects.scm ================================================ ; inherits php ================================================ FILE: queries/python/textobjects.scm ================================================ (decorated_definition (function_definition)) @function.outer (function_definition body: (block)? @function.inner) @function.outer (decorated_definition (class_definition)) @class.outer (class_definition body: (block)? @class.inner) @class.outer (while_statement body: (block)? @loop.inner) @loop.outer (for_statement body: (block)? @loop.inner) @loop.outer (if_statement alternative: (_ (_) @conditional.inner)?) @conditional.outer (if_statement consequence: (block)? @conditional.inner) (if_statement condition: (_) @conditional.inner) (_ (block) @block.inner) @block.outer ; leave space after comment marker if there is one ((comment) @comment.inner @comment.outer (#match? @comment.outer "# .*")) ; else remove everything accept comment marker ((comment) @comment.inner @comment.outer) (block (_) @statement.outer) (module (_) @statement.outer) (call) @call.outer (call arguments: (argument_list . "(" _+ @call.inner ")")) (return_statement (_)? @return.inner) @return.outer ; Parameters (parameters "," @parameter.outer . [ (identifier) (tuple) (typed_parameter) (default_parameter) (typed_default_parameter) (dictionary_splat_pattern) (list_splat_pattern) ] @parameter.inner @parameter.outer) (parameters . [ (identifier) (tuple) (typed_parameter) (default_parameter) (typed_default_parameter) (dictionary_splat_pattern) (list_splat_pattern) ] @parameter.inner @parameter.outer . ","? @parameter.outer) (lambda_parameters "," @parameter.outer . [ (identifier) (tuple) (typed_parameter) (default_parameter) (typed_default_parameter) (dictionary_splat_pattern) (list_splat_pattern) ] @parameter.inner @parameter.outer) (lambda_parameters . [ (identifier) (tuple) (typed_parameter) (default_parameter) (typed_default_parameter) (dictionary_splat_pattern) (list_splat_pattern) ] @parameter.inner @parameter.outer . ","? @parameter.outer) (tuple "," @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple "(" . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (dictionary . (pair) @parameter.inner @parameter.outer . ","? @parameter.outer) (dictionary "," @parameter.outer . (pair) @parameter.inner @parameter.outer) (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) (subscript "[" . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (subscript "," @parameter.outer . (_) @parameter.inner @parameter.outer) (import_statement . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (import_statement "," @parameter.outer . (_) @parameter.inner @parameter.outer) (import_from_statement "," @parameter.outer . (_) @parameter.inner @parameter.outer) (import_from_statement "import" . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) [ (integer) (float) ] @number.inner (assignment left: (_) @assignment.lhs right: (_) @assignment.inner @assignment.rhs) @assignment.outer (assignment left: (_) @assignment.inner) (augmented_assignment left: (_) @assignment.lhs right: (_) @assignment.inner @assignment.rhs) @assignment.outer (augmented_assignment left: (_) @assignment.inner) ; TODO: exclude comments using the future negate syntax from tree-sitter ================================================ FILE: queries/ql/textobjects.scm ================================================ ; class textobject (dataclass (typeExpr) (_) @class.inner) @class.outer ; function textobject (charpred (className) (_) @function.inner) @function.outer (memberPredicate (body) @function.inner) @function.outer (classlessPredicate (body) @function.inner) @function.outer ; scope name textobject (dataclass name: (className) @scopename.inner) (classlessPredicate name: (predicateName) @scopename.inner) (memberPredicate name: (predicateName) @scopename.inner) (charpred (className) @scopename.inner) ================================================ FILE: queries/query/textobjects.scm ================================================ (comment) @comment.outer [ (named_node) (grouping) (list) ] @block.outer (program [ (named_node) (grouping) (list) ] @statement.outer) (parameters (_) @parameter.inner) ================================================ FILE: queries/r/textobjects.scm ================================================ ; block ; call (call) @call.outer (arguments) @call.inner ; class ; comment (comment) @comment.outer ; conditional (if_statement condition: (_)? @conditional.inner) @conditional.outer ; function (function_definition [ (call) (binary_operator) (braced_expression) ] @function.inner) @function.outer ; loop [ (while_statement) (repeat_statement) (for_statement) ] @loop.outer (while_statement body: (_) @loop.inner) (repeat_statement body: (_) @loop.inner) (for_statement body: (_) @loop.inner) ; statement (braced_expression (_) @statement.outer) (program (_) @statement.outer) ; parameter (parameters (comma) @parameter.outer . (_) @parameter.inner @parameter.outer) (parameters . (_) @parameter.inner @parameter.outer . (comma)? @parameter.outer) (arguments (comma)? @parameter.outer . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner @parameter.outer . (comma)? @parameter.outer) ; number (float) @number.inner ; assignment (binary_operator lhs: (_) @assignment.inner @assignment.lhs rhs: (_) @assignment.rhs) @assignment.outer ================================================ FILE: queries/readline/textobjects.scm ================================================ (variable_setting) @statement.outer (comment) @comment.outer ((comment) @comment.inner) [ (alternative) (consequence) (test) ] @conditional.inner (conditional_construct) @conditional.outer [ (number_value) (version_number) ] @number.inner ================================================ FILE: queries/rst/textobjects.scm ================================================ (directive body: (body) @function.inner) @function.outer (section (title) @class.inner) @class.outer (transition) @class.outer [ (bullet_list) (enumerated_list) (definition_list) (field_list) (literal_block) (line_block) (block_quote) (doctest_block) ] @block.outer (footnote body: (body) @block.inner) @block.outer (citation body: (body) @block.inner) @block.outer (target link: (link) @block.inner) @block.outer (substitution_definition body: (directive) @block.inner) @block.outer (comment) @comment.outer ================================================ FILE: queries/ruby/textobjects.scm ================================================ ; @functions (method body: (body_statement) @function.inner) (method) @function.outer (singleton_method body: (body_statement) @function.inner) (singleton_method) @function.outer ; @blocks (block body: (block_body) @block.inner) (block) @block.outer (do_block body: (body_statement) @block.inner) (do_block) @block.outer ; @classes (class body: (body_statement) @class.inner) (class) @class.outer (module body: (body_statement) @class.inner) (module) @class.outer (singleton_class body: (body_statement) @class.inner) (singleton_class) @class.outer ; @parameters (block_parameters (_) @parameter.inner) (method_parameters (_) @parameter.inner) (lambda_parameters (_) @parameter.inner) (argument_list (_) @parameter.inner) [ (block_parameters) (method_parameters) (lambda_parameters) (argument_list) ] @parameter.outer ; @comment (comment) @comment.outer ; @regex (regex (string_content) @regex.inner) @regex.outer ================================================ FILE: queries/rust/textobjects.scm ================================================ ; functions (function_signature_item) @function.outer (function_item) @function.outer (function_item body: (block . "{" _+ @function.inner "}")) ; quantifies as class(es) (struct_item) @class.outer (struct_item body: (field_declaration_list . "{" _+ @class.inner "}")) (enum_item) @class.outer (enum_item body: (enum_variant_list . "{" _+ @class.inner "}")) (union_item) @class.outer (union_item body: (field_declaration_list . "{" _+ @class.inner "}")) (trait_item) @class.outer (trait_item body: (declaration_list . "{" _+ @class.inner "}")) (impl_item) @class.outer (impl_item body: (declaration_list . "{" _+ @class.inner "}")) (mod_item) @class.outer (mod_item body: (declaration_list . "{" _+ @class.inner "}")) ; conditionals (if_expression alternative: (_ (_) @conditional.inner)?) @conditional.outer (if_expression alternative: (else_clause (block) @conditional.inner)) (if_expression condition: (_) @conditional.inner) (if_expression consequence: (block) @conditional.inner) (match_arm (_)) @conditional.inner (match_expression) @conditional.outer ; loops (loop_expression body: (block . "{" _+ @loop.inner "}")) @loop.outer (while_expression body: (block . "{" _+ @loop.inner "}")) @loop.outer (for_expression body: (block . "{" _+ @loop.inner "}")) @loop.outer ; blocks (block (_)* @block.inner) @block.outer (unsafe_block (_)* @block.inner) @block.outer ; calls (macro_invocation) @call.outer (macro_invocation (token_tree . "(" _+ @call.inner ")")) (call_expression) @call.outer (call_expression arguments: (arguments . "(" _+ @call.inner ")")) ; returns (return_expression (_)? @return.inner) @return.outer ; statements (block (_) @statement.outer) ; comments (line_comment) @comment.outer (block_comment) @comment.outer ; parameter (parameters "," @parameter.outer . [ (self_parameter) (parameter) (type_identifier) ] @parameter.inner @parameter.outer) (parameters . [ (self_parameter) (parameter) (type_identifier) ] @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (parameters [ (self_parameter) (parameter) (type_identifier) ] @parameter.outer . "," @parameter.outer .) (type_parameters "," @parameter.outer . (_) @parameter.inner @parameter.outer) (type_parameters . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (type_parameters (_) @parameter.outer . "," @parameter.outer .) (tuple_pattern "," @parameter.outer . (identifier) @parameter.inner @parameter.outer) (tuple_pattern . (identifier) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (tuple_pattern (identifier) @parameter.outer . "," @parameter.outer .) (tuple_struct_pattern "," @parameter.outer . (identifier) @parameter.inner @parameter.outer) (tuple_struct_pattern . (identifier) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (tuple_struct_pattern (identifier) @parameter.outer . "," @parameter.outer .) (tuple_expression "," @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple_expression . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (tuple_expression (_) @parameter.outer . "," @parameter.outer .) (tuple_type "," @parameter.outer . (_) @parameter.inner @parameter.outer) (tuple_type . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (tuple_type (_) @parameter.outer . "," @parameter.outer .) (struct_item body: (field_declaration_list "," @parameter.outer . (_) @parameter.inner @parameter.outer)) (struct_item body: (field_declaration_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer)) ; last element, with trailing comma (struct_item body: (field_declaration_list (_) @parameter.outer . "," @parameter.outer .)) (struct_expression body: (field_initializer_list "," @parameter.outer . (_) @parameter.inner @parameter.outer)) (struct_expression body: (field_initializer_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer)) ; last element, with trailing comma (struct_expression body: (field_initializer_list (_) @parameter.outer . "," @parameter.outer .)) (closure_parameters "," @parameter.outer . (_) @parameter.inner @parameter.outer) (closure_parameters . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (closure_parameters (_) @parameter.outer . "," @parameter.outer .) (arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (arguments (_) @parameter.outer . "," @parameter.outer .) (type_arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (type_arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (type_arguments (_) @parameter.outer . "," @parameter.outer .) (token_tree "," @parameter.outer . (_) @parameter.inner @parameter.outer) (token_tree . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; last element, with trailing comma (token_tree (_) @parameter.outer . "," @parameter.outer .) (scoped_use_list list: (use_list "," @parameter.outer . (_) @parameter.inner @parameter.outer)) (scoped_use_list list: (use_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer)) ; last element, with trailing comma (scoped_use_list list: (use_list (_) @parameter.outer . "," @parameter.outer .)) [ (integer_literal) (float_literal) ] @number.inner (let_declaration pattern: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (let_declaration pattern: (_) @assignment.inner) (assignment_expression left: (_) @assignment.lhs right: (_) @assignment.inner @assignment.rhs) @assignment.outer (assignment_expression left: (_) @assignment.inner) ================================================ FILE: queries/scala/textobjects.scm ================================================ (class_definition body: (template_body)? @class.inner) @class.outer (object_definition body: (template_body)? @class.inner) @class.outer (function_definition body: [ (indented_block) (expression) (indented_cases) (block) ] @function.inner) @function.outer (parameter name: (identifier) @parameter.inner) @parameter.outer (class_parameter name: (identifier) @parameter.inner) @parameter.outer (case_clause body: (_) @conditional.inner) @conditional.outer (comment) @comment.outer ================================================ FILE: queries/scss/textobjects.scm ================================================ ; inherits: css ================================================ FILE: queries/slang/textobjects.scm ================================================ ; inherits: hlsl (template_declaration (interface_specifier)) @class.outer (template_declaration (extension_specifier)) @class.outer (extension_specifier body: (_) @class.inner) @class.outer (interface_specifier body: (_) @class.inner) @class.outer ================================================ FILE: queries/supercollider/textobjects.scm ================================================ ; assignment (variable_definition name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (function_definition name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer ; block (code_block (_)* @block.inner) @block.outer ; class (class_def (class_def_body) @class.inner) @class.outer ; call (function_call arguments: (_ . "(" _+ @call.inner ")")?) @call.outer ; comment (line_comment) @comment.outer (block_comment) @comment.outer ; conditional: (function_call name: (_) @_name (#eq? @_name "if") arguments: (parameter_call_list (_) @conditional.inner)?) @conditional.outer ; function ((function_block) @function.inner @function.outer) ; loop (function_call name: (identifier) @_fname (#eq? @_fname "while") arguments: (parameter_call_list (_) @loop.inner)?) @loop.outer (function_call name: (identifier) @_fname (#eq? @_fname "for") arguments: (parameter_call_list (_) @loop.inner .)?) @loop.outer (function_call name: (identifier) @_fname (#eq? @_fname "forBy") arguments: (parameter_call_list (_) @loop.inner .)?) @loop.outer ; number (number) @number.inner ;parameters (parameter_call_list (_) @parameter.inner @parameter.outer . (",")? @parameter.outer) (parameter_call_list "," @parameter.outer . (_) @parameter.inner @parameter.outer .) (parameter_list (_) @parameter.inner @parameter.outer . (",")? @parameter.outer) (parameter_list "," @parameter.outer . (_) @parameter.inner @parameter.outer .) (collection (_) @parameter.inner @parameter.outer . (",")? @parameter.outer) (collection "," @parameter.outer . (_) @parameter.inner @parameter.outer .) ; return (return_statement (_) @return.inner) @return.outer ================================================ FILE: queries/svelte/textobjects.scm ================================================ ; inherits: html ; Svelte-specific text objects ; based on grammar defined at ; https://github.com/tree-sitter-grammars/tree-sitter-svelte ; if block (if_statement) @block.outer @conditional.outer (if_statement (if_start) . _+ @block.inner @conditional.inner . (if_end)) ; each block (each_statement) @block.outer @loop.outer (each_statement (each_start) . _+ @block.inner @loop.inner . (each_end)) ; key block (key_statement) @block.outer (key_statement (key_start) . _+ @block.inner . (key_end)) ; await block (await_statement) @block.outer (await_statement (await_start) . _+ @block.inner . (await_end)) ; snippet block (snippet_statement) @block.outer (snippet_statement (snippet_start) . _+ @block.inner . (snippet_end)) ================================================ FILE: queries/swift/textobjects.scm ================================================ (class_declaration body: (class_body . "{" _+ @class.inner "}")) @class.outer (class_declaration body: (enum_class_body . "{" _+ @class.inner "}")) @class.outer (function_declaration body: (function_body . "{" _+ @function.inner "}")) @function.outer (lambda_literal ("{" _+ @function.inner "}")) @function.outer (call_suffix (value_arguments . "(" _+ @call.inner ")")) @call.outer (value_argument value: (_) @parameter.inner) @parameter.outer (comment) @comment.outer (multiline_comment) @comment.outer ================================================ FILE: queries/systemverilog/textobjects.scm ================================================ (function_declaration (function_body_declaration (tf_port_list) . _+ @function.inner . "endfunction")) @function.outer (task_declaration (task_body_declaration (tf_port_list) . _+ @function.inner . "endtask")) @function.outer [ (seq_block) (generate_block) ] @block.outer (seq_block "begin" (simple_identifier)? . _+ @block.inner . "end") (generate_block "begin" (simple_identifier)? . _+ @block.inner . "end") [ (one_line_comment) (block_comment) ] @comment.outer ================================================ FILE: queries/tact/textobjects.scm ================================================ ; See: https://github.com/nvim-treesitter/nvim-treesitter-textobjects#built-in-textobjects ; function.inner & outer ; ---------------------- ; global (global_function body: (_)) @function.outer (global_function body: (function_body . "{" _+ @function.inner "}")) ; init (init_function body: (_)) @function.outer (init_function body: (function_body . "{" _+ @function.inner "}")) ; bounced (bounced_function body: (_)) @function.outer (bounced_function body: (function_body . "{" _+ @function.inner "}")) ; receive (receive_function body: (_)) @function.outer (receive_function body: (function_body . "{" _+ @function.inner "}")) ; external (external_function body: (_)) @function.outer (external_function body: (function_body . "{" _+ @function.inner "}")) ; contract/trait function (storage_function body: (_)) @function.outer (storage_function body: (function_body . "{" _+ @function.inner "}")) ; class.inner & outer ; ------------------- (struct) @class.outer (struct body: (struct_body . "{" _+ @class.inner "}")) (message) @class.outer (message body: (message_body . "{" _+ @class.inner "}")) (contract) @class.outer (contract body: (contract_body . "{" _+ @class.inner "}")) (trait) @class.outer (trait body: (trait_body . "{" _+ @class.inner "}")) ; attribute.inner & outer ; ----------------------- ("@name" "(" func_name: (func_identifier) @attribute.inner ")") @attribute.outer (contract_attributes ("@interface" "(" (string) @attribute.inner ")") @attribute.outer) (trait_attributes ("@interface" "(" (string) @attribute.inner ")") @attribute.outer) (trait_attributes ("@interface" "(" (string) @attribute.inner ")") @attribute.outer) ; loop.inner & outer ; ------------------ (while_statement) @loop.outer (while_statement body: (block_statement . "{" _+ @loop.inner "}")) (repeat_statement) @loop.outer (repeat_statement body: (block_statement . "{" _+ @loop.inner "}")) (do_until_statement) @loop.outer (do_until_statement body: (block_statement . "{" _+ @loop.inner "}")) (foreach_statement) @loop.outer (foreach_statement body: (block_statement . "{" _+ @loop.inner "}")) ; conditional.inner & outer ; ------------------------- (if_statement) @conditional.outer (if_statement consequence: (block_statement . "{" _+ @conditional.inner "}")) (if_statement alternative: (else_clause (block_statement . "{" _+ @conditional.inner "}"))) ; block.inner & outer ; ------------------- (_ (block_statement) @block.inner) @block.outer ; call.inner & outer ; ------------------ (method_call_expression) @call.outer (method_call_expression arguments: (argument_list . "(" _+ @call.inner ")")) (static_call_expression) @call.outer (static_call_expression arguments: (argument_list . "(" _+ @call.inner ")")) (instance_expression) @call.outer (instance_expression arguments: (instance_argument_list . "{" _+ @call.inner "}")) (initOf name: (identifier) @call.outer arguments: (argument_list . "(" _+ @call.inner ")") @call.outer) ; return.inner & outer ; -------------------- (return_statement (_) @return.inner) @return.outer ; number.inner ; ------------ (integer) @number.inner ; parameter.inner & outer ; ----------------------- ; second and following (parameter_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) ; first (parameter_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; second and following (argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) ; first (argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; second and following (instance_argument_list "," @parameter.outer . (_) @parameter.inner @parameter.outer) ; first (instance_argument_list . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ; single parameter (receive_function parameter: (_) @parameter.inner @parameter.outer) (bounced_function parameter: (_) @parameter.inner @parameter.outer) (external_function parameter: (_) @parameter.inner @parameter.outer) ; assignment.inner & outer w/ lhs & rhs ; ------------------------------------- (let_statement name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (storage_variable name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (global_constant name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (storage_constant name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer (field name: (_) @assignment.lhs value: (_) @assignment.inner @assignment.rhs) @assignment.outer ; comment.inner & outer ; --------------------- (comment) @comment.inner @comment.outer ; quantified captures aren't supported yet: ; (comment)+ @comment.outer ================================================ FILE: queries/terraform/textobjects.scm ================================================ ; inherits: hcl ================================================ FILE: queries/toml/textobjects.scm ================================================ [ (integer) (float) ] @number.inner (table (pair) @parameter.inner @parameter.outer) (inline_table "," @parameter.outer . (_) @parameter.inner @parameter.outer) (inline_table . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (array "," @parameter.outer . (_) @parameter.inner @parameter.outer) (array . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (comment) @comment.outer ================================================ FILE: queries/tsx/textobjects.scm ================================================ ; inherits: typescript,jsx ================================================ FILE: queries/twig/textobjects.scm ================================================ ; comments (comment) @comment.outer ; statement (statement_directive) @statement.outer ; @parameter (arguments "," @parameter.outer . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) (parameters "," @parameter.outer . (_) @parameter.inner @parameter.outer) (parameters . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ================================================ FILE: queries/typescript/textobjects.scm ================================================ ; inherits: ecma (interface_declaration) @class.outer (interface_declaration body: (interface_body . "{" _+ @class.inner "}")) (type_alias_declaration) @class.outer (type_alias_declaration value: (object_type . "{" _+ @class.inner "}")) (enum_declaration) @class.outer (enum_declaration body: (enum_body . "{" _+ @class.inner "}")) ; type, interface items as @parameter ; 1. parameter.inner (property_signature) @parameter.inner ; 2. parameter.outer: Only one element, no comma (object_type . (property_signature) @parameter.outer .) (interface_body . (property_signature) @parameter.outer .) ; 3. parameter.outer: Comma/semicolon before or after [ (object_type [ "," ";" ] @parameter.outer . (property_signature) @parameter.outer) (interface_body [ "," ";" ] @parameter.outer . (property_signature) @parameter.outer) ] [ (object_type . (property_signature) @parameter.outer . [ "," ";" ] @parameter.outer) (interface_body . (property_signature) @parameter.outer . [ "," ";" ] @parameter.outer) ] ; last element with trailing comma/semicolon [ (object_type (property_signature) @parameter.outer . [ "," ";" ] @parameter.outer .) (interface_body (property_signature) @parameter.outer . [ "," ";" ] @parameter.outer .) ] ================================================ FILE: queries/v/textobjects.scm ================================================ ; assignment [ (var_declaration var_list: (_) @assignment.lhs expression_list: (_)* @assignment.rhs) (assignment_statement left: (_) @assignment.lhs right: (_)* @assignment.rhs) ] [ (var_declaration var_list: (_) @assignment.inner) (assignment_statement left: (_) @assignment.inner) ] [ (var_declaration expression_list: (_) @assignment.inner) (assignment_statement right: (_) @assignment.inner) ] ; block (_ (block . "{" _+ @block.inner "}")) @block.outer ; call (call_expression) @call.outer (call_expression arguments: (argument_list . "(" _+ @call.inner ")")) ; class: structs (struct_declaration ("{" _+ @class.inner "}")) (struct_declaration) @class.outer ; comment ; leave space after comment marker if there is one ((line_comment) @comment.inner @comment.outer (#match? @comment.outer "// .*")) ; else remove everything accept comment marker ((line_comment) @comment.inner @comment.outer) (block_comment) @comment.inner @comment.outer ; conditional (if_expression block: (block . "{" _+ @conditional.inner "}")?) @conditional.outer ; function (function_declaration body: (block . "{" _+ @function.inner "}")) (function_declaration) @function.outer ; loop (for_statement body: (block . "{" _+ @loop.inner "}")?) @loop.outer [ (int_literal) (float_literal) ] @number.inner ; parameter (parameter_list "," @parameter.outer . (parameter_declaration) @parameter.inner @parameter.outer) (parameter_list . (parameter_declaration) @parameter.inner @parameter.outer . ","? @parameter.outer) ; return (return_statement (_)* @return.inner) @return.outer ; statements (block (_) @statement.outer) ================================================ FILE: queries/verilog/textobjects.scm ================================================ (comment) @comment.outer ================================================ FILE: queries/vim/textobjects.scm ================================================ (comment) @comment.outer (function_definition (body) @function.inner) @function.outer (parameters (identifier) @parameter.inner) (parameters "," @parameter.outer . (identifier) @parameter.outer) (parameters . (identifier) @parameter.outer . "," @parameter.outer) (if_statement (body) @conditional.inner) @conditional.outer (for_loop (body) @loop.inner) @loop.outer (while_loop (body) @loop.inner) @loop.outer (call_expression) @call.outer (return_statement (_)? @return.inner) @return.outer (_ (body) @block.inner) @block.outer (body (_) @statement.outer) ((syntax_statement (pattern) @regex.inner @regex.outer)) [ (integer_literal) (float_literal) ] @number.inner (let_statement (_) @assignment.lhs (_) @assignment.rhs @assignment.inner) @assignment.outer (let_statement (_) @assignment.inner) ================================================ FILE: queries/vue/textobjects.scm ================================================ (element) @function.outer [ (attribute) (directive_attribute) ] @call.outer (attribute_value) @parameter.outer ================================================ FILE: queries/wgsl/textobjects.scm ================================================ (function_declaration) @function.outer (function_declaration body: (compound_statement . "{" _+ @function.inner "}")) (parameter_list "," @parameter.outer . (parameter) @parameter.inner @parameter.outer) (parameter_list . (parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) (compound_statement) @block.outer ; loops (loop_statement (_)? @loop.inner) @loop.outer (for_statement (_)? @loop.inner) @loop.outer (while_statement (_)? @loop.inner) @loop.outer (struct_declaration "{" _+ @class.inner "}") @class.outer ; conditional (if_statement consequence: (_)? @conditional.inner alternative: (_)? @conditional.inner) @conditional.outer (if_statement condition: (_) @conditional.inner) (argument_list_expression "," @parameter.outer . (_) @parameter.inner @parameter.outer) (argument_list_expression . (_) @parameter.inner @parameter.outer . ","? @parameter.outer) ================================================ FILE: queries/wgsl_bevy/textobjects.scm ================================================ ; inherits wgsl ================================================ FILE: queries/yaml/textobjects.scm ================================================ ; assignment, statement (block_mapping_pair key: (_) @assignment.lhs value: (_) @assignment.rhs) @assignment.outer @statement.outer (block_mapping_pair key: (_) @assignment.inner) (block_mapping_pair value: (_) @assignment.inner) ; comment ; leave space after comment marker if there is one ((comment) @comment.inner @comment.outer (#match? @comment.outer "# .*")) ; else remove everything accept comment marker ((comment) @comment.inner @comment.outer) ; number [ (integer_scalar) (float_scalar) ] @number.inner ================================================ FILE: queries/zig/textobjects.scm ================================================ ; "Classes" (variable_declaration (struct_declaration)) @class.outer (variable_declaration (struct_declaration "struct" "{" _+ @class.inner "}")) ; functions (function_declaration) @function.outer (function_declaration body: (block . "{" _+ @function.inner "}")) ; loops (for_statement) @loop.outer (for_statement body: (_) @loop.inner) (while_statement) @loop.outer (while_statement body: (_) @loop.inner) ; blocks (block) @block.outer (block "{" _+ @block.inner "}") ; statements (statement) @statement.outer ; parameters (parameters "," @parameter.outer . (parameter) @parameter.inner @parameter.outer) (parameters . (parameter) @parameter.inner @parameter.outer . ","? @parameter.outer) ; arguments (call_expression function: (_) arguments: (arguments "(" "," @parameter.outer . (_) @parameter.inner @parameter.outer ")")) (call_expression function: (_) arguments: (arguments "(" . (_) @parameter.inner @parameter.outer . ","? @parameter.outer ")")) ; comments (comment) @comment.outer ; conditionals (if_statement) @conditional.outer (if_statement condition: (_) @conditional.inner) (if_statement body: (_) @conditional.inner) (switch_expression) @conditional.outer (switch_expression "(" (_) @conditional.inner ")") (switch_expression "{" _+ @conditional.inner "}") (while_statement condition: (_) @conditional.inner) ; calls (call_expression) @call.outer (call_expression arguments: (arguments "(" _+ @call.inner ")")) ================================================ FILE: queries/zsh/textobjects.scm ================================================ (function_definition) @function.outer (function_definition body: (compound_statement . "{" _+ @function.inner "}")) (case_statement) @conditional.outer (if_statement (_) @conditional.inner) @conditional.outer (for_statement (_) @loop.inner) @loop.outer (while_statement (_) @loop.inner) @loop.outer (comment) @comment.outer (regex) @regex.inner ((word) @number.inner (#match? @number.inner "^[0-9]+$")) (variable_assignment) @assignment.outer (variable_assignment name: (_) @assignment.inner @assignment.lhs) (variable_assignment value: (_) @assignment.inner @assignment.rhs) (command argument: (word) @parameter.inner) ================================================ FILE: scripts/append-additional-helix-queries ================================================ #!/bin/sh set -e ls additional-queries/**/*.scm | while read -r file; do language="$(dirname "$file" | xargs basename)" echo "Processing $language" printf "\n;; Additional queries\n\n" >>"treesit-queries/$language/textobjects.scm" cat "$file" >>"treesit-queries/$language/textobjects.scm" done ================================================ FILE: scripts/check-available ================================================ #!/bin/sh # Get a list of languages currently supportable and supported tmpdir=$(mktemp -d) git clone --depth 1 https://github.com/emacs-tree-sitter/tree-sitter-langs $tmpdir/tslangs git clone --depth 1 https://github.com/nvim-treesitter/nvim-treesitter-textobjects $tmpdir/ntsto ls $tmpdir/tslangs/repos >$tmpdir/available-emacs-langs ls $tmpdir/ntsto/queries | tr '\n' '|' | sed 's/.$/$/' | xargs -I{} grep -E {} $tmpdir/available-emacs-langs >$tmpdir/supportable-languages echo "" # Just some spacing printf "Supportable languages: " cat $tmpdir/supportable-languages | xargs echo printf "Supportable but not supported languages: " grep -Eo '\([a-z+]+-mode . "[^"]+"' evil-textobj-tree-sitter.el | cut -d'"' -f2 | sort | uniq | tr '\n' '|' | sed 's/.$/$/' | xargs -I{} grep -Ev {} $tmpdir/supportable-languages | xargs echo ================================================ FILE: scripts/fix-queries ================================================ #!/bin/sh set -e find queries -type f | while read -r file; do echo "Processing $file" go run converter/main.go "$file" | sed 's|#lua-match|#match|' > "$file.new" mv "$file.new" "$file" done ================================================ FILE: scripts/get-helix-queries ================================================ #!/bin/sh set -e tmpdir="$(mktemp -d)" git clone --depth 1 https://github.com/helix-editor/helix "$tmpdir" HELIX_DIR="$tmpdir" find $HELIX_DIR/runtime/queries -name 'textobjects.scm' | sed "s|$HELIX_DIR/runtime/queries/||" | while read -r file; do dir="$(dirname "$file")" filename="$(basename "$file")" mkdir -p "treesit-queries/$dir" # match? to match mapping is kinda hacky sed 's|\(@[^\.]*\)\.inside|\1.inner|g;s|\(@[^\.]*\)\.around|\1.outer|g;s|#match? @\([^ ]*\) "\([^"]*\)"|#match "\2" @\1|g;s/#eq?/#equal/g' \ "$HELIX_DIR/runtime/queries/$file" > "treesit-queries/$dir/$filename" done ./scripts/append-additional-helix-queries # method_spec was removed from upstream go grammar, but helix still uses it sed -ibk 's|method_spec|method_elem|g' treesit-queries/go/textobjects.scm rm treesit-queries/go/textobjects.scmbk # function was removed from javascript/typescript grammar sed -ibk '/^(function$/,+1d' treesit-queries/ecma/textobjects.scm rm treesit-queries/ecma/textobjects.scmbk ================================================ FILE: scripts/get-neovim-queries ================================================ #!/bin/sh set -e rm -rf /tmp/nts git clone --depth 1 --branch main \ https://github.com/nvim-treesitter/nvim-treesitter-textobjects /tmp/nts rm -r queries && cp -r /tmp/nts/queries . ./scripts/fix-queries ================================================ FILE: treesit-queries/_jsx/textobjects.scm ================================================ ; See runtime/queries/ecma/README.md for more info. (jsx_self_closing_element) @xml-element.outer @xml-element.inner (jsx_element (jsx_opening_element) (_)* @xml-element.inner (jsx_closing_element)) (jsx_element) @xml-element.outer ================================================ FILE: treesit-queries/_typescript/textobjects.scm ================================================ [ (interface_declaration body:(_) @class.inner) (type_alias_declaration value: (_) @class.inner) ] @class.outer (enum_body (_) @entry.outer) (enum_assignment (_) @entry.inner) ================================================ FILE: treesit-queries/ada/textobjects.scm ================================================ ;; Support for high-level text objects selections. ;; For instance: ;; maf (v)isually select (a) (f)unction or subprogram ;; mif (v)isually select (i)nside a (f)unction or subprogram ;; mai (v)isually select (a) (i)f statement (or loop) ;; mii (v)isually select (i)nside an (i)f statement (or loop) ;; ;; For navigations using textobjects, check link below: ;; https://docs.helix-editor.com/master/usage.html#navigating-using-tree-sitter-textobjects ;; ;; For Textobject queries explanation, check out link below: ;; https://docs.helix-editor.com/master/guides/textobject.html (subprogram_body) @function.outer (subprogram_body (non_empty_declarative_part) @function.inner) (subprogram_body (handled_sequence_of_statements) @function.inner) (function_specification) @function.outer (procedure_specification) @function.outer (package_declaration) @function.outer (generic_package_declaration) @function.outer (package_body) @function.outer ================================================ FILE: treesit-queries/adl/textobjects.scm ================================================ (struct (_) @function.inner) @function.outer ================================================ FILE: treesit-queries/amber/textobjects.scm ================================================ ; Functions - capture both definition and body (function_definition body: (_) @function.inner) @function.outer ; Function parameters in definitions (function_parameter_list (function_parameter_list_item) @parameter.inner) ; Function call arguments (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ; Comments (comment) @comment.inner (comment)+ @comment.outer ; Arrays (array (_) @entry.outer) ; Main Block looks like a function (main_block (block) @function.inner) @function.outer ================================================ FILE: treesit-queries/awk/textobjects.scm ================================================ (func_def name: (identifier) (block) @function.inner) @function.outer (param_list (_) @parameter.inner) @parameter.outer (args (_) @parameter.inner) @parameter.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/bash/textobjects.scm ================================================ (function_definition body: (_) @function.inner) @function.outer (command argument: (_) @parameter.inner) (comment) @comment.inner (comment)+ @comment.outer (array (_) @entry.outer) ================================================ FILE: treesit-queries/basic/textobjects.scm ================================================ (for_statement) @function.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/blade/textobjects.scm ================================================ ; inherits: html ================================================ FILE: treesit-queries/c/textobjects.scm ================================================ (function_definition body: (_) @function.inner) @function.outer (struct_specifier body: (_) @class.inner) @class.outer (enum_specifier body: (_) @class.inner) @class.outer (union_specifier body: (_) @class.inner) @class.outer (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer (enumerator (_) @entry.inner) @entry.outer (initializer_list (_) @entry.outer) ;; Additional queries (for_statement body: (_) @loop.inner) @loop.outer (while_statement body: (_) @loop.inner) @loop.outer (do_statement body: (_) @loop.inner) @loop.outer (if_statement consequence: (_) @conditional.inner) @conditional.outer ================================================ FILE: treesit-queries/c-sharp/textobjects.scm ================================================ [ (class_declaration body: (_) @class.inner) (struct_declaration body: (_) @class.inner) (interface_declaration body: (_) @class.inner) (enum_declaration body: (_) @class.inner) (delegate_declaration) (record_declaration body: (_) @class.inner) ] @class.outer (constructor_declaration body: (_) @function.inner) @function.outer (destructor_declaration body: (_) @function.inner) @function.outer (method_declaration body: (_) @function.inner) @function.outer (property_declaration (_) @function.inner) @function.outer (parameter (_) @parameter.inner) @parameter.outer (comment)+ @comment.outer ================================================ FILE: treesit-queries/caddyfile/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (directive name: (directive_name) @parameter.inner) @parameter.outer (global_options "{" (_)* @class.inner "}") @class.outer (snippet_definition (block) @class.inner) @class.outer (named_route (block) @class.inner) @class.outer (site_definition (block) @class.inner) @class.outer ================================================ FILE: treesit-queries/cairo/textobjects.scm ================================================ (function_item body: (_) @function.inner) @function.outer (closure_expression body: (_) @function.inner) @function.outer (struct_item body: (_) @class.inner) @class.outer (enum_item body: (_) @class.inner) @class.outer (trait_item body: (_) @class.inner) @class.outer (impl_item body: (_) @class.inner) @class.outer (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (closure_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (field_initializer_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) [ (line_comment) ] @comment.inner (line_comment)+ @comment.outer (; #[test] (attribute_item (attribute (identifier) @_test_attribute)) ; allow other attributes like #[should_panic] and comments [ (attribute_item) (line_comment) ]* ; the test function (function_item body: (_) @test.inner) @test.outer (#equal @_test_attribute "test")) (array_expression (_) @entry.outer) (tuple_expression (_) @entry.outer) (tuple_pattern (_) @entry.outer) ; Commonly used vec macro initializer is special cased (macro_invocation (identifier) @_id (token_tree (_) @entry.outer) (#equal @_id "array")) (enum_variant) @entry.outer (field_declaration (_) @entry.inner) @entry.outer (field_initializer (_) @entry.inner) @entry.outer (shorthand_field_initializer) @entry.outer ================================================ FILE: treesit-queries/clojure/textobjects.scm ================================================ ; Function definitions (defn, defn-, defmacro, defmethod, etc.) (list_lit . (sym_lit) @_keyword . (sym_lit) (_)* @function.inner (#match "^(defn|defn-|defmacro|defmethod|defmulti|definline)$" @_keyword)) @function.outer ; Anonymous functions (fn) (list_lit . (sym_lit) @_fn (_)* @function.inner (#match "^fn$" @_fn)) @function.outer ; Anonymous function shorthand #() (anon_fn_lit (_)* @function.inner) @function.outer ; deftype, defrecord, defprotocol (list_lit . (sym_lit) @_keyword . (sym_lit) (_)* @class.inner (#match "^(deftype|defrecord|defprotocol|definterface|defstruct)$" @_keyword)) @class.outer ; Test definitions (deftest) (list_lit . (sym_lit) @_keyword . (sym_lit) (_)* @test.inner (#match "^deftest$" @_keyword)) @test.outer ; Function parameters in vectors (vec_lit (_)* @parameter.inner) @parameter.outer ; List entries (list_lit (_) @entry.inner @entry.outer) ; Vector entries (vec_lit (_) @entry.inner @entry.outer) ; Map entries (map_lit (_) @entry.inner @entry.outer) ; Set entries (set_lit (_) @entry.inner @entry.outer) ; Comments (comment) @comment.inner (comment)+ @comment.outer ; Discard expressions (also treated as comments) (dis_expr) @comment.inner ; Comment special form (comment ...) (list_lit . (sym_lit) @_comment (_)* @comment.inner (#match "^comment$" @_comment)) @comment.outer ================================================ FILE: treesit-queries/cmake/textobjects.scm ================================================ [ (macro_def) (function_def) ] @function.outer (argument) @parameter.inner [ (bracket_comment) (line_comment) ] @comment.inner (line_comment)+ @comment.outer (bracket_comment) @comment.outer ================================================ FILE: treesit-queries/codeql/textobjects.scm ================================================ (qldoc) @comment.outer (block_comment) @comment.outer (line_comment) @comment.inner (line_comment)+ @comment.outer (classlessPredicate ((varDecl) @parameter.inner . ","?) @parameter.outer (body "{" (_)* @function.inner "}")) @function.outer (memberPredicate ((varDecl) @parameter.inner . ","?) @parameter.outer (body "{" (_)* @function.inner "}")) @function.outer (dataclass ("{" (_)* @class.inner "}")?) @class.outer (datatype) @class.outer (datatypeBranch) @class.outer ================================================ FILE: treesit-queries/cpp/textobjects.scm ================================================ ; inherits: c (lambda_expression body: (_) @function.inner) @function.outer (class_specifier body: (_) @class.inner) @class.outer ================================================ FILE: treesit-queries/cross-config/textobjects.scm ================================================ ; inherits: toml ================================================ FILE: treesit-queries/crystal/textobjects.scm ================================================ (class_def name: (_) (_) @class.inner) @class.outer (struct_def name: (_) (_) @class.inner) @class.outer (module_def name: (_) (_) @class.inner) @class.outer (lib_def name: (_) (_) @class.inner) @class.outer (enum_def name: (_) (_) @class.inner) @class.outer (block params: (_) @parameter.inner) @parameter.outer (method_def params: (_) @parameter.inner) @parameter.outer (method_def name: (_) (_) @function.inner) @function.outer (block (_) @function.inner) @function.outer (comment) @comment.inner (comment)+ @comment.outer (array (_) @entry.outer) ================================================ FILE: treesit-queries/cylc/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (_ brackets_open: _ name: _? brackets_close: _ _* @class.inner) @class.outer (setting value: _? @function.inner) @function.outer (graph_setting value: _? @function.inner) @function.outer (graph_string_content (graph_task) @entry.inner) (task_parameter ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ================================================ FILE: treesit-queries/d/textobjects.scm ================================================ (function_declaration (function_body) @function.inner) @function.outer (comment) @comment.inner (comment)+ @comment.outer (class_declaration (aggregate_body) @class.inner) @class.outer (interface_declaration (aggregate_body) @class.inner) @class.outer (struct_declaration (aggregate_body) @class.inner) @class.outer (unittest_declaration (block_statement) @test.inner) @test.outer (parameter) @parameter.inner (template_parameter) @parameter.inner ================================================ FILE: treesit-queries/dart/textobjects.scm ================================================ (class_definition body: (_) @class.inner) @class.outer (mixin_declaration (class_body) @class.inner) @class.outer (extension_declaration (extension_body) @class.inner) @class.outer (enum_declaration body: (_) @class.inner) @class.outer (type_alias) @class.outer (_ ( [ (getter_signature) (setter_signature) (function_signature) (method_signature) (constructor_signature) ] . (function_body) @function.inner @function.outer ) @function.outer ) (declaration [ (constant_constructor_signature) (constructor_signature) (factory_constructor_signature) (redirecting_factory_constructor_signature) (getter_signature) (setter_signature) (operator_signature) (function_signature) ] ) @function.outer (lambda_expression body: (_) @function.inner ) @function.outer (function_expression body: (_) @function.inner ) @function.outer [ (comment) (documentation_comment) ] @comment.inner (comment)+ @comment.outer (documentation_comment)+ @comment.outer (formal_parameter_list ( (formal_parameter) @parameter.inner . ","? @parameter.outer ) @parameter.outer ) (optional_formal_parameters ( (formal_parameter) @parameter.inner . ","? @parameter.outer ) @parameter.outer ) (arguments ( [ (argument) @parameter.inner (named_argument (label) . (_)* @parameter.inner) ] . ","? @parameter.outer ) @parameter.outer ) (type_arguments ( ((_) . ("." . (_) @parameter.inner @parameter.outer)?) @parameter.inner . ","? @parameter.outer ) @parameter.outer ) (expression_statement ((identifier) @_name (#any-of? @_name "test" "testWidgets")) . (selector (argument_part (arguments . (_) . (argument) @test.inner))) ) @test.outer ================================================ FILE: treesit-queries/dhall/textobjects.scm ================================================ (lambda_expression (label) @parameter.inner (expression) @function.inner ) @function.outer (forall_expression (label) @parameter.inner (expression) @function.inner ) @function.outer (assert_expression (expression) @test.inner ) @test.outer [ (block_comment_content) (line_comment_content) ] @comment.inner [ (block_comment) (line_comment) ] @comment.outer ================================================ FILE: treesit-queries/docker-bake/textobjects.scm ================================================ ; inherits: hcl ================================================ FILE: treesit-queries/docker-compose/textobjects.scm ================================================ ; inherits: yaml ================================================ FILE: treesit-queries/dockerfile/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/doxyfile/textobjects.scm ================================================ (option value: (_) @entry.inner) @entry.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/earthfile/textobjects.scm ================================================ (target (block) @function.inner) @function.outer ================================================ FILE: treesit-queries/ecma/textobjects.scm ================================================ (function_declaration body: (_) @function.inner) @function.outer (function_expression body: (_) @function.inner) @function.outer (arrow_function body: (_) @function.inner) @function.outer (method_definition body: (_) @function.inner) @function.outer (generator_function_declaration body: (_) @function.inner) @function.outer (class_declaration body: (class_body) @class.inner) @class.outer (class (class_body) @class.inner) @class.outer (export_statement declaration: [ (function_declaration) @function.outer (class_declaration) @class.outer ]) (formal_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer (array (_) @entry.outer) (pair (_) @entry.inner) @entry.outer (pair_pattern (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/eiffel/textobjects.scm ================================================ [ (comment)+ (header_comment)+ ] @comment.outer [ (comment) (header_comment) ] @comment.inner (formal_arguments) @parameter.outer (entity_declaration_group) @parameter.inner (attribute_or_routine) @function.outer (feature_body) @function.inner (class_declaration) @class.outer (feature_clause) @class.inner ================================================ FILE: treesit-queries/elixir/textobjects.scm ================================================ ; Function heads and guards have no body at all, so `keywords` and `do_block` nodes are both optional ((call target: (identifier) @_keyword (arguments [ (call (arguments (_)? @parameter.inner)) ; function has a guard (binary_operator left: (call (arguments (_)? @parameter.inner))) ] ; body is "do: body" instead of a do-block (keywords (pair value: (_) @function.inner))?)? (do_block (_)* @function.inner)?) (#match "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$" @_keyword)) @function.outer (anonymous_function (stab_clause right: (body) @function.inner)) @function.outer ((call target: (identifier) @_keyword (do_block (_)* @class.inner)) (#match "^(defmodule|defprotocol|defimpl)$" @_keyword)) @class.outer ((call target: (identifier) @_keyword (arguments ((string) . (_)?)) (do_block (_)* @test.inner)?) (#match "^(test|describe)$" @_keyword)) @test.outer (comment)+ @comment.outer @comment.inner ================================================ FILE: treesit-queries/elm/textobjects.scm ================================================ (line_comment) @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.inner (block_comment)+ @comment.outer ((type_annotation)? (value_declaration (function_declaration_left (lower_case_identifier)) (eq) (_) @function.inner ) ) @function.outer (parenthesized_expr (anonymous_function_expr ( (arrow) (_) @function.inner ) ) ) @function.outer (value_declaration (function_declaration_left (lower_pattern (lower_case_identifier) @parameter.inner @parameter.outer ) ) ) (value_declaration (function_declaration_left (pattern) @parameter.inner @parameter.outer ) ) (value_declaration (function_declaration_left (tuple_pattern (pattern) @parameter.inner ) @parameter.outer ) ) (value_declaration (function_declaration_left (record_pattern (lower_pattern (lower_case_identifier) @parameter.inner ) ) @parameter.outer ) ) (parenthesized_expr (anonymous_function_expr ( (backslash) (pattern) @parameter.inner (arrow) ) ) ) ================================================ FILE: treesit-queries/env/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (variable_assignment (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/erlang/textobjects.scm ================================================ (function_clause pattern: (arguments (_)? @parameter.inner) body: (_) @function.inner) @function.outer (anonymous_function (stab_clause body: (_) @function.inner)) @function.outer (comment (comment_content) @comment.inner) @comment.outer ; EUnit test names. ; (CommonTest cases are not recognizable by syntax alone.) ((function_clause name: (atom) @_name pattern: (arguments (_)? @parameter.inner) body: (_) @test.inner) @test.outer (#match "_test$" @_name)) ================================================ FILE: treesit-queries/fga/textobjects.scm ================================================ (condition_declaration body: (_) @function.inner) @function.outer (param ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/fish/textobjects.scm ================================================ (function_definition) @function.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/freebasic/textobjects.scm ================================================ (function_declaration) @function.outer (sub_declaration) @function.outer (for_statement) @function.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/gas/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/gdscript/textobjects.scm ================================================ (class_definition (body) @class.inner) @class.outer (function_definition (body) @function.inner) @function.outer (lambda (body) @function.inner) @function.outer (parameters [ (identifier) (typed_parameter) (default_parameter) (typed_default_parameter) ] @parameter.inner @parameter.outer) (arguments (_expression) @parameter.inner @parameter.outer) [ (const_statement) (variable_statement) (pair) (enumerator) ] @entry.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/git-cliff-config/textobjects.scm ================================================ ; inherits: toml ================================================ FILE: treesit-queries/git-commit/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/git-config/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (variable (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/github-action/textobjects.scm ================================================ ; inherits: yaml ================================================ FILE: treesit-queries/gitlab-ci/textobjects.scm ================================================ ; inherits: yaml ================================================ FILE: treesit-queries/gjs/textobjects.scm ================================================ ; inherits: _gjs,_javascript,ecma ================================================ FILE: treesit-queries/gleam/textobjects.scm ================================================ (function parameters: (function_parameters (function_parameter)? @parameter.inner) body: (block) @function.inner) @function.outer (anonymous_function body: (block) @function.inner) @function.outer ((function name: (identifier) @_name body: (block) @test.inner) @test.outer (#match "_test$" @_name)) ================================================ FILE: treesit-queries/glsl/textobjects.scm ================================================ ; inherits: c ================================================ FILE: treesit-queries/go/textobjects.scm ================================================ (function_declaration body: (block)? @function.inner) @function.outer (func_literal (_)? @function.inner) @function.outer (method_declaration body: (block)? @function.inner) @function.outer ;; struct and interface declaration as class textobject? (type_declaration (type_spec (type_identifier) (struct_type (field_declaration_list (_)?) @class.inner))) @class.outer (type_declaration (type_spec (type_identifier) (interface_type (method_elem)+ @class.inner))) @class.outer (type_parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer ((function_declaration name: (identifier) @_name body: (block)? @test.inner) @test.outer (#match "^Test" @_name)) ;; Additional queries (if_statement consequence: (block) @conditional.inner) @conditional.outer (if_statement alternative: (block) @conditional.inner)? @conditional.outer (expression_switch_statement (expression_case) @conditional.inner) @conditional.outer (type_switch_statement (type_case) @conditional.inner) @conditional.outer (select_statement (communication_case) @conditional.inner) @conditional.outer (for_statement body: (block) @loop.inner) @loop.outer ================================================ FILE: treesit-queries/godot-resource/textobjects.scm ================================================ (section (identifier) (_) (property) @class.inner ) @class.outer (attribute (identifier) (_) @parameter.inner) @parameter.outer (property (path) (_) @entry.inner) @entry.outer (pair (_) @entry.inner) @entry.outer (array (_) @entry.outer) (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/graphql/textobjects.scm ================================================ (type_definition) @class.outer (executable_definition) @function.outer (arguments_definition (input_value_definition) @parameter.inner @parameter.movement) (arguments (argument) @parameter.inner @parameter.movement) (selection [(field) (fragment_spread)] @entry.outer) (selection (field (selection_set) @entry.inner)) (field_definition (_) @entry.inner) @entry.outer (input_fields_definition (input_value_definition ) @entry.outer) (enum_value) @entry.outer ================================================ FILE: treesit-queries/gren/textobjects.scm ================================================ (line_comment) @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.inner (block_comment)+ @comment.outer ((type_annotation)? (value_declaration (function_declaration_left (lower_case_identifier)) (eq) (_) @function.inner ) ) @function.outer (parenthesized_expr (anonymous_function_expr ( (arrow) (_) @function.inner ) ) ) @function.outer (value_declaration (function_declaration_left (lower_pattern (lower_case_identifier) @parameter.inner @parameter.outer ) ) ) (value_declaration (function_declaration_left (pattern) @parameter.inner @parameter.outer ) ) (value_declaration (function_declaration_left (record_pattern (lower_pattern (lower_case_identifier) @parameter.inner ) ) @parameter.outer ) ) (parenthesized_expr (anonymous_function_expr ( (backslash) (pattern) @parameter.inner (arrow) ) ) ) ================================================ FILE: treesit-queries/gts/textobjects.scm ================================================ ; inherits: _gjs,_typescript,ecma ================================================ FILE: treesit-queries/haskell/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (newtype (newtype_constructor (_) @class.inner)) @class.outer (data_type constructors: (_) @class.inner) @class.outer (decl/function (match expression:(_) @function.inner)) @function.outer (lambda expression:(_) @function.inner) @function.outer (decl/function patterns: (patterns (_) @parameter.inner)) (expression/lambda patterns: (patterns (_) @parameter.inner)) (decl/function (infix (pattern) @parameter.inner)) ================================================ FILE: treesit-queries/hcl/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (function_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (attribute (_) @entry.inner) @entry.outer (tuple (_) @entry.outer) ================================================ FILE: treesit-queries/heex/textobjects.scm ================================================ (comment) @comment.outer @comment.inner ================================================ FILE: treesit-queries/hocon/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (pair (_) @entry.inner) @entry.outer (array (_) @entry.outer) ================================================ FILE: treesit-queries/html/textobjects.scm ================================================ (script_element (start_tag) (_) @xml-element.inner (end_tag)) @xml-element.outer (style_element (start_tag) (_) @xml-element.inner (end_tag)) @xml-element.outer (element (start_tag) (_)* @xml-element.inner (end_tag)) (element) @xml-element.outer (comment) @comment.outer ================================================ FILE: treesit-queries/hurl/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (entry (_) @function.inner) @function.outer ================================================ FILE: treesit-queries/inko/textobjects.scm ================================================ (class body: (_) @class.inner) @class.outer (trait body: (_) @class.inner) @class.outer (method body: (_) @function.inner) @function.outer (reopen_class body: (_) @class.inner) @class.outer (implement_trait body: (_) @class.inner) @class.outer (external_function body: (_) @function.inner) @function.outer (closure body: (_) @function.inner) @function.outer (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (line_comment) @comment.inner (line_comment)+ @comment.outer (array (_) @entry.outer) (tuple (_) @entry.outer) (tuple_pattern (_) @entry.outer) (define_field (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/java/textobjects.scm ================================================ (method_declaration body: (_)? @function.inner) @function.outer (constructor_declaration body: (_) @function.inner) @function.outer (interface_declaration body: (_) @class.inner) @class.outer (class_declaration body: (_) @class.inner) @class.outer (record_declaration body: (_) @class.inner) @class.outer (enum_declaration body: (_) @class.inner) @class.outer (formal_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) [ (line_comment) (block_comment) ] @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.outer (array_initializer (_) @entry.outer) (enum_body (enum_constant) @entry.outer) ================================================ FILE: treesit-queries/javascript/textobjects.scm ================================================ ; See runtime/queries/ecma/README.md for more info. ; inherits: _javascript,ecma ================================================ FILE: treesit-queries/jjconfig/textobjects.scm ================================================ ; inherits: toml ================================================ FILE: treesit-queries/jq/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (funcdef (query) @function.inner) @function.outer (objectkeyval (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/json/textobjects.scm ================================================ (pair (_) @entry.inner) @entry.outer (array (_) @entry.outer) (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/json-ld/textobjects.scm ================================================ ; inherits: json ================================================ FILE: treesit-queries/json5/textobjects.scm ================================================ (member (_) @entry.inner) @entry.outer (array (_) @entry.outer) (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/jsonc/textobjects.scm ================================================ ; inherits: json ================================================ FILE: treesit-queries/jsx/textobjects.scm ================================================ ; See runtime/queries/ecma/README.md for more info. ; inherits: _jsx,_javascript,ecma ================================================ FILE: treesit-queries/julia/textobjects.scm ================================================ (function_definition (_)? @function.inner) @function.outer (short_function_definition (_)? @function.inner) @function.outer (macro_definition (_)? @function.inner) @function.outer (struct_definition (_)? @class.inner) @class.outer (abstract_definition (_)? @class.inner) @class.outer (primitive_definition (_)? @class.inner) @class.outer (parameter_list ; Match all children of parameter_list *except* keyword_parameters ([(identifier) (slurp_parameter) (optional_parameter) (typed_parameter) (tuple_expression) (interpolation_expression) (call_expression)] @parameter.inner . ","? @parameter.outer) @parameter.outer) (keyword_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (line_comment) @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.inner (block_comment)+ @comment.outer (_expression (macro_identifier (identifier) @_name (#match "^(test|test_throws|test_logs|inferred|test_deprecated|test_warn|test_nowarn|test_broken|test_skip)$" @_name) ) . (macro_argument_list) @test.inner) @test.outer ================================================ FILE: treesit-queries/just/textobjects.scm ================================================ ; Specify how to navigate around logical blocks in code (assert_parameters ((_) @parameter.inner . ","? @parameter.outer)) @parameter.outer (recipe (recipe_body) @function.inner) @function.outer (recipe_parameters ((_) @parameter.inner . ","? @parameter.outer)) @parameter.outer (recipe_dependency (_) @parameter.inner) @parameter.outer (function_call (function_parameters ((_) @parameter.inner . ","? @parameter.outer)) @parameter.outer) @function.outer (comment) @comment.outer ================================================ FILE: treesit-queries/kdl/textobjects.scm ================================================ (type (_) @test.inner) @test.outer (node children: (node_children)? @class.inner) @class.outer (node children: (node_children)? @function.inner) @function.outer (node (identifier) @function.movement) [ (single_line_comment) (multi_line_comment) ] @comment.inner [ (single_line_comment)+ (multi_line_comment)+ ] @comment.outer [ (prop) (value) ] @parameter.inner (value (type) ? (_) @parameter.inner @parameter.movement . ) @parameter.outer ================================================ FILE: treesit-queries/kotlin/textobjects.scm ================================================ (function_declaration (function_body)? @function.inner) @function.outer ; Unlike function_body above, the constructor body is does not have its own ; symbol in the current grammar. (secondary_constructor) @function.outer (class_declaration (class_body)? @class.inner) @class.outer (class_declaration (enum_class_body) @class.inner) @class.outer [ (line_comment) (multiline_comment) ] @comment.inner (line_comment)+ @comment.outer (multiline_comment) @comment.outer (enum_entry) @entry.outer (lambda_literal) @entry.outer (property_declaration) @entry.outer (object_declaration) @entry.outer (assignment) @entry.outer ; TODO: This doesn't work with annotations yet, but fixing it without breaking ; the case of multiple parameters is non-trivial. (function_value_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ; secondary constructor uses function_value_parameters above (primary_constructor ((_)@parameter.inner . ","? @parameter.outer) @parameter.outer) (function_type_parameters ((_)@parameter.inner . ","? @parameter.outer) @parameter.outer) (value_arguments ((_)@parameter.inner . ","? @parameter.outer) @parameter.outer) (lambda_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ================================================ FILE: treesit-queries/koto/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (function body: (_) @function.inner) @function.outer (args ((arg) @parameter.inner . ","? @parameter.outer) @parameter.outer) (call_args ((call_arg) @parameter.inner . ","? @parameter.outer) @parameter.outer) (map ((entry_inline) @entry.inner . ","? @entry.outer) @entry.outer) (map_block ((entry_block) @entry.inner) @entry.outer) (list ((element) @entry.inner . ","? @entry.outer) @entry.outer) (tuple (_) @entry.outer) (assign (meta (test)) (function body: (_) @test.inner) ) @test.outer (entry_block key: (meta (test)) value: (function body: (_) @test.inner) ) @test.outer ================================================ FILE: treesit-queries/latex/textobjects.scm ================================================ [ (generic_command) ] @function.outer [ (chapter) (part) (section) (subsection) (subsubsection) (paragraph) (subparagraph) ] @class.outer ================================================ FILE: treesit-queries/llvm/textobjects.scm ================================================ (define body: (_) @function.inner) @function.outer (struct_type (struct_body) @class.inner) @class.outer (packed_struct_type (struct_body) @class.inner) @class.outer (array_type (array_vector_body) @class.inner) @class.outer (vector_type (array_vector_body) @class.inner) @class.outer (argument) @parameter.inner (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/llvm-mir/textobjects.scm ================================================ (basic_block) @function.outer (argument) @parameter.inner [ (comment) (multiline_comment) ] @comment.inner (comment)+ @comment.outer (multiline_comment) @comment.outer ================================================ FILE: treesit-queries/lua/textobjects.scm ================================================ (function_definition body: (_) @function.inner) @function.outer (function_declaration body: (_) @function.inner) @function.outer (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer (table_constructor (field (_) @entry.inner) @entry.outer) ================================================ FILE: treesit-queries/luau/textobjects.scm ================================================ (fn_stmt body: (_)? @function.inner) @function.outer (local_fn_stmt body: (_)? @function.inner) @function.outer (anon_fn body: (_)? @function.inner) @function.outer (param ((name) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arglist ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/mail/textobjects.scm ================================================ (atom_block (atom) @entry.inner) @entry.outer (email_address) @entry.outer (header_other (header_unstructured) @entry.outer) (quoted_block)+ @comment.outer (body_block)+ @function.outer (header_subject (subject) @function.outer) ================================================ FILE: treesit-queries/matlab/textobjects.scm ================================================ (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (function_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (lambda expression: (_) @function.inner) @function.outer (function_definition (block) @function.inner) @function.outer (class_definition) @class.inner @class.outer (comment) @comment.inner @comment.outer ================================================ FILE: treesit-queries/miseconfig/textobjects.scm ================================================ ; inherits: toml ================================================ FILE: treesit-queries/mojo/textobjects.scm ================================================ ; inherits: python ================================================ FILE: treesit-queries/nasm/textobjects.scm ================================================ (preproc_multiline_macro body: (body) @function.inner) @function.outer (struc_declaration body: (struc_declaration_body) @class.inner) @class.outer (struc_instance body: (struc_instance_body) @class.inner) @class.outer (preproc_function_def_parameters (word) @parameter.inner) (call_syntax_arguments (_) @parameter.inner) (operand) @parameter.inner (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/nestedtext/textobjects.scm ================================================ ; inherits: yaml ================================================ FILE: treesit-queries/nim/textobjects.scm ================================================ (proc_declaration body: (_) @function.inner) @function.outer (func_declaration body: (_) @function.inner) @function.outer (iterator_declaration body: (_) @function.inner) @function.outer (converter_declaration body: (_) @function.inner) @function.outer (method_declaration body: (_) @function.inner) @function.outer (template_declaration body: (_) @function.inner) @function.outer (macro_declaration body: (_) @function.inner) @function.outer (type_declaration (_) @class.inner) @class.outer (parameter_declaration (symbol_declaration_list) @parameter.inner) @parameter.outer [ (comment) (block_comment) (documentation_comment) (block_documentation_comment) ] @comment.inner [ (comment)+ (block_comment) (documentation_comment)+ (block_documentation_comment)+ ] @comment.outer ================================================ FILE: treesit-queries/nix/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (formals ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (function_expression body: (_) @function.inner) @function.outer (binding (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/nu/textobjects.scm ================================================ ; (stmt_let) @assignment.outer ; (stmt_mut) @assignment.outer ; (stmt_const) @assignment.outer ; (stmt_let ; value: (_) @assignment.inner) ; (stmt_mut ; value: (_) @assignment.inner) ; (stmt_const ; value: (_) @assignment.inner) ; (block) @block.outer (comment) @comment.outer ; (pipeline) @pipeline.outer ; (pipe_element) @pipeline.inner (decl_def) @function.outer (decl_def body: (_) @function.inner) ; (ctrl_for) @loop.outer ; (ctrl_loop) @loop.outer ; (ctrl_while) @loop.outer ; (ctrl_for ; body: (_) @loop.inner) ; (ctrl_loop ; body: (_) @loop.inner) ; (ctrl_while ; body: (_) @loop.inner) ; Conditional inner counts the last one, rather than the current one. ; (ctrl_if ; then_branch: (_) @conditional.inner ; else_block: (_)? @conditional.inner) @conditional.outer (parameter) @parameter.outer ; (command ; head: (_) @call.inner) @call.outer ; (where_command ; predicate: (_) @call.inner) @call.outer ; define pipeline first, because it should only match as a fallback ; e.g., `let a = date now` should match the whole assignment. ; But a standalone `date now` should also match a statement ; (pipeline) @statement.outer ; (stmt_let) @statement.outer ; (stmt_mut) @statement.outer ; (stmt_const) @statement.outer ; (ctrl_if) @statement.outer ; (ctrl_try) @statement.outer ; (ctrl_match) @statement.outer ; (ctrl_while) @statement.outer ; (ctrl_loop) @statement.outer ; (val_number) @number.inner ================================================ FILE: treesit-queries/odin/textobjects.scm ================================================ (procedure_declaration (identifier) (procedure (block) @function.inner)) @function.outer (procedure_declaration (identifier) (procedure (uninitialized) @function.inner)) @function.outer (overloaded_procedure_declaration (identifier) @function.inner) @function.outer (procedure_type (parameters (parameter (identifier) @parameter.inner) @parameter.outer)) (procedure (parameters (parameter (identifier) @parameter.inner) @parameter.outer)) ((procedure_declaration (attributes (attribute "@" "(" (identifier) @attr_name ")")) (identifier) (procedure (block) @test.inner)) @test.outer (#match "test" @attr_name)) (comment) @comment.inner (comment)+ @comment.outer (block_comment) @comment.inner (block_comment)+ @comment.outer (struct_declaration (identifier) "::") @class.outer (enum_declaration (identifier) "::") @class.outer (union_declaration (identifier) "::") @class.outer (bit_field_declaration (identifier) "::") @class.outer (const_declaration (identifier) "::" [(array_type) (distinct_type) (bit_set_type) (pointer_type)]) @class.outer ================================================ FILE: treesit-queries/ohm/textobjects.scm ================================================ ; See: https://docs.helix-editor.com/guides/textobject.html ; function.inside & around ; ------------------------ (rule body: (_) @function.inner) @function.outer ; class.inside & around ; --------------------- (grammar body: (_) @class.inner) @class.outer ; parameter.inside & around ; ------------------------- (formals ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (rule_body ((_) @parameter.inner . "|"? @parameter.outer) @parameter.outer) (params ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (alt ((_) @parameter.inner . "|"? @parameter.outer) @parameter.outer) ; comment.inside ; -------------- (multiline_comment)+ @comment.inner (singleline_comment)+ @comment.inner ; comment.around ; -------------- (multiline_comment)+ @comment.outer (singleline_comment)+ @comment.outer ================================================ FILE: treesit-queries/opencl/textobjects.scm ================================================ ; inherits: c ================================================ FILE: treesit-queries/pascal/textobjects.scm ================================================ (declType (declClass (declSection) @class.inner)) @class.outer (defProc body: (_) @function.inner) @function.outer (declArgs (_) @parameter.inner) @parameter.outer (exprArgs (_) @parameter.inner) @parameter.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/penrose/textobjects.scm ================================================ ; Functions/constructors/predicates in Domain (constructor_decl) @function.outer (function_decl) @function.outer (predicate_decl) @function.outer ; Parameters (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ; Arguments (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ; Comments (comment) @comment.inner (comment) @comment.outer ================================================ FILE: treesit-queries/perl/textobjects.scm ================================================ (subroutine_declaration_statement body: (_) @function.inner) @function.outer (anonymous_subroutine_expression body: (_) @function.inner) @function.outer (package_statement) @class.outer (package_statement (block) @class.inner) (list_expression (_) @parameter.inner) (comment) @comment.outer (pod) @comment.outer ================================================ FILE: treesit-queries/pest/textobjects.scm ================================================ (grammar_rule (_) @class.inner) @class.outer (term (_) @entry.inner) @entry.outer (line_comment) @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.inner (block_comment)+ @comment.outer ================================================ FILE: treesit-queries/php/textobjects.scm ================================================ (class_declaration body: (_) @class.inner) @class.outer (interface_declaration body: (_) @class.inner) @class.outer (trait_declaration body: (_) @class.inner) @class.outer (enum_declaration body: (_) @class.inner) @class.outer (function_definition body: (_) @function.inner) @function.outer (method_declaration body: (_) @function.inner) @function.outer (arrow_function body: (_) @function.inner) @function.outer (anonymous_function_creation_expression body: (_) @function.inner) @function.outer (anonymous_function_use_clause ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (formal_parameters ([ (simple_parameter) (variadic_parameter) (property_promotion_parameter) ] @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer (array_creation_expression (array_element_initializer (_) @entry.inner ) @entry.outer @entry.movement) (list_literal (_) @entry.inner @entry.outer @entry.movement) [ (enum_case) ] @entry.outer @entry.movement ================================================ FILE: treesit-queries/picat/textobjects.scm ================================================ [ (function_definition [(function_rule) (function_fact)] @function.inner) (predicate_definition [(predicate_rule) (predicate_fact)] @function.inner) (actor_definition [(action_rule) (nonbacktrackable_predicate_rule)] @function.inner) ] @function.outer (import_declaration (atom) @function.outer) (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer (array_expression (_) @entry.outer) (list_expression (_) @entry.outer) ================================================ FILE: treesit-queries/pkgbuild/textobjects.scm ================================================ ; inherits: bash ================================================ FILE: treesit-queries/po/textobjects.scm ================================================ (msgid) @parameter.inner (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/ponylang/textobjects.scm ================================================ ;; Queries for helix to select textobjects: https://docs.helix-editor.com/usage.html#textobjects ;; function.inside ;; function.around ;; class.inside ;; class.around ;; test.inside ;; test.around ;; parameter.inside ;; comment.inside ;; comment.around ;; Queries for navigating using textobjects [ (line_comment) (block_comment) ] @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.outer (entity members: (members)? @class.inner) @class.outer (object members: (members)? @class.inner) @class.outer (method body: (block)? @function.inner ) @function.outer (behavior body: (block)? @function.inner ) @function.outer (constructor body: (block)? @function.inner ) @function.outer (lambda body: (block)? @function.inner ) @function.outside (params ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer ) (lambda params: ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer ) (typeargs ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer ) (typeparams ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer ) (arguments positional: (positional_args ((_) @parameter.inner . ","? @parameter.outer)? @parameter.outer) ; TODO: get named args right named: (named_args ((_) @parameter.inner . ","? @parameter.outer)? @parameter.outer) ) ( (entity provides: (type (nominal_type name: (identifier) @_provides)) members: (members) @test.inner ) @test.outside (#equal @_provides "UnitTest") ) ================================================ FILE: treesit-queries/prisma/textobjects.scm ================================================ (model_declaration ((statement_block) @class.inner)) @class.outer (call_expression (arguments (_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (column_declaration) @entry.outer (array (_) @entry.outer) (assignment_expression (_) @entry.inner) @entry.outer (developer_comment) @comment.inner (developer_comment)+ @comment.outer ================================================ FILE: treesit-queries/properties/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (property (key) @parameter.inner) @parameter.outer ================================================ FILE: treesit-queries/protobuf/textobjects.scm ================================================ (message (message_body) @class.inner) @class.outer (enum (enum_body) @class.inner) @class.outer (service (service_body) @class.inner) @class.outer (rpc (message_or_enum_type) @parameter.inner) @function.inner (rpc (message_or_enum_type) @parameter.outer) @function.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/purescript/textobjects.scm ================================================ (comment) @comment.inner [ (data) (type) (newtype) ] @class.outer ((signature)? (function rhs:(_) @function.inner)) @function.outer (exp_lambda) @function.outer (data (type_variable) @parameter.inner) (patterns (_) @parameter.inner) ================================================ FILE: treesit-queries/python/textobjects.scm ================================================ (function_definition body: (block)? @function.inner) @function.outer (class_definition body: (block)? @class.inner) @class.outer (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (lambda_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer ((function_definition name: (identifier) @_name body: (block)? @test.inner) @test.outer (#match "^test_" @_name)) (list (_) @entry.outer) (tuple (_) @entry.outer) (set (_) @entry.outer) (pair (_) @entry.inner) @entry.outer ;; Additional queries (for_statement body: (_) @loop.inner) @loop.outer (while_statement body: (_) @loop.inner) @loop.outer (if_statement consequence: (_) @conditional.inner) @conditional.outer ================================================ FILE: treesit-queries/qml/textobjects.scm ================================================ ; (comment) is used for both // and /* ... */ comment syntax (comment) @comment.inner (comment)+ @comment.outer (ui_object_definition initializer: (_) @class.inner) @class.outer (ui_binding name: (identifier) @parameter.inner) @parameter.outer (ui_property (_)+ @parameter.inner ":") @parameter.outer (function_declaration body: (_) @function.inner) @function.outer (arrow_function body: (_) @function.inner) @function.outer ; e.g. `onClicked: console.log("Button clicked!")` ((ui_binding name: (identifier) @_name value: (_) @function.outer @function.inner) (#match "^on[A-Z].*" @_name)) ; e.g. ; Component.onCompleted: { ; console.log("completed") ; } (statement_block (expression_statement)* @function.inner) @function.outer ; e.g. ; states: [ ; State { name: "activated" }, ; State { name: "deactivated" } ; ] (ui_object_array ((_) @entry.inner . ","? @entry.outer) @entry.outer) ; e.g. [1, 2, 3, 4] (array ((_) @entry.inner . ","? @entry.outer) @entry.outer) ; Tests in QML are written using "Qt Quick Test" and it's `TestCase` type ; ref: https://doc.qt.io/qt-6/qtquicktest-index.html ((ui_object_definition type_name: (identifier) @_name initializer: (_) @test.inner) @test.outer (#equal @_name "TestCase")) ================================================ FILE: treesit-queries/rescript/textobjects.scm ================================================ ; Classes (modules) ;------------------ (module_binding definition: ((_) @class.inner)) @class.outer ; Blocks ;------- (block (_) @function.inner) @function.outer ; Functions ;---------- (function body: (_) @function.inner) @function.outer ; Calls ;------ (call_expression arguments: ((_) @parameter.inner)) @parameter.outer ; Comments ;--------- (comment) @comment.inner (comment)+ @comment.outer ; Parameters ;----------- (function parameter: (_) @parameter.inner @parameter.outer) (formal_parameters "," . (_) @parameter.inner @parameter.outer) (formal_parameters . (_) @parameter.inner . ","? @parameter.outer) (arguments "," @_arguments_start . (_) @parameter.inner @parameter.outer) (arguments . (_) @parameter.inner . ","? @parameter.outer) (function_type_parameters "," . (_) @parameter.inner @parameter.outer) (function_type_parameters . (_) @parameter.inner . ","? @parameter.outer) (functor_parameters "," . (_) @parameter.inner @parameter.outer) (functor_parameters . (_) @parameter.inner . ","? @parameter.outer) (type_parameters "," . (_) @parameter.inner @parameter.outer) (type_parameters . (_) @parameter.inner . ","? @parameter.outer) (type_arguments "," . (_) @parameter.inner @parameter.outer) (type_arguments . (_) @parameter.inner . ","? @parameter.outer) (decorator_arguments "," . (_) @parameter.inner @parameter.outer) (decorator_arguments . (_) @parameter.inner . ","? @parameter.outer) (variant_parameters "," . (_) @parameter.inner @parameter.outer) (variant_parameters . (_) @parameter.inner . ","? @parameter.outer) (polyvar_parameters "," . (_) @parameter.inner @parameter.outer) (polyvar_parameters . (_) @parameter.inner . ","? @parameter.outer) ================================================ FILE: treesit-queries/robots.txt/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (rule (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/rshtml/textobjects.scm ================================================ (raw_block (html_text)? @entry.inner) @entry.outer (section_block body: (_)? @entry.inner) @entry.outer (rust_block content: (rust_text)? @entry.inner) @entry.outer (if_stmt body: (_)? @entry.inner) @entry.outer (while_stmt body: (_)? @entry.inner) @entry.outer (for_stmt body: (_)? @entry.inner) @entry.outer (match_stmt (match_stmt_arm) @entry.inner) (match_stmt (match_stmt_arm)+ @entry.inner) @entry.outer (component_tag (component_tag_parameter (rust_identifier) @parameter.inner) @parameter.outer) (component_tag body: (component_tag_body)? @entry.inner) @entry.outer (comment_block (comment_content) @comment.inner) @comment.outer ================================================ FILE: treesit-queries/ruby/textobjects.scm ================================================ ; Class and Modules (class body: (_)? @class.inner) @class.outer (singleton_class value: (_) (_)+ @class.inner) @class.outer (call receiver: (constant) @class_const method: (identifier) @class_method (#match "Class" @class_const) (#match "new" @class_method) (do_block (_)+ @class.inner)) @class.outer (module body: (_)? @class.inner) @class.outer ; Functions and Blocks (singleton_method body: (_)? @function.inner) @function.outer (method body: (_)? @function.inner) @function.outer (do_block body: (_)? @function.inner) @function.outer (block body: (_)? @function.inner) @function.outer ; Parameters (method_parameters (_) @parameter.inner) @parameter.outer (block_parameters (_) @parameter.inner) @parameter.outer (lambda_parameters (_) @parameter.inner) @parameter.outer ; Comments (comment) @comment.inner (comment)+ @comment.outer (pair (_) @entry.inner) @entry.outer (array (_) @entry.outer) (string_array (_) @entry.outer) (symbol_array (_) @entry.outer) ================================================ FILE: treesit-queries/rust/textobjects.scm ================================================ (function_item body: (_) @function.inner) @function.outer (closure_expression body: (_) @function.inner) @function.outer (struct_item body: (_) @class.inner) @class.outer (enum_item body: (_) @class.inner) @class.outer (union_item body: (_) @class.inner) @class.outer (trait_item body: (_) @class.inner) @class.outer (impl_item body: (_) @class.inner) @class.outer (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (closure_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (field_initializer_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) [ (line_comment) (block_comment) ] @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.outer (; #[test] (attribute_item (attribute (identifier) @_test_attribute)) ; allow other attributes like #[should_panic] and comments [ (attribute_item) (line_comment) ]* ; the test function (function_item body: (_) @test.inner) @test.outer (#equal @_test_attribute "test")) (array_expression (_) @entry.outer) (tuple_expression (_) @entry.outer) (tuple_pattern (_) @entry.outer) ; Commonly used vec macro initializer is special cased (macro_invocation (identifier) @_id (token_tree (_) @entry.outer) (#equal @_id "vec")) (enum_variant) @entry.outer (field_declaration (_) @entry.inner) @entry.outer (field_initializer (_) @entry.inner) @entry.outer (shorthand_field_initializer) @entry.outer ;; Additional queries (loop_expression body: (_) @loop.inner) @loop.outer (while_expression body: (_) @loop.inner) @loop.outer (for_expression body: (_) @loop.inner) @loop.outer (if_expression consequence: (_) @conditional.inner) @conditional.outer ================================================ FILE: treesit-queries/rust-format-args-macro/textobjects.scm ================================================ ; inherits: rust ================================================ FILE: treesit-queries/sage/textobjects.scm ================================================ ; inherits: python ================================================ FILE: treesit-queries/scala/textobjects.scm ================================================ ; Function queries (function_definition body: (_) @function.inner) @function.outer ; Does not include end marker (lambda_expression (_) @function.inner) @function.outer ; Scala 3 braceless lambda (colon_argument (_) @function.inner) @function.outer ; Class queries (object_definition body: (_)? @class.inner) @class.outer (class_definition body: (_)? @class.inner) @class.outer (trait_definition body: (_)? @class.inner) @class.outer (type_definition) @class.outer (enum_case_definitions) @class.outer (enum_definition body: (_)? @class.inner) @class.outer ; Parameter queries (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (class_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (parameter_types ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (bindings ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ; Does not match context bounds or higher-kinded types (type_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ; Comment queries [(comment) (block_comment)] @comment.inner [(comment) (block_comment)] @comment.outer ; Does not match consecutive block comments ; Test queries ; Not supported ================================================ FILE: treesit-queries/scheme/textobjects.scm ================================================ [ (comment) (block_comment) ] @comment.inner (comment)+ @comment.outer (block_comment) @comment.outer ================================================ FILE: treesit-queries/shellcheckrc/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer [ (disable_directive) (enable_directive) (extended_analysis_directive) (external_sources_directive) (source_directive) (source_path_directive) (shell_directive) ] @entry.outer ================================================ FILE: treesit-queries/slang/textobjects.scm ================================================ (function_definition body: (_) @function.inner) @function.outer (struct_specifier body: (_) @class.inner) @class.outer (interface_specifier body: (_) @class.inner) @class.outer (enum_specifier body: (_) @class.inner) @class.outer (union_specifier body: (_) @class.inner) @class.outer (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer (enumerator (_) @entry.inner) @entry.outer (initializer_list (_) @entry.outer) ================================================ FILE: treesit-queries/slint/textobjects.scm ================================================ (function_definition (imperative_block) @function.inner) @function.outer (callback_event (imperative_block) @function.inner) @function.outer (property (imperative_block) @function.inner) @function.outer (struct_definition (struct_block) @class.inner) @class.outer (enum_definition (enum_block) @class.inner) @class.outer (global_definition (global_block) @class.inner) @class.outer (component_definition (block) @class.inner) @class.outer (component_definition (block) @class.inner) @class.outer (comment) @comment.outer (typed_identifier name: (_) @parameter.inner) @parameter.outer (callback arguments: (_) @parameter.inner) (string_value "\"" . (_) @text.inner . "\"") @text.outer ================================================ FILE: treesit-queries/solidity/textobjects.scm ================================================ (function_definition body: (_) @function.inner) @function.outer (constructor_definition body: (_) @function.inner) @function.outer (fallback_receive_definition body: (_) @function.inner) @function.outer (yul_function_definition (yul_block) @function.inner) @function.outer (function_definition ((parameter) @parameter.inner . ","? @parameter.outer) @parameter.outer) (constructor_definition ((parameter) @parameter.inner . ","? @parameter.outer) @parameter.outer) (return_type_definition ((parameter) @entry.inner . ","? @entry.outer) @entry.outer) (modifier_definition ((parameter) @parameter.inner . ","? @parameter.outer) @parameter.outer) (event_definition ((event_parameter) @parameter.inner . ","? @parameter.outer) @parameter.outer) (error_declaration ((error_parameter) @parameter.inner . ","? @parameter.outer) @parameter.outer) (call_argument ((call_struct_argument) @entry.inner . ","? @entry.outer) @entry.outer) (call_expression ((call_argument) @parameter.inner . ","? @parameter.outer) @parameter.outer) (variable_declaration_tuple ((variable_declaration) @entry.inner . ","? @entry.outer) @entry.outer) (emit_statement ((call_argument) @parameter.inner . ","? @parameter.outer) @parameter.outer) (revert_arguments ((call_argument) @parameter.inner . ","? @parameter.outer) @parameter.outer) (struct_declaration body: (_) @class.inner) @class.outer (enum_declaration body: (_) @class.inner) @class.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/sourcepawn/textobjects.scm ================================================ (function_definition body: (_) @function.inner) @function.outer (alias_declaration body: (_) @function.inner) @function.outer (enum_struct_method body: (_) @function.inner) @function.outer (methodmap_method body: (_) @function.inner) @function.outer (methodmap_method_constructor body: (_) @function.inner) @function.outer (methodmap_method_destructor body: (_) @function.inner) @function.outer (methodmap_property_method body: (_) @function.inner) @function.outer (enum_struct) @class.outer (methodmap) @class.outer (parameter_declarations ((parameter_declaration) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.outer ================================================ FILE: treesit-queries/sql/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/starlark/textobjects.scm ================================================ ; inherits: python ================================================ FILE: treesit-queries/sway/textobjects.scm ================================================ (function_item body: (_) @function.inner) @function.outer(closure_expression body: (_) @function.inner) @function.outer (struct_item body: (_) @class.inner) @class.outer (enum_item body: (_) @class.inner) @class.outer (trait_item body: (_) @class.inner) @class.outer (impl_item body: (_) @class.inner) @class.outer (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (type_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (closure_parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) [ (line_comment) (block_comment) ] @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.outer (; #[test] (attribute_item (attribute (identifier) @_test_attribute)) ; allow other attributes like #[should_panic] and comments [ (attribute_item) (line_comment) ]* ; the test function (function_item body: (_) @test.inner) @test.outer (#equal @_test_attribute "test")) ================================================ FILE: treesit-queries/swift/textobjects.scm ================================================ (class_declaration body: (_) @class.inner) @class.outer (protocol_declaration body: (_) @class.inner) @class.outer (function_declaration body: (_) @function.inner) @function.outer (parameter (_) @parameter.inner) @parameter.outer (lambda_parameter (_) @parameter.inner) @parameter.outer [ (comment) (multiline_comment) ] @comment.inner (comment)+ @comment.outer (multiline_comment) @comment.outer ================================================ FILE: treesit-queries/tablegen/textobjects.scm ================================================ (class body: (_) @class.inner) @class.outer (multiclass body: (_) @class.inner) @class.outer (_ argument: _ @parameter.inner) [ (comment) (multiline_comment) ] @comment.inner (comment)+ @comment.outer (multiline_comment) @comment.outer ================================================ FILE: treesit-queries/tact/textobjects.scm ================================================ ; function.inside & around ; ------------------------ (static_function body: (_) @function.inner) @function.outer (init_function body: (_) @function.inner) @function.outer (bounced_function body: (_) @function.inner) @function.outer (receive_function body: (_) @function.inner) @function.outer (external_function body: (_) @function.inner) @function.outer (function body: (_) @function.inner) @function.outer ; class.inside & around ; --------------------- (struct body: (_) @class.inner) @class.outer (message body: (_) @class.inner) @class.outer (contract body: (_) @class.inner) @class.outer ; NOTE: Marked as @definition.interface in tags, as it's semantically correct (trait body: (_) @class.inner) @class.outer ; parameter.inside & around ; ------------------------- (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (instance_argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) ; comment.inside ; -------------- (comment) @comment.inner ; comment.around ; -------------- (comment)+ @comment.outer ================================================ FILE: treesit-queries/textproto/textobjects.scm ================================================ (message_field (_) @entry.inner) @entry.outer (scalar_field (_) @entry.inner) @entry.outer (message_list (_) @entry.outer) (scalar_list (_) @entry.outer) ================================================ FILE: treesit-queries/tilt/textobjects.scm ================================================ ; inherits: python ================================================ FILE: treesit-queries/toml/textobjects.scm ================================================ (pair (_) @entry.inner) @entry.outer (array (_) @entry.outer) (comment)+ @comment.outer ================================================ FILE: treesit-queries/tsx/textobjects.scm ================================================ ; See runtime/queries/ecma/README.md for more info. ; inherits: _jsx,_typescript,ecma ================================================ FILE: treesit-queries/typescript/textobjects.scm ================================================ ; See runtime/queries/ecma/README.md for more info. ; inherits: _typescript,ecma ================================================ FILE: treesit-queries/typespec/textobjects.scm ================================================ ; Classes (enum_statement (enum_body) @class.inner) @class.outer (model_statement (model_expression) @class.inner) @class.outer (union_statement (union_body) @class.inner) @class.outer ; Interfaces (interface_statement (interface_body (interface_member) @function.outer) @class.inner) @class.outer ; Comments [ (single_line_comment) (multi_line_comment) ] @comment.inner [ (single_line_comment) (multi_line_comment) ]+ @comment.outer ; Functions [ (decorator) (decorator_declaration_statement) (function_declaration_statement) (operation_statement) ] @function.outer (function_parameter_list (function_parameter)? @parameter.inner)* @function.inner (decorator_arguments (expression_list (_) @parameter.inner)*) @function.inner (operation_arguments (model_property)? @parameter.inner)* @function.inner (template_parameters (template_parameter_list (template_parameter) @parameter.inner)) @function.inner ================================================ FILE: treesit-queries/unison/textobjects.scm ================================================ (term_declaration) @function.outer (type_declaration) @class.inner (record) @class.inner (comment) @comment.inner (comment)+ @comment.outer (doc_block) @comment.outer (literal_list) @entry.outer (parenthesized_or_tuple_pattern) @entry.outer (pattern) @entry.outer ================================================ FILE: treesit-queries/v/textobjects.scm ================================================ (function_declaration body: (block)? @function.inner) @function.outer ((function_declaration name: (identifier) @_name body: (block)? @test.inner) @test.outer (#match "^test" @_name)) (function_literal body: (block)? @function.inner) @function.outer (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (call_expression (argument_list ((_) @parameter.inner) @parameter.outer)) (struct_declaration (struct_field_declaration) @class.inner) @class.outer (struct_field_declaration ((_) @parameter.inner) @parameter.outer) [(line_comment) (block_comment)] @comment.inner [(line_comment)+ (block_comment)+] @comment.outer ================================================ FILE: treesit-queries/vala/textobjects.scm ================================================ (method_declaration (block) @function.inner) @function.outer (creation_method_declaration (block) @function.inner) @function.outer (method_declaration ((parameter) @parameter.inner . ","? @parameter.outer) @parameter.outer) [ (class_declaration) (struct_declaration) (interface_declaration) ] @class.outer (type_arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (creation_method_declaration ((parameter) @parameter.inner . ","? @parameter.outer) @parameter.outer) (method_call_expression ((argument) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/verilog/textobjects.scm ================================================ (function_declaration (function_body_declaration (function_identifier (function_identifier (simple_identifier) @function.inner)))) @function.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/wesl/textobjects.scm ================================================ (function_decl body: (_) @function.inner) @function.outer (struct_decl body: (_) @class.inner) @class.outer (param_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (argument_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (template_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) [ (line_comment) (block_comment) ] @comment.inner (line_comment)+ @comment.outer (block_comment) @comment.outer ================================================ FILE: treesit-queries/wgsl/textobjects.scm ================================================ (function_declaration body: (_) @function.inner) @function.outer (struct_declaration) @class.outer [ (struct_member) (parameter) (variable_declaration) ] @parameter.outer (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/woodpecker-ci/textobjects.scm ================================================ ; inherits: yaml ================================================ FILE: treesit-queries/wren/textobjects.scm ================================================ (class_definition (class_body) @class.inner) @class.outer (call_expression (call_body (_) @function.inner) @function.outer) (method_definition body: (_) @function.inner) @function.outer (parameter_list ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer ================================================ FILE: treesit-queries/xml/textobjects.scm ================================================ (element (start_tag) (_)* @xml-element.inner (end_tag)) (element) @xml-element.outer (comment) @comment.outer ================================================ FILE: treesit-queries/yaml/textobjects.scm ================================================ (comment) @comment.inner (comment)+ @comment.outer (block_mapping_pair (_) @entry.inner) @entry.outer ================================================ FILE: treesit-queries/zig/textobjects.scm ================================================ (function_declaration body: (_) @function.inner) @function.outer (test_declaration (_) (block) @test.inner) @test.outer ; matches all of: struct, enum, union ; this unfortunately cannot be split up because ; of the way struct "container" types are defined (variable_declaration (identifier) (struct_declaration (_) @class.inner)) @class.outer (variable_declaration (identifier) (enum_declaration (_) @class.inner)) @class.outer (variable_declaration (identifier) (enum_declaration (_) @class.inner)) @class.outer (parameters ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (arguments ((_) @parameter.inner . ","? @parameter.outer) @parameter.outer) (comment) @comment.inner (comment)+ @comment.outer