├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ └── config.yml └── workflows │ ├── ci.yml │ ├── nightly.yml │ └── release-please.yml ├── .gitignore ├── .luarc.json ├── .release-please-manifest.json ├── .stylua.toml ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── doc └── nvim-treesitter-context.txt ├── lua ├── treesitter-context.lua └── treesitter-context │ ├── cache.lua │ ├── cli.lua │ ├── config.lua │ ├── context.lua │ ├── render.lua │ └── util.lua ├── plugin └── treesitter-context.lua ├── queries ├── ada │ └── context.scm ├── apex │ └── context.scm ├── bash │ └── context.scm ├── c │ └── context.scm ├── c_sharp │ └── context.scm ├── capnp │ └── context.scm ├── clojure │ └── context.scm ├── cmake │ └── context.scm ├── cpp │ └── context.scm ├── css │ └── context.scm ├── cuda │ └── context.scm ├── cue │ └── context.scm ├── d │ └── context.scm ├── dart │ └── context.scm ├── devicetree │ └── context.scm ├── diff │ └── context.scm ├── elixir │ └── context.scm ├── elm │ └── context.scm ├── enforce │ └── context.scm ├── fennel │ └── context.scm ├── fish │ └── context.scm ├── fortran │ └── context.scm ├── gdscript │ └── context.scm ├── glimmer │ └── context.scm ├── glsl │ └── context.scm ├── go │ └── context.scm ├── graphql │ └── context.scm ├── groovy │ └── context.scm ├── haskell │ └── context.scm ├── html │ └── context.scm ├── ini │ └── context.scm ├── janet_simple │ └── context.scm ├── java │ └── context.scm ├── javascript │ └── context.scm ├── json │ └── context.scm ├── jsonnet │ └── context.scm ├── julia │ └── context.scm ├── kdl │ └── context.scm ├── latex │ └── context.scm ├── liquidsoap │ └── context.scm ├── lua │ └── context.scm ├── make │ └── context.scm ├── markdown │ └── context.scm ├── matlab │ └── context.scm ├── nim │ └── context.scm ├── nix │ └── context.scm ├── nu │ └── context.scm ├── objdump │ └── context.scm ├── ocaml │ └── context.scm ├── ocaml_interface │ └── context.scm ├── odin │ └── context.scm ├── php │ └── context.scm ├── php_only │ └── context.scm ├── prisma │ └── context.scm ├── proto │ └── context.scm ├── python │ └── context.scm ├── r │ └── context.scm ├── ruby │ └── context.scm ├── rust │ └── context.scm ├── scala │ └── context.scm ├── scss │ └── context.scm ├── smali │ └── context.scm ├── solidity │ └── context.scm ├── starlark │ └── context.scm ├── svelte │ └── context.scm ├── swift │ └── context.scm ├── tact │ └── context.scm ├── tcl │ └── context.scm ├── teal │ └── context.scm ├── templ │ └── context.scm ├── terraform │ └── context.scm ├── toml │ └── context.scm ├── tsx │ └── context.scm ├── typescript │ └── context.scm ├── typoscript │ └── context.scm ├── typst │ └── context.scm ├── usd │ └── context.scm ├── verilog │ └── context.scm ├── vhdl │ └── context.scm ├── vim │ └── context.scm ├── vue │ └── context.scm ├── xml │ └── context.scm ├── yaml │ └── context.scm ├── yang │ └── context.scm └── zig │ └── context.scm ├── release-please-config.json ├── static └── demo.gif └── test ├── contexts_spec.lua ├── helpers.lua ├── lang ├── test.Makefile ├── test.adb ├── test.apex ├── test.bash ├── test.bzl ├── test.c ├── test.capnp ├── test.clj ├── test.cmake ├── test.cpp ├── test.cs ├── test.css ├── test.cu ├── test.cue ├── test.d ├── test.dart ├── test.diff ├── test.dts ├── test.elm ├── test.enforce ├── test.ex ├── test.f90 ├── test.fish ├── test.fnl ├── test.gd ├── test.glsl ├── test.go ├── test.graphql ├── test.groovy ├── test.hbs ├── test.hs ├── test.html ├── test.ini ├── test.janet ├── test.java ├── test.jl ├── test.js ├── test.json ├── test.jsonnet ├── test.kdl ├── test.latex ├── test.liq ├── test.lua ├── test.m ├── test.md ├── test.ml ├── test.nim ├── test.nix ├── test.norg ├── test.nu ├── test.objdump ├── test.odin ├── test.org ├── test.php ├── test.prisma ├── test.proto ├── test.py ├── test.r ├── test.rb ├── test.rs ├── test.scala ├── test.scss ├── test.smali ├── test.sol ├── test.svelte ├── test.swift ├── test.tact ├── test.tcl ├── test.templ ├── test.tf ├── test.tl ├── test.toml ├── test.ts ├── test.tsx ├── test.typ ├── test.typoscript ├── test.usd ├── test.v ├── test.vhd ├── test.vim ├── test.vue ├── test.xml ├── test.yang ├── test.yml └── test.zig ├── queries_spec.lua ├── snapshots ├── snapshot.cpp ├── snapshot.md ├── snapshot.php ├── snapshot.rs └── snapshot.ts ├── test.c ├── test_file.lua └── ts_context_spec.lua /.gitattributes: -------------------------------------------------------------------------------- 1 | /test/* -linguist-detectable 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [lewis6991] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yaml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Report a problem with nvim-treesitter-context 3 | type: bug 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: > 8 | Before reporting make sure that both nvim-treesitter-context is 9 | updated to the latest version. 10 | - type: textarea 11 | attributes: 12 | label: "Description" 13 | description: "A comprehensive description of the problem you are reporting." 14 | validations: 15 | required: true 16 | - type: input 17 | attributes: 18 | label: "Neovim version" 19 | description: | 20 | Output of `nvim --version` 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: "Expected behavior" 26 | description: "A description of the behavior you expected:" 27 | - type: textarea 28 | attributes: 29 | label: "Actual behavior" 30 | description: "Observed behavior (may optionally include images, or videos)." 31 | validations: 32 | required: true 33 | - type: textarea 34 | attributes: 35 | label: "Minimal config" 36 | description: > 37 | Minimal(!) configuration necessary to reproduce the issue. Save this as 38 | `minimal.lua`. If necessary, add plugins and config options from your 39 | `init.lua` at the indicated lines. 40 | render: Lua 41 | value: | 42 | local plugins = { 43 | ts = 'https://github.com/nvim-treesitter/nvim-treesitter', 44 | ts_context = 'https://github.com/nvim-treesitter/nvim-treesitter-context', 45 | -- ADD ADDITIONAL PLUGINS THAT ARE _NECESSARY_ TO REPRODUCE THE ISSUE 46 | } 47 | 48 | for name, url in pairs(plugins) do 49 | local install_path = '/tmp/nvim/site/'..name 50 | if vim.fn.isdirectory(install_path) == 0 then 51 | vim.fn.system { 'git', 'clone', '--depth=1', url, install_path } 52 | end 53 | vim.o.runtimepath = install_path..','..vim.o.runtimepath 54 | end 55 | 56 | -- ADD INIT.LUA SETTINGS THAT IS _NECESSARY_ FOR REPRODUCING THE ISSUE 57 | validations: 58 | required: true 59 | - type: textarea 60 | attributes: 61 | label: "Steps to reproduce" 62 | description: "Steps to reproduce using the minimal config provided." 63 | value: | 64 | 1. `nvim --clean -u minimal.lua` 65 | 2. ... 66 | validations: 67 | required: true 68 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | commit_lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | # Check commit messages 15 | - uses: webiny/action-conventional-commits@v1.1.0 16 | 17 | stylua: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | 23 | - name: Download stylua 24 | run: make stylua 25 | 26 | - name: Lint 27 | run: make stylua-check 28 | 29 | luals: 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v4 34 | 35 | - uses: lewis6991/gh-actions-lua@master 36 | with: 37 | luaVersion: "5.1.5" 38 | 39 | - uses: leafo/gh-actions-luarocks@v4 40 | 41 | - name: Download nvim-test 42 | run: make nvim-test 43 | 44 | - name: LuaLS 45 | run: make luals-check 46 | 47 | test: 48 | runs-on: ubuntu-latest 49 | 50 | strategy: 51 | fail-fast: false 52 | matrix: 53 | neovim_version: 54 | - 'v0.11.1' 55 | 56 | env: 57 | NVIM_TEST_VERSION: ${{ matrix.neovim_version }} 58 | 59 | steps: 60 | - name: Checkout 61 | uses: actions/checkout@v4 62 | 63 | - uses: lewis6991/gh-actions-lua@master 64 | with: 65 | luaVersion: "5.1.5" 66 | 67 | - uses: leafo/gh-actions-luarocks@v4 68 | 69 | - uses: tree-sitter/setup-action/cli@v1 70 | 71 | - name: Download nvim-test 72 | run: make nvim-test 73 | 74 | - name: Download nvim-treesitter 75 | run: make nvim-treesitter 76 | 77 | - name: Parsers Cache 78 | uses: actions/cache@v4 79 | with: 80 | path: ./nvim-treesitter/parser/ 81 | key: parsers-${{ join(matrix.*, '-') }}-${{ hashFiles( 82 | './nvim-treesitter/lockfile.json', 83 | './nvim-treesitter/lua/nvim-treesitter/install.lua', 84 | './nvim-treesitter/lua/nvim-treesitter/parsers.lua') }} 85 | 86 | - name: Install parsers 87 | run: make parsers 88 | 89 | - name: Run Test 90 | run: make test 91 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: Nightly 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | push: 7 | branches: [ master ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | test: 12 | runs-on: ubuntu-latest 13 | 14 | permissions: 15 | contents: write 16 | 17 | env: 18 | NVIM_TS_SHA: main 19 | 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | 24 | - uses: leafo/gh-actions-lua@v11 25 | with: 26 | luaVersion: "5.1.5" 27 | 28 | - uses: leafo/gh-actions-luarocks@v4 29 | 30 | - uses: tree-sitter/setup-action/cli@v1 31 | 32 | - name: Download nvim-test 33 | run: make nvim-test 34 | 35 | - name: Download nvim-treesitter 36 | run: make nvim-treesitter 37 | 38 | - name: Parsers Cache 39 | uses: actions/cache@v4 40 | with: 41 | path: ./nvim-treesitter/parser/ 42 | key: parsers-${{ join(matrix.*, '-') }}-${{ hashFiles( 43 | './deps/nvim-treesitter/lua/nvim-treesitter/parsers.lua') }} 44 | 45 | - name: Install parsers 46 | run: make parsers 47 | 48 | - name: Run Test 49 | run: make test 50 | 51 | # - uses: stefanzweifel/git-auto-commit-action@v5 52 | # with: 53 | # commit_message: "docs: Update README.md" 54 | -------------------------------------------------------------------------------- /.github/workflows/release-please.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | workflow_dispatch: 6 | 7 | permissions: 8 | contents: write 9 | pull-requests: write 10 | 11 | name: release-please 12 | 13 | jobs: 14 | release-please: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: googleapis/release-please-action@v4 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | deps 3 | -------------------------------------------------------------------------------- /.luarc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json", 3 | "runtime": { 4 | "version": "LuaJIT" 5 | }, 6 | "workspace.library": [ 7 | "$VIMRUNTIME", 8 | "${3rd}/busted/library", 9 | "${3rd}/luv/library", 10 | "deps/nvim-test" 11 | ], 12 | "workspace.checkThirdParty": false, 13 | "diagnostics": { 14 | "groupFileStatus": { 15 | "strict": "Opened", 16 | "strong": "Opened" 17 | }, 18 | "groupSeverity": { 19 | "strong": "Warning", 20 | "strict": "Warning" 21 | }, 22 | "unusedLocalExclude": [ "_*" ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "1.0.0" 3 | } 4 | -------------------------------------------------------------------------------- /.stylua.toml: -------------------------------------------------------------------------------- 1 | syntax = "Lua52" 2 | column_width = 100 3 | line_endings = "Unix" 4 | indent_type = "Spaces" 5 | indent_width = 2 6 | quote_style = "AutoPreferSingle" 7 | call_parentheses = "Always" 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Adding support for other languages 2 | 3 | ### Composing `context.scm` queries 4 | 5 | To add support for another language, simply add a `context.scm` file under 6 | `queries/[LANG]`. 7 | 8 | Queries specify the `@context` capture which specifies the first line of a node 9 | will be used for the context. 10 | 11 | Here is a basic example for C: 12 | 13 | ```query 14 | (function_definition) @context 15 | (for_statement) @context 16 | (if_statement) @context 17 | (while_statement) @context 18 | (do_statement) @context 19 | ``` 20 | 21 | You can look at a node names of a tree using `:InspectTree`. 22 | 23 | Additionally an optional `@context.end` capture can also be specified. When 24 | provided, the text from the start of the `@context` capture to the start of 25 | `@context.end` capture (exclusive) will be used for the context and joined into 26 | a single line. 27 | 28 | Here's what that looks like for C: 29 | 30 | ```query 31 | (if_statement consequence: (_ (_) @context.end)) @context 32 | ``` 33 | 34 | This query specifies that everything from the `if` keyword up-to the first 35 | statement (exclusive) should be used for the context. This is useful when an 36 | if-statement spans multiple lines. 37 | 38 | ### Committing your changes 39 | 40 | Your commit messages should follow the [Conventional Commits specification](https://conventionalcommits.org). 41 | 42 | Good: 43 | 44 | ``` 45 | feat(lua): added lua support 46 | ``` 47 | 48 | Bad: 49 | 50 | ``` 51 | added lua support 52 | ``` 53 | 54 | > You can do `git commit --amend` followed by `git push --force` if you made a mistake. 55 | 56 | ### Raising a pull request 57 | 58 | A pull request for supporting a new language requires: 59 | 60 | 1. Adding `queries/[LANG]/context.scm` as explained in the previous section. 61 | 62 | 2. Adding `test/lang/test.[LANG]` or `test/lang/test.[LANG].[EXT]` with code examples the `context.scm` is designed to support. 63 | - These test files use custom comment directives to annotate what lines should be a context. It has the format. 64 | 65 | ```c 66 | // {{TEST}} -- mark start of test 67 | 68 | int main() { // {{CONTEXT}} -- mark line as a context 69 | 70 | 71 | // {{CURSOR}} -- where cursor needs to be for contexts to be shown. 72 | 73 | } 74 | ``` 75 | 76 | See `test/lang/test.c` for examples. 77 | 78 | 3. Run `make test`. This should automatically update README.md to mark `[LANG]` as supported. 79 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright * romgrk 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .DEFAULT_GOAL := test 2 | 3 | export XDG_DATA_HOME ?= $(HOME)/.data 4 | 5 | # ------------------------------------------------------------------------------ 6 | # nvim-treesitter 7 | # ------------------------------------------------------------------------------ 8 | 9 | NVIM_TS_SHA ?= 61b0a05e 10 | NVIM_TS := deps/nvim-treesitter 11 | 12 | .PHONY: nvim-treesitter 13 | nvim-treesitter: $(NVIM_TS) 14 | 15 | $(NVIM_TS): 16 | git clone \ 17 | --filter=blob:none \ 18 | https://github.com/nvim-treesitter/nvim-treesitter $@ 19 | cd $@ && git checkout $(NVIM_TS_SHA) 20 | 21 | # ------------------------------------------------------------------------------ 22 | # Nvim-test 23 | # ------------------------------------------------------------------------------ 24 | 25 | FILTER=.* 26 | 27 | export NVIM_TEST_VERSION ?= v0.11.1 28 | export NVIM_RUNNER_VERSION ?= v0.11.1 29 | 30 | NVIM_TEST := deps/nvim-test 31 | NVIM_TEST_REV = v1.1.0 32 | 33 | .PHONY: nvim-test 34 | nvim-test: $(NVIM_TEST) 35 | 36 | $(NVIM_TEST): 37 | git clone \ 38 | --filter=blob:none \ 39 | --branch $(NVIM_TEST_REV) \ 40 | https://github.com/lewis6991/nvim-test $@ 41 | $(NVIM_TEST)/bin/nvim-test --init 42 | 43 | .PHONY: test 44 | test: $(NVIM_TEST) $(NVIM_TS) 45 | $(NVIM_TEST)/bin/nvim-test test \ 46 | --runner_version $(NVIM_RUNNER_VERSION) \ 47 | --target_version $(NVIM_TEST_VERSION) \ 48 | --lpath=$(PWD)/lua/?.lua \ 49 | --filter="$(FILTER)" \ 50 | --verbose 51 | 52 | .PHONY: parsers 53 | parsers: $(NVIM_TEST) $(NVIM_TS) 54 | $(XDG_DATA_HOME)/nvim-test/nvim-runner-$(NVIM_RUNNER_VERSION)/bin/nvim \ 55 | -l test/helpers.lua install 56 | 57 | # ------------------------------------------------------------------------------ 58 | # LuaLS 59 | # ------------------------------------------------------------------------------ 60 | 61 | ifeq ($(shell uname -m),arm64) 62 | LUALS_ARCH ?= arm64 63 | else 64 | LUALS_ARCH ?= x64 65 | endif 66 | 67 | LUALS_VERSION := 3.13.6 68 | LUALS := deps/lua-language-server-$(LUALS_VERSION)-$(shell uname -s)-$(LUALS_ARCH) 69 | LUALS_TARBALL := $(LUALS).tar.gz 70 | LUALS_URL := https://github.com/LuaLS/lua-language-server/releases/download/$(LUALS_VERSION)/$(notdir $(LUALS_TARBALL)) 71 | 72 | .PHONY: luals 73 | luals: $(LUALS) 74 | 75 | $(LUALS): 76 | wget --directory-prefix=$(dir $@) $(LUALS_URL) 77 | mkdir -p $@ 78 | tar -xf $(LUALS_TARBALL) -C $@ 79 | rm -rf $(LUALS_TARBALL) 80 | 81 | .PHONY: luals-check 82 | luals-check: $(LUALS) $(NVIM_TEST) 83 | VIMRUNTIME=$(XDG_DATA_HOME)/nvim-test/nvim-test-$(NVIM_TEST_VERSION)/share/nvim/runtime \ 84 | $(LUALS)/bin/lua-language-server \ 85 | --configpath=../.luarc.json \ 86 | --check=lua 87 | 88 | # ------------------------------------------------------------------------------ 89 | # Stylua 90 | # ------------------------------------------------------------------------------ 91 | ifeq ($(shell uname -s),Darwin) 92 | STYLUA_PLATFORM := macos-aarch64 93 | else 94 | STYLUA_PLATFORM := linux-x86_64 95 | endif 96 | 97 | # ------------------------------------------------------------------------------ 98 | # Stylua 99 | # ------------------------------------------------------------------------------ 100 | 101 | STYLUA_VERSION := v2.1.0 102 | STYLUA_ZIP := stylua-$(STYLUA_PLATFORM).zip 103 | STYLUA_URL := https://github.com/JohnnyMorganz/StyLua/releases/download/$(STYLUA_VERSION)/$(STYLUA_ZIP) 104 | STYLUA := deps/stylua 105 | 106 | .INTERMEDIATE: $(STYLUA_ZIP) 107 | $(STYLUA_ZIP): 108 | wget $(STYLUA_URL) 109 | 110 | .PHONY: stylua 111 | stylua: $(STYLUA) 112 | 113 | $(STYLUA): $(STYLUA_ZIP) 114 | unzip $< -d $(dir $@) 115 | 116 | LUA_FILES := $(shell git ls-files 'lua/*.lua' 'test/*_spec.lua') 117 | 118 | .PHONY: stylua-check 119 | stylua-check: $(STYLUA) 120 | $(STYLUA) --check $(LUA_FILES) 121 | @! grep -n -- '---.*nil' $(LUA_FILES) \ 122 | || (echo "Error: Found 'nil' in annotation, please use '?'" && exit 1) 123 | @! grep -n -- '---@' $(LUA_FILES) \ 124 | || (echo "Error: Found '---@' in Lua files, please use '--- @'" && exit 1) 125 | 126 | .PHONY: stylua-run 127 | stylua-run: $(STYLUA) 128 | $(STYLUA) $(LUA_FILES) 129 | perl -pi -e 's/---@/--- @/g' $(LUA_FILES) 130 | -------------------------------------------------------------------------------- /doc/nvim-treesitter-context.txt: -------------------------------------------------------------------------------- 1 | *nvim-treesitter-context* 2 | 3 | Authors: Rom Grk , 4 | Lewis Russell 5 | Version: NA 6 | Homepage: 7 | 8 | ============================================================================== 9 | INTRODUCTION *nvim-treesitter-context-intro* 10 | 11 | A plugin that shows the semantic context of the currently visible buffer 12 | region. Typically this context will be: the current function, if statement 13 | blocks, loops, etc. 14 | 15 | ============================================================================== 16 | CONFIGURATION *nvim-treesitter-context-config* 17 | 18 | Fields with default values are shown below. Note: calling `setup()` is 19 | not required. 20 | 21 | >lua 22 | require'treesitter-context'.setup({ 23 | -- Enable this plugin (Can be enabled/disabled later via commands) 24 | enable = true, 25 | 26 | -- Enable multiwindow support. 27 | multiwindow = false, 28 | 29 | -- How many lines the window should span. Values <= 0 mean no limit. 30 | -- Can be '%' like '30%' - to specify percentage of win.height 31 | max_lines = 0, 32 | 33 | -- Minimum editor window height to enable context. Values <= 0 mean no 34 | -- limit. 35 | min_window_height = 0, 36 | 37 | -- Whether to show line numbers 38 | line_numbers = true, 39 | 40 | -- Maximum number of lines to show for a single context 41 | multiline_threshold = 20, 42 | 43 | -- Which context lines to discard if `max_lines` is exceeded. 44 | -- Choices: 'inner', 'outer' 45 | trim_scope = 'outer', 46 | 47 | -- Line used to calculate context. 48 | -- Choices: 'cursor', 'topline' 49 | mode = 'cursor', 50 | 51 | -- Separator between context and content. Should be a single character 52 | -- string, like '-'. When separator is set, the context will only show 53 | -- up when there are at least 2 lines above cursorline. 54 | separator = nil, 55 | 56 | -- The Z-index of the context window 57 | zindex = 20, 58 | 59 | -- (fun(buf: integer): boolean) return false to disable attaching 60 | on_attach = nil, 61 | }) 62 | < 63 | 64 | ============================================================================== 65 | COMMANDS *nvim-treesitter-context-commands* 66 | 67 | `TSContext` with subcommands `enable`, `disable` and `toggle` 68 | 69 | ============================================================================== 70 | HIGHLIGHTS *nvim-treesitter-context-highlights* 71 | 72 | 73 | `TreesitterContext` *hl-TreesitterContext* 74 | (default: links to `NormalFloat`) 75 | 76 | Colors of the context. 77 | 78 | `TreesitterContextLineNumber` *hl-TreesitterContextLineNumber* 79 | (default: links to `LineNr`) 80 | 81 | Used for the context line numbers if `line_numbers` is set. 82 | 83 | `TreesitterContextSeparator` *hl-TreesitterContextSeparator* 84 | (default: links to `FloatBorder`) 85 | 86 | Used for the colors of the separator if `separator` is set. 87 | 88 | `TreesitterContextBottom` *hl-TreesitterContextBottom* 89 | (default: links to `NONE`) 90 | 91 | Use for the last line of the context. 92 | 93 | `TreesitterContextLineNumberBottom` *hl-TreesitterContextLineNumberBottom* 94 | (default: links to `NONE`) 95 | 96 | Use for the last line of the context line number. 97 | 98 | A border can be created by applying an underline highlight, e.g, for an 99 | underline across the screen: 100 | >vim 101 | :highlight TreesitterContextBottom gui=underline guisp=Grey 102 | :highlight TreesitterContextLineNumberBottom gui=underline guisp=Grey 103 | < 104 | 105 | ============================================================================== 106 | FUNCTIONS *nvim-treesitter-context-functions* 107 | 108 | disable() *nvim-treesitter-context-disable()* 109 | 110 | enabled() *nvim-treesitter-context-enabled()* 111 | 112 | Returns: ~ 113 | `boolean` indication whether the context is enabled for this buffer. 114 | 115 | enable() *nvim-treesitter-context-enable()* 116 | 117 | go_to_context({depth}) *nvim-treesitter-context-go_to_context()* 118 | 119 | Jump to the context at {depth}. 120 | 121 | Example use in a keymap: 122 | >lua 123 | vim.keymap.set("n", "[c", function() 124 | require("treesitter-context").go_to_context(vim.v.count1) 125 | end, { silent = true }) 126 | < 127 | 128 | Parameters: ~ 129 | {depth} (`integer`, default: `1`) Depth to jump to. 130 | 131 | 132 | setup({config}) *nvim-treesitter-context-setup()* 133 | 134 | See |nvim-treesitter-context-config|. 135 | 136 | Parameters: ~ 137 | {config} (`table`) Configuration table. 138 | 139 | toggle() *nvim-treesitter-context-toggle()* 140 | Toggle the context. 141 | 142 | ------------------------------------------------------------------------------ 143 | vim:tw=78:ts=8:ft=help:norl: 144 | -------------------------------------------------------------------------------- /lua/treesitter-context/cache.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | ---Memoize a function using hash_fn to hash the arguments. 4 | --- @generic F: function 5 | --- @param fn F 6 | --- @param hash_fn fun(...): any 7 | --- @return F 8 | function M.memoize(fn, hash_fn) 9 | local cache = setmetatable({}, { __mode = 'kv' }) --- @type table 10 | 11 | return function(...) 12 | local key = hash_fn(...) 13 | if cache[key] == nil then 14 | local v = fn(...) --- @type any 15 | cache[key] = v ~= nil and v or vim.NIL 16 | end 17 | 18 | local v = cache[key] 19 | return v ~= vim.NIL and vim.deepcopy(v) or nil 20 | end 21 | end 22 | 23 | return M 24 | -------------------------------------------------------------------------------- /lua/treesitter-context/cli.lua: -------------------------------------------------------------------------------- 1 | local subcmds = { 'enable', 'disable', 'toggle' } 2 | 3 | local M = {} 4 | 5 | --- @param command string 6 | local function do_subcmd(command) 7 | local TSContext = require('treesitter-context') 8 | if TSContext[command] then 9 | TSContext[command]() 10 | else 11 | vim.notify('TSContext: Unknown command ' .. command, vim.log.levels.ERROR) 12 | end 13 | end 14 | 15 | --- @param args string[] 16 | function M.run(args) 17 | if #args == 0 then 18 | vim.ui.select(subcmds, { 19 | prompt = 'Treesitter Context: ', 20 | format_item = function(item) 21 | return item:sub(1, 1):upper() .. item:sub(2) 22 | end, 23 | }, function(choice) 24 | if choice then 25 | do_subcmd(choice) 26 | end 27 | end) 28 | return 29 | end 30 | 31 | do_subcmd(args[1]) 32 | end 33 | 34 | function M.complete() 35 | return subcmds 36 | end 37 | 38 | return M 39 | -------------------------------------------------------------------------------- /lua/treesitter-context/config.lua: -------------------------------------------------------------------------------- 1 | --- @class (exact) TSContext.Config 2 | --- @field enable boolean 3 | --- @field multiwindow boolean 4 | --- @field max_lines integer | string 5 | --- @field min_window_height integer 6 | --- @field line_numbers boolean 7 | --- @field multiline_threshold integer 8 | --- @field trim_scope 'outer'|'inner' 9 | --- @field zindex integer 10 | --- @field mode 'cursor'|'topline' 11 | --- @field separator? string 12 | --- @field on_attach? fun(buf: integer): boolean 13 | 14 | --- @class (exact) TSContext.UserConfig : TSContext.Config 15 | --- 16 | --- Enable this plugin (Can be enabled/disabled later via commands) 17 | --- @field enable? boolean 18 | --- 19 | --- Enable multiwindow support. 20 | --- @field multiwindow? boolean 21 | --- 22 | --- How many lines the window should span. Values <= 0 mean no limit. 23 | --- Can be '%' like '30%' - to specify percentage of win.height. 24 | --- @field max_lines? integer | string 25 | --- 26 | --- Minimum editor window height to enable context. Values <= 0 mean no limit. 27 | --- @field min_window_height? integer 28 | --- 29 | --- @field line_numbers? boolean 30 | --- 31 | --- Maximum number of lines to show for a single context 32 | --- @field multiline_threshold? integer 33 | --- 34 | --- Which context lines to discard if `max_lines` is exceeded. 35 | --- @field trim_scope? 'outer'|'inner' 36 | --- 37 | --- @field zindex? integer 38 | --- 39 | --- Line used to calculate context. 40 | --- @field mode? 'cursor'|'topline' 41 | --- 42 | --- Separator between context and content. Should be a single character string, like '-'. 43 | --- When separator is set, the context will only show up when there are at least 2 lines above cursorline. 44 | --- @field separator? string 45 | --- 46 | --- Callback when attaching. Return false to disable attaching 47 | --- @field on_attach? fun(buf: integer): boolean 48 | 49 | --- @type TSContext.Config 50 | local default_config = { 51 | enable = true, 52 | multiwindow = false, 53 | max_lines = 0, -- no limit 54 | min_window_height = 0, 55 | line_numbers = true, 56 | multiline_threshold = 20, 57 | trim_scope = 'outer', 58 | zindex = 20, 59 | mode = 'cursor', 60 | } 61 | 62 | local config = vim.deepcopy(default_config) 63 | 64 | local M = {} 65 | 66 | --- @param cfg TSContext.UserConfig 67 | function M.update(cfg) 68 | config = vim.tbl_deep_extend('force', config, cfg) 69 | end 70 | 71 | setmetatable(M, { 72 | __index = function(_, k) 73 | return config[k] 74 | end, 75 | }) 76 | 77 | return M --[[@as TSContext.Config]] 78 | -------------------------------------------------------------------------------- /lua/treesitter-context/util.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | --- @param r Range4 4 | --- @return integer 5 | function M.get_range_height(r) 6 | return r[3] - r[1] + (r[4] == 0 and 0 or 1) 7 | end 8 | 9 | return M 10 | -------------------------------------------------------------------------------- /plugin/treesitter-context.lua: -------------------------------------------------------------------------------- 1 | vim.api.nvim_create_user_command('TSContext', function(args) 2 | require('treesitter-context.cli').run(args.fargs) 3 | end, { 4 | complete = function() 5 | return require('treesitter-context.cli').complete() 6 | end, 7 | nargs = '*', 8 | desc = 'Manage Treesitter Context', 9 | }) 10 | 11 | vim.api.nvim_set_hl(0, 'TreesitterContext', { link = 'NormalFloat', default = true }) 12 | vim.api.nvim_set_hl(0, 'TreesitterContextLineNumber', { link = 'LineNr', default = true }) 13 | vim.api.nvim_set_hl(0, 'TreesitterContextBottom', { link = 'NONE', default = true }) 14 | vim.api.nvim_set_hl( 15 | 0, 16 | 'TreesitterContextLineNumberBottom', 17 | { link = 'TreesitterContextBottom', default = true } 18 | ) 19 | vim.api.nvim_set_hl(0, 'TreesitterContextSeparator', { link = 'FloatBorder', default = true }) 20 | -------------------------------------------------------------------------------- /queries/ada/context.scm: -------------------------------------------------------------------------------- 1 | (full_type_declaration 2 | (record_type_definition 3 | (record_definition (_) @context.end) 4 | ) 5 | ) @context 6 | 7 | 8 | ([ 9 | (loop_statement) 10 | (case_statement) 11 | (subprogram_body) 12 | (package_declaration) 13 | ] @context) 14 | -------------------------------------------------------------------------------- /queries/apex/context.scm: -------------------------------------------------------------------------------- 1 | (if_statement 2 | consequence: (_) @context.end 3 | ) @context 4 | 5 | (method_declaration 6 | body: (_) @context.end 7 | ) @context 8 | 9 | (for_statement 10 | body: (_) @context.end 11 | ) @context 12 | 13 | (enhanced_for_statement 14 | body: (_) @context.end 15 | ) @context 16 | 17 | (expression_statement) @context 18 | -------------------------------------------------------------------------------- /queries/bash/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (for_statement) 3 | (c_style_for_statement) 4 | (function_definition) 5 | (if_statement) 6 | (case_statement) 7 | (case_item) 8 | (while_statement) 9 | ] @context) 10 | -------------------------------------------------------------------------------- /queries/c/context.scm: -------------------------------------------------------------------------------- 1 | 2 | (preproc_if 3 | (_) (_) @context.end 4 | ) @context 5 | 6 | (preproc_ifdef 7 | name: (identifier) (_) @context.end 8 | ) @context 9 | 10 | (function_definition 11 | body: (_ (_) @context.end) 12 | ) @context 13 | 14 | (for_statement 15 | (compound_statement) @context.end 16 | ) @context 17 | 18 | (if_statement 19 | consequence: (_ (_) @context.end) 20 | ) @context 21 | 22 | (else_clause 23 | (_ (_) @context.end) 24 | ) @context 25 | 26 | (while_statement 27 | body: (_ (_) @context.end) 28 | ) @context 29 | 30 | (do_statement 31 | body: (_ (_) @context.end) 32 | ) @context 33 | 34 | (struct_specifier 35 | body: (_ (_) @context.end) 36 | ) @context 37 | 38 | (enum_specifier 39 | body: (_ (_) @context.end) 40 | ) @context 41 | 42 | (switch_statement 43 | body: (_) @context.end 44 | ) @context 45 | 46 | (case_statement 47 | value: (_) (_) @context.end 48 | ) @context 49 | 50 | (declaration 51 | declarator: (_ (_) @content.end) 52 | ) @context 53 | -------------------------------------------------------------------------------- /queries/c_sharp/context.scm: -------------------------------------------------------------------------------- 1 | (interface_declaration 2 | body: (_) @context.end 3 | ) @context 4 | 5 | (class_declaration 6 | body: (_) @context.end 7 | ) @context 8 | 9 | (enum_declaration 10 | body: (_) @context.end 11 | ) @context 12 | 13 | (struct_declaration 14 | body: (_) @context.end 15 | ) @context 16 | 17 | (record_declaration 18 | body: (_) @context.end 19 | ) @context 20 | 21 | (namespace_declaration 22 | body: (_) @context.end 23 | ) @context 24 | 25 | (constructor_declaration 26 | body: (_) @context.end 27 | ) @context 28 | 29 | (destructor_declaration 30 | body: (_) @context.end 31 | ) @context 32 | 33 | (method_declaration 34 | body: (_) @context.end 35 | ) @context 36 | 37 | (switch_statement 38 | body: (_) @context.end 39 | ) @context 40 | 41 | (foreach_statement 42 | body: (_) @context.end 43 | ) @context 44 | 45 | (for_statement 46 | body: (_) @context.end 47 | ) @context 48 | 49 | (if_statement 50 | consequence: (_) @context.end 51 | ) @context 52 | 53 | ([ 54 | (do_statement) 55 | (while_statement) 56 | ] @context) 57 | 58 | (try_statement 59 | body: (_) @context.end 60 | ) @context 61 | 62 | (catch_clause 63 | body: (_) @context.end 64 | ) @context 65 | 66 | (finally_clause) @context 67 | -------------------------------------------------------------------------------- /queries/capnp/context.scm: -------------------------------------------------------------------------------- 1 | (enum 2 | "{" (_) @context.end 3 | ) @context 4 | 5 | (struct 6 | "{" (_) @context.end 7 | ) @context 8 | 9 | (group 10 | "{" (_) @context.end 11 | ) @context 12 | 13 | (union 14 | "{" (_) @context.end 15 | ) @context 16 | 17 | (interface 18 | "{" (_) @context.end 19 | ) @context 20 | 21 | (field 22 | "=" (_) @context.end 23 | ) @context 24 | 25 | (_ 26 | (struct_shorthand "(" (_) @context.end) 27 | ) @context 28 | 29 | (_ 30 | (const_list "[" (_) @context.end) 31 | ) @context 32 | -------------------------------------------------------------------------------- /queries/clojure/context.scm: -------------------------------------------------------------------------------- 1 | ([(list_lit) 2 | (map_lit) 3 | (vec_lit) 4 | ] @context) 5 | -------------------------------------------------------------------------------- /queries/cmake/context.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (if_condition) 3 | (foreach_loop) 4 | (while_loop) 5 | (function_def) 6 | (macro_def) 7 | (block_def) 8 | (normal_command) 9 | ] @context 10 | -------------------------------------------------------------------------------- /queries/cpp/context.scm: -------------------------------------------------------------------------------- 1 | ; inherits: c 2 | 3 | (for_range_loop 4 | body: (_ (_) @context.end) 5 | ) @context 6 | 7 | (namespace_definition 8 | body: (_ (_) @context.end) 9 | ) @context 10 | 11 | (class_specifier 12 | body: (_ (_) @context.end) 13 | ) @context 14 | 15 | (linkage_specification 16 | body: (declaration_list (_) @context.end) 17 | ) @context 18 | 19 | (lambda_expression 20 | body: (_ (_) @context.end) 21 | ) @context 22 | -------------------------------------------------------------------------------- /queries/css/context.scm: -------------------------------------------------------------------------------- 1 | (keyframe_block 2 | (block (_) @context.end) 3 | ) @context 4 | 5 | (at_rule 6 | (block (_) @context.end) 7 | ) @context 8 | 9 | (supports_statement 10 | (block (_) @context.end) 11 | ) @context 12 | 13 | (keyframes_statement 14 | (keyframe_block_list (_) @context.end) 15 | ) @context 16 | 17 | (media_statement 18 | (block (_) @context.end) 19 | ) @context 20 | 21 | (rule_set 22 | (block (_) @context.end) 23 | )@context 24 | -------------------------------------------------------------------------------- /queries/cuda/context.scm: -------------------------------------------------------------------------------- 1 | ; inherits: c 2 | 3 | (for_range_loop 4 | body: (_ (_) @context.end) 5 | ) @context 6 | 7 | (class_specifier 8 | body: (_ (_) @context.end) 9 | ) @context 10 | 11 | (linkage_specification 12 | body: (declaration_list (_) @context.end) 13 | ) @context 14 | -------------------------------------------------------------------------------- /queries/cue/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (import_declaration) 3 | (let_clause) 4 | ] @context) 5 | 6 | (field 7 | (value (_) @context.end) 8 | ) @context 9 | 10 | (call_expression 11 | (arguments (_) @context.end) 12 | ) @context 13 | 14 | (_ 15 | ([ 16 | (for_clause) 17 | (guard_clause) 18 | ] (_)+ @context.end) 19 | ) @context 20 | -------------------------------------------------------------------------------- /queries/d/context.scm: -------------------------------------------------------------------------------- 1 | (class_declaration 2 | (aggregate_body (_) @context.end) 3 | ) @context 4 | 5 | (interface_declaration 6 | (aggregate_body (_) @context.end) 7 | ) @context 8 | 9 | (function_declaration 10 | (function_body (block_statement (_) @context.end)) 11 | ) @context 12 | 13 | (template_declaration 14 | (identifier) 15 | (template_parameters) 16 | (_) @context.end 17 | ) @context 18 | 19 | (union_declaration 20 | (aggregate_body (_) @context.end) 21 | ) @context 22 | 23 | (enum_declaration 24 | (enum_member) @context.end 25 | ) @context 26 | 27 | (struct_declaration 28 | (aggregate_body (_) @context.end) 29 | ) @context 30 | 31 | (unittest_declaration 32 | (block_statement (_) @context.end) 33 | ) @context 34 | 35 | (try_statement 36 | body: (scope_statement (_) @context.end) 37 | ) @context 38 | 39 | (catch_statement 40 | body: (scope_statement (_) @context.end) 41 | ) @context 42 | 43 | (asm_statement 44 | (asm_inline (_) @context.end) 45 | ) @context 46 | 47 | (with_statement 48 | (scope_statement (_) @context.end) 49 | ) @context 50 | 51 | (while_statement 52 | (scope_statement (_) @context.end) 53 | ) @context 54 | 55 | (for_statement 56 | (block_statement (_) @context.end) 57 | ) @context 58 | 59 | (foreach_statement 60 | (scope_statement (_) @context.end) 61 | ) @context 62 | 63 | (if_statement 64 | consequence: (scope_statement 65 | (block_statement (_) @context.end) 66 | ) 67 | ) @context 68 | 69 | (if_statement 70 | (else) @context 71 | . 72 | (_) @context.end 73 | ; (scope_statement 74 | ; (block_statement (_) @context.end) 75 | ; ) 76 | ) 77 | 78 | (switch_statement 79 | (scope_statement (_) @context.end) 80 | ) @context 81 | 82 | (case_statement 83 | (case) 84 | . 85 | (expression_list) @context.end 86 | ) @context 87 | 88 | -------------------------------------------------------------------------------- /queries/dart/context.scm: -------------------------------------------------------------------------------- 1 | (function_body) @context 2 | 3 | (for_statement 4 | body: (_) @context.end 5 | ) @context 6 | 7 | (while_statement 8 | body: (_) @context.end 9 | ) @context 10 | 11 | (do_statement 12 | body: (_) @context.end 13 | ) @context 14 | 15 | (try_statement 16 | body: (_) @context.end 17 | ) @context 18 | 19 | (if_statement 20 | consequence: (_) @context.end 21 | ) @context 22 | 23 | (class_definition 24 | body: (_) @context.end 25 | ) @context 26 | 27 | (extension_declaration 28 | body: (_) @context.end 29 | ) @context 30 | -------------------------------------------------------------------------------- /queries/devicetree/context.scm: -------------------------------------------------------------------------------- 1 | (node) @context 2 | -------------------------------------------------------------------------------- /queries/diff/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (block) 3 | (hunk) 4 | ] @context) 5 | -------------------------------------------------------------------------------- /queries/elixir/context.scm: -------------------------------------------------------------------------------- 1 | (binary_operator 2 | left: (_) 3 | right: (_) @context) 4 | 5 | (pair 6 | key: (_) 7 | value: (_) @context) 8 | 9 | ((unary_operator 10 | operand: (call 11 | target: (identifier) 12 | (arguments (_)))) @_op (#lua-match? @_op "@[%w_]+")) @context 13 | 14 | (stab_clause right: (body (_) @context.end)) @context 15 | 16 | (call 17 | target: (identifier) 18 | (do_block (_) @context.end)) @context 19 | -------------------------------------------------------------------------------- /queries/elm/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (value_declaration) 3 | (case_of_expr) 4 | (case_of_branch) 5 | ] @context) 6 | -------------------------------------------------------------------------------- /queries/enforce/context.scm: -------------------------------------------------------------------------------- 1 | (if 2 | (block) @context.end) @context 3 | 4 | (decl_method 5 | body: (_) @context.end) @context 6 | 7 | (for 8 | body: (_) @context.end) @context 9 | 10 | (foreach 11 | body: (_) @context.end) @context 12 | 13 | (decl_class 14 | body: (_) @context.end) @context 15 | 16 | (decl_enum 17 | body: (_) @context.end) @context 18 | 19 | (switch 20 | body: (_) @context.end) @context 21 | 22 | (switch_case 23 | label: (_) @context.end) @context 24 | -------------------------------------------------------------------------------- /queries/fennel/context.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (quote_reader_macro) 3 | (quasi_quote_reader_macro) 4 | (quote_form) 5 | (fn_form) 6 | (lambda_form) 7 | (macro_form) 8 | (case_form) 9 | (match_form) 10 | (case_try_form) 11 | (match_try_form) 12 | ] @context 13 | 14 | (list 15 | call: (symbol) @_sym 16 | (#eq? @_sym "when")) @context 17 | 18 | (hashfn_reader_macro 19 | expression: (list 20 | call: (symbol) @_sym 21 | (#eq? @_sym "do"))) @context 22 | -------------------------------------------------------------------------------- /queries/fish/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (function_definition) 3 | (while_statement) 4 | (for_statement) 5 | (switch_statement) 6 | (case_clause) 7 | (if_statement) 8 | (else_if_clause) 9 | (else_clause) 10 | ]) @context 11 | -------------------------------------------------------------------------------- /queries/fortran/context.scm: -------------------------------------------------------------------------------- 1 | (program 2 | (program_statement (_)) 3 | (_) @context.end 4 | ) @context 5 | 6 | (derived_type_definition 7 | (derived_type_statement (_)) 8 | (_) @context.end 9 | ) @context 10 | 11 | (do_loop_statement 12 | (loop_control_expression (_)) 13 | (_) @context.end 14 | ) @context 15 | 16 | (subroutine 17 | (subroutine_statement (_)) 18 | (_) @context.end 19 | ) @context 20 | 21 | (if_statement 22 | (parenthesized_expression (_)) 23 | (_) @context.end 24 | ) @context 25 | 26 | (elseif_clause 27 | (parenthesized_expression (_)) 28 | (_) @context.end 29 | ) @context 30 | 31 | (else_clause 32 | (_) @context.end 33 | ) @context 34 | -------------------------------------------------------------------------------- /queries/gdscript/context.scm: -------------------------------------------------------------------------------- 1 | (function_definition 2 | body: (_) @context.end 3 | ) @context 4 | 5 | (if_statement 6 | body: (_) @context.end 7 | ) @context 8 | 9 | (elif_clause 10 | body: (_) @context.end 11 | ) @context 12 | 13 | (else_clause 14 | body: (_) @context.end 15 | ) @context 16 | 17 | (for_statement 18 | body: (_) @context.end 19 | ) @context 20 | 21 | (while_statement 22 | body: (_) @context.end 23 | ) @context 24 | 25 | (class_definition 26 | body: (_) @context.end 27 | ) @context 28 | 29 | (match_statement 30 | body: (_) @context.end 31 | ) @context 32 | 33 | (pattern_section 34 | body: (_) @context.end 35 | ) @context 36 | 37 | (enum_definition 38 | body: (_) @context.end 39 | ) @context 40 | 41 | -------------------------------------------------------------------------------- /queries/glimmer/context.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (element_node) 3 | (block_statement) 4 | ] @context 5 | -------------------------------------------------------------------------------- /queries/glsl/context.scm: -------------------------------------------------------------------------------- 1 | 2 | ([ 3 | (function_definition) 4 | ] @context) 5 | -------------------------------------------------------------------------------- /queries/go/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (var_declaration) 3 | (type_declaration) 4 | (import_declaration) 5 | (const_declaration) 6 | (select_statement) 7 | (expression_switch_statement) 8 | (expression_case) 9 | (default_case) 10 | ] @context) 11 | 12 | (function_declaration 13 | body: (block (_) @context.end) 14 | ) @context 15 | 16 | (func_literal 17 | body: (block (_) @context.end) 18 | ) @context 19 | 20 | (method_declaration 21 | body: (block (_) @context.end) 22 | ) @context 23 | 24 | (if_statement 25 | consequence: (block (_) @context.end) 26 | ) @context 27 | 28 | (for_statement 29 | body: (block (_) @context.end) 30 | ) @context 31 | 32 | (communication_case 33 | communication: (_) 34 | (_) @context.end 35 | ) @context 36 | -------------------------------------------------------------------------------- /queries/graphql/context.scm: -------------------------------------------------------------------------------- 1 | (interface_type_definition 2 | (fields_definition (_) @context.end) 3 | ) @context 4 | 5 | (object_type_definition 6 | (fields_definition (_) @context.end) 7 | ) @context 8 | 9 | (schema_definition 10 | (_) @context.end 11 | ) @context 12 | 13 | (input_object_type_definition 14 | (input_fields_definition (_) @context.end) 15 | ) @context 16 | 17 | (operation_definition 18 | (selection_set (_) @context.end) 19 | ) @context 20 | 21 | (inline_fragment 22 | (selection_set (_) @context.end) 23 | ) @context 24 | 25 | (selection 26 | (field 27 | (arguments) 28 | (selection_set (_) @context.end) 29 | ) 30 | ) @context 31 | -------------------------------------------------------------------------------- /queries/groovy/context.scm: -------------------------------------------------------------------------------- 1 | (juxt_function_call) @context 2 | 3 | ([ 4 | (function_call) 5 | (closure) 6 | ] @context) 7 | -------------------------------------------------------------------------------- /queries/haskell/context.scm: -------------------------------------------------------------------------------- 1 | (haskell (header 2 | module: (module) @context)) @context.end 3 | 4 | ([ 5 | (alternative) 6 | (expression/case) 7 | (signature) 8 | (bind) 9 | (function) 10 | (class) 11 | (data_type) 12 | ] @context) 13 | -------------------------------------------------------------------------------- /queries/html/context.scm: -------------------------------------------------------------------------------- 1 | 2 | ([ 3 | (element) 4 | (style_element) 5 | (script_element) 6 | ] @context) 7 | -------------------------------------------------------------------------------- /queries/ini/context.scm: -------------------------------------------------------------------------------- 1 | (section) @context 2 | -------------------------------------------------------------------------------- /queries/janet_simple/context.scm: -------------------------------------------------------------------------------- 1 | ([(par_arr_lit) 2 | (sqr_arr_lit) 3 | (struct_lit) 4 | (tbl_lit) 5 | (par_tup_lit) 6 | (sqr_tup_lit) 7 | ] @context) 8 | -------------------------------------------------------------------------------- /queries/java/context.scm: -------------------------------------------------------------------------------- 1 | (if_statement 2 | consequence: (_) @context.end 3 | ) @context 4 | 5 | (method_declaration 6 | body: (_) @context.end 7 | ) @context 8 | 9 | (for_statement 10 | body: (_) @context.end 11 | ) @context 12 | 13 | (enhanced_for_statement 14 | body: (_) @context.end 15 | ) @context 16 | 17 | (class_declaration 18 | body: (_) @context.end 19 | ) @context 20 | 21 | (switch_expression) @context 22 | 23 | (switch_block_statement_group) @context 24 | 25 | (expression_statement) @context 26 | -------------------------------------------------------------------------------- /queries/javascript/context.scm: -------------------------------------------------------------------------------- 1 | (if_statement 2 | consequence: (_) @context.end 3 | ) @context 4 | 5 | ([ 6 | (arrow_function) 7 | (call_expression) 8 | (class_declaration) 9 | (else_clause) 10 | (expression_statement) 11 | (for_statement) 12 | (for_in_statement) 13 | (function_declaration) 14 | (generator_function_declaration) 15 | (jsx_element) 16 | (jsx_self_closing_element) 17 | (lexical_declaration) 18 | (method_definition) 19 | (object) 20 | (pair) 21 | (while_statement) 22 | (switch_statement) 23 | (switch_case) 24 | ] @context) 25 | -------------------------------------------------------------------------------- /queries/json/context.scm: -------------------------------------------------------------------------------- 1 | 2 | ([ 3 | (object) 4 | (pair) 5 | ] @context) 6 | -------------------------------------------------------------------------------- /queries/jsonnet/context.scm: -------------------------------------------------------------------------------- 1 | (conditional 2 | consequence: (_) @context.end 3 | ) @context 4 | 5 | ([ 6 | (bind) 7 | (field) 8 | (forspec) 9 | (anonymous_function) 10 | (functioncall) 11 | ] @context) 12 | -------------------------------------------------------------------------------- /queries/julia/context.scm: -------------------------------------------------------------------------------- 1 | (struct_definition) @context 2 | 3 | (function_definition 4 | (signature) @context.final 5 | ) @context 6 | 7 | (for_statement) @context 8 | 9 | (if_statement 10 | condition: (_) @context.final 11 | ) @context 12 | 13 | (while_statement 14 | condition: (_) @context.final 15 | ) @context 16 | 17 | (try_statement) @context 18 | -------------------------------------------------------------------------------- /queries/kdl/context.scm: -------------------------------------------------------------------------------- 1 | (node_children) @context 2 | -------------------------------------------------------------------------------- /queries/latex/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (generic_environment) 3 | (chapter) 4 | (section) 5 | (subsection) 6 | (subsubsection) 7 | ] @context) 8 | -------------------------------------------------------------------------------- /queries/liquidsoap/context.scm: -------------------------------------------------------------------------------- 1 | (def) @context 2 | (if) @context 3 | (for) @context 4 | (while) @context 5 | (block) @context 6 | (anonymous_function) @context 7 | (app) @context 8 | (method_app) @context 9 | -------------------------------------------------------------------------------- /queries/lua/context.scm: -------------------------------------------------------------------------------- 1 | (for_statement 2 | body: (_) @context.end 3 | ) @context 4 | 5 | (while_statement 6 | body: (_) @context.end 7 | ) @context 8 | 9 | (do_statement 10 | body: (_) @context.end 11 | ) @context 12 | 13 | (function_definition 14 | parameters: (_) 15 | _ @context.end 16 | ) @context 17 | 18 | (table_constructor 19 | (_) @context.end 20 | ) @context 21 | 22 | (function_declaration 23 | parameters: (_) @context.final 24 | ) @context 25 | 26 | (if_statement 27 | consequence: (_) @context.end 28 | ) @context 29 | 30 | (if_statement 31 | (comment _) @context.end 32 | ) @context 33 | 34 | (repeat_statement 35 | body: (_) @context.end 36 | ) @context 37 | -------------------------------------------------------------------------------- /queries/make/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (rule) 3 | (conditional) 4 | (variable_assignment) 5 | (recipe_line) 6 | ] @context) 7 | -------------------------------------------------------------------------------- /queries/markdown/context.scm: -------------------------------------------------------------------------------- 1 | 2 | ((section) @context) 3 | -------------------------------------------------------------------------------- /queries/matlab/context.scm: -------------------------------------------------------------------------------- 1 | (function_definition 2 | (block (_) @context.end) 3 | ) @context 4 | 5 | (while_statement 6 | (block (_) @context.end) 7 | ) @context 8 | 9 | (for_statement 10 | (block (_) @context.end) 11 | ) @context 12 | 13 | (if_statement 14 | (block (_) @context.end) 15 | ) @context 16 | 17 | (elseif_clause 18 | (block (_) @context.end) 19 | ) @context 20 | 21 | (else_clause 22 | (block (_) @context.end) 23 | ) @context 24 | 25 | (switch_statement) @context 26 | 27 | (case_clause 28 | (block (_) @context.end) 29 | ) @context 30 | 31 | (otherwise_clause 32 | (block (_) @context.end) 33 | ) @context 34 | 35 | (try_statement 36 | "try" 37 | (block (_) @context.end) @context 38 | "end") 39 | (catch_clause 40 | "catch" 41 | (block (_) @context.end) @context) 42 | -------------------------------------------------------------------------------- /queries/nim/context.scm: -------------------------------------------------------------------------------- 1 | ; declarations 2 | (const_section (variable_declaration) @context.end) @context 3 | (var_section (variable_declaration) @context.end) @context 4 | (let_section (variable_declaration) @context.end) @context 5 | (using_section (variable_declaration) @context.end) @context 6 | 7 | ; types 8 | (type_section (type_declaration) @context.end) @context 9 | (object_declaration (field_declaration_list) @context.end) @context 10 | (tuple_type . (field_declaration) @context.end) @context 11 | (enum_declaration . (enum_field_declaration) @context.end) @context 12 | (concept_declaration body: (statement_list) @context.end) @context 13 | 14 | ; routines 15 | (proc_declaration body: (statement_list) @context.end) @context 16 | (func_declaration body: (statement_list) @context.end) @context 17 | (method_declaration body: (statement_list) @context.end) @context 18 | (iterator_declaration body: (statement_list) @context.end) @context 19 | (converter_declaration body: (statement_list) @context.end) @context 20 | (template_declaration body: (statement_list) @context.end) @context 21 | (macro_declaration body: (statement_list) @context.end) @context 22 | 23 | ; routine expressions 24 | (proc_expression body: (statement_list) @context.end) @context 25 | (func_expression body: (statement_list) @context.end) @context 26 | (iterator_expression body: (statement_list) @context.end) @context 27 | 28 | ; calls 29 | (do_block body: (statement_list) @context.end) @context 30 | (call (argument_list ":" (statement_list) @context.end)) @context 31 | 32 | ; single line statements 33 | (for body: (statement_list) @context.end) @context 34 | (while body: (statement_list) @context.end) @context 35 | (block body: (statement_list) @context.end) @context 36 | (static_statement body: (statement_list) @context.end) @context 37 | (pragma_statement body: (statement_list) @context.end) @context 38 | 39 | ; multi line statements 40 | (try body: (statement_list) @context.end) @context 41 | (except_branch consequence: (statement_list) @context.end) @context 42 | (finally_branch body: (statement_list) @context.end) @context 43 | 44 | (if consequence: (statement_list) @context.end) @context 45 | (when consequence: (statement_list) @context.end) @context 46 | (conditional_declaration consequence: (field_declaration_list) @context.end) @context 47 | (elif_branch 48 | consequence: [ 49 | (statement_list) 50 | (field_declaration_list) 51 | ] @context.end) @context 52 | (else_branch 53 | consequence: [ 54 | (statement_list) 55 | (field_declaration_list) 56 | ] @context.end) @context 57 | (case value: (_) . (_) @context.end) @context 58 | (variant_declaration (variant_discriminator_declaration) . (_) @context.end) @context 59 | (of_branch 60 | consequence: [ 61 | (statement_list) 62 | (field_declaration_list) 63 | ] @context.end) @context 64 | -------------------------------------------------------------------------------- /queries/nix/context.scm: -------------------------------------------------------------------------------- 1 | (function_expression body: (_ (_) @context.end)) @context 2 | (binding expression: (_ (_) @context.end)) @context 3 | -------------------------------------------------------------------------------- /queries/nu/context.scm: -------------------------------------------------------------------------------- 1 | ;; Functions and modules 2 | (decl_def 3 | (_) @context.end 4 | ) @context 5 | 6 | (decl_module 7 | (_) @context.end 8 | ) @context 9 | 10 | (decl_export 11 | (_) @context.end 12 | ) @context 13 | 14 | ;; Control flow 15 | (ctrl_if 16 | (_) @context.end 17 | ) @context 18 | 19 | (ctrl_try 20 | (_) @context.end 21 | ) @context 22 | 23 | (ctrl_match 24 | (_) @context.end 25 | ) @context 26 | 27 | (ctrl_for 28 | (_) @context.end 29 | ) @context 30 | 31 | (ctrl_while 32 | (_) @context.end 33 | ) @context 34 | 35 | (ctrl_do 36 | (_) @context.end 37 | ) @context 38 | 39 | (match_arm) @context 40 | (pipe_element) @context 41 | (block) @context 42 | (expr_parenthesized) @context 43 | (val_closure) @context 44 | -------------------------------------------------------------------------------- /queries/objdump/context.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (disassembly_section_label) 3 | (disassembly_section) 4 | ] @context 5 | -------------------------------------------------------------------------------- /queries/ocaml/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (module_binding) 3 | (class_binding) 4 | (class_type_binding) 5 | (method_definition) 6 | (type_binding) 7 | (let_binding) 8 | (function_expression) 9 | ] @context) 10 | -------------------------------------------------------------------------------- /queries/ocaml_interface/context.scm: -------------------------------------------------------------------------------- 1 | ; inherits: ocaml 2 | -------------------------------------------------------------------------------- /queries/odin/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (struct_declaration) 3 | (if_statement) 4 | (for_statement) 5 | (procedure_declaration) 6 | (switch_statement) 7 | (switch_case) 8 | ] @context) 9 | -------------------------------------------------------------------------------- /queries/php/context.scm: -------------------------------------------------------------------------------- 1 | 2 | (function_definition 3 | name: (_) @context.start 4 | body: (_ (_) @context.end) 5 | ) @context 6 | 7 | (method_declaration 8 | name: (_) @context.start 9 | body: (_ (_) @context.end) 10 | ) @context 11 | 12 | (while_statement 13 | body: (_ (_) @context.end) 14 | ) @context 15 | 16 | (if_statement 17 | body: (_ (_) @context.end) 18 | ) @context 19 | 20 | (else_clause 21 | body: (_ (_) @context.end) 22 | ) @context 23 | 24 | (else_if_clause 25 | body: (_ (_) @context.end) 26 | ) @context 27 | 28 | (do_statement 29 | body: (_ (_) @context.end) 30 | ) @context 31 | 32 | (foreach_statement 33 | body: (_ (_) @context.end) 34 | ) @context 35 | 36 | (class_declaration 37 | name: (_) @context.start 38 | body: (_ (_) @context.end) 39 | ) @context 40 | 41 | (for_statement 42 | (compound_statement (_) @context.end) 43 | ) @context 44 | 45 | (switch_statement) @context 46 | 47 | (case_statement) @context 48 | -------------------------------------------------------------------------------- /queries/php_only/context.scm: -------------------------------------------------------------------------------- 1 | ; inherits: php 2 | -------------------------------------------------------------------------------- /queries/prisma/context.scm: -------------------------------------------------------------------------------- 1 | (_ 2 | (statement_block (_) @context.end) 3 | ) @context 4 | 5 | (enum_declaration 6 | (enum_block (_) @context.end) 7 | ) @context 8 | 9 | -------------------------------------------------------------------------------- /queries/proto/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (enum) 3 | (message) 4 | (service) 5 | (oneof) 6 | ] @context) 7 | -------------------------------------------------------------------------------- /queries/python/context.scm: -------------------------------------------------------------------------------- 1 | (class_definition 2 | body: (_) @context.end 3 | ) @context 4 | 5 | (function_definition 6 | body: (_) @context.end 7 | ) @context 8 | 9 | (try_statement 10 | body: (_) @context.end 11 | ) @context 12 | 13 | (with_statement 14 | body: (_) @context.end 15 | ) @context 16 | 17 | (if_statement 18 | consequence: (_) @context.end 19 | ) @context 20 | 21 | (elif_clause 22 | consequence: (_) @context.end 23 | ) @context 24 | 25 | (case_clause 26 | consequence: (_) @context.end 27 | ) @context 28 | 29 | (while_statement 30 | body: (_) @context.end 31 | ) @context 32 | 33 | (except_clause 34 | (block) @context.end 35 | ) @context 36 | 37 | (match_statement 38 | body: (_) @context.end 39 | ) @context 40 | 41 | ([ 42 | (for_statement) 43 | (finally_clause) 44 | (else_clause) 45 | (pair) 46 | ] @context) 47 | -------------------------------------------------------------------------------- /queries/r/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (call) 3 | (binary_operator) 4 | ]) @context 5 | 6 | (for_statement 7 | body: (_) @context.end 8 | ) @context 9 | 10 | (while_statement 11 | body: (_) @context.end 12 | ) @context 13 | 14 | (if_statement 15 | consequence: (_) @context.end 16 | ) @context 17 | 18 | (if_statement 19 | consequence: (_) @context.end 20 | ) @context 21 | 22 | (function_definition 23 | (braced_expression) @context.end) @context 24 | -------------------------------------------------------------------------------- /queries/ruby/context.scm: -------------------------------------------------------------------------------- 1 | (class 2 | (body_statement) @context.end 3 | ) @context 4 | 5 | (singleton_class 6 | (body_statement) @context.end 7 | ) @context 8 | 9 | (module 10 | (body_statement) @context.end 11 | ) @context 12 | 13 | (method 14 | (body_statement) @context.end 15 | ) @context 16 | 17 | (singleton_method 18 | (body_statement) @context.end 19 | ) @context 20 | 21 | (if 22 | (then) @context.end 23 | ) @context 24 | 25 | (if 26 | (else (_) @context.end) 27 | ) @context 28 | 29 | (unless 30 | (then) @context.end 31 | ) @context 32 | 33 | (unless 34 | (else (_) @context.end) 35 | ) @context 36 | 37 | (_ 38 | (do_block (body_statement) @context.end) 39 | ) @context 40 | 41 | (call 42 | method: (identifier) @context.identifier 43 | block: (do_block body: (body_statement) @context.end) 44 | (#any-of? @context.identifier 45 | "it" 46 | "it_behaves_like" 47 | "include_examples" 48 | "include_context" 49 | "context" 50 | "describe" 51 | "shared_context" 52 | "shared_examples") 53 | ) @context 54 | 55 | (case 56 | (when (_) @context.end)* 57 | (else (_) @context.end)? 58 | ) @context 59 | 60 | (for 61 | (_) @context.end 62 | ) @context 63 | 64 | (while 65 | (_) @context.end 66 | ) @context 67 | 68 | (until 69 | (_) @context.end 70 | ) @context 71 | 72 | (begin 73 | (_) @context.end 74 | ) @context 75 | 76 | (rescue 77 | (_) @context.end 78 | ) @context 79 | 80 | (ensure 81 | (_) @context.end 82 | ) @context 83 | 84 | (lambda 85 | (_) @context.end 86 | ) @context 87 | 88 | -------------------------------------------------------------------------------- /queries/rust/context.scm: -------------------------------------------------------------------------------- 1 | ; standard if 2 | (if_expression 3 | consequence: (_ (_) @context.end) 4 | ) @context 5 | 6 | ; standard else 7 | (else_clause 8 | (block (_)) @context.end 9 | ) @context 10 | 11 | ; let if (its else is caught above) 12 | (let_declaration 13 | (if_expression 14 | (block (_))) @context.end 15 | ) @context 16 | 17 | ; let else 18 | (let_declaration 19 | alternative: (block (_) @context.end) 20 | ) @context 21 | 22 | ; let (tuple) = (values) 23 | (let_declaration 24 | (tuple_pattern (_)) 25 | (tuple_expression _) @context.end 26 | ) @context 27 | 28 | ; helps with long array definitions 29 | (let_declaration 30 | (array_expression _) @context.end 31 | ) @context 32 | 33 | (match_expression 34 | body: (_ (_) @context.end) 35 | ) @context 36 | 37 | (match_arm 38 | (block (_) @context.end) 39 | ) @context 40 | 41 | (for_expression 42 | body: (_ (_) @context.end) 43 | ) @context 44 | 45 | (while_expression 46 | body: (_ (_) @context.end) 47 | ) @context 48 | 49 | (loop_expression 50 | body: (_ (_) @context.end) 51 | ) @context 52 | 53 | (closure_expression 54 | body: (_ (_) @context.end) 55 | ) @context 56 | 57 | (function_item 58 | body: (_ (_) @context.end) 59 | ) @context 60 | 61 | (impl_item 62 | body: (_ (_) @context.end) 63 | ) @context 64 | 65 | (trait_item 66 | body: (_ (_) @context.end) 67 | ) @context 68 | 69 | (struct_item 70 | body: (_ (_) @context.end) 71 | ) @context 72 | 73 | (struct_expression 74 | (type_identifier) @context.end 75 | ) @context 76 | 77 | (union_item 78 | body: (_ (_) @context.end) 79 | ) @context 80 | 81 | (enum_item 82 | body: (_ (_) @context.end) 83 | ) @context 84 | 85 | (mod_item 86 | body: (_ (_) @context.end) 87 | ) @context 88 | 89 | ; extern 90 | (foreign_mod_item 91 | body: (_ (_) @context.end) 92 | ) @context 93 | 94 | (async_block 95 | (block (_) @context.end) 96 | ) @context 97 | 98 | (try_block 99 | (block (_) @context.end) 100 | ) @context 101 | 102 | (unsafe_block 103 | (block (_) @context.end) 104 | ) @context 105 | 106 | ; function call site; helps with long parameter lists 107 | (call_expression 108 | (arguments (_) @context.end) 109 | ) @context 110 | 111 | (macro_invocation 112 | (token_tree (_) @context.end) 113 | ) @context 114 | 115 | (macro_definition 116 | name: (_) @context.end 117 | ) @context 118 | -------------------------------------------------------------------------------- /queries/scala/context.scm: -------------------------------------------------------------------------------- 1 | 2 | (function_definition 3 | body: (_ (_) @context.end) 4 | ) @context 5 | 6 | (class_definition 7 | body: (_ (_) @context.end) 8 | ) @context 9 | 10 | (object_definition 11 | body: (_ (_) @context.end) 12 | ) @context 13 | 14 | (case_clause 15 | body: (_ (_) @context.end) 16 | ) @context 17 | 18 | (match_expression 19 | body: (_ (_) @context.end) 20 | ) @context 21 | 22 | (call_expression 23 | arguments: (_ (_) @context.end) 24 | ) @context 25 | 26 | (if_expression 27 | consequence: (_ (_) @context.end) 28 | ) @context 29 | -------------------------------------------------------------------------------- /queries/scss/context.scm: -------------------------------------------------------------------------------- 1 | ; inherits: css 2 | 3 | (if_statement) @context 4 | 5 | (else_if_clause 6 | (block (_) @context.end) 7 | ) @context 8 | 9 | (else_clause 10 | (block (_) @context.end) 11 | ) @context 12 | 13 | (while_statement 14 | (block (_) @context.end) 15 | ) @context 16 | 17 | (for_statement 18 | (block (_) @context.end) 19 | ) @context 20 | 21 | (each_statement 22 | (block (_) @context.end) 23 | ) @context 24 | 25 | (mixin_statement 26 | (block (_) @context.end) 27 | ) @context 28 | 29 | (function_statement 30 | (block (_) @context.end) 31 | ) @context 32 | -------------------------------------------------------------------------------- /queries/smali/context.scm: -------------------------------------------------------------------------------- 1 | (annotation_directive 2 | ".end annotation" @context.end 3 | ) @context 4 | 5 | (array_data_directive 6 | ".end array-data" @context.end 7 | ) @context 8 | 9 | (field_definition 10 | ".end field" @context.end 11 | ) @context 12 | 13 | (method_definition 14 | ".end method" @context.end 15 | ) @context 16 | 17 | (packed_switch_directive 18 | ".end packed-switch" @context.end 19 | ) @context 20 | 21 | (param_directive 22 | ".end param"? @context.end 23 | ) @context 24 | 25 | (parameter_directive 26 | ".end parameter"? @context.end 27 | ) @context 28 | 29 | (sparse_switch_directive 30 | ".end sparse-switch" @context.end 31 | ) @context 32 | 33 | (subannotation_directive 34 | ".end subannotation" @context.end 35 | ) @context 36 | -------------------------------------------------------------------------------- /queries/solidity/context.scm: -------------------------------------------------------------------------------- 1 | (contract_declaration) @context 2 | (library_declaration) @context 3 | (interface_declaration) @context 4 | 5 | (event_definition) @context 6 | (constructor_definition) @context 7 | (function_definition) @context 8 | (modifier_definition) @context 9 | (fallback_receive_definition) @context 10 | 11 | (block_statement) @context 12 | (if_statement) @context 13 | (emit_statement) @context 14 | (revert_statement) @context 15 | (try_statement) @context 16 | (catch_clause) @context 17 | (for_statement) @context 18 | (while_statement) @context 19 | (do_while_statement) @context 20 | 21 | (call_expression) @context 22 | (error_declaration) @context 23 | (struct_declaration) @context 24 | (enum_declaration) @context 25 | -------------------------------------------------------------------------------- /queries/starlark/context.scm: -------------------------------------------------------------------------------- 1 | ; comment captures are not inside the body block 2 | (function_definition 3 | (comment) @context.end 4 | ) @context 5 | 6 | (function_definition 7 | body: (_) @context.end 8 | ) @context 9 | 10 | ; comment captures are not inside the consequence block 11 | (if_statement 12 | (comment) @context.end 13 | ) @context 14 | 15 | (if_statement 16 | consequence: (_) @context.end 17 | ) @context 18 | 19 | (call 20 | (argument_list) @context.end 21 | ) @context 22 | 23 | ([ 24 | (dictionary) 25 | (list) 26 | ] @context) 27 | -------------------------------------------------------------------------------- /queries/svelte/context.scm: -------------------------------------------------------------------------------- 1 | ; inherits: html 2 | 3 | ([ 4 | (if_statement) 5 | (else_if_block) 6 | (each_statement) 7 | (await_statement) 8 | (key_statement) 9 | ] @context) 10 | -------------------------------------------------------------------------------- /queries/swift/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (switch_statement) 3 | (protocol_declaration) 4 | (repeat_while_statement) 5 | (do_statement) 6 | ] @context) 7 | 8 | (switch_entry 9 | (statements) @context.end 10 | ) @context 11 | 12 | (catch_block 13 | (statements) @context.end 14 | ) @context 15 | 16 | (class_declaration 17 | body: (_ (_) @context.end) 18 | ) @context 19 | 20 | (if_statement 21 | (statements) @context.end 22 | ) @context 23 | 24 | (function_declaration 25 | body: (_ (_) @context.end) 26 | ) @context 27 | 28 | (property_declaration 29 | computed_value: (_ (_) @context.end) 30 | ) @context 31 | 32 | (for_statement 33 | (statements) @context.end 34 | ) @context 35 | 36 | (while_statement 37 | (statements) @context.end 38 | ) @context 39 | 40 | (guard_statement 41 | (statements) @context.end 42 | ) @context 43 | 44 | (lambda_literal 45 | (statements) @context.end 46 | ) @context 47 | 48 | -------------------------------------------------------------------------------- /queries/tact/context.scm: -------------------------------------------------------------------------------- 1 | ; See: https://github.com/nvim-treesitter/nvim-treesitter-context/blob/master/CONTRIBUTING.md 2 | ; storage types 3 | ; ------------- 4 | (struct 5 | body: (_ 6 | (_) @context.end)) @context 7 | 8 | (message 9 | body: (_ 10 | (_) @context.end)) @context 11 | 12 | (contract 13 | body: (_ 14 | (_) @context.end)) @context 15 | 16 | (trait 17 | body: (_ 18 | (_) @context.end)) @context 19 | 20 | ; functions 21 | ; --------- 22 | (asm_function 23 | body: (_ 24 | (_) @context.end)) @context 25 | 26 | (global_function 27 | body: (_ 28 | (_) @context.end)) @context 29 | 30 | (init_function 31 | body: (_ 32 | (_) @context.end)) @context 33 | 34 | (receive_function 35 | body: (_ 36 | (_) @context.end)) @context 37 | 38 | (external_function 39 | body: (_ 40 | (_) @context.end)) @context 41 | 42 | (bounced_function 43 | body: (_ 44 | (_) @context.end)) @context 45 | 46 | (storage_function 47 | body: (_ 48 | (_) @context.end)) @context 49 | 50 | ; statements 51 | ; ---------- 52 | (if_statement 53 | consequence: (_ 54 | (_) @context.end)) @context 55 | 56 | (else_clause 57 | (_ 58 | (_) @context.end)) @context 59 | 60 | (try_statement 61 | body: (_ 62 | (_) @context.end)) @context 63 | 64 | (catch_clause 65 | body: (_ 66 | (_) @context.end)) @context 67 | 68 | (while_statement 69 | body: (_ 70 | (_) @context.end)) @context 71 | 72 | (repeat_statement 73 | body: (_ 74 | (_) @context.end)) @context 75 | 76 | (do_until_statement 77 | body: (_ 78 | (_) @context.end)) @context 79 | 80 | (foreach_statement 81 | body: (_ 82 | (_) @context.end)) @context 83 | 84 | [ 85 | (return_statement) 86 | (expression_statement) 87 | ] @context 88 | 89 | ; expressions 90 | ; ----------- 91 | (method_call_expression 92 | arguments: (_ 93 | (_) @context.end)) @context 94 | 95 | (static_call_expression 96 | arguments: (_ 97 | (_) @context.end)) @context 98 | 99 | (instance_expression 100 | arguments: (_ 101 | (_) @context.end)) @context 102 | 103 | (initOf 104 | arguments: (_ 105 | (_) @context.end)) @context 106 | -------------------------------------------------------------------------------- /queries/tcl/context.scm: -------------------------------------------------------------------------------- 1 | (procedure) @context 2 | (while) @context 3 | (if) @context 4 | (else) @context 5 | (elseif) @context 6 | (command) @context 7 | -------------------------------------------------------------------------------- /queries/teal/context.scm: -------------------------------------------------------------------------------- 1 | 2 | (while_statement) @context 3 | 4 | (generic_for_statement 5 | body: (_ (_) @context.end) 6 | ) @context 7 | 8 | (function_statement 9 | body: (_) @context.end 10 | ) @context 11 | 12 | (anon_function 13 | body: (_) @context.end 14 | ) @context 15 | 16 | (if_statement 17 | condition: (_) 18 | (_) @context.end 19 | ) @context 20 | 21 | (elseif_block 22 | condition: (_) 23 | (_) @context.end 24 | ) @context 25 | 26 | (record_declaration 27 | record_body: (_) @context.end 28 | ) @context 29 | -------------------------------------------------------------------------------- /queries/templ/context.scm: -------------------------------------------------------------------------------- 1 | ; inherits: go,html 2 | 3 | ([ 4 | (component_declaration) 5 | (script_declaration) 6 | (css_declaration) 7 | (component_switch_statement) 8 | (component_switch_expression_case) 9 | (component_switch_default_case) 10 | ] @context) 11 | 12 | (component_if_statement 13 | consequence: (component_block (_) @context.end) 14 | ) @context 15 | 16 | (component_for_statement 17 | body: (component_block (_) @context.end) 18 | ) @context 19 | 20 | (component_import 21 | body: (component_block (_) @context.end) 22 | ) @context 23 | -------------------------------------------------------------------------------- /queries/terraform/context.scm: -------------------------------------------------------------------------------- 1 | 2 | ([ 3 | (block) 4 | (object) 5 | (object_elem) 6 | (attribute) 7 | (template_literal) 8 | ] @context) 9 | 10 | (for_object_expr 11 | (_) 12 | (for_intro) @context.start 13 | (_) @context.end 14 | ) @context 15 | 16 | -------------------------------------------------------------------------------- /queries/toml/context.scm: -------------------------------------------------------------------------------- 1 | 2 | ([ 3 | (table) 4 | (table_array_element) 5 | (inline_table) 6 | (array) 7 | (pair) 8 | ] @context) 9 | -------------------------------------------------------------------------------- /queries/tsx/context.scm: -------------------------------------------------------------------------------- 1 | (if_statement 2 | consequence: (_) @context.end 3 | ) @context 4 | 5 | ([ 6 | (call_expression) 7 | (class_declaration) 8 | (else_clause) 9 | (expression_statement) 10 | (for_statement) 11 | (for_in_statement) 12 | (interface_declaration) 13 | (jsx_element) 14 | (jsx_self_closing_element) 15 | (lexical_declaration) 16 | (method_definition) 17 | (object) 18 | (pair) 19 | (while_statement) 20 | (switch_statement) 21 | (switch_case) 22 | ] @context) 23 | 24 | (arrow_function 25 | body: (_ (_) @context.end) 26 | ) @context 27 | 28 | (function_declaration 29 | body: (_ (_) @context.end) 30 | ) @context 31 | 32 | (generator_function_declaration 33 | body: (_ (_) @context.end) 34 | ) @context 35 | -------------------------------------------------------------------------------- /queries/typescript/context.scm: -------------------------------------------------------------------------------- 1 | (if_statement 2 | consequence: (_) @context.end 3 | ) @context 4 | 5 | ([ 6 | (call_expression) 7 | (class_declaration) 8 | (else_clause) 9 | (expression_statement) 10 | (for_statement) 11 | (for_in_statement) 12 | (interface_declaration) 13 | (lexical_declaration) 14 | (method_definition) 15 | (object) 16 | (pair) 17 | (while_statement) 18 | (switch_statement) 19 | (switch_case) 20 | ] @context) 21 | 22 | (arrow_function 23 | body: (_ (_) @context.end) 24 | ) @context 25 | 26 | (function_declaration 27 | body: (_ (_) @context.end) 28 | ) @context 29 | 30 | (generator_function_declaration 31 | body: (_ (_) @context.end) 32 | ) @context 33 | -------------------------------------------------------------------------------- /queries/typoscript/context.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (configuration_block) 3 | (condition_block) 4 | ]@context 5 | -------------------------------------------------------------------------------- /queries/typst/context.scm: -------------------------------------------------------------------------------- 1 | ((section) @context) 2 | -------------------------------------------------------------------------------- /queries/usd/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (prim_definition) 3 | (variant_set_definition) 4 | (variant) 5 | ] @context) 6 | -------------------------------------------------------------------------------- /queries/verilog/context.scm: -------------------------------------------------------------------------------- 1 | (always_construct) @context 2 | (conditional_statement) @context 3 | (loop_generate_construct) @context 4 | (hierarchical_instance) @context 5 | -------------------------------------------------------------------------------- /queries/vhdl/context.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (block_comment) 3 | (architecture_definition) 4 | (architecture_head) 5 | (concurrent_block) 6 | (configuration_declaration) 7 | (component_instantiation_statement) 8 | (generic_map_aspect) 9 | (port_map_aspect) 10 | (process_statement) 11 | (process_head) 12 | (sequential_block) 13 | (block_configuration) 14 | (block_statement) 15 | (block_head) 16 | (component_declaration) 17 | (component_configuration) 18 | (generic_clause) 19 | (port_clause) 20 | (entity_declaration) 21 | (entity_head) 22 | (entity_body) 23 | (package_declaration) 24 | (package_definition) 25 | (function_specification) 26 | (subprogram_declaration) 27 | (subprogram_definition) 28 | (subprogram_head) 29 | (procedure_specification 30 | (identifier) @context.end) 31 | (sequential_block) 32 | (loop_statement) 33 | (if_statement_block) 34 | (if_statement) 35 | (elsif_statement) 36 | (else_statement) 37 | (case_statement) 38 | (case_statement_alternative) 39 | (for_generate_statement) 40 | (if_generate_statement) 41 | (if_generate) 42 | (elsif_generate) 43 | (else_generate) 44 | (case_generate_statement) 45 | (case_generate_alternative) 46 | (type_declaration) 47 | ] @context 48 | 49 | ; A nice to have, unfortunately, treesitter-context does not support the make-range function 50 | ; https://github.com/nvim-treesitter/nvim-treesitter-context/issues/454 51 | ; (_ 52 | ; (if_conditional_analysis) @_start @context.start @context.end 53 | ; (end_conditional_analysis) @_end 54 | ; (#make-range! "context" @_start @_end)) 55 | -------------------------------------------------------------------------------- /queries/vim/context.scm: -------------------------------------------------------------------------------- 1 | 2 | (if_statement 3 | (body) @context.end 4 | ) @context 5 | 6 | (elseif_statement 7 | (body) @context.end 8 | ) @context 9 | 10 | (else_statement 11 | (body) @context.end 12 | ) @context 13 | 14 | (function_definition 15 | (body) @context.end 16 | ) @context 17 | 18 | (while_loop 19 | (body) @context.end 20 | ) @context 21 | 22 | (for_loop 23 | (body) @context.end 24 | ) @context 25 | 26 | (try_statement 27 | (body) @context.end 28 | ) @context 29 | 30 | (catch_statement 31 | (body) @context.end 32 | ) @context 33 | 34 | (finally_statement 35 | (body) @context.end 36 | ) @context 37 | -------------------------------------------------------------------------------- /queries/vue/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (element) 3 | (template_element) 4 | (script_element) 5 | (style_element) 6 | ] @context) 7 | -------------------------------------------------------------------------------- /queries/xml/context.scm: -------------------------------------------------------------------------------- 1 | 2 | ([ 3 | (element) 4 | ] @context) 5 | -------------------------------------------------------------------------------- /queries/yaml/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (block_mapping_pair) 3 | (block_sequence_item) 4 | ] @context) 5 | -------------------------------------------------------------------------------- /queries/yang/context.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (module) 3 | (statement) 4 | ]@context 5 | -------------------------------------------------------------------------------- /queries/zig/context.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (for_statement) 3 | (while_statement) 4 | (if_expression) 5 | (if_type_expression) 6 | (test_declaration) 7 | (comptime_declaration) 8 | (using_namespace_declaration) 9 | ] @context) 10 | 11 | (function_declaration 12 | (block (_) @context.end) 13 | ) @context 14 | 15 | (variable_declaration 16 | type: (_)? @context.end 17 | ) @context 18 | 19 | (if_statement 20 | (block (_) @context.end) 21 | ) @context 22 | 23 | (switch_expression 24 | "{" @context.end 25 | ) @context 26 | -------------------------------------------------------------------------------- /release-please-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", 3 | "release-type": "simple", 4 | "include-component-in-tag": false 5 | } 6 | -------------------------------------------------------------------------------- /static/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter-context/464a443b5a6657f39772b20baa95d02ffe97b268/static/demo.gif -------------------------------------------------------------------------------- /test/contexts_spec.lua: -------------------------------------------------------------------------------- 1 | local helpers = require('nvim-test.helpers') 2 | local exec_lua = helpers.exec_lua 3 | local cmd = helpers.api.nvim_command 4 | local feed = helpers.feed 5 | local api = helpers.api 6 | local fn = helpers.fn 7 | 8 | local tc_helpers = require('test.helpers') 9 | 10 | --- @param line string 11 | --- @return string? 12 | local function parse_directive(line) 13 | --- @type string? 14 | local directive = line:match('{{([A-Z]+)}}') 15 | return directive 16 | end 17 | 18 | --- @param filename string 19 | --- @return table? contexts 20 | local function parse_directives(filename) 21 | local f = io.open(filename, 'r') 22 | if not f then 23 | return 24 | end 25 | 26 | local context = {} --- @type table 27 | local contexts = {} --- @type table 28 | 29 | local i = 0 30 | for l in f:lines() do 31 | local directive = parse_directive(l) 32 | if directive then 33 | if directive == 'TEST' then 34 | context = {} 35 | elseif directive == 'CURSOR' then 36 | contexts[i] = vim.deepcopy(context) 37 | elseif directive == 'CONTEXT' then 38 | table.insert(context, i) 39 | elseif directive == 'POPCONTEXT' then 40 | table.remove(context, #context) 41 | end 42 | end 43 | i = i + 1 44 | end 45 | f:close() 46 | 47 | for _, c in pairs(contexts) do 48 | table.sort(c) 49 | end 50 | 51 | return contexts 52 | end 53 | 54 | --- Install the root treesitter language for the given file and injected languages. 55 | --- @param filename string 56 | --- @param root_lang string 57 | local function install_langs_for_file(filename, root_lang) 58 | cmd('edit ' .. filename) 59 | local bufnr = api.nvim_get_current_buf() 60 | local line_count = api.nvim_buf_line_count(bufnr) 61 | --- @type table 62 | local seen_langs = {} 63 | --- @type string[] 64 | local langs_to_check = { root_lang } 65 | while #langs_to_check > 0 do 66 | local current_lang = table.remove(langs_to_check, 1) 67 | -- We might encounter recursion, so check if we've traversed this language before. 68 | if seen_langs[current_lang] then 69 | goto continue 70 | end 71 | exec_lua(tc_helpers.install_langs, current_lang) 72 | 73 | -- Query for injections in the current language, and queue them for installation. 74 | --- @diagnostic disable-next-line: redefined-local Not actually redefining locals 75 | langs_to_check = exec_lua(function(bufnr, current_lang, line_count, langs_to_check) 76 | local current_parser = vim.treesitter.get_parser(bufnr, current_lang) 77 | if not current_parser then 78 | return langs_to_check 79 | end 80 | -- Parsing the whole file is a simple way to get all injections for the file. 81 | local tree_map = current_parser:parse({ 0, line_count }) 82 | if not tree_map then 83 | return langs_to_check 84 | end 85 | local injection_query = vim.treesitter.query.get(current_lang, 'injections') 86 | if not injection_query then 87 | return langs_to_check 88 | end 89 | for _, tree in pairs(tree_map) do 90 | local root = tree:root() 91 | for id, node, metadata in injection_query:iter_captures(root, bufnr, 0, line_count) do 92 | -- The name of the injection language is either available through metadata or the text 93 | -- content of the `injection.language` capture. 94 | if metadata['injection.language'] then 95 | table.insert(langs_to_check, metadata['injection.language']) 96 | end 97 | local capture_name = injection_query.captures[id] 98 | if capture_name == 'injection.language' then 99 | local node_text = vim.treesitter.get_node_text(node, bufnr) 100 | table.insert(langs_to_check, node_text) 101 | end 102 | end 103 | end 104 | return langs_to_check 105 | end, bufnr, current_lang, line_count, langs_to_check) 106 | seen_langs[current_lang] = true 107 | ::continue:: 108 | end 109 | end 110 | 111 | local langs = tc_helpers.get_langs() 112 | local langs_with_queries = {} --- @type string[] 113 | for _, lang in ipairs(langs) do 114 | if vim.uv.fs_stat('queries/' .. lang .. '/context.scm') then 115 | table.insert(langs_with_queries, lang) 116 | end 117 | end 118 | 119 | local lang_to_test_files = {} --- @type table 120 | setup(function() 121 | helpers.clear() 122 | exec_lua(tc_helpers.setup) 123 | exec_lua(tc_helpers.install_langs, 'lua') 124 | 125 | local test_files = fn.globpath('test/lang', '*', true, true) --- @type string[] 126 | for _, test_file in ipairs(test_files) do 127 | cmd('edit ' .. test_file) 128 | local bufnr = api.nvim_get_current_buf() 129 | --- @type string 130 | local treesitter_lang = exec_lua(function(...) 131 | local ok, parser = pcall(vim.treesitter.get_parser, ...) 132 | if not ok then 133 | return nil 134 | end 135 | return parser:lang() 136 | end, bufnr) 137 | if treesitter_lang ~= nil and treesitter_lang ~= '' then 138 | if not lang_to_test_files[treesitter_lang] then 139 | lang_to_test_files[treesitter_lang] = {} 140 | end 141 | if not vim.tbl_contains(lang_to_test_files[treesitter_lang], test_file) then 142 | table.insert(lang_to_test_files[treesitter_lang], test_file) 143 | end 144 | end 145 | end 146 | end) 147 | 148 | for _, lang in ipairs(langs_with_queries) do 149 | describe('contexts (' .. lang .. '):', function() 150 | local test_files_for_filetype = lang_to_test_files[lang] 151 | if not test_files_for_filetype then 152 | pending('No test file') 153 | return 154 | end 155 | for _, test_file in ipairs(test_files_for_filetype) do 156 | local contexts = parse_directives(test_file) 157 | 158 | if not contexts or not next(contexts) then 159 | pending('No test markers in ' .. test_file) 160 | return 161 | end 162 | 163 | lazy_setup(function() 164 | cmd([[let $XDG_CACHE_HOME='scratch/cache']]) 165 | install_langs_for_file(test_file, lang) 166 | end) 167 | 168 | for cursor_row, context_rows in pairs(contexts) do 169 | it(('line %s in %s'):format(cursor_row, test_file), function() 170 | cmd('edit ' .. test_file) 171 | local winid = api.nvim_get_current_win() 172 | api.nvim_win_set_cursor(winid, { cursor_row + 1, 0 }) 173 | assert(fn.getline('.'):match('{{CURSOR}}')) 174 | feed(string.format('zt%d', #context_rows + 2)) 175 | 176 | --- @type [integer,integer,integer,integer][] 177 | local ranges = exec_lua(function(...) 178 | return assert(require('treesitter-context.context').get(...)) 179 | end, winid) 180 | 181 | local act_context_rows = {} --- @type integer[] 182 | for _, r in ipairs(ranges) do 183 | local start_row = r[1] 184 | local end_row = r[3] 185 | for i = start_row, end_row - 1 do 186 | table.insert(act_context_rows, i) 187 | end 188 | end 189 | 190 | helpers.eq( 191 | context_rows, 192 | act_context_rows, 193 | string.format('test for cursor %d failed', cursor_row) 194 | ) 195 | end) 196 | end 197 | end 198 | end) 199 | end 200 | -------------------------------------------------------------------------------- /test/helpers.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.install_langs(langs) 4 | if type(langs) == 'string' then 5 | langs = { langs } 6 | end 7 | require('nvim-treesitter').install(langs):wait() 8 | -- Dirty hack to clear ext_messages 9 | vim.cmd.normal(':') 10 | end 11 | 12 | local langs --- @type string[]? 13 | 14 | function M.get_langs() 15 | if langs then 16 | return langs 17 | end 18 | 19 | langs = {} 20 | local f = assert(io.open('README.md', 'r')) 21 | local readme_langs = {} --- @type table 22 | for l in f:lines() do 23 | --- @type string? 24 | local lang = l:match('%- %[x%] `([^`]+)`') 25 | if lang then 26 | readme_langs[lang] = true 27 | end 28 | end 29 | f:close() 30 | 31 | ---@type table 32 | local parsers = require('deps/nvim-treesitter/lua/nvim-treesitter/parsers') 33 | 34 | for k in vim.spairs(parsers) do 35 | langs[#langs + 1] = k 36 | if readme_langs[k] then 37 | readme_langs[k] = nil 38 | end 39 | end 40 | if next(readme_langs) then 41 | print('Invalid languages in README:', table.concat(vim.tbl_keys(readme_langs), ', ')) 42 | end 43 | return langs 44 | end 45 | 46 | --- @param opts? TSContext.UserConfig 47 | function M.setup(opts) 48 | -- Do not pull in parsers from /usr/local/share/ as they may 49 | -- be the wrong ABI 50 | vim.opt.runtimepath = { 51 | vim.env.VIMRUNTIME, 52 | '.', 53 | './deps/nvim-treesitter', 54 | } 55 | require('nvim-treesitter').setup({ 56 | install_dir = vim.fs.joinpath('deps', 'nvim-treesitter-data'), 57 | }) 58 | 59 | require('treesitter-context').setup(opts) 60 | -- Need to source plugin to define highlights for screen tests 61 | vim.cmd.source(vim.api.nvim_get_runtime_file('plugin/treesitter-context.lua', false)[1]) 62 | 63 | vim.env.XDG_CACHE_HOME = 'scratch/cache' 64 | vim.opt.packpath = '' 65 | end 66 | 67 | if arg[0] == 'test/helpers.lua' and arg[1] == 'install' then 68 | M.setup() 69 | M.install_langs(M.get_langs()) 70 | end 71 | 72 | return M 73 | -------------------------------------------------------------------------------- /test/lang/test.Makefile: -------------------------------------------------------------------------------- 1 | test: # {{CONTEXT}} 2 | 3 | 4 | 5 | echo "Hello {{CURSOR}}" 6 | 7 | -------------------------------------------------------------------------------- /test/lang/test.adb: -------------------------------------------------------------------------------- 1 | with Ada.Text_IO; use Ada.Text_IO; 2 | 3 | -- {{TEST}} 4 | package Week is -- {{CONTEXT}} 5 | 6 | Mon : constant String := "Monday"; 7 | Tue : constant String := "Tuesday"; 8 | Wed : constant String := "Wednesday"; 9 | Thu : constant String := "Thursday"; 10 | Fri : constant String := "Friday"; 11 | Sat : constant String := "Saturday"; 12 | Sun : constant String := "Sunday"; -- {{CURSOR}} 13 | 14 | 15 | 16 | end Week; 17 | 18 | -- {{TEST}} 19 | package Months -- {{CONTEXT}} 20 | is 21 | 22 | Jan : constant String := "January"; 23 | Feb : constant String := "February"; -- {{CURSOR}} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | end Months; 35 | 36 | -- {{TEST}} 37 | procedure Show_Increment is -- {{CONTEXT}} 38 | A, B, C : Integer; 39 | 40 | procedure Display_Result is -- {{CONTEXT}} 41 | begin 42 | Put_Line ("Increment of " 43 | & Integer'Image (A) 44 | & " with " 45 | & Integer'Image (B) 46 | & " is " 47 | & Integer'Image (C)); -- {{CURSOR}} 48 | 49 | 50 | end Display_Result; 51 | 52 | -- {{POPCONTEXT}} 53 | begin 54 | A := 10; 55 | B := 3; 56 | C := Increment_By (A, B); 57 | Display_Result; 58 | A := 20; 59 | B := 5; 60 | C := Increment_By (A, B); -- {{CURSOR}} 61 | Display_Result; 62 | end Show_Increment; 63 | 64 | 65 | -- {{TEST}} 66 | type Date is -- {{CONTEXT}} 67 | record -- {{CONTEXT}} 68 | Day : Integer range 1 .. 31; 69 | 70 | Month : Months := Jan; 71 | 72 | 73 | 74 | -- {{CURSOR}} 75 | end record; 76 | 77 | -- {{TEST}} 78 | procedure Greet is -- {{CONTEXT}} 79 | begin 80 | 81 | X := 2; 82 | 83 | Ada.Text_IO.Put_Line ("Hello"); 84 | 85 | 86 | for N in 1 .. 5 loop -- {{CONTEXT}} 87 | 88 | 89 | Put_Line("Hi"); 90 | 91 | -- {{CURSOR}} 92 | end loop; 93 | -- {{POPCONTEXT}} 94 | Y := 1; 95 | loop -- {{CONTEXT}} 96 | 97 | 98 | exit when Y = 5; 99 | 100 | -- {{CURSOR}} 101 | end loop; 102 | -- {{POPCONTEXT}} 103 | while Y >= 0 loop -- {{CONTEXT}} 104 | Y := Y - 1; 105 | 106 | 107 | 108 | -- {{CURSOR}} 109 | end loop; 110 | 111 | 112 | -- {{POPCONTEXT}} 113 | case Y is -- {{CONTEXT}} 114 | when 0 .. 10 => 115 | Put_Line("foo"); 116 | 117 | 118 | 119 | when others => 120 | Put_Line("bar"); -- {{CURSOR}} 121 | end case; 122 | 123 | end Greet; 124 | 125 | 126 | -- {{TEST}} 127 | function Foo -- {{CONTEXT}} 128 | (I : Integer := 0;) 129 | return Integer is 130 | begin 131 | -- bar 132 | 133 | 134 | 135 | 136 | return I + 1; -- {{CURSOR}} 137 | end Foo; 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /test/lang/test.apex: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | public class MyClass { 3 | 4 | 5 | 6 | 7 | 8 | public void my_method(Integer param) { // {{CONTEXT}} 9 | 10 | 11 | 12 | 13 | if (true) { // {{CONTEXT}} 14 | 15 | 16 | 17 | 18 | for (Integer i = 0; i < 10; i++) { // {{CONTEXT}} 19 | 20 | 21 | 22 | 23 | for (Integer v : values) { // {{CONTEXT}} 24 | 25 | 26 | 27 | 28 | System. // {{CONTEXT}} 29 | 30 | 31 | 32 | debug('a message'); // {{CURSOR}} 33 | } 34 | } 35 | } 36 | } 37 | } 38 | // vim: ft=apex 39 | -------------------------------------------------------------------------------- /test/lang/test.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # {{TEST}} 4 | 5 | foo() { # {{CONTEXT}} 6 | 7 | if [ 1 -eq 1 ]; then # {{CONTEXT}} 8 | echo 1 9 | 10 | 11 | # {{CURSOR}} 12 | fi 13 | 14 | } 15 | 16 | 17 | # {{TEST}} 18 | 19 | bar() { # {{CONTEXT}} 20 | case "$i" in # {{CONTEXT}} 21 | 1) echo 1 # {{CONTEXT}} 22 | 23 | 24 | 25 | # {{CURSOR}} 26 | ;; 27 | 2|3) echo 2 or 3 28 | ;; 29 | *) echo default 30 | ;; 31 | esac 32 | } 33 | 34 | 35 | # {{TEST}} 36 | 37 | baz() { # {{CONTEXT}} 38 | while [ $x -le 5 ] # {{CONTEXT}} 39 | do 40 | echo "Welcome $x times" 41 | 42 | x=$(( $x + 1 )) 43 | # {{CURSOR}} 44 | done 45 | } 46 | 47 | # {{TEST}} 48 | 49 | baz2() { # {{CONTEXT}} 50 | # until is also a while loop 51 | until [ $x -gt 5 ] # {{CONTEXT}} 52 | do 53 | echo Counter: $x 54 | ((x++)) 55 | # {{CURSOR}} 56 | done 57 | } 58 | 59 | # {{TEST}} 60 | 61 | # select is a for statement 62 | select character in Sheldon Leonard Penny Howard Raj # {{CONTEXT}} 63 | do 64 | echo "Selected character: $character" 65 | 66 | # {{CURSOR}} 67 | done 68 | 69 | # {{POPCONTEXT}} 70 | 71 | for ((i=0; i<=10000; i++)); do # {{CONTEXT}} 72 | 73 | 74 | 75 | # {{CURSOR}} 76 | echo "$i" 77 | done 78 | 79 | 80 | -------------------------------------------------------------------------------- /test/lang/test.bzl: -------------------------------------------------------------------------------- 1 | # {{TEST}} 2 | def function_definition(): # {{CONTEXT}} 3 | """ 4 | 5 | 6 | {{CURSOR}}""" 7 | if True: # {{CONTEXT}} 8 | 9 | 10 | 11 | 12 | "{{CURSOR}}" 13 | 14 | # {{TEST}} 15 | def function_definition_2(): # {{CONTEXT}} 16 | native.genrule( # {{CONTEXT}} 17 | name = "genrule", 18 | 19 | 20 | # {{CURSOR}} 21 | ) 22 | 23 | # {{TEST}} 24 | LIST = [ # {{CONTEXT}} 25 | 26 | 27 | 28 | "{{CURSOR}}", 29 | ] 30 | # {{TEST}} 31 | DICT = { # {{CONTEXT}} 32 | "key": "value", 33 | "dict_key": { # {{CONTEXT}} 34 | "key": "value", 35 | "list_key": [ # {{CONTEXT}} 36 | 37 | 38 | 39 | "{{CURSOR}}", 40 | ], 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/lang/test.c: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | 3 | struct Bert { // {{CONTEXT}} 4 | int *f1; 5 | int *f2; 6 | 7 | // {{CURSOR}} 8 | }; 9 | 10 | 11 | // {{TEST}} 12 | 13 | typedef enum { // {{CONTEXT}} 14 | E1, 15 | E2, 16 | E3 17 | // {{CURSOR}} 18 | } Myenum; 19 | 20 | 21 | // {{TEST}} 22 | 23 | int main(int arg1, // {{CONTEXT}} 24 | char **arg2, // {{CONTEXT}} 25 | char **arg3) // {{CONTEXT}} 26 | { // {{CONTEXT}} 27 | 28 | if (arg1 == 4 // {{CONTEXT}} 29 | && arg2 == arg3) { // {{CONTEXT}} 30 | 31 | 32 | 33 | 34 | // {{CURSOR}} 35 | 36 | for (int i = 0; i < arg1; i++) { // {{CONTEXT}} 37 | 38 | 39 | 40 | 41 | // {{CURSOR}} 42 | while (1) { // {{CONTEXT}} 43 | 44 | 45 | 46 | 47 | // {{CURSOR}} 48 | } 49 | 50 | } 51 | } 52 | } 53 | 54 | 55 | // {{TEST}} 56 | 57 | void foo(int a) { // {{CONTEXT}} 58 | if (a) { // {{CONTEXT}} 59 | do { // {{CONTEXT}} 60 | 61 | 62 | 63 | // {{CURSOR}} 64 | } while (1); 65 | } 66 | } 67 | 68 | 69 | // {{TEST}} 70 | 71 | void bar(int a) { // {{CONTEXT}} 72 | if (a) { // {{CONTEXT}} 73 | 74 | } else if (a == 4) { // {{CONTEXT}} 75 | // comment 76 | } else { // {{CONTEXT}} 77 | 78 | 79 | 80 | // {{CURSOR}} 81 | } 82 | } 83 | 84 | 85 | // {{TEST}} 86 | 87 | void baz(int a) { // {{CONTEXT}} 88 | switch (a) { // {{CONTEXT}} 89 | case 0: 90 | break; 91 | case 1: { // {{CONTEXT}} 92 | 93 | 94 | 95 | // {{CURSOR}} 96 | } break; 97 | } 98 | } 99 | 100 | // {{TEST}} 101 | void declaration() { // {{CONTEXT}} 102 | struct Bert foo = { // {{CONTEXT}} 103 | .f1 = 0, 104 | 105 | 106 | // {{CURSOR}} 107 | .f2 = 0, 108 | 109 | }; 110 | } 111 | -------------------------------------------------------------------------------- /test/lang/test.cmake: -------------------------------------------------------------------------------- 1 | 2 | # {{TEST}} 3 | foreach(subdir # {{CONTEXT}} 4 | os 5 | api 6 | api/private 7 | msgpack_rpc 8 | tui 9 | event 10 | eval 11 | lua 12 | viml 13 | viml/parser # {{CURSOR}} 14 | ) 15 | 16 | if(WIN32) # {{CONTEXT}} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | # {{CURSOR}} 30 | 31 | add_custom_command( # {{CONTEXT}} 32 | 33 | 34 | 35 | OUTPUT ${GEN_EVAL_FILES} 36 | 37 | 38 | 39 | 40 | COMMAND ${PROJECT_SOURCE_DIR}/scripts/gen_eval_files.lua 41 | 42 | 43 | 44 | DEPENDS 45 | ${API_METADATA} 46 | ${PROJECT_SOURCE_DIR}/scripts/gen_eval_files.lua 47 | ${PROJECT_SOURCE_DIR}/src/nvim/eval.lua 48 | ${PROJECT_SOURCE_DIR}/src/nvim/options.lua 49 | ${PROJECT_SOURCE_DIR}/runtime/doc/api.mpack 50 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} # {{CURSOR}} 51 | ) 52 | # {{POPCONTEXT}} 53 | 54 | 55 | 56 | 57 | 58 | elseif(APPLE) 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | # {{CURSOR}} 85 | 86 | endif() 87 | # {{POPCONTEXT}} 88 | 89 | 90 | 91 | 92 | # {{CURSOR}} 93 | endforeach() 94 | -------------------------------------------------------------------------------- /test/lang/test.cpp: -------------------------------------------------------------------------------- 1 | // # {{TEST}} 2 | struct Struct { // {{CONTEXT}} 3 | int *f1; 4 | int *f2; 5 | 6 | 7 | 8 | // {{CURSOR}} 9 | }; 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | // {{TEST}} 18 | class Class { // {{CONTEXT}} 19 | int *f1; 20 | int *f2; 21 | 22 | 23 | 24 | // {{CURSOR}} 25 | }; 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | // {{TEST}} 35 | typedef enum { // {{CONTEXT}} 36 | E1, 37 | E2, 38 | E3 39 | 40 | 41 | // {{CURSOR}} 42 | } myenum; 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | // {{TEST}} 53 | int main(int arg1, // {{CONTEXT}} 54 | char **arg2, // {{CONTEXT}} 55 | char **arg3 // {{CONTEXT}} 56 | ) // {{CONTEXT}} 57 | { // {{CONTEXT}} 58 | if (arg1 == 4 // {{CONTEXT}} 59 | && arg2 == arg3) { // {{CONTEXT}} 60 | for (int i = 0; i < arg1; i++) { // {{CONTEXT}} 61 | while (1) { // {{CONTEXT}} 62 | 63 | 64 | 65 | 66 | 67 | // {{CURSOR}} 68 | } 69 | } 70 | } 71 | // {{POPCONTEXT}} 72 | // {{POPCONTEXT}} 73 | // {{POPCONTEXT}} 74 | // {{POPCONTEXT}} 75 | 76 | 77 | do { // {{CONTEXT}} 78 | int array[1]; 79 | for (auto value : array) { // {{CONTEXT}} 80 | 81 | 82 | 83 | 84 | 85 | // {{CURSOR}} 86 | } 87 | } while (1); 88 | } 89 | -------------------------------------------------------------------------------- /test/lang/test.cs: -------------------------------------------------------------------------------- 1 | // # {{TEST}} 2 | namespace hello_world // {{CONTEXT}} 3 | { 4 | interface IInterface // {{CONTEXT}} 5 | { 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | // {{CURSOR}} 15 | } 16 | // {{POPCONTEXT}} 17 | public enum Direction // {{CONTEXT}} 18 | { 19 | Left, 20 | Right, 21 | Up, 22 | Down 23 | 24 | 25 | // {{CURSOR}} 26 | } 27 | // {{POPCONTEXT}} 28 | class Cls // {{CONTEXT}} 29 | { 30 | // Constructor 31 | public Cls () // {{CONTEXT}} 32 | { 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | // {{CURSOR}} 45 | } 46 | // {{POPCONTEXT}} 47 | // Destructor 48 | ~Cls() // {{CONTEXT}} 49 | { 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | // {{CURSOR}} 62 | } // {{POPCONTEXT}} 63 | } // {{POPCONTEXT}} 64 | 65 | record Record // {{CONTEXT}} 66 | { 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | // {{CURSOR}} 81 | } // {{POPCONTEXT}} 82 | 83 | record struct RecordStruct // {{CONTEXT}} 84 | { 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | // {{CURSOR}} 101 | } // {{POPCONTEXT}} 102 | 103 | public struct Test // {{CONTEXT}} 104 | { 105 | public void Test1() // {{CONTEXT}} 106 | { 107 | if (true) // {{CONTEXT}} 108 | { 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | // {{CURSOR}} 122 | } 123 | else 124 | { 125 | Console.WriteLine(); 126 | Console.WriteLine(); 127 | Console.WriteLine(); 128 | Console.WriteLine(); 129 | Console.WriteLine(); 130 | Console.WriteLine(); 131 | Console.WriteLine(); 132 | Console.WriteLine(); 133 | Console.WriteLine(); 134 | Console.WriteLine(); 135 | Console.WriteLine(); // {{CURSOR}} 136 | } // {{POPCONTEXT}} 137 | var arr = new[] { 1, 2, 3 }; 138 | 139 | foreach (var item in arr) // {{CONTEXT}} 140 | { 141 | 142 | 143 | 144 | 145 | 146 | 147 | // {{CURSOR}} 148 | } // {{POPCONTEXT}} 149 | 150 | for (int i = 0; i < arr.Length; i++) // {{CONTEXT}} 151 | { 152 | try // {{CONTEXT}} 153 | { 154 | Console.WriteLine(); 155 | Console.WriteLine(); 156 | Console.WriteLine(); 157 | Console.WriteLine(); 158 | Console.WriteLine(); 159 | Console.WriteLine(); 160 | Console.WriteLine(); 161 | Console.WriteLine(); 162 | Console.WriteLine(); 163 | Console.WriteLine(); 164 | Console.WriteLine(); 165 | Console.WriteLine(); 166 | Console.WriteLine(); 167 | Console.WriteLine(); 168 | Console.WriteLine(); 169 | Console.WriteLine(); 170 | Console.WriteLine(); 171 | Console.WriteLine(); 172 | Console.WriteLine(); 173 | Console.WriteLine(); 174 | Console.WriteLine(); 175 | Console.WriteLine(); 176 | Console.WriteLine(); 177 | Console.WriteLine(); 178 | Console.WriteLine(); 179 | Console.WriteLine(); 180 | Console.WriteLine(); 181 | Console.WriteLine(); 182 | Console.WriteLine(); 183 | Console.WriteLine(); 184 | Console.WriteLine(); 185 | Console.WriteLine(); 186 | Console.WriteLine(); // {{CURSOR}} 187 | Console.WriteLine(); 188 | Console.WriteLine(); 189 | Console.WriteLine(); 190 | Console.WriteLine(); 191 | Console.WriteLine(); 192 | Console.WriteLine(); 193 | Console.WriteLine(); 194 | Console.WriteLine(); 195 | } 196 | catch // {{CONTEXT}} 197 | { 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | // {{CURSOR}} 211 | 212 | } // {{POPCONTEXT}} 213 | finally // {{CONTEXT}} 214 | { 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | // {{CURSOR}} 228 | 229 | 230 | } // {{POPCONTEXT}} 231 | // {{POPCONTEXT}} 232 | } // {{POPCONTEXT}} 233 | } // {{POPCONTEXT}} 234 | 235 | int Switch(int key) // {{CONTEXT}} 236 | { 237 | switch (key) // {{CONTEXT}} 238 | { 239 | case 0: 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | return 1; // {{CURSOR}} 254 | case 1: 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | return 2; // {{CURSOR}} 264 | case 2: 265 | 266 | 267 | 268 | 269 | 270 | 271 | return 12; 272 | case 3: 273 | return 444; 274 | case 4: 275 | case 5: 276 | case 6: 277 | case 7: 278 | case 8: 279 | case 9: 280 | case 10: 281 | case 11: 282 | case 12: 283 | case 13: 284 | case 14: 285 | case 15: 286 | case 16: 287 | case 17: 288 | case 18: 289 | case 19: 290 | case 20: 291 | case 21: 292 | case 22: 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | return 1234444; 312 | default: throw new Exception(); // {{CURSOR}} 313 | 314 | } // {{POPCONTEXT}} 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | // {{CURSOR}} 329 | 330 | } 331 | } 332 | } 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | -------------------------------------------------------------------------------- /test/lang/test.css: -------------------------------------------------------------------------------- 1 | /* {{TEST}} */ 2 | .foo { /* {{CONTEXT}} */ 3 | background-color: #fff; 4 | color: #000; 5 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 6 | 7 | 8 | font-size: 14px; /* {{CURSOR}} */ 9 | 10 | 11 | @supports (font-size: calc(1vw + 1vh + 1vmin)) { /* {{CONTEXT}} */ 12 | 13 | 14 | 15 | font-size: calc(1vw + 1vh + 1vmin); 16 | 17 | 18 | 19 | 20 | 21 | /* {{CURSOR}} */ 22 | 23 | } /* {{POPCONTEXT}} */ 24 | 25 | @color-profile /* {{CONTEXT}} */ 26 | --swop5c { /* {{CONTEXT}} */ 27 | 28 | 29 | 30 | src: url("https://example.org/SWOP2006_Coated5v2.icc"); 31 | 32 | 33 | 34 | 35 | 36 | 37 | /* {{CURSOR}} */ 38 | 39 | } /* {{POPCONTEXT}} */ 40 | /* {{POPCONTEXT}} */ 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | line-height: 1.42857143; /* {{CURSOR}} */ 49 | } 50 | 51 | /* {{TEST}} */ 52 | @keyframes wave { /* {{CONTEXT}} */ 53 | 0% { /* {{CONTEXT}} */ 54 | transform: translateY(-50%) scale(0); 55 | opacity: 0; 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | /* {{CURSOR}} */ 64 | } /* {{POPCONTEXT}} */ 65 | 50% { /* {{CONTEXT}} */ 66 | 67 | 68 | 69 | transform: translateY(-50%) scale(1); 70 | opacity: 1; /* {{CURSOR}} */ 71 | } /* {{POPCONTEXT}} */ 72 | 100% { /* {{CONTEXT}} */ 73 | transform: translateY(-50%) scale(0); 74 | 75 | 76 | 77 | opacity: 0; /* {{CURSOR}} */ 78 | } /* {{POPCONTEXT}} */ 79 | } /* {{POPCONTEXT}} */ 80 | 81 | /* {{TEST}} */ 82 | @media ( /* {{CONTEXT}} */ 83 | /* {{CONTEXT}} */ 84 | prefers-reduced-motion: reduce) { /* {{CONTEXT}} */ 85 | 86 | 87 | 88 | 89 | /* {{CURSOR}} */ 90 | *, /* {{CONTEXT}} */ 91 | *::before, /* {{CONTEXT}} */ 92 | *::after { /* {{CONTEXT}} */ 93 | animation-duration: 0.01ms !important; 94 | animation-iteration-count: 1 !important; 95 | transition-duration: 0.01ms !important; 96 | scroll-behavior: auto !important; 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | /* {{CURSOR}} */ 112 | 113 | } /* {{POPCONTEXT}} */ 114 | /* {{POPCONTEXT}} */ 115 | /* {{POPCONTEXT}} */ 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | /* {{CURSOR}} */ 127 | } 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /test/lang/test.cu: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | struct Struct { // {{CONTEXT}} 3 | int *f1; 4 | int *f2; 5 | 6 | 7 | 8 | // {{CURSOR}} 9 | }; 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | // {{TEST}} 18 | class Class { // {{CONTEXT}} 19 | int *f1; 20 | int *f2; 21 | 22 | 23 | 24 | // {{CURSOR}} 25 | }; 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | // {{TEST}} 34 | typedef enum { // {{CONTEXT}} 35 | E1, 36 | E2, 37 | E3 38 | 39 | 40 | // {{CURSOR}} 41 | } myenum; 42 | 43 | 44 | 45 | 46 | 47 | 48 | // {{TEST}} 49 | __global__ void kernel(int *a, int *b, int *c) { // {{CONTEXT}} 50 | int i = threadIdx.x; 51 | c[i] = a[i] + b[i]; 52 | 53 | 54 | 55 | // {{CURSOR}} 56 | } 57 | 58 | 59 | // {{TEST}} 60 | int main(int arg1, // {{CONTEXT}} 61 | char **arg2, // {{CONTEXT}} 62 | char **arg3 // {{CONTEXT}} 63 | ) // {{CONTEXT}} 64 | { // {{CONTEXT}} 65 | if (arg1 == 4 // {{CONTEXT}} 66 | && arg2 == arg3) { // {{CONTEXT}} 67 | for (int i = 0; i < arg1; i++) { // {{CONTEXT}} 68 | while (1) { // {{CONTEXT}} 69 | 70 | 71 | 72 | 73 | 74 | // {{CURSOR}} 75 | } // {{POPCONTEXT}} 76 | } // {{POPCONTEXT}} 77 | } // {{POPCONTEXT}} 78 | // {{POPCONTEXT}} 79 | 80 | 81 | 82 | // {{CURSOR}} 83 | 84 | do { // {{CONTEXT}} 85 | int array[1]; 86 | for (auto value : array) { // {{CONTEXT}} 87 | 88 | 89 | 90 | 91 | 92 | // {{CURSOR}} 93 | } 94 | } while (1); 95 | } 96 | -------------------------------------------------------------------------------- /test/lang/test.cue: -------------------------------------------------------------------------------- 1 | package main 2 | // {{TEST}} 3 | import ( // {{CONTEXT}} 4 | 5 | 6 | 7 | 8 | "strings" 9 | 10 | 11 | 12 | "encoding/json" // {{CURSOR}} 13 | ) 14 | // {{TEST}} 15 | jsonVal: json.Marshal({ // {{CONTEXT}} 16 | 17 | 18 | 19 | 20 | 21 | hello: strings.ToUpper("world") 22 | 23 | 24 | 25 | 26 | 27 | list: [1, 2] 28 | nested: foo: "bar" // {{CURSOR}} 29 | }) 30 | 31 | apps: ["nginx", "express", "postgres"] 32 | #labels: [string]: string 33 | // {{TEST}} 34 | stack: { // {{CONTEXT}} 35 | let local = { // {{CONTEXT}} 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | name: "Alice" 44 | 45 | // {{CURSOR}} 46 | } // {{POPCONTEXT}} 47 | local 48 | 49 | injected: _ @tag(inj, type=int) 50 | 51 | 52 | 53 | for i, app in apps 54 | if app != "nginx" { 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | "\(app)": { 65 | if app == "postgres" { 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | isPostgres: true 75 | } 76 | 77 | 78 | name: app 79 | labels: #labels & { 80 | 81 | 82 | 83 | 84 | 85 | app: "foo" 86 | tier: "\(i)" 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /test/lang/test.d: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | struct S // {{CONTEXT}} 3 | { // {{CONTEXT}} 4 | 5 | 6 | 7 | int i; // {{CURSOR}} 8 | } 9 | // {{TEST}} 10 | template t(T: int) { // {{CONTEXT}} 11 | 12 | 13 | 14 | // {{CURSOR}} 15 | } 16 | // {{TEST}} 17 | unittest { // {{CONTEXT}} 18 | 19 | 20 | 21 | // {{CURSOR}} 22 | } 23 | 24 | // {{TEST}} 25 | enum Things { // {{CONTEXT}} 26 | A, 27 | 28 | 29 | B, 30 | C, // {{CURSOR}} 31 | } 32 | // {{TEST}} 33 | union U // {{CONTEXT}} 34 | { // {{CONTEXT}} 35 | ubyte i; 36 | 37 | 38 | 39 | 40 | char c; // {{CURSOR}} 41 | } 42 | // {{TEST}} 43 | interface Bar // {{CONTEXT}} 44 | { // {{CONTEXT}} 45 | 46 | 47 | 48 | // {{CURSOR}} 49 | } 50 | // {{TEST}} 51 | class Foo : Bar // {{CONTEXT}} 52 | { // {{CONTEXT}} 53 | 54 | 55 | 56 | // {{CURSOR}} 57 | void bar (int a, // {{CONTEXT}} 58 | int b) // {{CONTEXT}} 59 | { // {{CONTEXT}} 60 | 61 | try { // {{CONTEXT}} 62 | 63 | 64 | 65 | // {{CURSOR}} 66 | } catch (Exception e) { // {{CONTEXT}} 67 | 68 | 69 | 70 | // {{CURSOR}} 71 | } 72 | // BUG: Should keep class context 73 | asm 74 | { 75 | 76 | 77 | mov EAX, dword ptr 0x1234; 78 | mov EAX, dword ptr 0x1234; 79 | } 80 | 81 | with (S) { 82 | 83 | 84 | //stuff 85 | } 86 | 87 | for (int i = a; 88 | i < b; i++) 89 | { 90 | 91 | 92 | 93 | // stuff 94 | } 95 | 96 | char[] a = ['h', 'i']; 97 | 98 | foreach (i, 99 | char c; a) 100 | { 101 | 102 | 103 | 104 | 105 | // stuff 106 | } 107 | 108 | if ( 109 | a < b) { 110 | 111 | 112 | 113 | // stuff 114 | } else if ( 115 | b < a) { 116 | 117 | 118 | 119 | // stuff 120 | } else { 121 | 122 | 123 | 124 | 125 | 126 | 127 | // stuff 128 | } 129 | 130 | 131 | while ( 132 | true) { 133 | 134 | 135 | 136 | 137 | 138 | // stuff 139 | } 140 | 141 | switch (i) 142 | { 143 | default: // valid: ends with 'throw' 144 | throw new Exception("unknown number"); 145 | 146 | case 3: // valid: ends with 'break' (break out of the 'switch' only) 147 | message ~= "three"; 148 | 149 | 150 | 151 | 152 | break; 153 | 154 | case 4: // valid: ends with 'continue' (continue the enclosing loop) 155 | message ~= "four"; 156 | continue; // don't append a comma 157 | 158 | case 1: 159 | message ~= ">"; 160 | goto case; 161 | 162 | case 2: // valid: this is the last case in the switch statement. 163 | message ~= "one or two"; 164 | } 165 | 166 | writeln("hello!"); // calls std.stdio.writeln 167 | } 168 | 169 | } 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /test/lang/test.dart: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | @Deprecated('') // {{CONTEXT}} 3 | abstract // {{CONTEXT}} 4 | class User // {{CONTEXT}} 5 | extends // {{CONTEXT}} 6 | Object { // {{CONTEXT}} 7 | User(this.age); 8 | int age; 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | // {{CURSOR}} 20 | 21 | void printAge() { // {{CONTEXT}} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | print(age); // {{CURSOR}} 37 | } 38 | 39 | } 40 | // {{TEST}} 41 | String( 42 | int magicalNumber, 43 | ) { // {{CONTEXT}} 44 | if (magicalNumber == "69" // {{CONTEXT}} 45 | // {{CONTEXT}} 46 | || // {{CONTEXT}} 47 | magicalNumber == "420") { // {{CONTEXT}} 48 | return 'pretty nice'; 49 | 50 | 51 | 52 | // {{CURSOR}} 53 | } else if (magicalNumber == "420" // {{CONTEXT}} 54 | && // {{CONTEXT}} 55 | magicalNumber == "69") { // {{CONTEXT}} 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | return 'pretty high'; // {{CURSOR}} 79 | } // {{POPCONTEXT}} 80 | 81 | return 'just decent'; // BUG: should mark cursor here 82 | } 83 | 84 | // {{TEST}} 85 | void catching() { // {{CONTEXT}} 86 | try // {{CONTEXT}} 87 | // {{CONTEXT}} 88 | { 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | // {{CURSOR}} 103 | } catch (e) { 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | // {{CURSOR}} 113 | 114 | } finally { 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | // {{CURSOR}} 126 | 127 | } 128 | } 129 | // {{TEST}} 130 | void foring() { // {{CONTEXT}} 131 | for (int i = 0; // {{CONTEXT}} 132 | i < 10; // {{CONTEXT}} 133 | i++) { // {{CONTEXT}} 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | // {{CURSOR}} 148 | } // {{POPCONTEXT}} 149 | // {{POPCONTEXT}} 150 | // {{POPCONTEXT}} 151 | 152 | while (true // {{CONTEXT}} 153 | == false) { // {{CONTEXT}} 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | // {{CURSOR}} 171 | 172 | } // {{POPCONTEXT}} 173 | // {{POPCONTEXT}} 174 | 175 | do { // {{CONTEXT}} 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | // {{CURSOR}} 190 | } while (true); 191 | } 192 | // {{TEST}} 193 | extension ext // {{CONTEXT}} 194 | on int { // {{CONTEXT}} 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | // {{CURSOR}} 204 | } 205 | -------------------------------------------------------------------------------- /test/lang/test.diff: -------------------------------------------------------------------------------- 1 | diff --git a/src/main.rs b/src/main.rs // {{CONTEXT}} 2 | index 8a23456..9b78901 100644 3 | --- a/src/main.rs 4 | +++ b/src/main.rs 5 | @@ -10,7 +10,7 @@ fn main() { // {{CONTEXT}} 6 | println!("Hello, world!"); 7 | 8 | // Initialize configuration 9 | - let config = Config::new(); 10 | + let config = Config::new_with_defaults(); 11 | 12 | let args = std::env::args().collect::>(); // {{CURSOR}} 13 | 14 | @@ -25,6 +25,8 @@ fn main() { 15 | // Process command line arguments 16 | let mut processor = ArgProcessor::new(&args); 17 | processor.process(); 18 | + 19 | + println!("Configuration loaded successfully"); 20 | 21 | if args.len() > 1 { 22 | println!("Arguments provided: {}", args.len() - 1); 23 | @@ -45,9 +47,7 @@ fn process_file(path: &str) -> Result<(), Error> { 24 | let file = File::open(path)?; 25 | let reader = BufReader::new(file); 26 | 27 | - for line in reader.lines() { 28 | - println!("{}", line?); 29 | - } 30 | + reader.lines().for_each(|line| println!("{}", line.unwrap_or_default())); 31 | 32 | Ok(()) 33 | } 34 | @@ -78,6 +78,11 @@ impl Config { 35 | } 36 | } 37 | 38 | + pub fn new_with_defaults() -> Self { 39 | + let mut config = Self::new(); 40 | + config.timeout = Some(30); 41 | + config 42 | + } 43 | + 44 | // Other methods... 45 | } 46 | 47 | -------------------------------------------------------------------------------- /test/lang/test.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | // {{TEST}} 4 | 5 | / { // {{CONTEXT}} 6 | compatible = "test"; 7 | #address-cells = <2>; 8 | #size-cells = <2>; 9 | 10 | soc { // {{CONTEXT}} 11 | compatible = "simple-bus"; 12 | ranges; 13 | #address-cells = <2>; 14 | #size-cells = <2>; 15 | 16 | // {{CURSOR}} 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/lang/test.elm: -------------------------------------------------------------------------------- 1 | module Test exposing (..) 2 | 3 | import Html exposing (div, text) 4 | 5 | 6 | main : Html.Html msg 7 | -- {{TEST}} 8 | main = -- {{CONTEXT}} 9 | let 10 | test = 11 | "Test content" 12 | in 13 | case test of -- {{CONTEXT}} 14 | "Hello" -> -- {{CONTEXT}} 15 | div [] 16 | [ text "Hello, World!" 17 | , -- Generate some lines 18 | -- Generate some lines 19 | -- Generate some lines 20 | -- Generate some lines 21 | -- Generate some lines 22 | -- Generate some lines 23 | -- Generate some lines 24 | -- Generate some lines 25 | -- Generate some lines 26 | -- Generate some lines 27 | -- Generate some lines 28 | -- Generate some lines 29 | -- Generate some lines 30 | -- Generate some lines 31 | -- Generate some lines 32 | -- Generate some lines 33 | -- Generate some lines {{CURSOR}} 34 | -- Generate some lines 35 | -- Generate some lines 36 | -- Generate some lines 37 | -- Generate some lines 38 | -- Generate some lines 39 | -- Generate some lines 40 | -- Generate some lines 41 | div [] 42 | [ text "Some more lines" 43 | , text "Some more lines" 44 | , text "Some more lines" 45 | , text "Some more lines" 46 | , text "Some more lines" 47 | , text "Some more lines" 48 | , text "Some more lines" 49 | , text "Some more lines" 50 | , text "Some more lines" 51 | , text "Some more lines" 52 | , text "Some more lines" 53 | , text "Some more lines" 54 | , text "Some more lines" 55 | , text "Some more lines" 56 | , text "Some more lines" 57 | , text "Some more lines" 58 | , text "Some more lines" 59 | , text "Some more lines" 60 | , text "Some more lines" 61 | , text "Some more lines" 62 | , text "Some more lines" 63 | , text "Some more lines" 64 | , text "Some more lines" 65 | , text "Some more lines" 66 | , text "Some more lines" 67 | , text "Some more lines" 68 | , text "Some more lines" 69 | , text "Some more lines" 70 | , text "Some more lines" 71 | , text "Some more lines" -- {{CURSOR}} 72 | , text "Some more lines" 73 | , text "Some more lines" 74 | , text "Some more lines" 75 | , text "Some more lines" 76 | , text "Some more lines" 77 | , text "Some more lines" 78 | , text "Some more lines" 79 | , text "Some more lines" 80 | , text "Some more lines" 81 | ] 82 | ] -- {{POPCONTEXT}} 83 | 84 | _ -> 85 | text "Default" -- {{CURSOR}} 86 | -------------------------------------------------------------------------------- /test/lang/test.enforce: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | class Foo { // {{CONTEXT}} 3 | 4 | 5 | 6 | // {{CONTEXT}} 7 | } 8 | 9 | 10 | // {{TEST}} 11 | class Foo { // {{CONTEXT}} 12 | void Foo() { // {{CONTEXT}} 13 | 14 | 15 | 16 | // {{CURSOR}} 17 | } 18 | } 19 | 20 | // {{TEST}} 21 | class Foo { // {{CONTEXT}} 22 | void foo() { // {{CONTEXT}} 23 | if (true) { // {{CONTEXT}} 24 | switch (foo) { // {{CONTEXT}} 25 | case "foo": // {{CONTEXT}} 26 | 27 | 28 | 29 | // {{CURSOR}} 30 | break; 31 | } 32 | } 33 | } 34 | } 35 | 36 | 37 | // {{TEST}} 38 | enum Foo { // {{CONTEXT}} 39 | 40 | 41 | 42 | // {{CURSOR}} 43 | } 44 | 45 | // vim: ft=enforce 46 | -------------------------------------------------------------------------------- /test/lang/test.ex: -------------------------------------------------------------------------------- 1 | # {{TEST}} 2 | defmodule Foo do # {{CONTEXT}} 3 | @moduledoc """ {{CONTEXT}} 4 | Some really long 5 | 6 | 7 | 8 | 9 | documentation. {{CURSOR}} 10 | """ # {{POPCONTEXT}} 11 | 12 | @some_const ~w[ # {{CONTEXT}} 13 | hi 14 | i'm 15 | a 16 | big 17 | list 18 | sigil # {{CURSOR}} 19 | ] # {{POPCONTEXT}} 20 | 21 | 22 | 23 | def run(%{ # {{CONTEXT}} 24 | multi: multi, 25 | line: line, 26 | function_clause: function_clause 27 | }) do 28 | 29 | 30 | # BUG: max context lines reached 31 | case line do 32 | 33 | 34 | {:ok, foos}-> 35 | Enum.map(foos, fn 36 | {f, f2} -> 37 | 38 | 39 | 40 | String.downcase(f2) 41 | 42 | f -> 43 | 44 | 45 | 46 | 47 | 48 | String.upcase(f) 49 | 50 | end) 51 | 52 | 53 | _ -> 54 | with some_num <- Enum.random(1..100), 55 | another_num <- Enum.random(1..100) do 56 | # TODO: all of it 57 | 58 | 59 | 60 | end 61 | 62 | 63 | 64 | 65 | :ok 66 | end 67 | end 68 | 69 | def stop(params) do 70 | %{ 71 | foo: %{ 72 | "alice" => "alice", 73 | "bob" => "bob", 74 | "carol" => "carol", 75 | "dave" => "dave", 76 | 77 | 78 | 79 | "bar" => [ 80 | :bing, 81 | %{ 82 | "very deeply nested" => %{ 83 | 84 | 85 | 86 | "jk, even deeper" => %{ 87 | 88 | 89 | 90 | "one more" => %{ 91 | 92 | 93 | 94 | } 95 | } 96 | } 97 | } 98 | 99 | 100 | 101 | :bong, 102 | 103 | 104 | :bang 105 | ] 106 | } 107 | } 108 | 109 | end 110 | end 111 | -------------------------------------------------------------------------------- /test/lang/test.f90: -------------------------------------------------------------------------------- 1 | ! {{TEST}} 2 | program ! {{CONTEXT}} 3 | foo ! {{CONTEXT}} 4 | 5 | 6 | 7 | ! {{CURSOR}} 8 | type ! {{CONTEXT}} 9 | eigensys_t ! {{CONTEXT}} 10 | 11 | real(idp) :: bar1(:,:) 12 | 13 | 14 | 15 | integer :: n ! {{CURSOR}} 16 | end type eigensys_t ! {{POPCONTEXT}} 17 | ! {{POPCONTEXT}} 18 | 19 | do i = 1, ! {{CONTEXT}} 20 | eigensystem%n ! {{CONTEXT}} 21 | 22 | write(*,'(" Eigenvector ",I1,": ")') i 23 | 24 | 25 | write(*,*) eigensystem%eigen_vecs(:,i) ! {{CURSOR}} 26 | end do ! {{POPCONTEXT}} 27 | 28 | contains 29 | subroutine aaaaaaaa(foo, 30 | bar) 31 | 32 | if ( 33 | foo /= 0) then 34 | 35 | 36 | 37 | else if ( 38 | foo /= 1) then 39 | 40 | 41 | foo = foo + 1 42 | else 43 | 44 | ! BUG: cannot mark cursor here 45 | bar = 2 46 | endif 47 | end subroutine get_eigensystem 48 | 49 | end program foo 50 | -------------------------------------------------------------------------------- /test/lang/test.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | # {{TEST}} 3 | function foo # {{CONTEXT}} 4 | 5 | while true # {{CONTEXT}} 6 | 7 | 8 | 9 | 10 | echo 'foo' 11 | 12 | 13 | # {{CURSOR}} 14 | end # {{POPCONTEXT}} 15 | 16 | switch (uname) # {{CONTEXT}} 17 | case 'Linux' # {{CONTEXT}} 18 | 19 | 20 | 21 | echo 'Linux' # {{CURSOR}} 22 | # {{POPCONTEXT}} 23 | case 'Darwin' # {{CONTEXT}} 24 | echo 'Mac' 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | # {{CURSOR}} 34 | 35 | 36 | otherwise 37 | 38 | 39 | 40 | echo 'Windows' # {{CURSOR}} 41 | # {{POPCONTEXT}} 42 | end # {{POPCONTEXT}} 43 | 44 | if grep fish /etc/shells # {{CONTEXT}} 45 | 46 | 47 | 48 | echo Found fish # {{CURSOR}} 49 | else if grep bash /etc/shells # {{CONTEXT}} 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | echo Found bash # {{CURSOR}} 59 | # {{POPCONTEXT}} 60 | else # {{CONTEXT}} 61 | 62 | 63 | 64 | 65 | echo Got nothing # {{CURSOR}} 66 | end # {{POPCONTEXT}} 67 | # {{POPCONTEXT}} 68 | 69 | for file in *.txt # {{CONTEXT}} 70 | 71 | 72 | 73 | cp $file $file.bak 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | # {{CURSOR}} 85 | end 86 | end 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /test/lang/test.gd: -------------------------------------------------------------------------------- 1 | # {{TEST}} 2 | enum Test { # {{CONTEXT}} 3 | 4 | 5 | VALUE1, 6 | 7 | 8 | 9 | VALUE2, 10 | 11 | 12 | 13 | VALUE3, 14 | 15 | # {{CURSOR}} 16 | } 17 | # {{TEST}} 18 | func test_function(): # {{CONTEXT}} 19 | 20 | 21 | 22 | var test_value = Test.Value1 23 | 24 | 25 | if test_value = Test.VALUE1: # {{CONTEXT}} 26 | 27 | 28 | 29 | 30 | 31 | # {{CURSOR}} 32 | pass 33 | 34 | elif test_value = Test.VALUE2: # {{CONTEXT}} 35 | 36 | 37 | 38 | 39 | 40 | for i in 5: # {{CONTEXT}} 41 | 42 | 43 | 44 | 45 | 46 | # {{CURSOR}} 47 | pass # {{POPCONTEXT}} 48 | # {{POPCONTEXT}} 49 | else: # {{CONTEXT}} 50 | 51 | 52 | 53 | 54 | # {{CURSOR}} 55 | while true: # {{CONTEXT}} 56 | 57 | 58 | 59 | 60 | # {{CURSOR}} 61 | pass # {{POPCONTEXT}} 62 | # {{POPCONTEXT}} 63 | # {{POPCONTEXT}} 64 | match test_value: # {{CONTEXT}} 65 | Test.VALUE1: # {{CONTEXT}} 66 | 67 | 68 | 69 | 70 | 71 | 72 | print("foo") # {{CURSOR}} 73 | # {{POPCONTEXT}} 74 | Test.VALUE2: # {{CONTEXT}} 75 | 76 | 77 | 78 | 79 | print("bar") # {{CURSOR}} 80 | # {{TEST}} 81 | class HelpClass: # {{CONTEXT}} 82 | 83 | 84 | 85 | 86 | 87 | var class_variable 88 | func class_function(): # {{CONTEXT}} 89 | 90 | 91 | 92 | 93 | 94 | 95 | print("foobar") # {{CURSOR}} 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /test/lang/test.glsl: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | vec3 test(vec3 a, vec3 b) { // {{CONTEXT} 3 | 4 | // {{CURSOR}} 5 | } 6 | -------------------------------------------------------------------------------- /test/lang/test.go: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | 3 | import ( // {{CONTEXT}} 4 | "errors" 5 | 6 | 7 | "fmt" 8 | 9 | // {{CURSOR}} 10 | ) 11 | 12 | // {{TEST}} 13 | 14 | func (r *rect) area(a int, // {{CONTEXT}} 15 | b int) int { // {{CONTEXT}} 16 | return r.width * r.height 17 | 18 | 19 | 20 | // {{CURSOR}} 21 | } 22 | 23 | var b 24 | ,c 25 | ,d int = 1, 2 26 | 27 | // {{TEST}} 28 | 29 | func foo(a int, // {{CONTEXT}} 30 | b int) (int, // {{CONTEXT}} 31 | int) { // {{CONTEXT}} 32 | 33 | i := 1 34 | 35 | select { // {{CONTEXT}} 36 | case msg1 := <-c1: 37 | fmt.Println("received", msg1) 38 | case msg2 := <-c2: // {{CONTEXT}} 39 | 40 | 41 | 42 | 43 | // {{CURSOR}} 44 | fmt.Println("received", msg2) 45 | } 46 | 47 | 48 | for n := 0; 49 | n <= 5; n++ { 50 | if num := 9; 51 | num < 0 { 52 | fmt.Println(num, "is negative") 53 | 54 | 55 | 56 | 57 | 58 | } else if num < 10 { 59 | fmt.Println(num, "has 1 digit") 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | } else { 68 | fmt.Println(num, "has multiple digits") 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | } 78 | fmt.Println(n) 79 | } 80 | 81 | switch i { 82 | case 1: 83 | fmt.Println("one") 84 | case 2: 85 | fmt.Println("two") 86 | case 3: 87 | fmt.Println("three") 88 | 89 | 90 | 91 | 92 | 93 | 94 | default: 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | fmt.Println("Not valid") 106 | } 107 | } 108 | 109 | 110 | 111 | 112 | 113 | 114 | var _ = Describe("something", func() { 115 | 116 | 117 | 118 | When("it works", func() { 119 | 120 | 121 | 122 | It("works!", func() { 123 | Expect(thing).To(Work()) 124 | 125 | 126 | 127 | }) 128 | }) 129 | }) 130 | -------------------------------------------------------------------------------- /test/lang/test.graphql: -------------------------------------------------------------------------------- 1 | # {{TEST}} 2 | interface # {{CONTEXT}} 3 | Foo # {{CONTEXT}} 4 | { # {{CONTEXT}} 5 | id: ID! 6 | name: String 7 | 8 | # {{CURSOR}} 9 | } 10 | # {{TEST}} 11 | input # {{CONTEXT}} 12 | Stuff { # {{CONTEXT}} 13 | limit: Int 14 | since_id: ID 15 | 16 | 17 | # {{CURSOR}} 18 | } 19 | # {{TEST}} 20 | type Bar # {{CONTEXT}} 21 | implements Foo { # {{CONTEXT}} 22 | age: Int 23 | 24 | 25 | # {{CURSOR}} 26 | } 27 | # {{TEST}} 28 | type Mutation { # {{CONTEXT}} 29 | addBar(name: String, age: int): Bar 30 | 31 | 32 | # {{CURSOR}} 33 | } 34 | # {{TEST}} 35 | query Stuff { # {{CONTEXT}} 36 | name 37 | foo { 38 | 39 | 40 | 41 | name # {{CURSOR}} 42 | } 43 | } 44 | # {{TEST}} 45 | query GetSearchResults { # {{CONTEXT}} 46 | search(contains: "Shakespeare") { # {{CONTEXT}} 47 | __typename 48 | 49 | 50 | # {{CURSOR}} 51 | # inline fragment 52 | ... on Book { # {{CONTEXT}} 53 | title 54 | 55 | 56 | # {{CURSOR}} 57 | } # {{POPCONTEXT}} 58 | ... on Author { # {{CONTEXT}} 59 | name 60 | 61 | 62 | # {{CURSOR}} 63 | } 64 | } 65 | } 66 | # {{TEST}} 67 | mutation # {{CONTEXT}} 68 | CreateBar { # {{CONTEXT}} 69 | addBar(name: "AAAA", # {{CONTEXT}} 70 | age: 42) { # {{CONTEXT}} 71 | name 72 | foo { 73 | age 74 | 75 | 76 | # {{CURSOR}} 77 | } 78 | } 79 | } 80 | # {{TEST}} 81 | type Root { # {{CONTEXT}} 82 | name: String 83 | 84 | 85 | # {{CURSOR}} 86 | } 87 | # {{TEST}} 88 | schema { # {{CONTEXT}} 89 | query: Root 90 | 91 | 92 | # {{CURSOR}} 93 | } 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /test/lang/test.groovy: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | pipeline { // {{CONTEXT}} 3 | 4 | agent { // {{CONTEXT}} 5 | label "docker" 6 | 7 | 8 | // {{CURSOR}} 9 | } // {{POPCONTEXT}} 10 | 11 | options { // {{CONTEXT}} 12 | ansiColor('xterm') 13 | timeout(time: 60, unit: 'MINUTES') 14 | timestamps() 15 | 16 | // {{CURSOR}} 17 | } // {{POPCONTEXT}} 18 | 19 | environment { // {{CONTEXT}} 20 | 21 | // Kubernetes deploy (default) 22 | KUBERNETES_CONFIG = 'kube.yaml' 23 | KUBERNETES_ENV="test" 24 | KUBERNETES_NAMESPACE="namspace-test" 25 | 26 | // Docker 27 | HOME = "$WORKSPACE" 28 | DOCKER_WORKSPACE = "/workdir" // {{CURSOR}} 29 | 30 | GIT_COMMIT = sh( // {{CONTEXT}} 31 | script: "printf \$(git rev-parse --short HEAD)", 32 | returnStdout: true 33 | 34 | // {{CURSOR}} 35 | ) // {{POPCONTEXT}} 36 | GIT_BRANCH = sh( 37 | script: "printf \$(git rev-parse --abbrev-ref HEAD)", 38 | returnStdout: true 39 | ) 40 | 41 | GIT_TAG = sh( // {{CONTEXT}} 42 | script: "git tag --points-at ${env.GIT_COMMIT}", 43 | returnStdout: true 44 | 45 | 46 | 47 | // {{CURSOR}} 48 | 49 | 50 | 51 | 52 | 53 | 54 | )?.trim() // {{POPCONTEXT}} 55 | 56 | TAG_NAME = "${GIT_TAG}" 57 | 58 | 59 | 60 | // {{CURSOR}} 61 | 62 | 63 | 64 | } // {{POPCONTEXT}} 65 | 66 | stages { // {{CONTEXT}} 67 | 68 | stage ('Checkout') { // {{CONTEXT}} 69 | 70 | steps { // {{CONTEXT}} 71 | 72 | checkout scm 73 | sh 'git rev-parse --abbrev-ref HEAD' 74 | sh 'git rev-parse --short HEAD' 75 | sh 'echo ${GIT_COMMIT}' 76 | sh 'echo ${GIT_BRANCH}' 77 | stash name: "source" // {{CURSOR}} 78 | 79 | script { // {{CONTEXT}} 80 | env.VERSION = env.TAG_NAME // will be NULL when empty 81 | sh "echo 'Found version ${env.VERSION}'" 82 | 83 | 84 | 85 | 86 | // {{CURSOR}} 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | } // {{POPCONTEXT}} 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | // {{CURSOR}} 104 | 105 | 106 | 107 | 108 | } // steps 109 | 110 | } // Checkout 111 | 112 | } // stages 113 | 114 | } // pipeline 115 | 116 | -------------------------------------------------------------------------------- /test/lang/test.hbs: -------------------------------------------------------------------------------- 1 | {{! {{TEST}} 2 |
{{! {{CONTEXT}} 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{! {{CURSOR}} 10 |
11 | {{! {{TEST}} 12 |
{{! {{CONTEXT}} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | {{! {{CURSOR}} 43 |
    {{! {{CONTEXT}} 44 |
  • 45 |
  • {{! {{CONTEXT}} 46 | 47 | 48 | 49 | 50 | 51 | 52 | {{! {{CURSOR}} 53 | 54 |
  • {{! {{POPCONTEXT}} 55 |
  • 56 |
{{! {{POPCONTEXT}} 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | {{#if this.test}} {{! {{CONTEXT}} 65 |
{{! {{CONTEXT}} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | {{! {{CURSOR}} 89 |
{{! {{POPCONTEXT}} 90 | {{else}} 91 |
{{! {{CONTEXT}} 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | {{! {{CURSOR}} 114 | 115 |
116 | {{/if}} 117 |
118 | -------------------------------------------------------------------------------- /test/lang/test.hs: -------------------------------------------------------------------------------- 1 | -- {{TEST}} 2 | function arg1 arg2 = -- {{CONTEXT}} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -- {{CURSOR}} 18 | case (arg1, arg2) of 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -- {{CURSOR}} 32 | 33 | (Just _, Just _) -> do -- {{CONTEXT}} 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -- {{CURSOR}} 47 | 48 | 49 | undefined -- {{POPCONTEXT}} 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -- {{CURSOR}} 67 | _ -> undefined 68 | -------------------------------------------------------------------------------- /test/lang/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 |
99 | 100 | 101 | 102 | 103 | 104 |
    105 |
  • 106 |
  • 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
  • 116 |
  • 117 |
118 | 119 | 148 | 149 | -------------------------------------------------------------------------------- /test/lang/test.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # {{TEST}} 5 | [{{CONTEXT}}] 6 | # comment 7 | foo1=1 8 | foo2=2 9 | foo3=2 10 | # {{CURSOR}} 11 | foo4={{CURSOR}} 12 | 13 | [bar] 14 | bar1=1 15 | bar2=2 16 | bar3=2 17 | bar4=4 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /test/lang/test.java: -------------------------------------------------------------------------------- 1 | package mymod; 2 | 3 | import stuff1; 4 | import stuff2; 5 | 6 | @class_annot_1 // {{CONTEXT}} 7 | @class_annot_2 // {{CONTEXT}} 8 | public class MyClass { // {{CONTEXT}} 9 | 10 | 11 | 12 | // {{CURSOR}} 13 | @method_annot_1 // {{CONTEXT}} 14 | @method_annot_2 // {{CONTEXT}} 15 | public void my_method(int param) { // {{CONTEXT}} 16 | 17 | 18 | 19 | // {{CURSOR}} 20 | if (true) { // {{CONTEXT}} 21 | 22 | 23 | 24 | // {{CURSOR}} 25 | for (int i = 0; i < 10; i++) { // {{CONTEXT}} 26 | 27 | 28 | 29 | // {{CURSOR}} 30 | for (int var : iterable) { // {{CONTEXT}} 31 | 32 | 33 | 34 | // {{CURSOR}} 35 | System. // {{CONTEXT}} 36 | 37 | 38 | 39 | out.println("a message"); // {{CURSOR}} 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/lang/test.jl: -------------------------------------------------------------------------------- 1 | # {{TEST}} 2 | struct Foo{T} # {{CONTEXT}} 3 | bar::T # T can be any type 4 | baz::Int 5 | # comment 6 | # comment 7 | # comment 8 | # comment 9 | # comment 10 | # comment 11 | # comment 12 | # comment 13 | # comment 14 | # {{CURSOR}} 15 | end 16 | # {{TEST}} 17 | function myfunc( # {{CONTEXT}} 18 | x::Vector, # {{CONTEXT}} 19 | y::Int, # {{CONTEXT}} 20 | ) # {{CONTEXT}} 21 | @assert y > 0 22 | for i in 1:y # {{CONTEXT}} 23 | if i == 0 && # {{CONTEXT}} 24 | i == 0 # {{CONTEXT}} 25 | println("zero") 26 | # comment 27 | # comment 28 | # comment 29 | # comment 30 | # {{CURSOR}} 31 | elseif i == 1 32 | println("one") 33 | # comment 34 | # comment 35 | # comment 36 | # comment 37 | # {{CURSOR}} 38 | else 39 | println("other") 40 | # comment 41 | # comment 42 | # comment 43 | # comment 44 | # {{CURSOR}} 45 | end # {{POPCONTEXT}} 46 | # {{POPCONTEXT}} 47 | end # {{POPCONTEXT}} 48 | # comment 49 | # comment 50 | # comment 51 | # comment 52 | # {{CURSOR}} 53 | foo = y 54 | while foo > 0 && # {{CONTEXT}} 55 | foo > 0 # {{CONTEXT}} 56 | println(foo) 57 | foo -= 1 58 | # comment 59 | # comment 60 | # comment 61 | # comment 62 | # {{CURSOR}} 63 | end # {{POPCONTEXT}} 64 | # {{POPCONTEXT}} 65 | # comment 66 | # comment 67 | # comment 68 | # {{CURSOR}} 69 | try # {{CONTEXT}} 70 | sqrt("ten") 71 | # comment 72 | # comment 73 | # comment 74 | # comment 75 | # {{CURSOR}} 76 | catch e 77 | println(e) 78 | # comment 79 | # comment 80 | # comment 81 | # comment 82 | # {{CURSOR}} 83 | end # {{POPCONTEXT}} 84 | # comment 85 | # comment 86 | # comment 87 | # comment 88 | # {{CURSOR}} 89 | return y * x 90 | end 91 | -------------------------------------------------------------------------------- /test/lang/test.js: -------------------------------------------------------------------------------- 1 | class UserAccount { // {{CONTEXT}} 2 | name; 3 | id; 4 | 5 | 6 | 7 | // {{CURSOR}} 8 | constructor(name, id) { // {{CONTEXT}} 9 | this.name = name; 10 | this.id = id; 11 | 12 | // {{CURSOR}} 13 | for (let i = 0; i < 3; i++) { // {{CONTEXT}} 14 | console.log("hello"); 15 | 16 | 17 | // {{CURSOR}} 18 | } // {{POPCONTEXT}} 19 | 20 | 21 | 22 | // {{CURSOR}} 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/lang/test.json: -------------------------------------------------------------------------------- 1 | {"{{CONTEXT}}": 2 | 3 | 4 | 5 | "{{CURSOR}}" 6 | } 7 | -------------------------------------------------------------------------------- /test/lang/test.jsonnet: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | local content = // {{CONTEXT}} 3 | local organizer(person) = // {{CONTEXT}} 4 | if person == 'Mary' then // {{CONTEXT}} 5 | 6 | 7 | 8 | 'Mary will not be with us today, due to her health issue.' // {{CURSOR}} 9 | else 10 | std.format("Welcome %s as an honor guest for the party.", [person]); 11 | 12 | 13 | // {{POPCONTEXT}} 14 | // {{POPCONTEXT}} 15 | // {{CURSOR}} 16 | function(people) { // {{CONTEXT}} 17 | invited: [organizer(x) for x in people], 18 | participants: [ // {{CONTEXT}} 19 | std.format( // {{CONTEXT}} 20 | ||| 21 | Welcome %s to the party! 22 | They're currently working as a %s for company %s. 23 | |||, [ 24 | x.name, 25 | x.job, 26 | x.company, // {{CURSOR}} 27 | ]) // {{POPCONTEXT}} 28 | for x in [ // {{CONTEXT}} 29 | { 30 | name: 'Martin', 31 | job: 'Java Developer', 32 | company: 'A', 33 | 34 | // {{CURSOR}} 35 | }, 36 | { 37 | name: 'Robert', 38 | job: 'DevOps Engineer', 39 | company: 'B', 40 | }, 41 | ] 42 | ], 43 | }; 44 | // {{TEST}} 45 | content([ // {{CONTEXT}} 46 | 'Mary', 47 | 'Peter', 48 | 'James', 49 | 'John', 50 | 'Mathew', // {{CURSOR}} 51 | ]) 52 | -------------------------------------------------------------------------------- /test/lang/test.kdl: -------------------------------------------------------------------------------- 1 | // {{TEST}} 2 | 3 | foo { // {{CONTEXT}} 4 | bar { // {{CONTEXT}} 5 | baz { // {{CONTEXT}} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | // {{CURSOR}} 43 | } 44 | } 45 | } 46 | 47 | // {{TEST}} 48 | 49 | bar { // {{CONTEXT}} 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | // {{CURSOR}} 98 | } 99 | -------------------------------------------------------------------------------- /test/lang/test.latex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \title{Sample LaTeX Document} 3 | \author{Author Name} 4 | \date{\today} 5 | 6 | \begin{document} % {{CONTEXT}} 7 | 8 | \maketitle 9 | 10 | \section{Introduction} % BUG: should have context 11 | 12 | 13 | 14 | This is a sample section in a LaTeX document. LaTeX is a document preparation system that is widely used for scientific and technical documents. 15 | 16 | 17 | % {{CURSOR}} 18 | 19 | 20 | \end{document} 21 | 22 | -------------------------------------------------------------------------------- /test/lang/test.lua: -------------------------------------------------------------------------------- 1 | -- {{TEST}} 2 | 3 | local function foo() -- {{CONTEXT}} 4 | 5 | local function bar() -- {{CONTEXT}} 6 | 7 | 8 | 9 | -- {{CURSOR}} 10 | 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /test/lang/test.m: -------------------------------------------------------------------------------- 1 | % {{TEST}} 2 | if x < 0 && % {{CONTEXT}} 3 | y < 0 % {{CONTEXT}} 4 | 5 | 6 | 7 | y = 0; % {{CURSOR}} 8 | elseif x < 1 % {{CONTEXT}} 9 | 10 | 11 | 12 | 13 | y = x; % {{CURSOR}} 14 | % {{POPCONTEXT}} 15 | else % {{CONTEXT}} 16 | 17 | 18 | 19 | y = 1; % {{CURSOR}} 20 | end 21 | 22 | % {{TEST}} 23 | while x < 5 % {{CONTEXT}} 24 | print(x); 25 | 26 | 27 | x = x + 1; % {{CURSOR}} 28 | end % {{POPCONTEXT}} 29 | 30 | % {{TEST}} 31 | try 32 | 33 | 34 | % do something 35 | catch ME 36 | 37 | 38 | % {{CURSOR}} 39 | end 40 | 41 | % {{TEST}} 42 | switch x % {{CONTEXT}} 43 | case 1 44 | 45 | 46 | y = 1; 47 | case 2 48 | 49 | 50 | y = 2; 51 | otherwise % {{CONTEXT}} 52 | 53 | 54 | 55 | y = 0; % {{CURSOR}} 56 | % {{POPCONTEXT}} 57 | end % {{POPCONTEXT}} 58 | 59 | % {{TEST}} 60 | function [C] = myMatMult(A, % {{CONTEXT}} 61 | B) % {{CONTEXT}} 62 | [m,n] = size(A); 63 | [p,q] = size(B); 64 | if n ~= % {{CONTEXT}} 65 | p % {{CONTEXT}} 66 | error('Inner matrix dimensions must agree.'); 67 | 68 | 69 | 70 | % {{CURSOR}} 71 | end % {{POPCONTEXT}} 72 | % {{POPCONTEXT}} 73 | C = zeros(m,q); % {{CURSOR}} 74 | for i = 75 | 1:m 76 | 77 | 78 | 79 | for j = 1:q 80 | 81 | 82 | for k = 1:n 83 | C(i,j) = C(i,j) + A(i,k)*B(k,j); 84 | 85 | 86 | 87 | end 88 | end 89 | end 90 | end 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /test/lang/test.md: -------------------------------------------------------------------------------- 1 | ```html 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 44 | 45 | 46 | ``` 47 | 48 | # Title {{CONTEXT}} 49 | 50 | 51 | 52 | 53 | 54 | Test {{CURSOR}} 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /test/lang/test.ml: -------------------------------------------------------------------------------- 1 | 2 | (* {{TEST}} *) 3 | let foo_let = function (* {{CONTEXT}} *) 4 | | A -> "a" 5 | 6 | 7 | 8 | | B -> "b" 9 | 10 | 11 | 12 | | C -> "c" 13 | 14 | 15 | 16 | | D -> "d" (* {{CURSOR}} *) 17 | 18 | 19 | 20 | let bar_let c = 21 | match c with 22 | | '0' -> Stdlib.int_of_char c 23 | 24 | 25 | 26 | | 'a' -> Stdlib.int_of_char c 27 | 28 | 29 | 30 | | 'A' -> Stdlib.int_of_char c 31 | 32 | 33 | 34 | | _ -> -1 35 | 36 | 37 | let parse_int base s i = 38 | let len = String.length s in 39 | let rec next prev = 40 | let j = !i in 41 | if j >= len then prev 42 | else 43 | let c = s.[j] in 44 | let k = int_of_char c in 45 | if is_number base k then ( 46 | incr i; 47 | next ((prev * base) + k)) 48 | else prev 49 | in 50 | let i = !i in 51 | if i < len then 52 | if is_number base (int_of_char s.[i]) then next 0 else raise (bad_char i s) 53 | else raise (need_more s) 54 | 55 | module S128 : sig 56 | exception Overflow 57 | 58 | type t 59 | 60 | val shift_right : t -> int -> t 61 | val shift_left : t -> int -> t 62 | val write_octets_exn : ?off:int -> t -> bytes -> unit 63 | val succ_exn : t -> t 64 | val succ : t -> (t, [> `Msg of string ]) result 65 | val pred : t -> (t, [> `Msg of string ]) result 66 | end = struct 67 | exception Overflow 68 | 69 | type t = string 70 | 71 | let mk_zero () = Bytes.make 16 '\x00' 72 | let zero = Bytes.unsafe_to_string (mk_zero ()) 73 | let max_int = String.make 16 '\xff' 74 | let compare = String.compare 75 | let equal = String.equal 76 | 77 | let iteri_right2 f x y = 78 | for i = 15 downto 0 do 79 | let y' = Char.code (String.get y i) in 80 | f i x' y' 81 | done 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | let add_exn x y = 91 | let b = mk_zero () in 92 | let carry = ref 0 in 93 | iteri_right2 94 | (fun i x' y' -> 95 | let sum = x' + y' + !carry in 96 | if sum >= 256 then ( 97 | carry := 1; 98 | Bytes.set_uint8 b i (sum - 256)) 99 | else ( 100 | carry := 0; 101 | Bytes.set_uint8 b i sum)) 102 | x y; 103 | if !carry <> 0 then raise Overflow else Bytes.unsafe_to_string b 104 | 105 | let add x y = try Some (add_exn x y) with Overflow -> None 106 | 107 | let pred_exn x = 108 | if equal x zero then raise Overflow; 109 | let b = Bytes.of_string x in 110 | let rec go i = 111 | Bytes.set_uint8 b i (Char.code (String.get x i) - 1); 112 | if Char.code (String.get x i) = 0 then go (Stdlib.pred i) 113 | in 114 | go 15; 115 | Bytes.unsafe_to_string b 116 | 117 | 118 | 119 | 120 | 121 | module Byte = struct 122 | (* Extract the [n] least significant bits from [i] *) 123 | let get_lsbits n i = 124 | if n <= 0 || n > 8 then invalid_arg "out of bounds"; 125 | i land ((1 lsl n) - 1) 126 | 127 | (* Extract the [n] most significant bits from [i] *) 128 | let get_msbits n i = 129 | if n <= 0 || n > 8 then invalid_arg "out of bounds"; 130 | (i land (255 lsl (8 - n))) lsr (8 - n) 131 | 132 | (* Set value [x] in [i]'s [n] most significant bits *) 133 | let set_msbits n x i = 134 | if n < 0 || n > 8 then raise (Invalid_argument "n must be >= 0 && <= 8") 135 | else if n = 0 then i 136 | else if n = 8 then x 137 | else (x lsl (8 - n)) lor i 138 | 139 | (* set bits are represented as true *) 140 | let fold_left f a i = 141 | let bitmask = ref 0b1000_0000 in 142 | let a' = ref a in 143 | for _ = 0 to 7 do 144 | a' := f !a' (i land !bitmask > 0); 145 | bitmask := !bitmask lsr 1 146 | done; 147 | !a' 148 | end 149 | 150 | end 151 | 152 | let bar n = 153 | match Domain_name.count_labels n with 154 | | 6 -> ( 155 | match V4.of_domain_name n with None -> None | Some x -> Some (V4 x)) 156 | | 34 -> ( 157 | match V6.of_domain_name n with None -> None | Some x -> Some (V6 x)) 158 | | _ -> None 159 | 160 | let succ = function 161 | | V4 addr -> Result.map (fun v -> V4 v) (V4.succ addr) 162 | | V6 addr -> Result.map (fun v -> V6 v) (V6.succ addr) 163 | 164 | 165 | module Prefix = struct 166 | module Addr = struct 167 | let to_v6 = to_v6 168 | end 169 | 170 | | None -> None 171 | 172 | 173 | let foo = function 174 | | V1 p -> V1 (V1.foo.of_addr p) 175 | 176 | 177 | 178 | 179 | 180 | | V6 p -> V6 (V6.foo.of_addr p) 181 | 182 | 183 | end 184 | -------------------------------------------------------------------------------- /test/lang/test.nim: -------------------------------------------------------------------------------- 1 | const # {{CONTEXT}} 2 | 3 | 4 | 5 | C = 5 # {{CURSOR}} 6 | var 7 | 8 | 9 | 10 | v = 5 11 | let 12 | 13 | 14 | 15 | l = 5 16 | using 17 | 18 | 19 | 20 | u: int 21 | type 22 | 23 | 24 | 25 | O = object of RootObj 26 | 27 | 28 | 29 | f: int 30 | T = tuple 31 | 32 | 33 | 34 | f: int 35 | E = enum 36 | 37 | 38 | 39 | F1 40 | F2 41 | 42 | Comparable = concept x, y 43 | 44 | 45 | 46 | 47 | (x < y) is bool 48 | 49 | proc p[ 50 | T 51 | ]( 52 | a: int 53 | ): 54 | int 55 | {.nimcall.} 56 | = 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | discard 65 | 66 | func f() = 67 | 68 | 69 | 70 | 71 | discard 72 | 73 | method m(a: O) = 74 | 75 | 76 | 77 | 78 | discard 79 | 80 | iterator i(): int = 81 | 82 | 83 | 84 | 85 | discard 86 | 87 | converter c(a: int): int = 88 | 89 | 90 | 91 | 92 | discard 93 | 94 | template t() = 95 | 96 | 97 | 98 | 99 | discard 100 | 101 | macro ma(body: untyped) = 102 | 103 | 104 | 105 | 106 | discard 107 | 108 | let pe = proc (): int = 109 | 110 | 111 | 112 | 113 | discard 114 | 115 | let fe = func (): int = 116 | 117 | 118 | 119 | 120 | discard 121 | 122 | let ie = iterator (): int = 123 | 124 | 125 | 126 | 127 | discard 128 | 129 | import std/algorithm 130 | var array1 = [3,2,1] 131 | sort(array1) do (x, y: int) -> int: 132 | 133 | 134 | 135 | 136 | 1 137 | 138 | ma: 139 | 140 | 141 | ma: 142 | 143 | 144 | ma: 145 | 146 | 147 | ma: 148 | 149 | 150 | ma: 151 | 152 | 153 | discard 154 | 155 | 156 | # Foot of Mount Doom 157 | for x in 158 | [0,1,2]: 159 | 160 | 161 | 162 | while 163 | true: 164 | 165 | 166 | 167 | block label: 168 | 169 | 170 | 171 | static: 172 | 173 | 174 | 175 | try: 176 | 177 | 178 | 179 | discard 180 | 181 | except 182 | ValueError as e: 183 | 184 | 185 | 186 | 187 | 188 | 189 | discard 190 | 191 | finally: 192 | 193 | 194 | 195 | if 196 | true: 197 | 198 | 199 | 200 | 201 | discard 202 | 203 | elif 204 | true: 205 | 206 | 207 | 208 | discard 209 | 210 | else: 211 | 212 | when 213 | true: 214 | 215 | 216 | 217 | 218 | discard 219 | 220 | elif 221 | true: 222 | 223 | 224 | 225 | 226 | discard 227 | 228 | else: 229 | let en = E.F2 230 | case en: 231 | of 232 | F1: 233 | 234 | 235 | 236 | discard 237 | 238 | elif 239 | true: 240 | 241 | 242 | 243 | discard 244 | 245 | else: 246 | 247 | 248 | 249 | 250 | {.warning.}: 251 | 252 | 253 | 254 | 255 | echo "You have climbed Mount Doom!" 256 | 257 | -------------------------------------------------------------------------------- /test/lang/test.nix: -------------------------------------------------------------------------------- 1 | 2 | { 3 | output = # {{CONTEXT}} 4 | # {{CONTEXT}} 5 | # {{CONTEXT}} 6 | # {{CONTEXT}} 7 | # {{CONTEXT}} 8 | # {{CONTEXT}} 9 | # {{CONTEXT}} 10 | # {{CONTEXT}} 11 | # {{CONTEXT}} 12 | # {{CONTEXT}} 13 | let # {{CONTEXT}} 14 | l = { # {{CONTEXT}} 15 | a = false; 16 | b = false; 17 | c = false; 18 | 19 | # {{CURSOR}} 20 | }; #Succe 21 | m = { 22 | a = false; 23 | b = true; 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | c = false; 34 | }; #Success 35 | n = { 36 | a = false; 37 | b = true; 38 | c = true; 39 | }; #Fail 40 | 41 | functions = { 42 | check = pkgs: 43 | list: 44 | let 45 | length = 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | builtins.length (pkgs.lib.remove false list); 55 | 56 | 57 | 58 | otherfunc = { a, b, c, ... }@nice: a + b + c; 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | setFunc = 67 | { a 68 | , b 69 | , c 70 | , ... 71 | }@extras: ( 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | a * b * c 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | ); 91 | in 92 | (length == 0) || (length == 1); 93 | }; 94 | in 95 | functions.check l; 96 | } 97 | -------------------------------------------------------------------------------- /test/lang/test.norg: -------------------------------------------------------------------------------- 1 | * a heading {{CONTEXT}} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {{CURSOR}} 12 | ** a subheading {{CONTEXT}} 13 | 14 | 15 | 16 | {{CURSOR}} 17 | 18 | 19 | 20 | 21 | 22 | 23 | * another heading 24 | 25 | 26 | 27 | 28 | ** a subheading 29 | 30 | 31 | 32 | 33 | 34 | 35 | *** a subsubheading 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /test/lang/test.nu: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env nu 2 | 3 | def foo [] { # {{CONTEXT}} 4 | 5 | 6 | 7 | # {{CURSOR}} 8 | } 9 | 10 | module bar { 11 | # comment 12 | } 13 | 14 | export-env { 15 | # comment 16 | } 17 | 18 | if true { 19 | # comment 20 | } 21 | 22 | try { 23 | # comment 24 | } catch { 25 | } 26 | 27 | match "A" { 28 | # comment 29 | "A" => "B" 30 | } 31 | 32 | for x in 0..10 { 33 | # comment 34 | } 35 | 36 | while true { 37 | # comment 38 | } 39 | 40 | do {|| 41 | print "foo" 42 | # comment 43 | } 44 | 45 | let foo = ( 46 | ls 47 | | # context 48 | get name 49 | | # context 50 | first 51 | ) 52 | -------------------------------------------------------------------------------- /test/lang/test.objdump: -------------------------------------------------------------------------------- 1 | 0000000000000012 (File Offset: 0x82): 2 | _ZN6engine5world5World10initializeEv(): 3 | /home/selecaoone/repositories/jumpy/engine/src/lib/world.cpp:22 4 | 5 | 12: 55 push rbp 6 | 13: 53 push rbx 7 | 14: 48 83 ec 08 sub rsp,0x8 {{CURSOR}} 8 | _ZN9__gnu_cxx17__normal_iteratorIPSt10unique_ptrIN6engine7systems6SystemESt14default_deleteIS4_EESt6vectorIS7_SaIS7_EEEC4ERKS8_(): 9 | /opt/rh/devtoolset-9/root/usr/include/c++/9/bits/stl_iterator.h:807 10 | 18: 48 8b 5f 60 mov rbx,QWORD PTR [rdi+0x60] 11 | 1c: 48 8b 6f 68 mov rbp,QWORD PTR [rdi+0x68] 12 | _ZN6engine5world5World10initializeEv(): 13 | /home/selecaoone/repositories/jumpy/engine/src/lib/world.cpp:23 14 | 20: 48 39 eb cmp rbx,rbp 15 | 23: 74 12 je 37 (File Offset: 0xa7) 16 | _ZNKSt15__uniq_ptr_implIN6engine7systems6SystemESt14default_deleteIS2_EE6_M_ptrEv(): 17 | /opt/rh/devtoolset-9/root/usr/include/c++/9/bits/unique_ptr.h:154 18 | 25: 48 8b 3b mov rdi,QWORD PTR [rbx] 19 | _ZN6engine5world5World10initializeEv(): 20 | /home/selecaoone/repositories/jumpy/engine/src/lib/world.cpp:25 21 | 28: 48 8b 07 mov rax,QWORD PTR [rdi] 22 | 2b: ff 50 10 call QWORD PTR [rax+0x10] 23 | -------------------------------------------------------------------------------- /test/lang/test.odin: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "core:fmt" 4 | 5 | // {{TEST}} 6 | demo_struct :: struct($T: typeid) { // {{CONTEXT}} 7 | name: string, 8 | payload: T, 9 | // comment 10 | // comment 11 | // comment 12 | // comment 13 | // comment 14 | // comment 15 | // comment 16 | // comment 17 | // comment 18 | // comment 19 | // comment 20 | // comment 21 | // {{CURSOR}} 22 | 23 | } 24 | 25 | 26 | main :: proc() { 27 | 28 | a := 1 29 | 30 | if a > 0 { 31 | a = do_stuff(a) 32 | 33 | } 34 | 35 | 36 | //comment 37 | //comment 38 | //comment 39 | //comment 40 | //comment 41 | //comment 42 | //comment 43 | //commen 44 | for x:=0; x<100; x+=1 { 45 | //comment 46 | //comment 47 | //comment 48 | //comment 49 | //comment 50 | //comment 51 | //comment 52 | //comment 53 | fmt.printf("{0}\n", x) 54 | } 55 | //comment 56 | fmt.printf("{0}\n", a) 57 | } 58 | 59 | do_stuff :: proc(x: int) -> int { 60 | switch x { 61 | case 1: 62 | return 42 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | case 0: 75 | return 420 76 | } 77 | return 0 78 | } 79 | -------------------------------------------------------------------------------- /test/lang/test.org: -------------------------------------------------------------------------------- 1 | * a heading 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ** a subheading 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | * another heading 25 | 26 | 27 | 28 | 29 | ** a subheading 30 | 31 | 32 | 33 | 34 | 35 | 36 | *** a subsubheading 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /test/lang/test.php: -------------------------------------------------------------------------------- 1 | $key) { 26 | // comment 27 | do { 28 | // comment 29 | echo "The number is: $x
"; 30 | $x++; 31 | 32 | 33 | 34 | 35 | } while ($x <= 5); 36 | 37 | for ($x = 0; $x <= 10; $x++) { 38 | echo "The number is: $x
"; 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | } 51 | 52 | 53 | 54 | foreach ($colors as $value) { 55 | echo "$value
"; 56 | 57 | 58 | 59 | 60 | 61 | 62 | } 63 | 64 | $high = $index - 1; 65 | } 66 | } 67 | 68 | 69 | 70 | //when key not found in array or array not sorted 71 | return null; 72 | } 73 | 74 | #[Attribute] 75 | class Fruit { 76 | 77 | 78 | 79 | 80 | #[ReturnTypeWillChange] 81 | public function rot(): void 82 | { 83 | 84 | 85 | return; 86 | } 87 | 88 | 89 | 90 | // comment 91 | 92 | 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /test/lang/test.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "postgresql" 3 | // foo 4 | 5 | 6 | 7 | url = env("DATABASE_URL") 8 | } 9 | 10 | generator 11 | client { 12 | provider = "prisma-client-js" 13 | 14 | 15 | } 16 | 17 | enum // {{CONTEXT}} 18 | Role { // {{CONTEXT}} 19 | 20 | USER 21 | 22 | ADMIN 23 | 24 | // {{CURSOR}} 25 | } 26 | 27 | 28 | model 29 | User { 30 | 31 | 32 | 33 | id Int @id @default(autoincrement()) 34 | email String @unique 35 | 36 | 37 | 38 | name String? 39 | posts Post[] 40 | 41 | 42 | 43 | } 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /test/lang/test.proto: -------------------------------------------------------------------------------- 1 | 2 | syntax = "proto2" 3 | 4 | package test; 5 | 6 | // {{TEST}} 7 | enum SomeEnum { // {{CONTEXT}} 8 | UNDEFINED = 0; 9 | 10 | FIRST = 1; 11 | 12 | SECOND = 2; 13 | 14 | THIRD = 3; 15 | 16 | FORTH = 4; 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | FIFTH = 5; 34 | 35 | SIXTH = 6; 36 | 37 | SEVENTH = 7; 38 | 39 | EIGHTH = 8; 40 | 41 | NINTH = 9; 42 | // {{CURSOR}} 43 | } 44 | 45 | 46 | 47 | // {{TEST}} 48 | message SomeMessage { // {{CONTEXT}} 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | optional SomeEnum someEnum = 1; 60 | 61 | optional string name = 2; 62 | 63 | optional int32 id = 3; 64 | 65 | optional int32 age = 4; 66 | 67 | optional bool isMale = 5; 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | optional int32 height = 6; 80 | 81 | optional int32 weight = 7; 82 | 83 | optional int32 score = 8; 84 | 85 | optional int32 level = 9; 86 | 87 | 88 | 89 | 90 | // {{CURSOR}} 91 | } 92 | 93 | 94 | 95 | // {{TEST}} 96 | service SomeService { // {{CONTEXT}} 97 | 98 | rpc SomeMethod(SomeMessage) returns (SomeMessage); 99 | 100 | rpc AnotherMethod(SomeMessage) returns (SomeMessage); 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | rpc GetRandomUser(SomeMessage) returns (SomeMessage); 113 | 114 | rpc GenerateRandomData(SomeMessage) returns (SomeMessage); 115 | 116 | rpc FetchRandomStats(SomeMessage) returns (SomeMessage); 117 | 118 | rpc CreateRandomProfile(SomeMessage) returns (SomeMessage); 119 | 120 | rpc ComputeRandomMetrics(SomeMessage) returns (SomeMessage); 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | // {{CURSOR}} 133 | } 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | // {{TEST}} 146 | message SomeMessage { // {{CONTEXT}} 147 | oneof someOneof { // {{CONTEXT}} 148 | SomeEnum someEnum = 1; 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | // {{CURSOR}} 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /test/lang/test.py: -------------------------------------------------------------------------------- 1 | def hello(name: str, age: int) -> None: # {{CONTEXT}} 2 | print(f"Hello {name}! You are {age} years old.") 3 | 4 | 5 | 6 | # {{CURSOR}} 7 | -------------------------------------------------------------------------------- /test/lang/test.r: -------------------------------------------------------------------------------- 1 | # (for) 2 | for (x in 1:10) { # {{CONTEXT}} 3 | 4 | 5 | 6 | 7 | 8 | print(x) # {{CURSOR}} 9 | } 10 | 11 | # (while) 12 | i <- 1 13 | while (i < 6) { 14 | 15 | 16 | 17 | 18 | 19 | 20 | print(i) 21 | i <- i + 1 22 | } 23 | 24 | # (if) 25 | if (b > a) { 26 | 27 | 28 | 29 | 30 | 31 | print("b is greater than a") 32 | } else if (a == b) { 33 | 34 | 35 | 36 | 37 | print("a and b are equal") 38 | } else { 39 | 40 | 41 | 42 | 43 | 44 | print("a is greater than b") 45 | } 46 | 47 | # (left_assignment) 48 | left_assign <- list("a", 49 | 50 | 51 | 52 | 53 | 54 | "b") 55 | 56 | # (equals_assignment) 57 | equals_assign = list("a", 58 | 59 | 60 | 61 | 62 | 63 | "b") 64 | 65 | 66 | # (super_assignment) 67 | super_assign <<- list("a", 68 | 69 | 70 | 71 | 72 | 73 | "b") 74 | 75 | # (binary) 76 | mtcars %>% 77 | 78 | 79 | 80 | 81 | mt 82 | 83 | # (call) 84 | library( 85 | 86 | 87 | 88 | 89 | 90 | 91 | ggplot2) 92 | 93 | # (function_definition) 94 | 95 | function(foo, bar) { 96 | 97 | 98 | 99 | 100 | 101 | 102 | print(foo) 103 | print(bar) 104 | } 105 | -------------------------------------------------------------------------------- /test/lang/test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Bar # BUG: The contexts here include too many newlines 4 | class Foo 5 | class << self 6 | def run 7 | 8 | 9 | 10 | 11 | if false 12 | (20..30).each do |element| 13 | block.call(element) 14 | end 15 | else 16 | 1 + 1 17 | end 18 | end 19 | end 20 | 21 | def self.other_method 22 | unless false 23 | (10..20).each do |element| 24 | block.call(element) 25 | end 26 | else 27 | 1 + 1 28 | end 29 | end 30 | 31 | def run(&block) 32 | unless false 33 | (1..10).each do |element| 34 | block.call(element) 35 | end 36 | else 37 | 1 + 1 38 | end 39 | end 40 | end 41 | end 42 | 43 | RSpec.describe 'foo' do # {{CONTEXT}} 44 | context 'bar' do # {{CONTEXT}} 45 | shared_context 'shared context' do # {{CONTEXT}} 46 | it 'test' do # {{CONTEXT}} 47 | 48 | 49 | 50 | 51 | expect(1).to eq(1) # {{CURSOR}} 52 | end 53 | end 54 | 55 | shared_examples 'shared examples' do 56 | it 'test' do 57 | expect(1).to eq(1) 58 | end 59 | end 60 | 61 | context 'xpto' do 62 | context 'other' do 63 | it 'test' do 64 | expect(1).to eq(1) 65 | end 66 | 67 | it_behaves_like 'shared examples' do 68 | let(:one) { 1 } 69 | end 70 | 71 | include_context 'shared examples' do 72 | let(:one) { 1 } 73 | end 74 | 75 | include_examples 'shared examples' do 76 | let(:one) { 1 } 77 | end 78 | end 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /test/lang/test.rs: -------------------------------------------------------------------------------- 1 | impl Foo { // {{CONTEXT}} 2 | 3 | 4 | 5 | // {{CURSOR}} 6 | fn bar(&self) { 7 | 8 | 9 | 10 | 11 | 12 | if condition { 13 | 14 | 15 | 16 | 17 | 18 | 19 | for i in 0..100 { 20 | 21 | 22 | 23 | 24 | 25 | 26 | foo(async move { 27 | 28 | 29 | 30 | 31 | 32 | 33 | // comment 34 | 35 | 36 | 37 | 38 | 39 | 40 | }) 41 | } 42 | } 43 | 44 | 45 | 46 | 47 | 48 | try { 49 | 50 | 51 | 52 | 53 | 54 | 55 | let Foo::Bar { 56 | texts, 57 | values, 58 | } = foo().bar() else { 59 | 60 | 61 | 62 | 63 | 64 | let a = if b { 65 | 66 | 67 | 68 | 69 | 70 | // comment 71 | 72 | 73 | 74 | 75 | 76 | } else { 77 | 78 | 79 | 80 | 81 | // comment 82 | 83 | 84 | 85 | 86 | }; 87 | } 88 | } 89 | 90 | 91 | 92 | 93 | short_call_site(a, b); 94 | 95 | long_call_site( 96 | a, 97 | 98 | b, 99 | 100 | c, 101 | 102 | d, 103 | 104 | e, 105 | ); 106 | 107 | 108 | 109 | 110 | macro_rules! x { 111 | 112 | 113 | // comment 114 | () => {}; 115 | 116 | 117 | } 118 | 119 | 120 | 121 | 122 | x! { 123 | 124 | 125 | 126 | // comment 127 | 128 | 129 | 130 | } 131 | 132 | 133 | 134 | unsafe { 135 | 136 | 137 | *0 // run 138 | 139 | 140 | } 141 | 142 | 143 | 144 | 145 | let short_array = []; 146 | 147 | let long_array = [ 148 | 1, 149 | 150 | 2, 151 | 152 | 3, 153 | 154 | 4, 155 | ]; 156 | 157 | let (short, tuple) = (1, 2); 158 | 159 | let ( 160 | a, 161 | 162 | rather, 163 | 164 | long, 165 | 166 | tuple, 167 | ) = ( 168 | 1, 169 | 170 | 2, 171 | 172 | 3, 173 | 174 | 4, 175 | ); 176 | } 177 | 178 | let s = BigStruct { 179 | 180 | a, 181 | 182 | b, 183 | 184 | c, 185 | 186 | d, 187 | }; 188 | } 189 | 190 | pub extern "C" { 191 | 192 | 193 | 194 | pub fn foobar(_: *u8); 195 | 196 | 197 | 198 | } 199 | 200 | struct Foo { 201 | 202 | active: bool, 203 | 204 | username: String, 205 | 206 | email: String, 207 | 208 | sign_in_count: u64, 209 | 210 | } 211 | 212 | union Bar { 213 | 214 | a: u8, 215 | 216 | b: u16, 217 | 218 | c: u32, 219 | 220 | } 221 | -------------------------------------------------------------------------------- /test/lang/test.scala: -------------------------------------------------------------------------------- 1 | class Test { // {{CONTEXT}} 2 | def hello(name: String, age: Int): Unit = { // {{CONTEXT}} 3 | println(s"Hello $name! You are $age years old.") 4 | 5 | 6 | 7 | // {{CURSOR}} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/lang/test.scss: -------------------------------------------------------------------------------- 1 | $sizes: 40px, 50px, 80px; 2 | 3 | .foo-container { // {{CONTEXT}} 4 | .foo-item { // {{CONTEXT}} 5 | color: red; 6 | 7 | 8 | 9 | 10 | // {{CURSOR}} 11 | } 12 | .foo-image { 13 | width: 100%; 14 | height: 100%; 15 | 16 | 17 | 18 | 19 | 20 | 21 | } 22 | } 23 | 24 | @each $size in $sizes { 25 | } 26 | 27 | @each $size in $sizes { 28 | .foo-#{$size} { 29 | 30 | 31 | 32 | 33 | width: $size; 34 | 35 | 36 | 37 | 38 | 39 | height: $size; 40 | } 41 | } 42 | 43 | @for $i from 1 through 3 { 44 | 45 | 46 | 47 | 48 | 49 | // only works if something is here 50 | 51 | 52 | } 53 | 54 | @while $i < 10 { 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | // comment 63 | 64 | 65 | 66 | } 67 | 68 | @keyframes FooKeyframes { 69 | 0% { 70 | 71 | 72 | 73 | 74 | 75 | 76 | transform: rotateX(60deg) rotateZ(-45deg) scale(1); 77 | filter: blur(5px); 78 | } 79 | 80 | 50% { 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | transform: rotateX(60deg) rotateZ(-225deg) scale(1.1); 89 | filter: blur(15px); 90 | } 91 | 92 | 100% { 93 | transform: rotateX(60deg) rotateZ(-405deg) scale(1); 94 | filter: blur(5px); 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | } 103 | } 104 | 105 | @media (prefers-reduced-motion: reduce) { 106 | 107 | 108 | 109 | *, 110 | *::before, 111 | *::after { 112 | animation-duration: 0.01ms !important; 113 | animation-iteration-count: 1 !important; 114 | transition-duration: 0.01ms !important; 115 | scroll-behavior: auto !important; 116 | } 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | } 131 | 132 | @mixin FooMixin($a, 133 | $b) { 134 | 135 | @if $a > $b { 136 | color: red; 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | } @else if $a < $b { 147 | color: blue; 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | } @else { 156 | 157 | 158 | 159 | 160 | color: green; 161 | 162 | 163 | 164 | 165 | 166 | } 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | } 182 | 183 | 184 | 185 | @function add($a, 186 | $b) { 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | @return $a + $b; 195 | 196 | 197 | 198 | 199 | 200 | 201 | } 202 | 203 | @at-root { 204 | 205 | 206 | 207 | 208 | 209 | color: red; 210 | 211 | 212 | 213 | 214 | } 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /test/lang/test.smali: -------------------------------------------------------------------------------- 1 | .class public Lbaksmali/test/class; # BUG: The contexts here are extremely buggy and include too many newlines 2 | .super Ljava/lang/Object; 3 | 4 | .source "baksmali_test_class.smali" 5 | 6 | .implements Lsome/interface; 7 | .implements Lsome/other/interface; 8 | 9 | 10 | .annotation build Lsome/annotation; 11 | value1 = "test" 12 | value2 = .subannotation Lsome/annotation; 13 | value1 = "test2" 14 | value2 = Lsome/enum; 15 | .end subannotation 16 | .end annotation 17 | 18 | .annotation system Lsome/annotation; 19 | .end annotation 20 | 21 | 22 | 23 | .field public static aStaticFieldWithoutAnInitializer:I 24 | 25 | .field public static longStaticField:J = 0x300000000L 26 | .field public static longNegStaticField:J = -0x300000000L 27 | 28 | .field public static intStaticField:I = 0x70000000 29 | .field public static intNegStaticField:I = -500 30 | 31 | .field public static shortStaticField:S = 500s 32 | .field public static shortNegStaticField:S = -500s 33 | 34 | .field public static byteStaticField:B = 123t 35 | .field public static byteNegStaticField:B = 0xAAt 36 | 37 | .field public static floatStaticField:F = 3.1415926f 38 | 39 | .field public static doubleStaticField:D = 3.141592653589793 40 | 41 | .field public static charStaticField:C = 'a' 42 | .field public static charEscapedStaticField:C = '\n' 43 | 44 | .field public static boolTrueStaticField:Z = true 45 | .field public static boolFalseStaticField:Z = false 46 | 47 | .field public static typeStaticField:Ljava/lang/Class; = Lbaksmali/test/class; 48 | 49 | .field public static stringStaticField:Ljava/lang/String; = "test" 50 | .field public static stringEscapedStaticField:Ljava/lang/String; = "test\ntest" 51 | 52 | 53 | .field public static fieldStaticField:Ljava/lang/reflect/Field; = Lbaksmali/test/class;->fieldStaticField:Ljava/lang/reflect/Field; 54 | 55 | .field public static methodStaticField:Ljava/lang/reflect/Method; = Lbaksmali/test/class;->testMethod(ILjava/lang/String;)Ljava/lang/String; 56 | 57 | .field public static arrayStaticField:[I = {1, 2, 3, {1, 2, 3, 4}} 58 | 59 | .field public static enumStaticField:Lsome/enum; = .enum Lsome/enum;->someEnumValue:Lsome/enum; 60 | 61 | .field public static annotationStaticField:Lsome/annotation; = .subannotation Lsome/annotation; 62 | value1 = "test" 63 | value2 = .subannotation Lsome/annotation; 64 | value1 = "test2" 65 | value2 = Lsome/enum; 66 | .end subannotation 67 | .end subannotation 68 | 69 | .field public static staticFieldWithAnnotation:I 70 | .annotation runtime La/field/annotation; 71 | this = "is" 72 | a = "test" 73 | .end annotation 74 | .annotation runtime Lorg/junit/Test; 75 | .end annotation 76 | .end field 77 | 78 | .field public instanceField:Ljava/lang/String; 79 | 80 | 81 | 82 | .method public constructor ()V 83 | .registers 1 84 | invoke-direct {p0}, Ljava/lang/Object;->()V 85 | return-void 86 | .end method 87 | 88 | .method public testMethod(ILjava/lang/String;)Ljava/lang/String; 89 | .registers 3 90 | .annotation runtime Lorg/junit/Test; 91 | .end annotation 92 | .annotation system Lyet/another/annotation; 93 | somevalue = 1234 94 | anothervalue = 3.14159 95 | .end annotation 96 | 97 | const-string v0, "testing\n123" 98 | 99 | goto switch: 100 | 101 | sget v0, Lbaksmali/test/class;->staticField:I 102 | 103 | switch: 104 | packed-switch v0, pswitch: 105 | 106 | try_start: 107 | const/4 v0, 7 108 | const v0, 10 109 | nop 110 | try_end: 111 | .catch Ljava/lang/Exception; {try_start: .. try_end:} handler: 112 | .catchall {try_start: .. try_end:} handler2: 113 | 114 | handler: 115 | 116 | Label10: 117 | Label11: 118 | Label12: 119 | Label13: 120 | return-object v0 121 | 122 | 123 | 124 | .array-data 4 125 | 1 2 3 4 5 6 200 126 | .end array-data 127 | 128 | pswitch: 129 | .packed-switch 10 130 | Label10: 131 | Label11: 132 | Label12: 133 | Label13: 134 | .end packed-switch 135 | 136 | handler2: 137 | 138 | return-void 139 | .end method 140 | 141 | .method public abstract testMethod2()V 142 | .annotation runtime Lsome/annotation; 143 | subannotation = .subannotation Lsome/other/annotation; 144 | value = "value" 145 | .end subannotation 146 | .end annotation 147 | .annotation runtime Lorg/junit/Test; 148 | .end annotation 149 | .end method 150 | 151 | 152 | .method public tryTest()V 153 | .registers 1 154 | 155 | handler: 156 | nop 157 | 158 | 159 | try_start: 160 | const/4 v0, 7 161 | const v0, 10 162 | nop 163 | try_end: 164 | .catch Ljava/lang/Exception; {try_start: .. try_end:} handler: 165 | .end method 166 | 167 | 168 | .method public debugTest(IIIII)V 169 | .registers 10 170 | 171 | .parameter "Blah" 172 | .parameter 173 | .parameter "BlahWithAnnotations" 174 | .annotation runtime Lsome/annotation; 175 | something = "some value" 176 | somethingelse = 1234 177 | .end annotation 178 | .annotation runtime La/second/annotation; 179 | .end annotation 180 | .end parameter 181 | .parameter 182 | .annotation runtime Lsome/annotation; 183 | something = "some value" 184 | somethingelse = 1234 185 | .end annotation 186 | .end parameter 187 | .parameter "LastParam" 188 | 189 | .prologue 190 | 191 | nop 192 | nop 193 | 194 | .source "somefile.java" 195 | .line 101 196 | 197 | nop 198 | 199 | 200 | .line 50 201 | 202 | .local v0, aNumber:I 203 | const v0, 1234 204 | .end local v0 205 | 206 | .source "someotherfile.java" 207 | .line 900 208 | 209 | const-string v0, "1234" 210 | 211 | .restart local v0 212 | const v0, 6789 213 | .end local v0 214 | 215 | .epilogue 216 | 217 | .end method 218 | -------------------------------------------------------------------------------- /test/lang/test.sol: -------------------------------------------------------------------------------- 1 | interface SomeInterface { // {{CONTEXT}} 2 | function someFunction(uint a, uint b) external returns (uint c); 3 | function testFunction(uint) external returns (uint); 4 | 5 | 6 | // {{CURSOR}} 7 | } 8 | 9 | contract Contract { 10 | event SomeEvent( 11 | uint a, 12 | uint b, 13 | uint c, 14 | uint d 15 | ); 16 | 17 | error SomeError( 18 | uint a, 19 | uint b, 20 | uint c, 21 | uint d 22 | ); 23 | 24 | struct SomeStruct { 25 | uint a; 26 | uint b; 27 | uint c; 28 | uint d; 29 | } 30 | 31 | enum SomeEnum { 32 | Entry1, 33 | Entry2, 34 | Entry3, 35 | Entry4 36 | } 37 | 38 | constructor() { 39 | // do some construction 40 | } 41 | 42 | fallback() external payable { 43 | // this is 44 | // fallback 45 | } 46 | 47 | receive() external payable { 48 | // this is 49 | // receive 50 | // function 51 | } 52 | 53 | function someFunction(uint a, uint b) external pure returns (uint _c) { 54 | _c = a + b; 55 | 56 | if (true) { 57 | // do 58 | // something 59 | // in if statement 60 | emit SomeEvent(1, 2, 61 | 3, 4); 62 | } else { 63 | // do 64 | // something 65 | // in else statement 66 | 67 | revert SomeError( 68 | 1, 69 | 2, 70 | 3, 4 71 | ); 72 | } 73 | 74 | for (uint i = 0; i < 10; i++) { 75 | // something 76 | // in loop 77 | 78 | uint j = 0; 79 | while (j < 5) { 80 | j++; 81 | // something 82 | // something 83 | 84 | try { 85 | // will error 86 | // need to catch 87 | } catch (bytes memory reason) { 88 | // catch 89 | // do some cleanup 90 | } 91 | } 92 | 93 | do { 94 | // this is do 95 | // while 96 | 97 | unchecked { 98 | j++; 99 | } 100 | } while (j < 5); 101 | } 102 | } 103 | 104 | modifier withSomething(uint a) { 105 | // modifier logic 106 | _; 107 | } 108 | } 109 | 110 | library SomeLibrary { 111 | function libraryFunction(uint a, uint b, uint c, uint d) internal pure { 112 | a = 1; 113 | b = 2; 114 | c = 3; 115 | d = 4; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /test/lang/test.svelte: -------------------------------------------------------------------------------- 1 | 28 | 29 |
30 | 31 |
    32 | {#each items(10) as item} 33 |
  • 34 | {#key item} 35 | {item} 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {/key} 46 |
  • 47 | 48 | {/each} 49 | 50 | 51 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {#if x > 10} 63 | 64 | 65 | 66 | 67 |

{x} is greater than 10

68 | 69 | 70 | 71 | 72 | 73 | {:else if 5 > x} 74 | 75 | 76 | 77 | 78 |

{x} is less than 5

79 | 80 | 81 | 82 | 83 | {:else} 84 | 85 | 86 | 87 | 88 | 89 |

{x} is between 5 and 10

90 | 91 | 92 | 93 | 94 | 95 | 96 | {/if} 97 | 98 | 99 |
100 | -------------------------------------------------------------------------------- /test/lang/test.swift: -------------------------------------------------------------------------------- 1 | let i = 0; 2 | let k = 0; 3 | let l = 0; 4 | var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 5 | 6 | switch i { // {{CONTEXT}} 7 | 8 | case let x // {{CONTEXT}} 9 | where x > 0: // {{CONTEXT}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | print("i is greater than 0") // {{CURSOR}} 18 | default: 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | print("i is not 0") 27 | } 28 | 29 | if (i > 0) { 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | print("i is greater than 0") 42 | } else if (i < 0 && 43 | k < 0 && 44 | l > 0) { 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | print("i is less than 0") 59 | } else { 60 | 61 | 62 | 63 | 64 | 65 | } 66 | 67 | // for with multiple incrementors 68 | for (j, 69 | k 70 | ) in zip(rx, 71 | ry) 72 | { 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | println(j, k) 84 | } 85 | 86 | foo: for i in list { 87 | print(i) 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | } 98 | 99 | 100 | 101 | while ( 102 | i < 10 103 | && k < 2 104 | ) { 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | print(i) 117 | } 118 | 119 | repeat { 120 | 121 | 122 | 123 | 124 | 125 | defer { 126 | print(score) 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | } 136 | 137 | 138 | 139 | } while (i < 10) 140 | 141 | func greet(person: String, 142 | person2: String, 143 | person3: String) -> String { 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | let greeting = "Hello, " + person + "!" 152 | return greeting 153 | 154 | 155 | } 156 | 157 | protocol CornersRoundable { 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | func roundCorners() 166 | } 167 | 168 | func vend(itemNamed name: String) throws { 169 | guard let item = inventory[name] 170 | else { 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | throw VendingMachineError.invalidSelection 187 | } 188 | 189 | 190 | guard item.count > 0 else { 191 | throw VendingMachineError.outOfStock 192 | } 193 | } 194 | 195 | 196 | do { 197 | try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine) 198 | print("Success! Yum.") 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | } catch VendingMachineError.insufficientFunds(let coinsNeeded, 213 | let coinsDeposited) { 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.") 229 | } catch { 230 | print("Unexpected error: \(error).") 231 | } 232 | 233 | 234 | // enum is also class 235 | class SomeClass: SomeSuperclass, 236 | FirstProtocol, 237 | AnotherProtocol { 238 | 239 | 240 | 241 | 242 | 243 | // comment 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | } 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /test/lang/test.tact: -------------------------------------------------------------------------------- 1 | // vim: ft=tact 2 | struct S { // {{CONTEXT}} 3 | 4 | 5 | 6 | 7 | // {{CURSOR}} 8 | } 9 | 10 | message M { 11 | 12 | 13 | 14 | 15 | // comment 16 | } 17 | 18 | trait C { 19 | 20 | 21 | 22 | 23 | // comment 24 | } 25 | 26 | contract C { 27 | init() { 28 | 29 | 30 | 31 | 32 | // comment 33 | } 34 | 35 | receive() { 36 | 37 | 38 | 39 | 40 | // comment 41 | } 42 | 43 | external() { 44 | 45 | 46 | 47 | 48 | // comment 49 | } 50 | 51 | bounced(msg: bounced) { 52 | 53 | 54 | 55 | 56 | // comment 57 | } 58 | 59 | fun someFunction() { 60 | 61 | 62 | 63 | 64 | // comment 65 | } 66 | } 67 | 68 | fun statements() { 69 | let a: map = null; 70 | 71 | if (true) { 72 | 73 | 74 | 75 | 76 | // comment 77 | } else { 78 | 79 | 80 | 81 | 82 | // comment 83 | } 84 | 85 | try { 86 | 87 | 88 | 89 | 90 | // comment 91 | } catch (e) { 92 | 93 | 94 | 95 | 96 | // comment 97 | } 98 | 99 | while (true) { 100 | 101 | 102 | 103 | 104 | // comment 105 | } 106 | 107 | repeat (5) { 108 | 109 | 110 | 111 | 112 | // comment 113 | } 114 | 115 | do { 116 | 117 | 118 | 119 | 120 | // comment 121 | } until (true); 122 | 123 | foreach (k, v in a) { 124 | 125 | 126 | 127 | 128 | // comment 129 | } 130 | 131 | // expression_statement 132 | 0 133 | 134 | 135 | 136 | 137 | // comment 138 | ; 139 | 140 | // return_statement 141 | return 142 | 143 | 144 | 145 | 146 | // comment 147 | 0; 148 | 149 | // method_call_expression 150 | 0.toString( 151 | 152 | 153 | 154 | 155 | // comment 156 | ); 157 | 158 | // static_call_expression 159 | ton( 160 | 161 | 162 | 163 | 164 | "0.1" // comment 165 | ); 166 | 167 | // instance_expression 168 | S { 169 | 170 | 171 | 172 | 173 | // comment 174 | }; 175 | 176 | // initOf_expression 177 | initOf C( 178 | 179 | 180 | 181 | 182 | // comment 183 | ); 184 | } 185 | -------------------------------------------------------------------------------- /test/lang/test.tcl: -------------------------------------------------------------------------------- 1 | proc hello {name age} { # {{CONTEXT}} 2 | puts "Hello $name! You are $age years old." 3 | 4 | 5 | 6 | 7 | # {{CURSOR}} 8 | } 9 | -------------------------------------------------------------------------------- /test/lang/test.templ: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( // {{CONTEXT}} 4 | "fmt" 5 | 6 | 7 | 8 | 9 | 10 | "time" // {{CURSOR}} 11 | ) 12 | 13 | templ headerTemplate(name string) { 14 |
15 | switch name { 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | case "Alice", "Bob": 29 |

{ name }

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | default: 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |

{ "Unknown" }

57 | } 58 | 59 | 64 |
65 | } 66 | 67 | templ posts(posts []Post) { 68 | @layout("Posts") { 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | @postsTemplate(posts) 77 | if len(posts) > 0 { 78 |
{ "Not empty" }
79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | } else { 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 |
{ "Empty" }
102 | } 103 | } 104 | } 105 | 106 | templ postsTemplate(posts []Post) { 107 |
108 | for _, p := range posts { 109 | 110 |
111 |
{ p.Name }
112 |
{ p.Author }
113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 |
130 | } 131 |
132 | } 133 | 134 | script withParameters(a string, b string, c int) { 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | console.log(a, b, c); 144 | } 145 | 146 | css red() { 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | background-color: #ff0000; 160 | font-family: "Iosevka"; 161 | } 162 | -------------------------------------------------------------------------------- /test/lang/test.tf: -------------------------------------------------------------------------------- 1 | 2 | locals { // {{CONTEXT}} 3 | input_deps = { 4 | for slug, group in local.t2r_map : // {{CONTEXT}} 5 | slug => { // {{CONTEXT}} 6 | a = 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | // {{CURSOR}} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | a = 1 27 | a = 1 28 | a = 1 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/lang/test.tl: -------------------------------------------------------------------------------- 1 | while true do -- {{CONTEXT}} 2 | print("Hello world!") 3 | 4 | 5 | 6 | -- {{CURSOR}} 7 | end 8 | -------------------------------------------------------------------------------- /test/lang/test.toml: -------------------------------------------------------------------------------- 1 | [test] # {{CONTEXT}} 2 | wow = [ # {{CONTEXT}} 3 | 4 | 5 | 6 | "hello", # {{CURSOR}} 7 | ] 8 | -------------------------------------------------------------------------------- /test/lang/test.ts: -------------------------------------------------------------------------------- 1 | interface User { // {{CONTEXT}} 2 | name: string; 3 | 4 | 5 | 6 | id: number; 7 | 8 | 9 | 10 | // {{CURSOR}} 11 | } 12 |   13 | class UserAccount { 14 | name: string; 15 | id: number; 16 | 17 | 18 | 19 |   20 | constructor(name: string, id: number) { 21 | this.name = name; 22 | this.id = id; 23 | 24 | for (let i = 0; i < 3; i++) { 25 | console.log("hello"); 26 | 27 | 28 | 29 | } 30 | 31 | 32 | 33 | 34 | } 35 | } 36 | 37 | 38 | function wrapInArray(obj: string | string[]) { 39 | if (typeof obj === "string") { 40 | return [obj]; 41 | 42 | 43 | 44 | 45 | } 46 | return obj; 47 | } 48 | -------------------------------------------------------------------------------- /test/lang/test.tsx: -------------------------------------------------------------------------------- 1 | /** @jsx Object */ 2 | 3 | interface User { // {{CONTEXT}} 4 | name: string; 5 | 6 | 7 | 8 | id: number; 9 | 10 | 11 | // {{CURSOR}} 12 | 13 | } 14 |   15 | class UserAccount { 16 | name: string; 17 | id: number; 18 | 19 | 20 | 21 |   22 | constructor(name: string, id: number) { 23 | this.name = name; 24 | this.id = id; 25 | 26 | for (let i = 0; i < 3; i++) { 27 | console.log("hello"); 28 | 29 | 30 | 31 | } 32 | 33 | 34 | 35 | 36 | } 37 | } 38 | 39 | 40 | function wrapInArray(obj: string | string[]) { 41 | if (typeof obj === "string") { 42 | return [obj]; 43 | 44 | 45 | 46 | 47 | } 48 | return obj; 49 | } 50 | 51 | function* wrapInArray2( 52 | obj: string | string[]): 53 | string[] { 54 | if (typeof obj === "string") { 55 | return [obj]; 56 | 57 | 58 | 59 | 60 | } 61 | return obj; 62 | } 63 | 64 | 65 | function MyComponent() { 66 | return ( 67 |
68 |
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
82 |
83 | ); 84 | } 85 | 86 | const MyComponentExpression = Object(() => { 87 | return ( 88 |
89 |
90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
103 |
104 | ); 105 | }) 106 | -------------------------------------------------------------------------------- /test/lang/test.typ: -------------------------------------------------------------------------------- 1 | = Introduction {{CONTEXT}} 2 | 3 | This is a sample section in Typst. Typst is a markup-based typesetting system that's designed to be powerful and easy to learn. 4 | 5 | {{CURSOR}} 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/lang/test.typoscript: -------------------------------------------------------------------------------- 1 | // vim: ft=typoscript 2 | foo { // {{CONTEXT}} 3 | 4 | 5 | 6 | 7 | // {{CURSOR}} 8 | } 9 | 10 | [condition] 11 | 12 | 13 | 14 | 15 | 16 | [end] 17 | 18 | [condition] 19 | 20 | 21 | 22 | 23 | 24 | foo { 25 | 26 | 27 | 28 | 29 | 30 | nested { 31 | 32 | 33 | 34 | 35 | 36 | } 37 | 38 | 39 | 40 | 41 | 42 | 43 | } 44 | 45 | 46 | 47 | 48 | 49 | [global] 50 | -------------------------------------------------------------------------------- /test/lang/test.usd: -------------------------------------------------------------------------------- 1 | def Xform "thing" // {{CONTEXT}} 2 | { 3 | 4 | 5 | 6 | 7 | 8 | 9 | // {{CURSOR}} 10 | def "thing" {} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | def Scope "child" 28 | { 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | variantSet "thing" = { 49 | "stuff" { 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | def Scope "more_child_001" 66 | { 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | } 85 | } 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | } 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | } 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | } 112 | -------------------------------------------------------------------------------- /test/lang/test.v: -------------------------------------------------------------------------------- 1 | module module_name#( 2 | parameter A = 1 3 | 4 | ) ( 5 | input i_clk, 6 | output reg o_test 7 | ); 8 | wire s_a [20:0]; 9 | 10 | wire s_1; 11 | wire s_2; 12 | wire s_3; 13 | wire s_4; 14 | wire s_5; 15 | wire s_6; 16 | wire s_7; 17 | wire s_8; 18 | wire s_9; 19 | wire s_10; 20 | wire s_11; 21 | wire s_12; 22 | wire s_13; 23 | wire s_14; 24 | wire s_15; 25 | wire s_16; 26 | wire s_17; 27 | wire s_18; 28 | wire s_19; 29 | wire s_20; 30 | wire s_21; 31 | 32 | // {{TEST}} 33 | genvar i; 34 | generate 35 | for (i = 0; i < 10; i = i + 1) // {{CONTEXT}} 36 | begin : gen_loop 37 | test uut ( // {{CONTEXT}} 38 | .i_1 (s_1 ), 39 | .i_2 (s_2 ), 40 | .i_3 (s_3 ), 41 | .i_4 (s_4 ), 42 | .i_5 (s_5 ), 43 | .i_6 (s_6 ), 44 | .i_7 (s_7 ), 45 | .i_8 (s_8 ), 46 | .i_9 (s_9 ), 47 | .i_10 (s_10 ), 48 | .i_11 (s_11 ), 49 | .i_12 (s_12 ), 50 | .i_13 (s_13 ), // {{CURSOR}} 51 | .i_14 (s_14 ), 52 | .i_15 (s_15 ), 53 | .i_16 (s_16 ), 54 | .i_17 (s_17 ), 55 | .i_18 (s_18 ), 56 | .i_19 (s_19 ), 57 | .i_20 (s_20 ), 58 | .i_21 (s_21 ) 59 | ); 60 | end 61 | endgenerate 62 | 63 | // {{TEST}} 64 | always @(posedge i_clk) begin // {{CONTEXT}} 65 | if (s_1) begin // {{CONTEXT}} 66 | s_a[0] <= s_1; 67 | s_a[1] <= s_2; 68 | s_a[2] <= s_3; 69 | s_a[3] <= s_4; 70 | s_a[4] <= s_5; 71 | s_a[5] <= s_6; 72 | s_a[6] <= s_7; 73 | s_a[7] <= s_8; 74 | s_a[8] <= s_9; 75 | s_a[9] <= s_10; 76 | s_a[10] <= s_11; 77 | s_a[11] <= s_12; 78 | s_a[12] <= s_13; 79 | s_a[13] <= s_14; // {{CURSOR}} 80 | s_a[14] <= s_15; 81 | s_a[15] <= s_16; 82 | s_a[16] <= s_17; 83 | s_a[17] <= s_18; 84 | s_a[18] <= s_19; 85 | s_a[19] <= s_20; 86 | s_a[20] <= s_21; 87 | end 88 | else begin 89 | o_test <= s_a[20]; 90 | end 91 | end 92 | 93 | endmodule 94 | -------------------------------------------------------------------------------- /test/lang/test.vhd: -------------------------------------------------------------------------------- 1 | --+------------------------------- 2 | --| Block Comment 3 | --+------------------------------- 4 | 5 | -- (architecture_definition) 6 | architecture Behavioral of MyEntity is -- {{CONTEXT}} 7 | 8 | 9 | 10 | -- {{CURSOR}} 11 | -- (architecture_head) 12 | signal clk: std_logic; 13 | begin 14 | -- (concurrent_block) 15 | clk_process: process(clk) 16 | begin 17 | clk <= not clk after 10 ns; 18 | wait for 10 ns; 19 | end process clk_process; 20 | 21 | -- -- (case_statement) 22 | -- case state is 23 | -- when Idle => state <= Active; 24 | -- when Active => state <= Waiting; 25 | -- when others => state <= Idle; 26 | -- end case; 27 | 28 | -- (for_generate_statement) 29 | g_GENERATE_FOR: for i in 0 to 3 generate 30 | comp_inst: MyComponent 31 | port map ( 32 | a => data(i) 33 | ); 34 | end generate g_GENERATE_FOR; 35 | 36 | -- (if_generate_statement) 37 | g_GENERATE_IF: if clk = '1' generate 38 | comp_inst: MyComponent port map (a => clk); 39 | end generate g_GENERATE_IF; 40 | 41 | U1: MyComponent 42 | generic map ( 43 | WIDTH => 8 44 | ) 45 | port map ( 46 | a => data(0) 47 | ); 48 | 49 | end Behavioral; 50 | 51 | -- (configuration_declaration) 52 | configuration Config of MyEntity is 53 | for Behavioral 54 | end for; 55 | end configuration Config; 56 | 57 | -- (process_statement) 58 | process (clk) 59 | begin 60 | if rising_edge(clk) then 61 | -- (sequential_block) 62 | if_statement_block: if enable = '1' then 63 | -- (loop_statement) 64 | for i in 0 to 7 loop 65 | -- (if_statement) 66 | if data(i) = '1' then 67 | -- (elsif_statement) 68 | elsif data(i) = '0' then 69 | -- (else_statement) 70 | else 71 | data(i) <= 'X'; 72 | end if; 73 | end loop; 74 | end if; 75 | end if; 76 | end process; 77 | 78 | -- (type_declaration) 79 | type State_Type is (Idle, Active, Waiting); 80 | -- (entity_declaration) 81 | entity MyEntity is 82 | -- (entity_head) 83 | port ( 84 | clk: in std_logic; 85 | reset: in std_logic; 86 | data: out std_logic_vector(7 downto 0) 87 | ); 88 | end MyEntity; 89 | 90 | -- (package_declaration) 91 | package MyPackage is 92 | -- (package_definition) 93 | function Add (a, b: integer) return integer; 94 | end MyPackage; 95 | 96 | -- (subprogram_declaration) 97 | function Add (a, b: integer) return integer is 98 | begin 99 | -- (subprogram_head) 100 | return a + b; 101 | end Add; 102 | 103 | 104 | -------------------------------------------------------------------------------- /test/lang/test.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_{{CONTEXT}}') | 2 | 3 | 4 | 5 | 6 | 7 | finish | endif " {{CURSOR}} 8 | 9 | -------------------------------------------------------------------------------- /test/lang/test.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 56 | 57 | 82 | -------------------------------------------------------------------------------- /test/lang/test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Python Crash Course 93 | 94 |
95 |
96 |
97 | 98 | 99 | -------------------------------------------------------------------------------- /test/lang/test.yml: -------------------------------------------------------------------------------- 1 | '{{CONTEXT}}': 2 | '{{CONTEXT}}': 3 | 4 | 5 | 6 | 7 | 8 | - '{{CURSOR}}' 9 | -------------------------------------------------------------------------------- /test/lang/test.zig: -------------------------------------------------------------------------------- 1 | test "stuff" { // {{CONTEXT}} 2 | while (i < 3 && // {{CONTEXT}} 3 | j > 4) { 4 | i += 1; 5 | 6 | // {{CURSOR}} 7 | if (i == 2 8 | && j == 3) { 9 | // stuff 10 | 11 | 12 | 13 | 14 | } else if (i == 3 && 15 | j == 4) { 16 | // stuff 17 | 18 | 19 | 20 | 21 | } else { 22 | // stuff 23 | 24 | 25 | 26 | 27 | } 28 | } 29 | 30 | inline while (i < 3) : (i += 1) { 31 | 32 | 33 | // stuff 34 | 35 | 36 | } 37 | 38 | 39 | while (eventuallyNullSequence()) |value| { 40 | 41 | 42 | 43 | 44 | 45 | sum1 += value; 46 | 47 | 48 | 49 | } 50 | 51 | 52 | const items = [_]i32 { 4, 5, 3, 4, 0 }; 53 | 54 | // counting for loop 55 | for 56 | 57 | 58 | var sum: i32 = 0; 59 | const result = for ( 60 | items) |value| { 61 | if (value != null) { 62 | sum += value.?; 63 | } 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | } else blk: { 76 | try expect(sum == 12); 77 | break :blk sum; 78 | 79 | 80 | 81 | 82 | 83 | }; 84 | 85 | 86 | } 87 | 88 | 89 | 90 | const Stuff = struct { 91 | a: i8, 92 | 93 | 94 | 95 | b: i8, 96 | 97 | 98 | 99 | 100 | c: i8, 101 | 102 | 103 | 104 | 105 | 106 | d: i8, 107 | } 108 | 109 | fn bar(a: i8, 110 | b: i8) { 111 | switch (a) { 112 | 42, 113 | 1 => { 114 | 115 | } 116 | } 117 | const b = switch (a) { 118 | 42, 119 | 1 => { 120 | 121 | 122 | }, 123 | 124 | 101, 125 | 102=> blk: { 126 | 127 | 128 | 129 | 130 | const c: u64 = 5; 131 | 132 | 133 | 134 | 135 | break :blk c * 2 + 1; 136 | }, 137 | 138 | else => 9, 139 | }; 140 | 141 | } 142 | fn foo(a: i8, 143 | 144 | b:i8) Stuff { 145 | var p = Stuff { 146 | a: 1, 147 | 148 | 149 | 150 | b: 2, 151 | 152 | 153 | 154 | c: 3, 155 | 156 | 157 | 158 | d: 4, 159 | }; 160 | 161 | return Stuff { 162 | .a = a, 163 | 164 | 165 | .b = b, 166 | 167 | 168 | }; 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | } 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /test/queries_spec.lua: -------------------------------------------------------------------------------- 1 | --- Test the query for each language is valid and update the README. 2 | local helpers = require('nvim-test.helpers') 3 | local exec_lua = helpers.exec_lua 4 | 5 | local tc_helpers = require('test.helpers') 6 | 7 | describe('query:', function() 8 | local readme_lines = {} --- @type string[] 9 | 10 | setup(function() 11 | helpers.clear() 12 | exec_lua(tc_helpers.setup) 13 | 14 | local f = assert(io.open('README.md', 'r')) 15 | for l in f:lines() do 16 | readme_lines[#readme_lines + 1] = l 17 | end 18 | f:close() 19 | end) 20 | 21 | for _, lang in ipairs(tc_helpers.get_langs()) do 22 | it(lang, function() 23 | local lang_index --- @type integer 24 | local last_supported_lang_index --- @type integer 25 | local last_lang_index --- @type integer 26 | 27 | -- Find the line in the README for this lang 28 | for i, l in ipairs(readme_lines) do 29 | --- @type string? 30 | local tick, lang1 = l:match('%- %[(.)%] `([^`]+)`') 31 | if lang1 then 32 | if tick == 'x' then 33 | last_supported_lang_index = i 34 | else 35 | last_lang_index = i 36 | end 37 | 38 | if lang1 == lang then 39 | lang_index = i 40 | end 41 | end 42 | end 43 | 44 | if lang_index then 45 | table.remove(readme_lines, lang_index) 46 | end 47 | 48 | if not vim.uv.fs_stat('queries/' .. lang .. '/context.scm') then 49 | table.insert(readme_lines, last_lang_index, (' - [ ] `%s`'):format(lang)) 50 | pending('no queries/' .. lang .. '/context.scm') 51 | return 52 | end 53 | exec_lua(tc_helpers.install_langs, lang) 54 | local ok = exec_lua(function(...) 55 | return (pcall(vim.treesitter.query.get, ...)) 56 | end, lang, 'context') 57 | table.insert( 58 | readme_lines, 59 | last_supported_lang_index, 60 | (' - [x] `%s`%s'):format(lang, ok and '' or ' (broken)') 61 | ) 62 | assert(ok) 63 | end) 64 | end 65 | 66 | teardown(function() 67 | -- Update the README. 68 | local f = assert(io.open('README.md', 'w')) 69 | for _, l in ipairs(readme_lines) do 70 | f:write(l) 71 | f:write('\n') 72 | end 73 | f:close() 74 | end) 75 | end) 76 | -------------------------------------------------------------------------------- /test/snapshots/snapshot.cpp: -------------------------------------------------------------------------------- 1 | struct Struct { 2 | int *f1; 3 | int *f2; 4 | 5 | 6 | 7 | // cursor position 1 8 | }; 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | class Class { 18 | int *f1; 19 | int *f2; 20 | 21 | 22 | 23 | // cursor position 2 24 | }; 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | typedef enum { 34 | E1, 35 | E2, 36 | E3 37 | 38 | 39 | // cursor position 3 40 | } myenum; 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | int main(int arg1, 52 | char **arg2, 53 | char **arg3 54 | ) 55 | { 56 | if (arg1 == 4 57 | && arg2 == arg3) { 58 | for (int i = 0; i < arg1; i++) { 59 | while (1) { 60 | 61 | 62 | 63 | 64 | 65 | // cursor position 4 66 | } 67 | } 68 | } 69 | 70 | 71 | 72 | 73 | 74 | 75 | do { 76 | int array[1]; 77 | for (auto value : array) { 78 | 79 | 80 | 81 | 82 | 83 | // cursor position 5 84 | } 85 | } while (1); 86 | } 87 | -------------------------------------------------------------------------------- /test/snapshots/snapshot.md: -------------------------------------------------------------------------------- 1 | ```html 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 43 | 44 | 45 | ``` 46 | 47 | # Title 48 | 49 | 50 | 51 | 52 | 53 | Test 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/snapshots/snapshot.php: -------------------------------------------------------------------------------- 1 | $key) { 26 | // comment 27 | do { 28 | // comment 29 | echo "The number is: $x
"; 30 | $x++; 31 | 32 | 33 | 34 | 35 | } while ($x <= 5); 36 | 37 | for ($x = 0; $x <= 10; $x++) { 38 | echo "The number is: $x
"; 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | } 51 | 52 | 53 | 54 | foreach ($colors as $value) { 55 | echo "$value
"; 56 | 57 | 58 | 59 | 60 | 61 | 62 | } 63 | 64 | $high = $index - 1; 65 | } 66 | } 67 | 68 | 69 | 70 | //when key not found in array or array not sorted 71 | return null; 72 | } 73 | 74 | #[Attribute] 75 | class Fruit { 76 | 77 | 78 | 79 | 80 | #[ReturnTypeWillChange] 81 | public function rot(): void 82 | { 83 | 84 | 85 | return; 86 | } 87 | 88 | 89 | 90 | // comment 91 | 92 | 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /test/snapshots/snapshot.rs: -------------------------------------------------------------------------------- 1 | impl Foo { 2 | 3 | 4 | 5 | 6 | fn bar(&self) { 7 | 8 | 9 | 10 | 11 | 12 | if condition { 13 | 14 | 15 | 16 | 17 | 18 | 19 | for i in 0..100 { 20 | 21 | 22 | 23 | 24 | 25 | 26 | foo(async move { 27 | 28 | 29 | 30 | 31 | 32 | 33 | // comment 34 | 35 | 36 | 37 | 38 | 39 | 40 | }) 41 | } 42 | } 43 | 44 | 45 | 46 | 47 | 48 | try { 49 | 50 | 51 | 52 | 53 | 54 | 55 | let Foo::Bar { 56 | texts, 57 | values, 58 | } = foo().bar() else { 59 | 60 | 61 | 62 | 63 | 64 | let a = if b { 65 | 66 | 67 | 68 | 69 | 70 | // comment 71 | 72 | 73 | 74 | 75 | 76 | } else { 77 | 78 | 79 | 80 | 81 | // comment 82 | 83 | 84 | 85 | 86 | }; 87 | } 88 | } 89 | 90 | 91 | 92 | 93 | short_call_site(a, b); 94 | 95 | long_call_site( 96 | a, 97 | 98 | b, 99 | 100 | c, 101 | 102 | d, 103 | 104 | e, 105 | ); 106 | 107 | 108 | 109 | 110 | macro_rules! x { 111 | 112 | 113 | // comment 114 | () => {}; 115 | 116 | 117 | } 118 | 119 | 120 | 121 | 122 | x! { 123 | 124 | 125 | 126 | // comment 127 | 128 | 129 | 130 | } 131 | 132 | 133 | 134 | unsafe { 135 | 136 | 137 | *0 // run 138 | 139 | 140 | } 141 | 142 | 143 | 144 | 145 | let short_array = []; 146 | 147 | let long_array = [ 148 | 1, 149 | 150 | 2, 151 | 152 | 3, 153 | 154 | 4, 155 | ]; 156 | 157 | let (short, tuple) = (1, 2); 158 | 159 | let ( 160 | a, 161 | 162 | rather, 163 | 164 | long, 165 | 166 | tuple, 167 | ) = ( 168 | 1, 169 | 170 | 2, 171 | 172 | 3, 173 | 174 | 4, 175 | ); 176 | } 177 | 178 | let s = BigStruct { 179 | 180 | a, 181 | 182 | b, 183 | 184 | c, 185 | 186 | d, 187 | }; 188 | } 189 | 190 | pub extern "C" { 191 | 192 | 193 | 194 | pub fn foobar(_: *u8); 195 | 196 | 197 | 198 | } 199 | 200 | struct Foo { 201 | 202 | active: bool, 203 | 204 | username: String, 205 | 206 | email: String, 207 | 208 | sign_in_count: u64, 209 | 210 | } 211 | 212 | union Bar { 213 | 214 | a: u8, 215 | 216 | b: u16, 217 | 218 | c: u32, 219 | 220 | } 221 | -------------------------------------------------------------------------------- /test/snapshots/snapshot.ts: -------------------------------------------------------------------------------- 1 | interface User { 2 | name: string; 3 | 4 | 5 | 6 | id: number; 7 | 8 | 9 | 10 | 11 | } 12 |   13 | class UserAccount { 14 | name: string; 15 | id: number; 16 | 17 | 18 | 19 |   20 | constructor(name: string, id: number) { 21 | this.name = name; 22 | this.id = id; 23 | 24 | for (let i = 0; i < 3; i++) { 25 | console.log("hello"); 26 | 27 | 28 | 29 | } 30 | 31 | 32 | 33 | 34 | } 35 | } 36 | 37 | 38 | function wrapInArray(obj: string | string[]) { 39 | if (typeof obj === "string") { 40 | return [obj]; 41 | 42 | 43 | 44 | 45 | } 46 | return obj; 47 | } 48 | -------------------------------------------------------------------------------- /test/test.c: -------------------------------------------------------------------------------- 1 | struct Bert { 2 | int *f1; 3 | // comment 4 | int *f2; 5 | // comment 6 | // comment 7 | // comment 8 | // comment 9 | // comment 10 | }; 11 | 12 | typedef enum { 13 | E1, 14 | E2, 15 | E3 16 | // comment 17 | // comment 18 | // comment 19 | // comment 20 | // comment 21 | // comment 22 | } Myenum; 23 | 24 | int main(int arg1, 25 | char **arg2, 26 | char **arg3 27 | ) 28 | { 29 | 30 | if (arg1 == 4 31 | && arg2 == arg3) { 32 | 33 | // comment 34 | // comment 35 | // comment 36 | // comment 37 | // comment 38 | // comment 39 | // comment 40 | // comment 41 | // comment 42 | // comment 43 | // comment 44 | // comment 45 | // comment 46 | // comment 47 | for (int i = 0; i < arg1; i++) { 48 | // comment 49 | // comment 50 | // comment 51 | // comment 52 | while (1) { 53 | // comment 54 | // comment 55 | // comment 56 | // comment 57 | // comment 58 | } 59 | 60 | do { 61 | // comment 62 | // comment 63 | // comment 64 | // comment 65 | // comment 66 | 67 | } while (1); 68 | // comment 69 | // comment 70 | // comment 71 | // comment 72 | // comment 73 | } 74 | 75 | } else if (arg1 == 4) { 76 | // comment 77 | // comment 78 | // comment 79 | // comment 80 | // comment 81 | // comment 82 | // comment 83 | // comment 84 | // comment 85 | // comment 86 | // comment 87 | // comment 88 | // comment 89 | // comment 90 | // comment 91 | // comment 92 | // comment 93 | // comment 94 | 95 | } else { 96 | // comment 97 | // comment 98 | // comment 99 | // comment 100 | // comment 101 | // comment 102 | // comment 103 | // comment 104 | // comment 105 | // comment 106 | // comment 107 | // comment 108 | // comment 109 | // comment 110 | // comment 111 | // comment 112 | // comment 113 | // comment 114 | // comment 115 | // comment 116 | // comment 117 | 118 | } 119 | 120 | switch (arg1) { 121 | // comment 122 | // comment 123 | case 0: 124 | // comment 125 | // comment 126 | // comment 127 | // comment 128 | // comment 129 | // comment 130 | // comment 131 | // comment 132 | // comment 133 | // comment 134 | break; 135 | case 1: { 136 | // comment 137 | // comment 138 | // comment 139 | // comment 140 | // comment 141 | // comment 142 | // comment 143 | // comment 144 | // comment 145 | // comment 146 | } break; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /test/test_file.lua: -------------------------------------------------------------------------------- 1 | local function foo() 2 | 3 | local function bar() 4 | 5 | 6 | 7 | end 8 | 9 | local function baz() 10 | 11 | 12 | 13 | end 14 | 15 | end 16 | --------------------------------------------------------------------------------