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

View file

@ -2,6 +2,9 @@
# nvim-treesitter
Treesitter configurations and abstraction layer for Neovim.
**Warning: Treesitter and Treesitter highlighting are an experimental feature of nightly versions of Neovim.
Please consider the experience with this plug-in as experimental until Neovim 0.5 is released!**
# Quickstart
## Requirements
@ -33,7 +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`
provides two command to tackle this issue:
- `TSInstall` to install a given parser.
- `TSInstall` to install one or more parser. You can use `TSInstall all` to download all parsers.
- `TSInstallInfo` to know which parser is installed.
Let's say you need parsers for `lua`, `c`, and `python`, this is how you do with these commands:
@ -131,19 +134,13 @@ Some of these features are :
You can find the roadmap [here](https://github.com/nvim-treesitter/nvim-treesitter/projects/1).
The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated!
## Api
## 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
local ts_node_api = require 'nvim-treesitter'.get_node_api()
local ts_utils = require 'nvim-treesitter.ts_utils'
```
You can also retrieve the current state of the current buffer with:
```lua
local buf_state = require'nvim-treesitter'.get_buf_state()
```
More information is available in neovim documentation (`:help nvim-treesitter-api`).
More information is available in the help file (`:help nvim-treesitter-utils`).
## Supported Languages
@ -156,13 +153,13 @@ List of currently supported languages:
- [x] ruby (maintained by @TravonteD)
- [x] c (maintained by @vigoux)
- [x] go (maintained by @theHamsta)
- [ ] cpp
- [x] cpp (maintained by @theHamsta, extends C queries)
- [ ] rust
- [x] python (maintained by @theHamsta)
- [ ] javascript
- [ ] typescript
- [x] javascript (maintained by @steelsojka)
- [x] typescript (maintained by @steelsojka)
- [ ] tsx
- [ ] json
- [x] json (maintained by @steelsojka)
- [x] html (maintained by @TravonteD)
- [ ] csharp
- [ ] swift
@ -171,7 +168,7 @@ List of currently supported languages:
- [x] css (maintained by @TravonteD)
- [ ] julia
- [ ] php
- [ ] bash
- [x] bash (maintained by @TravonteD)
- [ ] scala
- [ ] haskell
- [ ] toml
@ -180,6 +177,14 @@ List of currently supported languages:
- [ ] yaml
- [ ] nix
- [ ] markdown
- [x] regex (maintained by @theHamsta)
## User Query Extensions
You can add your own query files by placing a query file in vim's runtime path after `nvim-treesitter` is sourced.
If the language has a built in query file, that file will be appended to or it will be used (useful for languages not yet supported).
For example, you can add files to `<vim-config-dir>/after/queries/lua/highlights.scm` to add more queries to lua highlights.
You can also manually add query paths to the runtime path by adding this to your vim config `set rtp+='path/to/queries'`.
## Troubleshooting
Before doing anything run `:checkhealth nvim_treesitter`. This will help you find where the bug might come from.

View file

