Merge branch 'master' into master

This commit is contained in:
Chinmay Dalal 2020-06-29 17:25:57 +05:30 committed by GitHub
commit 0f4ee7af72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 1778 additions and 921 deletions

34
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,34 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Output of `:checkhealth nvim_treesitter` ***
```
Paste the output here
```
**Output of `nvim --version`**
```
Paste your output here
```
**Additional context**
Add any other context about the problem here.

View file

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -0,0 +1,12 @@
---
name: Language request
about: Request for a new language to be supported
title: ''
labels: enhancement, good first issue, help wanted
assignees: ''
---
**Language informations**
Please paste any useful informations here !

View file

@ -29,6 +29,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), - 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 you should then be able to open a local playground using `tree-sitter build-wasm && tree-sitter web-ui` within the
parsers repo. parsers repo.
- An Example of somewhat complex highlight queries can be found in queries/ruby/highlights.scm (Maintained by @TravonteD)
### Highlights ### Highlights
@ -36,65 +37,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 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. effect on highlighting. We will work on improving highlighting in the near future though.
#### Misc #### Misc
`@comment` ```
`@error` for error `(ERROR)` nodes. @comment
`@punctuation.delimiter` for `;` `.` `,` @error for error (ERROR` nodes.
`@punctuation.bracket` for `()` or `{}` @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 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. are optional and will not have any effect for now.
`@embedded` ```
`@injection` @embedded
`language` @injection
`content` language
content
```
#### Constants #### Constants
`@constant` ```
`builtin` @constant
`macro` builtin
`@string` macro
`regex` @string
`escape` regex
`@character` escape
`@number` @character
`@boolean` @number
`@float` @boolean
@float
```
#### Functions #### Functions
`@function` ```
`builtin` @function
`macro` builtin
`@parameter` macro
@parameter
`@method` @method
`@field` or `@property` @field or @property
`@constructor` @constructor
```
#### Keywords #### Keywords
`@conditional` ```
`@repeat` @conditional
`@label` for C/Lua-like labels @repeat
`@operator` @label for C/Lua-like labels
`@keyword` @operator
`@exception` @keyword
`@include` keywords for including modules (e.g. import/from in Python) @exception
@include keywords for including modules (e.g. import/from in Python)
`@type`
`builtin`
`@structure`
@type
builtin
@structure
```
### Locals ### Locals
```
`@definition` for various definitions @definition for various definitions
`function` function
`method` method
`var` var
`macro` macro
`type` type
`field` field
`doc` for documentation adjecent to a definition. E.g. doc for documentation adjecent to a definition. E.g.
```
```scheme ```scheme
(comment)* @definition.doc (comment)* @definition.doc
@ -102,7 +113,8 @@ are optional and will not have any effect for now.
name: (field_identifier) @definition.method) name: (field_identifier) @definition.method)
``` ```
`@scope` ```
@scope
`@reference` @reference
```

View file

