mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-02 20:30:05 +08:00
chore(treesitter): use bundle treesitter
This commit is contained in:
parent
4d04e3ff96
commit
d5cf952778
@ -13,7 +13,13 @@
|
||||
|
||||
function! SpaceVim#layers#treesitter#plugins() abort
|
||||
let plugins = []
|
||||
call add(plugins, ['nvim-treesitter/nvim-treesitter', {'do' : ':TSUpdate'}])
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/nvim-treesitter',
|
||||
\ {
|
||||
\ 'merged' : 0,
|
||||
\ 'loadconf' : 1 ,
|
||||
\ 'do' : 'TSUpdate',
|
||||
\ 'loadconf_before' : 1
|
||||
\ }])
|
||||
return plugins
|
||||
endfunction
|
||||
|
||||
|
20
bundle/nvim-treesitter/.editorconfig
Normal file
20
bundle/nvim-treesitter/.editorconfig
Normal file
@ -0,0 +1,20 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
tab_width = 8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
|
||||
[*.lua]
|
||||
tab_width = 2
|
||||
|
||||
[*.py]
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
|
||||
[{Makefile,**/Makefile,runtime/doc/*.txt}]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
7
bundle/nvim-treesitter/.github/CODEOWNERS
vendored
Normal file
7
bundle/nvim-treesitter/.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/lua/nvim-treesitter/textobjects/ @theHamsta
|
||||
/lua/nvim-treesitter/incremental_selection.lua @theHamsta
|
||||
|
||||
/lua/nvim-treesitter/fold.lua @vigoux
|
||||
/lua/nvim-treesitter/highlight.lua @vigoux
|
||||
|
||||
/lua/nvim-treesitter/refactor/ @steelsojka
|
1
bundle/nvim-treesitter/.github/FUNDING.yml
vendored
Normal file
1
bundle/nvim-treesitter/.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
open_collective: "nvim-treesitter"
|
58
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
58
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us improve
|
||||
labels: [ bug ]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Before reporting
|
||||
Please do the following steps before reporting an issue.
|
||||
|
||||
- I have updated my neovim version to latest _master_
|
||||
- I have updated my plugin to the latest version
|
||||
- I have run `:TSUpdate`
|
||||
- I have read the [troubleshooting section](https://github.com/nvim-treesitter/nvim-treesitter#troubleshooting)
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: To Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Output of `:checkhealth nvim-treesitter`
|
||||
render: markdown
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Output of `nvim --version`
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any context about the problem here.
|
20
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
98
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/highlighting_issue.yml
vendored
Normal file
98
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/highlighting_issue.yml
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
name: Highlighting issue
|
||||
description: Missing or incorrect highlights or you want to change the way something is highlighted
|
||||
labels: [ highlights ]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Before reporting
|
||||
Please perform the following steps before reporting an issue.
|
||||
- I have updated my neovim version to latest _master_.
|
||||
- I have updated my plugin to the latest version.
|
||||
- I have run `:TSUpdate`.
|
||||
- I have inspected the syntax tree using https://github.com/nvim-treesitter/playground and made sure
|
||||
that no `ERROR` nodes are in the syntax tree. nvim-treesitter can not guarantee correct highlighting in the
|
||||
presence of `ERROR`s -- in this case, please report the bug directly at corresponding parser's repository. (You can find all repository URLs in [README.md](https://github.com/nvim-treesitter/nvim-treesitter#supported-languages).)
|
||||
- I have used `:TSHighlightCapturesUnderCursor` from https://github.com/nvim-treesitter/playground to inspect which highlight groups Neovim is using and that legacy syntax highlighting is not interfering (i.e., what you are observing is actual tree-sitter highlighting).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the highlighting problem
|
||||
description: A clear and concise description of what should be highlighted in a different way.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Example snippet that causes the problem
|
||||
description: Please provide an example snippet in plain text that causes the problem.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Tree-sitter parsing result
|
||||
description: |
|
||||
Please provide the output of `:TSPlaygroundToggle` from https://github.com/nvim-treesitter/playground
|
||||
(screenshot or plain text) with the following options enabled (pressing the key):
|
||||
- `I` (name of the parsed language)
|
||||
- `t` (toggle injected languages)
|
||||
- `a` (show anonymous nodes)
|
||||
placeholder: |
|
||||
This should look somehow like this:
|
||||
```
|
||||
preproc_ifdef [0, 0] - [4, 6] cpp
|
||||
"#ifdef" [0, 0] - [0, 6] cpp
|
||||
name: identifier [0, 7] - [0, 17] cpp
|
||||
preproc_def [1, 0] - [2, 0] cpp
|
||||
"#define" [1, 0] - [1, 7] cpp
|
||||
name: identifier [1, 8] - [1, 16] cpp
|
||||
value: preproc_arg [1, 16] - [1, 27] cpp
|
||||
"\n" [1, 27] - [2, 0] cpp
|
||||
alternative: preproc_else [2, 0] - [4, 0] cpp
|
||||
"#else" [2, 0] - [2, 5] cpp
|
||||
preproc_def [3, 0] - [4, 0] cpp
|
||||
"#define" [3, 0] - [3, 7] cpp
|
||||
name: identifier [3, 8] - [3, 16] cpp
|
||||
value: preproc_arg [3, 16] - [3, 29] cpp
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Example screenshot
|
||||
description: |
|
||||
Please provide a screenshot of the current highlighting. Please also tell us the `:h colorscheme` you are using
|
||||
and how to install it. If applicable, you can also upload a screenshot with the contents of
|
||||
`:TSHighlightCapturesUnderCursor'.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: |
|
||||
A clear and concise description of what you expect to be changed. You can provide screenshot of
|
||||
other editors or traditional Vim highlighting that don't show this problem or show a screenshot how
|
||||
nvim-treesitter highlighting would look like when a problematic query would be removed/altered.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Output of `:checkhealth nvim-treesitter`
|
||||
render: markdown
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Output of `nvim --version`
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any context about the problem here.
|
12
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/language-request.md
vendored
Normal file
12
bundle/nvim-treesitter/.github/ISSUE_TEMPLATE/language-request.md
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
name: Language request
|
||||
about: Request for a new language to be supported
|
||||
title: ''
|
||||
labels: enhancement, good first issue, help wanted
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Language information**
|
||||
|
||||
Please paste any useful information here !
|
37
bundle/nvim-treesitter/.github/mergify.yml
vendored
Normal file
37
bundle/nvim-treesitter/.github/mergify.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
pull_request_rules:
|
||||
- name: Merge lockfile updates
|
||||
conditions:
|
||||
- "title=Update lockfile.json"
|
||||
actions:
|
||||
review:
|
||||
type: APPROVE
|
||||
message: Automatically approving lockfile updates
|
||||
merge:
|
||||
method: merge
|
||||
|
||||
- name: Prepare for merge
|
||||
conditions:
|
||||
- and:
|
||||
- "-draft"
|
||||
- "#approved-reviews-by=1"
|
||||
- "#review-requested=0"
|
||||
actions:
|
||||
comment:
|
||||
message: |
|
||||
This PR is ready to be merged, and will be in 1 day if nothing happens before.
|
||||
If you want other people to review your PR, request their reviews.
|
||||
If you don't want this PR to be merged now, mark it as a Draft.
|
||||
|
||||
- name: Merge on approval
|
||||
conditions:
|
||||
- and:
|
||||
- or:
|
||||
- "#approved-reviews-by>=2"
|
||||
- and:
|
||||
- "#approved-reviews-by=1"
|
||||
- "updated-at>=1 day ago"
|
||||
- "-draft"
|
||||
- "#review-requested=0"
|
||||
actions:
|
||||
merge:
|
||||
method: rebase
|
33
bundle/nvim-treesitter/.github/workflows/lint.yml
vendored
Normal file
33
bundle/nvim-treesitter/.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
name: Linting and style checking
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
|
||||
jobs:
|
||||
luacheck:
|
||||
name: Luacheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install luarocks -y
|
||||
sudo luarocks install luacheck
|
||||
|
||||
- name: Run Luacheck
|
||||
run: luacheck .
|
||||
|
||||
stylua:
|
||||
name: StyLua
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Lint with stylua
|
||||
uses: JohnnyMorganz/stylua-action@1.0.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --check .
|
92
bundle/nvim-treesitter/.github/workflows/test-queries.yml
vendored
Normal file
92
bundle/nvim-treesitter/.github/workflows/test-queries.yml
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
name: Test queries
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
# Cancel any in-progress CI runs for a PR if it is updated
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check_compilation:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-2022, macos-latest]
|
||||
cc: [ gcc, clang ]
|
||||
nvim_tag: [ stable ]
|
||||
exclude:
|
||||
- os: ubuntu-latest
|
||||
cc: clang
|
||||
nvim_tag: stable
|
||||
|
||||
- os: macos-latest
|
||||
cc: gcc
|
||||
nvim_tag: stable
|
||||
|
||||
- os: windows-2022
|
||||
cc: clang
|
||||
nvim_tag: stable
|
||||
|
||||
include:
|
||||
- os: windows-2022
|
||||
cc: cl
|
||||
nvim_tag: stable
|
||||
|
||||
- os: ubuntu-latest
|
||||
cc: gcc
|
||||
nvim_tag: nightly
|
||||
|
||||
name: Parser compilation
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CC: ${{ matrix.cc }}
|
||||
NVIM: ${{ matrix.os == 'windows-2022' && 'Neovim\\bin\\nvim.exe' || 'nvim' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- uses: actions/setup-node@v2
|
||||
|
||||
- name: Install and prepare Neovim
|
||||
env:
|
||||
NVIM_TAG: ${{ matrix.nvim_tag }}
|
||||
TREE_SITTER_CLI_TAG: v0.20.4
|
||||
run: |
|
||||
bash ./scripts/ci-install-${{ matrix.os }}.sh
|
||||
|
||||
- name: Setup Parsers Cache
|
||||
id: parsers-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
./parser/
|
||||
~/AppData/Local/nvim/pack/nvim-treesitter/start/nvim-treesitter/parser/
|
||||
key: ${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.nvim_tag }}-parsers-v1-${{ hashFiles('./lockfile.json', './lua/nvim-treesitter/parsers.lua', './lua/nvim-treesitter/install.lua', './lua/nvim-treesitter/shell_selectors.lua') }}
|
||||
|
||||
- name: Compile parsers
|
||||
run: $NVIM --headless -c "lua require'nvim-treesitter.install'.prefer_git=false" -c "TSInstallSync all" -c "q"
|
||||
|
||||
- name: Post compile Windows
|
||||
if: matrix.os == 'windows-2022'
|
||||
run: cp -r ~/AppData/Local/nvim/pack/nvim-treesitter/start/nvim-treesitter/parser/* parser
|
||||
|
||||
# NOTE: this is a temporary workaround to skip swift tests on ubuntu
|
||||
# stable and should be removed once neovim 0.7 is released.
|
||||
- if: matrix.os == 'ubuntu-latest' && matrix.nvim_tag == 'stable'
|
||||
run: echo "SKIP_SWIFT_CHECK=TRUE" >> $GITHUB_ENV
|
||||
|
||||
- name: Check query files
|
||||
env:
|
||||
SKIP_SWIFT_CHECK: ${{ env.SKIP_SWIFT_CHECK }}
|
||||
run: $NVIM --headless -c "luafile ./scripts/check-queries.lua" -c "q"
|
63
bundle/nvim-treesitter/.github/workflows/tests.yml
vendored
Normal file
63
bundle/nvim-treesitter/.github/workflows/tests.yml
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
# Cancel any in-progress CI runs for a PR if it is updated
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check_compilation:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
cc: [ gcc ]
|
||||
|
||||
name: Run tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CC: ${{ matrix.cc }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
|
||||
- name: Test Dependencies
|
||||
run: |
|
||||
mkdir -p ~/.local/share/nvim/site/pack/plenary.nvim/start
|
||||
cd ~/.local/share/nvim/site/pack/plenary.nvim/start
|
||||
git clone https://github.com/nvim-lua/plenary.nvim
|
||||
curl -L https://github.com/theHamsta/highlight-assertions/releases/download/v0.1.5/highlight-assertions_v0.1.5_x86_64-unknown-linux-gnu.tar.gz | tar -xz
|
||||
cp highlight-assertions /usr/local/bin
|
||||
|
||||
- name: Install and prepare Neovim
|
||||
env:
|
||||
NVIM_TAG: stable
|
||||
TREE_SITTER_CLI_TAG: v0.20.4
|
||||
run: |
|
||||
bash ./scripts/ci-install-${{ matrix.os }}.sh
|
||||
|
||||
- name: Setup Parsers Cache
|
||||
id: parsers-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
./parser/
|
||||
~/AppData/Local/nvim/pack/nvim-treesitter/start/nvim-treesitter/parser/
|
||||
key: ${{ matrix.os }}-${{ matrix.cc }}-parsers-v1-${{ hashFiles('./lockfile.json', './lua/nvim-treesitter/parsers.lua', './lua/nvim-treesitter/install.lua', './lua/nvim-treesitter/shell_selectors.lua') }}
|
||||
|
||||
- name: Compile parsers Unix like
|
||||
if: ${{ matrix.os != 'windows-latest' && steps.parsers-cache.outputs.cache-hit != 'true' }}
|
||||
run: |
|
||||
nvim --headless -c "TSInstallSync all" -c "q"
|
||||
|
||||
- name: Tests
|
||||
run: PATH=/usr/local/bin:$PATH ./scripts/run_tests.sh
|
55
bundle/nvim-treesitter/.github/workflows/update-lockfile.yml
vendored
Normal file
55
bundle/nvim-treesitter/.github/workflows/update-lockfile.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
name: Update lockfile
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 6 * * *'
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
update-lockfile:
|
||||
name: Update lockfile
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: master
|
||||
|
||||
- name: Prepare
|
||||
env:
|
||||
NVIM_TAG: stable
|
||||
run: |
|
||||
wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
|
||||
mv ./jq-linux64 /tmp/jq
|
||||
chmod +x /tmp/jq
|
||||
wget https://github.com/neovim/neovim/releases/download/${NVIM_TAG}/nvim.appimage
|
||||
chmod u+x nvim.appimage
|
||||
mkdir -p ~/.local/share/nvim/site/pack/nvim-treesitter/start
|
||||
ln -s $(pwd) ~/.local/share/nvim/site/pack/nvim-treesitter/start
|
||||
|
||||
- name: Update parsers
|
||||
env:
|
||||
SKIP_LOCKFILE_UPDATE_FOR_LANGS: verilog,gleam,nix
|
||||
run: |
|
||||
./nvim.appimage --headless -c "luafile ./scripts/write-lockfile.lua" -c "q"
|
||||
# Pretty print
|
||||
cp lockfile.json /tmp/lockfile.json
|
||||
cat /tmp/lockfile.json | /tmp/jq --sort-keys > lockfile.json
|
||||
|
||||
- name: Commit changes
|
||||
run: |
|
||||
git config user.name "GitHub"
|
||||
git config user.email "noreply@github.com"
|
||||
git add lockfile.json
|
||||
git commit -m "Update lockfile.json" || echo 'No commit necessary!'
|
||||
git clean -xf
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
commit-message: Update lockfile.json
|
||||
title: Update lockfile.json
|
||||
branch: update-lockfile-pr
|
||||
base: ${{ github.head_ref }}
|
||||
draft: true
|
40
bundle/nvim-treesitter/.github/workflows/update-readme.yml
vendored
Normal file
40
bundle/nvim-treesitter/.github/workflows/update-readme.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: Update README
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
update-readme:
|
||||
name: Update README
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Prepare
|
||||
env:
|
||||
NVIM_TAG: stable
|
||||
run: |
|
||||
wget https://github.com/neovim/neovim/releases/download/${NVIM_TAG}/nvim.appimage
|
||||
chmod u+x nvim.appimage
|
||||
mkdir -p ~/.local/share/nvim/site/pack/nvim-treesitter/start
|
||||
ln -s $(pwd) ~/.local/share/nvim/site/pack/nvim-treesitter/start
|
||||
|
||||
- name: Check README
|
||||
run: |
|
||||
git config user.email "actions@github"
|
||||
git config user.name "Github Actions"
|
||||
./nvim.appimage --headless -c "luafile ./scripts/update-readme.lua" -c "q" || echo "Needs update"
|
||||
git add README.md
|
||||
git commit -m "Update README" || echo 'No commit necessary!'
|
||||
git clean -xf
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
commit-message: Update README
|
||||
title: Update README
|
||||
branch: update-readme-pr
|
||||
base: ${{ github.head_ref }}
|
||||
draft: true
|
4
bundle/nvim-treesitter/.gitignore
vendored
Normal file
4
bundle/nvim-treesitter/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
doc/tags
|
||||
.luacheckcache
|
||||
/tags
|
||||
nvim.appimage
|
21
bundle/nvim-treesitter/.luacheckrc
Normal file
21
bundle/nvim-treesitter/.luacheckrc
Normal file
@ -0,0 +1,21 @@
|
||||
-- Rerun tests only if their modification time changed.
|
||||
cache = true
|
||||
codes = true
|
||||
|
||||
exclude_files = {
|
||||
"tests/indent/lua/"
|
||||
}
|
||||
|
||||
-- Glorious list of warnings: https://luacheck.readthedocs.io/en/stable/warnings.html
|
||||
ignore = {
|
||||
"212", -- Unused argument, In the case of callback function, _arg_name is easier to understand than _, so this option is set to off.
|
||||
"411", -- Redefining a local variable.
|
||||
"412", -- Redefining an argument.
|
||||
"422", -- Shadowing an argument
|
||||
"122" -- Indirectly setting a readonly global
|
||||
}
|
||||
|
||||
-- Global objects defined by the C code
|
||||
read_globals = {
|
||||
"vim",
|
||||
}
|
6
bundle/nvim-treesitter/.stylua.toml
Normal file
6
bundle/nvim-treesitter/.stylua.toml
Normal file
@ -0,0 +1,6 @@
|
||||
column_width = 120
|
||||
line_endings = "Unix"
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
quote_style = "AutoPreferDouble"
|
||||
call_parentheses = "None"
|
1
bundle/nvim-treesitter/.styluaignore
Normal file
1
bundle/nvim-treesitter/.styluaignore
Normal file
@ -0,0 +1 @@
|
||||
tests/indent/lua/
|
299
bundle/nvim-treesitter/CONTRIBUTING.md
Normal file
299
bundle/nvim-treesitter/CONTRIBUTING.md
Normal file
@ -0,0 +1,299 @@
|
||||
# Contributing to `nvim-treesitter`
|
||||
|
||||
First of all, thank you very much for contributing to `nvim-treesitter`.
|
||||
|
||||
If you haven't already, you should really come and reach out to us on our [Zulip]
|
||||
server, so we can help you with any question you might have!
|
||||
There is also a [Matrix channel] for tree-sitter support in Neovim.
|
||||
|
||||
As you know, `nvim-treesitter` is roughly split in two parts:
|
||||
|
||||
- Parser configurations : for various things like `locals`, `highlights`
|
||||
- What we like to call *modules* : tiny lua modules that provide a given feature, based on parser configurations
|
||||
|
||||
Depending on which part of the plugin you want to contribute to, please read the appropriate section.
|
||||
|
||||
## Style Checks and Tests
|
||||
|
||||
We haven't implemented any functional tests yet. Feel free to contribute.
|
||||
However, we check code style with `luacheck` and `stylua`!
|
||||
Please install luacheck and activate our `pre-push` hook to automatically check style before
|
||||
every push:
|
||||
|
||||
```bash
|
||||
luarocks install luacheck
|
||||
cargo install stylua
|
||||
ln -s ../../scripts/pre-push .git/hooks/pre-push
|
||||
```
|
||||
|
||||
## Adding new modules
|
||||
|
||||
If you want to see a new functionality added to `nvim-treesitter` feel free to first open an issue
|
||||
to that we can track our solution!
|
||||
Thus far, there is basically two types of modules:
|
||||
|
||||
- Little modules (like `incremental selection`) that are built in `nvim-treesitter`, we call them
|
||||
`builtin modules`.
|
||||
- Bigger modules (like `completion-treesitter`, or `nvim-tree-docs`), or modules that integrate
|
||||
with other plugins, that we call `remote modules`.
|
||||
|
||||
In any case, you can build your own module ! To help you started in the process, we have a template
|
||||
repository designed to build new modules [here](https://github.com/nvim-treesitter/module-template).
|
||||
Feel free to use it, and contact us over on our
|
||||
[Zulip] or on the "Neovim tree-sitter" [Matrix channel].
|
||||
|
||||
## Parser configurations
|
||||
|
||||
Contributing to parser configurations is basically modifying one of the `queries/*/*.scm`.
|
||||
Each of these `scheme` files contains a *tree-sitter query* for a given purpose.
|
||||
Before going any further, we highly suggest that you [read more about tree-sitter queries](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries).
|
||||
|
||||
Each query has an appropriate name, which is then used by modules to extract data from the syntax tree.
|
||||
For now these are the types of queries used by `nvim-treesitter`:
|
||||
|
||||
- `highlights.scm`: used for syntax highlighting, using the `highlight` module.
|
||||
- `locals.scm`: used to extract keyword definitions, scopes, references, etc, using the `locals` module.
|
||||
- `textobjects.scm`: used to define text objects.
|
||||
- `folds.scm`: used to define folds.
|
||||
- `injections.scm`: used to define injections.
|
||||
|
||||
For these types there is a *norm* you will have to follow so that features work fine.
|
||||
Here are some global advices :
|
||||
|
||||
- If your language is listed [here](https://github.com/nvim-treesitter/nvim-treesitter#supported-languages),
|
||||
you can install the [playground plugin](https://github.com/nvim-treesitter/playground).
|
||||
- If your language is listed [here](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries),
|
||||
you can debug and experiment with your queries there.
|
||||
- If not, you should consider installing the [tree-sitter cli](https://github.com/tree-sitter/tree-sitter/tree/master/cli),
|
||||
you should then be able to open a local playground using `tree-sitter build-wasm && tree-sitter web-ui` within the
|
||||
parsers repo.
|
||||
- Examples of queries can be found in [queries/](queries/)
|
||||
- Matches in the bottom will override queries that are above of them.
|
||||
|
||||
If your language is an extension of a language (TypeScript is an extension of JavaScript for
|
||||
example), you can include the queries from your base language by adding the following _as the first
|
||||
line of your file_.
|
||||
|
||||
```query
|
||||
; inherits: lang1,(optionallang)
|
||||
```
|
||||
|
||||
If you want to inherit a language, but don't want the languages inheriting from yours to inherit it,
|
||||
you can mark the language as optional (by putting it between parenthesis).
|
||||
|
||||
### Highlights
|
||||
|
||||
As languages differ quite a lot, here is a set of captures available to you when building a `highlights.scm` query.
|
||||
One important thing to note is that many of these capture groups are not supported by `neovim` for now, and will not have any
|
||||
effect on highlighting. We will work on improving highlighting in the near future though.
|
||||
|
||||
#### Misc
|
||||
|
||||
```
|
||||
@comment
|
||||
@debug
|
||||
@error for error `ERROR` nodes.
|
||||
@none to disable completely the highlight
|
||||
@preproc
|
||||
@punctuation.delimiter for `;` `.` `,`
|
||||
@punctuation.bracket for `()` or `{}`
|
||||
@punctuation.special for symbols with special meaning like `{}` in string interpolation.
|
||||
```
|
||||
|
||||
#### Constants
|
||||
|
||||
```
|
||||
@constant
|
||||
@constant.builtin
|
||||
@constant.macro
|
||||
@string
|
||||
@string.regex
|
||||
@string.escape
|
||||
@string.special
|
||||
@character
|
||||
@character.special
|
||||
@number
|
||||
@boolean
|
||||
@float
|
||||
```
|
||||
|
||||
#### Functions
|
||||
|
||||
```
|
||||
@function
|
||||
@function.builtin
|
||||
@function.macro
|
||||
@parameter
|
||||
|
||||
@method
|
||||
@field
|
||||
@property
|
||||
|
||||
@constructor
|
||||
```
|
||||
|
||||
#### Keywords
|
||||
|
||||
```
|
||||
@conditional (e.g. `if`, `else`)
|
||||
@repeat (e.g. `for`, `while`)
|
||||
@label for C/Lua-like labels
|
||||
@keyword
|
||||
@keyword.function (keyword to define a function, e.g. `func` in Go, `def` in Python)
|
||||
@keyword.operator (for operators that are English words, e.g. `and`, `or`)
|
||||
@keyword.return
|
||||
@operator (for symbolic operators, e.g. `+`, `*`)
|
||||
@exception (e.g. `throw`, `catch`)
|
||||
@include keywords for including modules (e.g. import/from in Python)
|
||||
@storageclass
|
||||
|
||||
@type
|
||||
@type.builtin
|
||||
@type.definition
|
||||
@type.qualifier
|
||||
@namespace for identifiers referring to namespaces
|
||||
@symbol for identifiers referring to symbols
|
||||
@attribute for e.g. Python decorators
|
||||
```
|
||||
|
||||
@conceal followed by `(#set! conceal "")` for captures that are not used for highlights but only for concealing.
|
||||
|
||||
#### Variables
|
||||
|
||||
```
|
||||
@variable
|
||||
@variable.builtin
|
||||
```
|
||||
|
||||
#### Text
|
||||
|
||||
Mainly for markup languages.
|
||||
|
||||
```
|
||||
@text
|
||||
@text.strong
|
||||
@text.emphasis
|
||||
@text.underline
|
||||
@text.strike
|
||||
@text.title
|
||||
@text.literal
|
||||
@text.uri
|
||||
@text.math (e.g. for LaTeX math environments)
|
||||
@text.environment (e.g. for text environments of markup languages)
|
||||
@text.environment.name (e.g. for the name/the string indicating the type of text environment)
|
||||
@text.reference (for footnotes, text references, citations)
|
||||
|
||||
@text.note
|
||||
@text.warning
|
||||
@text.danger
|
||||
|
||||
@todo
|
||||
```
|
||||
|
||||
#### Tags
|
||||
|
||||
Used for xml-like tags
|
||||
|
||||
```
|
||||
@tag
|
||||
@tag.attribute
|
||||
@tag.delimiter
|
||||
```
|
||||
|
||||
#### Conceal
|
||||
|
||||
@conceal followed by `(#set! conceal "")` for captures that are not used for highlights but only for concealing.
|
||||
|
||||
### Locals
|
||||
|
||||
```
|
||||
@definition for various definitions
|
||||
@definition.constant
|
||||
@definition.function
|
||||
@definition.method
|
||||
@definition.var
|
||||
@definition.parameter
|
||||
@definition.macro
|
||||
@definition.type
|
||||
@definition.field
|
||||
@definition.enum
|
||||
@definition.namespace for modules or C++ namespaces
|
||||
@definition.import for imported names
|
||||
|
||||
@definition.associated to determine the type of a variable
|
||||
@definition.doc for documentation adjacent to a definition. E.g.
|
||||
|
||||
@scope
|
||||
@reference
|
||||
@constructor
|
||||
```
|
||||
|
||||
|
||||
#### Definition Scope
|
||||
|
||||
You can set the scope of a definition by setting the `scope` property on the definition.
|
||||
|
||||
For example, a javascript function declaration creates a scope. The function name is captured as the definition.
|
||||
This means that the function definition would only be available WITHIN the scope of the function, which is not the case.
|
||||
The definition can be used in the scope the function was defined in.
|
||||
|
||||
```javascript
|
||||
function doSomething() {}
|
||||
|
||||
doSomething(); // Should point to the declaration as the definition
|
||||
```
|
||||
|
||||
```query
|
||||
(function_declaration
|
||||
((identifier) @definition.var)
|
||||
(#set! "definition.var.scope" "parent"))
|
||||
```
|
||||
|
||||
Possible scope values are:
|
||||
|
||||
- `parent`: The definition is valid in the containing scope and one more scope above that scope
|
||||
- `global`: The definition is valid in the root scope
|
||||
- `local`: The definition is valid in the containing scope. This is the default behavior
|
||||
|
||||
### Folds
|
||||
|
||||
You can define folds for a given language by adding a `folds.scm` query :
|
||||
|
||||
```
|
||||
@fold
|
||||
```
|
||||
|
||||
If the `fold.scm` query is not present, this will fallback to the `@scope` captures in the `locals`
|
||||
query.
|
||||
|
||||
### Injections
|
||||
|
||||
Some captures are related to language injection (like markdown code blocks). They are used in `injections.scm`.
|
||||
You can directly use the name of the language that you want to inject (e.g. `@html` to inject html).
|
||||
|
||||
If you want to dynamically detect the language (e.g. for Markdown blocks) use the `@language` to capture
|
||||
the node describing the language and `@content` to describe the injection region.
|
||||
|
||||
```
|
||||
@{language} ; e.g. @html to describe a html region
|
||||
|
||||
@language ; dynamic detection of the injection language (i.e. the text of the captured node describes the language).
|
||||
@content ; region for the dynamically detected language.
|
||||
@combined ; This will combine all matches of a pattern as one single block of content.
|
||||
```
|
||||
|
||||
### Indents
|
||||
|
||||
```
|
||||
@indent ; Indent children when matching this node
|
||||
@indent_end ; Marks the end of indented block
|
||||
@aligned_indent ; Behaves like python aligned/hanging indent
|
||||
@dedent ; Dedent children when matching this node
|
||||
@branch ; Dedent itself when matching this node
|
||||
@ignore ; Do not indent in this node
|
||||
@auto ; Behaves like 'autoindent' buffer option
|
||||
@zero_indent ; Sets this node at position 0 (no indent)
|
||||
```
|
||||
|
||||
[Zulip]: https://nvim-treesitter.zulipchat.com
|
||||
[Matrix channel]: https://matrix.to/#/#nvim-treesitter:matrix.org
|
201
bundle/nvim-treesitter/LICENSE
Normal file
201
bundle/nvim-treesitter/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
569
bundle/nvim-treesitter/README.md
Normal file
569
bundle/nvim-treesitter/README.md
Normal file
@ -0,0 +1,569 @@
|
||||
<div align="center">
|
||||
<h1>nvim-treesitter</h1>
|
||||
<p>
|
||||
<a href="https://nvim-treesitter.zulipchat.com/">
|
||||
<img alt="Zulip Chat" src="https://img.shields.io/badge/zulip-join_chat-brightgreen.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/nvim-treesitter/nvim-treesitter/actions?query=workflow%3A%22Linting+and+style+checking%22+branch%3Amaster">
|
||||
<img alt="Linting and Style" src="https://github.com/nvim-treesitter/nvim-treesitter/workflows/Linting%20and%20style%20checking/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/nvim-treesitter/nvim-treesitter/actions?query=workflow%3A%22Check+loading+of+syntax+files%22+branch%3Amaster">
|
||||
<img alt="Syntax files" src="https://github.com/nvim-treesitter/nvim-treesitter/workflows/Check%20loading%20of%20syntax%20files/badge.svg" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<p>
|
||||
<img src="assets/logo.png" align="center" alt="Logo" />
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://github.com/tree-sitter/tree-sitter">Treesitter</a>
|
||||
configurations and abstraction layer for
|
||||
<a href="https://github.com/neovim/neovim/">Neovim</a>.
|
||||
</p>
|
||||
<p>
|
||||
<i>
|
||||
Logo by <a href="https://github.com/steelsojka">@steelsojka</a>
|
||||
</i>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
The goal of `nvim-treesitter` is both to provide a simple and easy way to use the interface for [tree-sitter](https://github.com/tree-sitter/tree-sitter) in Neovim and to provide some basic functionality such as highlighting based on it:
|
||||
|
||||
![cpp example](assets/example-cpp.png)
|
||||
|
||||
Traditional highlighting (left) vs Treesitter-based highlighting (right).
|
||||
More examples can be found in [our gallery](https://github.com/nvim-treesitter/nvim-treesitter/wiki/Gallery).
|
||||
|
||||
**Warning: Treesitter and nvim-treesitter highlighting are an experimental feature of Neovim.
|
||||
Please consider the experience with this plug-in as experimental until Tree-Sitter support in Neovim is stable!
|
||||
We recommend using the nightly builds of Neovim if possible.
|
||||
You can find the current roadmap [here](https://github.com/nvim-treesitter/nvim-treesitter/projects/1).
|
||||
The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated!**
|
||||
|
||||
Nvim-treesitter is based on three interlocking features: [**language parsers**](#language-parsers), [**queries**](#adding-queries), and [**modules**](#available-modules), where *modules* provide features – e.g., highlighting – based on *queries* for syntax objects extracted from a given buffer by *language parsers*.
|
||||
Users will generally only need to interact with parsers and modules as explained in the next section.
|
||||
For more detailed information on setting these up, see ["Advanced setup"](#advanced-setup).
|
||||
|
||||
---
|
||||
|
||||
### Table of contents
|
||||
|
||||
* [Quickstart](#quickstart)
|
||||
* [Supported languages](#supported-languages)
|
||||
* [Available modules](#available-modules)
|
||||
* [Advanced setup](#advanced-setup)
|
||||
* [Extra features](#extra-features)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
# Quickstart
|
||||
|
||||
## Requirements
|
||||
|
||||
- Neovim latest stable version or [nightly](https://github.com/neovim/neovim#install-from-source)
|
||||
- `tar` and `curl` in your path (or alternatively `git`)
|
||||
- A C compiler in your path and libstdc++ installed ([Windows users please read this!](https://github.com/nvim-treesitter/nvim-treesitter/wiki/Windows-support)).
|
||||
|
||||
## Installation
|
||||
|
||||
You can install `nvim-treesitter` with your favorite package manager (or using the native `package` feature of vim, see `:h packages`).
|
||||
|
||||
**NOTE: This plugin is only guaranteed to work with specific versions of language parsers** (as specified in the `lockfile.json`). **When upgrading the plugin, you must make sure that all installed parsers are updated to the latest version** via `:TSUpdate`.
|
||||
It is strongly recommended to automate this; e.g., if you are using [vim-plug](https://github.com/junegunn/vim-plug), put this in your `init.vim` file:
|
||||
|
||||
```vim
|
||||
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
|
||||
```
|
||||
|
||||
For other plugin managers such as `packer.nvim`, see this [Installation page from the wiki](https://github.com/nvim-treesitter/nvim-treesitter/wiki/Installation) (Note that this page is community maintained).
|
||||
|
||||
## Language parsers
|
||||
|
||||
Treesitter uses a different _parser_ for every language, which needs to be generated via `tree-sitter-cli` from a `grammar.js` file, then compiled to a `.so` library that needs to be placed in neovim's `runtimepath` (typically under `parser/{language}.so`).
|
||||
To simplify this, `nvim-treesitter` provides commands to automate this process.
|
||||
If the language is already [supported by `nvim-treesitter`](#supported-languages), you can install it with
|
||||
```vim
|
||||
:TSInstall <language_to_install>
|
||||
```
|
||||
This command supports tab expansion.
|
||||
You can also get a list of all available languages and their installation status with `:TSInstallInfo`.
|
||||
Parsers not on this list can be added manually by following the steps described under ["Adding parsers"](#adding-parsers) below.
|
||||
|
||||
To make sure a parser is at the latest compatible version (as specified in `nvim-treesitter`'s `lockfile.json`), use `:TSUpdate {language}`. To update all parsers unconditionally, use `:TSUpdate all` or just `:TSUpdate`.
|
||||
|
||||
## Modules
|
||||
|
||||
Each module provides a distinct tree-sitter-based feature such as [highlighting](#highlight), [indentation](#indentation), or [folding](#folding); see [`:h nvim-treesitter-modules`](doc/nvim-treesitter.txt) or ["Available modules"](#available-modules) below for a list of modules and their options.
|
||||
|
||||
Following examples assume that you are configuring neovim with lua. If you are using vimscript, see `:help lua-heredoc`.
|
||||
All modules are disabled by default and need to be activated explicitly in your `init.lua`, e.g., via
|
||||
|
||||
```lua
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
-- A list of parser names, or "all"
|
||||
ensure_installed = { "c", "lua", "rust" },
|
||||
|
||||
-- Install parsers synchronously (only applied to `ensure_installed`)
|
||||
sync_install = false,
|
||||
|
||||
-- List of parsers to ignore installing (for "all")
|
||||
ignore_install = { "javascript" },
|
||||
|
||||
highlight = {
|
||||
-- `false` will disable the whole extension
|
||||
enable = true,
|
||||
|
||||
-- NOTE: these are the names of the parsers and not the filetype. (for example if you want to
|
||||
disable highlighting for the `tex` filetype, you need to include `latex` in this list as this is
|
||||
the name of the parser)
|
||||
-- list of language that will be disabled
|
||||
disable = { "c", "rust" },
|
||||
|
||||
-- Setting this to true will run `:h syntax` and tree-sitter at the same time.
|
||||
-- Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
|
||||
-- Using this option may slow down your editor, and you may see some duplicate highlights.
|
||||
-- Instead of true it can also be a list of languages
|
||||
additional_vim_regex_highlighting = false,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Each module can also be enabled or disabled interactively through the following commands:
|
||||
|
||||
```vim
|
||||
:TSBufEnable {module} " enable module on current buffer
|
||||
:TSBufDisable {module} " disable module on current buffer
|
||||
:TSEnable {module} [{ft}] " enable module on every buffer. If filetype is specified, enable only for this filetype.
|
||||
:TSDisable {module} [{ft}] " disable module on every buffer. If filetype is specified, disable only for this filetype.
|
||||
:TSModuleInfo [{module}] " list information about modules state for each filetype
|
||||
```
|
||||
|
||||
Check [`:h nvim-treesitter-commands`](doc/nvim-treesitter.txt) for a list of all available commands.
|
||||
It may be necessary to reload the buffer (e.g., via `:e`) after enabling a module interactively.
|
||||
|
||||
# Supported languages
|
||||
|
||||
For `nvim-treesitter` to support a specific feature for a specific language requires both a parser for that language and an appropriate language-specific query file for that feature.
|
||||
|
||||
The following is a list of languages for which a parser can be installed through `:TSInstall`; a checked box means that `nvim-treesitter` also contains queries at least for the `highlight` module.
|
||||
|
||||
Experimental parsers are parsers that have a maintainer but are not stable enough for
|
||||
daily use yet.
|
||||
|
||||
We are looking for maintainers to add more parsers and to write query files for their languages. Check our [tracking issue](https://github.com/nvim-treesitter/nvim-treesitter/issues/2282) for open language requests.
|
||||
|
||||
<!--This section of the README is automatically updated by a CI job-->
|
||||
<!--parserinfo-->
|
||||
- [x] [astro](https://github.com/virchau13/tree-sitter-astro) (maintained by @virchau13)
|
||||
- [x] [bash](https://github.com/tree-sitter/tree-sitter-bash) (maintained by @TravonteD)
|
||||
- [x] [beancount](https://github.com/polarmutex/tree-sitter-beancount) (maintained by @polarmutex)
|
||||
- [x] [bibtex](https://github.com/latex-lsp/tree-sitter-bibtex) (maintained by @theHamsta, @clason)
|
||||
- [x] [c](https://github.com/tree-sitter/tree-sitter-c) (maintained by @vigoux)
|
||||
- [x] [c_sharp](https://github.com/tree-sitter/tree-sitter-c-sharp) (maintained by @Luxed)
|
||||
- [x] [clojure](https://github.com/sogaiu/tree-sitter-clojure) (maintained by @sogaiu)
|
||||
- [x] [cmake](https://github.com/uyha/tree-sitter-cmake) (maintained by @uyha)
|
||||
- [x] [comment](https://github.com/stsewd/tree-sitter-comment) (maintained by @stsewd)
|
||||
- [x] [commonlisp](https://github.com/theHamsta/tree-sitter-commonlisp) (maintained by @theHamsta)
|
||||
- [x] [cooklang](https://github.com/addcninblue/tree-sitter-cooklang) (maintained by @addcninblue)
|
||||
- [x] [cpp](https://github.com/tree-sitter/tree-sitter-cpp) (maintained by @theHamsta)
|
||||
- [x] [css](https://github.com/tree-sitter/tree-sitter-css) (maintained by @TravonteD)
|
||||
- [x] [cuda](https://github.com/theHamsta/tree-sitter-cuda) (maintained by @theHamsta)
|
||||
- [x] [d](https://github.com/CyberShadow/tree-sitter-d) (experimental, maintained by @nawordar)
|
||||
- [x] [dart](https://github.com/UserNobody14/tree-sitter-dart) (maintained by @Akin909)
|
||||
- [x] [devicetree](https://github.com/joelspadin/tree-sitter-devicetree) (maintained by @jedrzejboczar)
|
||||
- [x] [dockerfile](https://github.com/camdencheek/tree-sitter-dockerfile) (maintained by @camdencheek)
|
||||
- [x] [dot](https://github.com/rydesun/tree-sitter-dot) (maintained by @rydesun)
|
||||
- [x] [eex](https://github.com/connorlay/tree-sitter-eex) (maintained by @connorlay)
|
||||
- [x] [elixir](https://github.com/elixir-lang/tree-sitter-elixir) (maintained by @jonatanklosko, @connorlay)
|
||||
- [ ] [elm](https://github.com/elm-tooling/tree-sitter-elm)
|
||||
- [x] [elvish](https://github.com/ckafi/tree-sitter-elvish) (maintained by @ckafi)
|
||||
- [x] [erlang](https://github.com/AbstractMachinesLab/tree-sitter-erlang) (maintained by @ostera)
|
||||
- [x] [fennel](https://github.com/travonted/tree-sitter-fennel) (maintained by @TravonteD)
|
||||
- [x] [fish](https://github.com/ram02z/tree-sitter-fish) (maintained by @ram02z)
|
||||
- [x] [foam](https://github.com/FoamScience/tree-sitter-foam) (experimental, maintained by @FoamScience)
|
||||
- [ ] [fortran](https://github.com/stadelmanma/tree-sitter-fortran)
|
||||
- [x] [fusion](https://gitlab.com/jirgn/tree-sitter-fusion.git) (maintained by @jirgn)
|
||||
- [x] [Godot (gdscript)](https://github.com/PrestonKnopp/tree-sitter-gdscript) (maintained by @Shatur95)
|
||||
- [x] [gleam](https://github.com/J3RN/tree-sitter-gleam) (maintained by @connorlay)
|
||||
- [x] [Glimmer and Ember](https://github.com/alexlafroscia/tree-sitter-glimmer) (maintained by @alexlafroscia)
|
||||
- [x] [glsl](https://github.com/theHamsta/tree-sitter-glsl) (maintained by @theHamsta)
|
||||
- [x] [go](https://github.com/tree-sitter/tree-sitter-go) (maintained by @theHamsta, @WinWisely268)
|
||||
- [x] [Godot Resources (gdresource)](https://github.com/PrestonKnopp/tree-sitter-godot-resource) (maintained by @pierpo)
|
||||
- [x] [gomod](https://github.com/camdencheek/tree-sitter-go-mod) (maintained by @camdencheek)
|
||||
- [x] [gowork](https://github.com/omertuc/tree-sitter-go-work) (maintained by @omertuc)
|
||||
- [x] [graphql](https://github.com/bkegley/tree-sitter-graphql) (maintained by @bkegley)
|
||||
- [ ] [hack](https://github.com/slackhq/tree-sitter-hack)
|
||||
- [ ] [haskell](https://github.com/tree-sitter/tree-sitter-haskell)
|
||||
- [x] [hcl](https://github.com/MichaHoffmann/tree-sitter-hcl) (maintained by @MichaHoffmann)
|
||||
- [x] [heex](https://github.com/connorlay/tree-sitter-heex) (maintained by @connorlay)
|
||||
- [x] [help](https://github.com/vigoux/tree-sitter-vimdoc) (experimental, maintained by @vigoux)
|
||||
- [x] [hjson](https://github.com/winston0410/tree-sitter-hjson) (maintained by @winston0410)
|
||||
- [x] [hocon](https://github.com/antosha417/tree-sitter-hocon) (maintained by @antosha417)
|
||||
- [x] [html](https://github.com/tree-sitter/tree-sitter-html) (maintained by @TravonteD)
|
||||
- [x] [http](https://github.com/NTBBloodbath/tree-sitter-http) (maintained by @NTBBloodbath)
|
||||
- [x] [java](https://github.com/tree-sitter/tree-sitter-java) (maintained by @p00f)
|
||||
- [x] [javascript](https://github.com/tree-sitter/tree-sitter-javascript) (maintained by @steelsojka)
|
||||
- [x] [jsdoc](https://github.com/tree-sitter/tree-sitter-jsdoc) (maintained by @steelsojka)
|
||||
- [x] [json](https://github.com/tree-sitter/tree-sitter-json) (maintained by @steelsojka)
|
||||
- [x] [json5](https://github.com/Joakker/tree-sitter-json5) (maintained by @Joakker)
|
||||
- [x] [JSON with comments](https://gitlab.com/WhyNotHugo/tree-sitter-jsonc.git) (maintained by @WhyNotHugo)
|
||||
- [x] [julia](https://github.com/tree-sitter/tree-sitter-julia) (maintained by @mroavi, @theHamsta)
|
||||
- [x] [kotlin](https://github.com/fwcd/tree-sitter-kotlin) (maintained by @SalBakraa)
|
||||
- [x] [lalrpop](https://github.com/traxys/tree-sitter-lalrpop) (maintained by @traxys)
|
||||
- [x] [latex](https://github.com/latex-lsp/tree-sitter-latex) (maintained by @theHamsta, @clason)
|
||||
- [x] [ledger](https://github.com/cbarrete/tree-sitter-ledger) (maintained by @cbarrete)
|
||||
- [x] [llvm](https://github.com/benwilliamgraham/tree-sitter-llvm) (maintained by @benwilliamgraham)
|
||||
- [x] [lua](https://github.com/MunifTanjim/tree-sitter-lua) (maintained by @muniftanjim)
|
||||
- [x] [make](https://github.com/alemuller/tree-sitter-make) (maintained by @lewis6991)
|
||||
- [ ] [markdown](https://github.com/MDeiml/tree-sitter-markdown)
|
||||
- [x] [ninja](https://github.com/alemuller/tree-sitter-ninja) (maintained by @alemuller)
|
||||
- [x] [nix](https://github.com/cstrahan/tree-sitter-nix) (maintained by @leo60228)
|
||||
- [x] [norg](https://github.com/nvim-neorg/tree-sitter-norg) (maintained by @JoeyGrajciar, @vhyrro, @mrossinek)
|
||||
- [x] [ocaml](https://github.com/tree-sitter/tree-sitter-ocaml) (maintained by @undu)
|
||||
- [x] [ocaml_interface](https://github.com/tree-sitter/tree-sitter-ocaml) (maintained by @undu)
|
||||
- [x] [ocamllex](https://github.com/atom-ocaml/tree-sitter-ocamllex) (maintained by @undu)
|
||||
- [x] [pascal](https://github.com/Isopod/tree-sitter-pascal.git) (maintained by @isopod)
|
||||
- [x] [perl](https://github.com/ganezdragon/tree-sitter-perl) (maintained by @ganezdragon)
|
||||
- [x] [php](https://github.com/tree-sitter/tree-sitter-php) (maintained by @tk-shirasaka)
|
||||
- [x] [phpdoc](https://github.com/claytonrcarter/tree-sitter-phpdoc) (experimental, maintained by @mikehaertl)
|
||||
- [x] [pioasm](https://github.com/leo60228/tree-sitter-pioasm) (maintained by @leo60228)
|
||||
- [x] [prisma](https://github.com/victorhqc/tree-sitter-prisma) (maintained by @elianiva)
|
||||
- [x] [pug](https://github.com/zealot128/tree-sitter-pug) (maintained by @zealot128)
|
||||
- [x] [python](https://github.com/tree-sitter/tree-sitter-python) (maintained by @stsewd, @theHamsta)
|
||||
- [x] [ql](https://github.com/tree-sitter/tree-sitter-ql) (maintained by @pwntester)
|
||||
- [x] [Tree-sitter query language](https://github.com/nvim-treesitter/tree-sitter-query) (maintained by @steelsojka)
|
||||
- [x] [r](https://github.com/r-lib/tree-sitter-r) (maintained by @jimhester)
|
||||
- [x] [rasi](https://github.com/Fymyte/tree-sitter-rasi) (maintained by @Fymyte)
|
||||
- [x] [regex](https://github.com/tree-sitter/tree-sitter-regex) (maintained by @theHamsta)
|
||||
- [x] [rego](https://github.com/FallenAngel97/tree-sitter-rego) (maintained by @FallenAngel97)
|
||||
- [x] [rst](https://github.com/stsewd/tree-sitter-rst) (maintained by @stsewd)
|
||||
- [x] [ruby](https://github.com/tree-sitter/tree-sitter-ruby) (maintained by @TravonteD)
|
||||
- [x] [rust](https://github.com/tree-sitter/tree-sitter-rust) (maintained by @vigoux)
|
||||
- [x] [scala](https://github.com/tree-sitter/tree-sitter-scala) (maintained by @stevanmilic)
|
||||
- [x] [scheme](https://github.com/6cdh/tree-sitter-scheme) (maintained by @6cdh)
|
||||
- [x] [scss](https://github.com/serenadeai/tree-sitter-scss) (maintained by @elianiva)
|
||||
- [x] [slint](https://github.com/jrmoulton/tree-sitter-slint) (experimental, maintained by @jrmoulton)
|
||||
- [x] [solidity](https://github.com/YongJieYongJie/tree-sitter-solidity) (maintained by @YongJieYongJie)
|
||||
- [x] [sparql](https://github.com/BonaBeavis/tree-sitter-sparql) (maintained by @bonabeavis)
|
||||
- [x] [supercollider](https://github.com/madskjeldgaard/tree-sitter-supercollider) (maintained by @madskjeldgaard)
|
||||
- [x] [surface](https://github.com/connorlay/tree-sitter-surface) (maintained by @connorlay)
|
||||
- [x] [svelte](https://github.com/Himujjal/tree-sitter-svelte) (maintained by @elianiva)
|
||||
- [ ] [swift](https://github.com/alex-pinkus/tree-sitter-swift)
|
||||
- [x] [teal](https://github.com/euclidianAce/tree-sitter-teal) (maintained by @euclidianAce)
|
||||
- [x] [tlaplus](https://github.com/tlaplus-community/tree-sitter-tlaplus) (maintained by @ahelwer, @susliko)
|
||||
- [x] [todotxt](https://github.com/arnarg/tree-sitter-todotxt.git) (experimental, maintained by @arnarg)
|
||||
- [x] [toml](https://github.com/ikatyang/tree-sitter-toml) (maintained by @tk-shirasaka)
|
||||
- [x] [tsx](https://github.com/tree-sitter/tree-sitter-typescript) (maintained by @steelsojka)
|
||||
- [x] [turtle](https://github.com/BonaBeavis/tree-sitter-turtle) (maintained by @bonabeavis)
|
||||
- [x] [typescript](https://github.com/tree-sitter/tree-sitter-typescript) (maintained by @steelsojka)
|
||||
- [x] [vala](https://github.com/matbme/tree-sitter-vala) (maintained by @matbme)
|
||||
- [x] [verilog](https://github.com/tree-sitter/tree-sitter-verilog) (experimental, maintained by @zegervdv)
|
||||
- [x] [vim](https://github.com/vigoux/tree-sitter-viml) (maintained by @vigoux)
|
||||
- [x] [vue](https://github.com/ikatyang/tree-sitter-vue) (maintained by @WhyNotHugo)
|
||||
- [x] [wgsl](https://github.com/szebniok/tree-sitter-wgsl) (maintained by @szebniok)
|
||||
- [x] [yaml](https://github.com/ikatyang/tree-sitter-yaml) (maintained by @stsewd)
|
||||
- [x] [yang](https://github.com/Hubro/tree-sitter-yang) (maintained by @Hubro)
|
||||
- [x] [zig](https://github.com/maxxnino/tree-sitter-zig) (maintained by @maxxnino)
|
||||
<!--parserinfo-->
|
||||
|
||||
|
||||
# Available modules
|
||||
|
||||
Modules provide the top-level features of `nvim-treesitter`.
|
||||
The following is a list of modules included in `nvim-treesitter` and their configuration via `init.lua` (where multiple modules can be combined in a single call to `setup`).
|
||||
Note that not all modules work for all languages (depending on the queries available for them).
|
||||
Additional modules can be provided as [external plugins](https://github.com/nvim-treesitter/nvim-treesitter/wiki/Extra-modules-and-plugins).
|
||||
|
||||
#### Highlight
|
||||
|
||||
Consistent syntax highlighting.
|
||||
|
||||
```lua
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
highlight = {
|
||||
enable = true,
|
||||
-- Setting this to true will run `:h syntax` and tree-sitter at the same time.
|
||||
-- Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
|
||||
-- Using this option may slow down your editor, and you may see some duplicate highlights.
|
||||
-- Instead of true it can also be a list of languages
|
||||
additional_vim_regex_highlighting = false,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
You can add custom highlight captures with:
|
||||
|
||||
```vim
|
||||
lua <<EOF
|
||||
require"nvim-treesitter.highlight".set_custom_captures {
|
||||
-- Highlight the @foo.bar capture group with the "Identifier" highlight group.
|
||||
["foo.bar"] = "Identifier",
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Incremental selection
|
||||
|
||||
Incremental selection based on the named nodes from the grammar.
|
||||
|
||||
```lua
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
incremental_selection = {
|
||||
enable = true,
|
||||
keymaps = {
|
||||
init_selection = "gnn",
|
||||
node_incremental = "grn",
|
||||
scope_incremental = "grc",
|
||||
node_decremental = "grm",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
#### Indentation
|
||||
|
||||
Indentation based on treesitter for the `=` operator.
|
||||
**NOTE: This is an experimental feature**.
|
||||
|
||||
```lua
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
indent = {
|
||||
enable = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Folding
|
||||
|
||||
Tree-sitter based folding. *(Technically not a module because it's per windows and not per buffer.)*
|
||||
|
||||
```vim
|
||||
set foldmethod=expr
|
||||
set foldexpr=nvim_treesitter#foldexpr()
|
||||
```
|
||||
|
||||
This will respect your `foldminlines` and `foldnestmax` settings.
|
||||
|
||||
# Advanced setup
|
||||
|
||||
## Adding parsers
|
||||
|
||||
If you have a parser that is not on the list of supported languages (either as a repository on Github or in a local directory), you can add it manually for use by `nvim-treesitter` as follows:
|
||||
|
||||
1. Clone the repository or [create a new project](https://tree-sitter.github.io/tree-sitter/creating-parsers#project-setup) in, say, `~/projects/tree-sitter-zimbu`. Make sure that the `tree-sitter-cli` executable is installed and in your path; see <https://tree-sitter.github.io/tree-sitter/creating-parsers#installation> for installation instructions.
|
||||
2. Run `tree-sitter generate` in this directory (followed by `tree-sitter test` for good measure).
|
||||
3. Add the following snippet to your `init.lua`:
|
||||
|
||||
```lua
|
||||
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
|
||||
parser_config.zimbu = {
|
||||
install_info = {
|
||||
url = "~/projects/tree-sitter-zimbu", -- local path or git repo
|
||||
files = {"src/parser.c"},
|
||||
-- optional entries:
|
||||
branch = "main", -- default branch in case of git repo if different from master
|
||||
generate_requires_npm = false, -- if stand-alone parser without npm dependencies
|
||||
requires_generate_from_grammar = false, -- if folder contains pre-generated src/parser.c
|
||||
},
|
||||
filetype = "zu", -- if filetype does not match the parser name
|
||||
}
|
||||
```
|
||||
|
||||
If you wish to set a specific parser for a filetype, you should extend the `filetype_to_parsername` table:
|
||||
|
||||
```lua
|
||||
local ft_to_parser = require"nvim-treesitter.parsers".filetype_to_parsername
|
||||
ft_to_parser.someft = "python" -- the someft filetype will use the python parser and queries.
|
||||
```
|
||||
|
||||
4. Start `nvim` and `:TSInstall zimbu`.
|
||||
|
||||
You can also skip step 2 and use `:TSInstallFromGrammar zimbu` to install directly from a `grammar.js` in the top-level directory specified by `url`.
|
||||
Once the parser is installed, you can update it (from the latest revision of the `main` branch if `url` is a Github repository) with `:TSUpdate zimbu`.
|
||||
|
||||
Note that neither `:TSInstall` nor `:TSInstallFromGrammar` copy query files from the grammar repository.
|
||||
If you want your installed grammar to be useful, you must manually [add query files](#adding-queries) to your local nvim-treesitter installation.
|
||||
Note also that module functionality is only triggered if your language's filetype is correctly identified.
|
||||
If Neovim does not detect your language's filetype by default, you can use [Neovim's `vim.filetype.add()`](https://neovim.io/doc/user/lua.html#vim.filetype.add()) (0.7.0 and above) to add a custom detection rule.
|
||||
|
||||
If you use a git repository for your parser and want to use a specific version, you can set the `revision` key
|
||||
in the `install_info` table for you parser config.
|
||||
|
||||
## Adding queries
|
||||
|
||||
Queries are what `nvim-treesitter` uses to extract information from the syntax tree;
|
||||
they are located in the `queries/{language}/*` runtime directories (see `:h rtp`),
|
||||
like the `queries` folder of this plugin, e.g. `queries/{language}/{locals,highlights,textobjects}.scm`.
|
||||
Other modules may require additional queries such as `folding.scm`. You can find a
|
||||
list of all supported capture names in [CONTRIBUTING.md](https://github.com/nvim-treesitter/nvim-treesitter/blob/master/CONTRIBUTING.md#parser-configurations).
|
||||
|
||||
All queries found in the runtime directories will be combined.
|
||||
By convention, if you want to write a query, use the `queries/` directory,
|
||||
but if you want to extend a query use the `after/queries/` directory.
|
||||
|
||||
If you want to completely override a query, you can use `:h set_query()`.
|
||||
For example, to override the `injections` queries from `c` with your own:
|
||||
|
||||
```lua
|
||||
require("vim.treesitter.query").set_query("c", "injections", "(comment) @comment")
|
||||
```
|
||||
|
||||
Note: when using `set_query`, all queries in the runtime directories will be ignored.
|
||||
|
||||
## Adding modules
|
||||
|
||||
If you wish you write your own module, you need to support
|
||||
|
||||
- tree-sitter language detection support;
|
||||
- attaching and detaching to buffers;
|
||||
- all nvim-treesitter commands.
|
||||
|
||||
At the top level, you can use the `define_modules` function to define one or more modules or module groups:
|
||||
|
||||
```lua
|
||||
require'nvim-treesitter'.define_modules {
|
||||
my_cool_plugin = {
|
||||
attach = function(bufnr, lang)
|
||||
-- Do cool stuff here
|
||||
end,
|
||||
detach = function(bufnr)
|
||||
-- Undo cool stuff here
|
||||
end,
|
||||
is_supported = function(lang)
|
||||
-- Check if the language is supported
|
||||
end
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
with the following properties:
|
||||
|
||||
- `module_path` specifies a require path (string) that exports a module with an `attach` and `detach` function. This is not required if the functions are on this definition.
|
||||
- `enable` determines if the module is enabled by default. This is usually overridden by the user.
|
||||
- `disable` takes a list of languages that this module is disabled for. This is usually overridden by the user.
|
||||
- `is_supported` takes a function that takes a language and determines if this module supports that language.
|
||||
- `attach` takes a function that attaches to a buffer. This is required if `module_path` is not provided.
|
||||
- `detach` takes a function that detaches from a buffer. This is required if `module_path` is not provided.
|
||||
|
||||
# Extra features
|
||||
|
||||
### Statusline indicator
|
||||
|
||||
```vim
|
||||
echo nvim_treesitter#statusline(90) " 90 can be any length
|
||||
module->expression_statement->call->identifier
|
||||
```
|
||||
|
||||
### Utilities
|
||||
|
||||
You can get some utility functions with
|
||||
|
||||
```lua
|
||||
local ts_utils = require 'nvim-treesitter.ts_utils'
|
||||
```
|
||||
|
||||
Check [`:h nvim-treesitter-utils`](doc/nvim-treesitter.txt) for more information.
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
Before doing anything, make sure you have the latest version of this plugin and run `:checkhealth nvim_treesitter`.
|
||||
It can also help to update the parsers via `:TSUpdate`.
|
||||
|
||||
#### Feature `X` does not work for `{language}`...
|
||||
|
||||
First, check the `health#nvim_treesitter#check` and the `health#treesitter#check` sections of `:checkhealth` for any warning.
|
||||
If there is one, it's highly likely that this is the cause of the problem.
|
||||
|
||||
Next check the `## Parser/Features` subsection of the `health#nvim_treesitter#check` section of `:checkhealth` to ensure the desired module is enabled for your language.
|
||||
If not, you might be missing query files; see [Adding queries](#adding-queries).
|
||||
|
||||
Finally, ensure Neovim is correctly identifying your language's filetype using the `:echo &filetype` command while one of your language's files is open in Neovim.
|
||||
If not, add a short Vimscript file to nvim-treesitter's `ftdetect` runtime directory following [Neovim's documentation](https://neovim.io/doc/user/filetype.html#new-filetype) on filetype detection.
|
||||
You can also quickly & temporarily set the filetype for a single buffer with the `:set filetype=langname` command to test whether it fixes the problem.
|
||||
|
||||
If everything is okay, then it might be an actual error.
|
||||
In that case, feel free to [open an issue here](https://github.com/nvim-treesitter/nvim-treesitter/issues/new/choose).
|
||||
|
||||
#### I get `module 'vim.treesitter.query' not found`
|
||||
|
||||
Make sure you have the latest version of Neovim.
|
||||
|
||||
#### I get `Error detected while processing .../plugin/nvim-treesitter.vim` every time I open Neovim
|
||||
|
||||
This is probably due to a change in a parser's grammar or its queries.
|
||||
Try updating the parser that you suspect has changed (`:TSUpdate {language}`) or all of them (`:TSUpdate`).
|
||||
If the error persists after updating all parsers,
|
||||
please [open an issue](https://github.com/nvim-treesitter/nvim-treesitter/issues/new/choose).
|
||||
|
||||
#### I get `query error: invalid node type at position`
|
||||
|
||||
This could be due a query file outside this plugin using outdated nodes,
|
||||
or due to an outdated parser.
|
||||
|
||||
- Make sure you have the parsers up to date with `:TSUpdate`
|
||||
- Make sure you don't have more than one `parser` runtime directory.
|
||||
You can execute this command `:echo nvim_get_runtime_file('parser', v:true)` to find all runtime directories.
|
||||
If you get more than one path, remove the ones that are outside this plugin (`nvim-treesitter` directory),
|
||||
so the correct version of the parser is used.
|
||||
|
||||
#### I experience weird highlighting issues similar to [#78](https://github.com/nvim-treesitter/nvim-treesitter/issues/78)
|
||||
|
||||
This is a well known issue, which arises when the tree and the buffer have gotten out of sync.
|
||||
As this is an upstream issue, we don't have any definite fix.
|
||||
To get around this, you can force reparsing the buffer with
|
||||
|
||||
```vim
|
||||
:write | edit | TSBufEnable highlight
|
||||
```
|
||||
|
||||
This will save, restore and enable highlighting for the current buffer.
|
||||
|
||||
#### I experience bugs when using `nvim-treesitter`'s `foldexpr` similar to [#194](https://github.com/nvim-treesitter/nvim-treesitter/issues/194)
|
||||
|
||||
This might happen, and is known to happen, with `vim-clap`.
|
||||
To avoid these kind of errors, please use `setlocal` instead of `set` for the respective filetypes.
|
||||
|
||||
#### I run into errors like `module 'nvim-treesitter.configs' not found` at startup
|
||||
|
||||
This is because of `rtp` management in `nvim`, adding `packadd
|
||||
nvim-treesitter` should fix the issue.
|
||||
|
||||
#### I want to use Git instead of curl for downloading the parsers
|
||||
|
||||
In your Lua config:
|
||||
|
||||
```lua
|
||||
require("nvim-treesitter.install").prefer_git = true
|
||||
```
|
||||
|
||||
#### I want to use a HTTP proxy for downloading the parsers
|
||||
|
||||
You can either configure curl to use additional CLI arguments in your Lua config:
|
||||
```lua
|
||||
require("nvim-treesitter.install").command_extra_args = {
|
||||
curl = { "--proxy", "<proxy url>" },
|
||||
}
|
||||
```
|
||||
or you can configure git via `.gitconfig` and use git instead of curl
|
||||
|
||||
```lua
|
||||
require("nvim-treesitter.install").prefer_git = true
|
||||
```
|
||||
|
||||
#### I want to use a mirror instead of "https://github.com/"
|
||||
|
||||
In your Lua config:
|
||||
|
||||
```lua
|
||||
for _, config in pairs(require("nvim-treesitter.parsers").get_parser_configs()) do
|
||||
config.install_info.url = config.install_info.url:gsub("https://github.com/", "something else")
|
||||
end
|
||||
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
--
|
||||
--
|
||||
}
|
||||
```
|
1
bundle/nvim-treesitter/after/ftplugin/elixir.vim
Normal file
1
bundle/nvim-treesitter/after/ftplugin/elixir.vim
Normal file
@ -0,0 +1 @@
|
||||
setlocal commentstring=#\ %s
|
1
bundle/nvim-treesitter/after/ftplugin/graphql.vim
Normal file
1
bundle/nvim-treesitter/after/ftplugin/graphql.vim
Normal file
@ -0,0 +1 @@
|
||||
setlocal commentstring=#\ %s
|
1
bundle/nvim-treesitter/after/ftplugin/heex.vim
Normal file
1
bundle/nvim-treesitter/after/ftplugin/heex.vim
Normal file
@ -0,0 +1 @@
|
||||
setlocal commentstring=<%#\ %s\ %>
|
1
bundle/nvim-treesitter/after/ftplugin/query.vim
Normal file
1
bundle/nvim-treesitter/after/ftplugin/query.vim
Normal file
@ -0,0 +1 @@
|
||||
setlocal commentstring=;\ %s
|
1
bundle/nvim-treesitter/after/ftplugin/surface.vim
Normal file
1
bundle/nvim-treesitter/after/ftplugin/surface.vim
Normal file
@ -0,0 +1 @@
|
||||
setlocal commentstring={!--\ %s\ --}
|
BIN
bundle/nvim-treesitter/assets/example-cpp.png
Normal file
BIN
bundle/nvim-treesitter/assets/example-cpp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 854 KiB |
BIN
bundle/nvim-treesitter/assets/logo.png
Normal file
BIN
bundle/nvim-treesitter/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,3 @@
|
||||
function! health#nvim_treesitter#check()
|
||||
lua require 'nvim-treesitter.health'.check()
|
||||
endfunction
|
27
bundle/nvim-treesitter/autoload/nvim_treesitter.vim
Normal file
27
bundle/nvim-treesitter/autoload/nvim_treesitter.vim
Normal file
@ -0,0 +1,27 @@
|
||||
function! nvim_treesitter#statusline(...) abort
|
||||
return luaeval("require'nvim-treesitter'.statusline(_A)", get(a:, 1, {}))
|
||||
endfunction
|
||||
|
||||
function! nvim_treesitter#foldexpr() abort
|
||||
return luaeval(printf('require"nvim-treesitter.fold".get_fold_indic(%d)', v:lnum))
|
||||
endfunction
|
||||
|
||||
function! nvim_treesitter#installable_parsers(arglead, cmdline, cursorpos) abort
|
||||
return join(luaeval("require'nvim-treesitter.parsers'.available_parsers()") + ['all', 'maintained'], "\n")
|
||||
endfunction
|
||||
|
||||
function! nvim_treesitter#installed_parsers(arglead, cmdline, cursorpos) abort
|
||||
return join(luaeval("require'nvim-treesitter.info'.installed_parsers()") + ['all', 'maintained'], "\n")
|
||||
endfunction
|
||||
|
||||
function! nvim_treesitter#available_modules(arglead, cmdline, cursorpos) abort
|
||||
return join(luaeval("require'nvim-treesitter.configs'.available_modules()"), "\n")
|
||||
endfunction
|
||||
|
||||
function! nvim_treesitter#available_query_groups(arglead, cmdline, cursorpos) abort
|
||||
return join(luaeval("require'nvim-treesitter.query'.available_query_groups()"), "\n")
|
||||
endfunction
|
||||
|
||||
function! nvim_treesitter#indent() abort
|
||||
return luaeval(printf('require"nvim-treesitter.indent".get_indent(%d)', v:lnum))
|
||||
endfunction
|
775
bundle/nvim-treesitter/doc/nvim-treesitter.txt
Normal file
775
bundle/nvim-treesitter/doc/nvim-treesitter.txt
Normal file
@ -0,0 +1,775 @@
|
||||
*nvim-treesitter* Treesitter configurations and abstraction layer for Neovim.
|
||||
|
||||
Minimum version of neovim: nightly
|
||||
|
||||
Authors:
|
||||
Kiyan Yazdani <yazdani.kiyan@protonmail.com>
|
||||
Thomas Vigouroux <tomvig38@gmail.com>
|
||||
Stephan Seitz <stephan.seitz@fau.de>
|
||||
Steven Sojka <Steven.Sojka@tdameritrade.com>
|
||||
Santos Gallegos <stsewd@protonmail.com>
|
||||
https://github.com/nvim-treesitter/nvim-treesitter/graphs/contributors
|
||||
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
INTRODUCTION *nvim-treesitter-intro*
|
||||
|
||||
nvim-treesitter wraps the Neovim treesitter API to provide functionalities
|
||||
such as highlighting and incremental selection, and a command to easily
|
||||
install parsers.
|
||||
|
||||
==============================================================================
|
||||
QUICK START *nvim-treesitter-quickstart*
|
||||
|
||||
Install the parser for your language
|
||||
|
||||
>
|
||||
:TSInstall {language}
|
||||
<
|
||||
|
||||
To get a list of supported languages
|
||||
|
||||
>
|
||||
:TSInstallInfo
|
||||
<
|
||||
|
||||
By default, everything is disabled.
|
||||
To enable supported features, put this in your `init.lua` file:
|
||||
|
||||
>
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
-- A list of parser names, or "all"
|
||||
ensure_installed = { "c", "lua", "rust" },
|
||||
|
||||
-- Install parsers synchronously (only applied to `ensure_installed`)
|
||||
sync_install = false,
|
||||
|
||||
-- List of parsers to ignore installing (for "all")
|
||||
ignore_install = { "javascript" },
|
||||
|
||||
highlight = {
|
||||
-- `false` will disable the whole extension
|
||||
enable = true,
|
||||
|
||||
-- list of language that will be disabled
|
||||
disable = { "c", "rust" },
|
||||
|
||||
-- Setting this to true will run `:h syntax` and tree-sitter at the same time.
|
||||
-- Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
|
||||
-- Using this option may slow down your editor, and you may see some duplicate highlights.
|
||||
-- Instead of true it can also be a list of languages
|
||||
additional_vim_regex_highlighting = false,
|
||||
},
|
||||
}
|
||||
<
|
||||
|
||||
See |nvim-treesitter-modules| for a list of all available modules and its options.
|
||||
|
||||
==============================================================================
|
||||
MODULES *nvim-treesitter-modules*
|
||||
|
||||
|nvim-treesitter| provides several functionalities via modules (and submodules),
|
||||
each module makes use of the query files defined for each language,
|
||||
|
||||
All modules are disabled by default, and some provide default keymaps.
|
||||
Each module corresponds to an entry in the dictionary passed to the
|
||||
`nvim-treesitter.configs.setup` function, this should be in your `init.lua` file.
|
||||
|
||||
>
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
-- Modules and its options go here
|
||||
highlight = { enable = true },
|
||||
incremental_selection = { enable = true },
|
||||
textobjects = { enable = true },
|
||||
}
|
||||
<
|
||||
|
||||
All modules share some common options, like `enable` and `disable`.
|
||||
When `enable` is `true` this will enable the module for all supported languages,
|
||||
if you want to disable the module for some languages you can pass a list to the `disable` option.
|
||||
|
||||
>
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
highlight = {
|
||||
enable = true,
|
||||
disable = { "cpp", "lua" },
|
||||
},
|
||||
}
|
||||
<
|
||||
|
||||
For more fine-grained control, `disable` can also take a function and
|
||||
whenever it returns `true`, the module is disabled for that buffer.
|
||||
The function is called once when a module starts in a buffer and receives the
|
||||
language and buffer number as arguments:
|
||||
|
||||
>
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
highlight = {
|
||||
enable = true,
|
||||
disable = function(lang, bufnr) -- Disable in large C++ buffers
|
||||
return lang == "cpp" and vim.api.nvim_buf_line_count(bufnr) > 50000
|
||||
end,
|
||||
},
|
||||
}
|
||||
<
|
||||
|
||||
Options that define or accept a keymap use the same format you use to define
|
||||
keymaps in Neovim, so you can write keymaps as `gd`, `<space>a`, `<leader>a`
|
||||
`<C-a>` (control + a), `<A-n>` (alt + n), `<CR>` (enter), etc.
|
||||
|
||||
External plugins can provide their own modules with their own options,
|
||||
those can also be configured using the `nvim-treesitter.configs.setup`
|
||||
function.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
HIGHLIGHT *nvim-treesitter-highlight-mod*
|
||||
|
||||
Consistent syntax highlighting.
|
||||
|
||||
Query files: `highlights.scm`.
|
||||
Supported options:
|
||||
|
||||
- enable: `true` or `false`.
|
||||
- disable: list of languages.
|
||||
- additional_vim_regex_highlighting: `true` or `false`, or a list of languages.
|
||||
Set this to `true` if you depend on 'syntax' being enabled
|
||||
(like for indentation). Using this option may slow down your editor,
|
||||
and you may see some duplicate highlights.
|
||||
Defaults to `false`.
|
||||
|
||||
>
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
highlight = {
|
||||
enable = true,
|
||||
custom_captures = {
|
||||
-- Highlight the @foo.bar capture group with the "Identifier" highlight group.
|
||||
["foo.bar"] = "Identifier",
|
||||
},
|
||||
-- Setting this to true or a list of languages will run `:h syntax` and tree-sitter at the same time.
|
||||
additional_vim_regex_highlighting = false,
|
||||
},
|
||||
}
|
||||
<
|
||||
|
||||
You can also set custom highlight captures
|
||||
>
|
||||
lua <<EOF
|
||||
require"nvim-treesitter.highlight".set_custom_captures {
|
||||
-- Highlight the @foo.bar capture group with the "Identifier" highlight group.
|
||||
["foo.bar"] = "Identifier",
|
||||
}
|
||||
EOF
|
||||
<
|
||||
Note: The api is not stable yet.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
INCREMENTAL SELECTION *nvim-treesitter-incremental-selection-mod*
|
||||
|
||||
Incremental selection based on the named nodes from the grammar.
|
||||
|
||||
Query files: `locals.scm`.
|
||||
Supported options:
|
||||
- enable: `true` or `false`.
|
||||
- disable: list of languages.
|
||||
- keymaps:
|
||||
- init_selection: in normal mode, start incremental selection.
|
||||
Defaults to `gnn`.
|
||||
- node_incremental: in visual mode, increment to the upper named parent.
|
||||
Defaults to `grn`.
|
||||
- scope_incremental: in visual mode, increment to the upper scope
|
||||
(as defined in `locals.scm`). Defaults to `grc`.
|
||||
- node_decremental: in visual mode, decrement to the previous named node.
|
||||
Defaults to `grm`.
|
||||
|
||||
>
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
incremental_selection = {
|
||||
enable = true,
|
||||
keymaps = {
|
||||
init_selection = "gnn",
|
||||
node_incremental = "grn",
|
||||
scope_incremental = "grc",
|
||||
node_decremental = "grm",
|
||||
},
|
||||
},
|
||||
}
|
||||
<
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
INDENTATION *nvim-treesitter-indentation-mod*
|
||||
|
||||
Indentation based on treesitter for the |=| operator.
|
||||
NOTE: this is an experimental feature.
|
||||
|
||||
Query files: `indents.scm`.
|
||||
Supported options:
|
||||
- enable: `true` or `false`.
|
||||
- disable: list of languages.
|
||||
>
|
||||
require'nvim-treesitter.configs'.setup {
|
||||
indent = {
|
||||
enable = true
|
||||
},
|
||||
}
|
||||
<
|
||||
==============================================================================
|
||||
COMMANDS *nvim-treesitter-commands*
|
||||
|
||||
*:TSInstall*
|
||||
:TSInstall {language} ...~
|
||||
|
||||
Install one or more treesitter parsers.
|
||||
You can use |:TSInstall| `all` to install all parsers. Use |:TSInstall!| to
|
||||
force the reinstallation of already installed parsers.
|
||||
*:TSInstallSync*
|
||||
:TSInstallSync {language} ...~
|
||||
|
||||
Perform the |:TSInstall| operation synchronously.
|
||||
|
||||
*:TSInstallInfo*
|
||||
:TSInstallInfo~
|
||||
|
||||
List information about currently installed parsers
|
||||
|
||||
*:TSUpdate*
|
||||
:TSUpdate {language} ...~
|
||||
|
||||
Update the installed parser for one more {language} or all installed parsers
|
||||
if {language} is omitted. The specified parser is installed if it is not already
|
||||
installed.
|
||||
|
||||
*:TSUpdateSync*
|
||||
:TSUpdateSync {language} ...~
|
||||
|
||||
Perform the |:TSUpdate| operation synchronously.
|
||||
|
||||
*:TSUninstall*
|
||||
:TSUninstall {language} ...~
|
||||
|
||||
Deletes the parser for one or more {language}. You can use 'all' for language
|
||||
to uninstall all parsers.
|
||||
|
||||
*:TSBufEnable*
|
||||
:TSBufEnable {module}~
|
||||
|
||||
Enable {module} on the current buffer.
|
||||
A list of modules can be found at |:TSModuleInfo|
|
||||
|
||||
*:TSBufDisable*
|
||||
:TSBufDisable {module}~
|
||||
|
||||
Disable {module} on the current buffer.
|
||||
A list of modules can be found at |:TSModuleInfo|
|
||||
|
||||
*:TSBufToggle*
|
||||
:TSBufToggle {module}~
|
||||
|
||||
Toggle (enable if disabled, disable if enabled) {module} on the current
|
||||
buffer.
|
||||
A list of modules can be found at |:TSModuleInfo|
|
||||
|
||||
*:TSEnable*
|
||||
:TSEnable {module} [{language}]~
|
||||
|
||||
Enable {module} for the session.
|
||||
If {language} is specified, enable module for the session only for this
|
||||
particular language.
|
||||
A list of modules can be found at |:TSModuleInfo|
|
||||
A list of languages can be found at |:TSInstallInfo|
|
||||
|
||||
*:TSDisable*
|
||||
:TSDisable {module} [{language}]~
|
||||
|
||||
Disable {module} for the session.
|
||||
If {language} is specified, disable module for the session only for this
|
||||
particular language.
|
||||
A list of modules can be found at |:TSModuleInfo|
|
||||
A list of languages can be found at |:TSInstallInfo|
|
||||
|
||||
*:TSToggle*
|
||||
:TSToggle {module} [{language}]~
|
||||
|
||||
Toggle (enable if disabled, disable if enabled) {module} for the session.
|
||||
If {language} is specified, toggle module for the session only for this
|
||||
particular language.
|
||||
A list of modules can be found at |:TSModuleInfo|
|
||||
A list of languages can be found at |:TSInstallInfo|
|
||||
|
||||
*:TSModuleInfo*
|
||||
:TSModuleInfo [{module}]~
|
||||
|
||||
List the state for the given module or all modules for the current session in
|
||||
a new buffer.
|
||||
|
||||
These highlight groups are used by default:
|
||||
>
|
||||
highlight default TSModuleInfoGood guifg=LightGreen gui=bold
|
||||
highlight default TSModuleInfoBad guifg=Crimson
|
||||
highlight default link TSModuleInfoHeader Type
|
||||
highlight default link TSModuleInfoNamespace Statement
|
||||
highlight default link TSModuleInfoParser Identifier
|
||||
<
|
||||
|
||||
*:TSEditQuery*
|
||||
:TSEditQuery {query-group} [{lang}]~
|
||||
|
||||
Edit the query file for a {query-group} (e.g. highlights, locals) for given
|
||||
{lang}. If there are multiple the user is prompted to select one of them.
|
||||
If no such file exists, a buffer for a new file in the user's config directory
|
||||
is created. If {lang} is not specified, the language of the current buffer
|
||||
is used.
|
||||
|
||||
*:TSEditQueryUserAfter*
|
||||
:TSEditQueryUserAfter {query-group} [{lang}]~
|
||||
|
||||
Same as |:TSEditQuery| but edits a file in the `after` directory of the
|
||||
user's config directory. Useful to add custom extensions for the queries
|
||||
provided by a plugin.
|
||||
|
||||
==============================================================================
|
||||
UTILS *nvim-treesitter-utils*
|
||||
|
||||
Nvim treesitter has some wrapper functions that you can retrieve with:
|
||||
>
|
||||
local ts_utils = require 'nvim-treesitter.ts_utils'
|
||||
<
|
||||
Methods
|
||||
*ts_utils.get_node_at_cursor*
|
||||
get_node_at_cursor(winnr)~
|
||||
|
||||
`winnr` will be 0 if nil.
|
||||
Returns the node under the cursor.
|
||||
|
||||
*ts_utils.get_node_text*
|
||||
get_node_text(node, bufnr)~
|
||||
|
||||
Returns the text content of a `node`.
|
||||
|
||||
*ts_utils.is_parent*
|
||||
is_parent(dest, source)~
|
||||
|
||||
Determines whether `dest` is a parent of `source`.
|
||||
Returns a boolean.
|
||||
|
||||
*ts_utils.get_named_children*
|
||||
get_named_children(node)~
|
||||
|
||||
Returns a table of named children of `node`.
|
||||
|
||||
*ts_utils.get_next_node*
|
||||
get_next_node(node, allow_switch_parent, allow_next_parent)~
|
||||
|
||||
Returns the next node within the same parent.
|
||||
If no node is found, returns `nil`.
|
||||
If `allow_switch_parent` is true, it will allow switching parent
|
||||
when the node is the last node.
|
||||
If `allow_next_parent` is true, it will allow next parent if
|
||||
the node is the last node and the next parent doesn't have children.
|
||||
|
||||
*ts_utils.get_previous_node*
|
||||
get_previous_node(node, allow_switch_parents, allow_prev_parent)~
|
||||
|
||||
Returns the previous node within the same parent.
|
||||
`allow_switch_parent` and `allow_prev_parent` follow the same rule
|
||||
as |ts_utils.get_next_node| but if the node is the first node.
|
||||
|
||||
*ts_utils.goto_node*
|
||||
goto_node(node, goto_end, avoid_set_jump)~
|
||||
|
||||
Sets cursor to the position of `node` in the current windows.
|
||||
If `goto_end` is truthy, the cursor is set to the end the node range.
|
||||
Setting `avoid_set_jump` to `true`, avoids setting the current cursor position
|
||||
to the jump list.
|
||||
|
||||
*ts_utils.swap_nodes*
|
||||
swap_nodes(node_or_range1, node_or_range2, bufnr, cursor_to_second)~
|
||||
|
||||
Swaps the nodes or ranges.
|
||||
set `cursor_to_second` to true to move the cursor to the second node
|
||||
|
||||
*ts_utils.memoize_by_buf_tick*
|
||||
memoize_by_buf_tick(fn, options)~
|
||||
|
||||
Caches the return value for a function and returns the cache value if the tick
|
||||
of the buffer has not changed from the previous.
|
||||
|
||||
`fn`: a function that takes any arguments
|
||||
and returns a value to store.
|
||||
`options?`: <table>
|
||||
- `bufnr`: a function/value that extracts the bufnr from the given arguments.
|
||||
- `key`: a function/value that extracts the cache key from the given arguments.
|
||||
`returns`: a function to call with bufnr as argument to
|
||||
retrieve the value from the cache
|
||||
|
||||
*ts_utils.node_to_lsp_range*
|
||||
node_to_lsp_range(node)~
|
||||
|
||||
Get an lsp formatted range from a node range
|
||||
|
||||
*ts_utils.get_node_range*
|
||||
get_node_range(node_or_range)~
|
||||
|
||||
Get the range from either a node or a range
|
||||
|
||||
*ts_utils.node_length*
|
||||
node_length(node)~
|
||||
|
||||
Get the byte length of node range
|
||||
|
||||
*ts_utils.update_selection*
|
||||
update_selection(buf, node)~
|
||||
|
||||
Set the selection to the node range
|
||||
|
||||
*ts_utils.highlight_range*
|
||||
highlight_range(range, buf, hl_namespace, hl_group)~
|
||||
|
||||
Set a highlight that spans the given range
|
||||
|
||||
*ts_utils.highlight_node*
|
||||
highlight_node(node, buf, hl_namespace, hl_group)~
|
||||
|
||||
Set a highlight that spans the given node's range
|
||||
|
||||
==============================================================================
|
||||
FUNCTIONS *nvim-treesitter-functions*
|
||||
|
||||
*nvim_treesitter#statusline()*
|
||||
nvim_treesitter#statusline(opts)~
|
||||
|
||||
Returns a string describing the current position in the file. This
|
||||
could be used as a statusline indicator.
|
||||
Default options (lua syntax):
|
||||
>
|
||||
{
|
||||
indicator_size = 100,
|
||||
type_patterns = {'class', 'function', 'method'},
|
||||
transform_fn = function(line) return line:gsub('%s*[%[%(%{]*%s*$', '') end,
|
||||
separator = ' -> '
|
||||
}
|
||||
<
|
||||
- `indicator_size` - How long should the string be. If longer, it is cut from
|
||||
the beginning.
|
||||
- `type_patterns` - Which node type patterns to match.
|
||||
- `transform_fn` - Function used to transform the single item in line. By
|
||||
default removes opening brackets and spaces from end.
|
||||
- `separator` - Separator between nodes.
|
||||
|
||||
*nvim_treesitter#foldexpr()*
|
||||
nvim_treesitter#foldexpr()~
|
||||
|
||||
Functions to be used to determine the fold level at a given line number.
|
||||
To use it: >
|
||||
set foldmethod=expr
|
||||
set foldexpr=nvim_treesitter#foldexpr()
|
||||
<
|
||||
|
||||
This will respect your 'foldminlines' and 'foldnestmax' settings.
|
||||
|
||||
Note: This is highly experimental, and folding can break on some types of
|
||||
edits. If you encounter such breakage, hiting `zx` should fix folding.
|
||||
In any case, feel free to open an issue with the reproducing steps.
|
||||
|
||||
==============================================================================
|
||||
HIGHLIGHTS *nvim-treesitter-highlights*
|
||||
|
||||
The following is a list of highlights groups, the syntactic elements they
|
||||
apply to, and some examples.
|
||||
|
||||
*hl-TSAttribute*
|
||||
`TSAttribute`
|
||||
Annotations that can be attached to the code to denote some kind of meta
|
||||
information. e.g. C++/Dart attributes.
|
||||
|
||||
*hl-TSBoolean*
|
||||
`TSBoolean`
|
||||
Boolean literals: `True` and `False` in Python.
|
||||
|
||||
*hl-TSCharacter*
|
||||
`TSCharacter`
|
||||
Character literals: `'a'` in C.
|
||||
|
||||
*hl-TSCharacterSpecial*
|
||||
`TSCharacterSpecial`
|
||||
Special characters.
|
||||
|
||||
*hl-TSComment*
|
||||
`TSComment`
|
||||
Line comments and block comments.
|
||||
|
||||
*hl-TSConditional*
|
||||
`TSConditional`
|
||||
Keywords related to conditionals: `if`, `when`, `cond`, etc.
|
||||
|
||||
*hl-TSConstant*
|
||||
`TSConstant`
|
||||
Constants identifiers. These might not be semantically constant.
|
||||
E.g. uppercase variables in Python.
|
||||
|
||||
*hl-TSConstBuiltin*
|
||||
`TSConstBuiltin`
|
||||
Built-in constant values: `nil` in Lua.
|
||||
|
||||
*hl-TSConstMacro*
|
||||
`TSConstMacro`
|
||||
Constants defined by macros: `NULL` in C.
|
||||
|
||||
*hl-TSConstructor*
|
||||
`TSConstructor`
|
||||
Constructor calls and definitions: `{}` in Lua, and Java constructors.
|
||||
|
||||
*hl-TSDebug*
|
||||
`TSDebug`
|
||||
Debugging statements.
|
||||
|
||||
*hl-TSDefine*
|
||||
`TSDefine`
|
||||
Preprocessor #define statements.
|
||||
|
||||
*hl-TSError*
|
||||
`TSError`
|
||||
Syntax/parser errors. This might highlight large sections of code while the
|
||||
user is typing still incomplete code, use a sensible highlight.
|
||||
|
||||
*hl-TSException*
|
||||
`TSException`
|
||||
Exception related keywords: `try`, `except`, `finally` in Python.
|
||||
|
||||
*hl-TSField*
|
||||
`TSField`
|
||||
Object and struct fields.
|
||||
|
||||
*hl-TSFloat*
|
||||
`TSFloat`
|
||||
Floating-point number literals.
|
||||
|
||||
*hl-TSFunction*
|
||||
`TSFunction`
|
||||
Function calls and definitions.
|
||||
|
||||
*hl-TSFuncBuiltin*
|
||||
`TSFuncBuiltin`
|
||||
Built-in functions: `print` in Lua.
|
||||
|
||||
*hl-TSFuncMacro*
|
||||
`TSFuncMacro`
|
||||
Macro defined functions (calls and definitions): each `macro_rules` in
|
||||
Rust.
|
||||
|
||||
*hl-TSInclude*
|
||||
`TSInclude`
|
||||
File or module inclusion keywords: `#include` in C, `use` or `extern crate` in
|
||||
Rust.
|
||||
|
||||
*hl-TSKeyword*
|
||||
`TSKeyword`
|
||||
Keywords that don't fit into other categories.
|
||||
|
||||
*hl-TSKeywordFunction*
|
||||
`TSKeywordFunction`
|
||||
Keywords used to define a function: `function` in Lua, `def` and `lambda` in
|
||||
Python.
|
||||
|
||||
*hl-TSKeywordOperator*
|
||||
`TSKeywordOperator`
|
||||
Unary and binary operators that are English words: `and`, `or` in Python;
|
||||
`sizeof` in C.
|
||||
|
||||
*hl-TSKeywordReturn*
|
||||
`TSKeywordReturn`
|
||||
Keywords like `return` and `yield`.
|
||||
|
||||
*hl-TSLabel*
|
||||
`TSLabel`
|
||||
GOTO labels: `label:` in C, and `::label::` in Lua.
|
||||
|
||||
*hl-TSMethod*
|
||||
`TSMethod`
|
||||
Method calls and definitions.
|
||||
|
||||
*hl-TSNamespace*
|
||||
`TSNamespace`
|
||||
Identifiers referring to modules and namespaces.
|
||||
|
||||
*hl-None*
|
||||
`TSNone`
|
||||
No highlighting (sets all highlight arguments to `NONE`). this group is used
|
||||
to clear certain ranges, for example, string interpolations. Don't change the
|
||||
values of this highlight group.
|
||||
|
||||
*hl-TSNumber*
|
||||
`TSNumber`
|
||||
Numeric literals that don't fit into other categories.
|
||||
|
||||
*hl-TSOperator*
|
||||
`TSOperator`
|
||||
Binary or unary operators: `+`, and also `->` and `*` in C.
|
||||
|
||||
*hl-TSParameter*
|
||||
`TSParameter`
|
||||
Parameters of a function.
|
||||
|
||||
*hl-TSParameterReference*
|
||||
`TSParameterReference`
|
||||
References to parameters of a function.
|
||||
|
||||
*hl-TSPreProc*
|
||||
`TSPreProc`
|
||||
Preprocessor #if, #else, #endif, etc.
|
||||
|
||||
*hl-TSProperty*
|
||||
`TSProperty`
|
||||
Same as `TSField`.
|
||||
|
||||
*hl-TSPunctDelimiter*
|
||||
`TSPunctDelimiter`
|
||||
Punctuation delimiters: Periods, commas, semicolons, etc.
|
||||
|
||||
*hl-TSPunctBracket*
|
||||
`TSPunctBracket`
|
||||
Brackets, braces, parentheses, etc.
|
||||
|
||||
*hl-TSPunctSpecial*
|
||||
`TSPunctSpecial`
|
||||
Special punctuation that doesn't fit into the previous categories.
|
||||
|
||||
*hl-TSRepeat*
|
||||
`TSRepeat`
|
||||
Keywords related to loops: `for`, `while`, etc.
|
||||
|
||||
*hl-StorageClass*
|
||||
`TSStorageClass`
|
||||
Keywords that affect how a variable is stored: `static`, `comptime`, `extern`,
|
||||
etc.
|
||||
|
||||
*hl-TSString*
|
||||
`TSString`
|
||||
String literals.
|
||||
|
||||
*hl-TSStringRegex*
|
||||
`TSStringRegex`
|
||||
Regular expression literals.
|
||||
|
||||
*hl-TSStringEscape*
|
||||
`TSStringEscape`
|
||||
Escape characters within a string: `\n`, `\t`, etc.
|
||||
|
||||
*hl-TSStringSpecial*
|
||||
`TSStringSpecial`
|
||||
Strings with special meaning that don't fit into the previous categories.
|
||||
|
||||
*hl-TSSymbol*
|
||||
`TSSymbol`
|
||||
Identifiers referring to symbols or atoms.
|
||||
|
||||
*hl-TSTag*
|
||||
`TSTag`
|
||||
Tags like HTML tag names.
|
||||
|
||||
*hl-TSTagAttribute*
|
||||
`TSTagAttribute`
|
||||
HTML tag attributes.
|
||||
|
||||
*hl-TSTagDelimiter*
|
||||
`TSTagDelimiter`
|
||||
Tag delimiters like `<` `>` `/`.
|
||||
|
||||
*hl-TSText*
|
||||
`TSText`
|
||||
Non-structured text. Like text in a markup language.
|
||||
|
||||
*hl-TSSTrong*
|
||||
`TSStrong`
|
||||
Text to be represented in bold.
|
||||
|
||||
*hl-TSEmphasis*
|
||||
`TSEmphasis`
|
||||
Text to be represented with emphasis.
|
||||
|
||||
*hl-TSUnderline*
|
||||
`TSUnderline`
|
||||
Text to be represented with an underline.
|
||||
|
||||
*hl-TSStrike*
|
||||
`TSStrike`
|
||||
Strikethrough text.
|
||||
|
||||
*hl-TSTitle*
|
||||
`TSTitle`
|
||||
Text that is part of a title.
|
||||
|
||||
*hl-TSLiteral*
|
||||
`TSLiteral`
|
||||
Literal or verbatim text.
|
||||
|
||||
*hl-TSURI*
|
||||
`TSURI`
|
||||
URIs like hyperlinks or email addresses.
|
||||
|
||||
*hl-TSMath*
|
||||
`TSMath`
|
||||
Math environments like LaTeX's `$ ... $`
|
||||
|
||||
*hl-TSTextReference*
|
||||
`TSTextReference`
|
||||
Footnotes, text references, citations, etc.
|
||||
|
||||
*hl-TSEnvironment*
|
||||
`TSEnvironment`
|
||||
Text environments of markup languages.
|
||||
|
||||
*hl-TSEnvironmentName*
|
||||
`TSEnvironmentName`
|
||||
Text/string indicating the type of text environment. Like the name of a
|
||||
`\begin` block in LaTeX.
|
||||
|
||||
*hl-TSNote*
|
||||
`TSNote`
|
||||
Text representation of an informational note.
|
||||
|
||||
*TSWarning*
|
||||
`TSWarning`
|
||||
Text representation of a warning note.
|
||||
|
||||
*TSDanger*
|
||||
`TSDanger`
|
||||
Text representation of a danger note.
|
||||
|
||||
*hl-TSTodo*
|
||||
`TSTodo`
|
||||
Anything that needs extra attention, such as keywords like TODO or FIXME.
|
||||
|
||||
*hl-TSType*
|
||||
`TSType`
|
||||
Type (and class) definitions and annotations.
|
||||
|
||||
*hl-TSTypeBuiltin*
|
||||
`TSTypeBuiltin`
|
||||
Built-in types: `i32` in Rust.
|
||||
|
||||
*hl-TSTypeQualifier*
|
||||
`TSTypeQualifier`
|
||||
Qualifiers on types, e.g. `const` or `volatile` in C or `mut` in Rust.
|
||||
|
||||
*hl-TSTypeDefinition*
|
||||
`TSTypeDefinition`
|
||||
Type definitions, e.g. `typedef` in C.
|
||||
|
||||
*hl-TSVariable*
|
||||
`TSVariable`
|
||||
Variable names that don't fit into other categories.
|
||||
|
||||
*hl-TSVariableBuiltin*
|
||||
`TSVariableBuiltin`
|
||||
Variable names defined by the language: `this` or `self` in Javascript.
|
||||
|
||||
==============================================================================
|
||||
PERFORMANCE *nvim-treesitter-performance*
|
||||
|
||||
`nvim-treesitter` checks the 'runtimepath' on startup in order to discover
|
||||
available parsers and queries and index them. As a consequence, a very long
|
||||
'runtimepath' might result in delayed startup times.
|
||||
|
||||
|
||||
vim:tw=78:ts=8:expandtab:noet:ft=help:norl:
|
1
bundle/nvim-treesitter/ftdetect/cooklang.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/cooklang.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.cook set filetype=cooklang
|
1
bundle/nvim-treesitter/ftdetect/fusion.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/fusion.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.fusion setfiletype fusion
|
2
bundle/nvim-treesitter/ftdetect/gdresource.vim
Normal file
2
bundle/nvim-treesitter/ftdetect/gdresource.vim
Normal file
@ -0,0 +1,2 @@
|
||||
autocmd BufRead,BufNewFile *.tscn setlocal ft=gdresource
|
||||
autocmd BufRead,BufNewFile *.tres setlocal ft=gdresource
|
1
bundle/nvim-treesitter/ftdetect/gdscript.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/gdscript.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.gd set ft=gdscript
|
1
bundle/nvim-treesitter/ftdetect/glimmer.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/glimmer.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.hbs set ft=handlebars
|
1
bundle/nvim-treesitter/ftdetect/glsl.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/glsl.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.glsl set filetype=glsl
|
1
bundle/nvim-treesitter/ftdetect/gowork.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/gowork.vim
Normal file
@ -0,0 +1 @@
|
||||
au BufRead,BufNewFile go.work set filetype=gowork
|
1
bundle/nvim-treesitter/ftdetect/graphql.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/graphql.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.graphql,*.graphqls,*.gql setfiletype graphql
|
1
bundle/nvim-treesitter/ftdetect/hack.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/hack.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.hack,*.hackpartial setfiletype hack
|
2
bundle/nvim-treesitter/ftdetect/hcl.vim
Normal file
2
bundle/nvim-treesitter/ftdetect/hcl.vim
Normal file
@ -0,0 +1,2 @@
|
||||
autocmd BufRead,BufNewFile *.hcl set filetype=hcl
|
||||
autocmd BufRead,BufNewFile *.tf,*.tfvars set filetype=terraform
|
1
bundle/nvim-treesitter/ftdetect/heex.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/heex.vim
Normal file
@ -0,0 +1 @@
|
||||
au BufRead,BufNewFile *.heex set filetype=heex
|
1
bundle/nvim-treesitter/ftdetect/hjson.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/hjson.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.hjson set filetype=hjson
|
1
bundle/nvim-treesitter/ftdetect/json5.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/json5.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.json5 set ft=json5
|
1
bundle/nvim-treesitter/ftdetect/ledger.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/ledger.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.ldg,*.ledger,*.journal setfiletype ledger
|
1
bundle/nvim-treesitter/ftdetect/nix.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/nix.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.nix setfiletype nix
|
1
bundle/nvim-treesitter/ftdetect/prisma.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/prisma.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.prisma set filetype=prisma
|
1
bundle/nvim-treesitter/ftdetect/pug.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/pug.vim
Normal file
@ -0,0 +1 @@
|
||||
au BufRead,BufNewFile *.pug setlocal filetype=pug
|
1
bundle/nvim-treesitter/ftdetect/ql.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/ql.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.ql,*.qll setfiletype ql
|
11
bundle/nvim-treesitter/ftdetect/query.vim
Normal file
11
bundle/nvim-treesitter/ftdetect/query.vim
Normal file
@ -0,0 +1,11 @@
|
||||
" Last Change: 2020 Sep 01
|
||||
|
||||
function! s:shouldFt(path)
|
||||
let l:q_dir = fnamemodify(a:path, ":p:h:h:t")
|
||||
|
||||
if l:q_dir =~? "queries"
|
||||
setlocal ft=query
|
||||
endif
|
||||
endfunction
|
||||
|
||||
autocmd BufNewFile,BufRead *.scm call s:shouldFt(expand("%"))
|
1
bundle/nvim-treesitter/ftdetect/surface.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/surface.vim
Normal file
@ -0,0 +1 @@
|
||||
au BufRead,BufNewFile *.sface set filetype=surface
|
1
bundle/nvim-treesitter/ftdetect/teal.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/teal.vim
Normal file
@ -0,0 +1 @@
|
||||
autocmd BufRead,BufNewFile *.tl setfiletype teal
|
1
bundle/nvim-treesitter/ftdetect/tlaplus.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/tlaplus.vim
Normal file
@ -0,0 +1 @@
|
||||
au BufRead,BufNewFile *.tla set filetype=tla
|
1
bundle/nvim-treesitter/ftdetect/yang.vim
Normal file
1
bundle/nvim-treesitter/ftdetect/yang.vim
Normal file
@ -0,0 +1 @@
|
||||
au BufRead,BufNewFile *.yang set filetype=yang
|
332
bundle/nvim-treesitter/lockfile.json
Normal file
332
bundle/nvim-treesitter/lockfile.json
Normal file
@ -0,0 +1,332 @@
|
||||
{
|
||||
"astro": {
|
||||
"revision": "6602ccbf9a5f79845dad62f1e118e07f97e3533c"
|
||||
},
|
||||
"bash": {
|
||||
"revision": "275effdfc0edce774acf7d481f9ea195c6c403cd"
|
||||
},
|
||||
"beancount": {
|
||||
"revision": "78b8ddca3ab774573a4e3bf64eabd79e9452cea9"
|
||||
},
|
||||
"bibtex": {
|
||||
"revision": "ccfd77db0ed799b6c22c214fe9d2937f47bc8b34"
|
||||
},
|
||||
"c": {
|
||||
"revision": "e348e8ec5efd3aac020020e4af53d2ff18f393a9"
|
||||
},
|
||||
"c_sharp": {
|
||||
"revision": "5b6ae1f88e741b9ed738891ad1362fb9f2041671"
|
||||
},
|
||||
"clojure": {
|
||||
"revision": "879f0e726295807d917d576fcf9e1e432c4c20fc"
|
||||
},
|
||||
"cmake": {
|
||||
"revision": "5020572408a386d5d2dfac3516584f5edda7a49b"
|
||||
},
|
||||
"comment": {
|
||||
"revision": "a37ca370310ac6f89b6e0ebf2b86b2219780494e"
|
||||
},
|
||||
"commonlisp": {
|
||||
"revision": "c7e814975ab0d0d04333d1f32391c41180c58919"
|
||||
},
|
||||
"cooklang": {
|
||||
"revision": "5e113412aadb78955c27010daa4dbe1d202013cf"
|
||||
},
|
||||
"cpp": {
|
||||
"revision": "a832195eb3685a279856bb480ce19cff19554b6d"
|
||||
},
|
||||
"css": {
|
||||
"revision": "a03f1d2d1dfbf6f8e0fdca5f9ff030228241eb57"
|
||||
},
|
||||
"cuda": {
|
||||
"revision": "5178a7a5b25dc7ee4a69bf72f31bd6d3ff0a0795"
|
||||
},
|
||||
"d": {
|
||||
"revision": "c2fbf21bd3aa45495fe13247e040ad5815250032"
|
||||
},
|
||||
"dart": {
|
||||
"revision": "6a25376685d1d47968c2cef06d4db8d84a70025e"
|
||||
},
|
||||
"devicetree": {
|
||||
"revision": "877adbfa0174d25894c40fa75ad52d4515a36368"
|
||||
},
|
||||
"dockerfile": {
|
||||
"revision": "25c71d6a24cdba8f0c74ef40d4d2d93defd7e196"
|
||||
},
|
||||
"dot": {
|
||||
"revision": "917230743aa10f45a408fea2ddb54bbbf5fbe7b7"
|
||||
},
|
||||
"eex": {
|
||||
"revision": "f742f2fe327463335e8671a87c0b9b396905d1d1"
|
||||
},
|
||||
"elixir": {
|
||||
"revision": "1dabc1c790e07115175057863808085ea60dd08a"
|
||||
},
|
||||
"elm": {
|
||||
"revision": "9835f900e4df40277f0701d1bc0b6cee0853f81b"
|
||||
},
|
||||
"elvish": {
|
||||
"revision": "e50787cadd3bc54f6d9c0704493a79078bb8a4e5"
|
||||
},
|
||||
"erlang": {
|
||||
"revision": "fab680273af1a8f5cc0c3a0c62cbf5b1bea71f39"
|
||||
},
|
||||
"fennel": {
|
||||
"revision": "d37fd84a702b78ff0282f223ece83c61ab062a6e"
|
||||
},
|
||||
"fish": {
|
||||
"revision": "d482d70ea8e191c05b2c1b613ed6fdff30a14da0"
|
||||
},
|
||||
"foam": {
|
||||
"revision": "fdb7f14b885abfc4df57728c9b2a2f2ad24d3cb7"
|
||||
},
|
||||
"fortran": {
|
||||
"revision": "f0f2f100952a353e64e26b0fa710b4c296d7af13"
|
||||
},
|
||||
"fusion": {
|
||||
"revision": "19db2f47ba4c3a0f6238d4ae0e2abfca16e61dd6"
|
||||
},
|
||||
"gdscript": {
|
||||
"revision": "2a6abdaa47fcb91397e09a97c7433fd995ea46c6"
|
||||
},
|
||||
"gleam": {
|
||||
"revision": "cfcbca3f8f734773878e00d7bfcedea98eb10be2"
|
||||
},
|
||||
"glimmer": {
|
||||
"revision": "5caf63ac0e3c549b90c9aeb042871206b4b7bc16"
|
||||
},
|
||||
"glsl": {
|
||||
"revision": "ffb93961426926554a0ba4a389ea6e9d6fafdea9"
|
||||
},
|
||||
"go": {
|
||||
"revision": "c8fed1f0847a65a04a4b8cb7655f5f416e0742ca"
|
||||
},
|
||||
"godot_resource": {
|
||||
"revision": "b6ef0768711086a86b3297056f9ffb5cc1d77b4a"
|
||||
},
|
||||
"gomod": {
|
||||
"revision": "e8f51f8e4363a3d9a427e8f63f4c1bbc5ef5d8d0"
|
||||
},
|
||||
"gowork": {
|
||||
"revision": "6dd9dd79fb51e9f2abc829d5e97b15015b6a8ae2"
|
||||
},
|
||||
"graphql": {
|
||||
"revision": "5e66e961eee421786bdda8495ed1db045e06b5fe"
|
||||
},
|
||||
"hack": {
|
||||
"revision": "d434b4e6c9af0524b163d7a912c8ce79d2b1f778"
|
||||
},
|
||||
"haskell": {
|
||||
"revision": "ed976b81b00ce7b72b99bca75e7a616cc526220c"
|
||||
},
|
||||
"hcl": {
|
||||
"revision": "d559c46ba170808b23a73da0cf49f315d221d095"
|
||||
},
|
||||
"heex": {
|
||||
"revision": "592e22292a367312c35e13de7fdb888f029981d6"
|
||||
},
|
||||
"help": {
|
||||
"revision": "41ac50500e68fadc139737bbee2a0618628b822b"
|
||||
},
|
||||
"hjson": {
|
||||
"revision": "02fa3b79b3ff9a296066da6277adfc3f26cbc9e0"
|
||||
},
|
||||
"hocon": {
|
||||
"revision": "bb412e2633f4a3611a4e16efe58d917093bb4782"
|
||||
},
|
||||
"html": {
|
||||
"revision": "161a92474a7bb2e9e830e48e76426f38299d99d1"
|
||||
},
|
||||
"http": {
|
||||
"revision": "bfddd16b1cf78e0042fd1f6846a179f76a254e20"
|
||||
},
|
||||
"java": {
|
||||
"revision": "881b84fe7078651af5077cc4cea4c85f9fddde3b"
|
||||
},
|
||||
"javascript": {
|
||||
"revision": "fdeb68ac8d2bd5a78b943528bb68ceda3aade2eb"
|
||||
},
|
||||
"jsdoc": {
|
||||
"revision": "189a6a4829beb9cdbe837260653b4a3dfb0cc3db"
|
||||
},
|
||||
"json": {
|
||||
"revision": "203e239408d642be83edde8988d6e7b20a19f0e8"
|
||||
},
|
||||
"json5": {
|
||||
"revision": "5dd5cdc418d9659682556b6adca2dd9ace0ac6d2"
|
||||
},
|
||||
"jsonc": {
|
||||
"revision": "02b01653c8a1c198ae7287d566efa86a135b30d5"
|
||||
},
|
||||
"julia": {
|
||||
"revision": "12ea597262125fc22fd2e91aa953ac69b19c26ca"
|
||||
},
|
||||
"kotlin": {
|
||||
"revision": "a4f71eb9b8c9b19ded3e0e9470be4b1b77c2b569"
|
||||
},
|
||||
"lalrpop": {
|
||||
"revision": "7744b56f03ac1e5643fad23c9dd90837fe97291e"
|
||||
},
|
||||
"latex": {
|
||||
"revision": "ab9c1c59de5da1a8d8c629c81d856a6378b6f116"
|
||||
},
|
||||
"ledger": {
|
||||
"revision": "1050a25df55a62878102d10e524b5184b316b7ad"
|
||||
},
|
||||
"llvm": {
|
||||
"revision": "e9948edc41e9e5869af99dddb2b5ff5cc5581af6"
|
||||
},
|
||||
"lua": {
|
||||
"revision": "2b4ffd5a5ffd0c6b4c84f0d9e003050a70db2a37"
|
||||
},
|
||||
"make": {
|
||||
"revision": "a4b9187417d6be349ee5fd4b6e77b4172c6827dd"
|
||||
},
|
||||
"markdown": {
|
||||
"revision": "d24196f9b3e5af6fcb2ec2a0b6cbc5c06f58b85e"
|
||||
},
|
||||
"ninja": {
|
||||
"revision": "0a95cfdc0745b6ae82f60d3a339b37f19b7b9267"
|
||||
},
|
||||
"nix": {
|
||||
"revision": "6d6aaa50793b8265b6a8b6628577a0083d3b923d"
|
||||
},
|
||||
"norg": {
|
||||
"revision": "17d61df817c1e0a9cdef8d915d4e4c556b7cf68c"
|
||||
},
|
||||
"ocaml": {
|
||||
"revision": "23d419ba45789c5a47d31448061557716b02750a"
|
||||
},
|
||||
"ocaml_interface": {
|
||||
"revision": "23d419ba45789c5a47d31448061557716b02750a"
|
||||
},
|
||||
"ocamllex": {
|
||||
"revision": "ac1d5957e719d49bd6acd27439b79843e4daf8ed"
|
||||
},
|
||||
"pascal": {
|
||||
"revision": "2fd40f477d3e2794af152618ccfac8d92eb72a66"
|
||||
},
|
||||
"perl": {
|
||||
"revision": "bbf86084d9b7eb4768f3fb9fe094b3e0600057b1"
|
||||
},
|
||||
"php": {
|
||||
"revision": "3c17a28da38afac41332d3ce79bbd8951867f346"
|
||||
},
|
||||
"phpdoc": {
|
||||
"revision": "d9150d4cb5941f6ff10adba89bfa1f11f4b05b37"
|
||||
},
|
||||
"pioasm": {
|
||||
"revision": "924aadaf5dea2a6074d72027b064f939acf32e20"
|
||||
},
|
||||
"prisma": {
|
||||
"revision": "bf0833cbedb2c5b39250f5ba900f1239a16c6749"
|
||||
},
|
||||
"pug": {
|
||||
"revision": "5875f9a7d94836708119b0a1102bb5792e8bf673"
|
||||
},
|
||||
"python": {
|
||||
"revision": "78c4e9b6b2f08e1be23b541ffced47b15e2972ad"
|
||||
},
|
||||
"ql": {
|
||||
"revision": "8e7fd7e638d4a0ec7a792ee16b19dbc6407aa810"
|
||||
},
|
||||
"query": {
|
||||
"revision": "5217c6805c09f8fc00ed13d17d5fcb791437aee6"
|
||||
},
|
||||
"r": {
|
||||
"revision": "cc04302e1bff76fa02e129f332f44636813b0c3c"
|
||||
},
|
||||
"rasi": {
|
||||
"revision": "e2961f02244c068a67549adf896b0779e4a29516"
|
||||
},
|
||||
"regex": {
|
||||
"revision": "e1cfca3c79896ff79842f057ea13e529b66af636"
|
||||
},
|
||||
"rego": {
|
||||
"revision": "858ca3013da4d50ea1bdb32162a2bfb43641b422"
|
||||
},
|
||||
"rst": {
|
||||
"revision": "b74770c0166f28c1a0ab293513a78712ca1c338b"
|
||||
},
|
||||
"ruby": {
|
||||
"revision": "0b107de5415e7470a30ef1a390d9db3306432bdb"
|
||||
},
|
||||
"rust": {
|
||||
"revision": "0509e440ae042db6483984b3a56b3c5f24b5d9b9"
|
||||
},
|
||||
"scala": {
|
||||
"revision": "ec6047f531e7d4c13787d4ff208b94a84de34165"
|
||||
},
|
||||
"scheme": {
|
||||
"revision": "a1d2233f4e5498bb305858323c93525e1dd165c0"
|
||||
},
|
||||
"scss": {
|
||||
"revision": "c478c6868648eff49eb04a4df90d703dc45b312a"
|
||||
},
|
||||
"slint": {
|
||||
"revision": "0d4dda94f96623302dfc234e06be62a5717f47da"
|
||||
},
|
||||
"solidity": {
|
||||
"revision": "52ed0880c0126df2f2c7693f215fe6f38e4a2e0a"
|
||||
},
|
||||
"sparql": {
|
||||
"revision": "05f949d3c1c15e3261473a244d3ce87777374dec"
|
||||
},
|
||||
"supercollider": {
|
||||
"revision": "0f0e5b5a96dd3e048a9c3db648ed969c44068bff"
|
||||
},
|
||||
"surface": {
|
||||
"revision": "f4586b35ac8548667a9aaa4eae44456c1f43d032"
|
||||
},
|
||||
"svelte": {
|
||||
"revision": "84c90ee15f851e1541c25c86e8a4338f5b4d5af2"
|
||||
},
|
||||
"swift": {
|
||||
"revision": "897df54ad1b2d103dcab3df94f335fceefa230dc"
|
||||
},
|
||||
"teal": {
|
||||
"revision": "fcc5f6f4d194dede4e676834ff28a506e39e17b4"
|
||||
},
|
||||
"tlaplus": {
|
||||
"revision": "dde405e5128c3c47ab8aa014d21b6e5296ca450f"
|
||||
},
|
||||
"todotxt": {
|
||||
"revision": "0207f6a4ab6aeafc4b091914d31d8235049a2578"
|
||||
},
|
||||
"toml": {
|
||||
"revision": "8bd2056818b21860e3d756b5a58c4f6e05fb744e"
|
||||
},
|
||||
"tsx": {
|
||||
"revision": "8e9dba7bd7cf089838a036a98be94db53ba2d0a9"
|
||||
},
|
||||
"turtle": {
|
||||
"revision": "085437f5cb117703b7f520dd92161140a684f092"
|
||||
},
|
||||
"typescript": {
|
||||
"revision": "8e9dba7bd7cf089838a036a98be94db53ba2d0a9"
|
||||
},
|
||||
"vala": {
|
||||
"revision": "31a08784cc74b61cb10c5d8314cf8a8aa98aa9a8"
|
||||
},
|
||||
"verilog": {
|
||||
"revision": "8f6b1f357d1231c420404b5f7a368a73c25adfa2"
|
||||
},
|
||||
"vim": {
|
||||
"revision": "68f7cacfd9ae4698181511c9fdd6641bc25a260b"
|
||||
},
|
||||
"vue": {
|
||||
"revision": "91fe2754796cd8fba5f229505a23fa08f3546c06"
|
||||
},
|
||||
"wgsl": {
|
||||
"revision": "5ca98b174f7dddf69fb7a80c54d49badd1f1f8c4"
|
||||
},
|
||||
"yaml": {
|
||||
"revision": "0e36bed171768908f331ff7dff9d956bae016efb"
|
||||
},
|
||||
"yang": {
|
||||
"revision": "8e9d175982afcefa3dac8ca20d40d1643accd2bd"
|
||||
},
|
||||
"zig": {
|
||||
"revision": "4cff36421dae9c05388b86cd64d2bab4b9ed6676"
|
||||
}
|
||||
}
|
88
bundle/nvim-treesitter/lua/nvim-treesitter.lua
Normal file
88
bundle/nvim-treesitter/lua/nvim-treesitter.lua
Normal file
@ -0,0 +1,88 @@
|
||||
if not pcall(require, "vim.treesitter.languagetree") then
|
||||
error "nvim-treesitter requires a more recent Neovim nightly version!"
|
||||
end
|
||||
|
||||
local install = require "nvim-treesitter.install"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local info = require "nvim-treesitter.info"
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
|
||||
-- Registers all query predicates
|
||||
require "nvim-treesitter.query_predicates"
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.setup()
|
||||
utils.setup_commands("install", install.commands)
|
||||
utils.setup_commands("info", info.commands)
|
||||
utils.setup_commands("configs", configs.commands)
|
||||
configs.init()
|
||||
end
|
||||
|
||||
function M.define_modules(...)
|
||||
configs.define_modules(...)
|
||||
end
|
||||
|
||||
local get_line_for_node = function(node, type_patterns, transform_fn)
|
||||
local node_type = node:type()
|
||||
local is_valid = false
|
||||
for _, rgx in ipairs(type_patterns) do
|
||||
if node_type:find(rgx) then
|
||||
is_valid = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not is_valid then
|
||||
return ""
|
||||
end
|
||||
local line = transform_fn(vim.trim(ts_utils.get_node_text(node)[1] or ""))
|
||||
-- Escape % to avoid statusline to evaluate content as expression
|
||||
return line:gsub("%%", "%%%%")
|
||||
end
|
||||
|
||||
-- Trim spaces and opening brackets from end
|
||||
local transform_line = function(line)
|
||||
return line:gsub("%s*[%[%(%{]*%s*$", "")
|
||||
end
|
||||
|
||||
function M.statusline(opts)
|
||||
if not parsers.has_parser() then
|
||||
return
|
||||
end
|
||||
local options = opts or {}
|
||||
if type(opts) == "number" then
|
||||
options = { indicator_size = opts }
|
||||
end
|
||||
local indicator_size = options.indicator_size or 100
|
||||
local type_patterns = options.type_patterns or { "class", "function", "method" }
|
||||
local transform_fn = options.transform_fn or transform_line
|
||||
local separator = options.separator or " -> "
|
||||
|
||||
local current_node = ts_utils.get_node_at_cursor()
|
||||
if not current_node then
|
||||
return ""
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
local expr = current_node
|
||||
|
||||
while expr do
|
||||
local line = get_line_for_node(expr, type_patterns, transform_fn)
|
||||
if line ~= "" and not vim.tbl_contains(lines, line) then
|
||||
table.insert(lines, 1, line)
|
||||
end
|
||||
expr = expr:parent()
|
||||
end
|
||||
|
||||
local text = table.concat(lines, separator)
|
||||
local text_len = #text
|
||||
if text_len > indicator_size then
|
||||
return "..." .. text:sub(text_len - indicator_size, text_len)
|
||||
end
|
||||
|
||||
return text
|
||||
end
|
||||
|
||||
return M
|
48
bundle/nvim-treesitter/lua/nvim-treesitter/caching.lua
Normal file
48
bundle/nvim-treesitter/lua/nvim-treesitter/caching.lua
Normal file
@ -0,0 +1,48 @@
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
--- Creates a cache table for buffers keyed by a type name.
|
||||
--- Cache entries attach to the buffer and cleanup entries
|
||||
--- as buffers are detached.
|
||||
function M.create_buffer_cache()
|
||||
local cache = {}
|
||||
|
||||
local items = setmetatable({}, {
|
||||
__index = function(tbl, key)
|
||||
rawset(tbl, key, {})
|
||||
return rawget(tbl, key)
|
||||
end,
|
||||
})
|
||||
|
||||
function cache.set(type_name, bufnr, value)
|
||||
if not cache.has(type_name, bufnr) then
|
||||
-- Clean up the cache if the buffer is detached
|
||||
-- to avoid memory leaks
|
||||
api.nvim_buf_attach(bufnr, false, {
|
||||
on_detach = function()
|
||||
cache.remove(type_name, bufnr)
|
||||
return true
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
items[type_name][bufnr] = value
|
||||
end
|
||||
|
||||
function cache.get(type_name, bufnr)
|
||||
return items[type_name][bufnr]
|
||||
end
|
||||
|
||||
function cache.has(type_name, bufnr)
|
||||
return cache.get(type_name, bufnr) ~= nil
|
||||
end
|
||||
|
||||
function cache.remove(type_name, bufnr)
|
||||
items[type_name][bufnr] = nil
|
||||
end
|
||||
|
||||
return cache
|
||||
end
|
||||
|
||||
return M
|
559
bundle/nvim-treesitter/lua/nvim-treesitter/configs.lua
Normal file
559
bundle/nvim-treesitter/lua/nvim-treesitter/configs.lua
Normal file
@ -0,0 +1,559 @@
|
||||
local api = vim.api
|
||||
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local ts_query = require "vim.treesitter.query"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local caching = require "nvim-treesitter.caching"
|
||||
|
||||
local M = {}
|
||||
|
||||
local config = {
|
||||
modules = {},
|
||||
sync_install = false,
|
||||
ensure_installed = {},
|
||||
ignore_install = {},
|
||||
update_strategy = "lockfile",
|
||||
}
|
||||
-- List of modules that need to be setup on initialization.
|
||||
local queued_modules_defs = {}
|
||||
-- Whether we've initialized the plugin yet.
|
||||
local is_initialized = false
|
||||
local builtin_modules = {
|
||||
highlight = {
|
||||
module_path = "nvim-treesitter.highlight",
|
||||
-- @deprecated: use `highlight.set_custom_captures` instead
|
||||
custom_captures = {},
|
||||
enable = false,
|
||||
is_supported = function(lang)
|
||||
return queries.has_highlights(lang)
|
||||
end,
|
||||
additional_vim_regex_highlighting = false,
|
||||
},
|
||||
incremental_selection = {
|
||||
module_path = "nvim-treesitter.incremental_selection",
|
||||
enable = false,
|
||||
keymaps = {
|
||||
init_selection = "gnn",
|
||||
node_incremental = "grn",
|
||||
scope_incremental = "grc",
|
||||
node_decremental = "grm",
|
||||
},
|
||||
is_supported = function()
|
||||
return true
|
||||
end,
|
||||
},
|
||||
indent = {
|
||||
module_path = "nvim-treesitter.indent",
|
||||
enable = false,
|
||||
is_supported = queries.has_indents,
|
||||
},
|
||||
}
|
||||
|
||||
local attached_buffers_by_module = caching.create_buffer_cache()
|
||||
|
||||
-- Resolves a module by requiring the `module_path` or using the module definition.
|
||||
local function resolve_module(mod_name)
|
||||
local config_mod = M.get_module(mod_name)
|
||||
|
||||
if not config_mod then
|
||||
return
|
||||
end
|
||||
|
||||
if type(config_mod.attach) == "function" and type(config_mod.detach) == "function" then
|
||||
return config_mod
|
||||
elseif type(config_mod.module_path) == "string" then
|
||||
return require(config_mod.module_path)
|
||||
end
|
||||
end
|
||||
|
||||
-- Enables and attaches the module to a buffer for lang.
|
||||
-- @param mod path to module
|
||||
-- @param bufnr buffer number, defaults to current buffer
|
||||
-- @param lang language, defaults to current language
|
||||
local function enable_module(mod, bufnr, lang)
|
||||
local module = M.get_module(mod)
|
||||
if not module then
|
||||
return
|
||||
end
|
||||
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
lang = lang or parsers.get_buf_lang(bufnr)
|
||||
|
||||
if not module.enable then
|
||||
if module.enabled_buffers then
|
||||
module.enabled_buffers[bufnr] = true
|
||||
else
|
||||
module.enabled_buffers = { [bufnr] = true }
|
||||
end
|
||||
end
|
||||
|
||||
M.attach_module(mod, bufnr, lang)
|
||||
end
|
||||
|
||||
-- Enables autocomands for the module.
|
||||
-- After the module is loaded `loaded` will be set to true for the module.
|
||||
-- @param mod path to module
|
||||
local function enable_mod_conf_autocmd(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod or config_mod.loaded then
|
||||
return
|
||||
end
|
||||
|
||||
local cmd = string.format("lua require'nvim-treesitter.configs'.reattach_module('%s')", mod)
|
||||
api.nvim_command(string.format("autocmd NvimTreesitter FileType * %s", cmd))
|
||||
|
||||
config_mod.loaded = true
|
||||
end
|
||||
|
||||
-- Enables the module globally and for all current buffers.
|
||||
-- After enabled, `enable` will be set to true for the module.
|
||||
-- @param mod path to module
|
||||
local function enable_all(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod then
|
||||
return
|
||||
end
|
||||
|
||||
enable_mod_conf_autocmd(mod)
|
||||
config_mod.enable = true
|
||||
config_mod.enabled_buffers = nil
|
||||
|
||||
for _, bufnr in pairs(api.nvim_list_bufs()) do
|
||||
enable_module(mod, bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
-- Disables and detaches the module for a buffer.
|
||||
-- @param mod path to module
|
||||
-- @param bufnr buffer number, defaults to current buffer
|
||||
local function disable_module(mod, bufnr)
|
||||
local module = M.get_module(mod)
|
||||
if not module then
|
||||
return
|
||||
end
|
||||
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
if module.enabled_buffers then
|
||||
module.enabled_buffers[bufnr] = false
|
||||
end
|
||||
M.detach_module(mod, bufnr)
|
||||
end
|
||||
|
||||
-- Disables autocomands for the module.
|
||||
-- After the module is unloaded `loaded` will be set to false for the module.
|
||||
-- @param mod path to module
|
||||
local function disable_mod_conf_autocmd(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod or not config_mod.loaded then
|
||||
return
|
||||
end
|
||||
-- TODO(kyazdani): detach the correct autocmd... doesn't work when using %s, cmd.
|
||||
-- This will remove all autocomands!
|
||||
api.nvim_command "autocmd! NvimTreesitter FileType *"
|
||||
config_mod.loaded = false
|
||||
end
|
||||
|
||||
-- Disables the module globally and for all current buffers.
|
||||
-- After disabled, `enable` will be set to false for the module.
|
||||
-- @param mod path to module
|
||||
local function disable_all(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod then
|
||||
return
|
||||
end
|
||||
|
||||
config_mod.enabled_buffers = nil
|
||||
disable_mod_conf_autocmd(mod)
|
||||
config_mod.enable = false
|
||||
|
||||
for _, bufnr in pairs(api.nvim_list_bufs()) do
|
||||
disable_module(mod, bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggles a module for a buffer
|
||||
-- @param mod path to module
|
||||
-- @param bufnr buffer number, defaults to current buffer
|
||||
-- @param lang language, defaults to current language
|
||||
local function toggle_module(mod, bufnr, lang)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
lang = lang or parsers.get_buf_lang(bufnr)
|
||||
|
||||
if attached_buffers_by_module.has(mod, bufnr) then
|
||||
disable_module(mod, bufnr)
|
||||
else
|
||||
enable_module(mod, bufnr, lang)
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggles the module globally and for all current buffers.
|
||||
-- @param mod path to module
|
||||
local function toggle_all(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod then
|
||||
return
|
||||
end
|
||||
|
||||
if config_mod.enable then
|
||||
disable_all(mod)
|
||||
else
|
||||
enable_all(mod)
|
||||
end
|
||||
end
|
||||
|
||||
-- Recurses through all modules including submodules
|
||||
-- @param accumulator function called for each module
|
||||
-- @param root root configuration table to start at
|
||||
-- @param path prefix path
|
||||
local function recurse_modules(accumulator, root, path)
|
||||
root = root or config.modules
|
||||
|
||||
for name, module in pairs(root) do
|
||||
local new_path = path and (path .. "." .. name) or name
|
||||
|
||||
if M.is_module(module) then
|
||||
accumulator(name, module, new_path, root)
|
||||
elseif type(module) == "table" then
|
||||
recurse_modules(accumulator, module, new_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Shows current configuration of all nvim-treesitter modules
|
||||
-- @param process_function function used as the `process` parameter
|
||||
-- for vim.inspect (https://github.com/kikito/inspect.lua#optionsprocess)
|
||||
local function config_info(process_function)
|
||||
process_function = process_function
|
||||
or function(item, path)
|
||||
if path[#path] == vim.inspect.METATABLE then
|
||||
return
|
||||
end
|
||||
if path[#path] == "is_supported" then
|
||||
return
|
||||
end
|
||||
return item
|
||||
end
|
||||
print(vim.inspect(config, { process = process_function }))
|
||||
end
|
||||
|
||||
if not vim.ui then
|
||||
vim.ui = {
|
||||
select = function(items, opts, on_choice)
|
||||
vim.validate {
|
||||
items = { items, "table", false },
|
||||
on_choice = { on_choice, "function", false },
|
||||
}
|
||||
opts = opts or {}
|
||||
local choices = { opts.prompt or "Select one of:" }
|
||||
local format_item = opts.format_item or tostring
|
||||
for i, item in pairs(items) do
|
||||
table.insert(choices, string.format("%d: %s", i, format_item(item)))
|
||||
end
|
||||
local choice = vim.fn.inputlist(choices)
|
||||
if choice < 1 or choice > #items then
|
||||
on_choice(nil, nil)
|
||||
else
|
||||
on_choice(items[choice], choice)
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
function M.edit_query_file(query_group, lang)
|
||||
lang = lang or parsers.get_buf_lang()
|
||||
local files = ts_query.get_query_files(lang, query_group, true)
|
||||
if #files == 0 then
|
||||
utils.notify "No query file found! Creating a new one!"
|
||||
M.edit_query_file_user_after(query_group, lang)
|
||||
elseif #files == 1 then
|
||||
vim.cmd(":edit " .. files[1])
|
||||
else
|
||||
vim.ui.select(files, { prompt = "Select a file:" }, function(file)
|
||||
if file then
|
||||
vim.cmd(":edit " .. file)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function M.edit_query_file_user_after(query_group, lang)
|
||||
lang = lang or parsers.get_buf_lang()
|
||||
local folder = utils.join_path(vim.fn.stdpath "config", "after", "queries", lang)
|
||||
local file = utils.join_path(folder, query_group .. ".scm")
|
||||
if vim.fn.isdirectory(folder) ~= 1 then
|
||||
vim.ui.select({ "Yes", "No" }, { prompt = '"' .. folder .. '" does not exist. Create it?' }, function(choice)
|
||||
if choice == "Yes" then
|
||||
vim.fn.mkdir(folder, "p", "0755")
|
||||
vim.cmd(":edit " .. file)
|
||||
end
|
||||
end)
|
||||
else
|
||||
vim.cmd(":edit " .. file)
|
||||
end
|
||||
end
|
||||
|
||||
M.commands = {
|
||||
TSBufEnable = {
|
||||
run = enable_module,
|
||||
args = {
|
||||
"-nargs=1",
|
||||
"-complete=custom,nvim_treesitter#available_modules",
|
||||
},
|
||||
},
|
||||
TSBufDisable = {
|
||||
run = disable_module,
|
||||
args = {
|
||||
"-nargs=1",
|
||||
"-complete=custom,nvim_treesitter#available_modules",
|
||||
},
|
||||
},
|
||||
TSBufToggle = {
|
||||
run = toggle_module,
|
||||
args = {
|
||||
"-nargs=1",
|
||||
"-complete=custom,nvim_treesitter#available_modules",
|
||||
},
|
||||
},
|
||||
TSEnable = {
|
||||
run = enable_all,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,nvim_treesitter#available_modules",
|
||||
},
|
||||
},
|
||||
TSDisable = {
|
||||
run = disable_all,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,nvim_treesitter#available_modules",
|
||||
},
|
||||
},
|
||||
TSToggle = {
|
||||
run = toggle_all,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,nvim_treesitter#available_modules",
|
||||
},
|
||||
},
|
||||
TSConfigInfo = {
|
||||
run = config_info,
|
||||
args = {
|
||||
"-nargs=0",
|
||||
},
|
||||
},
|
||||
TSEditQuery = {
|
||||
run = M.edit_query_file,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,nvim_treesitter#available_query_groups",
|
||||
},
|
||||
},
|
||||
TSEditQueryUserAfter = {
|
||||
run = M.edit_query_file_user_after,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,nvim_treesitter#available_query_groups",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- @param mod: module (string)
|
||||
-- @param lang: the language of the buffer (string)
|
||||
-- @param bufnr: the bufnr (number)
|
||||
function M.is_enabled(mod, lang, bufnr)
|
||||
if not parsers.list[lang] or not parsers.has_parser(lang) then
|
||||
return false
|
||||
end
|
||||
|
||||
local module_config = M.get_module(mod)
|
||||
if not module_config then
|
||||
return false
|
||||
end
|
||||
|
||||
local buffer_enabled = module_config.enabled_buffers and module_config.enabled_buffers[bufnr]
|
||||
local config_enabled = module_config.enable or buffer_enabled
|
||||
if not config_enabled or not module_config.is_supported(lang) then
|
||||
return false
|
||||
end
|
||||
|
||||
local disable = module_config.disable
|
||||
if type(disable) == "function" then
|
||||
if disable(lang, bufnr) then
|
||||
return false
|
||||
end
|
||||
elseif type(disable) == "table" then
|
||||
-- Otherwise it's a list of languages
|
||||
for _, parser in pairs(disable) do
|
||||
if lang == parser then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Setup call for users to override module configurations.
|
||||
-- @param user_data module overrides
|
||||
function M.setup(user_data)
|
||||
config.modules = vim.tbl_deep_extend("force", config.modules, user_data)
|
||||
config.ignore_install = user_data.ignore_install or {}
|
||||
|
||||
local ensure_installed = user_data.ensure_installed or {}
|
||||
if #ensure_installed > 0 then
|
||||
if user_data.sync_install then
|
||||
require("nvim-treesitter.install").ensure_installed_sync(ensure_installed)
|
||||
else
|
||||
require("nvim-treesitter.install").ensure_installed(ensure_installed)
|
||||
end
|
||||
end
|
||||
|
||||
config.modules.ensure_installed = nil
|
||||
|
||||
recurse_modules(function(_, _, new_path)
|
||||
local data = utils.get_at_path(config.modules, new_path)
|
||||
if data.enable then
|
||||
enable_all(new_path)
|
||||
end
|
||||
end, config.modules)
|
||||
end
|
||||
|
||||
-- Defines a table of modules that can be attached/detached to buffers
|
||||
-- based on language support. A module consist of the following properties:
|
||||
-- * @enable Whether the modules is enabled. Can be true or false.
|
||||
-- * @disable A list of languages to disable the module for. Only relevant if enable is true.
|
||||
-- * @keymaps A list of user mappings for a given module if relevant.
|
||||
-- * @is_supported A function which, given a ft, will return true if the ft works on the module.
|
||||
-- * @module_path A string path to a module file using `require`. The exported module must contain
|
||||
-- an `attach` and `detach` function. This path is not required if `attach` and `detach`
|
||||
-- functions are provided directly on the module definition.
|
||||
-- * @attach An attach function that is called for each buffer that the module is enabled for. This is required
|
||||
-- if a `module_path` is not specified.
|
||||
-- * @detach A detach function that is called for each buffer that the module is enabled for. This is required
|
||||
-- if a `module_path` is not specified.
|
||||
-- Modules are not setup until `init` is invoked by the plugin. This allows modules to be defined in any order
|
||||
-- and can be loaded lazily.
|
||||
-- @example
|
||||
-- require"nvim-treesitter".define_modules {
|
||||
-- my_cool_module = {
|
||||
-- attach = function()
|
||||
-- do_some_cool_setup()
|
||||
-- end,
|
||||
-- detach = function()
|
||||
-- do_some_cool_teardown()
|
||||
-- end
|
||||
-- }
|
||||
-- }
|
||||
function M.define_modules(mod_defs)
|
||||
if not is_initialized then
|
||||
table.insert(queued_modules_defs, mod_defs)
|
||||
return
|
||||
end
|
||||
|
||||
recurse_modules(function(key, mod, _, group)
|
||||
group[key] = vim.tbl_extend("keep", mod, {
|
||||
enable = false,
|
||||
disable = {},
|
||||
is_supported = function()
|
||||
return true
|
||||
end,
|
||||
})
|
||||
end, mod_defs)
|
||||
|
||||
config.modules = vim.tbl_deep_extend("keep", config.modules, mod_defs)
|
||||
|
||||
for _, mod in ipairs(M.available_modules(mod_defs)) do
|
||||
local module_config = M.get_module(mod)
|
||||
if module_config and module_config.enable then
|
||||
enable_mod_conf_autocmd(mod)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Attaches a module to a buffer
|
||||
-- @param mod_name the module name
|
||||
-- @param bufnr the bufnr
|
||||
-- @param lang the language of the buffer
|
||||
function M.attach_module(mod_name, bufnr, lang)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
lang = lang or parsers.get_buf_lang(bufnr)
|
||||
local resolved_mod = resolve_module(mod_name)
|
||||
|
||||
if resolved_mod and not attached_buffers_by_module.has(mod_name, bufnr) and M.is_enabled(mod_name, lang, bufnr) then
|
||||
attached_buffers_by_module.set(mod_name, bufnr, true)
|
||||
resolved_mod.attach(bufnr, lang)
|
||||
end
|
||||
end
|
||||
|
||||
-- Detaches a module to a buffer
|
||||
-- @param mod_name the module name
|
||||
-- @param bufnr the bufnr
|
||||
function M.detach_module(mod_name, bufnr)
|
||||
local resolved_mod = resolve_module(mod_name)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
|
||||
if resolved_mod and attached_buffers_by_module.has(mod_name, bufnr) then
|
||||
attached_buffers_by_module.remove(mod_name, bufnr)
|
||||
resolved_mod.detach(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
-- Same as attach_module, but if the module is already attached, detach it first.
|
||||
-- @param mod_name the module name
|
||||
-- @param bufnr the bufnr
|
||||
-- @param lang the language of the buffer
|
||||
function M.reattach_module(mod_name, bufnr, lang)
|
||||
M.detach_module(mod_name, bufnr)
|
||||
M.attach_module(mod_name, bufnr, lang)
|
||||
end
|
||||
|
||||
-- Gets available modules
|
||||
-- @param root root table to find modules
|
||||
function M.available_modules(root)
|
||||
local modules = {}
|
||||
|
||||
recurse_modules(function(_, _, path)
|
||||
table.insert(modules, path)
|
||||
end, root)
|
||||
|
||||
return modules
|
||||
end
|
||||
|
||||
-- Gets a module config by path
|
||||
-- @param mod_path path to the module
|
||||
-- @returns the module or nil
|
||||
function M.get_module(mod_path)
|
||||
local mod = utils.get_at_path(config.modules, mod_path)
|
||||
|
||||
return M.is_module(mod) and mod or nil
|
||||
end
|
||||
|
||||
-- Determines whether the provided table is a module.
|
||||
-- A module should contain an attach and detach function.
|
||||
-- @param mod the module table
|
||||
function M.is_module(mod)
|
||||
return type(mod) == "table"
|
||||
and ((type(mod.attach) == "function" and type(mod.detach) == "function") or type(mod.module_path) == "string")
|
||||
end
|
||||
|
||||
-- Initializes built-in modules and any queued modules
|
||||
-- registered by plugins or the user.
|
||||
function M.init()
|
||||
is_initialized = true
|
||||
M.define_modules(builtin_modules)
|
||||
|
||||
for _, mod_def in ipairs(queued_modules_defs) do
|
||||
M.define_modules(mod_def)
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_update_strategy()
|
||||
return config.update_strategy
|
||||
end
|
||||
|
||||
function M.get_ignored_parser_installs()
|
||||
return config.ignore_install or {}
|
||||
end
|
||||
|
||||
return M
|
112
bundle/nvim-treesitter/lua/nvim-treesitter/fold.lua
Normal file
112
bundle/nvim-treesitter/lua/nvim-treesitter/fold.lua
Normal file
@ -0,0 +1,112 @@
|
||||
local api = vim.api
|
||||
local tsutils = require "nvim-treesitter.ts_utils"
|
||||
local query = require "nvim-treesitter.query"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
|
||||
local M = {}
|
||||
|
||||
-- This is cached on buf tick to avoid computing that multiple times
|
||||
-- Especially not for every line in the file when `zx` is hit
|
||||
local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
|
||||
local max_fold_level = api.nvim_win_get_option(0, "foldnestmax")
|
||||
local trim_level = function(level)
|
||||
if level > max_fold_level then
|
||||
return max_fold_level
|
||||
end
|
||||
return level
|
||||
end
|
||||
|
||||
local parser = parsers.get_parser(bufnr)
|
||||
|
||||
if not parser then
|
||||
return {}
|
||||
end
|
||||
|
||||
local matches = query.get_capture_matches_recursively(bufnr, function(lang)
|
||||
if query.has_folds(lang) then
|
||||
return "@fold", "folds"
|
||||
elseif query.has_locals(lang) then
|
||||
return "@scope", "locals"
|
||||
end
|
||||
end)
|
||||
|
||||
-- start..stop is an inclusive range
|
||||
local start_counts = {}
|
||||
local stop_counts = {}
|
||||
|
||||
local prev_start = -1
|
||||
local prev_stop = -1
|
||||
|
||||
local min_fold_lines = api.nvim_win_get_option(0, "foldminlines")
|
||||
|
||||
for _, node in ipairs(matches) do
|
||||
local start, _, stop, stop_col = node.node:range()
|
||||
|
||||
if stop_col == 0 then
|
||||
stop = stop - 1
|
||||
end
|
||||
|
||||
local fold_length = stop - start + 1
|
||||
local should_fold = fold_length > min_fold_lines
|
||||
|
||||
-- Fold only multiline nodes that are not exactly the same as previously met folds
|
||||
-- Checking against just the previously found fold is sufficient if nodes
|
||||
-- are returned in preorder or postorder when traversing tree
|
||||
if should_fold and not (start == prev_start and stop == prev_stop) then
|
||||
start_counts[start] = (start_counts[start] or 0) + 1
|
||||
stop_counts[stop] = (stop_counts[stop] or 0) + 1
|
||||
prev_start = start
|
||||
prev_stop = stop
|
||||
end
|
||||
end
|
||||
|
||||
local levels = {}
|
||||
local current_level = 0
|
||||
|
||||
-- We now have the list of fold opening and closing, fill the gaps and mark where fold start
|
||||
for lnum = 0, api.nvim_buf_line_count(bufnr) do
|
||||
local prefix = ""
|
||||
|
||||
local last_trimmed_level = trim_level(current_level)
|
||||
current_level = current_level + (start_counts[lnum] or 0)
|
||||
local trimmed_level = trim_level(current_level)
|
||||
current_level = current_level - (stop_counts[lnum] or 0)
|
||||
local next_trimmed_level = trim_level(current_level)
|
||||
|
||||
-- Determine if it's the start/end of a fold
|
||||
-- NB: vim's fold-expr interface does not have a mechanism to indicate that
|
||||
-- two (or more) folds start at this line, so it cannot distinguish between
|
||||
-- ( \n ( \n )) \n (( \n ) \n )
|
||||
-- versus
|
||||
-- ( \n ( \n ) \n ( \n ) \n )
|
||||
-- If it did have such a mechanism, (trimmed_level - last_trimmed_level)
|
||||
-- would be the correct number of starts to pass on.
|
||||
if trimmed_level - last_trimmed_level > 0 then
|
||||
prefix = ">"
|
||||
elseif trimmed_level - next_trimmed_level > 0 then
|
||||
-- Ending marks tend to confuse vim more than it helps, particularly when
|
||||
-- the fold level changes by at least 2; we can uncomment this if
|
||||
-- vim's behavior gets fixed.
|
||||
-- prefix = "<"
|
||||
prefix = ""
|
||||
end
|
||||
|
||||
levels[lnum + 1] = prefix .. tostring(trimmed_level)
|
||||
end
|
||||
|
||||
return levels
|
||||
end)
|
||||
|
||||
function M.get_fold_indic(lnum)
|
||||
if not parsers.has_parser() or not lnum then
|
||||
return "0"
|
||||
end
|
||||
|
||||
local buf = api.nvim_get_current_buf()
|
||||
|
||||
local levels = folds_levels(buf) or {}
|
||||
|
||||
return levels[lnum] or "0"
|
||||
end
|
||||
|
||||
return M
|
168
bundle/nvim-treesitter/lua/nvim-treesitter/health.lua
Normal file
168
bundle/nvim-treesitter/lua/nvim-treesitter/health.lua
Normal file
@ -0,0 +1,168 @@
|
||||
local api = vim.api
|
||||
local fn = vim.fn
|
||||
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local info = require "nvim-treesitter.info"
|
||||
local shell = require "nvim-treesitter.shell_command_selectors"
|
||||
local install = require "nvim-treesitter.install"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
|
||||
local health_start = vim.fn["health#report_start"]
|
||||
local health_ok = vim.fn["health#report_ok"]
|
||||
local health_error = vim.fn["health#report_error"]
|
||||
local health_warn = vim.fn["health#report_warn"]
|
||||
|
||||
local M = {}
|
||||
|
||||
local NVIM_TREESITTER_MINIMUM_ABI = 13
|
||||
|
||||
local function install_health()
|
||||
health_start "Installation"
|
||||
|
||||
if fn.executable "tree-sitter" == 0 then
|
||||
health_warn(
|
||||
"`tree-sitter` executable not found (parser generator, only needed for :TSInstallFromGrammar,"
|
||||
.. " not required for :TSInstall)"
|
||||
)
|
||||
else
|
||||
health_ok(
|
||||
"`tree-sitter` found "
|
||||
.. (utils.ts_cli_version() or "(unknown version)")
|
||||
.. " (parser generator, only needed for :TSInstallFromGrammar)"
|
||||
)
|
||||
end
|
||||
|
||||
if fn.executable "node" == 0 then
|
||||
health_warn(
|
||||
"`node` executable not found (only needed for :TSInstallFromGrammar," .. " not required for :TSInstall)"
|
||||
)
|
||||
else
|
||||
local handle = io.popen "node --version"
|
||||
local result = handle:read "*a"
|
||||
handle:close()
|
||||
local version = vim.split(result, "\n")[1]
|
||||
health_ok("`node` found " .. version .. " (only needed for :TSInstallFromGrammar)")
|
||||
end
|
||||
|
||||
if fn.executable "git" == 0 then
|
||||
health_error("`git` executable not found.", {
|
||||
"Install it with your package manager.",
|
||||
"Check that your `$PATH` is set correctly.",
|
||||
})
|
||||
else
|
||||
health_ok "`git` executable found."
|
||||
end
|
||||
|
||||
local cc = shell.select_executable(install.compilers)
|
||||
if not cc then
|
||||
health_error("`cc` executable not found.", {
|
||||
"Check that any of "
|
||||
.. vim.inspect(install.compilers)
|
||||
.. " is in your $PATH"
|
||||
.. ' or set the environment variable CC or `require"nvim-treesitter.install".compilers` explicitly!',
|
||||
})
|
||||
else
|
||||
local version = vim.fn.systemlist(cc .. (cc == "cl" and "" or " --version"))[1]
|
||||
health_ok(
|
||||
"`"
|
||||
.. cc
|
||||
.. "` executable found. Selected from "
|
||||
.. vim.inspect(install.compilers)
|
||||
.. (version and ("\nVersion: " .. version) or "")
|
||||
)
|
||||
end
|
||||
if vim.treesitter.language_version then
|
||||
if vim.treesitter.language_version >= NVIM_TREESITTER_MINIMUM_ABI then
|
||||
health_ok(
|
||||
"Neovim was compiled with tree-sitter runtime ABI version "
|
||||
.. vim.treesitter.language_version
|
||||
.. " (required >="
|
||||
.. NVIM_TREESITTER_MINIMUM_ABI
|
||||
.. "). Parsers must be compatible with runtime ABI."
|
||||
)
|
||||
else
|
||||
health_error(
|
||||
"Neovim was compiled with tree-sitter runtime ABI version "
|
||||
.. vim.treesitter.language_version
|
||||
.. ".\n"
|
||||
.. "nvim-treesitter expects at least ABI version "
|
||||
.. NVIM_TREESITTER_MINIMUM_ABI
|
||||
.. "\n"
|
||||
.. "Please make sure that Neovim is linked against are recent tree-sitter runtime when building"
|
||||
.. " or raise an issue at your Neovim packager. Parsers must be compatible with runtime ABI."
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function query_status(lang, query_group)
|
||||
local ok, err = pcall(queries.get_query, lang, query_group)
|
||||
if not ok then
|
||||
return "x", err
|
||||
elseif not err then
|
||||
return "."
|
||||
else
|
||||
return "✓"
|
||||
end
|
||||
end
|
||||
|
||||
function M.check()
|
||||
local error_collection = {}
|
||||
-- Installation dependency checks
|
||||
install_health()
|
||||
queries.invalidate_query_cache()
|
||||
-- Parser installation checks
|
||||
local parser_installation = { "Parser/Features H L F I J" }
|
||||
for _, parser_name in pairs(info.installed_parsers()) do
|
||||
local installed = #api.nvim_get_runtime_file("parser/" .. parser_name .. ".so", false)
|
||||
|
||||
-- Only append information about installed parsers
|
||||
if installed >= 1 then
|
||||
local multiple_parsers = installed > 1 and "+" or ""
|
||||
local out = " - " .. parser_name .. multiple_parsers .. string.rep(" ", 15 - (#parser_name + #multiple_parsers))
|
||||
for _, query_group in pairs(queries.built_in_query_groups) do
|
||||
local status, err = query_status(parser_name, query_group)
|
||||
out = out .. status .. " "
|
||||
if err then
|
||||
table.insert(error_collection, { parser_name, query_group, err })
|
||||
end
|
||||
end
|
||||
table.insert(parser_installation, out)
|
||||
end
|
||||
end
|
||||
local legend = [[
|
||||
|
||||
Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections
|
||||
+) multiple parsers found, only one will be used
|
||||
x) errors found in the query, try to run :TSUpdate {lang}]]
|
||||
table.insert(parser_installation, legend)
|
||||
-- Finally call the report function
|
||||
health_start(table.concat(parser_installation, "\n"))
|
||||
if #error_collection > 0 then
|
||||
health_start "The following errors have been detected:"
|
||||
for _, p in ipairs(error_collection) do
|
||||
local lang, type, err = unpack(p)
|
||||
local lines = {}
|
||||
table.insert(lines, lang .. "(" .. type .. "): " .. err)
|
||||
local files = vim.treesitter.query.get_query_files(lang, type)
|
||||
if #files > 0 then
|
||||
table.insert(lines, lang .. "(" .. type .. ") is concatenated from the following files:")
|
||||
for _, file in ipairs(files) do
|
||||
local fd = io.open(file, "r")
|
||||
if fd then
|
||||
local ok, file_err = pcall(vim.treesitter.query.parse_query, lang, fd:read "*a")
|
||||
if ok then
|
||||
table.insert(lines, '| [OK]:"' .. file .. '"')
|
||||
else
|
||||
table.insert(lines, '| [ERROR]:"' .. file .. '", failed to load: ' .. file_err)
|
||||
end
|
||||
fd:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
health_error(table.concat(lines, "\n"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
159
bundle/nvim-treesitter/lua/nvim-treesitter/highlight.lua
Normal file
159
bundle/nvim-treesitter/lua/nvim-treesitter/highlight.lua
Normal file
@ -0,0 +1,159 @@
|
||||
local api = vim.api
|
||||
local ts = vim.treesitter
|
||||
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
|
||||
local M = {}
|
||||
|
||||
local hlmap = vim.treesitter.highlighter.hl_map
|
||||
|
||||
-- nvim-treesitter Highlight Group Mappings
|
||||
-- Note: Some highlight groups may not be applied upstream, some may be experimental
|
||||
|
||||
hlmap["annotation"] = "TSAnnotation"
|
||||
|
||||
hlmap["attribute"] = "TSAttribute"
|
||||
|
||||
hlmap["boolean"] = "TSBoolean"
|
||||
|
||||
hlmap["character"] = "TSCharacter"
|
||||
hlmap["character.special"] = "TSCharacterSpecial"
|
||||
|
||||
hlmap["comment"] = "TSComment"
|
||||
|
||||
hlmap["conditional"] = "TSConditional"
|
||||
|
||||
hlmap["constant"] = "TSConstant"
|
||||
hlmap["constant.builtin"] = "TSConstBuiltin"
|
||||
hlmap["constant.macro"] = "TSConstMacro"
|
||||
|
||||
hlmap["constructor"] = "TSConstructor"
|
||||
|
||||
hlmap["debug"] = "TSDebug"
|
||||
hlmap["define"] = "TSDefine"
|
||||
|
||||
hlmap["error"] = "TSError"
|
||||
hlmap["exception"] = "TSException"
|
||||
|
||||
hlmap["field"] = "TSField"
|
||||
|
||||
hlmap["float"] = "TSFloat"
|
||||
|
||||
hlmap["function"] = "TSFunction"
|
||||
hlmap["function.builtin"] = "TSFuncBuiltin"
|
||||
hlmap["function.macro"] = "TSFuncMacro"
|
||||
|
||||
hlmap["include"] = "TSInclude"
|
||||
|
||||
hlmap["keyword"] = "TSKeyword"
|
||||
hlmap["keyword.function"] = "TSKeywordFunction"
|
||||
hlmap["keyword.operator"] = "TSKeywordOperator"
|
||||
hlmap["keyword.return"] = "TSKeywordReturn"
|
||||
|
||||
hlmap["label"] = "TSLabel"
|
||||
|
||||
hlmap["method"] = "TSMethod"
|
||||
|
||||
hlmap["namespace"] = "TSNamespace"
|
||||
|
||||
hlmap["none"] = "TSNone"
|
||||
hlmap["number"] = "TSNumber"
|
||||
|
||||
hlmap["operator"] = "TSOperator"
|
||||
|
||||
hlmap["parameter"] = "TSParameter"
|
||||
hlmap["parameter.reference"] = "TSParameterReference"
|
||||
|
||||
hlmap["preproc"] = "TSPreProc"
|
||||
|
||||
hlmap["property"] = "TSProperty"
|
||||
|
||||
hlmap["punctuation.delimiter"] = "TSPunctDelimiter"
|
||||
hlmap["punctuation.bracket"] = "TSPunctBracket"
|
||||
hlmap["punctuation.special"] = "TSPunctSpecial"
|
||||
|
||||
hlmap["repeat"] = "TSRepeat"
|
||||
|
||||
hlmap["storageclass"] = "TSStorageClass"
|
||||
|
||||
hlmap["string"] = "TSString"
|
||||
hlmap["string.regex"] = "TSStringRegex"
|
||||
hlmap["string.escape"] = "TSStringEscape"
|
||||
hlmap["string.special"] = "TSStringSpecial"
|
||||
|
||||
hlmap["symbol"] = "TSSymbol"
|
||||
|
||||
hlmap["tag"] = "TSTag"
|
||||
hlmap["tag.attribute"] = "TSTagAttribute"
|
||||
hlmap["tag.delimiter"] = "TSTagDelimiter"
|
||||
|
||||
hlmap["text"] = "TSText"
|
||||
hlmap["text.strong"] = "TSStrong"
|
||||
hlmap["text.emphasis"] = "TSEmphasis"
|
||||
hlmap["text.underline"] = "TSUnderline"
|
||||
hlmap["text.strike"] = "TSStrike"
|
||||
hlmap["text.title"] = "TSTitle"
|
||||
hlmap["text.literal"] = "TSLiteral"
|
||||
hlmap["text.uri"] = "TSURI"
|
||||
hlmap["text.math"] = "TSMath"
|
||||
hlmap["text.reference"] = "TSTextReference"
|
||||
hlmap["text.environment"] = "TSEnvironment"
|
||||
hlmap["text.environment.name"] = "TSEnvironmentName"
|
||||
|
||||
hlmap["text.note"] = "TSNote"
|
||||
hlmap["text.warning"] = "TSWarning"
|
||||
hlmap["text.danger"] = "TSDanger"
|
||||
|
||||
hlmap["todo"] = "TSTodo"
|
||||
|
||||
hlmap["type"] = "TSType"
|
||||
hlmap["type.builtin"] = "TSTypeBuiltin"
|
||||
hlmap["type.qualifier"] = "TSTypeQualifier"
|
||||
hlmap["type.definition"] = "TSTypeDefinition"
|
||||
|
||||
hlmap["variable"] = "TSVariable"
|
||||
hlmap["variable.builtin"] = "TSVariableBuiltin"
|
||||
|
||||
local function should_enable_vim_regex(config, lang)
|
||||
local additional_hl = config.additional_vim_regex_highlighting
|
||||
local is_table = type(additional_hl) == "table"
|
||||
|
||||
return additional_hl and (not is_table or vim.tbl_contains(additional_hl, lang))
|
||||
end
|
||||
|
||||
local function enable_syntax(bufnr)
|
||||
api.nvim_buf_set_option(bufnr, "syntax", "ON")
|
||||
end
|
||||
|
||||
function M.stop(bufnr)
|
||||
if ts.highlighter.active[bufnr] then
|
||||
ts.highlighter.active[bufnr]:destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function M.start(bufnr, lang)
|
||||
local parser = parsers.get_parser(bufnr, lang)
|
||||
ts.highlighter.new(parser, {})
|
||||
end
|
||||
|
||||
function M.attach(bufnr, lang)
|
||||
local config = configs.get_module "highlight"
|
||||
M.start(bufnr, lang)
|
||||
if should_enable_vim_regex(config, lang) then
|
||||
enable_syntax(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
M.stop(bufnr)
|
||||
enable_syntax(bufnr)
|
||||
end
|
||||
|
||||
function M.set_custom_captures(captures)
|
||||
for k, v in pairs(captures) do
|
||||
hlmap[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
@ -0,0 +1,148 @@
|
||||
local api = vim.api
|
||||
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local locals = require "nvim-treesitter.locals"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local queries = require "nvim-treesitter.query"
|
||||
|
||||
local M = {}
|
||||
|
||||
local selections = {}
|
||||
|
||||
function M.init_selection()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local node = ts_utils.get_node_at_cursor()
|
||||
selections[buf] = { [1] = node }
|
||||
ts_utils.update_selection(buf, node)
|
||||
end
|
||||
|
||||
--- Get the range of the current visual selection.
|
||||
--
|
||||
-- The range start with 1 and the ending is inclusive.
|
||||
local function visual_selection_range()
|
||||
local _, csrow, cscol, _ = unpack(vim.fn.getpos "'<")
|
||||
local _, cerow, cecol, _ = unpack(vim.fn.getpos "'>")
|
||||
|
||||
local start_row, start_col, end_row, end_col
|
||||
|
||||
if csrow < cerow or (csrow == cerow and cscol <= cecol) then
|
||||
start_row = csrow
|
||||
start_col = cscol
|
||||
end_row = cerow
|
||||
end_col = cecol
|
||||
else
|
||||
start_row = cerow
|
||||
start_col = cecol
|
||||
end_row = csrow
|
||||
end_col = cscol
|
||||
end
|
||||
|
||||
return start_row, start_col, end_row, end_col
|
||||
end
|
||||
|
||||
local function range_matches(node)
|
||||
local csrow, cscol, cerow, cecol = visual_selection_range()
|
||||
local srow, scol, erow, ecol = ts_utils.get_vim_range { node:range() }
|
||||
return srow == csrow and scol == cscol and erow == cerow and ecol == cecol
|
||||
end
|
||||
|
||||
local function select_incremental(get_parent)
|
||||
return function()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local nodes = selections[buf]
|
||||
|
||||
local csrow, cscol, cerow, cecol = visual_selection_range()
|
||||
-- Initialize incremental selection with current selection
|
||||
if not nodes or #nodes == 0 or not range_matches(nodes[#nodes]) then
|
||||
local root = parsers.get_parser():parse()[1]:root()
|
||||
local node = root:named_descendant_for_range(csrow - 1, cscol - 1, cerow - 1, cecol)
|
||||
ts_utils.update_selection(buf, node)
|
||||
if nodes and #nodes > 0 then
|
||||
table.insert(selections[buf], node)
|
||||
else
|
||||
selections[buf] = { [1] = node }
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Find a node that changes the current selection.
|
||||
local node = nodes[#nodes]
|
||||
while true do
|
||||
local parent = get_parent(node)
|
||||
if not parent or parent == node then
|
||||
-- Keep searching in the main tree
|
||||
-- TODO: we should search on the parent tree of the current node.
|
||||
local root = parsers.get_parser():parse()[1]:root()
|
||||
parent = root:named_descendant_for_range(csrow - 1, cscol - 1, cerow - 1, cecol)
|
||||
if not parent or root == node or parent == node then
|
||||
ts_utils.update_selection(buf, node)
|
||||
return
|
||||
end
|
||||
end
|
||||
node = parent
|
||||
local srow, scol, erow, ecol = ts_utils.get_vim_range { node:range() }
|
||||
local same_range = (srow == csrow and scol == cscol and erow == cerow and ecol == cecol)
|
||||
if not same_range then
|
||||
table.insert(selections[buf], node)
|
||||
if node ~= nodes[#nodes] then
|
||||
table.insert(nodes, node)
|
||||
end
|
||||
ts_utils.update_selection(buf, node)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
M.node_incremental = select_incremental(function(node)
|
||||
return node:parent() or node
|
||||
end)
|
||||
|
||||
M.scope_incremental = select_incremental(function(node)
|
||||
local lang = parsers.get_buf_lang()
|
||||
if queries.has_locals(lang) then
|
||||
return locals.containing_scope(node:parent() or node)
|
||||
else
|
||||
return node
|
||||
end
|
||||
end)
|
||||
|
||||
function M.node_decremental()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local nodes = selections[buf]
|
||||
if not nodes or #nodes < 2 then
|
||||
return
|
||||
end
|
||||
|
||||
table.remove(selections[buf])
|
||||
local node = nodes[#nodes]
|
||||
ts_utils.update_selection(buf, node)
|
||||
end
|
||||
|
||||
function M.attach(bufnr)
|
||||
local config = configs.get_module "incremental_selection"
|
||||
for funcname, mapping in pairs(config.keymaps) do
|
||||
local mode
|
||||
if funcname == "init_selection" then
|
||||
mode = "n"
|
||||
else
|
||||
mode = "x"
|
||||
end
|
||||
local cmd = string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname)
|
||||
api.nvim_buf_set_keymap(bufnr, mode, mapping, cmd, { silent = true, noremap = true })
|
||||
end
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
local config = configs.get_module "incremental_selection"
|
||||
for f, mapping in pairs(config.keymaps) do
|
||||
if f == "init_selection" then
|
||||
api.nvim_buf_del_keymap(bufnr, "n", mapping)
|
||||
else
|
||||
api.nvim_buf_del_keymap(bufnr, "x", mapping)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
205
bundle/nvim-treesitter/lua/nvim-treesitter/indent.lua
Normal file
205
bundle/nvim-treesitter/lua/nvim-treesitter/indent.lua
Normal file
@ -0,0 +1,205 @@
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local tsutils = require "nvim-treesitter.ts_utils"
|
||||
|
||||
local M = {}
|
||||
|
||||
M.avoid_force_reparsing = {
|
||||
yaml = true,
|
||||
}
|
||||
|
||||
M.comment_parsers = {
|
||||
comment = true,
|
||||
jsdoc = true,
|
||||
phpdoc = true,
|
||||
}
|
||||
|
||||
local function get_first_node_at_line(root, lnum)
|
||||
local col = vim.fn.indent(lnum)
|
||||
return root:descendant_for_range(lnum - 1, col, lnum - 1, col)
|
||||
end
|
||||
|
||||
local function get_last_node_at_line(root, lnum)
|
||||
local col = #vim.fn.getline(lnum) - 1
|
||||
return root:descendant_for_range(lnum - 1, col, lnum - 1, col)
|
||||
end
|
||||
|
||||
local function find_delimiter(bufnr, node, delimiter)
|
||||
for child, _ in node:iter_children() do
|
||||
if child:type() == delimiter then
|
||||
local linenr = child:start()
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, linenr, linenr + 1, false)[1]
|
||||
local end_char = { child:end_() }
|
||||
return child, #line == end_char[2]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local get_indents = tsutils.memoize_by_buf_tick(function(bufnr, root, lang)
|
||||
local map = {
|
||||
auto = {},
|
||||
indent = {},
|
||||
indent_end = {},
|
||||
dedent = {},
|
||||
branch = {},
|
||||
ignore = {},
|
||||
aligned_indent = {},
|
||||
zero_indent = {},
|
||||
}
|
||||
|
||||
for name, node, metadata in queries.iter_captures(bufnr, "indents", root, lang) do
|
||||
map[name][node:id()] = metadata or {}
|
||||
end
|
||||
|
||||
return map
|
||||
end, {
|
||||
-- Memoize by bufnr and lang together.
|
||||
key = function(bufnr, root, lang)
|
||||
return tostring(bufnr) .. root:id() .. "_" .. lang
|
||||
end,
|
||||
})
|
||||
|
||||
---@param lnum number (1-indexed)
|
||||
function M.get_indent(lnum)
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local parser = parsers.get_parser(bufnr)
|
||||
if not parser or not lnum then
|
||||
return -1
|
||||
end
|
||||
|
||||
local root_lang = parsers.get_buf_lang(bufnr)
|
||||
|
||||
-- some languages like Python will actually have worse results when re-parsing at opened new line
|
||||
if not M.avoid_force_reparsing[root_lang] then
|
||||
-- Reparse in case we got triggered by ":h indentkeys"
|
||||
parser:parse()
|
||||
end
|
||||
|
||||
-- Get language tree with smallest range around node that's not a comment parser
|
||||
local root, lang_tree
|
||||
parser:for_each_tree(function(tstree, tree)
|
||||
if not tstree or M.comment_parsers[tree:lang()] then
|
||||
return
|
||||
end
|
||||
local local_root = tstree:root()
|
||||
if tsutils.is_in_node_range(local_root, lnum - 1, 0) then
|
||||
if not root or tsutils.node_length(root) >= tsutils.node_length(local_root) then
|
||||
root = local_root
|
||||
lang_tree = tree
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Not likely, but just in case...
|
||||
if not root then
|
||||
return 0
|
||||
end
|
||||
|
||||
local q = get_indents(vim.api.nvim_get_current_buf(), root, lang_tree:lang())
|
||||
local is_empty_line = string.match(vim.fn.getline(lnum), "^%s*$") ~= nil
|
||||
local node
|
||||
if is_empty_line then
|
||||
local prevlnum = vim.fn.prevnonblank(lnum)
|
||||
node = get_last_node_at_line(root, prevlnum)
|
||||
if q.indent_end[node:id()] then
|
||||
node = get_first_node_at_line(root, lnum)
|
||||
end
|
||||
else
|
||||
node = get_first_node_at_line(root, lnum)
|
||||
end
|
||||
|
||||
local indent_size = vim.fn.shiftwidth()
|
||||
local indent = 0
|
||||
local _, _, root_start = root:start()
|
||||
if root_start ~= 0 then
|
||||
-- injected tree
|
||||
indent = vim.fn.indent(root:start() + 1)
|
||||
end
|
||||
|
||||
-- tracks to ensure multiple indent levels are not applied for same line
|
||||
local is_processed_by_row = {}
|
||||
|
||||
if q.zero_indent[node:id()] then
|
||||
return 0
|
||||
end
|
||||
|
||||
while node do
|
||||
-- do 'autoindent' if not marked as @indent
|
||||
if not q.indent[node:id()] and q.auto[node:id()] and node:start() < lnum - 1 and lnum - 1 <= node:end_() then
|
||||
return -1
|
||||
end
|
||||
|
||||
-- Do not indent if we are inside an @ignore block.
|
||||
-- If a node spans from L1,C1 to L2,C2, we know that lines where L1 < line <= L2 would
|
||||
-- have their indentations contained by the node.
|
||||
if not q.indent[node:id()] and q.ignore[node:id()] and node:start() < lnum - 1 and lnum - 1 <= node:end_() then
|
||||
return 0
|
||||
end
|
||||
|
||||
local srow, _, erow = node:range()
|
||||
|
||||
local is_processed = false
|
||||
|
||||
if
|
||||
not is_processed_by_row[srow]
|
||||
and ((q.branch[node:id()] and srow == lnum - 1) or (q.dedent[node:id()] and srow ~= lnum - 1))
|
||||
then
|
||||
indent = indent - indent_size
|
||||
is_processed = true
|
||||
end
|
||||
|
||||
-- do not indent for nodes that starts-and-ends on same line and starts on target line (lnum)
|
||||
if
|
||||
not is_processed_by_row[srow]
|
||||
-- Dear stylua, please don't change the semantics of this statement!
|
||||
-- stylua: ignore start
|
||||
and (q.indent[node:id()] and srow ~= erow and ((srow ~= lnum - 1) or q.indent[node:id()].start_at_same_line))
|
||||
-- stylua: ignore end
|
||||
then
|
||||
indent = indent + indent_size
|
||||
is_processed = true
|
||||
end
|
||||
|
||||
-- do not indent for nodes that starts-and-ends on same line and starts on target line (lnum)
|
||||
if q.aligned_indent[node:id()] and srow ~= erow and (srow ~= lnum - 1) then
|
||||
local metadata = q.aligned_indent[node:id()]
|
||||
local o_delim_node, is_last_in_line
|
||||
if metadata.delimiter then
|
||||
local opening_delimiter = metadata.delimiter and metadata.delimiter:sub(1, 1)
|
||||
o_delim_node, is_last_in_line = find_delimiter(bufnr, node, opening_delimiter)
|
||||
else
|
||||
o_delim_node = node
|
||||
end
|
||||
|
||||
if o_delim_node then
|
||||
if is_last_in_line then
|
||||
-- hanging indent (previous line ended with starting delimiter)
|
||||
indent = indent + indent_size * 1
|
||||
else
|
||||
local _, o_scol = o_delim_node:start()
|
||||
return math.max(indent, 0) + o_scol + (metadata.increment or 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_processed_by_row[srow] = is_processed_by_row[srow] or is_processed
|
||||
|
||||
node = node:parent()
|
||||
end
|
||||
|
||||
return indent
|
||||
end
|
||||
|
||||
local indent_funcs = {}
|
||||
|
||||
function M.attach(bufnr)
|
||||
indent_funcs[bufnr] = vim.bo.indentexpr
|
||||
vim.bo.indentexpr = "nvim_treesitter#indent()"
|
||||
vim.api.nvim_command("au Filetype " .. vim.bo.filetype .. " setlocal indentexpr=nvim_treesitter#indent()")
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
vim.bo.indentexpr = indent_funcs[bufnr]
|
||||
end
|
||||
|
||||
return M
|
174
bundle/nvim-treesitter/lua/nvim-treesitter/info.lua
Normal file
174
bundle/nvim-treesitter/lua/nvim-treesitter/info.lua
Normal file
@ -0,0 +1,174 @@
|
||||
local api = vim.api
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
|
||||
local M = {}
|
||||
|
||||
local function install_info()
|
||||
local max_len = 0
|
||||
for _, ft in pairs(parsers.available_parsers()) do
|
||||
if #ft > max_len then
|
||||
max_len = #ft
|
||||
end
|
||||
end
|
||||
|
||||
local parser_list = parsers.available_parsers()
|
||||
table.sort(parser_list)
|
||||
for _, ft in pairs(parser_list) do
|
||||
local is_installed = #api.nvim_get_runtime_file("parser/" .. ft .. ".so", false) > 0
|
||||
api.nvim_out_write(ft .. string.rep(" ", max_len - #ft + 1))
|
||||
if is_installed then
|
||||
api.nvim_out_write "[✓] installed\n"
|
||||
else
|
||||
api.nvim_out_write "[✗] not installed\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Sort a list of modules into namespaces.
|
||||
-- {'mod1', 'mod2.sub1', 'mod2.sub2', 'mod3'}
|
||||
-- ->
|
||||
-- { default = {'mod1', 'mod3'}, mod2 = {'sub1', 'sub2'}}
|
||||
local function namespace_modules(modulelist)
|
||||
local modules = {}
|
||||
for _, module in ipairs(modulelist) do
|
||||
if module:find "%." then
|
||||
local namespace, submodule = module:match "^(.*)%.(.*)$"
|
||||
if not modules[namespace] then
|
||||
modules[namespace] = {}
|
||||
end
|
||||
table.insert(modules[namespace], submodule)
|
||||
else
|
||||
if not modules.default then
|
||||
modules.default = {}
|
||||
end
|
||||
table.insert(modules.default, module)
|
||||
end
|
||||
end
|
||||
return modules
|
||||
end
|
||||
|
||||
local function longest_string_length(list)
|
||||
local length = 0
|
||||
for _, value in ipairs(list) do
|
||||
if #value > length then
|
||||
length = #value
|
||||
end
|
||||
end
|
||||
return length
|
||||
end
|
||||
|
||||
local function append_module_table(curbuf, origbuf, parserlist, namespace, modulelist)
|
||||
local maxlen_parser = longest_string_length(parserlist)
|
||||
table.sort(modulelist)
|
||||
|
||||
-- header
|
||||
local header = ">> " .. namespace .. string.rep(" ", maxlen_parser - #namespace - 1)
|
||||
for _, module in pairs(modulelist) do
|
||||
header = header .. module .. " "
|
||||
end
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, { header })
|
||||
|
||||
-- actual table
|
||||
for _, parser in ipairs(parserlist) do
|
||||
local padding = string.rep(" ", maxlen_parser - #parser + 2)
|
||||
local line = parser .. padding
|
||||
local namespace_prefix = (namespace == "default") and "" or namespace .. "."
|
||||
for _, module in pairs(modulelist) do
|
||||
local modlen = #module
|
||||
module = namespace_prefix .. module
|
||||
if configs.is_enabled(module, parser, origbuf) then
|
||||
line = line .. "✓"
|
||||
else
|
||||
line = line .. "✗"
|
||||
end
|
||||
line = line .. string.rep(" ", modlen + 1)
|
||||
end
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, { line })
|
||||
end
|
||||
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, { "" })
|
||||
end
|
||||
|
||||
local function print_info_modules(parserlist, module)
|
||||
local origbuf = api.nvim_get_current_buf()
|
||||
api.nvim_command "enew"
|
||||
local curbuf = api.nvim_get_current_buf()
|
||||
|
||||
local modules
|
||||
if module then
|
||||
modules = namespace_modules { module }
|
||||
else
|
||||
modules = namespace_modules(configs.available_modules())
|
||||
end
|
||||
|
||||
local namespaces = {}
|
||||
for k, _ in pairs(modules) do
|
||||
table.insert(namespaces, k)
|
||||
end
|
||||
table.sort(namespaces)
|
||||
|
||||
table.sort(parserlist)
|
||||
for _, namespace in ipairs(namespaces) do
|
||||
append_module_table(curbuf, origbuf, parserlist, namespace, modules[namespace])
|
||||
end
|
||||
|
||||
api.nvim_buf_set_option(curbuf, "modified", false)
|
||||
api.nvim_buf_set_option(curbuf, "buftype", "nofile")
|
||||
api.nvim_exec(
|
||||
[[
|
||||
syntax match TSModuleInfoGood /✓/
|
||||
syntax match TSModuleInfoBad /✗/
|
||||
syntax match TSModuleInfoHeader /^>>.*$/ contains=TSModuleInfoNamespace
|
||||
syntax match TSModuleInfoNamespace /^>> \w*/ contained
|
||||
syntax match TSModuleInfoParser /^[^> ]*\ze /
|
||||
highlight default TSModuleInfoGood guifg=LightGreen gui=bold
|
||||
highlight default TSModuleInfoBad guifg=Crimson
|
||||
highlight default link TSModuleInfoHeader Type
|
||||
highlight default link TSModuleInfoNamespace Statement
|
||||
highlight default link TSModuleInfoParser Identifier
|
||||
]],
|
||||
false
|
||||
)
|
||||
end
|
||||
|
||||
local function module_info(module)
|
||||
if module and not configs.get_module(module) then
|
||||
return
|
||||
end
|
||||
|
||||
local parserlist = parsers.available_parsers()
|
||||
if module then
|
||||
print_info_modules(parserlist, module)
|
||||
else
|
||||
print_info_modules(parserlist)
|
||||
end
|
||||
end
|
||||
|
||||
function M.installed_parsers()
|
||||
local installed = {}
|
||||
for _, p in pairs(parsers.available_parsers()) do
|
||||
if parsers.has_parser(p) then
|
||||
table.insert(installed, p)
|
||||
end
|
||||
end
|
||||
return installed
|
||||
end
|
||||
|
||||
M.commands = {
|
||||
TSInstallInfo = {
|
||||
run = install_info,
|
||||
args = {
|
||||
"-nargs=0",
|
||||
},
|
||||
},
|
||||
TSModuleInfo = {
|
||||
run = module_info,
|
||||
args = {
|
||||
"-nargs=?",
|
||||
"-complete=custom,nvim_treesitter#available_modules",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return M
|
600
bundle/nvim-treesitter/lua/nvim-treesitter/install.lua
Normal file
600
bundle/nvim-treesitter/lua/nvim-treesitter/install.lua
Normal file
@ -0,0 +1,600 @@
|
||||
local api = vim.api
|
||||
local fn = vim.fn
|
||||
local luv = vim.loop
|
||||
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local info = require "nvim-treesitter.info"
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local shell = require "nvim-treesitter.shell_command_selectors"
|
||||
|
||||
local M = {}
|
||||
local lockfile = {}
|
||||
|
||||
M.compilers = { vim.fn.getenv "CC", "cc", "gcc", "clang", "cl", "zig" }
|
||||
M.prefer_git = fn.has "win32" == 1
|
||||
M.command_extra_args = {}
|
||||
M.ts_generate_args = nil
|
||||
|
||||
local started_commands = 0
|
||||
local finished_commands = 0
|
||||
local failed_commands = 0
|
||||
local complete_std_output = {}
|
||||
local complete_error_output = {}
|
||||
|
||||
local function reset_progress_counter()
|
||||
if started_commands ~= finished_commands then
|
||||
return
|
||||
end
|
||||
started_commands = 0
|
||||
finished_commands = 0
|
||||
failed_commands = 0
|
||||
complete_std_output = {}
|
||||
complete_error_output = {}
|
||||
end
|
||||
|
||||
local function get_job_status()
|
||||
return "[nvim-treesitter] ["
|
||||
.. finished_commands
|
||||
.. "/"
|
||||
.. started_commands
|
||||
.. (failed_commands > 0 and ", failed: " .. failed_commands or "")
|
||||
.. "]"
|
||||
end
|
||||
|
||||
local function get_parser_install_info(lang, validate)
|
||||
local parser_config = parsers.get_parser_configs()[lang]
|
||||
|
||||
if not parser_config then
|
||||
return error("Parser not available for language " .. lang)
|
||||
end
|
||||
|
||||
local install_info = parser_config.install_info
|
||||
|
||||
if validate then
|
||||
vim.validate {
|
||||
url = { install_info.url, "string" },
|
||||
files = { install_info.files, "table" },
|
||||
}
|
||||
end
|
||||
|
||||
return install_info
|
||||
end
|
||||
|
||||
local function load_lockfile()
|
||||
local filename = utils.join_path(utils.get_package_path(), "lockfile.json")
|
||||
lockfile = vim.fn.filereadable(filename) == 1 and vim.fn.json_decode(vim.fn.readfile(filename)) or {}
|
||||
end
|
||||
|
||||
local function get_revision(lang)
|
||||
if #lockfile == 0 then
|
||||
load_lockfile()
|
||||
end
|
||||
|
||||
local install_info = get_parser_install_info(lang)
|
||||
if install_info.revision then
|
||||
return install_info.revision
|
||||
end
|
||||
|
||||
return (lockfile[lang] and lockfile[lang].revision)
|
||||
end
|
||||
|
||||
local function get_installed_revision(lang)
|
||||
local lang_file = utils.join_path(utils.get_parser_info_dir(), lang .. ".revision")
|
||||
if vim.fn.filereadable(lang_file) == 1 then
|
||||
return vim.fn.readfile(lang_file)[1]
|
||||
end
|
||||
end
|
||||
|
||||
local function is_installed(lang)
|
||||
return #api.nvim_get_runtime_file("parser/" .. lang .. ".so", false) > 0
|
||||
end
|
||||
|
||||
local function needs_update(lang)
|
||||
local revision = get_revision(lang)
|
||||
return not revision or revision ~= get_installed_revision(lang)
|
||||
end
|
||||
|
||||
local function outdated_parsers()
|
||||
return vim.tbl_filter(function(lang)
|
||||
return needs_update(lang)
|
||||
end, info.installed_parsers())
|
||||
end
|
||||
|
||||
local function onread(handle, is_stderr)
|
||||
return function(err, data)
|
||||
if data then
|
||||
if is_stderr then
|
||||
complete_error_output[handle] = (complete_error_output[handle] or "") .. data
|
||||
else
|
||||
complete_std_output[handle] = (complete_std_output[handle] or "") .. data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.iter_cmd(cmd_list, i, lang, success_message)
|
||||
if i == 1 then
|
||||
started_commands = started_commands + 1
|
||||
end
|
||||
if i == #cmd_list + 1 then
|
||||
finished_commands = finished_commands + 1
|
||||
return print(get_job_status() .. " " .. success_message)
|
||||
end
|
||||
|
||||
local attr = cmd_list[i]
|
||||
if attr.info then
|
||||
print(get_job_status() .. " " .. attr.info)
|
||||
end
|
||||
|
||||
if attr.opts and attr.opts.args and M.command_extra_args[attr.cmd] then
|
||||
vim.list_extend(attr.opts.args, M.command_extra_args[attr.cmd])
|
||||
end
|
||||
|
||||
if type(attr.cmd) == "function" then
|
||||
local ok, err = pcall(attr.cmd)
|
||||
if ok then
|
||||
M.iter_cmd(cmd_list, i + 1, lang, success_message)
|
||||
else
|
||||
failed_commands = failed_commands + 1
|
||||
finished_commands = finished_commands + 1
|
||||
return api.nvim_err_writeln(
|
||||
(attr.err or ("Failed to execute the following command:\n" .. vim.inspect(attr))) .. "\n" .. vim.inspect(err)
|
||||
)
|
||||
end
|
||||
else
|
||||
local handle
|
||||
local stdout = luv.new_pipe(false)
|
||||
local stderr = luv.new_pipe(false)
|
||||
attr.opts.stdio = { nil, stdout, stderr }
|
||||
handle = luv.spawn(
|
||||
attr.cmd,
|
||||
attr.opts,
|
||||
vim.schedule_wrap(function(code)
|
||||
if code ~= 0 then
|
||||
stdout:read_stop()
|
||||
stderr:read_stop()
|
||||
end
|
||||
stdout:close()
|
||||
stderr:close()
|
||||
handle:close()
|
||||
if code ~= 0 then
|
||||
failed_commands = failed_commands + 1
|
||||
finished_commands = finished_commands + 1
|
||||
if complete_std_output[handle] and complete_std_output[handle] ~= "" then
|
||||
print(complete_std_output[handle])
|
||||
end
|
||||
|
||||
local err_msg = complete_error_output[handle] or ""
|
||||
api.nvim_err_writeln(
|
||||
"nvim-treesitter["
|
||||
.. lang
|
||||
.. "]: "
|
||||
.. (attr.err or ("Failed to execute the following command:\n" .. vim.inspect(attr)))
|
||||
.. "\n"
|
||||
.. err_msg
|
||||
)
|
||||
return
|
||||
end
|
||||
M.iter_cmd(cmd_list, i + 1, lang, success_message)
|
||||
end)
|
||||
)
|
||||
luv.read_start(stdout, onread(handle, false))
|
||||
luv.read_start(stderr, onread(handle, true))
|
||||
end
|
||||
end
|
||||
|
||||
local function get_command(cmd)
|
||||
local options = ""
|
||||
if cmd.opts and cmd.opts.args then
|
||||
if M.command_extra_args[cmd.cmd] then
|
||||
vim.list_extend(cmd.opts.args, M.command_extra_args[cmd.cmd])
|
||||
end
|
||||
for _, opt in ipairs(cmd.opts.args) do
|
||||
options = string.format("%s %s", options, opt)
|
||||
end
|
||||
end
|
||||
|
||||
local final = string.format("%s %s", cmd.cmd, options)
|
||||
if cmd.opts and cmd.opts.cwd then
|
||||
final = shell.make_directory_change_for_command(cmd.opts.cwd, final)
|
||||
end
|
||||
return final
|
||||
end
|
||||
|
||||
local function iter_cmd_sync(cmd_list)
|
||||
for _, cmd in ipairs(cmd_list) do
|
||||
if cmd.info then
|
||||
print(cmd.info)
|
||||
end
|
||||
|
||||
if type(cmd.cmd) == "function" then
|
||||
cmd.cmd()
|
||||
else
|
||||
local ret = vim.fn.system(get_command(cmd))
|
||||
if vim.v.shell_error ~= 0 then
|
||||
print(ret)
|
||||
api.nvim_err_writeln(
|
||||
(cmd.err and cmd.err .. "\n" or "") .. "Failed to execute the following command:\n" .. vim.inspect(cmd)
|
||||
)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function run_install(cache_folder, install_folder, lang, repo, with_sync, generate_from_grammar)
|
||||
parsers.reset_cache()
|
||||
|
||||
local path_sep = utils.get_path_sep()
|
||||
|
||||
local project_name = "tree-sitter-" .. lang
|
||||
local maybe_local_path = vim.fn.expand(repo.url)
|
||||
local from_local_path = vim.fn.isdirectory(maybe_local_path) == 1
|
||||
if from_local_path then
|
||||
repo.url = maybe_local_path
|
||||
end
|
||||
|
||||
-- compile_location only needed for typescript installs.
|
||||
local compile_location
|
||||
if from_local_path then
|
||||
compile_location = repo.url
|
||||
else
|
||||
local repo_location = string.gsub(repo.location or project_name, "/", path_sep)
|
||||
compile_location = cache_folder .. path_sep .. repo_location
|
||||
end
|
||||
local parser_lib_name = install_folder .. path_sep .. lang .. ".so"
|
||||
|
||||
generate_from_grammar = repo.requires_generate_from_grammar or generate_from_grammar
|
||||
|
||||
if generate_from_grammar and vim.fn.executable "tree-sitter" ~= 1 then
|
||||
api.nvim_err_writeln "tree-sitter CLI not found: `tree-sitter` is not executable!"
|
||||
if repo.requires_generate_from_grammar then
|
||||
api.nvim_err_writeln(
|
||||
"tree-sitter CLI is needed because `"
|
||||
.. lang
|
||||
.. "` is marked that it needs "
|
||||
.. "to be generated from the grammar definitions to be compatible with nvim!"
|
||||
)
|
||||
end
|
||||
return
|
||||
else
|
||||
if not M.ts_generate_args then
|
||||
local ts_cli_version = utils.ts_cli_version()
|
||||
if ts_cli_version and vim.split(ts_cli_version, " ")[1] > "0.20.2" then
|
||||
M.ts_generate_args = { "generate", "--abi", vim.treesitter.language_version }
|
||||
else
|
||||
M.ts_generate_args = { "generate" }
|
||||
end
|
||||
end
|
||||
end
|
||||
if generate_from_grammar and vim.fn.executable "node" ~= 1 then
|
||||
api.nvim_err_writeln "Node JS not found: `node` is not executable!"
|
||||
return
|
||||
end
|
||||
local cc = shell.select_executable(M.compilers)
|
||||
if not cc then
|
||||
api.nvim_err_writeln('No C compiler found! "' .. table.concat(
|
||||
vim.tbl_filter(function(c)
|
||||
return type(c) == "string"
|
||||
end, M.compilers),
|
||||
'", "'
|
||||
) .. '" are not executable.')
|
||||
return
|
||||
end
|
||||
local revision = configs.get_update_strategy() == "lockfile" and get_revision(lang)
|
||||
|
||||
local command_list = {}
|
||||
if not from_local_path then
|
||||
vim.list_extend(command_list, { shell.select_install_rm_cmd(cache_folder, project_name) })
|
||||
vim.list_extend(
|
||||
command_list,
|
||||
shell.select_download_commands(repo, project_name, cache_folder, revision, M.prefer_git)
|
||||
)
|
||||
end
|
||||
if generate_from_grammar then
|
||||
if repo.generate_requires_npm then
|
||||
if vim.fn.executable "npm" ~= 1 then
|
||||
api.nvim_err_writeln("`" .. lang .. "` requires NPM to be installed from grammar.js")
|
||||
return
|
||||
end
|
||||
vim.list_extend(command_list, {
|
||||
{
|
||||
cmd = "npm",
|
||||
info = "Installing NPM dependencies of " .. lang .. " parser",
|
||||
err = "Error during `npm install` (required for parser generation of " .. lang .. " with npm dependencies)",
|
||||
opts = {
|
||||
args = { "install" },
|
||||
cwd = compile_location,
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
vim.list_extend(command_list, {
|
||||
{
|
||||
cmd = vim.fn.exepath "tree-sitter",
|
||||
info = "Generating source files from grammar.js...",
|
||||
err = 'Error during "tree-sitter generate"',
|
||||
opts = {
|
||||
args = M.ts_generate_args,
|
||||
cwd = compile_location,
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
vim.list_extend(command_list, {
|
||||
shell.select_compile_command(repo, cc, compile_location),
|
||||
shell.select_mv_cmd("parser.so", parser_lib_name, compile_location),
|
||||
{
|
||||
cmd = function()
|
||||
vim.fn.writefile({ revision or "" }, utils.join_path(utils.get_parser_info_dir(), lang .. ".revision"))
|
||||
end,
|
||||
},
|
||||
{ -- auto-attach modules after installation
|
||||
cmd = function()
|
||||
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if parsers.get_buf_lang(buf) == lang then
|
||||
for _, mod in ipairs(require("nvim-treesitter.configs").available_modules()) do
|
||||
require("nvim-treesitter.configs").reattach_module(mod, buf)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
},
|
||||
})
|
||||
if not from_local_path then
|
||||
vim.list_extend(command_list, { shell.select_install_rm_cmd(cache_folder, project_name) })
|
||||
end
|
||||
|
||||
if with_sync then
|
||||
if iter_cmd_sync(command_list) == true then
|
||||
print("Treesitter parser for " .. lang .. " has been installed")
|
||||
end
|
||||
else
|
||||
M.iter_cmd(command_list, 1, lang, "Treesitter parser for " .. lang .. " has been installed")
|
||||
end
|
||||
end
|
||||
|
||||
local function install_lang(lang, ask_reinstall, cache_folder, install_folder, with_sync, generate_from_grammar)
|
||||
if is_installed(lang) and ask_reinstall ~= "force" then
|
||||
if not ask_reinstall then
|
||||
return
|
||||
end
|
||||
|
||||
local yesno = fn.input(lang .. " parser already available: would you like to reinstall ? y/n: ")
|
||||
print "\n "
|
||||
if not string.match(yesno, "^y.*") then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local install_info = get_parser_install_info(lang, true)
|
||||
|
||||
run_install(cache_folder, install_folder, lang, install_info, with_sync, generate_from_grammar)
|
||||
end
|
||||
|
||||
local function install(options)
|
||||
options = options or {}
|
||||
local with_sync = options.with_sync
|
||||
local ask_reinstall = options.ask_reinstall
|
||||
local generate_from_grammar = options.generate_from_grammar
|
||||
local exclude_configured_parsers = options.exclude_configured_parsers
|
||||
|
||||
return function(...)
|
||||
if fn.executable "git" == 0 then
|
||||
return api.nvim_err_writeln "Git is required on your system to run this command"
|
||||
end
|
||||
|
||||
local cache_folder, err = utils.get_cache_dir()
|
||||
if err then
|
||||
return api.nvim_err_writeln(err)
|
||||
end
|
||||
|
||||
local install_folder, err = utils.get_parser_install_dir()
|
||||
if err then
|
||||
return api.nvim_err_writeln(err)
|
||||
end
|
||||
|
||||
local languages
|
||||
local ask
|
||||
if ... == "all" then
|
||||
languages = parsers.available_parsers()
|
||||
ask = false
|
||||
elseif ... == "maintained" then
|
||||
languages = parsers.maintained_parsers()
|
||||
ask = false
|
||||
else
|
||||
languages = vim.tbl_flatten { ... }
|
||||
ask = ask_reinstall
|
||||
end
|
||||
|
||||
if exclude_configured_parsers then
|
||||
languages = utils.difference(languages, configs.get_ignored_parser_installs())
|
||||
end
|
||||
|
||||
if #languages > 1 then
|
||||
reset_progress_counter()
|
||||
end
|
||||
|
||||
for _, lang in ipairs(languages) do
|
||||
install_lang(lang, ask, cache_folder, install_folder, with_sync, generate_from_grammar)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.update(options)
|
||||
options = options or {}
|
||||
return function(...)
|
||||
M.lockfile = {}
|
||||
reset_progress_counter()
|
||||
if ... and ... ~= "all" then
|
||||
local languages = vim.tbl_flatten { ... }
|
||||
local installed = 0
|
||||
for _, lang in ipairs(languages) do
|
||||
if (not is_installed(lang)) or (needs_update(lang)) then
|
||||
installed = installed + 1
|
||||
install {
|
||||
ask_reinstall = "force",
|
||||
with_sync = options.with_sync,
|
||||
}(lang)
|
||||
end
|
||||
end
|
||||
if installed == 0 then
|
||||
utils.notify "Parsers are up-to-date!"
|
||||
end
|
||||
else
|
||||
local parsers_to_update = configs.get_update_strategy() == "lockfile" and outdated_parsers()
|
||||
or info.installed_parsers()
|
||||
if #parsers_to_update == 0 then
|
||||
utils.notify "All parsers are up-to-date!"
|
||||
end
|
||||
for _, lang in pairs(parsers_to_update) do
|
||||
install {
|
||||
ask_reinstall = "force",
|
||||
exclude_configured_parsers = true,
|
||||
with_sync = options.with_sync,
|
||||
}(lang)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.uninstall(...)
|
||||
local path_sep = "/"
|
||||
if fn.has "win32" == 1 then
|
||||
path_sep = "\\"
|
||||
end
|
||||
|
||||
if vim.tbl_contains({ "all", "maintained" }, ...) then
|
||||
reset_progress_counter()
|
||||
local installed = info.installed_parsers()
|
||||
if ... == "maintained" then
|
||||
local maintained = parsers.maintained_parsers()
|
||||
installed = vim.tbl_filter(function(l)
|
||||
return vim.tbl_contains(maintained, l)
|
||||
end, installed)
|
||||
end
|
||||
for _, langitem in pairs(installed) do
|
||||
M.uninstall(langitem)
|
||||
end
|
||||
elseif ... then
|
||||
local languages = vim.tbl_flatten { ... }
|
||||
for _, lang in ipairs(languages) do
|
||||
local install_dir, err = utils.get_parser_install_dir()
|
||||
if err then
|
||||
return api.nvim_err_writeln(err)
|
||||
end
|
||||
|
||||
local parser_lib = install_dir .. path_sep .. lang .. ".so"
|
||||
|
||||
local command_list = {
|
||||
shell.select_rm_file_cmd(parser_lib, "Uninstalling parser for " .. lang),
|
||||
}
|
||||
M.iter_cmd(command_list, 1, lang, "Treesitter parser for " .. lang .. " has been uninstalled")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.write_lockfile(verbose, skip_langs)
|
||||
local sorted_parsers = {}
|
||||
-- Load previous lockfile
|
||||
load_lockfile()
|
||||
skip_langs = skip_langs or {}
|
||||
|
||||
for k, v in pairs(parsers.get_parser_configs()) do
|
||||
table.insert(sorted_parsers, { name = k, parser = v })
|
||||
end
|
||||
|
||||
table.sort(sorted_parsers, function(a, b)
|
||||
return a.name < b.name
|
||||
end)
|
||||
|
||||
for _, v in ipairs(sorted_parsers) do
|
||||
if not vim.tbl_contains(skip_langs, v.name) then
|
||||
-- I'm sure this can be done in aync way with iter_cmd
|
||||
local sha
|
||||
if v.parser.install_info.branch then
|
||||
sha = vim.split(
|
||||
vim.fn.systemlist(
|
||||
"git ls-remote " .. v.parser.install_info.url .. " | grep refs/heads/" .. v.parser.install_info.branch
|
||||
)[1],
|
||||
"\t"
|
||||
)[1]
|
||||
else
|
||||
sha = vim.split(vim.fn.systemlist("git ls-remote " .. v.parser.install_info.url)[1], "\t")[1]
|
||||
end
|
||||
lockfile[v.name] = { revision = sha }
|
||||
if verbose then
|
||||
print(v.name .. ": " .. sha)
|
||||
end
|
||||
else
|
||||
print("Skipping " .. v.name)
|
||||
end
|
||||
end
|
||||
|
||||
if verbose then
|
||||
print(vim.inspect(lockfile))
|
||||
end
|
||||
vim.fn.writefile(
|
||||
vim.fn.split(vim.fn.json_encode(lockfile), "\n"),
|
||||
utils.join_path(utils.get_package_path(), "lockfile.json")
|
||||
)
|
||||
end
|
||||
|
||||
M.ensure_installed = install { exclude_configured_parsers = true }
|
||||
M.ensure_installed_sync = install { with_sync = true, exclude_configured_parsers = true }
|
||||
|
||||
M.commands = {
|
||||
TSInstall = {
|
||||
run = install { ask_reinstall = true },
|
||||
["run!"] = install { ask_reinstall = "force" },
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-bang",
|
||||
"-complete=custom,nvim_treesitter#installable_parsers",
|
||||
},
|
||||
},
|
||||
TSInstallFromGrammar = {
|
||||
run = install { generate_from_grammar = true, ask_reinstall = true },
|
||||
["run!"] = install { generate_from_grammar = true, ask_reinstall = "force" },
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-bang",
|
||||
"-complete=custom,nvim_treesitter#installable_parsers",
|
||||
},
|
||||
},
|
||||
TSInstallSync = {
|
||||
run = install { with_sync = true, ask_reinstall = true },
|
||||
["run!"] = install { with_sync = true, ask_reinstall = "force" },
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-bang",
|
||||
"-complete=custom,nvim_treesitter#installable_parsers",
|
||||
},
|
||||
},
|
||||
TSUpdate = {
|
||||
run = M.update {},
|
||||
args = {
|
||||
"-nargs=*",
|
||||
"-complete=custom,nvim_treesitter#installed_parsers",
|
||||
},
|
||||
},
|
||||
TSUpdateSync = {
|
||||
run = M.update { with_sync = true },
|
||||
args = {
|
||||
"-nargs=*",
|
||||
"-complete=custom,nvim_treesitter#installed_parsers",
|
||||
},
|
||||
},
|
||||
TSUninstall = {
|
||||
run = M.uninstall,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,nvim_treesitter#installed_parsers",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return M
|
349
bundle/nvim-treesitter/lua/nvim-treesitter/locals.lua
Normal file
349
bundle/nvim-treesitter/lua/nvim-treesitter/locals.lua
Normal file
@ -0,0 +1,349 @@
|
||||
-- Functions to handle locals
|
||||
-- Locals are a generalization of definition and scopes
|
||||
-- its the way nvim-treesitter uses to "understand" the code
|
||||
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.collect_locals(bufnr)
|
||||
return queries.collect_group_results(bufnr, "locals")
|
||||
end
|
||||
|
||||
-- Iterates matches from a locals query file.
|
||||
-- @param bufnr the buffer
|
||||
-- @param root the root node
|
||||
function M.iter_locals(bufnr, root)
|
||||
return queries.iter_group_results(bufnr, "locals", root)
|
||||
end
|
||||
|
||||
function M.get_locals(bufnr)
|
||||
return queries.get_matches(bufnr, "locals")
|
||||
end
|
||||
|
||||
--- Creates unique id for a node based on text and range
|
||||
-- @param scope: the scope node of the definition
|
||||
-- @param bufnr: the buffer
|
||||
-- @param node_text: the node text to use
|
||||
-- @returns a string id
|
||||
function M.get_definition_id(scope, node_text)
|
||||
-- Add a valid starting character in case node text doesn't start with a valid one.
|
||||
return table.concat({ "k", node_text or "", scope:range() }, "_")
|
||||
end
|
||||
|
||||
function M.get_definitions(bufnr)
|
||||
local locals = M.get_locals(bufnr)
|
||||
|
||||
local defs = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc.definition then
|
||||
table.insert(defs, loc.definition)
|
||||
end
|
||||
end
|
||||
|
||||
return defs
|
||||
end
|
||||
|
||||
function M.get_scopes(bufnr)
|
||||
local locals = M.get_locals(bufnr)
|
||||
|
||||
local scopes = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc.scope and loc.scope.node then
|
||||
table.insert(scopes, loc.scope.node)
|
||||
end
|
||||
end
|
||||
|
||||
return scopes
|
||||
end
|
||||
|
||||
function M.get_references(bufnr)
|
||||
local locals = M.get_locals(bufnr)
|
||||
|
||||
local refs = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc.reference and loc.reference.node then
|
||||
table.insert(refs, loc.reference.node)
|
||||
end
|
||||
end
|
||||
|
||||
return refs
|
||||
end
|
||||
|
||||
--- Gets a table with all the scopes containing a node
|
||||
-- The order is from most specific to least (bottom up)
|
||||
function M.get_scope_tree(node, bufnr)
|
||||
local scopes = {}
|
||||
|
||||
for scope in M.iter_scope_tree(node, bufnr) do
|
||||
table.insert(scopes, scope)
|
||||
end
|
||||
|
||||
return scopes
|
||||
end
|
||||
|
||||
--- Iterates over a nodes scopes moving from the bottom up
|
||||
function M.iter_scope_tree(node, bufnr)
|
||||
local last_node = node
|
||||
return function()
|
||||
if not last_node then
|
||||
return
|
||||
end
|
||||
|
||||
local scope = M.containing_scope(last_node, bufnr, false) or ts_utils.get_root_for_node(node)
|
||||
|
||||
last_node = scope:parent()
|
||||
|
||||
return scope
|
||||
end
|
||||
end
|
||||
|
||||
-- Gets a table of all nodes and their 'kinds' from a locals list
|
||||
-- @param local_def the local list result
|
||||
-- @returns a list of node entries
|
||||
function M.get_local_nodes(local_def)
|
||||
local result = {}
|
||||
|
||||
M.recurse_local_nodes(local_def, function(def, node, kind)
|
||||
table.insert(result, vim.tbl_extend("keep", { kind = kind }, def))
|
||||
end)
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- Recurse locals results until a node is found.
|
||||
-- The accumulator function is given
|
||||
-- * The table of the node
|
||||
-- * The node
|
||||
-- * The full definition match `@definition.var.something` -> 'var.something'
|
||||
-- * The last definition match `@definition.var.something` -> 'something'
|
||||
-- @param The locals result
|
||||
-- @param The accumulator function
|
||||
-- @param The full match path to append to
|
||||
-- @param The last match
|
||||
function M.recurse_local_nodes(local_def, accumulator, full_match, last_match)
|
||||
if type(local_def) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
if local_def.node then
|
||||
accumulator(local_def, local_def.node, full_match, last_match)
|
||||
else
|
||||
for match_key, def in pairs(local_def) do
|
||||
M.recurse_local_nodes(def, accumulator, full_match and (full_match .. "." .. match_key) or match_key, match_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Get a single dimension table to look definition nodes.
|
||||
-- Keys are generated by using the range of the containing scope and the text of the definition node.
|
||||
-- This makes looking up a definition for a given scope a simple key lookup.
|
||||
--
|
||||
-- This is memoized by buffer tick. If the function is called in succession
|
||||
-- without the buffer tick changing, then the previous result will be used
|
||||
-- since the syntax tree hasn't changed.
|
||||
--
|
||||
-- Usage lookups require finding the definition of the node, so `find_definition`
|
||||
-- is called very frequently, which is why this lookup must be fast as possible.
|
||||
--
|
||||
-- @param bufnr: the buffer
|
||||
-- @returns a table for looking up definitions
|
||||
M.get_definitions_lookup_table = ts_utils.memoize_by_buf_tick(function(bufnr)
|
||||
local definitions = M.get_definitions(bufnr)
|
||||
local result = {}
|
||||
|
||||
for _, definition in ipairs(definitions) do
|
||||
for _, node_entry in ipairs(M.get_local_nodes(definition)) do
|
||||
local scopes = M.get_definition_scopes(node_entry.node, bufnr, node_entry.scope)
|
||||
-- Always use the highest valid scope
|
||||
local scope = scopes[#scopes]
|
||||
local node_text = ts_utils.get_node_text(node_entry.node, bufnr)[1]
|
||||
local id = M.get_definition_id(scope, node_text)
|
||||
|
||||
result[id] = node_entry
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end)
|
||||
|
||||
--- Gets all the scopes of a definition based on the scope type
|
||||
-- Scope types can be
|
||||
--
|
||||
-- "parent": Uses the parent of the containing scope, basically, skipping a scope
|
||||
-- "global": Uses the top most scope
|
||||
-- "local": Uses the containing scope of the definition. This is the default
|
||||
--
|
||||
-- @param node: the definition node
|
||||
-- @param bufnr: the buffer
|
||||
-- @param scope_type: the scope type
|
||||
function M.get_definition_scopes(node, bufnr, scope_type)
|
||||
local scopes = {}
|
||||
local scope_count = 1
|
||||
|
||||
-- Definition is valid for the containing scope
|
||||
-- and the containing scope of that scope
|
||||
if scope_type == "parent" then
|
||||
scope_count = 2
|
||||
-- Definition is valid in all parent scopes
|
||||
elseif scope_type == "global" then
|
||||
scope_count = nil
|
||||
end
|
||||
|
||||
local i = 0
|
||||
for scope in M.iter_scope_tree(node, bufnr) do
|
||||
table.insert(scopes, scope)
|
||||
i = i + 1
|
||||
|
||||
if scope_count and i >= scope_count then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return scopes
|
||||
end
|
||||
|
||||
function M.find_definition(node, bufnr)
|
||||
local def_lookup = M.get_definitions_lookup_table(bufnr)
|
||||
local node_text = ts_utils.get_node_text(node, bufnr)[1]
|
||||
|
||||
for scope in M.iter_scope_tree(node, bufnr) do
|
||||
local id = M.get_definition_id(scope, node_text)
|
||||
|
||||
if def_lookup[id] then
|
||||
local entry = def_lookup[id]
|
||||
|
||||
return entry.node, scope, entry.kind
|
||||
end
|
||||
end
|
||||
|
||||
return node, ts_utils.get_root_for_node(node), nil
|
||||
end
|
||||
|
||||
-- Finds usages of a node in a given scope.
|
||||
-- @param node the node to find usages for
|
||||
-- @param scope_node the node to look within
|
||||
-- @returns a list of nodes
|
||||
function M.find_usages(node, scope_node, bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local node_text = ts_utils.get_node_text(node, bufnr)[1]
|
||||
|
||||
if not node_text or #node_text < 1 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local scope_node = scope_node or ts_utils.get_root_for_node(node)
|
||||
local usages = {}
|
||||
|
||||
for match in M.iter_locals(bufnr, scope_node) do
|
||||
if
|
||||
match.reference
|
||||
and match.reference.node
|
||||
and ts_utils.get_node_text(match.reference.node, bufnr)[1] == node_text
|
||||
then
|
||||
local def_node, _, kind = M.find_definition(match.reference.node, bufnr)
|
||||
|
||||
if kind == nil or def_node == node then
|
||||
table.insert(usages, match.reference.node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return usages
|
||||
end
|
||||
|
||||
function M.containing_scope(node, bufnr, allow_scope)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local allow_scope = allow_scope == nil or allow_scope == true
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local iter_node = node
|
||||
|
||||
while iter_node ~= nil and not vim.tbl_contains(scopes, iter_node) do
|
||||
iter_node = iter_node:parent()
|
||||
end
|
||||
|
||||
return iter_node or (allow_scope and node or nil)
|
||||
end
|
||||
|
||||
function M.nested_scope(node, cursor_pos)
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local row = cursor_pos.row
|
||||
local col = cursor_pos.col
|
||||
local scope = M.containing_scope(node)
|
||||
|
||||
for _, child in ipairs(ts_utils.get_named_children(scope)) do
|
||||
local row_, col_ = child:start()
|
||||
if vim.tbl_contains(scopes, child) and ((row_ + 1 == row and col_ > col) or row_ + 1 > row) then
|
||||
return child
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.next_scope(node)
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local scope = M.containing_scope(node)
|
||||
|
||||
local parent = scope:parent()
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
|
||||
local is_prev = true
|
||||
for _, child in ipairs(ts_utils.get_named_children(parent)) do
|
||||
if child == scope then
|
||||
is_prev = false
|
||||
elseif not is_prev and vim.tbl_contains(scopes, child) then
|
||||
return child
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.previous_scope(node)
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local scope = M.containing_scope(node)
|
||||
|
||||
local parent = scope:parent()
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
|
||||
local is_prev = true
|
||||
local children = ts_utils.get_named_children(parent)
|
||||
for i = #children, 1, -1 do
|
||||
if children[i] == scope then
|
||||
is_prev = false
|
||||
elseif not is_prev and vim.tbl_contains(scopes, children[i]) then
|
||||
return children[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
1129
bundle/nvim-treesitter/lua/nvim-treesitter/parsers.lua
Normal file
1129
bundle/nvim-treesitter/lua/nvim-treesitter/parsers.lua
Normal file
File diff suppressed because it is too large
Load Diff
390
bundle/nvim-treesitter/lua/nvim-treesitter/query.lua
Normal file
390
bundle/nvim-treesitter/lua/nvim-treesitter/query.lua
Normal file
@ -0,0 +1,390 @@
|
||||
local api = vim.api
|
||||
local tsq = require "vim.treesitter.query"
|
||||
local tsrange = require "nvim-treesitter.tsrange"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local caching = require "nvim-treesitter.caching"
|
||||
|
||||
local M = {}
|
||||
|
||||
local EMPTY_ITER = function() end
|
||||
|
||||
M.built_in_query_groups = { "highlights", "locals", "folds", "indents", "injections" }
|
||||
|
||||
-- Creates a function that checks whether a given query exists
|
||||
-- for a specific language.
|
||||
local function get_query_guard(query)
|
||||
return function(lang)
|
||||
return M.has_query_files(lang, query)
|
||||
end
|
||||
end
|
||||
|
||||
for _, query in ipairs(M.built_in_query_groups) do
|
||||
M["has_" .. query] = get_query_guard(query)
|
||||
end
|
||||
|
||||
function M.available_query_groups()
|
||||
local query_files = api.nvim_get_runtime_file("queries/*/*.scm", true)
|
||||
local groups = {}
|
||||
for _, f in ipairs(query_files) do
|
||||
groups[vim.fn.fnamemodify(f, ":t:r")] = true
|
||||
end
|
||||
local list = {}
|
||||
for k, _ in pairs(groups) do
|
||||
table.insert(list, k)
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
do
|
||||
local query_cache = caching.create_buffer_cache()
|
||||
|
||||
local function update_cached_matches(bufnr, changed_tick, query_group)
|
||||
query_cache.set(query_group, bufnr, {
|
||||
tick = changed_tick,
|
||||
cache = M.collect_group_results(bufnr, query_group) or {},
|
||||
})
|
||||
end
|
||||
|
||||
function M.get_matches(bufnr, query_group)
|
||||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local cached_local = query_cache.get(query_group, bufnr)
|
||||
if not cached_local or api.nvim_buf_get_changedtick(bufnr) > cached_local.tick then
|
||||
update_cached_matches(bufnr, api.nvim_buf_get_changedtick(bufnr), query_group)
|
||||
end
|
||||
|
||||
return query_cache.get(query_group, bufnr).cache
|
||||
end
|
||||
end
|
||||
|
||||
local function runtime_queries(lang, query_name)
|
||||
return api.nvim_get_runtime_file(string.format("queries/%s/%s.scm", lang, query_name), true) or {}
|
||||
end
|
||||
|
||||
local query_files_cache = {}
|
||||
function M.has_query_files(lang, query_name)
|
||||
if not query_files_cache[lang] then
|
||||
query_files_cache[lang] = {}
|
||||
end
|
||||
if query_files_cache[lang][query_name] == nil then
|
||||
local files = runtime_queries(lang, query_name)
|
||||
query_files_cache[lang][query_name] = files and #files > 0
|
||||
end
|
||||
return query_files_cache[lang][query_name]
|
||||
end
|
||||
|
||||
do
|
||||
local mt = {}
|
||||
mt.__index = function(tbl, key)
|
||||
if rawget(tbl, key) == nil then
|
||||
rawset(tbl, key, {})
|
||||
end
|
||||
return rawget(tbl, key)
|
||||
end
|
||||
|
||||
-- cache will auto set the table for each lang if it is nil
|
||||
local cache = setmetatable({}, mt)
|
||||
|
||||
--- Same as `vim.treesitter.query` except will return cached values
|
||||
function M.get_query(lang, query_name)
|
||||
if cache[lang][query_name] == nil then
|
||||
cache[lang][query_name] = tsq.get_query(lang, query_name)
|
||||
end
|
||||
|
||||
return cache[lang][query_name]
|
||||
end
|
||||
|
||||
--- Invalidates the query file cache.
|
||||
--- If lang and query_name is both present, will reload for only the lang and query_name.
|
||||
--- If only lang is present, will reload all query_names for that lang
|
||||
--- If none are present, will reload everything
|
||||
function M.invalidate_query_cache(lang, query_name)
|
||||
if lang and query_name then
|
||||
cache[lang][query_name] = nil
|
||||
if query_files_cache[lang] then
|
||||
query_files_cache[lang][query_name] = nil
|
||||
end
|
||||
elseif lang and not query_name then
|
||||
query_files_cache[lang] = nil
|
||||
for query_name, _ in pairs(cache[lang]) do
|
||||
M.invalidate_query_cache(lang, query_name)
|
||||
end
|
||||
elseif not lang and not query_name then
|
||||
query_files_cache = {}
|
||||
for lang, _ in pairs(cache) do
|
||||
for query_name, _ in pairs(cache[lang]) do
|
||||
M.invalidate_query_cache(lang, query_name)
|
||||
end
|
||||
end
|
||||
else
|
||||
error "Cannot have query_name by itself!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- This function is meant for an autocommand and not to be used. Only use if file is a query file.
|
||||
function M.invalidate_query_file(fname)
|
||||
local fnamemodify = vim.fn.fnamemodify
|
||||
M.invalidate_query_cache(fnamemodify(fname, ":p:h:t"), fnamemodify(fname, ":t:r"))
|
||||
end
|
||||
|
||||
local function prepare_query(bufnr, query_name, root, root_lang)
|
||||
local buf_lang = parsers.get_buf_lang(bufnr)
|
||||
|
||||
if not buf_lang then
|
||||
return
|
||||
end
|
||||
|
||||
local parser = parsers.get_parser(bufnr, buf_lang)
|
||||
if not parser then
|
||||
return
|
||||
end
|
||||
|
||||
if not root then
|
||||
local first_tree = parser:trees()[1]
|
||||
|
||||
if first_tree then
|
||||
root = first_tree:root()
|
||||
end
|
||||
end
|
||||
|
||||
if not root then
|
||||
return
|
||||
end
|
||||
|
||||
local range = { root:range() }
|
||||
|
||||
if not root_lang then
|
||||
local lang_tree = parser:language_for_range(range)
|
||||
|
||||
if lang_tree then
|
||||
root_lang = lang_tree:lang()
|
||||
end
|
||||
end
|
||||
|
||||
if not root_lang then
|
||||
return
|
||||
end
|
||||
|
||||
local query = M.get_query(root_lang, query_name)
|
||||
if not query then
|
||||
return
|
||||
end
|
||||
|
||||
return query,
|
||||
{
|
||||
root = root,
|
||||
source = bufnr,
|
||||
start = range[1],
|
||||
-- The end row is exclusive so we need to add 1 to it.
|
||||
stop = range[3] + 1,
|
||||
}
|
||||
end
|
||||
|
||||
function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
|
||||
-- A function that splits a string on '.'
|
||||
local function split(string)
|
||||
local t = {}
|
||||
for str in string.gmatch(string, "([^.]+)") do
|
||||
table.insert(t, str)
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
-- Given a path (i.e. a List(String)) this functions inserts value at path
|
||||
local function insert_to_path(object, path, value)
|
||||
local curr_obj = object
|
||||
|
||||
for index = 1, (#path - 1) do
|
||||
if curr_obj[path[index]] == nil then
|
||||
curr_obj[path[index]] = {}
|
||||
end
|
||||
|
||||
curr_obj = curr_obj[path[index]]
|
||||
end
|
||||
|
||||
curr_obj[path[#path]] = value
|
||||
end
|
||||
|
||||
local matches = query:iter_matches(qnode, bufnr, start_row, end_row)
|
||||
|
||||
local function iterator()
|
||||
local pattern, match = matches()
|
||||
if pattern ~= nil then
|
||||
local prepared_match = {}
|
||||
|
||||
-- Extract capture names from each match
|
||||
for id, node in pairs(match) do
|
||||
local name = query.captures[id] -- name of the capture in the query
|
||||
if name ~= nil then
|
||||
local path = split(name .. ".node")
|
||||
insert_to_path(prepared_match, path, node)
|
||||
end
|
||||
end
|
||||
|
||||
-- Add some predicates for testing
|
||||
local preds = query.info.patterns[pattern]
|
||||
if preds then
|
||||
for _, pred in pairs(preds) do
|
||||
-- functions
|
||||
if pred[1] == "set!" and type(pred[2]) == "string" then
|
||||
insert_to_path(prepared_match, split(pred[2]), pred[3])
|
||||
end
|
||||
if pred[1] == "make-range!" and type(pred[2]) == "string" and #pred == 4 then
|
||||
insert_to_path(
|
||||
prepared_match,
|
||||
split(pred[2] .. ".node"),
|
||||
tsrange.TSRange.from_nodes(bufnr, match[pred[3]], match[pred[4]])
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return prepared_match
|
||||
end
|
||||
end
|
||||
return iterator
|
||||
end
|
||||
|
||||
--- Return all nodes corresponding to a specific capture path (like @definition.var, @reference.type)
|
||||
-- Works like M.get_references or M.get_scopes except you can choose the capture
|
||||
-- Can also be a nested capture like @definition.function to get all nodes defining a function.
|
||||
--
|
||||
-- @param bufnr the buffer
|
||||
-- @param captures a single string or a list of strings
|
||||
-- @param query_group the name of query group (highlights or injections for example)
|
||||
-- @param root (optional) node from where to start the search
|
||||
-- @param lang (optional) the language from where to get the captures.
|
||||
-- Root nodes can have several languages.
|
||||
function M.get_capture_matches(bufnr, captures, query_group, root, lang)
|
||||
if type(captures) == "string" then
|
||||
captures = { captures }
|
||||
end
|
||||
local strip_captures = {}
|
||||
for i, capture in ipairs(captures) do
|
||||
if capture:sub(1, 1) ~= "@" then
|
||||
error 'Captures must start with "@"'
|
||||
return
|
||||
end
|
||||
-- Remove leading "@".
|
||||
strip_captures[i] = capture:sub(2)
|
||||
end
|
||||
|
||||
local matches = {}
|
||||
for match in M.iter_group_results(bufnr, query_group, root, lang) do
|
||||
for _, capture in ipairs(strip_captures) do
|
||||
local insert = utils.get_at_path(match, capture)
|
||||
if insert then
|
||||
table.insert(matches, insert)
|
||||
end
|
||||
end
|
||||
end
|
||||
return matches
|
||||
end
|
||||
|
||||
function M.iter_captures(bufnr, query_name, root, lang)
|
||||
local query, params = prepare_query(bufnr, query_name, root, lang)
|
||||
if not query then
|
||||
return EMPTY_ITER
|
||||
end
|
||||
|
||||
local iter = query:iter_captures(params.root, params.source, params.start, params.stop)
|
||||
|
||||
local function wrapped_iter()
|
||||
local id, node, metadata = iter()
|
||||
if not id then
|
||||
return
|
||||
end
|
||||
|
||||
local name = query.captures[id]
|
||||
if string.sub(name, 1, 1) == "_" then
|
||||
return wrapped_iter()
|
||||
end
|
||||
|
||||
return name, node, metadata
|
||||
end
|
||||
|
||||
return wrapped_iter
|
||||
end
|
||||
|
||||
function M.find_best_match(bufnr, capture_string, query_group, filter_predicate, scoring_function, root)
|
||||
if string.sub(capture_string, 1, 1) == "@" then
|
||||
--remove leading "@"
|
||||
capture_string = string.sub(capture_string, 2)
|
||||
end
|
||||
|
||||
local best
|
||||
local best_score
|
||||
|
||||
for maybe_match in M.iter_group_results(bufnr, query_group, root) do
|
||||
local match = utils.get_at_path(maybe_match, capture_string)
|
||||
|
||||
if match and filter_predicate(match) then
|
||||
local current_score = scoring_function(match)
|
||||
if not best then
|
||||
best = match
|
||||
best_score = current_score
|
||||
end
|
||||
if current_score > best_score then
|
||||
best = match
|
||||
best_score = current_score
|
||||
end
|
||||
end
|
||||
end
|
||||
return best
|
||||
end
|
||||
|
||||
-- Iterates matches from a query file.
|
||||
-- @param bufnr the buffer
|
||||
-- @param query_group the query file to use
|
||||
-- @param root the root node
|
||||
-- @param root the root node lang, if known
|
||||
function M.iter_group_results(bufnr, query_group, root, root_lang)
|
||||
local query, params = prepare_query(bufnr, query_group, root, root_lang)
|
||||
if not query then
|
||||
return EMPTY_ITER
|
||||
end
|
||||
|
||||
return M.iter_prepared_matches(query, params.root, params.source, params.start, params.stop)
|
||||
end
|
||||
|
||||
function M.collect_group_results(bufnr, query_group, root, lang)
|
||||
local matches = {}
|
||||
|
||||
for prepared_match in M.iter_group_results(bufnr, query_group, root, lang) do
|
||||
table.insert(matches, prepared_match)
|
||||
end
|
||||
|
||||
return matches
|
||||
end
|
||||
|
||||
--- Same as get_capture_matches except this will recursively get matches for every language in the tree.
|
||||
-- @param bufnr The bufnr
|
||||
-- @param capture_or_fn The capture to get. If a function is provided then that
|
||||
-- function will be used to resolve both the capture and query argument.
|
||||
-- The function can return `nil` to ignore that tree.
|
||||
-- @param query_type The query to get the capture from. This is ignore if a function is provided
|
||||
-- for the captuer argument.
|
||||
function M.get_capture_matches_recursively(bufnr, capture_or_fn, query_type)
|
||||
local type_fn = type(capture_or_fn) == "function" and capture_or_fn
|
||||
or function()
|
||||
return capture_or_fn, query_type
|
||||
end
|
||||
local parser = parsers.get_parser(bufnr)
|
||||
local matches = {}
|
||||
|
||||
if parser then
|
||||
parser:for_each_tree(function(tree, lang_tree)
|
||||
local lang = lang_tree:lang()
|
||||
local capture, type_ = type_fn(lang, tree, lang_tree)
|
||||
|
||||
if capture then
|
||||
vim.list_extend(matches, M.get_capture_matches(bufnr, capture, type_, tree:root(), lang))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
return matches
|
||||
end
|
||||
|
||||
return M
|
130
bundle/nvim-treesitter/lua/nvim-treesitter/query_predicates.lua
Normal file
130
bundle/nvim-treesitter/lua/nvim-treesitter/query_predicates.lua
Normal file
@ -0,0 +1,130 @@
|
||||
local query = require "vim.treesitter.query"
|
||||
|
||||
local function error(str)
|
||||
vim.api.nvim_err_writeln(str)
|
||||
end
|
||||
|
||||
local function valid_args(name, pred, count, strict_count)
|
||||
local arg_count = #pred - 1
|
||||
|
||||
if strict_count then
|
||||
if arg_count ~= count then
|
||||
error(string.format("%s must have exactly %d arguments", name, count))
|
||||
return false
|
||||
end
|
||||
elseif arg_count < count then
|
||||
error(string.format("%s must have at least %d arguments", name, count))
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
query.add_predicate("nth?", function(match, pattern, bufnr, pred)
|
||||
if not valid_args("nth?", pred, 2, true) then
|
||||
return
|
||||
end
|
||||
|
||||
local node = match[pred[2]]
|
||||
local n = tonumber(pred[3])
|
||||
if node and node:parent() and node:parent():named_child_count() > n then
|
||||
return node:parent():named_child(n) == node
|
||||
end
|
||||
|
||||
return false
|
||||
end)
|
||||
|
||||
local function has_ancestor(match, pattern, bufnr, pred)
|
||||
if not valid_args(pred[1], pred, 2) then
|
||||
return
|
||||
end
|
||||
|
||||
local node = match[pred[2]]
|
||||
local ancestor_types = { unpack(pred, 3) }
|
||||
if not node then
|
||||
return true
|
||||
end
|
||||
|
||||
local just_direct_parent = pred[1]:find("has-parent", 1, true)
|
||||
|
||||
node = node:parent()
|
||||
while node do
|
||||
if vim.tbl_contains(ancestor_types, node:type()) then
|
||||
return true
|
||||
end
|
||||
if just_direct_parent then
|
||||
node = nil
|
||||
else
|
||||
node = node:parent()
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
query.add_predicate("has-ancestor?", has_ancestor)
|
||||
|
||||
query.add_predicate("has-parent?", has_ancestor)
|
||||
|
||||
query.add_predicate("is?", function(match, pattern, bufnr, pred)
|
||||
if not valid_args("is?", pred, 2) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Avoid circular dependencies
|
||||
local locals = require "nvim-treesitter.locals"
|
||||
local node = match[pred[2]]
|
||||
local types = { unpack(pred, 3) }
|
||||
|
||||
if not node then
|
||||
return true
|
||||
end
|
||||
|
||||
local _, _, kind = locals.find_definition(node, bufnr)
|
||||
|
||||
return vim.tbl_contains(types, kind)
|
||||
end)
|
||||
|
||||
query.add_predicate("has-type?", function(match, pattern, bufnr, pred)
|
||||
if not valid_args(pred[1], pred, 2) then
|
||||
return
|
||||
end
|
||||
|
||||
local node = match[pred[2]]
|
||||
local types = { unpack(pred, 3) }
|
||||
|
||||
if not node then
|
||||
return true
|
||||
end
|
||||
|
||||
return vim.tbl_contains(types, node:type())
|
||||
end)
|
||||
|
||||
-- Just avoid some annoying warnings for this directive
|
||||
query.add_directive("make-range!", function() end)
|
||||
|
||||
query.add_directive("downcase!", function(match, _, bufnr, pred, metadata)
|
||||
local text, key, value
|
||||
|
||||
if #pred == 3 then
|
||||
-- (#downcase! @capture "key")
|
||||
key = pred[3]
|
||||
value = metadata[pred[2]][key]
|
||||
else
|
||||
-- (#downcase! "key")
|
||||
key = pred[2]
|
||||
value = metadata[key]
|
||||
end
|
||||
|
||||
if type(value) == "string" then
|
||||
text = value
|
||||
else
|
||||
local node = match[value]
|
||||
text = query.get_node_text(node, bufnr) or ""
|
||||
end
|
||||
|
||||
if #pred == 3 then
|
||||
metadata[pred[2]][key] = string.lower(text)
|
||||
else
|
||||
metadata[key] = string.lower(text)
|
||||
end
|
||||
end)
|
@ -0,0 +1,264 @@
|
||||
local fn = vim.fn
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.select_mkdir_cmd(directory, cwd, info_msg)
|
||||
if fn.has "win32" == 1 then
|
||||
return {
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { "/C", "mkdir", directory },
|
||||
cwd = cwd,
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not create " .. directory,
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = "mkdir",
|
||||
opts = {
|
||||
args = { directory },
|
||||
cwd = cwd,
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not create " .. directory,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_rm_file_cmd(file, info_msg)
|
||||
if fn.has "win32" == 1 then
|
||||
return {
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { "/C", "if", "exist", file, "del", file },
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not delete " .. file,
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = "rm",
|
||||
opts = {
|
||||
args = { file },
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not delete " .. file,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_executable(executables)
|
||||
return vim.tbl_filter(function(c)
|
||||
return c ~= vim.NIL and fn.executable(c) == 1
|
||||
end, executables)[1]
|
||||
end
|
||||
|
||||
function M.select_compiler_args(repo, compiler)
|
||||
if string.match(compiler, "cl$") or string.match(compiler, "cl.exe$") then
|
||||
return {
|
||||
"/Fe:",
|
||||
"parser.so",
|
||||
"/Isrc",
|
||||
repo.files,
|
||||
"-Os",
|
||||
"/LD",
|
||||
}
|
||||
elseif string.match(compiler, "zig$") or string.match(compiler, "zig.exe$") then
|
||||
return {
|
||||
"c++",
|
||||
"-o",
|
||||
"parser.so",
|
||||
repo.files,
|
||||
"-lc",
|
||||
"-Isrc",
|
||||
"-shared",
|
||||
"-Os",
|
||||
}
|
||||
else
|
||||
local args = {
|
||||
"-o",
|
||||
"parser.so",
|
||||
"-I./src",
|
||||
repo.files,
|
||||
"-shared",
|
||||
"-Os",
|
||||
"-lstdc++",
|
||||
}
|
||||
if fn.has "win32" == 0 then
|
||||
table.insert(args, "-fPIC")
|
||||
end
|
||||
return args
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_compile_command(repo, cc, compile_location)
|
||||
local make = M.select_executable { "gmake", "make" }
|
||||
if
|
||||
string.match(cc, "cl$")
|
||||
or string.match(cc, "cl.exe$")
|
||||
or not repo.use_makefile
|
||||
or fn.has "win32" == 1
|
||||
or not make
|
||||
then
|
||||
return {
|
||||
cmd = cc,
|
||||
info = "Compiling...",
|
||||
err = "Error during compilation",
|
||||
opts = {
|
||||
args = vim.tbl_flatten(M.select_compiler_args(repo, cc)),
|
||||
cwd = compile_location,
|
||||
},
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = make,
|
||||
info = "Compiling...",
|
||||
err = "Error during compilation",
|
||||
opts = {
|
||||
args = {
|
||||
"--makefile=" .. utils.join_path(utils.get_package_path(), "scripts", "compile_parsers.makefile"),
|
||||
"CC=" .. cc,
|
||||
"CXX_STANDARD=" .. (repo.cxx_standard or "c++14"),
|
||||
},
|
||||
cwd = compile_location,
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_install_rm_cmd(cache_folder, project_name)
|
||||
if fn.has "win32" == 1 then
|
||||
local dir = cache_folder .. "\\" .. project_name
|
||||
return {
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { "/C", "if", "exist", dir, "rmdir", "/s", "/q", dir },
|
||||
},
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = "rm",
|
||||
opts = {
|
||||
args = { "-rf", cache_folder .. "/" .. project_name },
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_mv_cmd(from, to, cwd)
|
||||
if fn.has "win32" == 1 then
|
||||
return {
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { "/C", "move", "/Y", from, to },
|
||||
cwd = cwd,
|
||||
},
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = "mv",
|
||||
opts = {
|
||||
args = { from, to },
|
||||
cwd = cwd,
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_download_commands(repo, project_name, cache_folder, revision, prefer_git)
|
||||
local can_use_tar = vim.fn.executable "tar" == 1 and vim.fn.executable "curl" == 1
|
||||
local is_github = repo.url:find("github.com", 1, true)
|
||||
local is_gitlab = repo.url:find("gitlab.com", 1, true)
|
||||
|
||||
revision = revision or repo.branch or "master"
|
||||
|
||||
if can_use_tar and (is_github or is_gitlab) and not prefer_git then
|
||||
local path_sep = utils.get_path_sep()
|
||||
local url = repo.url:gsub(".git$", "")
|
||||
|
||||
return {
|
||||
M.select_install_rm_cmd(cache_folder, project_name .. "-tmp"),
|
||||
{
|
||||
cmd = "curl",
|
||||
info = "Downloading...",
|
||||
err = "Error during download, please verify your internet connection",
|
||||
opts = {
|
||||
args = {
|
||||
"--silent",
|
||||
"-L", -- follow redirects
|
||||
is_github and url .. "/archive/" .. revision .. ".tar.gz"
|
||||
or url .. "/-/archive/" .. revision .. "/" .. project_name .. "-" .. revision .. ".tar.gz",
|
||||
"--output",
|
||||
project_name .. ".tar.gz",
|
||||
},
|
||||
cwd = cache_folder,
|
||||
},
|
||||
},
|
||||
M.select_mkdir_cmd(project_name .. "-tmp", cache_folder, "Creating temporary directory"),
|
||||
{
|
||||
cmd = "tar",
|
||||
info = "Extracting...",
|
||||
err = "Error during tarball extraction.",
|
||||
opts = {
|
||||
args = {
|
||||
"-xvzf",
|
||||
project_name .. ".tar.gz",
|
||||
"-C",
|
||||
project_name .. "-tmp",
|
||||
},
|
||||
cwd = cache_folder,
|
||||
},
|
||||
},
|
||||
M.select_rm_file_cmd(cache_folder .. path_sep .. project_name .. ".tar.gz"),
|
||||
M.select_mv_cmd(
|
||||
utils.join_path(project_name .. "-tmp", url:match "[^/]-$" .. "-" .. revision),
|
||||
project_name,
|
||||
cache_folder
|
||||
),
|
||||
M.select_install_rm_cmd(cache_folder, project_name .. "-tmp"),
|
||||
}
|
||||
else
|
||||
local git_folder = utils.join_path(cache_folder, project_name)
|
||||
local clone_error = "Error during download, please verify your internet connection"
|
||||
|
||||
return {
|
||||
{
|
||||
cmd = "git",
|
||||
info = "Downloading...",
|
||||
err = clone_error,
|
||||
opts = {
|
||||
args = {
|
||||
"clone",
|
||||
repo.url,
|
||||
project_name,
|
||||
},
|
||||
cwd = cache_folder,
|
||||
},
|
||||
},
|
||||
{
|
||||
cmd = "git",
|
||||
info = "Checking out locked revision",
|
||||
err = "Error while checking out revision",
|
||||
opts = {
|
||||
args = {
|
||||
"checkout",
|
||||
revision,
|
||||
},
|
||||
cwd = git_folder,
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.make_directory_change_for_command(dir, command)
|
||||
if fn.has "win32" == 1 then
|
||||
return string.format("pushd %s & %s & popd", dir, command)
|
||||
else
|
||||
return string.format("cd %s;\n %s", dir, command)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
392
bundle/nvim-treesitter/lua/nvim-treesitter/ts_utils.lua
Normal file
392
bundle/nvim-treesitter/lua/nvim-treesitter/ts_utils.lua
Normal file
@ -0,0 +1,392 @@
|
||||
local api = vim.api
|
||||
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
|
||||
local M = {}
|
||||
|
||||
--- Gets the actual text content of a node
|
||||
-- @param node the node to get the text from
|
||||
-- @param bufnr the buffer containing the node
|
||||
-- @return list of lines of text of the node
|
||||
function M.get_node_text(node, bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
if not node then
|
||||
return {}
|
||||
end
|
||||
|
||||
-- We have to remember that end_col is end-exclusive
|
||||
local start_row, start_col, end_row, end_col = M.get_node_range(node)
|
||||
|
||||
if start_row ~= end_row then
|
||||
local lines = api.nvim_buf_get_lines(bufnr, start_row, end_row + 1, false)
|
||||
lines[1] = string.sub(lines[1], start_col + 1)
|
||||
-- end_row might be just after the last line. In this case the last line is not truncated.
|
||||
if #lines == end_row - start_row + 1 then
|
||||
lines[#lines] = string.sub(lines[#lines], 1, end_col)
|
||||
end
|
||||
return lines
|
||||
else
|
||||
local line = api.nvim_buf_get_lines(bufnr, start_row, start_row + 1, false)[1]
|
||||
-- If line is nil then the line is empty
|
||||
return line and { string.sub(line, start_col + 1, end_col) } or {}
|
||||
end
|
||||
end
|
||||
|
||||
--- Determines whether a node is the parent of another
|
||||
-- @param dest the possible parent
|
||||
-- @param source the possible child node
|
||||
function M.is_parent(dest, source)
|
||||
if not (dest and source) then
|
||||
return false
|
||||
end
|
||||
|
||||
local current = source
|
||||
while current ~= nil do
|
||||
if current == dest then
|
||||
return true
|
||||
end
|
||||
|
||||
current = current:parent()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Get next node with same parent
|
||||
-- @param node node
|
||||
-- @param allow_switch_parents allow switching parents if last node
|
||||
-- @param allow_next_parent allow next parent if last node and next parent without children
|
||||
function M.get_next_node(node, allow_switch_parents, allow_next_parent)
|
||||
local destination_node
|
||||
local parent = node:parent()
|
||||
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
local found_pos = 0
|
||||
for i = 0, parent:named_child_count() - 1, 1 do
|
||||
if parent:named_child(i) == node then
|
||||
found_pos = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if parent:named_child_count() > found_pos + 1 then
|
||||
destination_node = parent:named_child(found_pos + 1)
|
||||
elseif allow_switch_parents then
|
||||
local next_node = M.get_next_node(node:parent())
|
||||
if next_node and next_node:named_child_count() > 0 then
|
||||
destination_node = next_node:named_child(0)
|
||||
elseif next_node and allow_next_parent then
|
||||
destination_node = next_node
|
||||
end
|
||||
end
|
||||
|
||||
return destination_node
|
||||
end
|
||||
|
||||
--- Get previous node with same parent
|
||||
-- @param node node
|
||||
-- @param allow_switch_parents allow switching parents if first node
|
||||
-- @param allow_previous_parent allow previous parent if first node and previous parent without children
|
||||
function M.get_previous_node(node, allow_switch_parents, allow_previous_parent)
|
||||
local destination_node
|
||||
local parent = node:parent()
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
|
||||
local found_pos = 0
|
||||
for i = 0, parent:named_child_count() - 1, 1 do
|
||||
if parent:named_child(i) == node then
|
||||
found_pos = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if 0 < found_pos then
|
||||
destination_node = parent:named_child(found_pos - 1)
|
||||
elseif allow_switch_parents then
|
||||
local previous_node = M.get_previous_node(node:parent())
|
||||
if previous_node and previous_node:named_child_count() > 0 then
|
||||
destination_node = previous_node:named_child(previous_node:named_child_count() - 1)
|
||||
elseif previous_node and allow_previous_parent then
|
||||
destination_node = previous_node
|
||||
end
|
||||
end
|
||||
return destination_node
|
||||
end
|
||||
|
||||
function M.get_named_children(node)
|
||||
local nodes = {}
|
||||
for i = 0, node:named_child_count() - 1, 1 do
|
||||
nodes[i + 1] = node:named_child(i)
|
||||
end
|
||||
return nodes
|
||||
end
|
||||
|
||||
function M.get_node_at_cursor(winnr)
|
||||
winnr = winnr or 0
|
||||
local cursor = api.nvim_win_get_cursor(winnr)
|
||||
local cursor_range = { cursor[1] - 1, cursor[2] }
|
||||
|
||||
local buf = vim.api.nvim_win_get_buf(winnr)
|
||||
local root_lang_tree = parsers.get_parser(buf)
|
||||
if not root_lang_tree then
|
||||
return
|
||||
end
|
||||
local root = M.get_root_for_position(cursor_range[1], cursor_range[2], root_lang_tree)
|
||||
|
||||
if not root then
|
||||
return
|
||||
end
|
||||
|
||||
return root:named_descendant_for_range(cursor_range[1], cursor_range[2], cursor_range[1], cursor_range[2])
|
||||
end
|
||||
|
||||
function M.get_root_for_position(line, col, root_lang_tree)
|
||||
if not root_lang_tree then
|
||||
if not parsers.has_parser() then
|
||||
return
|
||||
end
|
||||
|
||||
root_lang_tree = parsers.get_parser()
|
||||
end
|
||||
|
||||
local lang_tree = root_lang_tree:language_for_range { line, col, line, col }
|
||||
|
||||
for _, tree in ipairs(lang_tree:trees()) do
|
||||
local root = tree:root()
|
||||
|
||||
if root and M.is_in_node_range(root, line, col) then
|
||||
return root, tree, lang_tree
|
||||
end
|
||||
end
|
||||
|
||||
-- This isn't a likely scenario, since the position must belong to a tree somewhere.
|
||||
return nil, nil, lang_tree
|
||||
end
|
||||
|
||||
function M.get_root_for_node(node)
|
||||
local parent = node
|
||||
local result = node
|
||||
|
||||
while parent ~= nil do
|
||||
result = parent
|
||||
parent = result:parent()
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function M.highlight_node(node, buf, hl_namespace, hl_group)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
M.highlight_range({ node:range() }, buf, hl_namespace, hl_group)
|
||||
end
|
||||
|
||||
--- Get a compatible vim range (1 index based) from a TS node range.
|
||||
--
|
||||
-- TS nodes start with 0 and the end col is ending exclusive.
|
||||
-- They also treat a EOF/EOL char as a char ending in the first
|
||||
-- col of the next row.
|
||||
function M.get_vim_range(range, buf)
|
||||
local srow, scol, erow, ecol = unpack(range)
|
||||
srow = srow + 1
|
||||
scol = scol + 1
|
||||
erow = erow + 1
|
||||
|
||||
if ecol == 0 then
|
||||
-- Use the value of the last col of the previous row instead.
|
||||
erow = erow - 1
|
||||
if not buf or buf == 0 then
|
||||
ecol = vim.fn.col { erow, "$" } - 1
|
||||
else
|
||||
ecol = #api.nvim_buf_get_lines(buf, erow - 1, erow, false)[1]
|
||||
end
|
||||
end
|
||||
return srow, scol, erow, ecol
|
||||
end
|
||||
|
||||
function M.highlight_range(range, buf, hl_namespace, hl_group)
|
||||
local start_row, start_col, end_row, end_col = unpack(range)
|
||||
vim.highlight.range(buf, hl_namespace, hl_group, { start_row, start_col }, { end_row, end_col })
|
||||
end
|
||||
|
||||
-- Set visual selection to node
|
||||
-- @param selection_mode One of "charwise" (default) or "v", "linewise" or "V",
|
||||
-- "blockwise" or "<C-v>" (as a string with 5 characters or a single character)
|
||||
function M.update_selection(buf, node, selection_mode)
|
||||
selection_mode = selection_mode or "charwise"
|
||||
local start_row, start_col, end_row, end_col = M.get_vim_range({ M.get_node_range(node) }, buf)
|
||||
|
||||
vim.fn.setpos(".", { buf, start_row, start_col, 0 })
|
||||
|
||||
-- Start visual selection in appropriate mode
|
||||
local v_table = { charwise = "v", linewise = "V", blockwise = "<C-v>" }
|
||||
---- Call to `nvim_replace_termcodes()` is needed for sending appropriate
|
||||
---- command to enter blockwise mode
|
||||
local mode_string = vim.api.nvim_replace_termcodes(v_table[selection_mode] or selection_mode, true, true, true)
|
||||
vim.cmd("normal! " .. mode_string)
|
||||
vim.fn.setpos(".", { buf, end_row, end_col, 0 })
|
||||
end
|
||||
|
||||
-- Byte length of node range
|
||||
function M.node_length(node)
|
||||
local _, _, start_byte = node:start()
|
||||
local _, _, end_byte = node:end_()
|
||||
return end_byte - start_byte
|
||||
end
|
||||
|
||||
--- Determines whether (line, col) position is in node range
|
||||
-- @param node Node defining the range
|
||||
-- @param line A line (0-based)
|
||||
-- @param col A column (0-based)
|
||||
function M.is_in_node_range(node, line, col)
|
||||
local start_line, start_col, end_line, end_col = node:range()
|
||||
if line >= start_line and line <= end_line then
|
||||
if line == start_line and line == end_line then
|
||||
return col >= start_col and col < end_col
|
||||
elseif line == start_line then
|
||||
return col >= start_col
|
||||
elseif line == end_line then
|
||||
return col < end_col
|
||||
else
|
||||
return true
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_node_range(node_or_range)
|
||||
if type(node_or_range) == "table" then
|
||||
return unpack(node_or_range)
|
||||
else
|
||||
return node_or_range:range()
|
||||
end
|
||||
end
|
||||
|
||||
function M.node_to_lsp_range(node)
|
||||
local start_line, start_col, end_line, end_col = M.get_node_range(node)
|
||||
local rtn = {}
|
||||
rtn.start = { line = start_line, character = start_col }
|
||||
rtn["end"] = { line = end_line, character = end_col }
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Memoizes a function based on the buffer tick of the provided bufnr.
|
||||
-- The cache entry is cleared when the buffer is detached to avoid memory leaks.
|
||||
-- @param fn: the fn to memoize, taking the bufnr as first argument
|
||||
-- @param options:
|
||||
-- - bufnr: extracts a bufnr from the given arguments.
|
||||
-- - key: extracts the cache key from the given arguments.
|
||||
-- @returns a memoized function
|
||||
function M.memoize_by_buf_tick(fn, options)
|
||||
options = options or {}
|
||||
|
||||
local cache = {}
|
||||
local bufnr_fn = utils.to_func(options.bufnr or utils.identity)
|
||||
local key_fn = utils.to_func(options.key or utils.identity)
|
||||
|
||||
return function(...)
|
||||
local bufnr = bufnr_fn(...)
|
||||
local key = key_fn(...)
|
||||
local tick = api.nvim_buf_get_changedtick(bufnr)
|
||||
|
||||
if cache[key] then
|
||||
if cache[key].last_tick == tick then
|
||||
return cache[key].result
|
||||
end
|
||||
else
|
||||
local function detach_handler()
|
||||
cache[key] = nil
|
||||
end
|
||||
|
||||
-- Clean up logic only!
|
||||
api.nvim_buf_attach(bufnr, false, {
|
||||
on_detach = detach_handler,
|
||||
on_reload = detach_handler,
|
||||
})
|
||||
end
|
||||
|
||||
cache[key] = {
|
||||
result = fn(...),
|
||||
last_tick = tick,
|
||||
}
|
||||
|
||||
return cache[key].result
|
||||
end
|
||||
end
|
||||
|
||||
function M.swap_nodes(node_or_range1, node_or_range2, bufnr, cursor_to_second)
|
||||
if not node_or_range1 or not node_or_range2 then
|
||||
return
|
||||
end
|
||||
local range1 = M.node_to_lsp_range(node_or_range1)
|
||||
local range2 = M.node_to_lsp_range(node_or_range2)
|
||||
|
||||
local text1 = M.get_node_text(node_or_range1)
|
||||
local text2 = M.get_node_text(node_or_range2)
|
||||
|
||||
local edit1 = { range = range1, newText = table.concat(text2, "\n") }
|
||||
local edit2 = { range = range2, newText = table.concat(text1, "\n") }
|
||||
vim.lsp.util.apply_text_edits({ edit1, edit2 }, bufnr, "utf-8")
|
||||
|
||||
if cursor_to_second then
|
||||
utils.set_jump()
|
||||
|
||||
local char_delta = 0
|
||||
local line_delta = 0
|
||||
if
|
||||
range1["end"].line < range2.start.line
|
||||
or (range1["end"].line == range2.start.line and range1["end"].character < range2.start.character)
|
||||
then
|
||||
line_delta = #text2 - #text1
|
||||
end
|
||||
|
||||
if range1["end"].line == range2.start.line and range1["end"].character < range2.start.character then
|
||||
if line_delta ~= 0 then
|
||||
--- why?
|
||||
--correction_after_line_change = -range2.start.character
|
||||
--text_now_before_range2 = #(text2[#text2])
|
||||
--space_between_ranges = range2.start.character - range1["end"].character
|
||||
--char_delta = correction_after_line_change + text_now_before_range2 + space_between_ranges
|
||||
--- Equivalent to:
|
||||
char_delta = #text2[#text2] - range1["end"].character
|
||||
|
||||
-- add range1.start.character if last line of range1 (now text2) does not start at 0
|
||||
if range1.start.line == range2.start.line + line_delta then
|
||||
char_delta = char_delta + range1.start.character
|
||||
end
|
||||
else
|
||||
char_delta = #text2[#text2] - #text1[#text1]
|
||||
end
|
||||
end
|
||||
|
||||
api.nvim_win_set_cursor(
|
||||
api.nvim_get_current_win(),
|
||||
{ range2.start.line + 1 + line_delta, range2.start.character + char_delta }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function M.goto_node(node, goto_end, avoid_set_jump)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
if not avoid_set_jump then
|
||||
utils.set_jump()
|
||||
end
|
||||
local range = { M.get_vim_range { node:range() } }
|
||||
local position
|
||||
if not goto_end then
|
||||
position = { range[1], range[2] }
|
||||
else
|
||||
position = { range[3], range[4] }
|
||||
end
|
||||
-- Position is 1, 0 indexed.
|
||||
api.nvim_win_set_cursor(0, { position[1], position[2] - 1 })
|
||||
end
|
||||
|
||||
return M
|
154
bundle/nvim-treesitter/lua/nvim-treesitter/tsrange.lua
Normal file
154
bundle/nvim-treesitter/lua/nvim-treesitter/tsrange.lua
Normal file
@ -0,0 +1,154 @@
|
||||
local M = {}
|
||||
local TSRange = {}
|
||||
TSRange.__index = TSRange
|
||||
|
||||
local api = vim.api
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
|
||||
local function get_byte_offset(buf, row, col)
|
||||
return api.nvim_buf_get_offset(buf, row) + vim.fn.byteidx(api.nvim_buf_get_lines(buf, row, row + 1, false)[1], col)
|
||||
end
|
||||
|
||||
function TSRange.new(buf, start_row, start_col, end_row, end_col)
|
||||
return setmetatable({
|
||||
start_pos = { start_row, start_col, get_byte_offset(buf, start_row, start_col) },
|
||||
end_pos = { end_row, end_col, get_byte_offset(buf, end_row, end_col) },
|
||||
buf = buf,
|
||||
[1] = start_row,
|
||||
[2] = start_col,
|
||||
[3] = end_row,
|
||||
[4] = end_col,
|
||||
}, TSRange)
|
||||
end
|
||||
|
||||
function TSRange.from_nodes(buf, start_node, end_node)
|
||||
TSRange.__index = TSRange
|
||||
local start_pos = start_node and { start_node:start() } or { end_node:start() }
|
||||
local end_pos = end_node and { end_node:end_() } or { start_node:end_() }
|
||||
return setmetatable({
|
||||
start_pos = { start_pos[1], start_pos[2], start_pos[3] },
|
||||
end_pos = { end_pos[1], end_pos[2], end_pos[3] },
|
||||
buf = buf,
|
||||
[1] = start_pos[1],
|
||||
[2] = start_pos[2],
|
||||
[3] = end_pos[1],
|
||||
[4] = end_pos[2],
|
||||
}, TSRange)
|
||||
end
|
||||
|
||||
function TSRange.from_table(buf, range)
|
||||
return setmetatable({
|
||||
start_pos = { range[1], range[2], get_byte_offset(buf, range[1], range[2]) },
|
||||
end_pos = { range[3], range[4], get_byte_offset(buf, range[3], range[4]) },
|
||||
buf = buf,
|
||||
[1] = range[1],
|
||||
[2] = range[2],
|
||||
[3] = range[3],
|
||||
[4] = range[4],
|
||||
}, TSRange)
|
||||
end
|
||||
|
||||
function TSRange:parent()
|
||||
local root_lang_tree = parsers.get_parser(self.buf)
|
||||
local root = ts_utils.get_root_for_position(self[1], self[2], root_lang_tree)
|
||||
|
||||
return root
|
||||
and root:named_descendant_for_range(self.start_pos[1], self.start_pos[2], self.end_pos[1], self.end_pos[2])
|
||||
or nil
|
||||
end
|
||||
|
||||
function TSRange:field() end
|
||||
|
||||
function TSRange:child_count()
|
||||
return #self:collect_children()
|
||||
end
|
||||
|
||||
function TSRange:named_child_count()
|
||||
return #self:collect_children(function(c)
|
||||
return c:named()
|
||||
end)
|
||||
end
|
||||
|
||||
function TSRange:iter_children()
|
||||
local raw_iterator = self:parent().iter_children()
|
||||
return function()
|
||||
while true do
|
||||
local node = raw_iterator()
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
local _, _, start_byte = node:start()
|
||||
local _, _, end_byte = node:end_()
|
||||
if start_byte >= self.start_pos[3] and end_byte <= self.end_pos[3] then
|
||||
return node
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TSRange:collect_children(filter_fun)
|
||||
local children = {}
|
||||
for _, c in self:iter_children() do
|
||||
if not filter_fun or filter_fun(c) then
|
||||
table.insert(children, c)
|
||||
end
|
||||
end
|
||||
return children
|
||||
end
|
||||
|
||||
function TSRange:child(index)
|
||||
return self:collect_children()[index + 1]
|
||||
end
|
||||
|
||||
function TSRange:named_child(index)
|
||||
return self:collect_children(function(c)
|
||||
return c.named()
|
||||
end)[index + 1]
|
||||
end
|
||||
|
||||
function TSRange:start()
|
||||
return unpack(self.start_pos)
|
||||
end
|
||||
|
||||
function TSRange:end_()
|
||||
return unpack(self.end_pos)
|
||||
end
|
||||
|
||||
function TSRange:range()
|
||||
return self.start_pos[1], self.start_pos[2], self.end_pos[1], self.end_pos[2]
|
||||
end
|
||||
|
||||
function TSRange:type()
|
||||
return "nvim-treesitter-range"
|
||||
end
|
||||
|
||||
function TSRange:symbol()
|
||||
return -1
|
||||
end
|
||||
|
||||
function TSRange:named()
|
||||
return false
|
||||
end
|
||||
|
||||
function TSRange:missing()
|
||||
return false
|
||||
end
|
||||
|
||||
function TSRange:has_error()
|
||||
return #self:collect_children(function(c)
|
||||
return c:has_error()
|
||||
end) > 0 and true or false
|
||||
end
|
||||
|
||||
function TSRange:sexpr()
|
||||
return table.concat(
|
||||
vim.tbl_map(function(c)
|
||||
return c:sexpr()
|
||||
end, self:collect_children()),
|
||||
" "
|
||||
)
|
||||
end
|
||||
|
||||
M.TSRange = TSRange
|
||||
return M
|
236
bundle/nvim-treesitter/lua/nvim-treesitter/utils.lua
Normal file
236
bundle/nvim-treesitter/lua/nvim-treesitter/utils.lua
Normal file
@ -0,0 +1,236 @@
|
||||
local api = vim.api
|
||||
local fn = vim.fn
|
||||
local luv = vim.loop
|
||||
|
||||
local M = {}
|
||||
|
||||
-- Wrapper around vim.notify with common options set.
|
||||
function M.notify(msg, log_level, opts)
|
||||
local default_opts = { title = "nvim-treesitter" }
|
||||
vim.notify(msg, log_level, vim.tbl_extend("force", default_opts, opts or {}))
|
||||
end
|
||||
|
||||
--- Define user defined vim command which calls nvim-treesitter module function
|
||||
--- - If module name is 'mod', it should be defined in hierarchy 'nvim-treesitter.mod'
|
||||
--- - A table with name 'commands' should be defined in 'mod' which needs to be passed as
|
||||
--- the commands param of this function
|
||||
---
|
||||
---@param mod string, Name of the module that resides in the heirarchy - nvim-treesitter.module
|
||||
---@param commands table, Command list for the module
|
||||
--- - {command_name} Name of the vim user defined command, Keys:
|
||||
--- - {run}: (function) callback function that needs to be executed
|
||||
--- - {f_args}: (string, default <f-args>)
|
||||
--- - type of arguments that needs to be passed to the vim command
|
||||
--- - {args}: (string, optional)
|
||||
--- - vim command attributes
|
||||
---
|
||||
---Example:
|
||||
--- If module is nvim-treesitter.custom_mod
|
||||
--- <pre>
|
||||
--- M.commands = {
|
||||
--- custom_command = {
|
||||
--- run = M.module_function,
|
||||
--- f_args = "<f-args>",
|
||||
--- args = {
|
||||
--- "-range"
|
||||
--- }
|
||||
--- }
|
||||
--- }
|
||||
---
|
||||
--- utils.setup_commands("custom_mod", require("nvim-treesitter.custom_mod").commands)
|
||||
--- </pre>
|
||||
---
|
||||
--- Will generate command :
|
||||
--- <pre>
|
||||
--- command! -range custom_command \
|
||||
--- lua require'nvim-treesitter.custom_mod'.commands.custom_command['run<bang>'](<f-args>)
|
||||
--- </pre>
|
||||
function M.setup_commands(mod, commands)
|
||||
for command_name, def in pairs(commands) do
|
||||
local f_args = def.f_args or "<f-args>"
|
||||
local call_fn = string.format(
|
||||
"lua require'nvim-treesitter.%s'.commands.%s['run<bang>'](%s)",
|
||||
mod,
|
||||
command_name,
|
||||
f_args
|
||||
)
|
||||
local parts = vim.tbl_flatten {
|
||||
"command!",
|
||||
def.args,
|
||||
command_name,
|
||||
call_fn,
|
||||
}
|
||||
api.nvim_command(table.concat(parts, " "))
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_path_sep()
|
||||
return fn.has "win32" == 1 and "\\" or "/"
|
||||
end
|
||||
|
||||
-- Returns a function that joins the given arguments with separator. Arguments
|
||||
-- can't be nil. Example:
|
||||
--[[
|
||||
print(M.generate_join(" ")("foo", "bar"))
|
||||
--]]
|
||||
-- prints "foo bar"
|
||||
function M.generate_join(separator)
|
||||
return function(...)
|
||||
return table.concat({ ... }, separator)
|
||||
end
|
||||
end
|
||||
|
||||
M.join_path = M.generate_join(M.get_path_sep())
|
||||
|
||||
local join_space = M.generate_join " "
|
||||
|
||||
function M.get_package_path()
|
||||
-- Path to this source file, removing the leading '@'
|
||||
local source = string.sub(debug.getinfo(1, "S").source, 2)
|
||||
|
||||
-- Path to the package root
|
||||
return fn.fnamemodify(source, ":p:h:h:h")
|
||||
end
|
||||
|
||||
function M.get_cache_dir()
|
||||
local cache_dir = fn.stdpath "data"
|
||||
|
||||
if luv.fs_access(cache_dir, "RW") then
|
||||
return cache_dir
|
||||
elseif luv.fs_access("/tmp", "RW") then
|
||||
return "/tmp"
|
||||
end
|
||||
|
||||
return nil, join_space("Invalid cache rights,", fn.stdpath "data", "or /tmp should be read/write")
|
||||
end
|
||||
|
||||
-- Returns $XDG_DATA_HOME/nvim/site, but could use any directory that is in
|
||||
-- runtimepath
|
||||
function M.get_site_dir()
|
||||
local path_sep = M.get_path_sep()
|
||||
return M.join_path(fn.stdpath "data", path_sep, "site")
|
||||
end
|
||||
|
||||
-- Try the package dir of the nvim-treesitter plugin first, followed by the
|
||||
-- "site" dir from "runtimepath". "site" dir will be created if it doesn't
|
||||
-- exist. Using only the package dir won't work when the plugin is installed
|
||||
-- with Nix, since the "/nix/store" is read-only.
|
||||
function M.get_parser_install_dir(folder_name)
|
||||
folder_name = folder_name or "parser"
|
||||
local package_path = M.get_package_path()
|
||||
local package_path_parser_dir = M.join_path(package_path, folder_name)
|
||||
|
||||
-- If package_path is read/write, use that
|
||||
if luv.fs_access(package_path_parser_dir, "RW") then
|
||||
return package_path_parser_dir
|
||||
end
|
||||
|
||||
local site_dir = M.get_site_dir()
|
||||
local path_sep = M.get_path_sep()
|
||||
local parser_dir = M.join_path(site_dir, path_sep, folder_name)
|
||||
|
||||
-- Try creating and using parser_dir if it doesn't exist
|
||||
if not luv.fs_stat(parser_dir) then
|
||||
local ok, error = pcall(vim.fn.mkdir, parser_dir, "p", "0755")
|
||||
if not ok then
|
||||
return nil, join_space("Couldn't create parser dir", parser_dir, ":", error)
|
||||
end
|
||||
|
||||
return parser_dir
|
||||
end
|
||||
|
||||
-- parser_dir exists, use it if it's read/write
|
||||
if luv.fs_access(parser_dir, "RW") then
|
||||
return parser_dir
|
||||
end
|
||||
|
||||
-- package_path isn't read/write, parser_dir exists but isn't read/write
|
||||
-- either, give up
|
||||
return nil, join_space("Invalid cache rights,", package_path, "or", parser_dir, "should be read/write")
|
||||
end
|
||||
|
||||
function M.get_parser_info_dir()
|
||||
return M.get_parser_install_dir "parser-info"
|
||||
end
|
||||
|
||||
-- Gets a property at path
|
||||
-- @param tbl the table to access
|
||||
-- @param path the '.' separated path
|
||||
-- @returns the value at path or nil
|
||||
function M.get_at_path(tbl, path)
|
||||
if path == "" then
|
||||
return tbl
|
||||
end
|
||||
local segments = vim.split(path, ".", true)
|
||||
local result = tbl
|
||||
|
||||
for _, segment in ipairs(segments) do
|
||||
if type(result) == "table" then
|
||||
result = result[segment]
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function M.set_jump()
|
||||
vim.cmd "normal! m'"
|
||||
end
|
||||
|
||||
function M.index_of(tbl, obj)
|
||||
for i, o in ipairs(tbl) do
|
||||
if o == obj then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Filters a list based on the given predicate
|
||||
-- @param tbl The list to filter
|
||||
-- @param predicate The predicate to filter with
|
||||
function M.filter(tbl, predicate)
|
||||
local result = {}
|
||||
|
||||
for i, v in ipairs(tbl) do
|
||||
if predicate(v, i) then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- Returns a list of all values from the first list
|
||||
-- that are not present in the second list.
|
||||
-- @params tbl1 The first table
|
||||
-- @params tbl2 The second table
|
||||
function M.difference(tbl1, tbl2)
|
||||
return M.filter(tbl1, function(v)
|
||||
return not vim.tbl_contains(tbl2, v)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.identity(a)
|
||||
return a
|
||||
end
|
||||
|
||||
function M.constant(a)
|
||||
return function()
|
||||
return a
|
||||
end
|
||||
end
|
||||
|
||||
function M.to_func(a)
|
||||
return type(a) == "function" and a or M.constant(a)
|
||||
end
|
||||
|
||||
function M.ts_cli_version()
|
||||
if fn.executable "tree-sitter" == 1 then
|
||||
local handle = io.popen "tree-sitter -V"
|
||||
local result = handle:read "*a"
|
||||
handle:close()
|
||||
return vim.split(result, "\n")[1]:match "[^tree%psitter ].*"
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
2
bundle/nvim-treesitter/parser-info/.gitignore
vendored
Normal file
2
bundle/nvim-treesitter/parser-info/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
2
bundle/nvim-treesitter/parser/.gitignore
vendored
Normal file
2
bundle/nvim-treesitter/parser/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
106
bundle/nvim-treesitter/plugin/nvim-treesitter.vim
Normal file
106
bundle/nvim-treesitter/plugin/nvim-treesitter.vim
Normal file
@ -0,0 +1,106 @@
|
||||
" Last Change: 2020 Aug 13
|
||||
|
||||
if exists('g:loaded_nvim_treesitter')
|
||||
finish
|
||||
endif
|
||||
|
||||
augroup NvimTreesitter
|
||||
" on every query file write we want to set an autocommand that will reload the cache
|
||||
autocmd FileType query
|
||||
\ autocmd! NvimTreesitter BufWritePost <buffer> call v:lua.require('nvim-treesitter.query').invalidate_query_file(expand('%:p'))
|
||||
augroup END
|
||||
|
||||
let g:loaded_nvim_treesitter = 1
|
||||
|
||||
lua require'nvim-treesitter'.setup()
|
||||
|
||||
function s:has_attr(attr, mode)
|
||||
let norm_color = synIDattr(hlID('Normal'), a:attr, a:mode)
|
||||
return strlen(norm_color) > 0
|
||||
endfunction
|
||||
|
||||
" if the ctermfg or guifg is not known by nvim then using the
|
||||
" fg or foreground highlighting value will cause an E419 error
|
||||
" so we check to see if either highlight has been set if not default to NONE
|
||||
let cterm_normal = s:has_attr('fg', 'cterm') ? 'fg' : 'NONE'
|
||||
let gui_normal = s:has_attr('fg', 'gui') ? 'foreground' : 'NONE'
|
||||
|
||||
execute 'highlight default TSNone term=NONE cterm=NONE gui=NONE guifg='.gui_normal.' ctermfg='.cterm_normal
|
||||
|
||||
highlight default link TSPunctDelimiter Delimiter
|
||||
highlight default link TSPunctBracket Delimiter
|
||||
highlight default link TSPunctSpecial Delimiter
|
||||
|
||||
highlight default link TSConstant Constant
|
||||
highlight default link TSConstBuiltin Special
|
||||
highlight default link TSConstMacro Define
|
||||
highlight default link TSString String
|
||||
highlight default link TSStringRegex String
|
||||
highlight default link TSStringEscape SpecialChar
|
||||
highlight default link TSStringSpecial SpecialChar
|
||||
highlight default link TSCharacter Character
|
||||
highlight default link TSCharacterSpecial SpecialChar
|
||||
highlight default link TSNumber Number
|
||||
highlight default link TSBoolean Boolean
|
||||
highlight default link TSFloat Float
|
||||
|
||||
highlight default link TSFunction Function
|
||||
highlight default link TSFuncBuiltin Special
|
||||
highlight default link TSFuncMacro Macro
|
||||
highlight default link TSParameter Identifier
|
||||
highlight default link TSParameterReference TSParameter
|
||||
highlight default link TSMethod Function
|
||||
highlight default link TSField Identifier
|
||||
highlight default link TSProperty Identifier
|
||||
highlight default link TSConstructor Special
|
||||
highlight default link TSAnnotation PreProc
|
||||
highlight default link TSAttribute PreProc
|
||||
highlight default link TSNamespace Include
|
||||
highlight default link TSSymbol Identifier
|
||||
|
||||
highlight default link TSConditional Conditional
|
||||
highlight default link TSRepeat Repeat
|
||||
highlight default link TSLabel Label
|
||||
highlight default link TSOperator Operator
|
||||
highlight default link TSKeyword Keyword
|
||||
highlight default link TSKeywordFunction Keyword
|
||||
highlight default link TSKeywordOperator TSOperator
|
||||
highlight default link TSKeywordReturn TSKeyword
|
||||
highlight default link TSException Exception
|
||||
highlight default link TSDebug Debug
|
||||
highlight default link TSDefine Define
|
||||
highlight default link TSPreProc PreProc
|
||||
highlight default link TSStorageClass StorageClass
|
||||
|
||||
highlight default link TSTodo Todo
|
||||
|
||||
highlight default link TSType Type
|
||||
highlight default link TSTypeBuiltin Type
|
||||
highlight default link TSTypeQualifier Type
|
||||
highlight default link TSTypeDefinition Typedef
|
||||
|
||||
highlight default link TSInclude Include
|
||||
|
||||
highlight default link TSVariableBuiltin Special
|
||||
|
||||
highlight default link TSText TSNone
|
||||
highlight default TSStrong term=bold cterm=bold gui=bold
|
||||
highlight default TSEmphasis term=italic cterm=italic gui=italic
|
||||
highlight default TSUnderline term=underline cterm=underline gui=underline
|
||||
highlight default TSStrike term=strikethrough cterm=strikethrough gui=strikethrough
|
||||
highlight default link TSMath Special
|
||||
highlight default link TSTextReference Constant
|
||||
highlight default link TSEnvironment Macro
|
||||
highlight default link TSEnvironmentName Type
|
||||
highlight default link TSTitle Title
|
||||
highlight default link TSLiteral String
|
||||
highlight default link TSURI Underlined
|
||||
|
||||
highlight default link TSComment Comment
|
||||
highlight default link TSNote SpecialComment
|
||||
highlight default link TSWarning Todo
|
||||
highlight default link TSDanger WarningMsg
|
||||
|
||||
highlight default link TSTag Label
|
||||
highlight default link TSTagDelimiter Delimiter
|
||||
highlight default link TSTagAttribute TSProperty
|
1
bundle/nvim-treesitter/queries/astro/folds.scm
Normal file
1
bundle/nvim-treesitter/queries/astro/folds.scm
Normal file
@ -0,0 +1 @@
|
||||
; inherits: html
|
5
bundle/nvim-treesitter/queries/astro/highlights.scm
Normal file
5
bundle/nvim-treesitter/queries/astro/highlights.scm
Normal file
@ -0,0 +1,5 @@
|
||||
; inherits: html
|
||||
|
||||
[ "---" ] @punctuation.delimiter
|
||||
|
||||
[ "{" "}" ] @punctuation.special
|
1
bundle/nvim-treesitter/queries/astro/indents.scm
Normal file
1
bundle/nvim-treesitter/queries/astro/indents.scm
Normal file
@ -0,0 +1 @@
|
||||
; inherits: html
|
7
bundle/nvim-treesitter/queries/astro/injections.scm
Normal file
7
bundle/nvim-treesitter/queries/astro/injections.scm
Normal file
@ -0,0 +1,7 @@
|
||||
; inherits: html
|
||||
|
||||
((frontmatter
|
||||
(raw_text) @typescript))
|
||||
|
||||
((interpolation
|
||||
(raw_text) @tsx))
|
1
bundle/nvim-treesitter/queries/astro/locals.scm
Normal file
1
bundle/nvim-treesitter/queries/astro/locals.scm
Normal file
@ -0,0 +1 @@
|
||||
; inherits: html
|
8
bundle/nvim-treesitter/queries/bash/folds.scm
Normal file
8
bundle/nvim-treesitter/queries/bash/folds.scm
Normal file
@ -0,0 +1,8 @@
|
||||
[
|
||||
(function_definition)
|
||||
(if_statement)
|
||||
(case_statement)
|
||||
(for_statement)
|
||||
(while_statement)
|
||||
(c_style_for_statement)
|
||||
] @fold
|
131
bundle/nvim-treesitter/queries/bash/highlights.scm
Normal file
131
bundle/nvim-treesitter/queries/bash/highlights.scm
Normal file
@ -0,0 +1,131 @@
|
||||
(simple_expansion) @none
|
||||
(expansion
|
||||
"${" @punctuation.special
|
||||
"}" @punctuation.special) @none
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"(("
|
||||
"))"
|
||||
"{"
|
||||
"}"
|
||||
"["
|
||||
"]"
|
||||
"[["
|
||||
"]]"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
";"
|
||||
";;"
|
||||
(heredoc_start)
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"$"
|
||||
] @punctuation.special
|
||||
|
||||
[
|
||||
">"
|
||||
">>"
|
||||
"<"
|
||||
"<<"
|
||||
"&"
|
||||
"&&"
|
||||
"|"
|
||||
"||"
|
||||
"="
|
||||
"=~"
|
||||
"=="
|
||||
"!="
|
||||
] @operator
|
||||
|
||||
[
|
||||
(string)
|
||||
(raw_string)
|
||||
(heredoc_body)
|
||||
] @string
|
||||
|
||||
(variable_assignment (word) @string)
|
||||
|
||||
[
|
||||
"if"
|
||||
"then"
|
||||
"else"
|
||||
"elif"
|
||||
"fi"
|
||||
"case"
|
||||
"in"
|
||||
"esac"
|
||||
] @conditional
|
||||
|
||||
[
|
||||
"for"
|
||||
"do"
|
||||
"done"
|
||||
"while"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"declare"
|
||||
"export"
|
||||
"local"
|
||||
"readonly"
|
||||
"unset"
|
||||
] @keyword
|
||||
|
||||
"function" @keyword.function
|
||||
|
||||
(special_variable_name) @constant
|
||||
|
||||
((word) @constant.builtin
|
||||
(#match? @constant.builtin "^SIG(INT|TERM|QUIT|TIN|TOU|STP|HUP)$"))
|
||||
|
||||
((word) @boolean
|
||||
(#match? @boolean "^(true|false)$"))
|
||||
|
||||
(comment) @comment
|
||||
(test_operator) @string
|
||||
|
||||
(command_substitution
|
||||
[ "$(" ")" ] @punctuation.bracket)
|
||||
|
||||
(process_substitution
|
||||
[ "<(" ")" ] @punctuation.bracket)
|
||||
|
||||
|
||||
(function_definition
|
||||
name: (word) @function)
|
||||
|
||||
(command_name (word) @function)
|
||||
|
||||
((command_name (word) @function.builtin)
|
||||
(#any-of? @function.builtin
|
||||
"alias" "cd" "clear" "echo" "eval" "exit" "getopts" "popd"
|
||||
"pushd" "return" "set" "shift" "shopt" "source" "test"))
|
||||
|
||||
(command
|
||||
argument: [
|
||||
(word) @parameter
|
||||
(concatenation (word) @parameter)
|
||||
])
|
||||
|
||||
((word) @number
|
||||
(#lua-match? @number "^[0-9]+$"))
|
||||
|
||||
(file_redirect
|
||||
descriptor: (file_descriptor) @operator
|
||||
destination: (word) @parameter)
|
||||
|
||||
(expansion
|
||||
[ "${" "}" ] @punctuation.bracket)
|
||||
|
||||
(variable_name) @variable
|
||||
|
||||
((variable_name) @constant
|
||||
(#lua-match? @constant "^[A-Z][A-Z_0-9]*$"))
|
||||
|
||||
(case_item
|
||||
value: (word) @parameter)
|
||||
|
||||
(regex) @string.regex
|
1
bundle/nvim-treesitter/queries/bash/injections.scm
Normal file
1
bundle/nvim-treesitter/queries/bash/injections.scm
Normal file
@ -0,0 +1 @@
|
||||
(comment) @comment
|
13
bundle/nvim-treesitter/queries/bash/locals.scm
Normal file
13
bundle/nvim-treesitter/queries/bash/locals.scm
Normal file
@ -0,0 +1,13 @@
|
||||
; Scopes
|
||||
(function_definition) @scope
|
||||
|
||||
; Definitions
|
||||
(variable_assignment
|
||||
name: (variable_name) @definition.var)
|
||||
|
||||
(function_definition
|
||||
name: (word) @definition.function)
|
||||
|
||||
; References
|
||||
(variable_name) @reference
|
||||
(word) @reference
|
4
bundle/nvim-treesitter/queries/beancount/folds.scm
Normal file
4
bundle/nvim-treesitter/queries/beancount/folds.scm
Normal file
@ -0,0 +1,4 @@
|
||||
[
|
||||
(transaction)
|
||||
(heading)
|
||||
] @fold
|
26
bundle/nvim-treesitter/queries/beancount/highlights.scm
Normal file
26
bundle/nvim-treesitter/queries/beancount/highlights.scm
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
(date) @field
|
||||
(txn) @attribute
|
||||
|
||||
(account) @type
|
||||
|
||||
(amount) @number
|
||||
(incomplete_amount) @number
|
||||
(amount_tolerance) @number
|
||||
|
||||
(currency) @property
|
||||
|
||||
(key) @label
|
||||
(string) @string
|
||||
|
||||
(tag) @constant
|
||||
(link) @constant
|
||||
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
(balance) (open) (close) (commodity) (pad)
|
||||
(event) (price) (note) (document) (query)
|
||||
(custom) (pushtag) (poptag) (pushmeta)
|
||||
(popmeta) (option) (include) (plugin)
|
||||
] @keyword
|
3
bundle/nvim-treesitter/queries/bibtex/folds.scm
Normal file
3
bundle/nvim-treesitter/queries/bibtex/folds.scm
Normal file
@ -0,0 +1,3 @@
|
||||
[
|
||||
(entry)
|
||||
] @fold
|
49
bundle/nvim-treesitter/queries/bibtex/highlights.scm
Normal file
49
bundle/nvim-treesitter/queries/bibtex/highlights.scm
Normal file
@ -0,0 +1,49 @@
|
||||
; CREDITS @pfoerster (adapted from https://github.com/latex-lsp/tree-sitter-bibtex)
|
||||
|
||||
[
|
||||
(string_type)
|
||||
(preamble_type)
|
||||
(entry_type)
|
||||
] @keyword
|
||||
|
||||
[
|
||||
(junk)
|
||||
(comment)
|
||||
] @comment
|
||||
|
||||
[
|
||||
"="
|
||||
"#"
|
||||
] @operator
|
||||
|
||||
(command) @function.builtin
|
||||
|
||||
(number) @number
|
||||
|
||||
(field
|
||||
name: (identifier) @field)
|
||||
|
||||
(token
|
||||
(identifier) @parameter)
|
||||
|
||||
[
|
||||
(brace_word)
|
||||
(quote_word)
|
||||
] @string
|
||||
|
||||
[
|
||||
(key_brace)
|
||||
(key_paren)
|
||||
] @symbol
|
||||
|
||||
(string
|
||||
name: (identifier) @constant)
|
||||
|
||||
[
|
||||
"{"
|
||||
"}"
|
||||
"("
|
||||
")"
|
||||
] @punctuation.bracket
|
||||
|
||||
"," @punctuation.delimiter
|
10
bundle/nvim-treesitter/queries/bibtex/indents.scm
Normal file
10
bundle/nvim-treesitter/queries/bibtex/indents.scm
Normal file
@ -0,0 +1,10 @@
|
||||
[
|
||||
(entry)
|
||||
] @indent
|
||||
|
||||
[
|
||||
"{"
|
||||
"}"
|
||||
] @branch
|
||||
|
||||
(comment) @ignore
|
19
bundle/nvim-treesitter/queries/c/folds.scm
Normal file
19
bundle/nvim-treesitter/queries/c/folds.scm
Normal file
@ -0,0 +1,19 @@
|
||||
[
|
||||
(for_statement)
|
||||
(if_statement)
|
||||
(while_statement)
|
||||
(switch_statement)
|
||||
(case_statement)
|
||||
(function_definition)
|
||||
(struct_specifier)
|
||||
(enum_specifier)
|
||||
(comment)
|
||||
(preproc_if)
|
||||
(preproc_elif)
|
||||
(preproc_else)
|
||||
(preproc_ifdef)
|
||||
(initializer_list)
|
||||
] @fold
|
||||
|
||||
(compound_statement
|
||||
(compound_statement) @fold)
|
187
bundle/nvim-treesitter/queries/c/highlights.scm
Normal file
187
bundle/nvim-treesitter/queries/c/highlights.scm
Normal file
@ -0,0 +1,187 @@
|
||||
(identifier) @variable
|
||||
|
||||
[
|
||||
"const"
|
||||
"default"
|
||||
"enum"
|
||||
"extern"
|
||||
"inline"
|
||||
"static"
|
||||
"struct"
|
||||
"typedef"
|
||||
"union"
|
||||
"volatile"
|
||||
"goto"
|
||||
"register"
|
||||
] @keyword
|
||||
|
||||
"sizeof" @keyword.operator
|
||||
"return" @keyword.return
|
||||
|
||||
[
|
||||
"while"
|
||||
"for"
|
||||
"do"
|
||||
"continue"
|
||||
"break"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"if"
|
||||
"else"
|
||||
"case"
|
||||
"switch"
|
||||
] @conditional
|
||||
|
||||
"#define" @constant.macro
|
||||
[
|
||||
"#if"
|
||||
"#ifdef"
|
||||
"#ifndef"
|
||||
"#else"
|
||||
"#elif"
|
||||
"#endif"
|
||||
(preproc_directive)
|
||||
] @keyword
|
||||
|
||||
"#include" @include
|
||||
|
||||
[
|
||||
"="
|
||||
|
||||
"-"
|
||||
"*"
|
||||
"/"
|
||||
"+"
|
||||
"%"
|
||||
|
||||
"~"
|
||||
"|"
|
||||
"&"
|
||||
"^"
|
||||
"<<"
|
||||
">>"
|
||||
|
||||
"->"
|
||||
|
||||
"<"
|
||||
"<="
|
||||
">="
|
||||
">"
|
||||
"=="
|
||||
"!="
|
||||
|
||||
"!"
|
||||
"&&"
|
||||
"||"
|
||||
|
||||
"-="
|
||||
"+="
|
||||
"*="
|
||||
"/="
|
||||
"%="
|
||||
"|="
|
||||
"&="
|
||||
"^="
|
||||
">>="
|
||||
"<<="
|
||||
"--"
|
||||
"++"
|
||||
] @operator
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
] @boolean
|
||||
|
||||
[ "." ";" ":" "," ] @punctuation.delimiter
|
||||
|
||||
"..." @punctuation.special
|
||||
|
||||
(conditional_expression [ "?" ":" ] @conditional)
|
||||
|
||||
|
||||
[ "(" ")" "[" "]" "{" "}"] @punctuation.bracket
|
||||
|
||||
(string_literal) @string
|
||||
(system_lib_string) @string
|
||||
(escape_sequence) @string.escape
|
||||
|
||||
(null) @constant.builtin
|
||||
(number_literal) @number
|
||||
(char_literal) @character
|
||||
|
||||
[
|
||||
(preproc_arg)
|
||||
(preproc_defined)
|
||||
] @function.macro
|
||||
|
||||
(((field_expression
|
||||
(field_identifier) @property)) @_parent
|
||||
(#not-has-parent? @_parent template_method function_declarator call_expression))
|
||||
|
||||
(((field_identifier) @property)
|
||||
(#has-ancestor? @property field_declaration)
|
||||
(#not-has-ancestor? @property function_declarator))
|
||||
|
||||
(statement_identifier) @label
|
||||
|
||||
[
|
||||
(type_identifier)
|
||||
(primitive_type)
|
||||
(sized_type_specifier)
|
||||
(type_descriptor)
|
||||
] @type
|
||||
|
||||
(sizeof_expression value: (parenthesized_expression (identifier) @type))
|
||||
|
||||
((identifier) @constant
|
||||
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
|
||||
(enumerator
|
||||
name: (identifier) @constant)
|
||||
(case_statement
|
||||
value: (identifier) @constant)
|
||||
|
||||
;; Preproc def / undef
|
||||
(preproc_def
|
||||
name: (_) @constant)
|
||||
(preproc_call
|
||||
directive: (preproc_directive) @_u
|
||||
argument: (_) @constant
|
||||
(#eq? @_u "#undef"))
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
(call_expression
|
||||
function: (field_expression
|
||||
field: (field_identifier) @function))
|
||||
(function_declarator
|
||||
declarator: (identifier) @function)
|
||||
(preproc_function_def
|
||||
name: (identifier) @function.macro)
|
||||
|
||||
(comment) @comment
|
||||
|
||||
;; Parameters
|
||||
(parameter_declaration
|
||||
declarator: (identifier) @parameter)
|
||||
|
||||
(parameter_declaration
|
||||
declarator: (pointer_declarator) @parameter)
|
||||
|
||||
(preproc_params (identifier) @parameter)
|
||||
|
||||
[
|
||||
"__attribute__"
|
||||
"__cdecl"
|
||||
"__clrcall"
|
||||
"__stdcall"
|
||||
"__fastcall"
|
||||
"__thiscall"
|
||||
"__vectorcall"
|
||||
"_unaligned"
|
||||
"__unaligned"
|
||||
"__declspec"
|
||||
] @attribute
|
||||
|
||||
(ERROR) @error
|
49
bundle/nvim-treesitter/queries/c/indents.scm
Normal file
49
bundle/nvim-treesitter/queries/c/indents.scm
Normal file
@ -0,0 +1,49 @@
|
||||
[
|
||||
(compound_statement)
|
||||
(preproc_arg)
|
||||
(field_declaration_list)
|
||||
(case_statement)
|
||||
(enumerator_list)
|
||||
(struct_specifier)
|
||||
(compound_literal_expression)
|
||||
(initializer_list)
|
||||
(while_statement)
|
||||
(for_statement)
|
||||
(switch_statement)
|
||||
(expression_statement)
|
||||
] @indent
|
||||
(if_statement condition: (_) @indent)
|
||||
((if_statement
|
||||
consequence: (_) @_consequence
|
||||
(#not-has-type? @_consequence compound_statement)
|
||||
) @indent)
|
||||
(init_declarator) @indent
|
||||
|
||||
(compound_statement "}" @indent_end)
|
||||
|
||||
[
|
||||
"else"
|
||||
")"
|
||||
"}"
|
||||
(statement_identifier)
|
||||
] @branch
|
||||
|
||||
[
|
||||
"#define"
|
||||
"#ifdef"
|
||||
"#if"
|
||||
"#else"
|
||||
"#endif"
|
||||
] @zero_indent
|
||||
|
||||
[
|
||||
(preproc_arg)
|
||||
(string_literal)
|
||||
] @ignore
|
||||
|
||||
((ERROR (parameter_declaration)) @aligned_indent
|
||||
(#set! "delimiter" "()"))
|
||||
([(argument_list) (parameter_list)] @aligned_indent
|
||||
(#set! "delimiter" "()"))
|
||||
|
||||
(comment) @auto
|
3
bundle/nvim-treesitter/queries/c/injections.scm
Normal file
3
bundle/nvim-treesitter/queries/c/injections.scm
Normal file
@ -0,0 +1,3 @@
|
||||
(preproc_arg) @c
|
||||
|
||||
(comment) @comment
|
53
bundle/nvim-treesitter/queries/c/locals.scm
Normal file
53
bundle/nvim-treesitter/queries/c/locals.scm
Normal file
@ -0,0 +1,53 @@
|
||||
;; Functions definitions
|
||||
(function_declarator
|
||||
declarator: (identifier) @definition.function)
|
||||
(preproc_function_def
|
||||
name: (identifier) @definition.macro) @scope
|
||||
|
||||
(preproc_def
|
||||
name: (identifier) @definition.macro)
|
||||
(pointer_declarator
|
||||
declarator: (identifier) @definition.var)
|
||||
(parameter_declaration
|
||||
declarator: (identifier) @definition.parameter)
|
||||
(init_declarator
|
||||
declarator: (identifier) @definition.var)
|
||||
(array_declarator
|
||||
declarator: (identifier) @definition.var)
|
||||
(declaration
|
||||
declarator: (identifier) @definition.var)
|
||||
(enum_specifier
|
||||
name: (_) @definition.type
|
||||
(enumerator_list
|
||||
(enumerator name: (identifier) @definition.var)))
|
||||
|
||||
;; Type / Struct / Enum
|
||||
(field_declaration
|
||||
declarator: (field_identifier) @definition.field)
|
||||
(type_definition
|
||||
declarator: (type_identifier) @definition.type)
|
||||
(struct_specifier
|
||||
name: (type_identifier) @definition.type)
|
||||
|
||||
;; goto
|
||||
(labeled_statement (statement_identifier) @definition)
|
||||
|
||||
;; References
|
||||
(identifier) @reference
|
||||
((field_identifier) @reference
|
||||
(set! reference.kind "field"))
|
||||
((type_identifier) @reference
|
||||
(set! reference.kind "type"))
|
||||
|
||||
(goto_statement (statement_identifier) @reference)
|
||||
|
||||
;; Scope
|
||||
[
|
||||
(for_statement)
|
||||
(if_statement)
|
||||
(while_statement)
|
||||
(translation_unit)
|
||||
(function_definition)
|
||||
(compound_statement) ; a block in curly braces
|
||||
(struct_specifier)
|
||||
] @scope
|
15
bundle/nvim-treesitter/queries/c_sharp/folds.scm
Normal file
15
bundle/nvim-treesitter/queries/c_sharp/folds.scm
Normal file
@ -0,0 +1,15 @@
|
||||
body: [
|
||||
(declaration_list)
|
||||
(switch_body)
|
||||
(enum_member_declaration_list)
|
||||
] @fold
|
||||
|
||||
accessors: [
|
||||
(accessor_list)
|
||||
] @fold
|
||||
|
||||
initializer: [
|
||||
(initializer_expression)
|
||||
] @fold
|
||||
|
||||
(block) @fold
|
390
bundle/nvim-treesitter/queries/c_sharp/highlights.scm
Normal file
390
bundle/nvim-treesitter/queries/c_sharp/highlights.scm
Normal file
@ -0,0 +1,390 @@
|
||||
(identifier) @variable
|
||||
|
||||
((identifier) @keyword
|
||||
(#eq? @keyword "value")
|
||||
(#has-ancestor? @keyword accessor_declaration))
|
||||
|
||||
(method_declaration
|
||||
name: (identifier) @method)
|
||||
|
||||
(local_function_statement
|
||||
name: (identifier) @method)
|
||||
|
||||
(method_declaration
|
||||
type: (identifier) @type)
|
||||
|
||||
(local_function_statement
|
||||
type: (identifier) @type)
|
||||
|
||||
(interpolation) @none
|
||||
|
||||
(invocation_expression
|
||||
(member_access_expression
|
||||
name: (identifier) @method))
|
||||
|
||||
(invocation_expression
|
||||
function: (conditional_access_expression
|
||||
(member_binding_expression
|
||||
name: (identifier) @method)))
|
||||
|
||||
(namespace_declaration
|
||||
name: [(qualified_name) (identifier)] @namespace)
|
||||
|
||||
(qualified_name
|
||||
(identifier) @type)
|
||||
|
||||
(invocation_expression
|
||||
(identifier) @method)
|
||||
|
||||
(field_declaration
|
||||
(variable_declaration
|
||||
(variable_declarator
|
||||
(identifier) @field)))
|
||||
|
||||
(initializer_expression
|
||||
(assignment_expression
|
||||
left: (identifier) @field))
|
||||
|
||||
(parameter_list
|
||||
(parameter
|
||||
name: (identifier) @parameter))
|
||||
|
||||
(parameter_list
|
||||
(parameter
|
||||
type: (identifier) @type))
|
||||
|
||||
(integer_literal) @number
|
||||
(real_literal) @float
|
||||
|
||||
(null_literal) @constant.builtin
|
||||
(character_literal) @character
|
||||
|
||||
[
|
||||
(string_literal)
|
||||
(verbatim_string_literal)
|
||||
(interpolated_string_expression)
|
||||
] @string
|
||||
|
||||
(boolean_literal) @boolean
|
||||
|
||||
[
|
||||
(predefined_type)
|
||||
(void_keyword)
|
||||
] @type.builtin
|
||||
|
||||
(implicit_type) @keyword
|
||||
|
||||
(comment) @comment
|
||||
|
||||
(using_directive
|
||||
(identifier) @type)
|
||||
|
||||
(property_declaration
|
||||
name: (identifier) @property)
|
||||
|
||||
(property_declaration
|
||||
type: (identifier) @type)
|
||||
|
||||
(nullable_type
|
||||
(identifier) @type)
|
||||
|
||||
(catch_declaration
|
||||
type: (identifier) @type)
|
||||
|
||||
(interface_declaration
|
||||
name: (identifier) @type)
|
||||
(class_declaration
|
||||
name: (identifier) @type)
|
||||
(record_declaration
|
||||
name: (identifier) @type)
|
||||
(enum_declaration
|
||||
name: (identifier) @type)
|
||||
(constructor_declaration
|
||||
name: (identifier) @constructor)
|
||||
(constructor_initializer [
|
||||
"base" @constructor
|
||||
])
|
||||
|
||||
(variable_declaration
|
||||
(identifier) @type)
|
||||
(object_creation_expression
|
||||
(identifier) @type)
|
||||
|
||||
; Generic Types.
|
||||
(type_of_expression
|
||||
(generic_name
|
||||
(identifier) @type))
|
||||
|
||||
(type_argument_list
|
||||
(generic_name
|
||||
(identifier) @type))
|
||||
|
||||
(base_list
|
||||
(generic_name
|
||||
(identifier) @type))
|
||||
|
||||
(type_constraint
|
||||
(generic_name
|
||||
(identifier) @type))
|
||||
|
||||
(object_creation_expression
|
||||
(generic_name
|
||||
(identifier) @type))
|
||||
|
||||
(property_declaration
|
||||
(generic_name
|
||||
(identifier) @type))
|
||||
|
||||
(_
|
||||
type: (generic_name
|
||||
(identifier) @type))
|
||||
; Generic Method invocation with generic type
|
||||
(invocation_expression
|
||||
function: (generic_name
|
||||
. (identifier) @method))
|
||||
|
||||
(invocation_expression
|
||||
(member_access_expression
|
||||
(generic_name
|
||||
(identifier) @method)))
|
||||
|
||||
(base_list
|
||||
(identifier) @type)
|
||||
|
||||
(type_argument_list
|
||||
(identifier) @type)
|
||||
|
||||
(type_parameter_list
|
||||
(type_parameter) @type)
|
||||
|
||||
(type_parameter_constraints_clause
|
||||
target: (identifier) @type)
|
||||
|
||||
(attribute
|
||||
name: (identifier) @attribute)
|
||||
|
||||
(for_each_statement
|
||||
type: (identifier) @type)
|
||||
|
||||
(tuple_element
|
||||
type: (identifier) @type)
|
||||
|
||||
(tuple_expression
|
||||
(argument
|
||||
(declaration_expression
|
||||
type: (identifier) @type)))
|
||||
|
||||
(as_expression
|
||||
right: (identifier) @type)
|
||||
|
||||
(type_of_expression
|
||||
(identifier) @type)
|
||||
|
||||
(name_colon
|
||||
(identifier) @parameter)
|
||||
|
||||
(warning_directive) @text.warning
|
||||
(error_directive) @exception
|
||||
|
||||
(define_directive
|
||||
(identifier) @constant) @constant.macro
|
||||
(undef_directive
|
||||
(identifier) @constant) @constant.macro
|
||||
|
||||
(line_directive) @constant.macro
|
||||
(line_directive
|
||||
(preproc_integer_literal) @constant
|
||||
(preproc_string_literal)? @string)
|
||||
|
||||
(pragma_directive
|
||||
(identifier) @constant) @constant.macro
|
||||
(pragma_directive
|
||||
(preproc_string_literal) @string) @constant.macro
|
||||
|
||||
[
|
||||
(nullable_directive)
|
||||
(region_directive)
|
||||
(endregion_directive)
|
||||
] @constant.macro
|
||||
|
||||
[
|
||||
"if"
|
||||
"else"
|
||||
"switch"
|
||||
"break"
|
||||
"case"
|
||||
(if_directive)
|
||||
(elif_directive)
|
||||
(else_directive)
|
||||
(endif_directive)
|
||||
] @conditional
|
||||
|
||||
(if_directive
|
||||
(identifier) @constant)
|
||||
(elif_directive
|
||||
(identifier) @constant)
|
||||
|
||||
[
|
||||
"while"
|
||||
"for"
|
||||
"do"
|
||||
"continue"
|
||||
"goto"
|
||||
"foreach"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"try"
|
||||
"catch"
|
||||
"throw"
|
||||
"finally"
|
||||
] @exception
|
||||
|
||||
[
|
||||
"+"
|
||||
"?"
|
||||
":"
|
||||
"++"
|
||||
"-"
|
||||
"--"
|
||||
"&"
|
||||
"&&"
|
||||
"|"
|
||||
"||"
|
||||
"!"
|
||||
"!="
|
||||
"=="
|
||||
"*"
|
||||
"/"
|
||||
"%"
|
||||
"<"
|
||||
"<="
|
||||
">"
|
||||
">="
|
||||
"="
|
||||
"-="
|
||||
"+="
|
||||
"*="
|
||||
"/="
|
||||
"%="
|
||||
"^"
|
||||
"^="
|
||||
"&="
|
||||
"|="
|
||||
"~"
|
||||
">>"
|
||||
"<<"
|
||||
"<<="
|
||||
">>="
|
||||
"=>"
|
||||
] @operator
|
||||
|
||||
[
|
||||
";"
|
||||
"."
|
||||
","
|
||||
":"
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
"("
|
||||
")"
|
||||
"<"
|
||||
">"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
(this_expression)
|
||||
(base_expression)
|
||||
] @variable.builtin
|
||||
|
||||
[
|
||||
"using"
|
||||
] @include
|
||||
|
||||
(alias_qualified_name
|
||||
(identifier "global") @include)
|
||||
|
||||
[
|
||||
"with"
|
||||
"new"
|
||||
"typeof"
|
||||
"nameof"
|
||||
"sizeof"
|
||||
"is"
|
||||
"as"
|
||||
"and"
|
||||
"or"
|
||||
"not"
|
||||
"stackalloc"
|
||||
"in"
|
||||
"out"
|
||||
"ref"
|
||||
] @keyword.operator
|
||||
|
||||
[
|
||||
"lock"
|
||||
"params"
|
||||
"operator"
|
||||
"default"
|
||||
"abstract"
|
||||
"const"
|
||||
"extern"
|
||||
"implicit"
|
||||
"explicit"
|
||||
"internal"
|
||||
"override"
|
||||
"private"
|
||||
"protected"
|
||||
"public"
|
||||
"internal"
|
||||
"partial"
|
||||
"readonly"
|
||||
"sealed"
|
||||
"static"
|
||||
"virtual"
|
||||
"volatile"
|
||||
"async"
|
||||
"await"
|
||||
"class"
|
||||
"delegate"
|
||||
"enum"
|
||||
"interface"
|
||||
"namespace"
|
||||
"struct"
|
||||
"get"
|
||||
"set"
|
||||
"init"
|
||||
"where"
|
||||
"record"
|
||||
"event"
|
||||
"add"
|
||||
"remove"
|
||||
"checked"
|
||||
"unchecked"
|
||||
"fixed"
|
||||
] @keyword
|
||||
|
||||
(parameter_modifier) @operator
|
||||
|
||||
(query_expression
|
||||
(_ [
|
||||
"from"
|
||||
"orderby"
|
||||
"select"
|
||||
"group"
|
||||
"by"
|
||||
"ascending"
|
||||
"descending"
|
||||
"equals"
|
||||
"let"
|
||||
] @keyword))
|
||||
|
||||
[
|
||||
"return"
|
||||
"yield"
|
||||
] @keyword.return
|
1
bundle/nvim-treesitter/queries/c_sharp/injections.scm
Normal file
1
bundle/nvim-treesitter/queries/c_sharp/injections.scm
Normal file
@ -0,0 +1 @@
|
||||
(comment) @comment
|
41
bundle/nvim-treesitter/queries/c_sharp/locals.scm
Normal file
41
bundle/nvim-treesitter/queries/c_sharp/locals.scm
Normal file
@ -0,0 +1,41 @@
|
||||
;; Definitions
|
||||
(variable_declarator
|
||||
. (identifier) @definition.var)
|
||||
|
||||
(variable_declarator
|
||||
(tuple_pattern
|
||||
(identifier) @definition.var))
|
||||
|
||||
(declaration_expression
|
||||
name: (identifier) @definition.var)
|
||||
|
||||
(for_each_statement
|
||||
left: (identifier) @definition.var)
|
||||
|
||||
(for_each_statement
|
||||
left: (tuple_pattern
|
||||
(identifier) @definition.var))
|
||||
|
||||
(parameter
|
||||
(identifier) @definition.parameter)
|
||||
|
||||
(method_declaration
|
||||
name: (identifier) @definition.method)
|
||||
|
||||
(local_function_statement
|
||||
name: (identifier) @definition.method)
|
||||
|
||||
(property_declaration
|
||||
name: (identifier) @definition)
|
||||
|
||||
(type_parameter
|
||||
(identifier) @definition.type)
|
||||
|
||||
(class_declaration
|
||||
name: (identifier) @definition)
|
||||
|
||||
;; References
|
||||
(identifier) @reference
|
||||
|
||||
;; Scope
|
||||
(block) @scope
|
1
bundle/nvim-treesitter/queries/clojure/folds.scm
Normal file
1
bundle/nvim-treesitter/queries/clojure/folds.scm
Normal file
@ -0,0 +1 @@
|
||||
(source (list_lit) @fold)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user