@ -52,9 +52,10 @@ By default, everything is disabled. To enable support for features, in your `ini
==============================================================================
COMMANDS *nvim-treesitter-commands*
|:TSInstall| {language} *:TSInstall*
|:TSInstall| {language} ... *:TSInstall*
Download, compile and install a parser for {language}
Install one or more treesitter parsers.
You can use |:TSInstall| `all` to install all parsers.
|:TSInstallInfo| *:TSInstallInfo*
@ -91,26 +92,29 @@ A list of languages can be found at |:TSInstallInfo|
List modules state for the current session.
==============================================================================
API *nvim-treesitter-api*
UTILS *nvim-treesitter-utils*
Nvim treesitter exposes extended functions to use on nodes and scopes.
you can retrieve the api with:
Nvim treesitter has some wrapper functions that you can retrieve with:
>
local ts_node_api = require 'nvim-treesitter'.get_node_api()
local ts_utils = require 'nvim-treesitter.ts_utils'
<
Methods
get_node_text(node, bufnr) *ts_api.get_node_text*
get_node_at_cursor(winnr) *ts_utils.get_node_at_cursor*
winnr will be 0 if nil
returns the node under the cursor
get_node_text(node, bufnr) *ts_utils.get_node_text*
return the text content of a node
is_parent(dest, source) *ts_api.is_parent*
is_parent(dest, source) *ts_utils.is_parent*
determines wether `dest` is a parent of `source`
return a boolean
get_named_children(node) *ts_api.get_named_children*
get_named_children(node) *ts_utils.get_named_children*
return a table of named children of `node`
get_next_node(node, allow_switch_parent, allow_next_parent) *ts_api.get_next_node*
get_next_node(node, allow_switch_parent, allow_next_parent) *ts_utils.get_next_node*
return the next node within the same parent.
if no node is found, returns `nil`.
if `allow_switch_parent` is true, it will allow switching parent
@ -118,42 +122,28 @@ get_next_node(node, allow_switch_parent, allow_next_parent) *ts_api.get_next_nod
if `allow_next_parent` is true, it will allow next parent if
the node is the last node and the next parent doesn't have children.
get_previous_node(node, allow_switch_parents, allow_prev_parent) *ts_api.get_previous_node*
get_previous_node(node, allow_switch_parents, allow_prev_parent) *ts_utils.get_previous_node*
return the previous node within the same parent.
`allow_switch_parent` and `allow_prev_parent` follow the same rule
as |ts_api.get_next_node| but if the node is the first node.
as |ts_utils.get_next_node| but if the node is the first node.
containing_scope(node) *ts_api.containing_scope*
containing_scope(node) *ts_utils.containing_scope*
return the smallest scope containing the node
parent_scope(node, cursor_pos) *ts_api.parent_scope*
parent_scope(node, cursor_pos) *ts_utils.parent_scope*
return the parent scope of the current scope that contains the node.
`cursor_pos` should be `{ row = number, col = number }`
you can retrieve the cursor_pos with the buffer state
nested_scope(node, cursor_pos) *ts_api.nested_scope*
nested_scope(node, cursor_pos) *ts_utils.nested_scope*
return the first scope within current scope that contains the node.
`cursor_pos` should be `{ row = number, col = number }`
you can retrieve the cursor_pos with the buffer state
next_scope(node) *ts_api.next_scope*
next_scope(node) *ts_utils.next_scope*
return the neighbour scope of the current node
previous_scope(node) *ts_api.previous_scope*
previous_scope(node) *ts_utils.previous_scope*
return the previous neighbour scope of the current node
Nvim-treesitter also provides access to the state of the current buffer:
>
local cur_buf_state = require'nvim-treesitter'.get_buf_state()
print(vim.inspect(cur_buf_state))
--[[
{
cursor_pos = { row = number, col = number }, (current cursor pos in the buffer)
current_node = tsnode (smallest node the cursor is on)
}
]]--
<
==============================================================================
FUNCTIONS *nvim-treesitter-functions*
@ -177,4 +167,141 @@ Note: This is highly experimental, and folding can break on some types of
edits. If you encounter such breakage, hiting `zx` should fix folding.
In any case, feel free to open an issue with the reproducing steps.
==============================================================================
HIGHLIGHTS *nvim-treesitter-highlights*
`TSError`
*hl-TSError*
For syntax/parser errors.
You can deactivate highlighting of syntax errors by adding this to your
init.vim: >
highlight link TSError Normal
`TSPunctDelimiter`
*hl-TSPunctDelimiter*
For delimiters ie: `.`
`TSPunctBracket`
*hl-TSPunctBracket*
For brackets and parens.
`TSPunctSpecial`
*hl-TSPunctSpecial*
For special punctutation that does not fall in the catagories before.
`TSConstant`
*hl-TSConstant*
For constants
`TSConstBuiltin`
*hl-TSConstBuiltin*
For constant that are built in the language: `nil` in Lua.
`TSConstMacro`
*hl-TSConstMacro*
For constants that are defined by macros: `NULL` in C.
`TSString`
*hl-TSString*
For strings.
`TSStringRegex`
*hl-TSStringRegex*
For regexes.
`TSStringEscape`
*hl-TSStringEscape*
For escape characters within a string.
`TSCharacter`
*hl-TSCharacter*
For characters.
`TSNumber`
*hl-TSNumber*
For integers.
`TSBoolean`
*hl-TSBoolean*
For booleans.
`TSFloat`
*hl-TSFloat*
For floats.
`TSFunction`
*hl-TSFunction*
For function (calls and definitions).
`TSFuncBuiltin`
*hl-TSFuncBuiltin*
For builtin functions: `table.insert` in Lua.
`TSFuncMacro`
*hl-TSFuncMacro*
For macro defined fuctions (calls and definitions): each `macro_rules` in
Rust.
`TSParameter`
*hl-TSParameter*
For parameters of a function.
`TSMethod`
*hl-TSMethod*
For method calls and definitions.
`TSField`
*hl-TSField*
For fields.
`TSProperty`
*hl-TSProperty*
Same as `TSField`.
`TSConstructor`
*hl-TSConstructor*
For constructor calls and definitions: `{}` in Lua, and Java constructors.
`TSConditional`
*hl-TSConditional*
For keywords related to conditionnals.
`TSRepeat`
*hl-TSRepeat*
For keywords related to loops.
`TSLabel`
*hl-TSLabel*
For labels: `label:` in C and `:label:` in Lua.
`TSOperator`
*hl-TSOperator*
For any operator: `+`, but also `->` and `*` in C.
`TSKeyword`
*hl-TSKeyword*
For keywords that don't fall in previous categories.
`TSException`
*hl-TSException*
For exception related keywords.
`TSType`
*hl-TSType*
For types.
`TSTypeBuiltin`
*hl-TSTypeBuiltin*
For builtin types (you guessed it, right ?).
`TSStructure`
*hl-TSStructure*
This is left as an exercise for the reader.
`TSInclude`
*hl-TSInclude*
For includes: `#include` in C, `use` or `extern crate` in Rust, or `require`
in Lua
vim:tw=78:ts=8:noet:ft=help:norl:

View file

@ -5,21 +5,54 @@
:TSInstall nvim-treesitter.txt /*:TSInstall*
:TSInstallInfo nvim-treesitter.txt /*:TSInstallInfo*
: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-api nvim-treesitter.txt /*nvim-treesitter-api*
nvim-treesitter-commands nvim-treesitter.txt /*nvim-treesitter-commands*
nvim-treesitter-functions nvim-treesitter.txt /*nvim-treesitter-functions*
nvim-treesitter-highlights nvim-treesitter.txt /*nvim-treesitter-highlights*
nvim-treesitter-intro nvim-treesitter.txt /*nvim-treesitter-intro*
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#statusline() nvim-treesitter.txt /*nvim_treesitter#statusline()*
ts_api.containing_scope nvim-treesitter.txt /*ts_api.containing_scope*
ts_api.get_named_children nvim-treesitter.txt /*ts_api.get_named_children*
ts_api.get_next_node nvim-treesitter.txt /*ts_api.get_next_node*
ts_api.get_node_text nvim-treesitter.txt /*ts_api.get_node_text*
ts_api.get_previous_node nvim-treesitter.txt /*ts_api.get_previous_node*
ts_api.is_parent nvim-treesitter.txt /*ts_api.is_parent*
ts_api.nested_scope nvim-treesitter.txt /*ts_api.nested_scope*
ts_api.next_scope nvim-treesitter.txt /*ts_api.next_scope*
ts_api.parent_scope nvim-treesitter.txt /*ts_api.parent_scope*
ts_api.previous_scope nvim-treesitter.txt /*ts_api.previous_scope*
ts_utils.containing_scope nvim-treesitter.txt /*ts_utils.containing_scope*
ts_utils.get_named_children nvim-treesitter.txt /*ts_utils.get_named_children*
ts_utils.get_next_node nvim-treesitter.txt /*ts_utils.get_next_node*
ts_utils.get_node_at_cursor nvim-treesitter.txt /*ts_utils.get_node_at_cursor*
ts_utils.get_node_text nvim-treesitter.txt /*ts_utils.get_node_text*
ts_utils.get_previous_node nvim-treesitter.txt /*ts_utils.get_previous_node*
ts_utils.is_parent nvim-treesitter.txt /*ts_utils.is_parent*
ts_utils.nested_scope nvim-treesitter.txt /*ts_utils.nested_scope*
ts_utils.next_scope nvim-treesitter.txt /*ts_utils.next_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 utils = require'nvim-treesitter.utils'
local ts_utils = require'nvim-treesitter.ts_utils'
local info = require'nvim-treesitter.info'
local configs = require'nvim-treesitter.configs'
local state = require'nvim-treesitter.state'
local ts_utils = require'nvim-treesitter.ts_utils'
local parsers = require'nvim-treesitter.parsers'
local M = {}
@ -14,27 +14,22 @@ function M.setup()
utils.setup_commands('info', info.commands)
utils.setup_commands('configs', configs.commands)
for _, ft in pairs(configs.available_parsers()) do
for _, lang in pairs(parsers.available_parsers()) do
for _, mod in pairs(configs.available_modules()) do
if configs.is_enabled(mod, ft) then
if configs.is_enabled(mod, lang) then
local ft = parsers.lang_to_ft(lang)
local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd))
end
end
local cmd = string.format("lua require'nvim-treesitter.state'.attach_to_buffer(%s)", ft)
api.nvim_command(string.format('autocmd NvimTreesitter FileType %s %s', ft, cmd))
end
state.run_update()
end
function M.statusline(indicator_size)
if not parsers.has_parser() then return end
local indicator_size = indicator_size or 100
local bufnr = api.nvim_get_current_buf()
local buf_state = state.get_buf_state(bufnr)
if not buf_state then return "" end
local current_node = buf_state.current_node
local current_node = ts_utils.get_node_at_cursor()
if not current_node then return "" end
local expr = current_node:parent()
@ -56,13 +51,4 @@ function M.statusline(indicator_size)
end
end
function M.get_buf_state()
local bufnr = api.nvim_get_current_buf()
return state.exposed_state(bufnr)
end
function M.get_node_api()
return ts_utils
end
return M

View file

@ -1,207 +1,7 @@
local api = vim.api
local queries = require'nvim-treesitter.query'
local utils = require'nvim-treesitter.utils'
local parsers = {}
parsers.javascript = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-javascript",
files = { "src/parser.c", "src/scanner.c" },
}
}
parsers.c = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-c",
files = { "src/parser.c" }
}
}
parsers.cpp = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-cpp",
files = { "src/parser.c", "src/scanner.cc" }
}
}
parsers.rust = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-rust",
files = { "src/parser.c", "src/scanner.c" },
}
}
parsers.lua = {
install_info = {
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
files = { "src/parser.c", "src/scanner.cc" }
}
}
parsers.python = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-python",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.go = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-go",
files = { "src/parser.c" },
}
}
parsers.ruby = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-ruby",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.bash = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-bash",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.php = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-php",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.java = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-java",
files = { "src/parser.c" },
}
}
parsers.html = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-html",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.julia = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-julia",
files = { "src/parser.c", "src/scanner.c" },
}
}
parsers.json = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-json",
files = { "src/parser.c" },
}
}
parsers.css = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-css",
files = { "src/parser.c", "src/scanner.c" },
}
}
parsers.ocaml = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.swift = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-swift",
files = { "src/parser.c" },
}
}
parsers.csharp = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
files = { "src/parser.c", "src/scanner.c" },
}
}
parsers.typescript = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-typescript",
files = { "src/parser.c", "src/scanner.c" },
location = "tree-sitter-typescript/typescript"
}
}
parsers.tsx = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-typescript",
files = { "src/parser.c", "src/scanner.c" },
location = "tree-sitter-tsx/tsx"
}
}
parsers.scala = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-scala",
files = { "src/parser.c", "src/scanner.c" },
}
}
parsers.haskell = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-haskell",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.markdown = {
install_info = {
url = "https://github.com/ikatyang/tree-sitter-markdown",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.toml = {
install_info = {
url = "https://github.com/ikatyang/tree-sitter-toml",
files = { "src/parser.c", "src/scanner.c" },
}
}
parsers.vue = {
install_info = {
url = "https://github.com/ikatyang/tree-sitter-vue",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.elm = {
install_info = {
url = "https://github.com//razzeee/tree-sitter-elm",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.yaml = {
install_info = {
url = "https://github.com/ikatyang/tree-sitter-yaml",
files = { "src/parser.c", "src/scanner.cc" },
}
}
parsers.nix = {
install_info = {
url = "https://github.com/cstrahan/tree-sitter-nix",
files = { "src/parser.c", "src/scanner.cc" },
}
}
local parsers = require'nvim-treesitter.parsers'
-- @enable can be true or false
-- @disable is a list of languages, only relevant if enable is true
@ -212,8 +12,8 @@ local config = {
highlight = {
enable = false,
disable = {},
is_supported = function(ft)
return queries.get_query(ft, 'highlights') ~= nil
is_supported = function(lang)
return queries.get_query(lang, 'highlights') ~= nil
end
},
incremental_selection = {
@ -225,8 +25,8 @@ local config = {
scope_incremental="grc",
node_decremental="grm"
},
is_supported = function(ft)
return queries.get_query(ft, 'locals')
is_supported = function(lang)
return queries.get_query(lang, 'locals')
end
}
},
@ -235,81 +35,89 @@ local config = {
local M = {}
local function enable_module(mod, bufnr, ft)
local function enable_module(mod, bufnr, lang)
local bufnr = bufnr or api.nvim_get_current_buf()
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
if not parsers[ft] or not config.modules[mod] then
local lang = lang or parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, 'ft'))
if not parsers.list[lang] or not config.modules[mod] then
return
end
local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
loaded_mod.attach(bufnr, ft)
loaded_mod.attach(bufnr, lang)
end
local function enable_mod_conf_autocmd(mod, ft)
if not config.modules[mod] or M.is_enabled(mod, ft) then return end
local function enable_mod_conf_autocmd(mod, lang)
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)
api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd))
for i, parser in pairs(config.modules[mod].disable) do
if parser == ft then
if parser == lang then
table.remove(config.modules[mod].disable, i)
break
end
end
end
local function enable_all(mod, ft)
local function enable_all(mod, lang)
if not config.modules[mod] then return end
for _, bufnr in pairs(api.nvim_list_bufs()) do
if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then
enable_module(mod, bufnr, ft)
local ft = api.nvim_buf_get_option(bufnr, 'ft')
if not lang or ft == parsers.lang_to_ft(lang) then
enable_module(mod, bufnr, lang)
end
end
if ft then
if utils.has_parser(ft) then
enable_mod_conf_autocmd(mod, ft)
if lang then
if parsers.has_parser(lang) then
enable_mod_conf_autocmd(mod, lang)
end
else
for _, ft in pairs(M.available_parsers()) do
if utils.has_parser(ft) then
enable_mod_conf_autocmd(mod, ft)
for _, lang in pairs(parsers.available_parsers()) do
if parsers.has_parser(lang) then
enable_mod_conf_autocmd(mod, lang)
end
end
end
config.modules[mod].enable = true
end
local function disable_module(mod, bufnr, ft)
local function disable_module(mod, bufnr, lang)
local bufnr = bufnr or api.nvim_get_current_buf()
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
if not parsers[ft] or not config.modules[mod] then
local lang = lang or parsers.ft_to_lang(api.nvim_buf_get_option(bufnr, 'ft'))
if not lang then
return
end
if not parsers.list[lang] or not config.modules[mod] then
return
end
local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
loaded_mod.detach(bufnr, ft)
loaded_mod.detach(bufnr)
end
local function disable_mod_conf_autocmd(mod, ft)
if not config.modules[mod] or not M.is_enabled(mod, ft) then return end
local function disable_mod_conf_autocmd(mod, lang)
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))
table.insert(config.modules[mod].disable, ft)
table.insert(config.modules[mod].disable, lang)
end
local function disable_all(mod, ft)
local function disable_all(mod, lang)
for _, bufnr in pairs(api.nvim_list_bufs()) do
if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then
disable_module(mod, bufnr, ft)
local ft = api.nvim_buf_get_option(bufnr, 'ft')
if not lang or ft == parsers.lang_to_ft(lang) then
disable_module(mod, bufnr, lang)
end
end
if ft then
disable_mod_conf_autocmd(mod, ft)
if lang then
disable_mod_conf_autocmd(mod, lang)
else
for _, ft in pairs(M.available_parsers()) do
disable_mod_conf_autocmd(mod, ft)
for _, lang in pairs(parsers.available_parsers()) do
disable_mod_conf_autocmd(mod, lang)
end
config.modules[mod].enable = false
end
@ -352,20 +160,20 @@ M.commands = {
-- @param mod: module (string)
-- @param ft: filetype (string)
function M.is_enabled(mod, ft)
if not M.get_parser_configs()[ft] or not utils.has_parser(ft) then
function M.is_enabled(mod, lang)
if not parsers.list[lang] or not parsers.has_parser(lang) then
return false
end
local module_config = config.modules[mod]
if not module_config then return false end
if not module_config.enable or not module_config.is_supported(ft) then
if not module_config.enable or not module_config.is_supported(lang) then
return false
end
for _, parser in pairs(module_config.disable) do
if ft == parser then return false end
if lang == parser then return false end
end
return true
@ -396,14 +204,6 @@ function M.setup(user_data)
end
end
function M.get_parser_configs()
return parsers
end
function M.available_parsers()
return vim.tbl_keys(parsers)
end
function M.available_modules()
return vim.tbl_keys(config.modules)
end

View file

@ -4,7 +4,7 @@ local fn = vim.fn
local queries = require'nvim-treesitter.query'
local locals = require'nvim-treesitter.locals'
local highlight = require'nvim-treesitter.highlight'
local configs = require'nvim-treesitter.configs'
local parsers = require'nvim-treesitter.parsers'
local health_start = vim.fn["health#report_start"]
local health_ok = vim.fn['health#report_ok']
@ -62,7 +62,7 @@ function M.checkhealth()
local missing_parsers = {}
-- Parser installation checks
for _, parser_name in pairs(configs.available_parsers()) do
for _, parser_name in pairs(parsers.available_parsers()) do
local installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false)
-- Only print informations about installed parsers

View file

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

View file

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

View file

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

View file

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

View file

@ -1,18 +1,257 @@
local api = vim.api
local ts = vim.treesitter
local M = {}
local list = {}
list.javascript = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-javascript",
files = { "src/parser.c", "src/scanner.c" },
}
}
list.c = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-c",
files = { "src/parser.c" }
}
}
list.cpp = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-cpp",
files = { "src/parser.c", "src/scanner.cc" }
}
}
list.rust = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-rust",
files = { "src/parser.c", "src/scanner.c" },
}
}
list.lua = {
install_info = {
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
files = { "src/parser.c", "src/scanner.cc" }
}
}
list.python = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-python",
files = { "src/parser.c", "src/scanner.cc" },
}
}
list.go = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-go",
files = { "src/parser.c" },
}
}
list.ruby = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-ruby",
files = { "src/parser.c", "src/scanner.cc" },
}
}
list.bash = {
install_info = {
url = "https://github.com/tree-sitter/tree-sitter-bash",
files = { "src/parser.c", "src/scanner.cc" },
},
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)
local lang = lang or api.nvim_buf_get_option(0, 'filetype')
local buf = api.nvim_get_current_buf()
local lang = lang or M.ft_to_lang(api.nvim_buf_get_option(buf, 'ft'))
if not lang or #lang == 0 then return false end
return #api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0
end
function M.get_parser(bufnr, lang)
local buf = bufnr or api.nvim_get_current_buf()
local lang = lang or M.ft_to_lang(api.nvim_buf_get_option(buf, 'ft'))
if M.has_parser(lang) then
local buf = bufnr or api.nvim_get_current_buf()
local lang = lang or api.nvim_buf_get_option(buf, 'ft')
if not M[buf] then
M[buf] = {}
end

View file

@ -3,14 +3,41 @@ local ts = vim.treesitter
local M = {}
local function read_query_file(fname)
return table.concat(vim.fn.readfile(fname), '\n')
local function read_query_files(filenames)
local contents = {}
for _,filename in ipairs(filenames) do
vim.list_extend(contents, vim.fn.readfile(filename))
end
return table.concat(contents, '\n')
end
function M.get_query(ft, query_name)
local query_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', ft, query_name), false)
-- Some treesitter grammars extend others.
-- We can use that to import the queries of the base language
M.base_language_map = {
cpp = {'c'},
typescript = {'javascript'},
tsx = {'typescript', 'javascript'},
}
function M.get_query(lang, query_name)
local query_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', lang, query_name), true)
local query_string = ''
if #query_files > 0 then
return ts.parse_query(ft, read_query_file(query_files[1]))
query_string = read_query_files(query_files) .. "\n" .. query_string
end
for _, base_lang in ipairs(M.base_language_map[lang] or {}) do
local base_files = api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', base_lang, query_name), true)
if base_files and #base_files > 0 then
query_string = read_query_files(base_files) .. "\n" .. query_string
end
end
if #query_string > 0 then
return ts.parse_query(lang, query_string)
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 locals = require'nvim-treesitter.locals'
local parsers = require'nvim-treesitter.parsers'
local M = {}
@ -205,4 +206,10 @@ function M.previous_scope(node)
end
end
function M.get_node_at_cursor(winnr)
local cursor = api.nvim_win_get_cursor(winnr or 0)
local root = parsers.get_parser().tree:root()
return root:named_descendant_for_range(cursor[1]-1,cursor[2],cursor[1]-1,cursor[2])
end
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'
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

View file

@ -1,4 +1,4 @@
" Last Change: 2020 avril 25
" Last Change: 2020 Jun 29
if exists('g:loaded_nvim_treesitter')
finish
@ -11,10 +11,49 @@ let g:loaded_nvim_treesitter = 1
lua << EOF
ts_installable_parsers = function()
return table.concat(require'nvim-treesitter.configs'.available_parsers(), '\n')
return table.concat(require'nvim-treesitter.parsers'.available_parsers(), '\n')
end
ts_available_modules = function()
return table.concat(require'nvim-treesitter.configs'.available_modules(), '\n')
end
require'nvim-treesitter'.setup()
EOF
highlight default link TSError Error
highlight default link TSPunctDelimiter Delimiter
highlight default link TSPunctBracket Delimiter
highlight default link TSPunctSpecial Delimiter
highlight default link TSConstant Constant
highlight default link TSConstBuiltin Special
highlight default link TSConstMacro Define
highlight default link TSString String
highlight default link TSStringRegex String
highlight default link TSStringEscape SpecialChar
highlight default link TSCharacter Character
highlight default link TSNumber Number
highlight default link TSBoolean Boolean
highlight default link TSFloat 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
"#define" @constant.macro
"#else" @keyword
"#endif" @keyword
"#if" @keyword
"#ifdef" @keyword
"#ifndef" @keyword
"#include" @keyword
(preproc_directive) @keyword
[
"#if"
"#ifdef"
"#ifndef"
"#else"
"#elif"
"#endif"
"#include"
(preproc_directive)
] @keyword
"--" @operator
"-" @operator
"-=" @operator
"->" @operator
"!=" @operator
"*" @operator
"/" @operator
"&" @operator
"&&" @operator
"+" @operator
"++" @operator
"+=" @operator
"<" @operator
"<=" @operator
"==" @operator
"=" @operator
"~" @operator
">" @operator
">=" @operator
"!" @operator
"||" @operator
"." @delimiter
";" @delimiter
"-=" @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
(string_literal) @string
(system_lib_string) @string
@ -64,6 +87,8 @@
declarator: (identifier) @function)
(preproc_function_def
name: (identifier) @function.macro)
(preproc_arg) @function.macro
; TODO (preproc_arg) @embedded
(field_identifier) @property
(statement_identifier) @label
@ -71,7 +96,20 @@
(primitive_type) @type
(sized_type_specifier) @type
((identifier) @type
(#match? @type "^[A-Z]"))
((identifier) @constant
(match? @constant "^[A-Z][A-Z\\d_]+$"))
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
(comment) @comment
;; Parameters
(parameter_list
(parameter_declaration) @parameter)
(preproc_params
(identifier)) @parameter
(ERROR) @error

View file

@ -17,7 +17,7 @@
(declaration
declarator: (identifier) @definition.var)
(enum_specifier
name: (*) @definition.type
name: (_) @definition.type
(enumerator_list
(enumerator name: (identifier) @definition.var)))
@ -36,3 +36,4 @@
(while_statement) @scope
(translation_unit) @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
"@charset" @keyword
"@namespace" @keyword
"@supports" @keyword
"@keyframes" @keyword
(at_keyword) @keyword
(to) @keyword
(from) @keyword
(important) @keyword
[
"@media"
"@import"
"@charset"
"@namespace"
"@supports"
"@keyframes"
(at_keyword)
(to)
(from)
(important)
] @keyword
(comment) @comment
(tag_name) @type
(nesting_selector) @type
(universal_selector) @type
[
(tag_name)
(nesting_selector)
(universal_selector)
] @type
(function_name) @function
"~" @operator
">" @operator
"+" @operator
"-" @operator
"*" @operator
"/" @operator
"=" @operator
"^=" @operator
"|=" @operator
"~=" @operator
"$=" @operator
"*=" @operator
[
"~"
">"
"+"
"-"
"*"
"/"
"="
"^="
"|="
"~="
"$="
"*="
"and"
"or"
"not"
"only"
] @operator
"and" @operator
"or" @operator
"not" @operator
"only" @operator
(attribute_selector (plain_value) @string)
(pseudo_element_selector (tag_name) @property)
(pseudo_class_selector (class_name) @property)
(class_name) @property
(id_name) @property
(namespace_name) @property
(property_name) @property
(feature_name) @property
(attribute_name) @property
[
(class_name)
(id_name)
(namespace_name)
(property_name)
(feature_name)
(attribute_name)
] @property
((property_name) @type
(match? @type "^--"))
(#match? @type "^--"))
((plain_value) @type
(match? @type "^--"))
(#match? @type "^--"))
(string_value) @string
(color_value) @string
(identifier) @string
[
(string_value)
(color_value)
(identifier)
(unit)
] @string
(integer_value) @number
(float_value) @number
(unit) @string
[
(integer_value)
(float_value)
] @number
"#" @punctuation.delimiter
"," @punctuation.delimiter
"." @punctuation.delimiter
":" @punctuation.delimiter
"::" @punctuation.delimiter
";" @punctuation.delimiter
"{" @punctuation.bracket
")" @punctuation.bracket
"(" @punctuation.bracket
"}" @punctuation.bracket
[
"#"
","
"."
":"
"::"
";"
] @punctuation.delimiter
[
"{"
")"
"("
"}"
] @punctuation.bracket
(ERROR) @error

View file

@ -8,8 +8,9 @@
"=" @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
; Copyright (c) 2016 Max Brunsfeld
; Reset highlighing in f-string interpolations
(interpolation) @Normal
; Identifier naming conventions
((import_from_statement
name: (dotted_name
(identifier)) @type)
(match? @type "^[A-Z]"))
((identifier) @type
(match? @type "^[A-Z]"))
((identifier) @constant
(match? @constant "^[A-Z][A-Z_]*$"))
(match? @constant "^[A-Z][A-Z_0-9]*$"))
((identifier) @constant.builtin
(match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
; Function calls
(decorator) @function
((decorator (dotted_name (identifier) @function))
(match? @function "^([A-Z])@!.*$"))
(call
function: (identifier) @function)
(call
function: (attribute
attribute: (identifier) @method))
(call
function: (identifier) @function)
((call
function: (identifier) @constructor)
(match? @constructor "^[A-Z]"))
((call
(identifier) @constructor)
function: (attribute
attribute: (identifier) @constructor))
(match? @constructor "^[A-Z]"))
;; Builtin functions
@ -43,9 +48,8 @@
(function_definition
name: (identifier) @function)
(identifier) @variable
(attribute attribute: (identifier) @property)
(type (identifier) @type)
((call
function: (identifier) @isinstance
arguments: (argument_list
@ -74,8 +78,7 @@
; Literals
(none) @constant.builtin
(true) @boolean
(false) @boolean
[(true) (false)] @boolean
((identifier) @constant.builtin
(match? @constant.builtin "self"))
@ -84,90 +87,85 @@
(comment) @comment
(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
"{" @punctuation.special
"}" @punctuation.special) @embedded
; Tokens
[ "," "." ":" ] @punctuation.delimiter
"-" @operator
"->" @operator
"-=" @operator
"!=" @operator
"*" @operator
"**" @operator
"**=" @operator
"*=" @operator
"/" @operator
"//" @operator
"//=" @operator
"/=" @operator
"&" @operator
"%" @operator
"%=" @operator
"^" @operator
"+" @operator
"+=" @operator
"<" @operator
"<<" @operator
"<=" @operator
"<>" @operator
"=" @operator
"==" @operator
">" @operator
">=" @operator
">>" @operator
"|" @operator
"~" @operator
"and" @operator
"in" @operator
"is" @operator
"not" @operator
"or" @operator
; Keywords
"as" @include
"assert" @keyword
"async" @keyword
"await" @keyword
"break" @repeat
"class" @keyword
"continue" @repeat
"def" @keyword
"del" @keyword
"elif" @conditional
"else" @conditional
"except" @keyword
"exec" @keyword
"finally" @keyword
"for" @repeat
"from" @include
"global" @keyword
"if" @conditional
"import" @include
"lambda" @keyword
"nonlocal" @keyword
"pass" @keyword
"print" @keyword
"raise" @keyword
"return" @keyword
"try" @keyword
"while" @repeat
"with" @keyword
"yield" @keyword
; Additions for nvim-treesitter
"(" @punctuation.bracket
")" @punctuation.bracket
"[" @punctuation.bracket
"]" @punctuation.bracket
"," @punctuation.delimiter
"." @punctuation.delimiter
":" @punctuation.delimiter
; Class definitions
(class_definition
name: (identifier) @type)
@ -175,35 +173,17 @@
superclasses: (argument_list
(identifier) @type))
(attribute
((attribute
attribute: (identifier) @field)
((attribute
attribute: (identifier) @constant)
(match? @constant "^[A-Z][A-Z_]*$"))
((attribute
attribute: (identifier) @type)
(match? @type "^[A-Z][a-z_]+"))
((attribute
object: (identifier) @type)
(match? @type "^[A-Z][a-z_]+"))
(class_definition
body: (block
(expression_statement
(assignment
left: (expression_list
(identifier) @field)))))
(match? @field "^([A-Z])@!.*$"))
((class_definition
body: (block
(expression_statement
(assignment
left: (expression_list
(identifier) @constant)))))
(match? @constant "^[A-Z][A-Z_]*$"))
(identifier) @field)))))
(match? @field "^([A-Z])@!.*$"))
;; Error
(ERROR) @error

View file

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

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

View file

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

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)