@ -2,6 +2,9 @@
# nvim-treesitter # nvim-treesitter
Treesitter configurations and abstraction layer for Neovim. 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 # Quickstart
## Requirements ## Requirements
@ -33,7 +36,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` 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: 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. - `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: Let's say you need parsers for `lua`, `c`, and `python`, this is how you do with these commands:
@ -131,19 +134,13 @@ Some of these features are :
You can find the roadmap [here](https://github.com/nvim-treesitter/nvim-treesitter/projects/1). 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! The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated!
## Api ## Utils
Nvim-treesitter exposes an api to extend node capabilites. You can retrieve the api like this: you can get some utility functions with
```lua ```lua
local ts_node_api = require 'nvim-treesitter'.get_node_api() local ts_utils = require 'nvim-treesitter.ts_utils'
``` ```
More information is available in the help file (`:help nvim-treesitter-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`).
## Supported Languages ## Supported Languages
@ -156,13 +153,13 @@ List of currently supported languages:
- [x] ruby (maintained by @TravonteD) - [x] ruby (maintained by @TravonteD)
- [x] c (maintained by @vigoux) - [x] c (maintained by @vigoux)
- [x] go (maintained by @theHamsta) - [x] go (maintained by @theHamsta)
- [ ] cpp - [x] cpp (maintained by @theHamsta, extends C queries)
- [ ] rust - [ ] rust
- [x] python (maintained by @theHamsta) - [x] python (maintained by @theHamsta)
- [ ] javascript - [x] javascript (maintained by @steelsojka)
- [ ] typescript - [x] typescript (maintained by @steelsojka)
- [ ] tsx - [ ] tsx
- [ ] json - [x] json (maintained by @steelsojka)
- [x] html (maintained by @TravonteD) - [x] html (maintained by @TravonteD)
- [ ] csharp - [ ] csharp
- [ ] swift - [ ] swift
@ -171,7 +168,7 @@ List of currently supported languages:
- [x] css (maintained by @TravonteD) - [x] css (maintained by @TravonteD)
- [ ] julia - [ ] julia
- [ ] php - [ ] php
- [ ] bash - [x] bash (maintained by @TravonteD)
- [ ] scala - [ ] scala
- [ ] haskell - [ ] haskell
- [ ] toml - [ ] toml
@ -180,6 +177,14 @@ List of currently supported languages:
- [ ] yaml - [ ] yaml
- [ ] nix - [ ] nix
- [ ] markdown - [ ] 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 ## Troubleshooting
Before doing anything run `:checkhealth nvim_treesitter`. This will help you find where the bug might come from. Before doing anything run `:checkhealth nvim_treesitter`. This will help you find where the bug might come from.

View file

@ -52,9 +52,10 @@ By default, everything is disabled. To enable support for features, in your `ini
============================================================================== ==============================================================================
COMMANDS *nvim-treesitter-commands* 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* |:TSInstallInfo| *:TSInstallInfo*
@ -91,26 +92,29 @@ A list of languages can be found at |:TSInstallInfo|
List modules state for the current session. 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. Nvim treesitter has some wrapper functions that you can retrieve with:
you can retrieve the api with:
> >
local ts_node_api = require 'nvim-treesitter'.get_node_api() local ts_utils = require 'nvim-treesitter.ts_utils'
< <
Methods 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 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` determines wether `dest` is a parent of `source`
return a boolean 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` 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. return the next node within the same parent.
if no node is found, returns `nil`. if no node is found, returns `nil`.
if `allow_switch_parent` is true, it will allow switching parent 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 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. 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. return the previous node within the same parent.
`allow_switch_parent` and `allow_prev_parent` follow the same rule `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 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. return the parent scope of the current scope that contains the node.
`cursor_pos` should be `{ row = number, col = number }` `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. return the first scope within current scope that contains the node.
`cursor_pos` should be `{ row = number, col = number }` `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 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 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* 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. edits. If you encounter such breakage, hiting `zx` should fix folding.
In any case, feel free to open an issue with the reproducing steps. 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: vim:tw=78:ts=8:noet:ft=help:norl:

View file

@ -5,21 +5,54 @@
:TSInstall nvim-treesitter.txt /*:TSInstall* :TSInstall nvim-treesitter.txt /*:TSInstall*
:TSInstallInfo nvim-treesitter.txt /*:TSInstallInfo* :TSInstallInfo nvim-treesitter.txt /*:TSInstallInfo*
:TSModuleInfo nvim-treesitter.txt /*:TSModuleInfo* :TSModuleInfo nvim-treesitter.txt /*:TSModuleInfo*
hl-TSBoolean nvim-treesitter.txt /*hl-TSBoolean*
hl-TSCharacter nvim-treesitter.txt /*hl-TSCharacter*
hl-TSConditional nvim-treesitter.txt /*hl-TSConditional*
hl-TSConstBuiltin nvim-treesitter.txt /*hl-TSConstBuiltin*
hl-TSConstMacro nvim-treesitter.txt /*hl-TSConstMacro*
hl-TSConstant nvim-treesitter.txt /*hl-TSConstant*
hl-TSConstructor nvim-treesitter.txt /*hl-TSConstructor*
hl-TSException nvim-treesitter.txt /*hl-TSException*
hl-TSField nvim-treesitter.txt /*hl-TSField*
hl-TSFloat nvim-treesitter.txt /*hl-TSFloat*
hl-TSFuncBuiltin nvim-treesitter.txt /*hl-TSFuncBuiltin*
hl-TSFuncMacro nvim-treesitter.txt /*hl-TSFuncMacro*
hl-TSFunction nvim-treesitter.txt /*hl-TSFunction*
hl-TSInclude nvim-treesitter.txt /*hl-TSInclude*
hl-TSKeyword nvim-treesitter.txt /*hl-TSKeyword*
hl-TSLabel nvim-treesitter.txt /*hl-TSLabel*
hl-TSMethod nvim-treesitter.txt /*hl-TSMethod*
hl-TSNumber nvim-treesitter.txt /*hl-TSNumber*
hl-TSOperator nvim-treesitter.txt /*hl-TSOperator*
hl-TSParameter nvim-treesitter.txt /*hl-TSParameter*
hl-TSProperty nvim-treesitter.txt /*hl-TSProperty*
hl-TSPunctBracket nvim-treesitter.txt /*hl-TSPunctBracket*
hl-TSPunctDelimiter nvim-treesitter.txt /*hl-TSPunctDelimiter*
hl-TSPunctSpecial nvim-treesitter.txt /*hl-TSPunctSpecial*
hl-TSRepeat nvim-treesitter.txt /*hl-TSRepeat*
hl-TSString nvim-treesitter.txt /*hl-TSString*
hl-TSStringEscape nvim-treesitter.txt /*hl-TSStringEscape*
hl-TSStringRegex nvim-treesitter.txt /*hl-TSStringRegex*
hl-TSStructure nvim-treesitter.txt /*hl-TSStructure*
hl-TSType nvim-treesitter.txt /*hl-TSType*
hl-TSTypeBuiltin nvim-treesitter.txt /*hl-TSTypeBuiltin*
nvim-treesitter nvim-treesitter.txt /*nvim-treesitter* 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-commands nvim-treesitter.txt /*nvim-treesitter-commands*
nvim-treesitter-functions nvim-treesitter.txt /*nvim-treesitter-functions* nvim-treesitter-functions nvim-treesitter.txt /*nvim-treesitter-functions*
nvim-treesitter-highlights nvim-treesitter.txt /*nvim-treesitter-highlights*
nvim-treesitter-intro nvim-treesitter.txt /*nvim-treesitter-intro* nvim-treesitter-intro nvim-treesitter.txt /*nvim-treesitter-intro*
nvim-treesitter-quickstart nvim-treesitter.txt /*nvim-treesitter-quickstart* nvim-treesitter-quickstart nvim-treesitter.txt /*nvim-treesitter-quickstart*
nvim-treesitter-utils nvim-treesitter.txt /*nvim-treesitter-utils*
nvim_treesitter#foldexpr() nvim-treesitter.txt /*nvim_treesitter#foldexpr()* nvim_treesitter#foldexpr() nvim-treesitter.txt /*nvim_treesitter#foldexpr()*
nvim_treesitter#statusline() nvim-treesitter.txt /*nvim_treesitter#statusline()* nvim_treesitter#statusline() nvim-treesitter.txt /*nvim_treesitter#statusline()*
ts_api.containing_scope nvim-treesitter.txt /*ts_api.containing_scope* ts_utils.containing_scope nvim-treesitter.txt /*ts_utils.containing_scope*
ts_api.get_named_children nvim-treesitter.txt /*ts_api.get_named_children* ts_utils.get_named_children nvim-treesitter.txt /*ts_utils.get_named_children*
ts_api.get_next_node nvim-treesitter.txt /*ts_api.get_next_node* ts_utils.get_next_node nvim-treesitter.txt /*ts_utils.get_next_node*
ts_api.get_node_text nvim-treesitter.txt /*ts_api.get_node_text* ts_utils.get_node_at_cursor nvim-treesitter.txt /*ts_utils.get_node_at_cursor*
ts_api.get_previous_node nvim-treesitter.txt /*ts_api.get_previous_node* ts_utils.get_node_text nvim-treesitter.txt /*ts_utils.get_node_text*
ts_api.is_parent nvim-treesitter.txt /*ts_api.is_parent* ts_utils.get_previous_node nvim-treesitter.txt /*ts_utils.get_previous_node*
ts_api.nested_scope nvim-treesitter.txt /*ts_api.nested_scope* ts_utils.is_parent nvim-treesitter.txt /*ts_utils.is_parent*
ts_api.next_scope nvim-treesitter.txt /*ts_api.next_scope* ts_utils.nested_scope nvim-treesitter.txt /*ts_utils.nested_scope*
ts_api.parent_scope nvim-treesitter.txt /*ts_api.parent_scope* ts_utils.next_scope nvim-treesitter.txt /*ts_utils.next_scope*
ts_api.previous_scope nvim-treesitter.txt /*ts_api.previous_scope* ts_utils.parent_scope nvim-treesitter.txt /*ts_utils.parent_scope*
ts_utils.previous_scope nvim-treesitter.txt /*ts_utils.previous_scope*

View file

@ -2,10 +2,10 @@ local api = vim.api
local install = require'nvim-treesitter.install' local install = require'nvim-treesitter.install'
local utils = require'nvim-treesitter.utils' local utils = require'nvim-treesitter.utils'
local ts_utils = require'nvim-treesitter.ts_utils'
local info = require'nvim-treesitter.info' local info = require'nvim-treesitter.info'
local configs = require'nvim-treesitter.configs' local configs = require'nvim-treesitter.configs'
local state = require'nvim-treesitter.state' local parsers = require'nvim-treesitter.parsers'
local ts_utils = require'nvim-treesitter.ts_utils'
local M = {} local M = {}
@ -14,27 +14,22 @@ function M.setup()
utils.setup_commands('info', info.commands) utils.setup_commands('info', info.commands)
utils.setup_commands('configs', configs.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 for _, mod in pairs(configs.available_modules()) do
if configs.is_enabled(mod, ft) then if configs.is_enabled(mod, lang) then
local ft = parsers.lang_to_ft(lang)
local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod) local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd)) api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd))
end 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 end
state.run_update()
end end
function M.statusline(indicator_size) function M.statusline(indicator_size)
if not parsers.has_parser() then return end
local indicator_size = indicator_size or 100 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 if not current_node then return "" end
local expr = current_node:parent() local expr = current_node:parent()
@ -56,13 +51,4 @@ function M.statusline(indicator_size)
end end
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 return M

View file

@ -1,207 +1,7 @@
local api = vim.api local api = vim.api
local queries = require'nvim-treesitter.query' local queries = require'nvim-treesitter.query'
local utils = require'nvim-treesitter.utils' local parsers = require'nvim-treesitter.parsers'
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" },
}
}
-- @enable can be true or false -- @enable can be true or false
-- @disable is a list of languages, only relevant if enable is true -- @disable is a list of languages, only relevant if enable is true
@ -212,8 +12,8 @@ local config = {
highlight = { highlight = {
enable = false, enable = false,
disable = {}, disable = {},
is_supported = function(ft) is_supported = function(lang)
return queries.get_query(ft, 'highlights') ~= nil return queries.get_query(lang, 'highlights') ~= nil
end end
}, },
incremental_selection = { incremental_selection = {
@ -225,8 +25,8 @@ local config = {
scope_incremental="grc", scope_incremental="grc",
node_decremental="grm" node_decremental="grm"
}, },
is_supported = function(ft) is_supported = function(lang)
return queries.get_query(ft, 'locals') return queries.get_query(lang, 'locals')
end end
} }
}, },
@ -235,81 +35,89 @@ local config = {
local M = {} 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 bufnr = bufnr or api.nvim_get_current_buf()
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft') local lang = lang or parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, 'ft'))
if not parsers[ft] or not config.modules[mod] then if not parsers.list[lang] or not config.modules[mod] then
return return
end end
local loaded_mod = require(string.format("nvim-treesitter.%s", mod)) local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
loaded_mod.attach(bufnr, ft) loaded_mod.attach(bufnr, lang)
end end
local function enable_mod_conf_autocmd(mod, ft) local function enable_mod_conf_autocmd(mod, lang)
if not config.modules[mod] or M.is_enabled(mod, ft) then return end if not config.modules[mod] or M.is_enabled(mod, lang) then return end
local ft = parsers.lang_to_ft(lang)
local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod) local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd)) api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd))
for i, parser in pairs(config.modules[mod].disable) do for i, parser in pairs(config.modules[mod].disable) do
if parser == ft then if parser == lang then
table.remove(config.modules[mod].disable, i) table.remove(config.modules[mod].disable, i)
break break
end end
end end
end end
local function enable_all(mod, ft) local function enable_all(mod, lang)
if not config.modules[mod] then return end if not config.modules[mod] then return end
for _, bufnr in pairs(api.nvim_list_bufs()) do for _, bufnr in pairs(api.nvim_list_bufs()) do
if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then local ft = api.nvim_buf_get_option(bufnr, 'ft')
enable_module(mod, bufnr, ft) if not lang or ft == parsers.lang_to_ft(lang) then
enable_module(mod, bufnr, lang)
end end
end end
if ft then if lang then
if utils.has_parser(ft) then if parsers.has_parser(lang) then
enable_mod_conf_autocmd(mod, ft) enable_mod_conf_autocmd(mod, lang)
end end
else else
for _, ft in pairs(M.available_parsers()) do for _, lang in pairs(parsers.available_parsers()) do
if utils.has_parser(ft) then if parsers.has_parser(lang) then
enable_mod_conf_autocmd(mod, ft) enable_mod_conf_autocmd(mod, lang)
end end
end end
end end
config.modules[mod].enable = true config.modules[mod].enable = true
end 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 bufnr = bufnr or api.nvim_get_current_buf()
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft') local lang = lang or parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, 'ft'))
if not parsers[ft] or not config.modules[mod] then if not lang then
return
end
if not parsers.list[lang] or not config.modules[mod] then
return return
end end
local loaded_mod = require(string.format("nvim-treesitter.%s", mod)) local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
loaded_mod.detach(bufnr, ft) loaded_mod.detach(bufnr)
end end
local function disable_mod_conf_autocmd(mod, ft) local function disable_mod_conf_autocmd(mod, lang)
if not config.modules[mod] or not M.is_enabled(mod, ft) then return end if not config.modules[mod] or not M.is_enabled(mod, lang) then return end
local ft = parsers.lang_to_ft(lang)
api.nvim_command(string.format("autocmd! FileType %s", ft)) api.nvim_command(string.format("autocmd! FileType %s", ft))
table.insert(config.modules[mod].disable, ft) table.insert(config.modules[mod].disable, lang)
end end
local function disable_all(mod, ft) local function disable_all(mod, lang)
for _, bufnr in pairs(api.nvim_list_bufs()) do for _, bufnr in pairs(api.nvim_list_bufs()) do
if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then local ft = api.nvim_buf_get_option(bufnr, 'ft')
disable_module(mod, bufnr, ft) if not lang or ft == parsers.lang_to_ft(lang) then
disable_module(mod, bufnr, lang)
end end
end end
if ft then if lang then
disable_mod_conf_autocmd(mod, ft) disable_mod_conf_autocmd(mod, lang)
else else
for _, ft in pairs(M.available_parsers()) do for _, lang in pairs(parsers.available_parsers()) do
disable_mod_conf_autocmd(mod, ft) disable_mod_conf_autocmd(mod, lang)
end end
config.modules[mod].enable = false config.modules[mod].enable = false
end end
@ -352,20 +160,20 @@ M.commands = {
-- @param mod: module (string) -- @param mod: module (string)
-- @param ft: filetype (string) -- @param ft: filetype (string)
function M.is_enabled(mod, ft) function M.is_enabled(mod, lang)
if not M.get_parser_configs()[ft] or not utils.has_parser(ft) then if not parsers.list[lang] or not parsers.has_parser(lang) then
return false return false
end end
local module_config = config.modules[mod] local module_config = config.modules[mod]
if not module_config then return false end 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 return false
end end
for _, parser in pairs(module_config.disable) do for _, parser in pairs(module_config.disable) do
if ft == parser then return false end if lang == parser then return false end
end end
return true return true
@ -396,14 +204,6 @@ function M.setup(user_data)
end 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() function M.available_modules()
return vim.tbl_keys(config.modules) return vim.tbl_keys(config.modules)
end end

View file

@ -4,7 +4,7 @@ local fn = vim.fn
local queries = require'nvim-treesitter.query' local queries = require'nvim-treesitter.query'
local locals = require'nvim-treesitter.locals' local locals = require'nvim-treesitter.locals'
local highlight = require'nvim-treesitter.highlight' 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_start = vim.fn["health#report_start"]
local health_ok = vim.fn['health#report_ok'] local health_ok = vim.fn['health#report_ok']
@ -62,7 +62,7 @@ function M.checkhealth()
local missing_parsers = {} local missing_parsers = {}
-- Parser installation checks -- 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) local installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false)
-- Only print informations about installed parsers -- Only print informations about installed parsers

View file

@ -2,6 +2,7 @@ local api = vim.api
local ts = vim.treesitter local ts = vim.treesitter
local queries = require'nvim-treesitter.query' local queries = require'nvim-treesitter.query'
local parsers = require'nvim-treesitter.parsers'
local M = { local M = {
highlighters = {} highlighters = {}
@ -10,53 +11,54 @@ local M = {
local hlmap = vim.treesitter.TSHighlighter.hl_map local hlmap = vim.treesitter.TSHighlighter.hl_map
-- Misc -- Misc
hlmap.error = "Error" hlmap.error = "TSError"
hlmap["punctuation.delimiter"] = "Delimiter" hlmap["punctuation.delimiter"] = "TSPunctDelimiter"
hlmap["punctuation.bracket"] = "Delimiter" hlmap["punctuation.bracket"] = "TSPunctBracket"
hlmap["punctuation.special"] = "TSPunctSpecial"
-- Constants -- Constants
hlmap["constant"] = "Constant" hlmap["constant"] = "TSConstant"
hlmap["constant.builtin"] = "Special" hlmap["constant.builtin"] = "TSConstBuiltin"
hlmap["constant.macro"] = "Define" hlmap["constant.macro"] = "TSConstMacro"
hlmap["string"] = "String" hlmap["string"] = "TSString"
hlmap["string.regex"] = "String" hlmap["string.regex"] = "TSStringRegex"
hlmap["string.escape"] = "SpecialChar" hlmap["string.escape"] = "TSStringEscape"
hlmap["character"] = "Character" hlmap["character"] = "TSCharacter"
hlmap["number"] = "Number" hlmap["number"] = "TSNumber"
hlmap["boolean"] = "Boolean" hlmap["boolean"] = "TSBoolean"
hlmap["float"] = "Float" hlmap["float"] = "TSFloat"
-- Functions -- Functions
hlmap["function"] = "Function" hlmap["function"] = "TSFunction"
hlmap["function.builtin"] = "Special" hlmap["function.builtin"] = "TSFuncBuiltin"
hlmap["function.macro"] = "Macro" hlmap["function.macro"] = "TSFuncMacro"
hlmap["parameter"] = "Identifier" hlmap["parameter"] = "TSIdentifier"
hlmap["method"] = "Function" hlmap["method"] = "TSMethod"
hlmap["field"] = "Identifier" hlmap["field"] = "TSField"
hlmap["property"] = "Identifier" hlmap["property"] = "TSProperty"
hlmap["constructor"] = "Special" hlmap["constructor"] = "TSConstructor"
-- Keywords -- Keywords
hlmap["conditional"] = "Conditional" hlmap["conditional"] = "TSConditional"
hlmap["repeat"] = "Repeat" hlmap["repeat"] = "TSRepeat"
hlmap["label"] = "Label" hlmap["label"] = "TSLabel"
hlmap["operator"] = "Operator" hlmap["operator"] = "TSOperator"
hlmap["keyword"] = "Keyword" hlmap["keyword"] = "TSKeyword"
hlmap["exception"] = "Exception" hlmap["exception"] = "TSException"
hlmap["type"] = "Type" hlmap["type"] = "TSType"
hlmap["type.builtin"] = "Type" hlmap["type.builtin"] = "TSTypeBuiltin"
hlmap["structure"] = "Structure" hlmap["structure"] = "TSStructure"
hlmap["include"] = "Include" hlmap["include"] = "TSInclude"
function M.attach(bufnr, ft) function M.attach(bufnr, lang)
local buf = bufnr or api.nvim_get_current_buf() local bufnr = bufnr or api.nvim_get_current_buf()
local ft = ft or api.nvim_buf_get_option(buf, 'ft') 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 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 end
function M.detach(bufnr) function M.detach(bufnr)

View file

@ -1,11 +1,13 @@
local api = vim.api local api = vim.api
local state = require'nvim-treesitter.state'
local configs = require'nvim-treesitter.configs' local configs = require'nvim-treesitter.configs'
local ts_utils = require'nvim-treesitter.ts_utils' local ts_utils = require'nvim-treesitter.ts_utils'
local parsers = require'nvim-treesitter.parsers'
local M = {} local M = {}
local selections = {}
local function update_selection(buf, node) local function update_selection(buf, node)
local start_row, start_col, end_row, end_col = node:range() 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 }) vim.fn.setpos(".", { buf, end_row+1, end_col+1, 0 })
end 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) local function select_incremental(get_parent)
return function() return function()
local buf = api.nvim_get_current_buf() 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 selection
-- initialize incremental selection with current range if not nodes or #nodes == 0 or not range_matches(nodes[#nodes]) then
if #buf_state.selection.nodes == 0 then local csrow, cscol, cerow, cecol = visual_selection_range()
local cur_range = buf_state.selection.range local root = parsers.get_parser().tree:root()
if not cur_range then local node = root:named_descendant_for_range(csrow, cscol, cerow, cecol)
local _, cursor_row, cursor_col, _ = unpack(vim.fn.getpos(".")) update_selection(buf, node)
cur_range = { cursor_row, cursor_col, cursor_row, cursor_col + 1 } selections[buf] = { [1] = node }
end return
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])
end end
node = get_parent(nodes[#nodes])
if not node then return end if not node then return end
if node ~= buf_state.selection.nodes[#buf_state.selection.nodes] then if node ~= nodes[#nodes] then
state.insert_selection_node(buf, node) table.insert(nodes, node)
end end
update_selection(buf, node) update_selection(buf, node)
@ -60,13 +79,10 @@ end)
function M.node_decremental() function M.node_decremental()
local buf = api.nvim_get_current_buf() local buf = api.nvim_get_current_buf()
local buf_state = state.get_buf_state(buf) local nodes = selections[buf]
if not nodes or #nodes < 2 then return end
local nodes = buf_state.selection.nodes
if #nodes < 2 then return end
state.pop_selection_node(buf)
table.remove(selections[buf])
local node = nodes[#nodes] local node = nodes[#nodes]
update_selection(buf, node) update_selection(buf, node)
end end
@ -76,14 +92,14 @@ function M.attach(bufnr)
local config = configs.get_module('incremental_selection') local config = configs.get_module('incremental_selection')
for funcname, mapping in pairs(config.keymaps) do for funcname, mapping in pairs(config.keymaps) do
local mode
if funcname == "init_selection" then if funcname == "init_selection" then
local cmd = ":lua require'nvim-treesitter.incremental_selection'.node_incremental()<CR>" mode = 'n'
api.nvim_buf_set_keymap(buf, 'n', mapping, cmd, { silent = true })
else else
local cmd = string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname) mode = 'v'
api.nvim_buf_set_keymap(buf, 'v', mapping, cmd, { silent = true })
end 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
end end

View file

@ -1,15 +1,16 @@
local api = vim.api local api = vim.api
local configs = require'nvim-treesitter.configs' local configs = require'nvim-treesitter.configs'
local parsers = require'nvim-treesitter.parsers'
local M = {} local M = {}
local function install_info() local function install_info()
local max_len = 0 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 if #ft > max_len then max_len = #ft end
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 local is_installed = #api.nvim_get_runtime_file('parser/'..ft..'.so', false) > 0
api.nvim_out_write(ft..string.rep(' ', max_len - #ft + 1)) api.nvim_out_write(ft..string.rep(' ', max_len - #ft + 1))
if is_installed then if is_installed then
@ -20,14 +21,14 @@ local function install_info()
end end
end end
local function print_info_module(sorted_filetypes, mod) local function print_info_module(sorted_languages, mod)
local max_str_len = #sorted_filetypes[1] local max_str_len = #sorted_languages[1]
local header = string.format('%s%s', string.rep(' ', max_str_len + 2), mod) local header = string.format('%s%s', string.rep(' ', max_str_len + 2), mod)
api.nvim_out_write(header..'\n') api.nvim_out_write(header..'\n')
for _, ft in pairs(sorted_filetypes) do for _, lang in pairs(sorted_languages) do
local padding = string.rep(' ', max_str_len - #ft + #mod / 2 + 1) local padding = string.rep(' ', max_str_len - #lang + #mod / 2 + 1)
api.nvim_out_write(ft..":"..padding) api.nvim_out_write(lang..":"..padding)
if configs.is_enabled(mod, ft) then if configs.is_enabled(mod, lang) then
api.nvim_out_write('') api.nvim_out_write('')
else else
api.nvim_out_write('') api.nvim_out_write('')
@ -36,23 +37,23 @@ local function print_info_module(sorted_filetypes, mod)
end end
end end
local function print_info_modules(sorted_filetypes) local function print_info_modules(sorted_languages)
local max_str_len = #sorted_filetypes[1] local max_str_len = #sorted_languages[1]
local header = string.rep(' ', max_str_len + 2) local header = string.rep(' ', max_str_len + 2)
for _, mod in pairs(configs.available_modules()) do for _, mod in pairs(configs.available_modules()) do
header = string.format('%s%s ', header, mod) header = string.format('%s%s ', header, mod)
end end
api.nvim_out_write(header..'\n') api.nvim_out_write(header..'\n')
for _, ft in pairs(sorted_filetypes) do for _, lang in pairs(sorted_languages) do
local padding = string.rep(' ', max_str_len - #ft) local padding = string.rep(' ', max_str_len - #lang)
api.nvim_out_write(ft..":"..padding) api.nvim_out_write(lang..":"..padding)
for _, mod in pairs(configs.available_modules()) do for _, mod in pairs(configs.available_modules()) do
local pad_len = #mod / 2 + 1 local pad_len = #mod / 2 + 1
api.nvim_out_write(string.rep(' ', pad_len)) 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('') api.nvim_out_write('')
else else
api.nvim_out_write('') api.nvim_out_write('')
@ -66,12 +67,12 @@ end
local function module_info(mod) local function module_info(mod)
if mod and not configs.get_config()[mod] then return end if mod and not configs.get_config()[mod] then return end
local ft_by_len = configs.available_parsers() local parserlist = parsers.available_parsers()
table.sort(ft_by_len, function(a, b) return #a > #b end) table.sort(parserlist, function(a, b) return #a > #b end)
if mod then if mod then
print_info_module(ft_by_len, mod) print_info_module(parserlist, mod)
else else
print_info_modules(ft_by_len) print_info_modules(parserlist)
end end
end end

View file

@ -2,13 +2,13 @@ local api = vim.api
local fn = vim.fn local fn = vim.fn
local luv = vim.loop local luv = vim.loop
local configs = require'nvim-treesitter.configs'
local utils = require'nvim-treesitter.utils' local utils = require'nvim-treesitter.utils'
local parsers = require'nvim-treesitter.parsers'
local M = {} local M = {}
local function iter_cmd(cmd_list, i, ft) local function iter_cmd(cmd_list, i, lang)
if i == #cmd_list + 1 then return print('Treesitter parser for '..ft..' has been installed') end if i == #cmd_list + 1 then return print('Treesitter parser for '..lang..' has been installed') end
local attr = cmd_list[i] local attr = cmd_list[i]
if attr.info then print(attr.info) end if attr.info then print(attr.info) end
@ -18,16 +18,16 @@ local function iter_cmd(cmd_list, i, ft)
handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code) handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code)
handle:close() handle:close()
if code ~= 0 then return api.nvim_err_writeln(attr.err) end 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))
end end
local function run_install(cache_folder, package_path, ft, repo) local function run_install(cache_folder, package_path, lang, repo)
local project_name = 'tree-sitter-'..ft local project_name = 'tree-sitter-'..lang
local project_repo = cache_folder..'/'..project_name local project_repo = cache_folder..'/'..project_name
-- compile_location only needed for typescript installs. -- compile_location only needed for typescript installs.
local compile_location = cache_folder..'/'..(repo.location or project_name) 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 = { local command_list = {
{ {
cmd = 'rm', cmd = 'rm',
@ -76,7 +76,7 @@ local function run_install(cache_folder, package_path, ft, repo)
} }
} }
iter_cmd(command_list, 1, ft) iter_cmd(command_list, 1, lang)
end end
-- TODO(kyazdani): this should work on windows too -- TODO(kyazdani): this should work on windows too
@ -95,16 +95,25 @@ local function install(...)
local cache_folder, err = utils.get_cache_dir() local cache_folder, err = utils.get_cache_dir()
if err then return api.nvim_err_writeln(err) end if err then return api.nvim_err_writeln(err) end
for _, ft in ipairs({ ... }) do local languages = { ... }
if #api.nvim_get_runtime_file('parser/'..ft..'.so', false) > 0 then local check_installed = true
local yesno = fn.input(ft .. ' parser already available: would you like to reinstall ? y/n: ') if ... == 'all' then
print('\n ') -- mandatory to avoid messing up command line languages = parsers.available_parsers()
if not string.match(yesno, '^y.*') then return end check_installed = false
end
for _, lang in ipairs(languages) do
if check_installed then
if #api.nvim_get_runtime_file('parser/'..lang..'.so', false) > 0 then
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 goto continue end
end
end end
local parser_config = configs.get_parser_configs()[ft] local parser_config = parsers.get_parser_configs()[lang]
if not parser_config then if not parser_config then
return api.nvim_err_writeln('Parser not available for language '..ft) return api.nvim_err_writeln('Parser not available for language '..lang)
end end
local install_info = parser_config.install_info local install_info = parser_config.install_info
@ -113,7 +122,8 @@ local function install(...)
files={ install_info.files, 'table' } files={ install_info.files, 'table' }
} }
run_install(cache_folder, package_path, ft, install_info) run_install(cache_folder, package_path, lang, install_info)
::continue::
end end
end end
@ -121,15 +131,15 @@ end
M.ensure_installed = function(languages) M.ensure_installed = function(languages)
if type(languages) == 'string' then if type(languages) == 'string' then
if languages == 'all' then if languages == 'all' then
languages = configs.available_parsers() languages = parsers.available_parsers()
else else
languages = {languages} languages = {languages}
end end
end end
for _, ft in ipairs(languages) do for _, lang in ipairs(languages) do
if not utils.has_parser(ft) then if not parsers.has_parser(lang) then
install(ft) install(lang)
end end
end end
end end
@ -142,7 +152,7 @@ M.commands = {
"-nargs=+", "-nargs=+",
"-complete=custom,v:lua.ts_installable_parsers" "-complete=custom,v:lua.ts_installable_parsers"
}, },
description = '`:TSInstall {ft}` installs a parser under nvim-treesitter/parser/{name}.so' description = '`:TSInstall {lang}` installs a parser under nvim-treesitter/parser/{lang}.so'
} }
} }

View file

@ -5,20 +5,20 @@ local api = vim.api
local ts = vim.treesitter local ts = vim.treesitter
local queries = require'nvim-treesitter.query' local queries = require'nvim-treesitter.query'
local utils = require'nvim-treesitter.utils' local parsers = require'nvim-treesitter.parsers'
local M = { local M = {
locals = {} locals = {}
} }
function M.collect_locals(bufnr) function M.collect_locals(bufnr)
local ft = api.nvim_buf_get_option(bufnr, "ft") local lang = parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, "ft"))
if not ft then return end if not lang then return end
local query = queries.get_query(ft, 'locals') local query = queries.get_query(lang, 'locals')
if not query then return end 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 if not parser then return end
local root = parser:parse():root() local root = parser:parse():root()
@ -40,7 +40,7 @@ end
function M.get_locals(bufnr) function M.get_locals(bufnr)
local bufnr = bufnr or api.nvim_get_current_buf() local bufnr = bufnr or api.nvim_get_current_buf()
local cached_local = M.locals[bufnr] local cached_local = M.locals[bufnr]
if not cached_local or api.nvim_buf_get_changedtick(bufnr) < cached_local.tick then 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)) update_cached_locals(bufnr,api.nvim_buf_get_changedtick(bufnr))
end end

View file

@ -1,18 +1,257 @@
local api = vim.api local api = vim.api
local ts = vim.treesitter 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" },
},
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 obj.filetype then
ft_to_parsername[obj.filetype] = name
else
ft_to_parsername[name] = name
end
end
function M.ft_to_lang(ft)
return ft_to_parsername[ft]
end
function M.lang_to_ft(lang)
return M.list[lang].filetype or lang
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) 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 if not lang or #lang == 0 then return false end
return #api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0 return #api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0
end end
function M.get_parser(bufnr, lang) 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 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 if not M[buf] then
M[buf] = {} M[buf] = {}
end end

View file

@ -3,14 +3,41 @@ local ts = vim.treesitter
local M = {} local M = {}
local function read_query_file(fname) local function read_query_files(filenames)
return table.concat(vim.fn.readfile(fname), '\n') local contents = {}
for _,filename in ipairs(filenames) do
vim.list_extend(contents, vim.fn.readfile(filename))
end
return table.concat(contents, '\n')
end end
function M.get_query(ft, query_name) -- Some treesitter grammars extend others.
local query_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', ft, query_name), false) -- We can use that to import the queries of the base language
M.base_language_map = {
cpp = {'c'},
typescript = {'javascript'},
tsx = {'typescript', 'javascript'},
}
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 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
if #query_string > 0 then
return ts.parse_query(lang, query_string)
end end
end end

View file

@ -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

View file

@ -1,6 +1,7 @@
local api = vim.api local api = vim.api
local locals = require'nvim-treesitter.locals' local locals = require'nvim-treesitter.locals'
local parsers = require'nvim-treesitter.parsers'
local M = {} local M = {}
@ -205,4 +206,10 @@ function M.previous_scope(node)
end end
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
return M return M

View file

@ -45,23 +45,4 @@ function M.get_cache_dir()
return nil, 'Invalid cache rights, $XDG_CACHE_HOME or /tmp should be read/write' return nil, 'Invalid cache rights, $XDG_CACHE_HOME or /tmp should be read/write'
end 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
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
end
return M return M

View file

@ -1,4 +1,4 @@
" Last Change: 2020 avril 25 " Last Change: 2020 Jun 29
if exists('g:loaded_nvim_treesitter') if exists('g:loaded_nvim_treesitter')
finish finish
@ -11,10 +11,49 @@ let g:loaded_nvim_treesitter = 1
lua << EOF lua << EOF
ts_installable_parsers = function() 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 end
ts_available_modules = function() ts_available_modules = function()
return table.concat(require'nvim-treesitter.configs'.available_modules(), '\n') return table.concat(require'nvim-treesitter.configs'.available_modules(), '\n')
end end
require'nvim-treesitter'.setup() require'nvim-treesitter'.setup()
EOF 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 TSFloat
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

110
queries/bash/highlights.scm Normal file
View 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)

View file

@ -21,32 +21,55 @@
"while" @repeat "while" @repeat
"#define" @constant.macro "#define" @constant.macro
"#else" @keyword [
"#endif" @keyword "#if"
"#if" @keyword "#ifdef"
"#ifdef" @keyword "#ifndef"
"#ifndef" @keyword "#else"
"#include" @keyword "#elif"
(preproc_directive) @keyword "#endif"
"#include"
(preproc_directive)
] @keyword
"--" @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 ">" @operator
">=" @operator
"!" @operator
"||" @operator "||" @operator
"." @delimiter "-=" @operator
";" @delimiter "+=" @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
(string_literal) @string (string_literal) @string
(system_lib_string) @string (system_lib_string) @string
@ -64,6 +87,8 @@
declarator: (identifier) @function) declarator: (identifier) @function)
(preproc_function_def (preproc_function_def
name: (identifier) @function.macro) name: (identifier) @function.macro)
(preproc_arg) @function.macro
; TODO (preproc_arg) @embedded
(field_identifier) @property (field_identifier) @property
(statement_identifier) @label (statement_identifier) @label
@ -71,7 +96,20 @@
(primitive_type) @type (primitive_type) @type
(sized_type_specifier) @type (sized_type_specifier) @type
((identifier) @type
(#match? @type "^[A-Z]"))
((identifier) @constant ((identifier) @constant
(match? @constant "^[A-Z][A-Z\\d_]+$")) (#match? @constant "^[A-Z][A-Z0-9_]+$"))
(comment) @comment (comment) @comment
;; Parameters
(parameter_list
(parameter_declaration) @parameter)
(preproc_params
(identifier)) @parameter
(ERROR) @error

View file

@ -17,7 +17,7 @@
(declaration (declaration
declarator: (identifier) @definition.var) declarator: (identifier) @definition.var)
(enum_specifier (enum_specifier
name: (*) @definition.type name: (_) @definition.type
(enumerator_list (enumerator_list
(enumerator name: (identifier) @definition.var))) (enumerator name: (identifier) @definition.var)))
@ -36,3 +36,4 @@
(while_statement) @scope (while_statement) @scope
(translation_unit) @scope (translation_unit) @scope
(function_definition) @scope (function_definition) @scope
(compound_statement) @scope ; a block in curly braces

View file

@ -0,0 +1,96 @@
((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]"))
(auto) @keyword
; Constants
(this) @constant.builtin
(nullptr) @constant
(true) @boolean
(false) @boolean
; Keywords
"catch" @exception
"class" @keyword
"constexpr" @keyword
"delete" @keyword
"explicit" @keyword
"final" @exception
"friend" @keyword
"mutable" @keyword
"namespace" @keyword
"noexcept" @keyword
"new" @keyword
"override" @keyword
"private" @keyword
"protected" @keyword
"public" @keyword
"template" @keyword
"throw" @keyword
"try" @exception
"typename" @keyword
"using" @keyword
"virtual" @keyword
"::" @operator

49
queries/cpp/locals.scm Normal file
View file

@ -0,0 +1,49 @@
;; Class / struct defintions
(class_specifier) @scope
(struct_specifier) @scope
(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)

View file

@ -1,72 +1,91 @@
"@media" @keyword [
"@import" @include "@media"
"@charset" @keyword "@import"
"@namespace" @keyword "@charset"
"@supports" @keyword "@namespace"
"@keyframes" @keyword "@supports"
(at_keyword) @keyword "@keyframes"
(to) @keyword (at_keyword)
(from) @keyword (to)
(important) @keyword (from)
(important)
] @keyword
(comment) @comment (comment) @comment
(tag_name) @type [
(nesting_selector) @type (tag_name)
(universal_selector) @type (nesting_selector)
(universal_selector)
] @type
(function_name) @function (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) (attribute_selector (plain_value) @string)
(pseudo_element_selector (tag_name) @property) (pseudo_element_selector (tag_name) @property)
(pseudo_class_selector (class_name) @property) (pseudo_class_selector (class_name) @property)
(class_name) @property [
(id_name) @property (class_name)
(namespace_name) @property (id_name)
(property_name) @property (namespace_name)
(feature_name) @property (property_name)
(attribute_name) @property (feature_name)
(attribute_name)
] @property
((property_name) @type ((property_name) @type
(match? @type "^--")) (#match? @type "^--"))
((plain_value) @type ((plain_value) @type
(match? @type "^--")) (#match? @type "^--"))
(string_value) @string [
(color_value) @string (string_value)
(identifier) @string (color_value)
(identifier)
(unit)
] @string
(integer_value) @number [
(float_value) @number (integer_value)
(unit) @string (float_value)
] @number
"#" @punctuation.delimiter [
"," @punctuation.delimiter "#"
"." @punctuation.delimiter ","
":" @punctuation.delimiter "."
"::" @punctuation.delimiter ":"
";" @punctuation.delimiter "::"
"{" @punctuation.bracket ";"
")" @punctuation.bracket ] @punctuation.delimiter
"(" @punctuation.bracket
"}" @punctuation.bracket [
"{"
")"
"("
"}"
] @punctuation.bracket
(ERROR) @error

View file

@ -8,8 +8,9 @@
"=" @operator "=" @operator
"<" @punctuation.bracket [
">" @punctuation.bracket "<"
"</" @punctuation.bracket ">"
"/>" @punctuation.bracket "</"
"/>"
] @punctuation.bracket

View 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

View file

@ -0,0 +1,35 @@
; 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)
; References
;------------
(identifier) @reference

View 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

View file

@ -1,33 +1,38 @@
;; From tree-sitter-python licensed under MIT License ;; From tree-sitter-python licensed under MIT License
; Copyright (c) 2016 Max Brunsfeld ; Copyright (c) 2016 Max Brunsfeld
; Reset highlighing in f-string interpolations
(interpolation) @Normal
; Identifier naming conventions ; Identifier naming conventions
((import_from_statement
name: (dotted_name
(identifier)) @type)
(match? @type "^[A-Z]"))
((identifier) @type ((identifier) @type
(match? @type "^[A-Z]")) (match? @type "^[A-Z]"))
((identifier) @constant ((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 ; Function calls
(decorator) @function (decorator) @function
((decorator (dotted_name (identifier) @function))
(match? @function "^([A-Z])@!.*$"))
(call
function: (identifier) @function)
(call (call
function: (attribute function: (attribute
attribute: (identifier) @method)) attribute: (identifier) @method))
(call ((call
function: (identifier) @function) function: (identifier) @constructor)
(match? @constructor "^[A-Z]"))
((call ((call
(identifier) @constructor) function: (attribute
attribute: (identifier) @constructor))
(match? @constructor "^[A-Z]")) (match? @constructor "^[A-Z]"))
;; Builtin functions ;; Builtin functions
@ -43,10 +48,9 @@
(function_definition (function_definition
name: (identifier) @function) name: (identifier) @function)
(identifier) @variable
(attribute attribute: (identifier) @property)
(type (identifier) @type) (type (identifier) @type)
((call
((call
function: (identifier) @isinstance function: (identifier) @isinstance
arguments: (argument_list arguments: (argument_list
(*) (*)
@ -55,7 +59,7 @@
; Normal parameters ; Normal parameters
(parameters (parameters
(identifier) @parameter) (identifier) @parameter)
; Default parameters ; Default parameters
(keyword_argument (keyword_argument
name: (identifier) @parameter) name: (identifier) @parameter)
@ -65,17 +69,16 @@
; Variadic parameters *args, **kwargs ; Variadic parameters *args, **kwargs
(parameters (parameters
(list_splat ; *args (list_splat ; *args
(identifier) @parameter)) (identifier) @parameter))
(parameters (parameters
(dictionary_splat ; **kwargs (dictionary_splat ; **kwargs
(identifier) @parameter)) (identifier) @parameter))
; Literals ; Literals
(none) @constant.builtin (none) @constant.builtin
(true) @boolean [(true) (false)] @boolean
(false) @boolean
((identifier) @constant.builtin ((identifier) @constant.builtin
(match? @constant.builtin "self")) (match? @constant.builtin "self"))
@ -84,126 +87,103 @@
(comment) @comment (comment) @comment
(string) @string (string) @string
(escape_sequence) @escape (escape_sequence) @string.escape
; Tokens
[
"-"
"-="
":="
"!="
"*"
"**"
"**="
"*="
"/"
"//"
"//="
"/="
"&"
"%"
"%="
"^"
"+"
"+="
"<"
"<<"
"<="
"<>"
"="
"=="
">"
">="
">>"
"|"
"~"
"and"
"in"
"is"
"not"
"or"
] @operator
; Keywords
[
"assert"
"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 (interpolation
"{" @punctuation.special "{" @punctuation.special
"}" @punctuation.special) @embedded "}" @punctuation.special) @embedded
; Tokens [ "," "." ":" ] @punctuation.delimiter
"-" @operator ; Class definitions
"->" @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_definition (class_definition
name: (identifier) @type) name: (identifier) @type)
(class_definition (class_definition
superclasses: (argument_list superclasses: (argument_list
(identifier) @type)) (identifier) @type))
(attribute ((attribute
attribute: (identifier) @field) attribute: (identifier) @field)
(match? @field "^([A-Z])@!.*$"))
((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)))))
((class_definition ((class_definition
body: (block body: (block
(expression_statement (expression_statement
(assignment (assignment
left: (expression_list left: (expression_list
(identifier) @constant))))) (identifier) @field)))))
(match? @constant "^[A-Z][A-Z_]*$")) (match? @field "^([A-Z])@!.*$"))
;; Error ;; Error
(ERROR) @error (ERROR) @error

View file

@ -30,12 +30,8 @@
; Function defines function and scope ; Function defines function and scope
(function_definition (function_definition
name: (identifier) @definition.function) @scope name: (identifier) @definition.function
body: (block (expression_statement (string) @definition.doc)?)) @scope
;; Should be extended to when syntax supported
;(function_definition
;name: (identifier) @definition.function
;body: (block (expression_statement (string) @definition.function.doc)?)) @scope
(class_definition (class_definition

View file

@ -0,0 +1,29 @@
;; Forked from tree-sitter-regex
;; The MIT License (MIT) Copyright (c) 2014 Max Brunsfeld
[
"("
")"
"(?"
"(?:"
"(?<"
">"
"["
"]"
"{"
"}"
] @punctuation.bracket
(group_name) @property
[
(identity_escape)
(control_letter_escape)
(character_class_escape)
(control_escape)
(start_assertion)
(end_assertion)
(boundary_assertion)
(non_boundary_assertion)
] @escape
[ "*" "+" "|" "=" "<=" "!" "<!" ] @operator

View file

@ -1,81 +1,105 @@
; Keywords ; Keywords
"alias" @keyword [
"and" @keyword "alias"
"begin" @keyword "and"
"break" @keyword "begin"
"case" @conditional "break"
"class" @keyword "class"
"def" @keyword "def"
"do" @keyword "do"
"else" @conditional "end"
"elsif" @conditional "ensure"
"end" @keyword "in"
"ensure" @keyword "module"
"for" @repeat "next"
"if" @conditional "or"
"in" @keyword "rescue"
"module" @keyword "retry"
"next" @keyword "return"
"or" @keyword "then"
"rescue" @keyword "yield"
"retry" @keyword ] @keyword
"return" @keyword
"then" @keyword [
"unless" @conditional "case"
"until" @repeat "else"
"when" @conditional "elsif"
"while" @repeat "if"
"yield" @keyword "unless"
"when"
] @conditional
[
"for"
"until"
"while"
] @repeat
((identifier) @keyword ((identifier) @keyword
(match? @keyword "^(private|protected|public)$")) (#match? @keyword "^(private|protected|public)$"))
; Function calls ; Function calls
((identifier) @function ((identifier) @function
(eq? @function "require")) (#eq? @function "require"))
"defined?" @function "defined?" @function
(call (call
receiver: (constant) @constant) [
receiver: (constant) @constant
method: [
(identifier)
(constant)
] @function
])
(method_call (method_call
receiver: (constant) @constant) [
(call receiver: (constant) @constant
method: (identifier) @function) method: [
(method_call (identifier)
method: (identifier) @function) (constant)
(call ] @function
method: (constant) @function) ])
(method_call
method: (constant) @function)
; Function definitions ; Function definitions
(alias (identifier) @function) (alias (identifier) @function)
(setter (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) (class name: (constant) @constant)
(singleton_method name: (identifier) @function)
(singleton_method name: (constant) @constant)
; Identifiers ; Identifiers
[
(class_variable) @label (class_variable)
(instance_variable) @label (instance_variable)
] @label
((identifier) @constant.builtin ((identifier) @constant.builtin
(match? @constant.builtin "^__(FILE|LINE|ENCODING)__$")) (#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
((constant) @constant.macro ((constant) @constant.macro
(match? @constant.macro "^[A-Z\\d_]+$")) (#match? @constant.macro "^[A-Z\\d_]+$"))
(constant) @constant (constant) @constant
(self) @constant.builtin [
(super) @constant.builtin (self)
(super)
] @constant.builtin
(method_parameters (identifier) @parameter) (method_parameters (identifier) @parameter)
(lambda_parameters (identifier) @parameter) (lambda_parameters (identifier) @parameter)
@ -87,27 +111,37 @@
(block_parameter (identifier) @parameter) (block_parameter (identifier) @parameter)
(keyword_parameter (identifier) @parameter) (keyword_parameter (identifier) @parameter)
((identifier) @function ; TODO: Re-enable this once it is supported
(is-not? local)) ; ((identifier) @function
; (#is-not? local))
; Literals ; Literals
(string) @string [
(bare_string) @string (string)
(bare_symbol) @constant (bare_string)
(subshell) @string (subshell)
(heredoc_beginning) @constant (heredoc_body)
(heredoc_body) @string ] @string
(heredoc_end) @constant
(symbol) @constant [
(bare_symbol)
(heredoc_beginning)
(heredoc_end)
(symbol)
] @constant
(pair key: (symbol) ":" @constant)
(regex) @string.regex (regex) @string.regex
(escape_sequence) @string.escape (escape_sequence) @string.escape
(integer) @number (integer) @number
(float) @float (float) @float
(nil) @boolean [
(true) @boolean (nil)
(false) @boolean (true)
(false)
] @boolean
(interpolation (interpolation
"#{" @punctuation.bracket "#{" @punctuation.bracket
@ -117,25 +151,31 @@
; Operators ; 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 (ERROR) @error

View file

@ -24,8 +24,10 @@
((method) @scope ((method) @scope
(set! scope-inherits false)) (set! scope-inherits false))
(block) @scope [
(do_block) @scope (block)
(do_block)
] @scope
(method_parameters (identifier) @definition.function) (method_parameters (identifier) @definition.function)
(lambda_parameters (identifier) @definition.function) (lambda_parameters (identifier) @definition.function)

View 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)

View file

@ -0,0 +1,2 @@
(required_parameter (identifier) @definition)
(optional_parameter (identifier) @definition)