mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-02 11:36:54 -04:00
Merge branch 'master' into rust-queries
This commit is contained in:
commit
8a76b16814
49 changed files with 2887 additions and 1109 deletions
11
.github/ISSUE_TEMPLATE/bug_report.md
vendored
11
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -20,10 +20,15 @@ Steps to reproduce the behavior:
|
|||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Output of `:checkhealth nvim_treesitter` ***
|
||||
```
|
||||
**Output of `:checkhealth nvim_treesitter`**
|
||||
|
||||
<details>
|
||||
<code>
|
||||
|
||||
Paste the output here
|
||||
```
|
||||
|
||||
</code>
|
||||
</details>
|
||||
|
||||
**Output of `nvim --version`**
|
||||
```
|
||||
|
|
|
|||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
doc/tags
|
||||
.luacheckcache
|
||||
16
.luacheckrc
Normal file
16
.luacheckrc
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- Rerun tests only if their modification time changed.
|
||||
cache = true
|
||||
|
||||
-- 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",
|
||||
}
|
||||
11
.travis.yml
Normal file
11
.travis.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
language: c
|
||||
dist: bionic
|
||||
before_install:
|
||||
- sudo apt-get update
|
||||
- sudo add-apt-repository universe
|
||||
- sudo apt install luarocks -y
|
||||
- sudo luarocks install luacheck
|
||||
|
||||
script:
|
||||
- ./scripts/style-check.sh
|
||||
122
CONTRIBUTING.md
122
CONTRIBUTING.md
|
|
@ -11,6 +11,18 @@ As you know, `nvim-treesitter` is roughly splitted in two parts :
|
|||
|
||||
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 functionality tests yet. Feel free to contribute.
|
||||
However, we check code style with `luacheck`!
|
||||
Please install luacheck and activate our `pre-push` hook to automatically check style before
|
||||
every push:
|
||||
|
||||
```bash
|
||||
luarocks install luacheck
|
||||
ln -s ../../scripts/pre-push .git/hooks/pre-push
|
||||
```
|
||||
|
||||
## Parser configurations
|
||||
|
||||
Contributing to parser configurations is basically modifying one of the `queries/*/*.scm`.
|
||||
|
|
@ -29,6 +41,7 @@ Here are some global advices :
|
|||
- 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.
|
||||
- An Example of somewhat complex highlight queries can be found in queries/ruby/highlights.scm (Maintained by @TravonteD)
|
||||
|
||||
### Highlights
|
||||
|
||||
|
|
@ -36,65 +49,75 @@ As languages differ quite a lot, here is a set of captures available to you when
|
|||
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`
|
||||
`@error` for error `(ERROR)` nodes.
|
||||
`@punctuation.delimiter` for `;` `.` `,`
|
||||
`@punctuation.bracket` for `()` or `{}`
|
||||
```
|
||||
@comment
|
||||
@error for error (ERROR` nodes.
|
||||
@punctuation.delimiter for `;` `.` `,`
|
||||
@punctuation.bracket for `()` or `{}`
|
||||
```
|
||||
|
||||
Some captures are related to language injection (like markdown code blocks). As this is not supported by neovim yet, these
|
||||
are optional and will not have any effect for now.
|
||||
`@embedded`
|
||||
`@injection`
|
||||
`language`
|
||||
`content`
|
||||
|
||||
```
|
||||
@embedded
|
||||
@injection
|
||||
language
|
||||
content
|
||||
```
|
||||
#### Constants
|
||||
`@constant`
|
||||
`builtin`
|
||||
`macro`
|
||||
`@string`
|
||||
`regex`
|
||||
`escape`
|
||||
`@character`
|
||||
`@number`
|
||||
`@boolean`
|
||||
`@float`
|
||||
```
|
||||
@constant
|
||||
builtin
|
||||
macro
|
||||
@string
|
||||
regex
|
||||
escape
|
||||
@character
|
||||
@number
|
||||
@boolean
|
||||
@float
|
||||
```
|
||||
|
||||
#### Functions
|
||||
`@function`
|
||||
`builtin`
|
||||
`macro`
|
||||
`@parameter`
|
||||
```
|
||||
@function
|
||||
builtin
|
||||
macro
|
||||
@parameter
|
||||
|
||||
`@method`
|
||||
`@field` or `@property`
|
||||
@method
|
||||
@field or @property
|
||||
|
||||
`@constructor`
|
||||
@constructor
|
||||
```
|
||||
|
||||
#### Keywords
|
||||
`@conditional`
|
||||
`@repeat`
|
||||
`@label` for C/Lua-like labels
|
||||
`@operator`
|
||||
`@keyword`
|
||||
`@exception`
|
||||
`@include` keywords for including modules (e.g. import/from in Python)
|
||||
|
||||
`@type`
|
||||
`builtin`
|
||||
`@structure`
|
||||
```
|
||||
@conditional
|
||||
@repeat
|
||||
@label for C/Lua-like labels
|
||||
@operator
|
||||
@keyword
|
||||
@exception
|
||||
@include keywords for including modules (e.g. import/from in Python)
|
||||
|
||||
@type
|
||||
builtin
|
||||
@structure
|
||||
```
|
||||
### Locals
|
||||
|
||||
`@definition` for various definitions
|
||||
`function`
|
||||
`method`
|
||||
`var`
|
||||
`macro`
|
||||
`type`
|
||||
`field`
|
||||
`doc` for documentation adjecent to a definition. E.g.
|
||||
```
|
||||
@definition for various definitions
|
||||
function
|
||||
method
|
||||
var
|
||||
macro
|
||||
type
|
||||
field
|
||||
doc for documentation adjecent to a definition. E.g.
|
||||
```
|
||||
|
||||
```scheme
|
||||
(comment)* @definition.doc
|
||||
|
|
@ -102,7 +125,8 @@ are optional and will not have any effect for now.
|
|||
name: (field_identifier) @definition.method)
|
||||
```
|
||||
|
||||
`@scope`
|
||||
|
||||
`@reference`
|
||||
```
|
||||
@scope
|
||||
@reference
|
||||
```
|
||||
|
||||
|
|
|
|||
201
LICENSE
Normal file
201
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.
|
||||
65
README.md
65
README.md
|
|
@ -1,7 +1,11 @@
|
|||
[](https://gitter.im/nvim-treesitter/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://travis-ci.com/nvim-treesitter/nvim-treesitter)
|
||||
# nvim-treesitter
|
||||
Treesitter configurations and abstraction layer for Neovim.
|
||||
|
||||
**Warning: Treesitter and Treesitter highlighting are an experimental feature of nightly versions of Neovim.
|
||||
Please consider the experience with this plug-in as experimental until Neovim 0.5 is released!**
|
||||
|
||||
# Quickstart
|
||||
|
||||
## Requirements
|
||||
|
|
@ -33,7 +37,7 @@ $ git clone https://github.com/nvim-treesitter/nvim-treesitter.git
|
|||
|
||||
Treesitter is using a different _parser_ for every language. It can be quite a pain to install, but fortunately `nvim-treesitter`
|
||||
provides two command to tackle this issue:
|
||||
- `TSInstall` to install a given parser.
|
||||
- `TSInstall` to install one or more parser. You can use `TSInstall all` to download all parsers.
|
||||
- `TSInstallInfo` to know which parser is installed.
|
||||
|
||||
Let's say you need parsers for `lua`, `c`, and `python`, this is how you do with these commands:
|
||||
|
|
@ -99,9 +103,23 @@ require'nvim-treesitter.configs'.setup {
|
|||
init_selection = 'gnn', -- maps in normal mode to init the node/scope selection
|
||||
node_incremental = "grn", -- increment to the upper named parent
|
||||
scope_incremental = "grc", -- increment to the upper scope (as defined in locals.scm)
|
||||
node_decremental = "grm", -- decrement to the previous node
|
||||
node_decremental = "grm", -- decrement to the previous node
|
||||
}
|
||||
},
|
||||
refactor = {
|
||||
highlight_defintions = {
|
||||
enable = true
|
||||
},
|
||||
smart_rename = {
|
||||
enable = true,
|
||||
smart_rename = "grr" -- mapping to rename reference under cursor
|
||||
},
|
||||
navigation = {
|
||||
enable = true,
|
||||
goto_definition = "gnd", -- mapping to go to definition of symbol under cursor
|
||||
list_definitions = "gnD" -- mapping to list all definitions in current file
|
||||
}
|
||||
},
|
||||
ensure_installed = 'all' -- one of 'all', 'language', or a list of languages
|
||||
}
|
||||
EOF
|
||||
|
|
@ -131,19 +149,23 @@ Some of these features are :
|
|||
You can find the 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!
|
||||
|
||||
## Api
|
||||
## Available Modules
|
||||
|
||||
Nvim-treesitter exposes an api to extend node capabilites. You can retrieve the api like this:
|
||||
- `highlight`: Consistent syntax highlighting.
|
||||
- `incremental_selection`: Syntax based selection.
|
||||
- `refactor.highlight_definitions`: Syntax based definition and usage highlighting.
|
||||
- `refactor.smart_rename`: Syntax based definition and usage renaming.
|
||||
- `refactor.navigation`: Syntax based definition listing and navigation.
|
||||
* List all definitions
|
||||
* Go to definition
|
||||
|
||||
## Utils
|
||||
|
||||
you can get some utility functions with
|
||||
```lua
|
||||
local ts_node_api = require 'nvim-treesitter'.get_node_api()
|
||||
local ts_utils = require 'nvim-treesitter.ts_utils'
|
||||
```
|
||||
|
||||
You can also retrieve the current state of the current buffer with:
|
||||
```lua
|
||||
local buf_state = require'nvim-treesitter'.get_buf_state()
|
||||
```
|
||||
|
||||
More information is available in neovim documentation (`:help nvim-treesitter-api`).
|
||||
More information is available in the help file (`:help nvim-treesitter-utils`).
|
||||
|
||||
## Supported Languages
|
||||
|
||||
|
|
@ -156,22 +178,22 @@ List of currently supported languages:
|
|||
- [x] ruby (maintained by @TravonteD)
|
||||
- [x] c (maintained by @vigoux)
|
||||
- [x] go (maintained by @theHamsta)
|
||||
- [ ] cpp
|
||||
- [x] cpp (maintained by @theHamsta, extends C queries)
|
||||
- [ ] rust
|
||||
- [x] python (maintained by @theHamsta)
|
||||
- [ ] javascript
|
||||
- [ ] typescript
|
||||
- [x] javascript (maintained by @steelsojka)
|
||||
- [x] typescript (maintained by @steelsojka)
|
||||
- [ ] tsx
|
||||
- [ ] json
|
||||
- [x] json (maintained by @steelsojka)
|
||||
- [x] html (maintained by @TravonteD)
|
||||
- [ ] csharp
|
||||
- [ ] swift
|
||||
- [ ] java
|
||||
- [x] java
|
||||
- [ ] ocaml
|
||||
- [x] css (maintained by @TravonteD)
|
||||
- [ ] julia
|
||||
- [ ] php
|
||||
- [ ] bash
|
||||
- [x] bash (maintained by @TravonteD)
|
||||
- [ ] scala
|
||||
- [ ] haskell
|
||||
- [ ] toml
|
||||
|
|
@ -182,6 +204,13 @@ List of currently supported languages:
|
|||
- [ ] markdown
|
||||
- [x] regex (maintained by @theHamsta)
|
||||
|
||||
## User Query Extensions
|
||||
|
||||
You can add your own query files by placing a query file in vim's runtime path after `nvim-treesitter` is sourced.
|
||||
If the language has a built in query file, that file will be appended to or it will be used (useful for languages not yet supported).
|
||||
For example, you can add files to `<vim-config-dir>/after/queries/lua/highlights.scm` to add more queries to lua highlights.
|
||||
You can also manually add query paths to the runtime path by adding this to your vim config `set rtp+='path/to/queries'`.
|
||||
|
||||
## Troubleshooting
|
||||
Before doing anything run `:checkhealth nvim_treesitter`. This will help you find where the bug might come from.
|
||||
|
||||
|
|
|
|||
|
|
@ -52,9 +52,10 @@ By default, everything is disabled. To enable support for features, in your `ini
|
|||
==============================================================================
|
||||
COMMANDS *nvim-treesitter-commands*
|
||||
|
||||
|:TSInstall| {language} *:TSInstall*
|
||||
|:TSInstall| {language} ... *:TSInstall*
|
||||
|
||||
Download, compile and install a parser for {language}
|
||||
Install one or more treesitter parsers.
|
||||
You can use |:TSInstall| `all` to install all parsers.
|
||||
|
||||
|:TSInstallInfo| *:TSInstallInfo*
|
||||
|
||||
|
|
@ -91,26 +92,29 @@ A list of languages can be found at |:TSInstallInfo|
|
|||
List modules state for the current session.
|
||||
|
||||
==============================================================================
|
||||
API *nvim-treesitter-api*
|
||||
UTILS *nvim-treesitter-utils*
|
||||
|
||||
Nvim treesitter exposes extended functions to use on nodes and scopes.
|
||||
you can retrieve the api with:
|
||||
Nvim treesitter has some wrapper functions that you can retrieve with:
|
||||
>
|
||||
local ts_node_api = require 'nvim-treesitter'.get_node_api()
|
||||
local ts_utils = require 'nvim-treesitter.ts_utils'
|
||||
<
|
||||
Methods
|
||||
|
||||
get_node_text(node, bufnr) *ts_api.get_node_text*
|
||||
get_node_at_cursor(winnr) *ts_utils.get_node_at_cursor*
|
||||
winnr will be 0 if nil
|
||||
returns the node under the cursor
|
||||
|
||||
get_node_text(node, bufnr) *ts_utils.get_node_text*
|
||||
return the text content of a node
|
||||
|
||||
is_parent(dest, source) *ts_api.is_parent*
|
||||
is_parent(dest, source) *ts_utils.is_parent*
|
||||
determines wether `dest` is a parent of `source`
|
||||
return a boolean
|
||||
|
||||
get_named_children(node) *ts_api.get_named_children*
|
||||
get_named_children(node) *ts_utils.get_named_children*
|
||||
return a table of named children of `node`
|
||||
|
||||
get_next_node(node, allow_switch_parent, allow_next_parent) *ts_api.get_next_node*
|
||||
get_next_node(node, allow_switch_parent, allow_next_parent) *ts_utils.get_next_node*
|
||||
return 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
|
||||
|
|
@ -118,42 +122,28 @@ get_next_node(node, allow_switch_parent, allow_next_parent) *ts_api.get_next_nod
|
|||
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.
|
||||
|
||||
get_previous_node(node, allow_switch_parents, allow_prev_parent) *ts_api.get_previous_node*
|
||||
get_previous_node(node, allow_switch_parents, allow_prev_parent) *ts_utils.get_previous_node*
|
||||
return the previous node within the same parent.
|
||||
`allow_switch_parent` and `allow_prev_parent` follow the same rule
|
||||
as |ts_api.get_next_node| but if the node is the first node.
|
||||
as |ts_utils.get_next_node| but if the node is the first node.
|
||||
|
||||
containing_scope(node) *ts_api.containing_scope*
|
||||
containing_scope(node) *ts_utils.containing_scope*
|
||||
return the smallest scope containing the node
|
||||
|
||||
parent_scope(node, cursor_pos) *ts_api.parent_scope*
|
||||
parent_scope(node, cursor_pos) *ts_utils.parent_scope*
|
||||
return the parent scope of the current scope that contains the node.
|
||||
`cursor_pos` should be `{ row = number, col = number }`
|
||||
you can retrieve the cursor_pos with the buffer state
|
||||
|
||||
nested_scope(node, cursor_pos) *ts_api.nested_scope*
|
||||
nested_scope(node, cursor_pos) *ts_utils.nested_scope*
|
||||
return the first scope within current scope that contains the node.
|
||||
`cursor_pos` should be `{ row = number, col = number }`
|
||||
you can retrieve the cursor_pos with the buffer state
|
||||
|
||||
next_scope(node) *ts_api.next_scope*
|
||||
next_scope(node) *ts_utils.next_scope*
|
||||
return the neighbour scope of the current node
|
||||
|
||||
previous_scope(node) *ts_api.previous_scope*
|
||||
previous_scope(node) *ts_utils.previous_scope*
|
||||
return the previous neighbour scope of the current node
|
||||
|
||||
Nvim-treesitter also provides access to the state of the current buffer:
|
||||
>
|
||||
local cur_buf_state = require'nvim-treesitter'.get_buf_state()
|
||||
print(vim.inspect(cur_buf_state))
|
||||
--[[
|
||||
{
|
||||
cursor_pos = { row = number, col = number }, (current cursor pos in the buffer)
|
||||
current_node = tsnode (smallest node the cursor is on)
|
||||
}
|
||||
]]--
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
FUNCTIONS *nvim-treesitter-functions*
|
||||
|
||||
|
|
@ -177,4 +167,141 @@ 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*
|
||||
|
||||
`TSError`
|
||||
*hl-TSError*
|
||||
For syntax/parser errors.
|
||||
|
||||
You can deactivate highlighting of syntax errors by adding this to your
|
||||
init.vim: >
|
||||
highlight link TSError Normal
|
||||
|
||||
`TSPunctDelimiter`
|
||||
*hl-TSPunctDelimiter*
|
||||
For delimiters ie: `.`
|
||||
|
||||
`TSPunctBracket`
|
||||
*hl-TSPunctBracket*
|
||||
For brackets and parens.
|
||||
|
||||
`TSPunctSpecial`
|
||||
*hl-TSPunctSpecial*
|
||||
For special punctutation that does not fall in the catagories before.
|
||||
|
||||
`TSConstant`
|
||||
*hl-TSConstant*
|
||||
For constants
|
||||
|
||||
`TSConstBuiltin`
|
||||
*hl-TSConstBuiltin*
|
||||
For constant that are built in the language: `nil` in Lua.
|
||||
|
||||
`TSConstMacro`
|
||||
*hl-TSConstMacro*
|
||||
For constants that are defined by macros: `NULL` in C.
|
||||
|
||||
`TSString`
|
||||
*hl-TSString*
|
||||
For strings.
|
||||
|
||||
`TSStringRegex`
|
||||
*hl-TSStringRegex*
|
||||
For regexes.
|
||||
|
||||
`TSStringEscape`
|
||||
*hl-TSStringEscape*
|
||||
For escape characters within a string.
|
||||
|
||||
`TSCharacter`
|
||||
*hl-TSCharacter*
|
||||
For characters.
|
||||
|
||||
`TSNumber`
|
||||
*hl-TSNumber*
|
||||
For integers.
|
||||
|
||||
`TSBoolean`
|
||||
*hl-TSBoolean*
|
||||
For booleans.
|
||||
|
||||
`TSFloat`
|
||||
*hl-TSFloat*
|
||||
For floats.
|
||||
|
||||
`TSFunction`
|
||||
*hl-TSFunction*
|
||||
For function (calls and definitions).
|
||||
|
||||
`TSFuncBuiltin`
|
||||
*hl-TSFuncBuiltin*
|
||||
For builtin functions: `table.insert` in Lua.
|
||||
|
||||
`TSFuncMacro`
|
||||
*hl-TSFuncMacro*
|
||||
For macro defined fuctions (calls and definitions): each `macro_rules` in
|
||||
Rust.
|
||||
|
||||
`TSParameter`
|
||||
*hl-TSParameter*
|
||||
For parameters of a function.
|
||||
|
||||
`TSMethod`
|
||||
*hl-TSMethod*
|
||||
For method calls and definitions.
|
||||
|
||||
`TSField`
|
||||
*hl-TSField*
|
||||
For fields.
|
||||
|
||||
`TSProperty`
|
||||
*hl-TSProperty*
|
||||
Same as `TSField`.
|
||||
|
||||
`TSConstructor`
|
||||
*hl-TSConstructor*
|
||||
For constructor calls and definitions: `{}` in Lua, and Java constructors.
|
||||
|
||||
`TSConditional`
|
||||
*hl-TSConditional*
|
||||
For keywords related to conditionnals.
|
||||
|
||||
`TSRepeat`
|
||||
*hl-TSRepeat*
|
||||
For keywords related to loops.
|
||||
|
||||
`TSLabel`
|
||||
*hl-TSLabel*
|
||||
For labels: `label:` in C and `:label:` in Lua.
|
||||
|
||||
`TSOperator`
|
||||
*hl-TSOperator*
|
||||
For any operator: `+`, but also `->` and `*` in C.
|
||||
|
||||
`TSKeyword`
|
||||
*hl-TSKeyword*
|
||||
For keywords that don't fall in previous categories.
|
||||
|
||||
`TSException`
|
||||
*hl-TSException*
|
||||
For exception related keywords.
|
||||
|
||||
`TSType`
|
||||
*hl-TSType*
|
||||
For types.
|
||||
|
||||
`TSTypeBuiltin`
|
||||
*hl-TSTypeBuiltin*
|
||||
For builtin types (you guessed it, right ?).
|
||||
|
||||
`TSStructure`
|
||||
*hl-TSStructure*
|
||||
This is left as an exercise for the reader.
|
||||
|
||||
`TSInclude`
|
||||
*hl-TSInclude*
|
||||
For includes: `#include` in C, `use` or `extern crate` in Rust, or `require`
|
||||
in Lua
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
|
|
|||
25
doc/tags
25
doc/tags
|
|
@ -1,25 +0,0 @@
|
|||
:TSBufDisable nvim-treesitter.txt /*:TSBufDisable*
|
||||
:TSBufDisableAll nvim-treesitter.txt /*:TSBufDisableAll*
|
||||
:TSBufEnable nvim-treesitter.txt /*:TSBufEnable*
|
||||
:TSBufEnableAll nvim-treesitter.txt /*:TSBufEnableAll*
|
||||
:TSInstall nvim-treesitter.txt /*:TSInstall*
|
||||
:TSInstallInfo nvim-treesitter.txt /*:TSInstallInfo*
|
||||
:TSModuleInfo nvim-treesitter.txt /*:TSModuleInfo*
|
||||
nvim-treesitter nvim-treesitter.txt /*nvim-treesitter*
|
||||
nvim-treesitter-api nvim-treesitter.txt /*nvim-treesitter-api*
|
||||
nvim-treesitter-commands nvim-treesitter.txt /*nvim-treesitter-commands*
|
||||
nvim-treesitter-functions nvim-treesitter.txt /*nvim-treesitter-functions*
|
||||
nvim-treesitter-intro nvim-treesitter.txt /*nvim-treesitter-intro*
|
||||
nvim-treesitter-quickstart nvim-treesitter.txt /*nvim-treesitter-quickstart*
|
||||
nvim_treesitter#foldexpr() nvim-treesitter.txt /*nvim_treesitter#foldexpr()*
|
||||
nvim_treesitter#statusline() nvim-treesitter.txt /*nvim_treesitter#statusline()*
|
||||
ts_api.containing_scope nvim-treesitter.txt /*ts_api.containing_scope*
|
||||
ts_api.get_named_children nvim-treesitter.txt /*ts_api.get_named_children*
|
||||
ts_api.get_next_node nvim-treesitter.txt /*ts_api.get_next_node*
|
||||
ts_api.get_node_text nvim-treesitter.txt /*ts_api.get_node_text*
|
||||
ts_api.get_previous_node nvim-treesitter.txt /*ts_api.get_previous_node*
|
||||
ts_api.is_parent nvim-treesitter.txt /*ts_api.is_parent*
|
||||
ts_api.nested_scope nvim-treesitter.txt /*ts_api.nested_scope*
|
||||
ts_api.next_scope nvim-treesitter.txt /*ts_api.next_scope*
|
||||
ts_api.parent_scope nvim-treesitter.txt /*ts_api.parent_scope*
|
||||
ts_api.previous_scope nvim-treesitter.txt /*ts_api.previous_scope*
|
||||
|
|
@ -2,10 +2,10 @@ local api = vim.api
|
|||
|
||||
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 state = require'nvim-treesitter.state'
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local M = {}
|
||||
|
||||
|
|
@ -14,27 +14,23 @@ function M.setup()
|
|||
utils.setup_commands('info', info.commands)
|
||||
utils.setup_commands('configs', configs.commands)
|
||||
|
||||
for _, ft in pairs(configs.available_parsers()) do
|
||||
for _, lang in pairs(parsers.available_parsers()) do
|
||||
for _, mod in pairs(configs.available_modules()) do
|
||||
if configs.is_enabled(mod, ft) then
|
||||
if configs.is_enabled(mod, lang) then
|
||||
local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
|
||||
api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd))
|
||||
for _, ft in pairs(parsers.lang_to_ft(lang)) do
|
||||
api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd))
|
||||
end
|
||||
end
|
||||
end
|
||||
local cmd = string.format("lua require'nvim-treesitter.state'.attach_to_buffer(%s)", ft)
|
||||
api.nvim_command(string.format('autocmd NvimTreesitter FileType %s %s', ft, cmd))
|
||||
end
|
||||
|
||||
state.run_update()
|
||||
end
|
||||
|
||||
function M.statusline(indicator_size)
|
||||
if not parsers.has_parser() then return end
|
||||
local indicator_size = indicator_size or 100
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local buf_state = state.get_buf_state(bufnr)
|
||||
if not buf_state then return "" end
|
||||
|
||||
local current_node = buf_state.current_node
|
||||
local current_node = ts_utils.get_node_at_cursor()
|
||||
if not current_node then return "" end
|
||||
|
||||
local expr = current_node:parent()
|
||||
|
|
@ -56,13 +52,4 @@ function M.statusline(indicator_size)
|
|||
end
|
||||
end
|
||||
|
||||
function M.get_buf_state()
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
return state.exposed_state(bufnr)
|
||||
end
|
||||
|
||||
function M.get_node_api()
|
||||
return ts_utils
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -1,215 +1,9 @@
|
|||
local api = vim.api
|
||||
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
|
||||
local parsers = {}
|
||||
|
||||
parsers.javascript = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.c = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-c",
|
||||
files = { "src/parser.c" }
|
||||
}
|
||||
}
|
||||
|
||||
parsers.cpp = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-cpp",
|
||||
files = { "src/parser.c", "src/scanner.cc" }
|
||||
}
|
||||
}
|
||||
|
||||
parsers.rust = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.lua = {
|
||||
install_info = {
|
||||
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
||||
files = { "src/parser.c", "src/scanner.cc" }
|
||||
}
|
||||
}
|
||||
|
||||
parsers.python = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-python",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.go = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-go",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.ruby = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.bash = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-bash",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.php = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-php",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.java = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-java",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.html = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-html",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.julia = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.json = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-json",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.css = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-css",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.ocaml = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.swift = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.csharp = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.typescript = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
location = "tree-sitter-typescript/typescript"
|
||||
}
|
||||
}
|
||||
|
||||
parsers.tsx = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
location = "tree-sitter-tsx/tsx"
|
||||
}
|
||||
}
|
||||
|
||||
parsers.scala = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-scala",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.haskell = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-haskell",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.markdown = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-markdown",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.toml = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-toml",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.vue = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-vue",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.elm = {
|
||||
install_info = {
|
||||
url = "https://github.com//razzeee/tree-sitter-elm",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.yaml = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-yaml",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.nix = {
|
||||
install_info = {
|
||||
url = "https://github.com/cstrahan/tree-sitter-nix",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.regex = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-regex",
|
||||
files = { "src/parser.c" }
|
||||
}
|
||||
}
|
||||
|
||||
-- @enable can be true or false
|
||||
-- @disable is a list of languages, only relevant if enable is true
|
||||
-- @keymaps list of user mappings for a given module if relevant
|
||||
|
|
@ -219,9 +13,7 @@ local config = {
|
|||
highlight = {
|
||||
enable = false,
|
||||
disable = {},
|
||||
is_supported = function(ft)
|
||||
return queries.get_query(ft, 'highlights') ~= nil
|
||||
end
|
||||
is_supported = queries.has_highlights
|
||||
},
|
||||
incremental_selection = {
|
||||
enable = false,
|
||||
|
|
@ -232,9 +24,31 @@ local config = {
|
|||
scope_incremental="grc",
|
||||
node_decremental="grm"
|
||||
},
|
||||
is_supported = function(ft)
|
||||
return queries.get_query(ft, 'locals')
|
||||
end
|
||||
is_supported = queries.has_locals
|
||||
},
|
||||
refactor = {
|
||||
highlight_definitions = {
|
||||
enable = false,
|
||||
disable = {},
|
||||
is_supported = queries.has_locals
|
||||
},
|
||||
smart_rename = {
|
||||
enable = false,
|
||||
disable = {},
|
||||
is_supported = queries.has_locals,
|
||||
keymaps = {
|
||||
smart_rename = "grr"
|
||||
}
|
||||
},
|
||||
navigation = {
|
||||
enable = false,
|
||||
disable = {},
|
||||
is_supported = queries.has_locals,
|
||||
keymaps = {
|
||||
goto_definition = "gnd",
|
||||
list_definitions = "gnD"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ensure_installed = nil
|
||||
|
|
@ -242,83 +56,125 @@ local config = {
|
|||
|
||||
local M = {}
|
||||
|
||||
local function enable_module(mod, bufnr, ft)
|
||||
local function enable_module(mod, bufnr, lang)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
||||
if not parsers[ft] or not config.modules[mod] then
|
||||
local lang = lang or parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, 'ft'))
|
||||
|
||||
if not parsers.list[lang] or not M.get_module(mod) then
|
||||
return
|
||||
end
|
||||
|
||||
local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
|
||||
loaded_mod.attach(bufnr, ft)
|
||||
loaded_mod.attach(bufnr, lang)
|
||||
end
|
||||
|
||||
local function enable_mod_conf_autocmd(mod, ft)
|
||||
if not config.modules[mod] or M.is_enabled(mod, ft) then return end
|
||||
local function enable_mod_conf_autocmd(mod, lang)
|
||||
local config_mod = M.get_module(mod)
|
||||
|
||||
if not config_mod or M.is_enabled(mod, lang) then return end
|
||||
|
||||
local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
|
||||
api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd))
|
||||
for i, parser in pairs(config.modules[mod].disable) do
|
||||
if parser == ft then
|
||||
table.remove(config.modules[mod].disable, i)
|
||||
for _, ft in pairs(parsers.lang_to_ft(lang)) do
|
||||
api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd))
|
||||
end
|
||||
for i, parser in pairs(config_mod.disable) do
|
||||
if parser == lang then
|
||||
table.remove(config_mod.disable, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function enable_all(mod, ft)
|
||||
if not config.modules[mod] then return end
|
||||
local function enable_all(mod, lang)
|
||||
local config_mod = M.get_module(mod)
|
||||
|
||||
if not config_mod then return end
|
||||
|
||||
for _, bufnr in pairs(api.nvim_list_bufs()) do
|
||||
if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then
|
||||
enable_module(mod, bufnr, ft)
|
||||
local ft = api.nvim_buf_get_option(bufnr, 'ft')
|
||||
if not lang or parsers.lang_match_ft(lang, ft) then
|
||||
enable_module(mod, bufnr, lang)
|
||||
end
|
||||
end
|
||||
if ft then
|
||||
if utils.has_parser(ft) then
|
||||
enable_mod_conf_autocmd(mod, ft)
|
||||
if lang then
|
||||
if parsers.has_parser(lang) then
|
||||
enable_mod_conf_autocmd(mod, lang)
|
||||
end
|
||||
else
|
||||
for _, ft in pairs(M.available_parsers()) do
|
||||
if utils.has_parser(ft) then
|
||||
enable_mod_conf_autocmd(mod, ft)
|
||||
for _, lang in pairs(parsers.available_parsers()) do
|
||||
if parsers.has_parser(lang) then
|
||||
enable_mod_conf_autocmd(mod, lang)
|
||||
end
|
||||
end
|
||||
end
|
||||
config.modules[mod].enable = true
|
||||
config_mod.enable = true
|
||||
end
|
||||
|
||||
local function disable_module(mod, bufnr, ft)
|
||||
local function disable_module(mod, bufnr, lang)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
||||
if not parsers[ft] or not config.modules[mod] then
|
||||
local lang = lang or parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, 'ft'))
|
||||
if not lang then
|
||||
return
|
||||
end
|
||||
|
||||
if not parsers.list[lang] or not M.get_module(mod) then
|
||||
return
|
||||
end
|
||||
|
||||
local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
|
||||
loaded_mod.detach(bufnr, ft)
|
||||
loaded_mod.detach(bufnr)
|
||||
end
|
||||
|
||||
local function disable_mod_conf_autocmd(mod, ft)
|
||||
if not config.modules[mod] or not M.is_enabled(mod, ft) then return end
|
||||
local function disable_mod_conf_autocmd(mod, lang)
|
||||
local config_mod = M.get_module(mod)
|
||||
|
||||
api.nvim_command(string.format("autocmd! FileType %s", ft))
|
||||
table.insert(config.modules[mod].disable, ft)
|
||||
if not config_mod or not M.is_enabled(mod, lang) then return end
|
||||
|
||||
--local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
|
||||
-- TODO(kyazdani): detach the correct autocmd... doesn't work when using %s, cmd
|
||||
for _, ft in pairs(parsers.lang_to_ft(lang)) do
|
||||
api.nvim_command(string.format("autocmd! NvimTreesitter FileType %s", ft))
|
||||
end
|
||||
table.insert(config_mod.disable, lang)
|
||||
end
|
||||
|
||||
local function disable_all(mod, ft)
|
||||
local function disable_all(mod, lang)
|
||||
for _, bufnr in pairs(api.nvim_list_bufs()) do
|
||||
if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then
|
||||
disable_module(mod, bufnr, ft)
|
||||
local ft = api.nvim_buf_get_option(bufnr, 'ft')
|
||||
if not lang or parsers.lang_match_ft(lang, ft) then
|
||||
disable_module(mod, bufnr, lang)
|
||||
end
|
||||
end
|
||||
if ft then
|
||||
disable_mod_conf_autocmd(mod, ft)
|
||||
if lang then
|
||||
disable_mod_conf_autocmd(mod, lang)
|
||||
else
|
||||
for _, ft in pairs(M.available_parsers()) do
|
||||
disable_mod_conf_autocmd(mod, ft)
|
||||
for _, lang in pairs(parsers.available_parsers()) do
|
||||
disable_mod_conf_autocmd(mod, lang)
|
||||
end
|
||||
|
||||
local config_mod = M.get_module(mod)
|
||||
|
||||
if config_mod then
|
||||
config_mod.enable = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Recurses trough 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)
|
||||
local 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)
|
||||
elseif type(module) == 'table' then
|
||||
recurse_modules(accumulator, module, new_path)
|
||||
end
|
||||
config.modules[mod].enable = false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -328,51 +184,47 @@ M.commands = {
|
|||
args = {
|
||||
"-nargs=1",
|
||||
"-complete=custom,v:lua.ts_available_modules"
|
||||
},
|
||||
description = '`:TSBufEnable module_name` enable a specified module on the current buffer'
|
||||
}
|
||||
},
|
||||
TSBufDisable = {
|
||||
run = disable_module,
|
||||
args = {
|
||||
"-nargs=1",
|
||||
"-complete=custom,v:lua.ts_available_modules"
|
||||
},
|
||||
description = '`:TSBufDisable module_name` disable a specified module on the current buffer'
|
||||
}
|
||||
},
|
||||
TSEnableAll = {
|
||||
run = enable_all,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,v:lua.ts_available_modules"
|
||||
},
|
||||
description = '`:TSEnableAll module_name (filetype)` enables a specified module on all buffers. If filetype is specified, enable only for specified filetype'
|
||||
}
|
||||
},
|
||||
TSDisableAll = {
|
||||
run = disable_all,
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,v:lua.ts_available_modules"
|
||||
},
|
||||
description = '`:TSDisableAll module_name (filetype)` disables a specified module on all buffers. If filetype is specified, disable only for specified filetype'
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
-- @param mod: module (string)
|
||||
-- @param ft: filetype (string)
|
||||
function M.is_enabled(mod, ft)
|
||||
if not M.get_parser_configs()[ft] or not utils.has_parser(ft) then
|
||||
function M.is_enabled(mod, lang)
|
||||
if not parsers.list[lang] or not parsers.has_parser(lang) then
|
||||
return false
|
||||
end
|
||||
|
||||
local module_config = config.modules[mod]
|
||||
local module_config = M.get_module(mod)
|
||||
if not module_config then return false end
|
||||
|
||||
if not module_config.enable or not module_config.is_supported(ft) then
|
||||
if not module_config.enable or not module_config.is_supported(lang) then
|
||||
return false
|
||||
end
|
||||
|
||||
for _, parser in pairs(module_config.disable) do
|
||||
if ft == parser then return false end
|
||||
if lang == parser then return false end
|
||||
end
|
||||
|
||||
return true
|
||||
|
|
@ -381,42 +233,63 @@ end
|
|||
function M.setup(user_data)
|
||||
if not user_data then return end
|
||||
|
||||
for mod, data in pairs(user_data) do
|
||||
if config.modules[mod] then
|
||||
if type(data.enable) == 'boolean' then
|
||||
config.modules[mod].enable = data.enable
|
||||
end
|
||||
if type(data.disable) == 'table' then
|
||||
config.modules[mod].disable = data.disable
|
||||
end
|
||||
if config.modules[mod].keymaps and type(data.keymaps) == 'table' then
|
||||
for f, map in pairs(data.keymaps) do
|
||||
if config.modules[mod].keymaps[f] then
|
||||
config.modules[mod].keymaps[f] = map
|
||||
end
|
||||
M.setup_module(config.modules, user_data)
|
||||
end
|
||||
|
||||
-- Sets up a single module or all submodules of a group.
|
||||
-- Note, this method is recursive.
|
||||
-- @param mod the module or group of modules
|
||||
-- @param data user defined configuration for the module
|
||||
-- @param mod_name name of the module if it exists
|
||||
function M.setup_module(mod, data, mod_name)
|
||||
if mod_name == 'ensure_installed' then
|
||||
config.ensure_installed = data
|
||||
require'nvim-treesitter.install'.ensure_installed(data)
|
||||
elseif M.is_module(mod) then
|
||||
if type(data.enable) == 'boolean' then
|
||||
mod.enable = data.enable
|
||||
end
|
||||
if type(data.disable) == 'table' then
|
||||
mod.disable = data.disable
|
||||
end
|
||||
if mod.keymaps and type(data.keymaps) == 'table' then
|
||||
for f, map in pairs(data.keymaps) do
|
||||
if mod.keymaps[f] then
|
||||
mod.keymaps[f] = map
|
||||
end
|
||||
end
|
||||
elseif mod == 'ensure_installed' then
|
||||
config.ensure_installed = data
|
||||
require'nvim-treesitter.install'.ensure_installed(data)
|
||||
end
|
||||
elseif type(data) == 'table' and type(mod) == 'table' then
|
||||
for key, value in pairs(data) do
|
||||
M.setup_module(mod[key], value, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_parser_configs()
|
||||
return parsers
|
||||
end
|
||||
|
||||
function M.available_parsers()
|
||||
return vim.tbl_keys(parsers)
|
||||
end
|
||||
|
||||
function M.available_modules()
|
||||
return vim.tbl_keys(config.modules)
|
||||
local modules = {}
|
||||
|
||||
recurse_modules(function(_, _, path)
|
||||
table.insert(modules, path)
|
||||
end)
|
||||
|
||||
return modules
|
||||
end
|
||||
|
||||
function M.get_module(mod)
|
||||
return config.modules[mod]
|
||||
-- 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 'is_supported' function.
|
||||
-- @param mod the module table
|
||||
function M.is_module(mod)
|
||||
return type(mod) == 'table' and type(mod.is_supported) == 'function'
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
local api = vim.api
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local M = {}
|
||||
|
|
@ -21,7 +20,7 @@ function M.get_fold_indic(lnum)
|
|||
|
||||
local parser = parsers.get_parser()
|
||||
|
||||
local multiline_here, level = smallest_multiline_containing(parser:parse():root(), 0)
|
||||
local _, level = smallest_multiline_containing(parser:parse():root(), 0)
|
||||
|
||||
return tostring(level)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,13 +2,10 @@ local api = vim.api
|
|||
local fn = vim.fn
|
||||
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local locals = require'nvim-treesitter.locals'
|
||||
local highlight = require'nvim-treesitter.highlight'
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local health_start = vim.fn["health#report_start"]
|
||||
local health_ok = vim.fn['health#report_ok']
|
||||
local health_info = vim.fn['health#report_info']
|
||||
local health_warn = vim.fn['health#report_warn']
|
||||
local health_error = vim.fn['health#report_error']
|
||||
|
||||
|
|
@ -62,7 +59,7 @@ function M.checkhealth()
|
|||
|
||||
local missing_parsers = {}
|
||||
-- Parser installation checks
|
||||
for _, parser_name in pairs(configs.available_parsers()) do
|
||||
for _, parser_name in pairs(parsers.available_parsers()) do
|
||||
local installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false)
|
||||
|
||||
-- Only print informations about installed parsers
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ local api = vim.api
|
|||
local ts = vim.treesitter
|
||||
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local M = {
|
||||
highlighters = {}
|
||||
|
|
@ -10,53 +11,54 @@ local M = {
|
|||
local hlmap = vim.treesitter.TSHighlighter.hl_map
|
||||
|
||||
-- Misc
|
||||
hlmap.error = "Error"
|
||||
hlmap["punctuation.delimiter"] = "Delimiter"
|
||||
hlmap["punctuation.bracket"] = "Delimiter"
|
||||
hlmap.error = "TSError"
|
||||
hlmap["punctuation.delimiter"] = "TSPunctDelimiter"
|
||||
hlmap["punctuation.bracket"] = "TSPunctBracket"
|
||||
hlmap["punctuation.special"] = "TSPunctSpecial"
|
||||
|
||||
-- Constants
|
||||
hlmap["constant"] = "Constant"
|
||||
hlmap["constant.builtin"] = "Special"
|
||||
hlmap["constant.macro"] = "Define"
|
||||
hlmap["string"] = "String"
|
||||
hlmap["string.regex"] = "String"
|
||||
hlmap["string.escape"] = "SpecialChar"
|
||||
hlmap["character"] = "Character"
|
||||
hlmap["number"] = "Number"
|
||||
hlmap["boolean"] = "Boolean"
|
||||
hlmap["float"] = "Float"
|
||||
hlmap["constant"] = "TSConstant"
|
||||
hlmap["constant.builtin"] = "TSConstBuiltin"
|
||||
hlmap["constant.macro"] = "TSConstMacro"
|
||||
hlmap["string"] = "TSString"
|
||||
hlmap["string.regex"] = "TSStringRegex"
|
||||
hlmap["string.escape"] = "TSStringEscape"
|
||||
hlmap["character"] = "TSCharacter"
|
||||
hlmap["number"] = "TSNumber"
|
||||
hlmap["boolean"] = "TSBoolean"
|
||||
hlmap["float"] = "TSFloat"
|
||||
|
||||
-- Functions
|
||||
hlmap["function"] = "Function"
|
||||
hlmap["function.builtin"] = "Special"
|
||||
hlmap["function.macro"] = "Macro"
|
||||
hlmap["parameter"] = "Identifier"
|
||||
hlmap["method"] = "Function"
|
||||
hlmap["field"] = "Identifier"
|
||||
hlmap["property"] = "Identifier"
|
||||
hlmap["constructor"] = "Constant"
|
||||
hlmap["function"] = "TSFunction"
|
||||
hlmap["function.builtin"] = "TSFuncBuiltin"
|
||||
hlmap["function.macro"] = "TSFuncMacro"
|
||||
hlmap["parameter"] = "TSIdentifier"
|
||||
hlmap["method"] = "TSMethod"
|
||||
hlmap["field"] = "TSField"
|
||||
hlmap["property"] = "TSProperty"
|
||||
hlmap["constructor"] = "TSConstructor"
|
||||
|
||||
-- Keywords
|
||||
hlmap["conditional"] = "Conditional"
|
||||
hlmap["repeat"] = "Repeat"
|
||||
hlmap["label"] = "Label"
|
||||
hlmap["operator"] = "Operator"
|
||||
hlmap["keyword"] = "Keyword"
|
||||
hlmap["exception"] = "Exception"
|
||||
hlmap["conditional"] = "TSConditional"
|
||||
hlmap["repeat"] = "TSRepeat"
|
||||
hlmap["label"] = "TSLabel"
|
||||
hlmap["operator"] = "TSOperator"
|
||||
hlmap["keyword"] = "TSKeyword"
|
||||
hlmap["exception"] = "TSException"
|
||||
|
||||
hlmap["type"] = "Type"
|
||||
hlmap["type.builtin"] = "Type"
|
||||
hlmap["structure"] = "Structure"
|
||||
hlmap["include"] = "Include"
|
||||
hlmap["type"] = "TSType"
|
||||
hlmap["type.builtin"] = "TSTypeBuiltin"
|
||||
hlmap["structure"] = "TSStructure"
|
||||
hlmap["include"] = "TSInclude"
|
||||
|
||||
function M.attach(bufnr, ft)
|
||||
local buf = bufnr or api.nvim_get_current_buf()
|
||||
local ft = ft or api.nvim_buf_get_option(buf, 'ft')
|
||||
function M.attach(bufnr, lang)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local lang = lang or parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, 'ft'))
|
||||
|
||||
local query = queries.get_query(ft, "highlights")
|
||||
local query = queries.get_query(lang, "highlights")
|
||||
if not query then return end
|
||||
|
||||
M.highlighters[buf] = ts.TSHighlighter.new(query, buf, ft)
|
||||
M.highlighters[bufnr] = ts.TSHighlighter.new(query, bufnr, lang)
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
local api = vim.api
|
||||
|
||||
local state = require'nvim-treesitter.state'
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local M = {}
|
||||
|
||||
local selections = {}
|
||||
|
||||
local function update_selection(buf, node)
|
||||
local start_row, start_col, end_row, end_col = node:range()
|
||||
|
||||
|
|
@ -18,32 +20,49 @@ local function update_selection(buf, node)
|
|||
vim.fn.setpos(".", { buf, end_row+1, end_col+1, 0 })
|
||||
end
|
||||
|
||||
function M.init_selection()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local node = ts_utils.get_node_at_cursor()
|
||||
selections[buf] = { [1] = node }
|
||||
update_selection(buf, node)
|
||||
end
|
||||
|
||||
local function visual_selection_range()
|
||||
local _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
|
||||
local _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))
|
||||
if csrow < cerow then
|
||||
return csrow-1, cscol-1, cerow-1, cecol-1
|
||||
else
|
||||
return cerow-1, cecol-1, csrow-1, cscol-1
|
||||
end
|
||||
end
|
||||
|
||||
local function range_matches(node)
|
||||
local csrow, cscol, cerow, cecol = visual_selection_range()
|
||||
local srow, scol, erow, ecol = 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 buf_state = state.get_buf_state(buf)
|
||||
local nodes = selections[buf]
|
||||
|
||||
local node
|
||||
-- initialize incremental selection with current range
|
||||
if #buf_state.selection.nodes == 0 then
|
||||
local cur_range = buf_state.selection.range
|
||||
if not cur_range then
|
||||
local _, cursor_row, cursor_col, _ = unpack(vim.fn.getpos("."))
|
||||
cur_range = { cursor_row, cursor_col, cursor_row, cursor_col + 1 }
|
||||
end
|
||||
|
||||
local root = buf_state.parser.tree:root()
|
||||
if not root then return end
|
||||
|
||||
node = root:named_descendant_for_range(cur_range[1]-1, cur_range[2]-1, cur_range[3]-1, cur_range[4]-1)
|
||||
else
|
||||
node = get_parent(buf_state.selection.nodes[#buf_state.selection.nodes])
|
||||
-- initialize incremental selection with current selection
|
||||
if not nodes or #nodes == 0 or not range_matches(nodes[#nodes]) then
|
||||
local csrow, cscol, cerow, cecol = visual_selection_range()
|
||||
local root = parsers.get_parser().tree:root()
|
||||
local node = root:named_descendant_for_range(csrow, cscol, cerow, cecol)
|
||||
update_selection(buf, node)
|
||||
selections[buf] = { [1] = node }
|
||||
return
|
||||
end
|
||||
|
||||
local node = get_parent(nodes[#nodes])
|
||||
if not node then return end
|
||||
|
||||
if node ~= buf_state.selection.nodes[#buf_state.selection.nodes] then
|
||||
state.insert_selection_node(buf, node)
|
||||
if node ~= nodes[#nodes] then
|
||||
table.insert(nodes, node)
|
||||
end
|
||||
|
||||
update_selection(buf, node)
|
||||
|
|
@ -60,13 +79,10 @@ end)
|
|||
|
||||
function M.node_decremental()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local buf_state = state.get_buf_state(buf)
|
||||
|
||||
local nodes = buf_state.selection.nodes
|
||||
if #nodes < 2 then return end
|
||||
|
||||
state.pop_selection_node(buf)
|
||||
local nodes = selections[buf]
|
||||
if not nodes or #nodes < 2 then return end
|
||||
|
||||
table.remove(selections[buf])
|
||||
local node = nodes[#nodes]
|
||||
update_selection(buf, node)
|
||||
end
|
||||
|
|
@ -76,14 +92,14 @@ 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
|
||||
local cmd = ":lua require'nvim-treesitter.incremental_selection'.node_incremental()<CR>"
|
||||
api.nvim_buf_set_keymap(buf, 'n', mapping, cmd, { silent = true })
|
||||
mode = 'n'
|
||||
else
|
||||
local cmd = string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname)
|
||||
api.nvim_buf_set_keymap(buf, 'v', mapping, cmd, { silent = true })
|
||||
mode = 'v'
|
||||
end
|
||||
local cmd = string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname)
|
||||
api.nvim_buf_set_keymap(buf, mode, mapping, cmd, { silent = true })
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
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(configs.available_parsers()) do
|
||||
for _, ft in pairs(parsers.available_parsers()) do
|
||||
if #ft > max_len then max_len = #ft end
|
||||
end
|
||||
|
||||
for _, ft in pairs(configs.available_parsers()) do
|
||||
for _, ft in pairs(parsers.available_parsers()) 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
|
||||
|
|
@ -20,14 +21,14 @@ local function install_info()
|
|||
end
|
||||
end
|
||||
|
||||
local function print_info_module(sorted_filetypes, mod)
|
||||
local max_str_len = #sorted_filetypes[1]
|
||||
local function print_info_module(sorted_languages, mod)
|
||||
local max_str_len = #sorted_languages[1]
|
||||
local header = string.format('%s%s', string.rep(' ', max_str_len + 2), mod)
|
||||
api.nvim_out_write(header..'\n')
|
||||
for _, ft in pairs(sorted_filetypes) do
|
||||
local padding = string.rep(' ', max_str_len - #ft + #mod / 2 + 1)
|
||||
api.nvim_out_write(ft..":"..padding)
|
||||
if configs.is_enabled(mod, ft) then
|
||||
for _, lang in pairs(sorted_languages) do
|
||||
local padding = string.rep(' ', max_str_len - #lang + #mod / 2 + 1)
|
||||
api.nvim_out_write(lang..":"..padding)
|
||||
if configs.is_enabled(mod, lang) then
|
||||
api.nvim_out_write('✓')
|
||||
else
|
||||
api.nvim_out_write('✗')
|
||||
|
|
@ -36,23 +37,23 @@ local function print_info_module(sorted_filetypes, mod)
|
|||
end
|
||||
end
|
||||
|
||||
local function print_info_modules(sorted_filetypes)
|
||||
local max_str_len = #sorted_filetypes[1]
|
||||
local function print_info_modules(sorted_languages)
|
||||
local max_str_len = #sorted_languages[1]
|
||||
local header = string.rep(' ', max_str_len + 2)
|
||||
for _, mod in pairs(configs.available_modules()) do
|
||||
header = string.format('%s%s ', header, mod)
|
||||
end
|
||||
api.nvim_out_write(header..'\n')
|
||||
|
||||
for _, ft in pairs(sorted_filetypes) do
|
||||
local padding = string.rep(' ', max_str_len - #ft)
|
||||
api.nvim_out_write(ft..":"..padding)
|
||||
for _, lang in pairs(sorted_languages) do
|
||||
local padding = string.rep(' ', max_str_len - #lang)
|
||||
api.nvim_out_write(lang..":"..padding)
|
||||
|
||||
for _, mod in pairs(configs.available_modules()) do
|
||||
local pad_len = #mod / 2 + 1
|
||||
api.nvim_out_write(string.rep(' ', pad_len))
|
||||
|
||||
if configs.is_enabled(mod, ft) then
|
||||
if configs.is_enabled(mod, lang) then
|
||||
api.nvim_out_write('✓')
|
||||
else
|
||||
api.nvim_out_write('✗')
|
||||
|
|
@ -64,14 +65,14 @@ local function print_info_modules(sorted_filetypes)
|
|||
end
|
||||
|
||||
local function module_info(mod)
|
||||
if mod and not configs.get_config()[mod] then return end
|
||||
if mod and not configs.get_module(mod) then return end
|
||||
|
||||
local ft_by_len = configs.available_parsers()
|
||||
table.sort(ft_by_len, function(a, b) return #a > #b end)
|
||||
local parserlist = parsers.available_parsers()
|
||||
table.sort(parserlist, function(a, b) return #a > #b end)
|
||||
if mod then
|
||||
print_info_module(ft_by_len, mod)
|
||||
print_info_module(parserlist, mod)
|
||||
else
|
||||
print_info_modules(ft_by_len)
|
||||
print_info_modules(parserlist)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -80,16 +81,14 @@ M.commands = {
|
|||
run = install_info,
|
||||
args = {
|
||||
"-nargs=0",
|
||||
},
|
||||
description = '`:TSInstallInfo` print installation state for every filetype'
|
||||
}
|
||||
},
|
||||
TSModuleInfo = {
|
||||
run = module_info,
|
||||
args = {
|
||||
"-nargs=?",
|
||||
"-complete=custom,v:lua.ts_available_modules"
|
||||
},
|
||||
description = '`:TSModuleInfo` print module state for every filetype, if module is specified, only for current module'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ local api = vim.api
|
|||
local fn = vim.fn
|
||||
local luv = vim.loop
|
||||
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local M = {}
|
||||
|
||||
local function iter_cmd(cmd_list, i, ft)
|
||||
if i == #cmd_list + 1 then return print('Treesitter parser for '..ft..' has been installed') end
|
||||
local function iter_cmd(cmd_list, i, lang)
|
||||
if i == #cmd_list + 1 then return print('Treesitter parser for '..lang..' has been installed') end
|
||||
|
||||
local attr = cmd_list[i]
|
||||
if attr.info then print(attr.info) end
|
||||
|
|
@ -18,22 +18,57 @@ local function iter_cmd(cmd_list, i, ft)
|
|||
handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code)
|
||||
handle:close()
|
||||
if code ~= 0 then return api.nvim_err_writeln(attr.err) end
|
||||
iter_cmd(cmd_list, i + 1, ft)
|
||||
iter_cmd(cmd_list, i + 1, lang)
|
||||
end))
|
||||
end
|
||||
|
||||
local function run_install(cache_folder, package_path, ft, repo)
|
||||
local project_name = 'tree-sitter-'..ft
|
||||
local function get_command(cmd)
|
||||
local ret = ''
|
||||
if cmd.opts and cmd.opts.cwd then
|
||||
ret = string.format('cd %s;\n', cmd.opts.cwd)
|
||||
end
|
||||
|
||||
ret = string.format('%s%s ', ret, cmd.cmd)
|
||||
|
||||
local options = ""
|
||||
if cmd.opts and cmd.opts.args then
|
||||
for _, opt in ipairs(cmd.opts.args) do
|
||||
options = string.format("%s %s", options, opt)
|
||||
end
|
||||
end
|
||||
|
||||
return string.format('%s%s', ret, options)
|
||||
end
|
||||
|
||||
local function iter_cmd_sync(cmd_list)
|
||||
for _, cmd in ipairs(cmd_list) do
|
||||
if cmd.info then
|
||||
print(cmd.info)
|
||||
end
|
||||
|
||||
vim.fn.system(get_command(cmd))
|
||||
if vim.v.shell_error ~= 0 then
|
||||
api.nvim_err_writeln(cmd.err)
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function run_install(cache_folder, package_path, lang, repo, with_sync)
|
||||
local project_name = 'tree-sitter-'..lang
|
||||
local project_repo = cache_folder..'/'..project_name
|
||||
-- compile_location only needed for typescript installs.
|
||||
local compile_location = cache_folder..'/'..(repo.location or project_name)
|
||||
local parser_lib_name = package_path.."/parser/"..ft..".so"
|
||||
local parser_lib_name = package_path.."/parser/"..lang..".so"
|
||||
local command_list = {
|
||||
{
|
||||
cmd = 'rm',
|
||||
opts = {
|
||||
args = { '-rf', project_repo },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
cmd = 'git',
|
||||
|
|
@ -76,73 +111,87 @@ local function run_install(cache_folder, package_path, ft, repo)
|
|||
}
|
||||
}
|
||||
|
||||
iter_cmd(command_list, 1, ft)
|
||||
if with_sync then
|
||||
if iter_cmd_sync(command_list, lang) == true then
|
||||
print('Treesitter parser for '..lang..' has been installed')
|
||||
end
|
||||
else
|
||||
iter_cmd(command_list, 1, lang)
|
||||
end
|
||||
end
|
||||
|
||||
local function install_lang(lang, ask_reinstall, cache_folder, package_path, with_sync)
|
||||
if #api.nvim_get_runtime_file('parser/'..lang..'.so', false) > 0 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 ') -- mandatory to avoid messing up command line
|
||||
if not string.match(yesno, '^y.*') then return end
|
||||
end
|
||||
|
||||
local parser_config = parsers.get_parser_configs()[lang]
|
||||
if not parser_config then
|
||||
return api.nvim_err_writeln('Parser not available for language '..lang)
|
||||
end
|
||||
|
||||
local install_info = parser_config.install_info
|
||||
vim.validate {
|
||||
url={ install_info.url, 'string' },
|
||||
files={ install_info.files, 'table' }
|
||||
}
|
||||
|
||||
run_install(cache_folder, package_path, lang, install_info, with_sync)
|
||||
end
|
||||
|
||||
-- TODO(kyazdani): this should work on windows too
|
||||
local function install(...)
|
||||
if fn.has('win32') == 1 then
|
||||
return api.nvim_err_writeln('This command is not available on windows at the moment.')
|
||||
end
|
||||
|
||||
if fn.executable('git') == 0 then
|
||||
return api.nvim_err_writeln('Git is required on your system to run this command')
|
||||
end
|
||||
|
||||
local package_path, err = utils.get_package_path()
|
||||
if err then return api.nvim_err_writeln(err) end
|
||||
|
||||
local cache_folder, err = utils.get_cache_dir()
|
||||
if err then return api.nvim_err_writeln(err) end
|
||||
|
||||
for _, ft in ipairs({ ... }) do
|
||||
if #api.nvim_get_runtime_file('parser/'..ft..'.so', false) > 0 then
|
||||
local yesno = fn.input(ft .. ' parser already available: would you like to reinstall ? y/n: ')
|
||||
print('\n ') -- mandatory to avoid messing up command line
|
||||
if not string.match(yesno, '^y.*') then return end
|
||||
local function install(with_sync, ask_reinstall)
|
||||
return function (...)
|
||||
if fn.has('win32') == 1 then
|
||||
return api.nvim_err_writeln('This command is not available on windows at the moment.')
|
||||
end
|
||||
|
||||
local parser_config = configs.get_parser_configs()[ft]
|
||||
if not parser_config then
|
||||
return api.nvim_err_writeln('Parser not available for language '..ft)
|
||||
if fn.executable('git') == 0 then
|
||||
return api.nvim_err_writeln('Git is required on your system to run this command')
|
||||
end
|
||||
|
||||
local install_info = parser_config.install_info
|
||||
vim.validate {
|
||||
url={ install_info.url, 'string' },
|
||||
files={ install_info.files, 'table' }
|
||||
}
|
||||
local package_path, err = utils.get_package_path()
|
||||
if err then return api.nvim_err_writeln(err) end
|
||||
|
||||
run_install(cache_folder, package_path, ft, install_info)
|
||||
end
|
||||
end
|
||||
local cache_folder, err = utils.get_cache_dir()
|
||||
if err then return api.nvim_err_writeln(err) end
|
||||
|
||||
|
||||
M.ensure_installed = function(languages)
|
||||
if type(languages) == 'string' then
|
||||
if languages == 'all' then
|
||||
languages = configs.available_parsers()
|
||||
local languages
|
||||
local ask
|
||||
if ... == 'all' then
|
||||
languages = parsers.available_parsers()
|
||||
ask = false
|
||||
else
|
||||
languages = {languages}
|
||||
languages = vim.tbl_flatten({...})
|
||||
ask = ask_reinstall
|
||||
end
|
||||
end
|
||||
|
||||
for _, ft in ipairs(languages) do
|
||||
if not utils.has_parser(ft) then
|
||||
install(ft)
|
||||
for _, lang in ipairs(languages) do
|
||||
install_lang(lang, ask, cache_folder, package_path, with_sync)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
M.ensure_installed = install(false, false)
|
||||
|
||||
M.commands = {
|
||||
TSInstall = {
|
||||
run = install,
|
||||
run = install(false, true),
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,v:lua.ts_installable_parsers"
|
||||
},
|
||||
description = '`:TSInstall {ft}` installs a parser under nvim-treesitter/parser/{name}.so'
|
||||
}
|
||||
},
|
||||
TSInstallSync = {
|
||||
run = install(true, true),
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-complete=custom,v:lua.ts_installable_parsers"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,23 +2,36 @@
|
|||
-- Locals are a generalization of definition and scopes
|
||||
-- its the way nvim-treesitter uses to "understand" the code
|
||||
local api = vim.api
|
||||
local ts = vim.treesitter
|
||||
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
|
||||
local M = {
|
||||
locals = {}
|
||||
local default_dict = {
|
||||
__index = function(table, key)
|
||||
local exists = rawget(table, key)
|
||||
if not exists then
|
||||
table[key] = {}
|
||||
end
|
||||
return rawget(table, key)
|
||||
end
|
||||
}
|
||||
|
||||
function M.collect_locals(bufnr)
|
||||
local ft = api.nvim_buf_get_option(bufnr, "ft")
|
||||
if not ft then return end
|
||||
local query_cache = {}
|
||||
setmetatable(query_cache, default_dict)
|
||||
|
||||
local query = queries.get_query(ft, 'locals')
|
||||
local M = {}
|
||||
|
||||
function M.collect_locals(bufnr, query_kind)
|
||||
query_kind = query_kind or 'locals'
|
||||
|
||||
local lang = parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, "ft"))
|
||||
if not lang then return end
|
||||
|
||||
local query = queries.get_query(lang, query_kind)
|
||||
if not query then return end
|
||||
|
||||
local parser = utils.get_parser(bufnr, ft)
|
||||
local parser = parsers.get_parser(bufnr, lang)
|
||||
if not parser then return end
|
||||
|
||||
local root = parser:parse():root()
|
||||
|
|
@ -33,18 +46,20 @@ function M.collect_locals(bufnr)
|
|||
return locals
|
||||
end
|
||||
|
||||
local function update_cached_locals(bufnr, changed_tick)
|
||||
M.locals[bufnr] = {tick=changed_tick, cache=( M.collect_locals(bufnr) or {} )}
|
||||
local function update_cached_locals(bufnr, changed_tick, query_kind)
|
||||
query_cache[query_kind][bufnr] = {tick=changed_tick, cache=( M.collect_locals(bufnr, query_kind) or {} )}
|
||||
end
|
||||
|
||||
function M.get_locals(bufnr)
|
||||
function M.get_locals(bufnr, query_kind)
|
||||
query_kind = query_kind or 'locals'
|
||||
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local cached_local = M.locals[bufnr]
|
||||
if not cached_local or api.nvim_buf_get_changedtick(bufnr) < cached_local.tick then
|
||||
update_cached_locals(bufnr,api.nvim_buf_get_changedtick(bufnr))
|
||||
local cached_local = query_cache[query_kind][bufnr]
|
||||
if not cached_local or api.nvim_buf_get_changedtick(bufnr) > cached_local.tick then
|
||||
update_cached_locals(bufnr,api.nvim_buf_get_changedtick(bufnr), query_kind)
|
||||
end
|
||||
|
||||
return M.locals[bufnr].cache
|
||||
return query_cache[query_kind][bufnr].cache
|
||||
end
|
||||
|
||||
function M.get_definitions(bufnr)
|
||||
|
|
@ -89,4 +104,27 @@ function M.get_references(bufnr)
|
|||
return refs
|
||||
end
|
||||
|
||||
--- Return all nodes in locals corresponding to a specific capture (like @scope, @reference)
|
||||
-- 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
|
||||
function M.get_capture_matches(bufnr, capture_string, query_kind)
|
||||
if not string.sub(capture_string, 1,2) == '@' then
|
||||
print('capture_string must start with "@"')
|
||||
return
|
||||
end
|
||||
|
||||
--remove leading "@"
|
||||
capture_string = string.sub(capture_string, 2)
|
||||
|
||||
local matches = {}
|
||||
for _, match in pairs(M.get_locals(bufnr, query_kind)) do
|
||||
local insert = utils.get_at_path(match, capture_string..'.node')
|
||||
|
||||
if insert then
|
||||
table.insert(matches, insert)
|
||||
end
|
||||
end
|
||||
return matches
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -1,18 +1,270 @@
|
|||
local api = vim.api
|
||||
local ts = vim.treesitter
|
||||
|
||||
local M = {}
|
||||
local list = {}
|
||||
|
||||
list.javascript = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.c = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-c",
|
||||
files = { "src/parser.c" }
|
||||
}
|
||||
}
|
||||
|
||||
list.cpp = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-cpp",
|
||||
files = { "src/parser.c", "src/scanner.cc" }
|
||||
}
|
||||
}
|
||||
|
||||
list.rust = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.lua = {
|
||||
install_info = {
|
||||
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
||||
files = { "src/parser.c", "src/scanner.cc" }
|
||||
}
|
||||
}
|
||||
|
||||
list.python = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-python",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.go = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-go",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.ruby = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.bash = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-bash",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
used_by = { "zsh" },
|
||||
filetype = 'sh'
|
||||
}
|
||||
|
||||
list.php = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-php",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.java = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-java",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.html = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-html",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.julia = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.json = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-json",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.css = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-css",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.ocaml = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.swift = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
||||
files = { "src/parser.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.c_sharp = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
filetype = 'cs'
|
||||
}
|
||||
|
||||
list.typescript = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
location = "tree-sitter-typescript/typescript"
|
||||
}
|
||||
}
|
||||
|
||||
list.tsx = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
location = "tree-sitter-tsx/tsx"
|
||||
},
|
||||
filetype = 'typescriptreact'
|
||||
}
|
||||
|
||||
list.scala = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-scala",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.haskell = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-haskell",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.markdown = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-markdown",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.toml = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-toml",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
list.vue = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-vue",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.elm = {
|
||||
install_info = {
|
||||
url = "https://github.com//razzeee/tree-sitter-elm",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.yaml = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-yaml",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.nix = {
|
||||
install_info = {
|
||||
url = "https://github.com/cstrahan/tree-sitter-nix",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
list.regex = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-regex",
|
||||
files = { "src/parser.c" }
|
||||
}
|
||||
}
|
||||
|
||||
local M = {
|
||||
list = list
|
||||
}
|
||||
|
||||
local ft_to_parsername = {}
|
||||
|
||||
for name, obj in pairs(M.list) do
|
||||
if type(obj.used_by) == 'table' then
|
||||
for _, ft in pairs(obj.used_by) do
|
||||
ft_to_parsername[ft] = name
|
||||
end
|
||||
end
|
||||
ft_to_parsername[obj.filetype or name] = name
|
||||
end
|
||||
|
||||
function M.ft_to_lang(ft)
|
||||
return ft_to_parsername[ft]
|
||||
end
|
||||
|
||||
function M.lang_to_ft(lang)
|
||||
local obj = M.list[lang]
|
||||
return vim.tbl_flatten({{obj.filetype or lang}, obj.used_by or {}})
|
||||
end
|
||||
|
||||
function M.lang_match_ft(lang, ft)
|
||||
for _, f in pairs(M.lang_to_ft(lang)) do
|
||||
if ft == f then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function M.available_parsers()
|
||||
return vim.tbl_keys(M.list)
|
||||
end
|
||||
|
||||
function M.get_parser_configs()
|
||||
return M.list
|
||||
end
|
||||
|
||||
function M.has_parser(lang)
|
||||
local lang = lang or api.nvim_buf_get_option(0, 'filetype')
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local lang = lang or M.ft_to_lang(api.nvim_buf_get_option(buf, 'ft'))
|
||||
if not lang or #lang == 0 then return false end
|
||||
return #api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0
|
||||
end
|
||||
|
||||
function M.get_parser(bufnr, lang)
|
||||
local buf = bufnr or api.nvim_get_current_buf()
|
||||
local lang = lang or M.ft_to_lang(api.nvim_buf_get_option(buf, 'ft'))
|
||||
|
||||
if M.has_parser(lang) then
|
||||
local buf = bufnr or api.nvim_get_current_buf()
|
||||
local lang = lang or api.nvim_buf_get_option(buf, 'ft')
|
||||
if not M[buf] then
|
||||
M[buf] = {}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,14 +3,71 @@ local ts = vim.treesitter
|
|||
|
||||
local M = {}
|
||||
|
||||
local function read_query_file(fname)
|
||||
return table.concat(vim.fn.readfile(fname), '\n')
|
||||
local function read_query_files(filenames)
|
||||
local contents = {}
|
||||
|
||||
for _,filename in ipairs(filenames) do
|
||||
vim.list_extend(contents, vim.fn.readfile(filename))
|
||||
end
|
||||
|
||||
return table.concat(contents, '\n')
|
||||
end
|
||||
|
||||
function M.get_query(ft, query_name)
|
||||
local query_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', ft, query_name), false)
|
||||
-- Creates a function that checks whether a certain query exists
|
||||
-- for a specific language.
|
||||
local function get_query_guard(query)
|
||||
return function(lang)
|
||||
return M.get_query(lang, query) ~= nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Some treesitter grammars extend others.
|
||||
-- We can use that to import the queries of the base language
|
||||
M.base_language_map = {
|
||||
cpp = {'c'},
|
||||
typescript = {'javascript'},
|
||||
tsx = {'typescript', 'javascript'},
|
||||
}
|
||||
|
||||
M.query_extensions = {
|
||||
javascript = { 'jsx' },
|
||||
tsx = {'javascript.jsx'}
|
||||
}
|
||||
|
||||
M.has_locals = get_query_guard('locals')
|
||||
M.has_highlights = get_query_guard('highlights')
|
||||
|
||||
function M.get_query(lang, query_name)
|
||||
local query_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', lang, query_name), true)
|
||||
local query_string = ''
|
||||
|
||||
if #query_files > 0 then
|
||||
return ts.parse_query(ft, read_query_file(query_files[1]))
|
||||
query_string = read_query_files(query_files) .. "\n" .. query_string
|
||||
end
|
||||
|
||||
for _, base_lang in ipairs(M.base_language_map[lang] or {}) do
|
||||
local base_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', base_lang, query_name), true)
|
||||
if base_files and #base_files > 0 then
|
||||
query_string = read_query_files(base_files) .. "\n" .. query_string
|
||||
end
|
||||
end
|
||||
|
||||
local extensions = M.query_extensions[lang]
|
||||
for _, ext in ipairs(extensions or {}) do
|
||||
local l = lang
|
||||
local e = ext
|
||||
if e:match('%.') ~= nil then
|
||||
l = e:match('.*%.'):sub(0, -2)
|
||||
e = e:match('%..*'):sub(2, -1)
|
||||
end
|
||||
local ext_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', l, e), true)
|
||||
if ext_files and #ext_files > 0 then
|
||||
query_string = read_query_files(ext_files) .. "\n" .. query_string
|
||||
end
|
||||
end
|
||||
|
||||
if #query_string > 0 then
|
||||
return ts.parse_query(lang, query_string)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
77
lua/nvim-treesitter/refactor/highlight_definitions.lua
Normal file
77
lua/nvim-treesitter/refactor/highlight_definitions.lua
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
-- This module highlights reference usages and the corresponding
|
||||
-- definition on cursor hold.
|
||||
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local locals = require'nvim-treesitter.locals'
|
||||
local api = vim.api
|
||||
local cmd = api.nvim_command
|
||||
|
||||
local M = {}
|
||||
|
||||
local usage_namespace = api.nvim_create_namespace('nvim-treesitter-usages')
|
||||
|
||||
function M.highlight_usages(bufnr)
|
||||
M.clear_usage_highlights(bufnr)
|
||||
|
||||
local node_at_point = ts_utils.get_node_at_cursor()
|
||||
local references = locals.get_references(bufnr)
|
||||
|
||||
if not node_at_point or not vim.tbl_contains(references, node_at_point) then
|
||||
return
|
||||
end
|
||||
|
||||
local def_node, scope = ts_utils.find_definition(node_at_point, bufnr)
|
||||
local usages = ts_utils.find_usages(node_at_point, scope)
|
||||
|
||||
for _, usage_node in ipairs(usages) do
|
||||
local start_row, start_col, _, end_col = usage_node:range()
|
||||
|
||||
if usage_node ~= node_at_point then
|
||||
api.nvim_buf_add_highlight(
|
||||
bufnr,
|
||||
usage_namespace,
|
||||
'TSDefinitionUsage',
|
||||
start_row,
|
||||
start_col,
|
||||
end_col)
|
||||
end
|
||||
end
|
||||
|
||||
if def_node ~= node_at_point then
|
||||
local start_row, start_col, _, end_col = def_node:range()
|
||||
|
||||
api.nvim_buf_add_highlight(
|
||||
bufnr,
|
||||
usage_namespace,
|
||||
'TSDefinition',
|
||||
start_row,
|
||||
start_col,
|
||||
end_col)
|
||||
end
|
||||
end
|
||||
|
||||
function M.clear_usage_highlights(bufnr)
|
||||
api.nvim_buf_clear_namespace(bufnr, usage_namespace, 0, -1)
|
||||
end
|
||||
|
||||
function M.attach(bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
|
||||
cmd(string.format('augroup NvimTreesitterUsages_%d', bufnr))
|
||||
cmd 'au!'
|
||||
-- luacheck: push ignore 631
|
||||
cmd(string.format([[autocmd CursorHold <buffer=%d> lua require'nvim-treesitter.refactor.highlight_definitions'.highlight_usages(%d)]], bufnr, bufnr))
|
||||
cmd(string.format([[autocmd CursorMoved <buffer=%d> lua require'nvim-treesitter.refactor.highlight_definitions'.clear_usage_highlights(%d)]], bufnr, bufnr))
|
||||
cmd(string.format([[autocmd InsertEnter <buffer=%d> lua require'nvim-treesitter.refactor.highlight_definitions'.clear_usage_highlights(%d)]], bufnr, bufnr))
|
||||
-- luacheck: pop
|
||||
cmd 'augroup END'
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
M.clear_usage_highlights(bufnr)
|
||||
cmd(string.format('autocmd! NvimTreesitterUsages_%d CursorHold', bufnr))
|
||||
cmd(string.format('autocmd! NvimTreesitterUsages_%d CursorMoved', bufnr))
|
||||
cmd(string.format('autocmd! NvimTreesitterUsages_%d InsertEnter', bufnr))
|
||||
end
|
||||
|
||||
return M
|
||||
68
lua/nvim-treesitter/refactor/navigation.lua
Normal file
68
lua/nvim-treesitter/refactor/navigation.lua
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
-- Definition based navigation module
|
||||
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local locals = require'nvim-treesitter.locals'
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.goto_definition(bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local node_at_point = ts_utils.get_node_at_cursor()
|
||||
|
||||
if not node_at_point then return end
|
||||
|
||||
local definition, _ = ts_utils.find_definition(node_at_point, bufnr)
|
||||
local start_row, start_col, _ = definition:start()
|
||||
|
||||
api.nvim_win_set_cursor(0, { start_row + 1, start_col })
|
||||
end
|
||||
|
||||
function M.list_definitions(bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local definitions = locals.get_definitions(bufnr)
|
||||
|
||||
if #definitions < 1 then return end
|
||||
|
||||
local qf_list = {}
|
||||
|
||||
for _, def in ipairs(definitions) do
|
||||
ts_utils.recurse_local_nodes(def, function(_, node, _, match)
|
||||
local lnum, col, _ = node:start()
|
||||
|
||||
table.insert(qf_list, {
|
||||
bufnr = bufnr,
|
||||
lnum = lnum + 1,
|
||||
col = col + 1,
|
||||
text = ts_utils.get_node_text(node)[1] or "",
|
||||
kind = match and match:sub(1, 1) or ""
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
vim.fn.setqflist(qf_list, 'r')
|
||||
api.nvim_command('copen')
|
||||
end
|
||||
|
||||
function M.attach(bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
|
||||
local config = configs.get_module('refactor.navigation')
|
||||
|
||||
for fn_name, mapping in pairs(config.keymaps) do
|
||||
local cmd = string.format([[:lua require'nvim-treesitter.refactor.navigation'.%s(%d)<CR>]], fn_name, bufnr)
|
||||
|
||||
api.nvim_buf_set_keymap(bufnr, 'n', mapping, cmd, { silent = true })
|
||||
end
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
local config = configs.get_module('refactor.navigation')
|
||||
|
||||
for _, mapping in pairs(config.keymaps) do
|
||||
api.nvim_buf_del_keymap(bufnr, 'n', mapping)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
66
lua/nvim-treesitter/refactor/smart_rename.lua
Normal file
66
lua/nvim-treesitter/refactor/smart_rename.lua
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
-- Binds a keybinding to smart rename definitions and usages.
|
||||
-- Can be used directly using the `smart_rename` function.
|
||||
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.smart_rename(bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local node_at_point = ts_utils.get_node_at_cursor()
|
||||
|
||||
if not node_at_point then
|
||||
utils.print_warning("No node to rename!")
|
||||
return
|
||||
end
|
||||
|
||||
local node_text = ts_utils.get_node_text(node_at_point)[1]
|
||||
local new_name = vim.fn.input('New name: ', node_text or '')
|
||||
|
||||
-- Empty name cancels the interaction or ESC
|
||||
if not new_name or #new_name < 1 then return end
|
||||
|
||||
local definition, scope = ts_utils.find_definition(node_at_point, bufnr)
|
||||
local nodes_to_rename = ts_utils.find_usages(node_at_point, scope)
|
||||
|
||||
if not vim.tbl_contains(nodes_to_rename, node_at_point) then
|
||||
table.insert(nodes_to_rename, node_at_point)
|
||||
end
|
||||
|
||||
if not vim.tbl_contains(nodes_to_rename, definition) then
|
||||
table.insert(nodes_to_rename, definition)
|
||||
end
|
||||
|
||||
for _, node in ipairs(nodes_to_rename) do
|
||||
local start_row, start_col, _, end_col = node:range()
|
||||
local line = api.nvim_buf_get_lines(bufnr, start_row, start_row + 1, false)[1]
|
||||
|
||||
if line then
|
||||
local new_line = line:sub(1, start_col) .. new_name .. line:sub(end_col + 1, -1)
|
||||
api.nvim_buf_set_lines(bufnr, start_row, start_row + 1, false, { new_line })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.attach(bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local config = configs.get_module('refactor.smart_rename')
|
||||
|
||||
for fn_name, mapping in pairs(config.keymaps) do
|
||||
local cmd = string.format([[:lua require'nvim-treesitter.refactor.smart_rename'.%s(%d)<CR>]], fn_name, bufnr)
|
||||
api.nvim_buf_set_keymap(bufnr, 'n', mapping, cmd, { silent = true })
|
||||
end
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
local config = configs.get_module('refactor.smart_rename')
|
||||
|
||||
for _, mapping in pairs(config.keymaps) do
|
||||
api.nvim_buf_del_keymap(bufnr, 'n', mapping)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
local api = vim.api
|
||||
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
|
||||
local M = {}
|
||||
|
||||
local buffers = {}
|
||||
|
||||
local g_mode = api.nvim_get_mode().mode
|
||||
|
||||
local function get_selection_range()
|
||||
local _, vstart_row, vstart_col, _ = unpack(vim.fn.getpos("v"))
|
||||
local _, cursor_row, cursor_col, _ = unpack(vim.fn.getpos("."))
|
||||
if vstart_row < cursor_row then
|
||||
return vstart_row, vstart_col, cursor_row, cursor_col
|
||||
else
|
||||
return cursor_row, cursor_col, vstart_row, vstart_col
|
||||
end
|
||||
end
|
||||
|
||||
function M.update()
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local buf_config = buffers[bufnr]
|
||||
if not buf_config then return end
|
||||
|
||||
local mode = api.nvim_get_mode().mode
|
||||
local cursor = api.nvim_win_get_cursor(0)
|
||||
local row = cursor[1]
|
||||
local col = cursor[2]
|
||||
if row == buf_config.cursor_pos.row
|
||||
and col == buf_config.cursor_pos.col
|
||||
and mode == g_mode
|
||||
then
|
||||
return
|
||||
end
|
||||
|
||||
local root = buf_config.parser.tree:root()
|
||||
if not root then return end
|
||||
|
||||
local new_node = root:named_descendant_for_range(row - 1, col, row - 1, col)
|
||||
|
||||
if new_node ~= buf_config.current_node then
|
||||
buf_config.current_node = new_node
|
||||
end
|
||||
|
||||
-- We only want to update the range when the incremental selection has not started yet
|
||||
if mode == "v" and #buf_config.selection.nodes == 0 then
|
||||
local row_start, col_start, row_end, col_end = get_selection_range()
|
||||
buf_config.selection.range = { row_start, col_start, row_end, col_end }
|
||||
elseif mode ~= "v" then
|
||||
buf_config.selection.nodes = {}
|
||||
buf_config.selection.range = nil
|
||||
end
|
||||
|
||||
g_mode = mode
|
||||
buf_config.cursor_pos.row = row
|
||||
buf_config.cursor_pos.col = col
|
||||
end
|
||||
|
||||
function M.insert_selection_node(bufnr, range)
|
||||
local buf_config = buffers[bufnr]
|
||||
if not buf_config then return end
|
||||
|
||||
table.insert(buffers[bufnr].selection.nodes, range)
|
||||
end
|
||||
|
||||
function M.pop_selection_node(bufnr)
|
||||
local buf_config = buffers[bufnr]
|
||||
if not buf_config then return end
|
||||
|
||||
table.remove(
|
||||
buffers[bufnr].selection.nodes,
|
||||
#buffers[bufnr].selection.nodes
|
||||
)
|
||||
end
|
||||
|
||||
function M.run_update()
|
||||
local cmd = "lua require'nvim-treesitter.state'.update()"
|
||||
api.nvim_command('autocmd NvimTreesitter CursorMoved * '..cmd)
|
||||
end
|
||||
|
||||
function M.attach_to_buffer(ft)
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
||||
|
||||
if buffers[bufnr] then return end
|
||||
|
||||
local parser = utils.get_parser(bufnr, ft)
|
||||
if not parser then return end
|
||||
|
||||
buffers[bufnr] = {
|
||||
cursor_pos = {},
|
||||
current_node = nil,
|
||||
selection = {
|
||||
range = nil,
|
||||
nodes = {}
|
||||
},
|
||||
parser = parser,
|
||||
}
|
||||
|
||||
M.update()
|
||||
api.nvim_buf_attach(bufnr, false, {
|
||||
-- TODO(kyazdani): on lines should only parse the changed content
|
||||
-- TODO(kyazdani): add a timer to avoid too frequent updates
|
||||
on_lines = function(_, buf) buffers[buf].parser:parse() end,
|
||||
on_detach = function(bufnr) buffers[bufnr] = nil end,
|
||||
})
|
||||
end
|
||||
|
||||
function M.get_buf_state(bufnr)
|
||||
return buffers[bufnr]
|
||||
end
|
||||
|
||||
function M.exposed_state(bufnr)
|
||||
local buf_state = buffers[bufnr]
|
||||
return {
|
||||
cursor_pos = buf_state.cursor_pos,
|
||||
current_node = buf_state.current_node
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
local api = vim.api
|
||||
|
||||
local locals = require'nvim-treesitter.locals'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local M = {}
|
||||
|
||||
|
|
@ -14,14 +15,16 @@ function M.get_node_text(node, bufnr)
|
|||
|
||||
-- We have to remember that end_col is end-exclusive
|
||||
local start_row, start_col, end_row, end_col = node:range()
|
||||
|
||||
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)
|
||||
lines[#lines] = string.sub(lines[#lines], 1, end_col)
|
||||
return lines
|
||||
else
|
||||
local line = api.nvim_buf_get_lines(bufnr, start_row, start_row+1, true)[1]
|
||||
return { string.sub(line, start_col+1, end_col) }
|
||||
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
|
||||
|
||||
|
|
@ -205,4 +208,121 @@ function M.previous_scope(node)
|
|||
end
|
||||
end
|
||||
|
||||
function M.get_node_at_cursor(winnr)
|
||||
local cursor = api.nvim_win_get_cursor(winnr or 0)
|
||||
local root = parsers.get_parser().tree:root()
|
||||
return root:named_descendant_for_range(cursor[1]-1,cursor[2],cursor[1]-1,cursor[2])
|
||||
end
|
||||
|
||||
-- Finds the definition node and it's scope node of a node
|
||||
-- @param node starting node
|
||||
-- @param bufnr buffer
|
||||
-- @returns the definition node and the definition nodes scope node
|
||||
function M.find_definition(node, bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local node_text = M.get_node_text(node)[1]
|
||||
local current_scope = M.containing_scope(node)
|
||||
local matching_def_nodes = {}
|
||||
|
||||
-- If a scope wasn't found then use the root node
|
||||
if current_scope == node then
|
||||
current_scope = parsers.get_parser(bufnr).tree:root()
|
||||
end
|
||||
|
||||
-- Get all definitions that match the node text
|
||||
for _, def in ipairs(locals.get_definitions(bufnr)) do
|
||||
for _, def_node in ipairs(M.get_local_nodes(def)) do
|
||||
if M.get_node_text(def_node)[1] == node_text then
|
||||
table.insert(matching_def_nodes, def_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Continue up each scope until we find the scope that contains the definition
|
||||
while current_scope do
|
||||
for _, def_node in ipairs(matching_def_nodes) do
|
||||
if M.is_parent(current_scope, def_node) then
|
||||
return def_node, current_scope
|
||||
end
|
||||
end
|
||||
current_scope = M.containing_scope(current_scope:parent())
|
||||
end
|
||||
|
||||
return node, parsers.get_parser(bufnr).tree:root()
|
||||
end
|
||||
|
||||
-- Gets all nodes from a local list result.
|
||||
-- @param local_def the local list result
|
||||
-- @returns a list of nodes
|
||||
function M.get_local_nodes(local_def)
|
||||
local result = {}
|
||||
|
||||
M.recurse_local_nodes(local_def, function(_, node)
|
||||
table.insert(result, node)
|
||||
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 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
|
||||
|
||||
-- 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 = M.get_node_text(node)[1]
|
||||
|
||||
if not node_text or #node_text < 1 then return {} end
|
||||
|
||||
local scope_node = scope_node or parsers.get_parser(bufnr).tree:root()
|
||||
local references = locals.get_references(bufnr)
|
||||
local usages = {}
|
||||
|
||||
M.recurse_tree(scope_node, function(iter_node, _, next)
|
||||
if vim.tbl_contains(references, iter_node) and M.get_node_text(iter_node)[1] == node_text then
|
||||
table.insert(usages, iter_node)
|
||||
end
|
||||
next()
|
||||
end)
|
||||
|
||||
return usages
|
||||
end
|
||||
|
||||
-- Recurses all child nodes of a tree.
|
||||
-- The callback is provided the child node, parent_node, and a callback to recurse into
|
||||
-- the child node. This allows for the ability to short circuit the recursion
|
||||
-- if we found what we are looking for, we can then stop the recursion or skip a node
|
||||
-- if need be.
|
||||
-- @param tree the node root
|
||||
-- @param cb the callback for each node
|
||||
function M.recurse_tree(tree, cb)
|
||||
for _, child in ipairs(M.get_named_children(tree)) do
|
||||
cb(child, tree, function(next_node) M.recurse_tree(next_node or child, cb) end)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
local api = vim.api
|
||||
local fn = vim.fn
|
||||
local luv = vim.loop
|
||||
local ts = vim.treesitter
|
||||
|
||||
local M = {}
|
||||
|
||||
|
|
@ -45,23 +44,27 @@ function M.get_cache_dir()
|
|||
return nil, 'Invalid cache rights, $XDG_CACHE_HOME or /tmp should be read/write'
|
||||
end
|
||||
|
||||
function M.has_parser(lang)
|
||||
local lang = lang or api.nvim_buf_get_option(0, 'filetype')
|
||||
return #api.nvim_get_runtime_file('parser/' .. lang .. '.so', false) > 0
|
||||
-- Gets a property at path
|
||||
-- @param tbl the table to access
|
||||
-- @param path the '.' seperated path
|
||||
-- @returns the value at path or nil
|
||||
function M.get_at_path(tbl, path)
|
||||
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.get_parser(bufnr, lang)
|
||||
if M.has_parser() then
|
||||
local buf = bufnr or api.nvim_get_current_buf()
|
||||
local lang = lang or api.nvim_buf_get_option(buf, 'ft')
|
||||
if not M[buf] then
|
||||
M[buf] = {}
|
||||
end
|
||||
if not M[buf][lang] then
|
||||
M[buf][lang] = ts.get_parser(buf, lang)
|
||||
end
|
||||
return M[buf][lang]
|
||||
end
|
||||
-- Prints a warning message
|
||||
-- @param text the text message
|
||||
function M.print_warning(text)
|
||||
api.nvim_command(string.format([[echohl WarningMsg | echo "%s" | echohl None]], text))
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
" Last Change: 2020 avril 25
|
||||
" Last Change: 2020 Jun 29
|
||||
|
||||
if exists('g:loaded_nvim_treesitter')
|
||||
finish
|
||||
|
|
@ -11,10 +11,52 @@ let g:loaded_nvim_treesitter = 1
|
|||
|
||||
lua << EOF
|
||||
ts_installable_parsers = function()
|
||||
return table.concat(require'nvim-treesitter.configs'.available_parsers(), '\n')
|
||||
return table.concat(require'nvim-treesitter.parsers'.available_parsers(), '\n')
|
||||
end
|
||||
ts_available_modules = function()
|
||||
return table.concat(require'nvim-treesitter.configs'.available_modules(), '\n')
|
||||
end
|
||||
require'nvim-treesitter'.setup()
|
||||
EOF
|
||||
|
||||
highlight default link TSError Error
|
||||
|
||||
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 TSCharacter Character
|
||||
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 TSMethod Function
|
||||
highlight default link TSField Identifier
|
||||
highlight default link TSProperty Identifier
|
||||
highlight default link TSConstructor Special
|
||||
|
||||
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 TSException Exception
|
||||
|
||||
highlight default link TSType Type
|
||||
highlight default link TSTypeBuiltin Type
|
||||
highlight default link TSStructure Structure
|
||||
highlight default link TSInclude Include
|
||||
|
||||
highlight default link TSDefinitionUsage Visual
|
||||
highlight default link TSDefinition Search
|
||||
|
||||
|
|
|
|||
110
queries/bash/highlights.scm
Normal file
110
queries/bash/highlights.scm
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
[
|
||||
"("
|
||||
")"
|
||||
"{"
|
||||
"}"
|
||||
"["
|
||||
"]"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
";"
|
||||
";;"
|
||||
(heredoc_start)
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
">"
|
||||
"<"
|
||||
"&"
|
||||
"&&"
|
||||
"|"
|
||||
"||"
|
||||
"="
|
||||
"=="
|
||||
"!="
|
||||
] @operator
|
||||
|
||||
[
|
||||
(string)
|
||||
(raw_string)
|
||||
(heredoc_body)
|
||||
] @string
|
||||
|
||||
[
|
||||
"if"
|
||||
"then"
|
||||
"else"
|
||||
"elif"
|
||||
"fi"
|
||||
"case"
|
||||
"in"
|
||||
"esac"
|
||||
] @conditional
|
||||
|
||||
[
|
||||
"for"
|
||||
"do"
|
||||
"done"
|
||||
"while"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"declare"
|
||||
"export"
|
||||
"local"
|
||||
"readonly"
|
||||
"unset"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
(special_variable_name)
|
||||
("$" (special_variable_name))
|
||||
] @constant
|
||||
|
||||
((word) @constant
|
||||
(#match? @constant "SIG(INT|TERM|QUIT|TIN|TOU|STP|HUP)"))
|
||||
|
||||
((word) @boolean
|
||||
(#match? @boolean "true|false"))
|
||||
|
||||
((word) @number
|
||||
(#match? @number "^\d*$"))
|
||||
|
||||
(comment) @comment
|
||||
(test_operator) @string.
|
||||
|
||||
(command_substitution
|
||||
[ "$(" ")" ] @punctuation.bracket)
|
||||
|
||||
|
||||
(function_definition
|
||||
name: (word) @function)
|
||||
|
||||
(command_name (word)) @function
|
||||
|
||||
(command
|
||||
argument: [
|
||||
(word) @parameter
|
||||
((word) @number
|
||||
(#match? @number "^\d*$"))
|
||||
(concatenation (word) @parameter)
|
||||
])
|
||||
|
||||
(file_redirect
|
||||
descriptor: (file_descriptor) @operator
|
||||
destination: (word) @parameter)
|
||||
|
||||
|
||||
("$" (variable_name)) @identifier
|
||||
|
||||
(expansion
|
||||
[ "${" "}" ] @punctuation.bracket)
|
||||
|
||||
(variable_name) @identifier
|
||||
|
||||
(case_item
|
||||
value: (word) @parameter)
|
||||
|
||||
(concatenation (word) @parameter)
|
||||
|
||||
|
|
@ -1,52 +1,79 @@
|
|||
"break" @keyword
|
||||
"case" @conditional
|
||||
"const" @keyword
|
||||
"continue" @repeat
|
||||
"default" @keyword
|
||||
"do" @repeat
|
||||
"else" @conditional
|
||||
"enum" @keyword
|
||||
"extern" @keyword
|
||||
"for" @repeat
|
||||
"if" @conditional
|
||||
"inline" @keyword
|
||||
"return" @keyword
|
||||
"sizeof" @keyword
|
||||
"static" @keyword
|
||||
"struct" @keyword
|
||||
"switch" @keyword
|
||||
"typedef" @keyword
|
||||
"union" @keyword
|
||||
"volatile" @keyword
|
||||
"while" @repeat
|
||||
[
|
||||
"const"
|
||||
"default"
|
||||
"enum"
|
||||
"extern"
|
||||
"inline"
|
||||
"return"
|
||||
"sizeof"
|
||||
"static"
|
||||
"struct"
|
||||
"typedef"
|
||||
"union"
|
||||
"volatile"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"while"
|
||||
"for"
|
||||
"do"
|
||||
"continue"
|
||||
"break"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"if"
|
||||
"else"
|
||||
"case"
|
||||
"switch"
|
||||
] @conditional
|
||||
|
||||
(conditional_expression [ "?" ":" ] @conditional)
|
||||
|
||||
"#define" @constant.macro
|
||||
"#else" @keyword
|
||||
"#endif" @keyword
|
||||
"#if" @keyword
|
||||
"#ifdef" @keyword
|
||||
"#ifndef" @keyword
|
||||
"#include" @keyword
|
||||
(preproc_directive) @keyword
|
||||
[
|
||||
"#if"
|
||||
"#ifdef"
|
||||
"#ifndef"
|
||||
"#else"
|
||||
"#elif"
|
||||
"#endif"
|
||||
"#include"
|
||||
(preproc_directive)
|
||||
] @keyword
|
||||
|
||||
"--" @operator
|
||||
"-" @operator
|
||||
"-=" @operator
|
||||
"->" @operator
|
||||
"!=" @operator
|
||||
"*" @operator
|
||||
"&" @operator
|
||||
"&&" @operator
|
||||
"+" @operator
|
||||
"++" @operator
|
||||
"+=" @operator
|
||||
"<" @operator
|
||||
"==" @operator
|
||||
">" @operator
|
||||
"||" @operator
|
||||
[
|
||||
"--"
|
||||
"-"
|
||||
"->"
|
||||
"!="
|
||||
"*"
|
||||
"/"
|
||||
"&"
|
||||
"&&"
|
||||
"+"
|
||||
"++"
|
||||
"<"
|
||||
"<="
|
||||
"=="
|
||||
"="
|
||||
"~"
|
||||
">"
|
||||
">="
|
||||
"!"
|
||||
"||"
|
||||
|
||||
"." @delimiter
|
||||
";" @delimiter
|
||||
"-="
|
||||
"+="
|
||||
"*="
|
||||
"/="
|
||||
"|="
|
||||
"&="
|
||||
] @operator
|
||||
|
||||
[ "." ";" ":" "," ] @punctuation.delimiter
|
||||
|
||||
[ "(" ")" "[" "]" "{" "}"] @punctuation.bracket
|
||||
|
||||
(string_literal) @string
|
||||
(system_lib_string) @string
|
||||
|
|
@ -64,6 +91,8 @@
|
|||
declarator: (identifier) @function)
|
||||
(preproc_function_def
|
||||
name: (identifier) @function.macro)
|
||||
(preproc_arg) @function.macro
|
||||
; TODO (preproc_arg) @embedded
|
||||
|
||||
(field_identifier) @property
|
||||
(statement_identifier) @label
|
||||
|
|
@ -71,7 +100,19 @@
|
|||
(primitive_type) @type
|
||||
(sized_type_specifier) @type
|
||||
|
||||
((identifier) @type
|
||||
(#match? @type "^[A-Z]"))
|
||||
|
||||
((identifier) @constant
|
||||
(match? @constant "^[A-Z][A-Z\\d_]+$"))
|
||||
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
|
||||
|
||||
(comment) @comment
|
||||
|
||||
;; Parameters
|
||||
(parameter_list
|
||||
(parameter_declaration) @parameter)
|
||||
|
||||
(preproc_params
|
||||
(identifier)) @parameter
|
||||
|
||||
(ERROR) @error
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
(declaration
|
||||
declarator: (identifier) @definition.var)
|
||||
(enum_specifier
|
||||
name: (*) @definition.type
|
||||
name: (_) @definition.type
|
||||
(enumerator_list
|
||||
(enumerator name: (identifier) @definition.var)))
|
||||
|
||||
|
|
@ -31,8 +31,11 @@
|
|||
(identifier) @reference
|
||||
|
||||
;; Scope
|
||||
(for_statement) @scope
|
||||
(if_statement) @scope
|
||||
(while_statement) @scope
|
||||
(translation_unit) @scope
|
||||
(function_definition) @scope
|
||||
[
|
||||
(for_statement)
|
||||
(if_statement)
|
||||
(while_statement)
|
||||
(translation_unit)
|
||||
(function_definition)
|
||||
(compound_statement) ; a block in curly braces
|
||||
] @scope
|
||||
|
|
|
|||
103
queries/cpp/highlights.scm
Normal file
103
queries/cpp/highlights.scm
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
((identifier) @field
|
||||
(#match? @field "^_"))
|
||||
|
||||
((identifier) @field
|
||||
(#match? @field "^m_"))
|
||||
|
||||
((identifier) @field
|
||||
(#match? @field "_$"))
|
||||
|
||||
;(field_expression) @parameter ;; How to highlight this?
|
||||
(template_function
|
||||
name: (identifier) @function)
|
||||
|
||||
(template_method
|
||||
name: (field_identifier) @method)
|
||||
|
||||
(template_function
|
||||
name: (scoped_identifier
|
||||
name: (identifier) @function))
|
||||
|
||||
(namespace_identifier) @constant
|
||||
|
||||
((namespace_identifier) @type
|
||||
(#match? @type "^[A-Z]"))
|
||||
((namespace_identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
|
||||
|
||||
(destructor_name
|
||||
name: (_) @function)
|
||||
|
||||
(function_declarator
|
||||
declarator: (scoped_identifier
|
||||
name: (identifier) @function))
|
||||
((function_declarator
|
||||
declarator: (scoped_identifier
|
||||
name: (identifier) @constructor))
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
(call_expression
|
||||
function: (scoped_identifier
|
||||
name: (identifier) @function))
|
||||
|
||||
(call_expression
|
||||
function: (field_expression
|
||||
field: (field_identifier) @function))
|
||||
|
||||
((call_expression
|
||||
function: (scoped_identifier
|
||||
name: (identifier) @constructor))
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
((call_expression
|
||||
function: (field_expression
|
||||
field: (field_identifier) @constructor))
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
;; constructing a type in a intizializer list: Constructor (): **SuperType (1)**
|
||||
((field_initializer
|
||||
(field_identifier) @constructor
|
||||
(argument_list))
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
|
||||
; Constants
|
||||
|
||||
(this) @constant.builtin
|
||||
(nullptr) @constant
|
||||
|
||||
(true) @boolean
|
||||
(false) @boolean
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"try"
|
||||
"catch"
|
||||
"noexcept"
|
||||
"throw"
|
||||
] @exception
|
||||
|
||||
|
||||
[
|
||||
"class"
|
||||
"constexpr"
|
||||
"delete"
|
||||
"explicit"
|
||||
"final"
|
||||
"friend"
|
||||
"mutable"
|
||||
"namespace"
|
||||
"new"
|
||||
"override"
|
||||
"private"
|
||||
"protected"
|
||||
"public"
|
||||
"template"
|
||||
"typename"
|
||||
"using"
|
||||
"virtual"
|
||||
(auto)
|
||||
] @keyword
|
||||
|
||||
"::" @operator
|
||||
51
queries/cpp/locals.scm
Normal file
51
queries/cpp/locals.scm
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
;; Class / struct defintions
|
||||
(class_specifier) @scope
|
||||
(struct_specifier) @scope
|
||||
|
||||
(reference_declarator
|
||||
(identifier) @definition.var)
|
||||
|
||||
(struct_specifier
|
||||
name: (type_identifier) @definition.type)
|
||||
|
||||
(struct_specifier
|
||||
name: (scoped_type_identifier
|
||||
name: (type_identifier) @definition.type))
|
||||
|
||||
(class_specifier
|
||||
name: (type_identifier) @definition.type)
|
||||
|
||||
(class_specifier
|
||||
name: (scoped_type_identifier
|
||||
name: (type_identifier) @definition.type))
|
||||
|
||||
;; Function defintions
|
||||
(template_function
|
||||
name: (identifier) @definition.function) @scope
|
||||
|
||||
(template_method
|
||||
name: (field_identifier) @definition.method) @scope
|
||||
|
||||
(template_function
|
||||
name: (scoped_identifier
|
||||
name: (identifier) @definition.function)) @scope
|
||||
|
||||
(function_declarator
|
||||
declarator: (scoped_identifier
|
||||
name: (type_identifier) @definition.function)) @scope
|
||||
|
||||
(field_declaration
|
||||
declarator: (function_declarator
|
||||
(field_identifier) @definition.method))
|
||||
|
||||
(lambda_expression) @scope
|
||||
|
||||
;; Control structures
|
||||
(try_statement
|
||||
body: (_) @scope)
|
||||
|
||||
(catch_clause) @scope
|
||||
|
||||
(destructor_name
|
||||
name: (_) @constructor)
|
||||
|
|
@ -1,72 +1,91 @@
|
|||
"@media" @keyword
|
||||
"@import" @include
|
||||
"@charset" @keyword
|
||||
"@namespace" @keyword
|
||||
"@supports" @keyword
|
||||
"@keyframes" @keyword
|
||||
(at_keyword) @keyword
|
||||
(to) @keyword
|
||||
(from) @keyword
|
||||
(important) @keyword
|
||||
[
|
||||
"@media"
|
||||
"@import"
|
||||
"@charset"
|
||||
"@namespace"
|
||||
"@supports"
|
||||
"@keyframes"
|
||||
(at_keyword)
|
||||
(to)
|
||||
(from)
|
||||
(important)
|
||||
] @keyword
|
||||
|
||||
(comment) @comment
|
||||
|
||||
(tag_name) @type
|
||||
(nesting_selector) @type
|
||||
(universal_selector) @type
|
||||
[
|
||||
(tag_name)
|
||||
(nesting_selector)
|
||||
(universal_selector)
|
||||
] @type
|
||||
|
||||
(function_name) @function
|
||||
|
||||
"~" @operator
|
||||
">" @operator
|
||||
"+" @operator
|
||||
"-" @operator
|
||||
"*" @operator
|
||||
"/" @operator
|
||||
"=" @operator
|
||||
"^=" @operator
|
||||
"|=" @operator
|
||||
"~=" @operator
|
||||
"$=" @operator
|
||||
"*=" @operator
|
||||
[
|
||||
"~"
|
||||
">"
|
||||
"+"
|
||||
"-"
|
||||
"*"
|
||||
"/"
|
||||
"="
|
||||
"^="
|
||||
"|="
|
||||
"~="
|
||||
"$="
|
||||
"*="
|
||||
"and"
|
||||
"or"
|
||||
"not"
|
||||
"only"
|
||||
] @operator
|
||||
|
||||
"and" @operator
|
||||
"or" @operator
|
||||
"not" @operator
|
||||
"only" @operator
|
||||
|
||||
(attribute_selector (plain_value) @string)
|
||||
(pseudo_element_selector (tag_name) @property)
|
||||
(pseudo_class_selector (class_name) @property)
|
||||
|
||||
(class_name) @property
|
||||
(id_name) @property
|
||||
(namespace_name) @property
|
||||
(property_name) @property
|
||||
(feature_name) @property
|
||||
(attribute_name) @property
|
||||
[
|
||||
(class_name)
|
||||
(id_name)
|
||||
(namespace_name)
|
||||
(property_name)
|
||||
(feature_name)
|
||||
(attribute_name)
|
||||
] @property
|
||||
|
||||
|
||||
((property_name) @type
|
||||
(#match? @type "^--"))
|
||||
(#match? @type "^--"))
|
||||
((plain_value) @type
|
||||
(#match? @type "^--"))
|
||||
(#match? @type "^--"))
|
||||
|
||||
(string_value) @string
|
||||
(color_value) @string
|
||||
(identifier) @string
|
||||
[
|
||||
(string_value)
|
||||
(color_value)
|
||||
(identifier)
|
||||
(unit)
|
||||
] @string
|
||||
|
||||
(integer_value) @number
|
||||
(float_value) @number
|
||||
(unit) @string
|
||||
[
|
||||
(integer_value)
|
||||
(float_value)
|
||||
] @number
|
||||
|
||||
"#" @punctuation.delimiter
|
||||
"," @punctuation.delimiter
|
||||
"." @punctuation.delimiter
|
||||
":" @punctuation.delimiter
|
||||
"::" @punctuation.delimiter
|
||||
";" @punctuation.delimiter
|
||||
"{" @punctuation.bracket
|
||||
")" @punctuation.bracket
|
||||
"(" @punctuation.bracket
|
||||
"}" @punctuation.bracket
|
||||
[
|
||||
"#"
|
||||
","
|
||||
"."
|
||||
":"
|
||||
"::"
|
||||
";"
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"{"
|
||||
")"
|
||||
"("
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
(ERROR) @error
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@
|
|||
|
||||
"=" @operator
|
||||
|
||||
"<" @punctuation.bracket
|
||||
">" @punctuation.bracket
|
||||
"</" @punctuation.bracket
|
||||
"/>" @punctuation.bracket
|
||||
|
||||
[
|
||||
"<"
|
||||
">"
|
||||
"</"
|
||||
"/>"
|
||||
] @punctuation.bracket
|
||||
|
|
|
|||
214
queries/java/highlights.scm
Normal file
214
queries/java/highlights.scm
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
; CREDITS @maxbrunsfeld (maxbrunsfeld@gmail.com)
|
||||
|
||||
; Methods
|
||||
|
||||
|
||||
(method_declaration
|
||||
name: (identifier) @method)
|
||||
(method_invocation
|
||||
name: (identifier) @method)
|
||||
|
||||
(super) @function.builtin
|
||||
|
||||
; Parameters
|
||||
(formal_parameter
|
||||
name: (identifier) @parameter)
|
||||
|
||||
;; Lambda parameter
|
||||
(inferred_parameters (identifier) @parameter) ; (x,y) -> ...
|
||||
(lambda_expression
|
||||
parameters: (identifier) @parameter) ; x -> ...
|
||||
|
||||
|
||||
; Annotations
|
||||
|
||||
|
||||
(annotation
|
||||
name: (identifier) @attribute)
|
||||
(marker_annotation
|
||||
name: (identifier) @attribute)
|
||||
|
||||
|
||||
; Operators
|
||||
|
||||
[
|
||||
"@"
|
||||
"+"
|
||||
"?"
|
||||
":"
|
||||
"++"
|
||||
"-"
|
||||
"--"
|
||||
"&"
|
||||
"&&"
|
||||
"|"
|
||||
"||"
|
||||
"!="
|
||||
"=="
|
||||
"*"
|
||||
"/"
|
||||
"%"
|
||||
"<"
|
||||
"<="
|
||||
">"
|
||||
">="
|
||||
"="
|
||||
"-="
|
||||
"+="
|
||||
"*="
|
||||
"/="
|
||||
"%="
|
||||
"->"
|
||||
"^"
|
||||
"^="
|
||||
"&="
|
||||
"|="
|
||||
"~"
|
||||
">>"
|
||||
">>>"
|
||||
"<<"
|
||||
"::"
|
||||
] @operator
|
||||
|
||||
; Types
|
||||
|
||||
(interface_declaration
|
||||
name: (identifier) @type)
|
||||
(class_declaration
|
||||
name: (identifier) @type)
|
||||
(enum_declaration
|
||||
name: (identifier) @type)
|
||||
(constructor_declaration
|
||||
name: (identifier) @type)
|
||||
(type_identifier) @type
|
||||
|
||||
|
||||
|
||||
((field_access
|
||||
object: (identifier) @type)
|
||||
(#match? @type "^[A-Z]"))
|
||||
((scoped_identifier
|
||||
scope: (identifier) @type)
|
||||
(#match? @type "^[A-Z]"))
|
||||
|
||||
[
|
||||
(boolean_type)
|
||||
(integral_type)
|
||||
(floating_point_type)
|
||||
(void_type)
|
||||
] @type.builtin
|
||||
|
||||
; Variables
|
||||
|
||||
((identifier) @constant
|
||||
(#match? @constant "^_*[A-Z][A-Z\d_]+"))
|
||||
|
||||
|
||||
|
||||
; Literals
|
||||
|
||||
[
|
||||
(hex_integer_literal)
|
||||
(decimal_integer_literal)
|
||||
(octal_integer_literal)
|
||||
(binary_integer_literal)
|
||||
] @number
|
||||
|
||||
[
|
||||
(decimal_floating_point_literal)
|
||||
(hex_floating_point_literal)
|
||||
] @float
|
||||
|
||||
(character_literal) @character
|
||||
(string_literal) @string
|
||||
(null_literal) @constant.builtin
|
||||
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
] @boolean
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"abstract"
|
||||
"assert"
|
||||
"break"
|
||||
"catch"
|
||||
"class"
|
||||
"continue"
|
||||
"default"
|
||||
"enum"
|
||||
"exports"
|
||||
"extends"
|
||||
"final"
|
||||
"finally"
|
||||
"implements"
|
||||
"instanceof"
|
||||
"interface"
|
||||
"module"
|
||||
"native"
|
||||
"new"
|
||||
"open"
|
||||
"opens"
|
||||
"package"
|
||||
"private"
|
||||
"protected"
|
||||
"provides"
|
||||
"public"
|
||||
"requires"
|
||||
"return"
|
||||
"static"
|
||||
"strictfp"
|
||||
"synchronized"
|
||||
"throw"
|
||||
"throws"
|
||||
"to"
|
||||
"transient"
|
||||
"transitive"
|
||||
"try"
|
||||
"uses"
|
||||
"volatile"
|
||||
"with"
|
||||
] @keyword
|
||||
|
||||
; Conditionals
|
||||
|
||||
[
|
||||
"if"
|
||||
"else"
|
||||
"switch"
|
||||
"case"
|
||||
] @conditional
|
||||
|
||||
;
|
||||
|
||||
[
|
||||
"for"
|
||||
"while"
|
||||
"do"
|
||||
] @repeat
|
||||
|
||||
; Includes
|
||||
|
||||
"import" @include
|
||||
"package" @include
|
||||
|
||||
; Punctuation
|
||||
|
||||
[
|
||||
";"
|
||||
"."
|
||||
","
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
"("
|
||||
")"
|
||||
] @punctuation.bracket
|
||||
10
queries/java/locals.scm
Normal file
10
queries/java/locals.scm
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
; CREDITS @maxbrunsfeld (maxbrunsfeld@gmail.com)
|
||||
|
||||
(class_declaration
|
||||
name: (identifier) @name) @class
|
||||
|
||||
(method_declaration
|
||||
name: (identifier) @name) @method
|
||||
|
||||
(method_invocation
|
||||
name: (identifier) @name) @call
|
||||
190
queries/javascript/highlights.scm
Normal file
190
queries/javascript/highlights.scm
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
; Types
|
||||
|
||||
; Javascript
|
||||
; Special identifiers
|
||||
;--------------------
|
||||
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z_][A-Z\\d_]+$"))
|
||||
|
||||
((shorthand_property_identifier) @constant
|
||||
(#match? @constant "^[A-Z_][A-Z\\d_]+$"))
|
||||
|
||||
((identifier) @constructor
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
((identifier) @variable.builtin
|
||||
(#match? @variable.builtin "^(arguments|module|console|window|document)$"))
|
||||
|
||||
((identifier) @function.builtin
|
||||
(#eq? @function.builtin "require"))
|
||||
|
||||
; Function and method definitions
|
||||
;--------------------------------
|
||||
|
||||
(function
|
||||
name: (identifier) @function)
|
||||
(function_declaration
|
||||
name: (identifier) @function)
|
||||
(method_definition
|
||||
name: (property_identifier) @function.method)
|
||||
|
||||
(pair
|
||||
key: (property_identifier) @function.method
|
||||
value: (function))
|
||||
(pair
|
||||
key: (property_identifier) @function.method
|
||||
value: (arrow_function))
|
||||
|
||||
(assignment_expression
|
||||
left: (member_expression
|
||||
property: (property_identifier) @function.method)
|
||||
right: (arrow_function))
|
||||
(assignment_expression
|
||||
left: (member_expression
|
||||
property: (property_identifier) @function.method)
|
||||
right: (function))
|
||||
|
||||
(variable_declarator
|
||||
name: (identifier) @function
|
||||
value: (arrow_function))
|
||||
(variable_declarator
|
||||
name: (identifier) @function
|
||||
value: (function))
|
||||
|
||||
(assignment_expression
|
||||
left: (identifier) @function
|
||||
right: (arrow_function))
|
||||
(assignment_expression
|
||||
left: (identifier) @function
|
||||
right: (function))
|
||||
|
||||
; Function and method calls
|
||||
;--------------------------
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
|
||||
(call_expression
|
||||
function: (member_expression
|
||||
property: (property_identifier) @function.method))
|
||||
|
||||
; Variables
|
||||
;----------
|
||||
|
||||
(formal_parameters (identifier) @variable.parameter)
|
||||
|
||||
(identifier) @variable
|
||||
|
||||
; Properties
|
||||
;-----------
|
||||
|
||||
(property_identifier) @property
|
||||
|
||||
; Literals
|
||||
;---------
|
||||
|
||||
(this) @variable.builtin
|
||||
(super) @variable.builtin
|
||||
|
||||
(true) @boolean
|
||||
(false) @boolean
|
||||
(null) @constant.builtin
|
||||
(comment) @comment
|
||||
(string) @string
|
||||
(regex) @string.special
|
||||
(template_string) @string
|
||||
(number) @number
|
||||
|
||||
; Punctuation
|
||||
;------------
|
||||
|
||||
(template_substitution
|
||||
"${" @punctuation.special
|
||||
"}" @punctuation.special) @embedded
|
||||
|
||||
";" @punctuation.delimiter
|
||||
"." @punctuation.delimiter
|
||||
"," @punctuation.delimiter
|
||||
|
||||
"--" @operator
|
||||
"-" @operator
|
||||
"-=" @operator
|
||||
"&&" @operator
|
||||
"+" @operator
|
||||
"++" @operator
|
||||
"+=" @operator
|
||||
"<" @operator
|
||||
"<<" @operator
|
||||
"=" @operator
|
||||
"==" @operator
|
||||
"===" @operator
|
||||
"=>" @operator
|
||||
">" @operator
|
||||
">>" @operator
|
||||
"||" @operator
|
||||
"??" @operator
|
||||
|
||||
"(" @punctuation.bracket
|
||||
")" @punctuation.bracket
|
||||
"[" @punctuation.bracket
|
||||
"]" @punctuation.bracket
|
||||
"{" @punctuation.bracket
|
||||
"}" @punctuation.bracket
|
||||
|
||||
; Keywords
|
||||
;----------
|
||||
|
||||
[
|
||||
"if"
|
||||
"else"
|
||||
"switch"
|
||||
"case"
|
||||
"default"
|
||||
] @conditional
|
||||
|
||||
[
|
||||
"import"
|
||||
"from"
|
||||
"as"
|
||||
] @include
|
||||
|
||||
[
|
||||
"for"
|
||||
"of"
|
||||
"do"
|
||||
"while"
|
||||
"continue"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"async"
|
||||
"await"
|
||||
"break"
|
||||
"catch"
|
||||
"class"
|
||||
"const"
|
||||
"debugger"
|
||||
"delete"
|
||||
"export"
|
||||
"extends"
|
||||
"finally"
|
||||
"function"
|
||||
"get"
|
||||
"in"
|
||||
"instanceof"
|
||||
"let"
|
||||
"new"
|
||||
"return"
|
||||
"set"
|
||||
"static"
|
||||
"switch"
|
||||
"target"
|
||||
"throw"
|
||||
"try"
|
||||
"typeof"
|
||||
"var"
|
||||
"void"
|
||||
"with"
|
||||
"yield"
|
||||
] @keyword
|
||||
38
queries/javascript/locals.scm
Normal file
38
queries/javascript/locals.scm
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
; Scopes
|
||||
;-------
|
||||
|
||||
(statement_block) @scope
|
||||
(function) @scope
|
||||
(arrow_function) @scope
|
||||
(function_declaration) @scope
|
||||
(method_definition) @scope
|
||||
|
||||
; Definitions
|
||||
;------------
|
||||
|
||||
(formal_parameters
|
||||
(identifier) @definition)
|
||||
|
||||
(formal_parameters
|
||||
(object_pattern
|
||||
(identifier) @definition))
|
||||
|
||||
(formal_parameters
|
||||
(object_pattern
|
||||
(shorthand_property_identifier) @definition))
|
||||
|
||||
(formal_parameters
|
||||
(array_pattern
|
||||
(identifier) @definition))
|
||||
|
||||
(variable_declarator
|
||||
name: (identifier) @definition)
|
||||
|
||||
(import_specifier
|
||||
(identifier) @definition)
|
||||
|
||||
; References
|
||||
;------------
|
||||
|
||||
(identifier) @reference
|
||||
|
||||
13
queries/json/highlights.scm
Normal file
13
queries/json/highlights.scm
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
(true) @boolean
|
||||
(false) @boolean
|
||||
(null) @constant.builtin
|
||||
(number) @number
|
||||
(pair key: (string) @label)
|
||||
(pair value: (string) @string)
|
||||
(string_content (escape_sequence) @string.escape)
|
||||
(ERROR) @error
|
||||
"," @punctuation.delimiter
|
||||
"[" @punctuation.bracket
|
||||
"]" @punctuation.bracket
|
||||
"{" @punctuation.bracket
|
||||
"}" @punctuation.bracket
|
||||
|
|
@ -2,57 +2,70 @@
|
|||
|
||||
;;; Builtins
|
||||
;; Keywords
|
||||
"local" @keyword
|
||||
"if" @conditional
|
||||
"then" @conditional
|
||||
"else" @conditional
|
||||
"elseif" @conditional
|
||||
"end" @keyword
|
||||
"return" @keyword
|
||||
"do" @repeat
|
||||
"while" @repeat
|
||||
"repeat" @repeat
|
||||
"for" @repeat
|
||||
(break_statement) @keyword
|
||||
"goto" @keyword
|
||||
|
||||
[
|
||||
"if"
|
||||
"then"
|
||||
"else"
|
||||
"elseif"
|
||||
] @conditional
|
||||
|
||||
[
|
||||
"do"
|
||||
"while"
|
||||
"repeat"
|
||||
"for"
|
||||
"in"
|
||||
] @repeat
|
||||
|
||||
[
|
||||
"local"
|
||||
"end"
|
||||
"return"
|
||||
(break_statement)
|
||||
"goto"
|
||||
] @keyword
|
||||
|
||||
;; Operators
|
||||
"~=" @operator
|
||||
"==" @operator
|
||||
"<=" @operator
|
||||
">=" @operator
|
||||
"not" @operator
|
||||
"and" @operator
|
||||
"or" @operator
|
||||
"<" @operator
|
||||
">" @operator
|
||||
[
|
||||
"~="
|
||||
"=="
|
||||
"<="
|
||||
">="
|
||||
"not"
|
||||
"and"
|
||||
"or"
|
||||
"<"
|
||||
">"
|
||||
"+"
|
||||
"-"
|
||||
"%"
|
||||
"/"
|
||||
"//"
|
||||
"*"
|
||||
"^"
|
||||
"&"
|
||||
"~"
|
||||
"|"
|
||||
">>"
|
||||
"<<"
|
||||
".."
|
||||
"#"
|
||||
] @operator
|
||||
|
||||
"+" @operator
|
||||
"-" @operator
|
||||
"%" @operator
|
||||
"/" @operator
|
||||
"//" @operator
|
||||
"*" @operator
|
||||
"^" @operator
|
||||
"&" @operator
|
||||
"~" @operator
|
||||
"|" @operator
|
||||
">>" @operator
|
||||
"<<" @operator
|
||||
".." @operator
|
||||
"#" @operator
|
||||
|
||||
;; Constants
|
||||
(false) @boolean
|
||||
(true) @boolean
|
||||
[
|
||||
(false)
|
||||
(true)
|
||||
] @boolean
|
||||
(nil) @constant.builtin
|
||||
(spread) @constant ;; "..."
|
||||
|
||||
;; Nodes
|
||||
(function "function" @function "end" @function)
|
||||
(function_definition "function" @function "end" @function)
|
||||
(local_function "function" @function "end" @function)
|
||||
(table "{" @constructor "}" @constructor)
|
||||
(_ "function" @function "end" @function) ;; Any node that has both funtion and end in it
|
||||
|
||||
(table ["{" "}"] @constructor)
|
||||
(comment) @comment
|
||||
(string) @string
|
||||
(number) @number
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
(parameters (identifier) @definition.var)))
|
||||
((function
|
||||
(parameters (identifier) @definition.var)))
|
||||
((function_definition
|
||||
(parameters (identifier) @definition.var)))
|
||||
|
||||
;; Loops
|
||||
((loop_expression
|
||||
|
|
|
|||
|
|
@ -1,33 +1,38 @@
|
|||
;; From tree-sitter-python licensed under MIT License
|
||||
; Copyright (c) 2016 Max Brunsfeld
|
||||
|
||||
; Reset highlighing in f-string interpolations
|
||||
(interpolation) @Normal
|
||||
|
||||
; Identifier naming conventions
|
||||
|
||||
|
||||
((import_from_statement
|
||||
name: (dotted_name
|
||||
(identifier)) @type)
|
||||
(match? @type "^[A-Z]"))
|
||||
|
||||
((identifier) @type
|
||||
(match? @type "^[A-Z]"))
|
||||
|
||||
((identifier) @constant
|
||||
(match? @constant "^[A-Z][A-Z_]*$"))
|
||||
(match? @constant "^[A-Z][A-Z_0-9]*$"))
|
||||
|
||||
((identifier) @constant.builtin
|
||||
(match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
|
||||
|
||||
; Function calls
|
||||
|
||||
(decorator) @function
|
||||
((decorator (dotted_name (identifier) @function))
|
||||
(match? @function "^([A-Z])@!.*$"))
|
||||
|
||||
(call
|
||||
function: (identifier) @function)
|
||||
|
||||
(call
|
||||
function: (attribute
|
||||
attribute: (identifier) @method))
|
||||
|
||||
(call
|
||||
function: (identifier) @function)
|
||||
((call
|
||||
function: (identifier) @constructor)
|
||||
(match? @constructor "^[A-Z]"))
|
||||
|
||||
((call
|
||||
(identifier) @constructor)
|
||||
function: (attribute
|
||||
attribute: (identifier) @constructor))
|
||||
(match? @constructor "^[A-Z]"))
|
||||
|
||||
;; Builtin functions
|
||||
|
|
@ -43,10 +48,9 @@
|
|||
(function_definition
|
||||
name: (identifier) @function)
|
||||
|
||||
(identifier) @variable
|
||||
(attribute attribute: (identifier) @property)
|
||||
(type (identifier) @type)
|
||||
((call
|
||||
|
||||
((call
|
||||
function: (identifier) @isinstance
|
||||
arguments: (argument_list
|
||||
(*)
|
||||
|
|
@ -55,7 +59,7 @@
|
|||
|
||||
; Normal parameters
|
||||
(parameters
|
||||
(identifier) @parameter)
|
||||
(identifier) @parameter)
|
||||
; Default parameters
|
||||
(keyword_argument
|
||||
name: (identifier) @parameter)
|
||||
|
|
@ -65,17 +69,16 @@
|
|||
; Variadic parameters *args, **kwargs
|
||||
(parameters
|
||||
(list_splat ; *args
|
||||
(identifier) @parameter))
|
||||
(identifier) @parameter))
|
||||
(parameters
|
||||
(dictionary_splat ; **kwargs
|
||||
(identifier) @parameter))
|
||||
(identifier) @parameter))
|
||||
|
||||
|
||||
; Literals
|
||||
|
||||
(none) @constant.builtin
|
||||
(true) @boolean
|
||||
(false) @boolean
|
||||
[(true) (false)] @boolean
|
||||
((identifier) @constant.builtin
|
||||
(match? @constant.builtin "self"))
|
||||
|
||||
|
|
@ -84,126 +87,104 @@
|
|||
|
||||
(comment) @comment
|
||||
(string) @string
|
||||
(escape_sequence) @escape
|
||||
(escape_sequence) @string.escape
|
||||
|
||||
; Tokens
|
||||
|
||||
[
|
||||
"-"
|
||||
"-="
|
||||
":="
|
||||
"!="
|
||||
"*"
|
||||
"**"
|
||||
"**="
|
||||
"*="
|
||||
"/"
|
||||
"//"
|
||||
"//="
|
||||
"/="
|
||||
"&"
|
||||
"%"
|
||||
"%="
|
||||
"^"
|
||||
"+"
|
||||
"+="
|
||||
"<"
|
||||
"<<"
|
||||
"<="
|
||||
"<>"
|
||||
"="
|
||||
"=="
|
||||
">"
|
||||
">="
|
||||
">>"
|
||||
"|"
|
||||
"~"
|
||||
"and"
|
||||
"in"
|
||||
"is"
|
||||
"not"
|
||||
"or"
|
||||
] @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"assert"
|
||||
"async"
|
||||
"await"
|
||||
"class"
|
||||
"def"
|
||||
"del"
|
||||
"except"
|
||||
"exec"
|
||||
"finally"
|
||||
"global"
|
||||
"lambda"
|
||||
"nonlocal"
|
||||
"pass"
|
||||
"print"
|
||||
"raise"
|
||||
"return"
|
||||
"try"
|
||||
"with"
|
||||
"yield"
|
||||
] @keyword
|
||||
|
||||
[ "as" "from" "import"] @include
|
||||
|
||||
[ "if" "elif" "else" ] @conditional
|
||||
|
||||
[ "for" "while" "break" "continue" ] @repeat
|
||||
|
||||
[ "(" ")" "[" "]" "{" "}"] @punctuation.bracket
|
||||
|
||||
(interpolation
|
||||
"{" @punctuation.special
|
||||
"}" @punctuation.special) @embedded
|
||||
|
||||
; Tokens
|
||||
[ "," "." ":" ] @punctuation.delimiter
|
||||
|
||||
"-" @operator
|
||||
"->" @operator
|
||||
"-=" @operator
|
||||
"!=" @operator
|
||||
"*" @operator
|
||||
"**" @operator
|
||||
"**=" @operator
|
||||
"*=" @operator
|
||||
"/" @operator
|
||||
"//" @operator
|
||||
"//=" @operator
|
||||
"/=" @operator
|
||||
"&" @operator
|
||||
"%" @operator
|
||||
"%=" @operator
|
||||
"^" @operator
|
||||
"+" @operator
|
||||
"+=" @operator
|
||||
"<" @operator
|
||||
"<<" @operator
|
||||
"<=" @operator
|
||||
"<>" @operator
|
||||
"=" @operator
|
||||
"==" @operator
|
||||
">" @operator
|
||||
">=" @operator
|
||||
">>" @operator
|
||||
"|" @operator
|
||||
"~" @operator
|
||||
"and" @operator
|
||||
"in" @operator
|
||||
"is" @operator
|
||||
"not" @operator
|
||||
"or" @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
"as" @include
|
||||
"assert" @keyword
|
||||
"async" @keyword
|
||||
"await" @keyword
|
||||
"break" @repeat
|
||||
"class" @keyword
|
||||
"continue" @repeat
|
||||
"def" @keyword
|
||||
"del" @keyword
|
||||
"elif" @conditional
|
||||
"else" @conditional
|
||||
"except" @keyword
|
||||
"exec" @keyword
|
||||
"finally" @keyword
|
||||
"for" @repeat
|
||||
"from" @include
|
||||
"global" @keyword
|
||||
"if" @conditional
|
||||
"import" @include
|
||||
"lambda" @keyword
|
||||
"nonlocal" @keyword
|
||||
"pass" @keyword
|
||||
"print" @keyword
|
||||
"raise" @keyword
|
||||
"return" @keyword
|
||||
"try" @keyword
|
||||
"while" @repeat
|
||||
"with" @keyword
|
||||
"yield" @keyword
|
||||
|
||||
; Additions for nvim-treesitter
|
||||
"(" @punctuation.bracket
|
||||
")" @punctuation.bracket
|
||||
"[" @punctuation.bracket
|
||||
"]" @punctuation.bracket
|
||||
|
||||
"," @punctuation.delimiter
|
||||
"." @punctuation.delimiter
|
||||
":" @punctuation.delimiter
|
||||
; Class definitions
|
||||
|
||||
(class_definition
|
||||
name: (identifier) @type)
|
||||
(class_definition
|
||||
superclasses: (argument_list
|
||||
superclasses: (argument_list
|
||||
(identifier) @type))
|
||||
|
||||
(attribute
|
||||
((attribute
|
||||
attribute: (identifier) @field)
|
||||
|
||||
((attribute
|
||||
attribute: (identifier) @constant)
|
||||
(match? @constant "^[A-Z][A-Z_]*$"))
|
||||
|
||||
((attribute
|
||||
attribute: (identifier) @type)
|
||||
(match? @type "^[A-Z][a-z_]+"))
|
||||
|
||||
((attribute
|
||||
object: (identifier) @type)
|
||||
(match? @type "^[A-Z][a-z_]+"))
|
||||
|
||||
(class_definition
|
||||
body: (block
|
||||
(expression_statement
|
||||
(assignment
|
||||
left: (expression_list
|
||||
(identifier) @field)))))
|
||||
(match? @field "^([A-Z])@!.*$"))
|
||||
|
||||
((class_definition
|
||||
body: (block
|
||||
(expression_statement
|
||||
(assignment
|
||||
left: (expression_list
|
||||
(identifier) @constant)))))
|
||||
(match? @constant "^[A-Z][A-Z_]*$"))
|
||||
(identifier) @field)))))
|
||||
(match? @field "^([A-Z])@!.*$"))
|
||||
|
||||
;; Error
|
||||
(ERROR) @error
|
||||
|
|
|
|||
|
|
@ -30,12 +30,8 @@
|
|||
|
||||
; Function defines function and scope
|
||||
(function_definition
|
||||
name: (identifier) @definition.function) @scope
|
||||
|
||||
;; Should be extended to when syntax supported
|
||||
;(function_definition
|
||||
;name: (identifier) @definition.function
|
||||
;body: (block (expression_statement (string) @definition.function.doc)?)) @scope
|
||||
name: (identifier) @definition.function
|
||||
body: (block (expression_statement (string) @definition.doc)?)) @scope
|
||||
|
||||
|
||||
(class_definition
|
||||
|
|
|
|||
|
|
@ -1,32 +1,41 @@
|
|||
; Keywords
|
||||
|
||||
"alias" @keyword
|
||||
"and" @keyword
|
||||
"begin" @keyword
|
||||
"break" @keyword
|
||||
"case" @conditional
|
||||
"class" @keyword
|
||||
"def" @keyword
|
||||
"do" @keyword
|
||||
"else" @conditional
|
||||
"elsif" @conditional
|
||||
"end" @keyword
|
||||
"ensure" @keyword
|
||||
"for" @repeat
|
||||
"if" @conditional
|
||||
"in" @keyword
|
||||
"module" @keyword
|
||||
"next" @keyword
|
||||
"or" @keyword
|
||||
"rescue" @keyword
|
||||
"retry" @keyword
|
||||
"return" @keyword
|
||||
"then" @keyword
|
||||
"unless" @conditional
|
||||
"until" @repeat
|
||||
"when" @conditional
|
||||
"while" @repeat
|
||||
"yield" @keyword
|
||||
[
|
||||
"alias"
|
||||
"and"
|
||||
"begin"
|
||||
"break"
|
||||
"class"
|
||||
"def"
|
||||
"do"
|
||||
"end"
|
||||
"ensure"
|
||||
"in"
|
||||
"module"
|
||||
"next"
|
||||
"or"
|
||||
"rescue"
|
||||
"retry"
|
||||
"return"
|
||||
"then"
|
||||
"yield"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"case"
|
||||
"else"
|
||||
"elsif"
|
||||
"if"
|
||||
"unless"
|
||||
"when"
|
||||
] @conditional
|
||||
|
||||
[
|
||||
"for"
|
||||
"until"
|
||||
"while"
|
||||
] @repeat
|
||||
|
||||
|
||||
((identifier) @keyword
|
||||
(#match? @keyword "^(private|protected|public)$"))
|
||||
|
|
@ -39,32 +48,45 @@
|
|||
"defined?" @function
|
||||
|
||||
(call
|
||||
receiver: (constant) @constant)
|
||||
[
|
||||
receiver: (constant) @constant
|
||||
method: [
|
||||
(identifier)
|
||||
(constant)
|
||||
] @function
|
||||
])
|
||||
|
||||
(method_call
|
||||
receiver: (constant) @constant)
|
||||
(call
|
||||
method: (identifier) @function)
|
||||
(method_call
|
||||
method: (identifier) @function)
|
||||
(call
|
||||
method: (constant) @function)
|
||||
(method_call
|
||||
method: (constant) @function)
|
||||
[
|
||||
receiver: (constant) @constant
|
||||
method: [
|
||||
(identifier)
|
||||
(constant)
|
||||
] @function
|
||||
])
|
||||
|
||||
; Function definitions
|
||||
|
||||
(alias (identifier) @function)
|
||||
(setter (identifier) @function)
|
||||
(method name: (identifier) @function)
|
||||
(method name: (constant) @constant)
|
||||
|
||||
(method name: [
|
||||
(identifier) @function
|
||||
(constant) @constant
|
||||
])
|
||||
|
||||
(singleton_method name: [
|
||||
(identifier) @function
|
||||
(constant) @constant
|
||||
])
|
||||
|
||||
(class name: (constant) @constant)
|
||||
(singleton_method name: (identifier) @function)
|
||||
(singleton_method name: (constant) @constant)
|
||||
|
||||
; Identifiers
|
||||
|
||||
(class_variable) @label
|
||||
(instance_variable) @label
|
||||
[
|
||||
(class_variable)
|
||||
(instance_variable)
|
||||
] @label
|
||||
|
||||
((identifier) @constant.builtin
|
||||
(#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
|
||||
|
|
@ -74,8 +96,10 @@
|
|||
|
||||
(constant) @constant
|
||||
|
||||
(self) @constant.builtin
|
||||
(super) @constant.builtin
|
||||
[
|
||||
(self)
|
||||
(super)
|
||||
] @constant.builtin
|
||||
|
||||
(method_parameters (identifier) @parameter)
|
||||
(lambda_parameters (identifier) @parameter)
|
||||
|
|
@ -93,22 +117,31 @@
|
|||
|
||||
; Literals
|
||||
|
||||
(string) @string
|
||||
(bare_string) @string
|
||||
(bare_symbol) @constant
|
||||
(subshell) @string
|
||||
(heredoc_beginning) @constant
|
||||
(heredoc_body) @string
|
||||
(heredoc_end) @constant
|
||||
(symbol) @constant
|
||||
[
|
||||
(string)
|
||||
(bare_string)
|
||||
(subshell)
|
||||
(heredoc_body)
|
||||
] @string
|
||||
|
||||
[
|
||||
(bare_symbol)
|
||||
(heredoc_beginning)
|
||||
(heredoc_end)
|
||||
(symbol)
|
||||
] @constant
|
||||
|
||||
(pair key: (symbol) ":" @constant)
|
||||
(regex) @string.regex
|
||||
(escape_sequence) @string.escape
|
||||
(integer) @number
|
||||
(float) @float
|
||||
|
||||
(nil) @boolean
|
||||
(true) @boolean
|
||||
(false) @boolean
|
||||
[
|
||||
(nil)
|
||||
(true)
|
||||
(false)
|
||||
] @boolean
|
||||
|
||||
(interpolation
|
||||
"#{" @punctuation.bracket
|
||||
|
|
@ -118,25 +151,31 @@
|
|||
|
||||
; Operators
|
||||
|
||||
"=" @operator
|
||||
"=>" @operator
|
||||
"->" @operator
|
||||
"+" @operator
|
||||
"-" @operator
|
||||
"*" @operator
|
||||
"/" @operator
|
||||
[
|
||||
"="
|
||||
"=>"
|
||||
"->"
|
||||
"+"
|
||||
"-"
|
||||
"*"
|
||||
"/"
|
||||
] @operator
|
||||
|
||||
"," @punctuation.delimiter
|
||||
";" @punctuation.delimiter
|
||||
"." @punctuation.delimiter
|
||||
[
|
||||
","
|
||||
";"
|
||||
"."
|
||||
] @punctuation.delimiter
|
||||
|
||||
"(" @punctuation.bracket
|
||||
")" @punctuation.bracket
|
||||
"[" @punctuation.bracket
|
||||
"]" @punctuation.bracket
|
||||
"{" @punctuation.bracket
|
||||
"}" @punctuation.bracket
|
||||
"%w(" @punctuation.bracket
|
||||
"%i(" @punctuation.bracket
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
"%w("
|
||||
"%i("
|
||||
] @punctuation.bracket
|
||||
|
||||
(ERROR) @error
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@
|
|||
((method) @scope
|
||||
(set! scope-inherits false))
|
||||
|
||||
(block) @scope
|
||||
(do_block) @scope
|
||||
[
|
||||
(block)
|
||||
(do_block)
|
||||
] @scope
|
||||
|
||||
(method_parameters (identifier) @definition.function)
|
||||
(lambda_parameters (identifier) @definition.function)
|
||||
|
|
|
|||
27
queries/typescript/highlights.scm
Normal file
27
queries/typescript/highlights.scm
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
[
|
||||
"abstract"
|
||||
"declare"
|
||||
"enum"
|
||||
"export"
|
||||
"implements"
|
||||
"interface"
|
||||
"keyof"
|
||||
"namespace"
|
||||
"private"
|
||||
"protected"
|
||||
"public"
|
||||
"type"
|
||||
] @keyword
|
||||
|
||||
(readonly) @keyword
|
||||
(type_identifier) @type
|
||||
(predefined_type) @type.builtin
|
||||
|
||||
(type_arguments
|
||||
"<" @punctuation.bracket
|
||||
">" @punctuation.bracket)
|
||||
|
||||
; Variables
|
||||
|
||||
(required_parameter (identifier) @variable.parameter)
|
||||
(optional_parameter (identifier) @variable.parameter)
|
||||
2
queries/typescript/locals.scm
Normal file
2
queries/typescript/locals.scm
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
(required_parameter (identifier) @definition)
|
||||
(optional_parameter (identifier) @definition)
|
||||
7
scripts/pre-push
Executable file
7
scripts/pre-push
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Can be used as a pre-push hook
|
||||
# Just symlink this file to .git/hooks/pre-push
|
||||
|
||||
echo "Running style check..."
|
||||
./scripts/style-check.sh
|
||||
3
scripts/style-check.sh
Executable file
3
scripts/style-check.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
luacheck `find -name "*.lua"` --codes
|
||||
Loading…
Add table
Add a link
Reference in a new issue