mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-15 09:50:04 -04:00
commit
73ea03fb8d
21 changed files with 1422 additions and 171 deletions
99
CONTRIBUTING.md
Normal file
99
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Contributing to `nvim-treesitter`
|
||||||
|
|
||||||
|
First of all, thank you very much for contributing to `nvim-treesitter`.
|
||||||
|
|
||||||
|
If you haven't already, you should really come and reach out to us on our [gitter](https://gitter.im/nvim-treesitter/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link)
|
||||||
|
room, so we can help you with any question you might have!
|
||||||
|
|
||||||
|
As you know, `nvim-treesitter` is roughly splitted in two parts :
|
||||||
|
- Parser configurations : for various things like `locals`, `highlights`
|
||||||
|
- What we like to call *modules* : tiny lua modules that provide a given feature, based on parser configurations
|
||||||
|
|
||||||
|
Depending on which part of the plugin you want to contribute to, please read the appropriate section.
|
||||||
|
|
||||||
|
## Parser configurations
|
||||||
|
|
||||||
|
Contributing to parser configurations is basically modifying one of the `queries/*/*.scm`.
|
||||||
|
Each of these `scheme` files contains a *tree-sitter query* for a given purpose.
|
||||||
|
Before going any further, we highly suggest that you [read more about tree-sitter queries](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries).
|
||||||
|
|
||||||
|
Each query has an appropriate name, which is then used by modules to extract data from the syntax tree.
|
||||||
|
For now two types of queries are used by `nvim-treesitter`:
|
||||||
|
- `highlights.scm` : used for syntax highlighting, using the `highlight` module.
|
||||||
|
- `locals.scm` : used to extract keyword definitions, scopes, references,... using the `locals` module.
|
||||||
|
|
||||||
|
For both of these types there is a *norm* you will have to follow so that features work fine.
|
||||||
|
Here are some global advices :
|
||||||
|
- If your language is listed [here](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries),
|
||||||
|
you can debug and experiment with your queries there.
|
||||||
|
- If not, you should consider installing the [tree-sitter cli](https://github.com/tree-sitter/tree-sitter/tree/master/cli),
|
||||||
|
you should then be able to open a local playground using `tree-sitter build-wasm && tree-sitter web-ui` within the
|
||||||
|
parsers repo.
|
||||||
|
|
||||||
|
### Highlights
|
||||||
|
|
||||||
|
As languages differ quite a lot, here is a set of captures available to you when building a `highlights.scm` query.
|
||||||
|
One important thing to note is that many of these capture groups are not supported by `neovim` for now, and will not have any
|
||||||
|
effect on highlighting. We will work on improving highlighting in the near future though.
|
||||||
|
|
||||||
|
#### Misc
|
||||||
|
`@comment`
|
||||||
|
`@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`
|
||||||
|
|
||||||
|
#### Constants
|
||||||
|
`@constant`
|
||||||
|
`builtin`
|
||||||
|
`macro`
|
||||||
|
`@string`
|
||||||
|
`regex`
|
||||||
|
`escape`
|
||||||
|
`@character`
|
||||||
|
`@number`
|
||||||
|
`@boolean`
|
||||||
|
`@float`
|
||||||
|
|
||||||
|
#### Functions
|
||||||
|
`@function`
|
||||||
|
`builtin`
|
||||||
|
`macro`
|
||||||
|
`@parameter`
|
||||||
|
|
||||||
|
`@method`
|
||||||
|
`@field` or `@property`
|
||||||
|
|
||||||
|
`@constructor`
|
||||||
|
|
||||||
|
#### Keywords
|
||||||
|
`@conditional`
|
||||||
|
`@repeat`
|
||||||
|
`@label` for C/Lua-like labels
|
||||||
|
`@operator`
|
||||||
|
`@keyword`
|
||||||
|
`@exception`
|
||||||
|
|
||||||
|
`@type`
|
||||||
|
`builtin`
|
||||||
|
`@structure`
|
||||||
|
|
||||||
|
### Locals
|
||||||
|
|
||||||
|
`@definition` for various definitions
|
||||||
|
`function`
|
||||||
|
`method`
|
||||||
|
`var`
|
||||||
|
`macro`
|
||||||
|
`type`
|
||||||
|
|
||||||
|
`@scope`
|
||||||
|
|
||||||
|
`@reference`
|
||||||
|
|
||||||
96
README.md
96
README.md
|
|
@ -11,7 +11,7 @@ Treesitter configurations and abstraction layer for Neovim.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
You can install `nvim-treesitter` with your favorite package manager, or using the default `pack` feature of neovim !
|
You can install `nvim-treesitter` with your favorite package manager, or using the default `pack` feature of Neovim!
|
||||||
|
|
||||||
### Using a package manager
|
### Using a package manager
|
||||||
|
|
||||||
|
|
@ -79,19 +79,101 @@ bash [✗] not installed
|
||||||
tsx [✗] not installed
|
tsx [✗] not installed
|
||||||
```
|
```
|
||||||
|
|
||||||
And now you should be able to use every functionnality `nvim-treesitter` provides !
|
And now you should be able to use every functionality `nvim-treesitter` provides!
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
in your `init.vim`:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
lua <<EOF
|
||||||
|
require'nvim-treesitter.configs'.setup {
|
||||||
|
highlight = {
|
||||||
|
enable = true, -- false will disable the whole extension
|
||||||
|
disable = { 'c', 'rust' }, -- list of language that will be disabled
|
||||||
|
},
|
||||||
|
incremental_selection = { -- this enables incremental selection
|
||||||
|
enable = true,
|
||||||
|
disable = { 'cpp', 'lua' },
|
||||||
|
keymaps = { -- mappings for incremental selection (visual mappings)
|
||||||
|
node_incremental = "<leader>e", -- "grn" by default,
|
||||||
|
scope_incremental = "<leader>f" -- "grc" by default
|
||||||
|
}
|
||||||
|
},
|
||||||
|
node_movement = { -- this enables cursor movement in node hierarchy
|
||||||
|
enable = true,
|
||||||
|
disable = { 'cpp', 'rust' },
|
||||||
|
keymaps = { -- mappings for node movement (normal mappings)
|
||||||
|
move_up = "<a-k>", -- default is to move with alt key hold
|
||||||
|
move_down = "<a-j>",
|
||||||
|
move_left = "<a-h>",
|
||||||
|
move_right = "<a-l>",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensure_installed = 'all' -- one of 'all', 'language', or a list of languages
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
Each feature can be enabled or disabled by different means:
|
||||||
|
```vim
|
||||||
|
:TSBufEnable {module} " enable module on current buffer
|
||||||
|
:TSBufDisable {module} " disable module on current buffer
|
||||||
|
:TSEnableAll {module} [{ft}] " enable module on every buffer. If filetype is specified, enable only for this filetype.
|
||||||
|
:TSDisableAll {module} [{ft}] " disable module on every buffer. If filetype is specified, disable only for this filetype.
|
||||||
|
:TSModuleInfo [{module}] " list information about modules state for each filetype
|
||||||
|
```
|
||||||
|
|
||||||
## Features and Roadmap
|
## Features and Roadmap
|
||||||
|
|
||||||
The goal of `nvim-treesitter` is both to provide a simple and easy way to use the interface for treesitter in neovim,
|
The goal of `nvim-treesitter` is both to provide a simple and easy way to use the interface for Treesitter in Neovim,
|
||||||
but also to add some functionnalities to it:
|
but also to add some functionalities to it:
|
||||||
Some of these features are :
|
Some of these features are :
|
||||||
- [ ] Incremental selection
|
- [x] Incremental selection
|
||||||
- [ ] Syntax based code folding
|
- [ ] Syntax based code folding
|
||||||
- [ ] Consistent syntax highlighting
|
- [x] Consistent syntax highlighting (the api is not quite stable yet)
|
||||||
|
- [x] Cursor movement in node hierachy
|
||||||
|
- [x] Statusline indicator (`require'nvim-treesitter'.statusline(size)`)
|
||||||
|
|
||||||
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 apreciated !
|
The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated!
|
||||||
|
|
||||||
|
## Supported Languages
|
||||||
|
|
||||||
|
For treesitter to work, we need to use query files such as those you can find in `queries/{lang}/{locals,highlights}.scm`
|
||||||
|
|
||||||
|
We are looking for maintainers to write query files for their languages.
|
||||||
|
|
||||||
|
List of currently supported languages:
|
||||||
|
- [x] lua (maintained by @vigoux)
|
||||||
|
- [x] ruby (maintained by @TravonteD)
|
||||||
|
- [ ] c
|
||||||
|
- [ ] go
|
||||||
|
- [ ] cpp
|
||||||
|
- [ ] rust
|
||||||
|
- [ ] python
|
||||||
|
- [ ] javascript
|
||||||
|
- [ ] typescript
|
||||||
|
- [ ] tsx
|
||||||
|
- [ ] json
|
||||||
|
- [ ] html
|
||||||
|
- [ ] csharp
|
||||||
|
- [ ] swift
|
||||||
|
- [ ] java
|
||||||
|
- [ ] ocaml
|
||||||
|
- [ ] css
|
||||||
|
- [ ] julia
|
||||||
|
- [ ] php
|
||||||
|
- [ ] bash
|
||||||
|
- [ ] scala
|
||||||
|
- [ ] haskell
|
||||||
|
- [ ] toml
|
||||||
|
- [ ] vue
|
||||||
|
- [ ] elm
|
||||||
|
- [ ] yaml
|
||||||
|
- [ ] nix
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
|
||||||
3
autoload/nvim_treesitter.vim
Normal file
3
autoload/nvim_treesitter.vim
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
function! nvim_treesitter#statusline(len)
|
||||||
|
return luaeval("require'nvim-treesitter'.statusline(_A)", a:len)
|
||||||
|
endfunction
|
||||||
112
doc/nvim-treesitter.txt
Normal file
112
doc/nvim-treesitter.txt
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
*nvim-treesitter*
|
||||||
|
|
||||||
|
Minimum version of neovim: nightly
|
||||||
|
|
||||||
|
Authors: Yazdani Kiyan <yazdani.kiyan@protonmail.com>, Vigouroux Thomas <tomvig38@gmail.com>
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
INTRODUCTION *nvim-treesitter-intro*
|
||||||
|
|
||||||
|
nvim-treesitter wraps the neovim treesitter api to provide functionnalities such
|
||||||
|
as highlighting and incremental selection, and a command to easily install parsers.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
QUICK START *nvim-treesitter-quickstart*
|
||||||
|
|
||||||
|
Install the parser for your language
|
||||||
|
|
||||||
|
>
|
||||||
|
:TSInstall {language}
|
||||||
|
<
|
||||||
|
|
||||||
|
To get a list of supported languages
|
||||||
|
|
||||||
|
>
|
||||||
|
:TSInstallInfo
|
||||||
|
<
|
||||||
|
|
||||||
|
By default, everything is disabled. To enable support for features, in your `init.vim`:
|
||||||
|
|
||||||
|
>
|
||||||
|
lua <<EOF
|
||||||
|
require'nvim-treesitter.configs'.setup {
|
||||||
|
highlight = {
|
||||||
|
enable = true, -- false will disable the whole extension
|
||||||
|
disable = { 'c', 'rust' }, -- list of language that will be disabled
|
||||||
|
},
|
||||||
|
incremental_selection = { -- this enables incremental selection
|
||||||
|
enable = true,
|
||||||
|
disable = { 'cpp', 'lua' },
|
||||||
|
keymaps = { -- mappings for incremental selection (visual mappings)
|
||||||
|
node_incremental = "<leader>e", -- "grn" by default,
|
||||||
|
scope_incremental = "<leader>f" -- "grc" by default
|
||||||
|
}
|
||||||
|
},
|
||||||
|
node_movement = { -- this cursor movement in node hierachy
|
||||||
|
enable = true,
|
||||||
|
disable = { 'cpp', 'rust' },
|
||||||
|
keymaps = { -- mappings for node movement (normal mappings)
|
||||||
|
move_up = "<a-k>", -- default is to move with alt key hold
|
||||||
|
move_down = "<a-j>",
|
||||||
|
move_left = "<a-h>",
|
||||||
|
move_right = "<a-l>",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ensure_installed = 'all' -- one of 'all', 'language', or a list of languages
|
||||||
|
}
|
||||||
|
<
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
COMMANDS *nvim-treesitter-commands*
|
||||||
|
|
||||||
|
|:TSInstall| {language} *:TSInstall*
|
||||||
|
|
||||||
|
Download, compile and install a parser for {language}
|
||||||
|
|
||||||
|
|:TSInstallInfo| *:TSInstallInfo*
|
||||||
|
|
||||||
|
List informations about currently installed parsers
|
||||||
|
|
||||||
|
|:TSBufEnable| {module} *:TSBufEnable*
|
||||||
|
|
||||||
|
Enable {module} on the current buffer.
|
||||||
|
A list of modules can be found at |:TSModuleInfo|
|
||||||
|
|
||||||
|
|:TSBufDisable| {module} *:TSBufDisable*
|
||||||
|
|
||||||
|
Disable {module} on the current buffer
|
||||||
|
A list of modules can be found at |:TSModuleInfo|
|
||||||
|
|
||||||
|
|:TSBufEnableAll| {module} [{language}] *:TSBufEnableAll*
|
||||||
|
|
||||||
|
Enable {module} for the session
|
||||||
|
if {language} is specified, enable module for the session only for this
|
||||||
|
particular language.
|
||||||
|
A list of modules can be found at |:TSModuleInfo|
|
||||||
|
A list of languages can be found at |:TSInstallInfo|
|
||||||
|
|
||||||
|
|:TSBufDisableAll| {module} [{language}] *:TSBufDisableAll*
|
||||||
|
|
||||||
|
Disable {module} for the session
|
||||||
|
if {language} is specified, disable module for the session only for this
|
||||||
|
particular language.
|
||||||
|
A list of modules can be found at |:TSModuleInfo|
|
||||||
|
A list of languages can be found at |:TSInstallInfo|
|
||||||
|
|
||||||
|
|:TSModuleInfo| [{module}] *:TSModuleInfo*
|
||||||
|
|
||||||
|
List modules state for the current session.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
FUNCTIONS~
|
||||||
|
*nvim-treesitter-functions*
|
||||||
|
|
||||||
|
|nvim_treesitter#statusline(size)|
|
||||||
|
*nvim_treesitter#statusline()*
|
||||||
|
|
||||||
|
Returns a string describing the current position in the syntax tree. This
|
||||||
|
could be used as a statusline indicator.
|
||||||
|
Note: The `size` argument is optionnal. When specified, the string will not be
|
||||||
|
longer than `size`.
|
||||||
|
|
||||||
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
13
doc/tags
Normal file
13
doc/tags
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
:TSBufDisable nvim-treesitter.txt /*:TSBufDisable*
|
||||||
|
:TSBufDisableAll nvim-treesitter.txt /*:TSBufDisableAll*
|
||||||
|
:TSBufEnable nvim-treesitter.txt /*:TSBufEnable*
|
||||||
|
:TSBufEnableAll nvim-treesitter.txt /*:TSBufEnableAll*
|
||||||
|
:TSInstall nvim-treesitter.txt /*:TSInstall*
|
||||||
|
:TSInstallInfo nvim-treesitter.txt /*:TSInstallInfo*
|
||||||
|
:TSModuleInfo nvim-treesitter.txt /*:TSModuleInfo*
|
||||||
|
nvim-treesitter nvim-treesitter.txt /*nvim-treesitter*
|
||||||
|
nvim-treesitter-commands nvim-treesitter.txt /*nvim-treesitter-commands*
|
||||||
|
nvim-treesitter-functions nvim-treesitter.txt /*nvim-treesitter-functions*
|
||||||
|
nvim-treesitter-intro nvim-treesitter.txt /*nvim-treesitter-intro*
|
||||||
|
nvim-treesitter-quickstart nvim-treesitter.txt /*nvim-treesitter-quickstart*
|
||||||
|
nvim_treesitter#statusline() nvim-treesitter.txt /*nvim_treesitter#statusline()*
|
||||||
|
|
@ -1,30 +1,58 @@
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
local parsers = require'nvim-treesitter.parsers'
|
|
||||||
local configs = require 'nvim-treesitter.configs'
|
|
||||||
local install = require'nvim-treesitter.install'
|
local install = require'nvim-treesitter.install'
|
||||||
local locals = require'nvim-treesitter.locals'
|
local locals = require'nvim-treesitter.locals'
|
||||||
local highlight = require'nvim-treesitter.highlight'
|
local utils = require'nvim-treesitter.utils'
|
||||||
|
local info = require'nvim-treesitter.info'
|
||||||
|
local configs = require'nvim-treesitter.configs'
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M.available_parsers()
|
|
||||||
return vim.tbl_keys(configs.repositories)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This function sets up everythin needed for a given language
|
-- This function sets up everythin needed for a given language
|
||||||
-- this is the main interface through the plugin
|
-- this is the main interface through the plugin
|
||||||
function M.setup(lang)
|
function M.setup(lang)
|
||||||
if parsers.has_parser(lang) then
|
utils.setup_commands('install', install.commands)
|
||||||
local autocmd = "autocmd NvimTreesitter FileType %s lua require'nvim-treesitter.highlight'.setup()"
|
utils.setup_commands('info', info.commands)
|
||||||
api.nvim_command(string.format(autocmd, lang))
|
utils.setup_commands('configs', configs.commands)
|
||||||
|
|
||||||
|
for _, ft in pairs(configs.available_parsers()) do
|
||||||
|
for _, mod in pairs(configs.available_modules()) do
|
||||||
|
if configs.is_enabled(mod, ft) then
|
||||||
|
local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
|
||||||
|
api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This function initialize the plugin
|
function M.statusline(indicator_size)
|
||||||
-- it is run at startup
|
local indicator_size = indicator_size or 1000
|
||||||
M._root = {}
|
local expr = require"nvim-treesitter.utils".expression_at_point()
|
||||||
function M._root.setup()
|
local current_node =
|
||||||
install.setup()
|
require'nvim-treesitter.node_movement'.current_node[api.nvim_get_current_buf()]
|
||||||
|
|
||||||
|
local indicator = ""
|
||||||
|
while expr and (#indicator + #(expr:type()) + 5) < indicator_size do
|
||||||
|
|
||||||
|
local prefix = ""
|
||||||
|
if expr:parent() then
|
||||||
|
prefix = "->"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if expr == current_node then
|
||||||
|
indicator = string.format("%s[%s]%s", prefix, expr:type(), indicator)
|
||||||
|
else
|
||||||
|
indicator = prefix .. expr:type() .. indicator
|
||||||
|
end
|
||||||
|
|
||||||
|
expr = expr:parent()
|
||||||
|
end
|
||||||
|
|
||||||
|
if expr then
|
||||||
|
return "..." .. indicator
|
||||||
|
else
|
||||||
|
return indicator
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -1,88 +1,421 @@
|
||||||
local M = {}
|
local api = vim.api
|
||||||
|
local queries = require'nvim-treesitter.query'
|
||||||
|
local parser_utils = require'nvim-treesitter.parsers'
|
||||||
|
local parsers = {}
|
||||||
|
|
||||||
M.repositories = {
|
parsers.javascript = {
|
||||||
javascript = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
},
|
}
|
||||||
c = {
|
}
|
||||||
|
|
||||||
|
parsers.c = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-c",
|
url = "https://github.com/tree-sitter/tree-sitter-c",
|
||||||
files = { "src/parser.c" }
|
files = { "src/parser.c" }
|
||||||
},
|
}
|
||||||
cpp = {
|
}
|
||||||
|
|
||||||
|
parsers.cpp = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-cpp",
|
url = "https://github.com/tree-sitter/tree-sitter-cpp",
|
||||||
files = { "src/parser.c", "src/scanner.cc" }
|
files = { "src/parser.c", "src/scanner.cc" }
|
||||||
},
|
}
|
||||||
rust = {
|
}
|
||||||
|
|
||||||
|
parsers.rust = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
},
|
}
|
||||||
lua = {
|
}
|
||||||
|
|
||||||
|
parsers.lua = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
||||||
files = { "src/parser.c", "src/scanner.cc" }
|
files = { "src/parser.c", "src/scanner.cc" }
|
||||||
},
|
}
|
||||||
python = {
|
}
|
||||||
|
|
||||||
|
parsers.python = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-python",
|
url = "https://github.com/tree-sitter/tree-sitter-python",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
},
|
}
|
||||||
go = {
|
}
|
||||||
|
|
||||||
|
parsers.go = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-go",
|
url = "https://github.com/tree-sitter/tree-sitter-go",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
},
|
}
|
||||||
ruby = {
|
}
|
||||||
|
|
||||||
|
parsers.ruby = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
},
|
}
|
||||||
bash = {
|
}
|
||||||
|
|
||||||
|
parsers.bash = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-bash",
|
url = "https://github.com/tree-sitter/tree-sitter-bash",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
},
|
}
|
||||||
php = {
|
}
|
||||||
|
|
||||||
|
parsers.php = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-php",
|
url = "https://github.com/tree-sitter/tree-sitter-php",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
},
|
}
|
||||||
java = {
|
}
|
||||||
|
|
||||||
|
parsers.java = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-java",
|
url = "https://github.com/tree-sitter/tree-sitter-java",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
},
|
}
|
||||||
html = {
|
}
|
||||||
|
|
||||||
|
parsers.html = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-html",
|
url = "https://github.com/tree-sitter/tree-sitter-html",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
},
|
}
|
||||||
julia = {
|
}
|
||||||
|
|
||||||
|
parsers.julia = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
},
|
}
|
||||||
json = {
|
}
|
||||||
|
|
||||||
|
parsers.json = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-json",
|
url = "https://github.com/tree-sitter/tree-sitter-json",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
},
|
}
|
||||||
css = {
|
}
|
||||||
|
|
||||||
|
parsers.css = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-css",
|
url = "https://github.com/tree-sitter/tree-sitter-css",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
},
|
}
|
||||||
ocaml = {
|
}
|
||||||
|
|
||||||
|
parsers.ocaml = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
|
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
},
|
}
|
||||||
swift = {
|
}
|
||||||
|
|
||||||
|
parsers.swift = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
},
|
}
|
||||||
csharp = {
|
}
|
||||||
|
|
||||||
|
parsers.csharp = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
},
|
}
|
||||||
typescript = {
|
}
|
||||||
|
|
||||||
|
parsers.typescript = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
location = "tree-sitter-typescript/typescript"
|
location = "tree-sitter-typescript/typescript"
|
||||||
},
|
}
|
||||||
tsx = {
|
}
|
||||||
|
|
||||||
|
parsers.tsx = {
|
||||||
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
location = "tree-sitter-tsx/tsx"
|
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
|
||||||
|
-- @disable is a list of languages, only relevant if enable is true
|
||||||
|
-- @keymaps list of user mappings for a given module if relevant
|
||||||
|
-- @is_supported function which, given a ft, will return true if the ft works on the module
|
||||||
|
local config = {
|
||||||
|
modules = {
|
||||||
|
highlight = {
|
||||||
|
enable = false,
|
||||||
|
disable = {},
|
||||||
|
is_supported = function(ft)
|
||||||
|
return queries.get_query(ft, 'highlights') ~= nil
|
||||||
|
end
|
||||||
|
},
|
||||||
|
incremental_selection = {
|
||||||
|
enable = false,
|
||||||
|
disable = {},
|
||||||
|
keymaps = {
|
||||||
|
node_incremental="grn",
|
||||||
|
scope_incremental="grc"
|
||||||
|
},
|
||||||
|
is_supported = function() return true end
|
||||||
|
},
|
||||||
|
node_movement = {
|
||||||
|
enable = false,
|
||||||
|
disable = {},
|
||||||
|
is_supported = function() return true end,
|
||||||
|
keymaps = {
|
||||||
|
move_up = "<a-k>",
|
||||||
|
move_down = "<a-j>",
|
||||||
|
move_left = "<a-h>",
|
||||||
|
move_right = "<a-l>",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- folding = {
|
||||||
|
-- enable = false,
|
||||||
|
-- disable = {},
|
||||||
|
-- keymaps = {},
|
||||||
|
-- is_supported = function() return false end
|
||||||
|
-- }
|
||||||
|
},
|
||||||
|
ensure_installed = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local function enable_module(mod, bufnr, ft)
|
||||||
|
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
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
|
||||||
|
loaded_mod.attach(bufnr, ft)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function enable_mod_conf_autocmd(mod, ft)
|
||||||
|
if not config.modules[mod] or M.is_enabled(mod, ft) then return end
|
||||||
|
|
||||||
|
local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod)
|
||||||
|
api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd))
|
||||||
|
for i, parser in pairs(config.modules[mod].disable) do
|
||||||
|
if parser == ft then
|
||||||
|
table.remove(config.modules[mod].disable, i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function enable_all(mod, ft)
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ft then
|
||||||
|
if parser_utils.has_parser(ft) then
|
||||||
|
enable_mod_conf_autocmd(mod, ft)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _, ft in pairs(M.available_parsers()) do
|
||||||
|
if parser_utils.has_parser(ft) then
|
||||||
|
enable_mod_conf_autocmd(mod, ft)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
config.modules[mod].enable = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function disable_module(mod, bufnr, ft)
|
||||||
|
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
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local loaded_mod = require(string.format("nvim-treesitter.%s", mod))
|
||||||
|
loaded_mod.detach(bufnr, ft)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function disable_mod_conf_autocmd(mod, ft)
|
||||||
|
if not config.modules[mod] or not M.is_enabled(mod, ft) then return end
|
||||||
|
|
||||||
|
api.nvim_command(string.format("autocmd! FileType %s", ft))
|
||||||
|
table.insert(config.modules[mod].disable, ft)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function disable_all(mod, ft)
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ft then
|
||||||
|
disable_mod_conf_autocmd(mod, ft)
|
||||||
|
else
|
||||||
|
for _, ft in pairs(M.available_parsers()) do
|
||||||
|
disable_mod_conf_autocmd(mod, ft)
|
||||||
|
end
|
||||||
|
config.modules[mod].enable = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.commands = {
|
||||||
|
TSBufEnable = {
|
||||||
|
run = enable_module,
|
||||||
|
args = {
|
||||||
|
"-nargs=1",
|
||||||
|
"-complete=custom,v:lua.ts_available_modules"
|
||||||
|
},
|
||||||
|
description = '`:TSBufEnable module_name` enable a specified module on the current buffer'
|
||||||
|
},
|
||||||
|
TSBufDisable = {
|
||||||
|
run = disable_module,
|
||||||
|
args = {
|
||||||
|
"-nargs=1",
|
||||||
|
"-complete=custom,v:lua.ts_available_modules"
|
||||||
|
},
|
||||||
|
description = '`:TSBufDisable module_name` disable a specified module on the current buffer'
|
||||||
|
},
|
||||||
|
TSEnableAll = {
|
||||||
|
run = enable_all,
|
||||||
|
args = {
|
||||||
|
"-nargs=+",
|
||||||
|
"-complete=custom,v:lua.ts_available_modules"
|
||||||
|
},
|
||||||
|
description = '`:TSEnableAll module_name (filetype)` enables a specified module on all buffers. If filetype is specified, enable only for specified filetype'
|
||||||
|
},
|
||||||
|
TSDisableAll = {
|
||||||
|
run = disable_all,
|
||||||
|
args = {
|
||||||
|
"-nargs=+",
|
||||||
|
"-complete=custom,v:lua.ts_available_modules"
|
||||||
|
},
|
||||||
|
description = '`:TSDisableAll module_name (filetype)` disables a specified module on all buffers. If filetype is specified, disable only for specified filetype'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- @param mod: module (string)
|
||||||
|
-- @param ft: filetype (string)
|
||||||
|
function M.is_enabled(mod, ft)
|
||||||
|
if not M.get_parser_configs()[ft] or not parser_utils.has_parser(ft) 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
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, parser in pairs(module_config.disable) do
|
||||||
|
if ft == parser then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.setup(user_data)
|
||||||
|
if not user_data then return end
|
||||||
|
|
||||||
|
for mod, data in pairs(user_data) do
|
||||||
|
if config.modules[mod] then
|
||||||
|
if type(data.enable) == 'boolean' then
|
||||||
|
config.modules[mod].enable = data.enable
|
||||||
|
end
|
||||||
|
if type(data.disable) == 'table' then
|
||||||
|
config.modules[mod].disable = data.disable
|
||||||
|
end
|
||||||
|
if config.modules[mod].keymaps and type(data.keymaps) == 'table' then
|
||||||
|
config.modules[mod].keymaps = data.keymaps
|
||||||
|
end
|
||||||
|
elseif mod == 'ensure_installed' then
|
||||||
|
config.ensure_installed = data
|
||||||
|
require'nvim-treesitter/install'.ensure_installed(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get_parser_configs()
|
||||||
|
return parsers
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.available_parsers()
|
||||||
|
return vim.tbl_keys(parsers)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.available_modules()
|
||||||
|
return vim.tbl_keys(config.modules)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get_module(mod)
|
||||||
|
return config.modules[mod]
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,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 configs = require'nvim-treesitter.configs'
|
local configs = require'nvim-treesitter.configs'
|
||||||
|
|
||||||
local health_start = vim.fn["health#report_start"]
|
local health_start = vim.fn["health#report_start"]
|
||||||
|
|
@ -13,7 +14,7 @@ local health_error = vim.fn['health#report_error']
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local function configs_health()
|
local function install_health()
|
||||||
if fn.executable('git') == 0 then
|
if fn.executable('git') == 0 then
|
||||||
health_error('`git` executable not found.', {
|
health_error('`git` executable not found.', {
|
||||||
'Install it with your package manager.',
|
'Install it with your package manager.',
|
||||||
|
|
@ -34,15 +35,36 @@ local function configs_health()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function highlight_health(lang)
|
||||||
|
if not queries.get_query(lang, "highlights") then
|
||||||
|
health_warn("No `highlights.scm` query found for " .. lang, {
|
||||||
|
"Open an issue at https://github.com/nvim-treesitter/nvim-treesitter"
|
||||||
|
})
|
||||||
|
else
|
||||||
|
health_ok("`highlights.scm` found.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function locals_health(lang)
|
||||||
|
if not queries.get_query(lang, "locals") then
|
||||||
|
health_warn("No `locals.scm` query found for " .. lang, {
|
||||||
|
"Open an issue at https://github.com/nvim-treesitter/nvim-treesitter"
|
||||||
|
})
|
||||||
|
else
|
||||||
|
health_ok("`locals.scm` found.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- TODO(vigoux): Maybe we should move each check to be perform in its own module
|
-- TODO(vigoux): Maybe we should move each check to be perform in its own module
|
||||||
function M.checkhealth()
|
function M.checkhealth()
|
||||||
-- Installation dependency checks
|
-- Installation dependency checks
|
||||||
health_start('Installation')
|
health_start('Installation')
|
||||||
configs_health()
|
install_health()
|
||||||
|
|
||||||
local missing_parsers = {}
|
local missing_parsers = {}
|
||||||
-- Parser installation checks
|
-- Parser installation checks
|
||||||
for parser_name in pairs(configs.repositories) do
|
for _, parser_name in pairs(configs.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
|
||||||
|
|
@ -50,7 +72,8 @@ function M.checkhealth()
|
||||||
health_start(parser_name .. " parser healthcheck")
|
health_start(parser_name .. " parser healthcheck")
|
||||||
health_ok(parser_name .. " parser found.")
|
health_ok(parser_name .. " parser found.")
|
||||||
|
|
||||||
locals.checkhealth(parser_name)
|
locals_health(parser_name)
|
||||||
|
highlight_health(parser_name)
|
||||||
elseif installed > 1 then
|
elseif installed > 1 then
|
||||||
health_warn(string.format("Multiple parsers found for %s, only %s will be used.", parser_name, installed[1]))
|
health_warn(string.format("Multiple parsers found for %s, only %s will be used.", parser_name, installed[1]))
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,53 @@
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
local queries = require'nvim-treesitter.query'
|
|
||||||
local ts = vim.treesitter
|
local ts = vim.treesitter
|
||||||
|
local queries = require'nvim-treesitter.query'
|
||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
highlighters={}
|
highlighters = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function M.setup(bufnr, ft)
|
local hlmap = vim.treesitter.TSHighlighter.hl_map
|
||||||
|
|
||||||
|
-- Misc
|
||||||
|
hlmap.error = "Error"
|
||||||
|
hlmap["punctuation.delimiter"] = "Delimiter"
|
||||||
|
hlmap["punctuation.bracket"] = "Delimiter"
|
||||||
|
|
||||||
|
-- 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"
|
||||||
|
|
||||||
|
-- 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"
|
||||||
|
|
||||||
|
-- Keywords
|
||||||
|
hlmap["conditional"] = "Conditional"
|
||||||
|
hlmap["repeat"] = "Repeat"
|
||||||
|
hlmap["label"] = "Label"
|
||||||
|
hlmap["operator"] = "Operator"
|
||||||
|
hlmap["keyword"] = "Keyword"
|
||||||
|
hlmap["exception"] = "Exception"
|
||||||
|
|
||||||
|
hlmap["type"] = "Type"
|
||||||
|
hlmap["type.builtin"] = "Type"
|
||||||
|
hlmap["structure"] = "Structure"
|
||||||
|
|
||||||
|
function M.attach(bufnr, ft)
|
||||||
local buf = bufnr or api.nvim_get_current_buf()
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
local ft = ft or api.nvim_buf_get_option(buf, 'ft')
|
local ft = ft or api.nvim_buf_get_option(buf, 'ft')
|
||||||
|
|
||||||
|
|
@ -16,4 +57,13 @@ function M.setup(bufnr, ft)
|
||||||
M.highlighters[buf] = ts.TSHighlighter.new(query, buf, ft)
|
M.highlighters[buf] = ts.TSHighlighter.new(query, buf, ft)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.detach(bufnr)
|
||||||
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
|
if M.highlighters[buf] then
|
||||||
|
M.highlighters[buf]:set_query("")
|
||||||
|
M.highlighters[buf] = nil
|
||||||
|
end
|
||||||
|
api.nvim_buf_set_option(buf, 'syntax', 'on')
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
78
lua/nvim-treesitter/incremental_selection.lua
Normal file
78
lua/nvim-treesitter/incremental_selection.lua
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
local api = vim.api
|
||||||
|
local utils = require'nvim-treesitter.utils'
|
||||||
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local function node_range_to_vim(node)
|
||||||
|
if not node then return end
|
||||||
|
|
||||||
|
local start_row, start_col, end_row, end_col = node:range()
|
||||||
|
|
||||||
|
local select_range = [[
|
||||||
|
call cursor(%d, %d)
|
||||||
|
normal v
|
||||||
|
call cursor(%d, %d)
|
||||||
|
]]
|
||||||
|
local exec_command = string.format(select_range,
|
||||||
|
start_row+1, start_col+1,
|
||||||
|
end_row+1, end_col+1)
|
||||||
|
|
||||||
|
api.nvim_exec(exec_command, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function select_incremental(increment_func)
|
||||||
|
return function()
|
||||||
|
local buf, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<"))
|
||||||
|
local buf, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>"))
|
||||||
|
|
||||||
|
local node = nil
|
||||||
|
if parsers.has_parser() then
|
||||||
|
local root = parsers.get_parser():parse():root()
|
||||||
|
node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col)
|
||||||
|
local node_start_row, node_start_col, node_end_row, node_end_col = node:range()
|
||||||
|
|
||||||
|
if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col
|
||||||
|
and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then
|
||||||
|
node = increment_func(node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return node_range_to_vim(node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.node_incremental = select_incremental(function(node)
|
||||||
|
if node then
|
||||||
|
return node:parent() or node
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
M.scope_incremental = select_incremental(function(node)
|
||||||
|
if node then
|
||||||
|
return utils.smallest_containing_scope(node:parent() or node)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
function M.attach(bufnr)
|
||||||
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
|
|
||||||
|
local config = require'nvim-treesitter.configs'.get_module('incremental_selection')
|
||||||
|
for funcname, mapping in pairs(config.keymaps) do
|
||||||
|
api.nvim_buf_set_keymap(buf, 'v', mapping,
|
||||||
|
string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname), { silent = true })
|
||||||
|
api.nvim_buf_set_keymap(buf, 'o', mapping,
|
||||||
|
string.format(":normal v%s<CR>", mapping), { silent = true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.detach(bufnr)
|
||||||
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
|
|
||||||
|
local config = require'nvim-treesitter.configs'.get_module('incremental_selection')
|
||||||
|
for _, mapping in pairs(config.keymaps) do
|
||||||
|
api.nvim_buf_del_keymap(buf, 'v', mapping)
|
||||||
|
api.nvim_buf_del_keymap(buf, 'o', mapping)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
96
lua/nvim-treesitter/info.lua
Normal file
96
lua/nvim-treesitter/info.lua
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
local api = vim.api
|
||||||
|
local configs = require'nvim-treesitter.configs'
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local function install_info()
|
||||||
|
local max_len = 0
|
||||||
|
for _, ft in pairs(configs.available_parsers()) do
|
||||||
|
if #ft > max_len then max_len = #ft end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, ft in pairs(configs.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
|
||||||
|
api.nvim_out_write("[✓] installed\n")
|
||||||
|
else
|
||||||
|
api.nvim_out_write("[✗] not installed\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function print_info_module(sorted_filetypes, mod)
|
||||||
|
local max_str_len = #sorted_filetypes[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
|
||||||
|
api.nvim_out_write('✓')
|
||||||
|
else
|
||||||
|
api.nvim_out_write('✗')
|
||||||
|
end
|
||||||
|
api.nvim_out_write('\n')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function print_info_modules(sorted_filetypes)
|
||||||
|
local max_str_len = #sorted_filetypes[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 _, 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
|
||||||
|
api.nvim_out_write('✓')
|
||||||
|
else
|
||||||
|
api.nvim_out_write('✗')
|
||||||
|
end
|
||||||
|
api.nvim_out_write(string.rep(' ', pad_len - 1))
|
||||||
|
end
|
||||||
|
api.nvim_out_write('\n')
|
||||||
|
end
|
||||||
|
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)
|
||||||
|
if mod then
|
||||||
|
print_info_module(ft_by_len, mod)
|
||||||
|
else
|
||||||
|
print_info_modules(ft_by_len)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.commands = {
|
||||||
|
TSInstallInfo = {
|
||||||
|
run = install_info,
|
||||||
|
args = {
|
||||||
|
"-nargs=0",
|
||||||
|
},
|
||||||
|
description = '`:TSInstallInfo` print installation state for every filetype'
|
||||||
|
},
|
||||||
|
TSModuleInfo = {
|
||||||
|
run = module_info,
|
||||||
|
args = {
|
||||||
|
"-nargs=?",
|
||||||
|
"-complete=custom,v:lua.ts_available_modules"
|
||||||
|
},
|
||||||
|
description = '`:TSModuleInfo` print module state for every filetype, if module is specified, only for current module'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
local fn = vim.fn
|
local fn = vim.fn
|
||||||
local luv = vim.loop
|
local luv = vim.loop
|
||||||
local repositories = require'nvim-treesitter/configs'.repositories
|
local configs = require'nvim-treesitter/configs'
|
||||||
|
local parsers = configs.get_parser_configs()
|
||||||
|
local has_parser = require'nvim-treesitter/parsers'.has_parser
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
|
@ -33,11 +35,13 @@ local function get_cache_dir()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function iter_cmd(cmd_list, i, ft)
|
local function iter_cmd(cmd_list, i, ft)
|
||||||
if i == #cmd_list then return print('Treesitter parser for '..ft..' has been installed') end
|
if i == #cmd_list + 1 then return print('Treesitter parser for '..ft..' has been installed') end
|
||||||
|
|
||||||
local attr = cmd_list[i + 1]
|
local attr = cmd_list[i]
|
||||||
if attr.info then print(attr.info) end
|
if attr.info then print(attr.info) end
|
||||||
|
|
||||||
|
local handle
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -75,12 +79,12 @@ local function run_install(cache_folder, package_path, ft, repo)
|
||||||
args = vim.tbl_flatten({
|
args = vim.tbl_flatten({
|
||||||
'-o',
|
'-o',
|
||||||
'parser.so',
|
'parser.so',
|
||||||
|
'-I./src',
|
||||||
|
repo.files,
|
||||||
'-shared',
|
'-shared',
|
||||||
|
'-Os',
|
||||||
'-lstdc++',
|
'-lstdc++',
|
||||||
'-fPIC',
|
'-fPIC',
|
||||||
'-Os',
|
|
||||||
'-I./src',
|
|
||||||
repo.files
|
|
||||||
}),
|
}),
|
||||||
cwd = compile_location
|
cwd = compile_location
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +103,7 @@ local function run_install(cache_folder, package_path, ft, repo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iter_cmd(command_list, 0, ft)
|
iter_cmd(command_list, 1, ft)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO(kyazdani): this should work on windows too
|
-- TODO(kyazdani): this should work on windows too
|
||||||
|
|
@ -118,14 +122,15 @@ local function install(ft)
|
||||||
if not string.match(yesno, '^y.*') then return end
|
if not string.match(yesno, '^y.*') then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
local repository = repositories[ft]
|
local parser_config = parsers[ft]
|
||||||
if not repository 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 '..ft)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local install_info = parser_config.install_info
|
||||||
vim.validate {
|
vim.validate {
|
||||||
url={ repository.url, 'string' },
|
url={ install_info.url, 'string' },
|
||||||
files={ repository.files, 'table' }
|
files={ install_info.files, 'table' }
|
||||||
}
|
}
|
||||||
|
|
||||||
if fn.executable('git') == 0 then
|
if fn.executable('git') == 0 then
|
||||||
|
|
@ -138,26 +143,27 @@ local function install(ft)
|
||||||
local cache_folder, err = get_cache_dir()
|
local cache_folder, err = get_cache_dir()
|
||||||
if err then return api.nvim_err_writeln(err) end
|
if err then return api.nvim_err_writeln(err) end
|
||||||
|
|
||||||
run_install(cache_folder, package_path, ft, repository)
|
run_install(cache_folder, package_path, ft, install_info)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function install_info()
|
|
||||||
local max_len = 0
|
M.ensure_installed = function(languages)
|
||||||
for parser_name, _ in pairs(repositories) do
|
if type(languages) == 'string' then
|
||||||
if #parser_name > max_len then max_len = #parser_name end
|
if languages == 'all' then
|
||||||
|
languages = configs.available_parsers()
|
||||||
|
else
|
||||||
|
languages = {languages}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for parser_name, _ in pairs(repositories) do
|
for _, ft in ipairs(languages) do
|
||||||
local is_installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false) > 0
|
if not has_parser(ft) then
|
||||||
api.nvim_out_write(parser_name..string.rep(' ', max_len - #parser_name + 1))
|
install(ft)
|
||||||
if is_installed then
|
|
||||||
api.nvim_out_write("[✓] installed\n")
|
|
||||||
else
|
|
||||||
api.nvim_out_write("[✗] not installed\n")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
M.commands = {
|
M.commands = {
|
||||||
TSInstall = {
|
TSInstall = {
|
||||||
run = install,
|
run = install,
|
||||||
|
|
@ -166,25 +172,7 @@ M.commands = {
|
||||||
"-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 {ft}` installs a parser under nvim-treesitter/parser/{name}.so'
|
||||||
},
|
|
||||||
TSInstallInfo = {
|
|
||||||
run = install_info,
|
|
||||||
args = { "-nargs=0" },
|
|
||||||
description = '`:TSInstallInfo` print installation state for every filetype'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function M.setup()
|
|
||||||
for command_name, def in pairs(M.commands) do
|
|
||||||
local call_fn = string.format("lua require'nvim-treesitter.install'.commands.%s.run(<f-args>)", command_name)
|
|
||||||
local parts = vim.tbl_flatten({
|
|
||||||
"command!",
|
|
||||||
def.args,
|
|
||||||
command_name,
|
|
||||||
call_fn,
|
|
||||||
})
|
|
||||||
api.nvim_command(table.concat(parts, " "))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,6 @@ local M = {
|
||||||
locals={}
|
locals={}
|
||||||
}
|
}
|
||||||
|
|
||||||
function M.checkhealth(lang)
|
|
||||||
local health_start = vim.fn["health#report_start"]
|
|
||||||
local health_ok = vim.fn['health#report_ok']
|
|
||||||
local health_info = vim.fn['health#report_info']
|
|
||||||
local health_warn = vim.fn['health#report_warn']
|
|
||||||
local health_error = vim.fn['health#report_error']
|
|
||||||
|
|
||||||
if not queries.get_query(lang, "locals") then
|
|
||||||
health_warn("No `locals.scm` query found for " .. lang, {
|
|
||||||
"Open an issue at https://github.com/nvim-treesitter/nvim-treesitter"
|
|
||||||
})
|
|
||||||
else
|
|
||||||
health_ok("`locals.scm` found.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.collect_locals(bufnr)
|
function M.collect_locals(bufnr)
|
||||||
local ft = api.nvim_buf_get_option(bufnr, "ft")
|
local ft = api.nvim_buf_get_option(bufnr, "ft")
|
||||||
if not ft then return end
|
if not ft then return end
|
||||||
|
|
@ -69,7 +53,7 @@ function M.get_definitions(bufnr)
|
||||||
|
|
||||||
for _, loc in ipairs(locals) do
|
for _, loc in ipairs(locals) do
|
||||||
if loc.definition then
|
if loc.definition then
|
||||||
table.insert(defs, {definition=loc.definition, kind=loc.kind})
|
table.insert(defs, loc.definition)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -82,8 +66,8 @@ function M.get_scopes(bufnr)
|
||||||
local scopes = {}
|
local scopes = {}
|
||||||
|
|
||||||
for _, loc in ipairs(locals) do
|
for _, loc in ipairs(locals) do
|
||||||
if loc.scope then
|
if loc.scope and loc.scope.node then
|
||||||
table.insert(scopes, loc.scope)
|
table.insert(scopes, loc.scope.node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -96,8 +80,8 @@ function M.get_references(bufnr)
|
||||||
local refs = {}
|
local refs = {}
|
||||||
|
|
||||||
for _, loc in ipairs(locals) do
|
for _, loc in ipairs(locals) do
|
||||||
if loc.reference then
|
if loc.reference and loc.reference.node then
|
||||||
table.insert(refs, loc.reference)
|
table.insert(refs, loc.reference.node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
91
lua/nvim-treesitter/node_movement.lua
Normal file
91
lua/nvim-treesitter/node_movement.lua
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
local api = vim.api
|
||||||
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
local utils = require'nvim-treesitter.utils'
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
|
||||||
|
M.NodeMovementKind = {
|
||||||
|
up = 'up',
|
||||||
|
down = 'down',
|
||||||
|
left = 'left',
|
||||||
|
right = 'right',
|
||||||
|
}
|
||||||
|
|
||||||
|
M.current_node = {}
|
||||||
|
|
||||||
|
local function node_start_to_vim(node)
|
||||||
|
if not node then return end
|
||||||
|
|
||||||
|
local row, col = node:start()
|
||||||
|
local exec_command = string.format('call cursor(%d, %d)', row+1, col+1)
|
||||||
|
api.nvim_exec(exec_command, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
M.do_node_movement = function(kind)
|
||||||
|
local buf, line, col = unpack(vim.fn.getpos("."))
|
||||||
|
|
||||||
|
local current_node = M.current_node[buf]
|
||||||
|
|
||||||
|
if current_node then
|
||||||
|
local node_line, node_col = current_node:start()
|
||||||
|
if line-1 ~= node_line or col-1 ~= node_col then
|
||||||
|
current_node = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local destination_node
|
||||||
|
|
||||||
|
if parsers.has_parser() then
|
||||||
|
local root = parsers.get_parser():parse():root()
|
||||||
|
if not current_node then
|
||||||
|
current_node = root:named_descendant_for_range(line-1, col-1, line-1, col)
|
||||||
|
end
|
||||||
|
|
||||||
|
if kind == M.NodeMovementKind.up then
|
||||||
|
destination_node = current_node:parent()
|
||||||
|
elseif kind == M.NodeMovementKind.down then
|
||||||
|
if current_node:named_child_count() > 0 then
|
||||||
|
destination_node = current_node:named_child(0)
|
||||||
|
else
|
||||||
|
local next_node = utils.get_next_node(current_node)
|
||||||
|
if next_node and next_node:named_child_count() > 0 then
|
||||||
|
destination_node = next_node:named_child(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif kind == M.NodeMovementKind.left then
|
||||||
|
destination_node = utils.get_previous_node(current_node, true, true)
|
||||||
|
elseif kind == M.NodeMovementKind.right then
|
||||||
|
destination_node = utils.get_next_node(current_node, true, true)
|
||||||
|
end
|
||||||
|
M.current_node[buf] = destination_node or current_node
|
||||||
|
end
|
||||||
|
|
||||||
|
if destination_node then
|
||||||
|
node_start_to_vim(destination_node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.move_up = function() M.do_node_movement(M.NodeMovementKind.up) end
|
||||||
|
M.move_down = function() M.do_node_movement(M.NodeMovementKind.down) end
|
||||||
|
M.move_left = function() M.do_node_movement(M.NodeMovementKind.left) end
|
||||||
|
M.move_right = function() M.do_node_movement(M.NodeMovementKind.right) end
|
||||||
|
|
||||||
|
function M.attach(bufnr)
|
||||||
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
|
|
||||||
|
local config = require'nvim-treesitter.configs'.get_module('node_movement')
|
||||||
|
for funcname, mapping in pairs(config.keymaps) do
|
||||||
|
api.nvim_buf_set_keymap(buf, 'n', mapping,
|
||||||
|
string.format(":lua require'nvim-treesitter.node_movement'.%s()<CR>", funcname), { silent = true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.detach(bufnr)
|
||||||
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
|
|
||||||
|
local config = require'nvim-treesitter.configs'.get_module('node_movement')
|
||||||
|
for _, mapping in pairs(config.keymaps) do
|
||||||
|
api.nvim_buf_del_keymap(buf, 'n', mapping)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
@ -5,11 +5,12 @@ local M = {}
|
||||||
|
|
||||||
function M.has_parser(lang)
|
function M.has_parser(lang)
|
||||||
local lang = lang or api.nvim_buf_get_option(0, 'filetype')
|
local lang = lang or api.nvim_buf_get_option(0, 'filetype')
|
||||||
|
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)
|
||||||
if M.has_parser() then
|
if M.has_parser(lang) then
|
||||||
local buf = bufnr or api.nvim_get_current_buf()
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
local lang = lang or api.nvim_buf_get_option(buf, 'ft')
|
local lang = lang or api.nvim_buf_get_option(buf, 'ft')
|
||||||
if not M[buf] then
|
if not M[buf] then
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
-- Utils collection for nvim-treesitter
|
-- Utils collection for nvim-treesitter
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
local parsers = require'nvim-treesitter.parsers'
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
local locals = require'nvim-treesitter.locals'
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
|
@ -63,4 +64,92 @@ function M.is_parent(dest, source)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.setup_commands(mod, commands)
|
||||||
|
for command_name, def in pairs(commands) do
|
||||||
|
local call_fn = string.format("lua require'nvim-treesitter.%s'.commands.%s.run(<f-args>)", mod, command_name)
|
||||||
|
local parts = vim.tbl_flatten({
|
||||||
|
"command!",
|
||||||
|
def.args,
|
||||||
|
command_name,
|
||||||
|
call_fn,
|
||||||
|
})
|
||||||
|
api.nvim_command(table.concat(parts, " "))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets the smallest scope which contains @param node
|
||||||
|
function M.smallest_containing_scope(node, bufnr)
|
||||||
|
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||||
|
|
||||||
|
local root = parsers.get_parser(bufnr):parse():root()
|
||||||
|
if not node then return root end
|
||||||
|
|
||||||
|
local scopes = locals.get_scopes(bufnr)
|
||||||
|
local current = node
|
||||||
|
while current ~= nil and not vim.tbl_contains(scopes, current) do
|
||||||
|
current = current:parent()
|
||||||
|
end
|
||||||
|
|
||||||
|
return current or root
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get next node with same parent
|
||||||
|
-- @param node node
|
||||||
|
-- @param allow_switch_parents allow switching parents if last node
|
||||||
|
-- @param allow_next_parent allow next parent if last node and next parent without children
|
||||||
|
function M.get_next_node(node, allow_switch_parents, allow_next_parent)
|
||||||
|
local destination_node
|
||||||
|
local parent = node:parent()
|
||||||
|
|
||||||
|
if parent then
|
||||||
|
local found_pos = 0
|
||||||
|
for i = 0,parent:named_child_count()-1,1 do
|
||||||
|
if parent:named_child(i) == node then
|
||||||
|
found_pos = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if parent:named_child_count() > found_pos + 1 then
|
||||||
|
destination_node = parent:named_child(found_pos + 1)
|
||||||
|
elseif allow_switch_parents then
|
||||||
|
local next_node = M.get_next_node(node:parent())
|
||||||
|
if next_node and next_node:named_child_count() > 0 then
|
||||||
|
destination_node = next_node:named_child(0)
|
||||||
|
elseif next_node and allow_next_parent then
|
||||||
|
destination_node = next_node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return destination_node
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get previous node with same parent
|
||||||
|
-- @param node node
|
||||||
|
-- @param allow_switch_parents allow switching parents if first node
|
||||||
|
-- @param allow_previous_parent allow previous parent if first node and previous parent without children
|
||||||
|
function M.get_previous_node(node, allow_switch_parents, allow_previous_parent)
|
||||||
|
local destination_node
|
||||||
|
local parent = node:parent()
|
||||||
|
if parent then
|
||||||
|
local found_pos = 0
|
||||||
|
for i = 0,parent:named_child_count()-1,1 do
|
||||||
|
if parent:named_child(i) == node then
|
||||||
|
found_pos = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if 0 < found_pos then
|
||||||
|
destination_node = parent:named_child(found_pos - 1)
|
||||||
|
elseif allow_switch_parents then
|
||||||
|
local previous_node = M.get_previous_node(node:parent())
|
||||||
|
if previous_node and previous_node:named_child_count() > 0 then
|
||||||
|
destination_node = previous_node:named_child(previous_node:named_child_count() - 1)
|
||||||
|
elseif previous_node and allow_previous_parent then
|
||||||
|
destination_node = previous_node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return destination_node
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
" Last Change: 2020 avril 19
|
" Last Change: 2020 avril 25
|
||||||
|
|
||||||
if exists('g:loaded_nvim_treesitter')
|
if exists('g:loaded_nvim_treesitter')
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
lua << EOF
|
augroup NvimTreesitter
|
||||||
ts_installable_parsers = function()
|
augroup END
|
||||||
return table.concat(require'nvim-treesitter'.available_parsers(), '\n')
|
|
||||||
end
|
|
||||||
require'nvim-treesitter'._root.setup()
|
|
||||||
EOF
|
|
||||||
|
|
||||||
let g:loaded_nvim_treesitter = 1
|
let g:loaded_nvim_treesitter = 1
|
||||||
|
|
||||||
augroup NvimTreesitter
|
lua << EOF
|
||||||
augroup END
|
ts_installable_parsers = function()
|
||||||
|
return table.concat(require'nvim-treesitter.configs'.available_parsers(), '\n')
|
||||||
|
end
|
||||||
|
ts_available_modules = function()
|
||||||
|
return table.concat(require'nvim-treesitter.configs'.available_modules(), '\n')
|
||||||
|
end
|
||||||
|
require'nvim-treesitter'.setup()
|
||||||
|
EOF
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@
|
||||||
;;; Builtins
|
;;; Builtins
|
||||||
;; Keywords
|
;; Keywords
|
||||||
"local" @keyword
|
"local" @keyword
|
||||||
"if" @keyword
|
"if" @conditional
|
||||||
"then" @keyword
|
"then" @conditional
|
||||||
"else" @keyword
|
"else" @conditional
|
||||||
"elseif" @keyword
|
"elseif" @conditional
|
||||||
"end" @keyword
|
"end" @keyword
|
||||||
"return" @keyword
|
"return" @keyword
|
||||||
"do" @keyword
|
"do" @repeat
|
||||||
"while" @keyword
|
"while" @repeat
|
||||||
"repeat" @keyword
|
"repeat" @repeat
|
||||||
"for" @keyword
|
"for" @repeat
|
||||||
(break_statement) @keyword
|
(break_statement) @keyword
|
||||||
"goto" @keyword
|
"goto" @keyword
|
||||||
|
|
||||||
|
|
@ -43,15 +43,16 @@
|
||||||
"#" @operator
|
"#" @operator
|
||||||
|
|
||||||
;; Constants
|
;; Constants
|
||||||
(false) @constant
|
(false) @boolean
|
||||||
(true) @constant
|
(true) @boolean
|
||||||
(nil) @constant
|
(nil) @constant.builtin
|
||||||
(spread) @constant ;; "..."
|
(spread) @constant ;; "..."
|
||||||
|
|
||||||
;; Nodes
|
;; Nodes
|
||||||
(function "function" @function "end" @function)
|
(function "function" @function "end" @function)
|
||||||
|
(function_definition "function" @function "end" @function)
|
||||||
(local_function "function" @function "end" @function)
|
(local_function "function" @function "end" @function)
|
||||||
(table "{" @operator "}" @operator)
|
(table "{" @constructor "}" @constructor)
|
||||||
(comment) @comment
|
(comment) @comment
|
||||||
(string) @string
|
(string) @string
|
||||||
(number) @number
|
(number) @number
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,20 @@
|
||||||
|
|
||||||
;; Variable and field declarations
|
;; Variable and field declarations
|
||||||
((variable_declarator
|
((variable_declarator
|
||||||
(identifier) @definition)
|
(identifier) @definition.var))
|
||||||
(set! definition.kind "v"))
|
|
||||||
|
|
||||||
((variable_declarator
|
((variable_declarator
|
||||||
(field_expression object:(*) @definition.associated (property_identifier) @definition))
|
(field_expression object:(*) @definition.associated (property_identifier) @definition.var)))
|
||||||
(set! difinition.kind "v"))
|
|
||||||
|
|
||||||
;; Parameters
|
;; Parameters
|
||||||
((local_function
|
((local_function
|
||||||
(parameters (identifier) @definition))
|
(parameters (identifier) @definition.var)))
|
||||||
(set! definition.kind "v"))
|
|
||||||
((function
|
((function
|
||||||
(parameters (identifier) @definition))
|
(parameters (identifier) @definition.var)))
|
||||||
(set! definition.kind "v"))
|
|
||||||
|
|
||||||
;; Loops
|
;; Loops
|
||||||
((loop_expression
|
((loop_expression
|
||||||
(identifier) @definition)
|
(identifier) @definition.var))
|
||||||
(set! definition.kind "v"))
|
|
||||||
|
|
||||||
;; Function definitions
|
;; Function definitions
|
||||||
;; Functions definitions creates both a definition and a new scope
|
;; Functions definitions creates both a definition and a new scope
|
||||||
|
|
@ -28,16 +23,13 @@
|
||||||
(function_name
|
(function_name
|
||||||
(function_name_field
|
(function_name_field
|
||||||
(identifier) @definition.associated
|
(identifier) @definition.associated
|
||||||
(property_identifier) @definition))) @scope
|
(property_identifier) @definition.method))) @scope)
|
||||||
(set! definition.kind "m"))
|
|
||||||
|
|
||||||
((function
|
((function
|
||||||
(function_name (identifier) @definition)) @scope
|
(function_name (identifier) @definition.function)) @scope)
|
||||||
(set! definition.kind "f"))
|
|
||||||
|
|
||||||
((local_function
|
((local_function
|
||||||
(identifier) @definition) @scope
|
(identifier) @definition.function) @scope)
|
||||||
(set! definition.kind "f"))
|
|
||||||
|
|
||||||
((if_statement) @scope)
|
((if_statement) @scope)
|
||||||
((for_in_statement) @scope)
|
((for_in_statement) @scope)
|
||||||
|
|
|
||||||
140
queries/ruby/highlights.scm
Normal file
140
queries/ruby/highlights.scm
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
; Keywords
|
||||||
|
|
||||||
|
"alias" @keyword
|
||||||
|
"and" @keyword
|
||||||
|
"begin" @keyword
|
||||||
|
"break" @keyword
|
||||||
|
"case" @keyword
|
||||||
|
"class" @keyword
|
||||||
|
"def" @keyword
|
||||||
|
"do" @keyword
|
||||||
|
"else" @keyword
|
||||||
|
"elsif" @keyword
|
||||||
|
"end" @keyword
|
||||||
|
"ensure" @keyword
|
||||||
|
"for" @keyword
|
||||||
|
"if" @keyword
|
||||||
|
"in" @keyword
|
||||||
|
"module" @keyword
|
||||||
|
"next" @keyword
|
||||||
|
"or" @keyword
|
||||||
|
"rescue" @keyword
|
||||||
|
"retry" @keyword
|
||||||
|
"return" @keyword
|
||||||
|
"then" @keyword
|
||||||
|
"unless" @keyword
|
||||||
|
"until" @keyword
|
||||||
|
"when" @keyword
|
||||||
|
"while" @keyword
|
||||||
|
"yield" @keyword
|
||||||
|
|
||||||
|
((identifier) @keyword
|
||||||
|
(match? @keyword "^(private|protected|public)$"))
|
||||||
|
|
||||||
|
; Function calls
|
||||||
|
|
||||||
|
((identifier) @function
|
||||||
|
(eq? @function "require"))
|
||||||
|
|
||||||
|
"defined?" @function
|
||||||
|
|
||||||
|
(call
|
||||||
|
receiver: (constant) @constant)
|
||||||
|
(method_call
|
||||||
|
receiver: (constant) @constant)
|
||||||
|
(call
|
||||||
|
method: (identifier) @function)
|
||||||
|
(method_call
|
||||||
|
method: (identifier) @function)
|
||||||
|
(call
|
||||||
|
method: (constant) @function)
|
||||||
|
(method_call
|
||||||
|
method: (constant) @function)
|
||||||
|
|
||||||
|
; Function definitions
|
||||||
|
|
||||||
|
(alias (identifier) @function)
|
||||||
|
(setter (identifier) @function)
|
||||||
|
(method name: (identifier) @function)
|
||||||
|
(method name: (constant) @constant)
|
||||||
|
(class name: (constant) @constant)
|
||||||
|
(singleton_method name: (identifier) @function)
|
||||||
|
(singleton_method name: (constant) @constant)
|
||||||
|
|
||||||
|
; Identifiers
|
||||||
|
|
||||||
|
(class_variable) @Identifier
|
||||||
|
(instance_variable) @Identifier
|
||||||
|
|
||||||
|
((identifier) @constant
|
||||||
|
(match? @constant "^__(FILE|LINE|ENCODING)__$"))
|
||||||
|
|
||||||
|
((constant) @constant
|
||||||
|
(match? @constant "^[A-Z\\d_]+$"))
|
||||||
|
|
||||||
|
(constant) @constant
|
||||||
|
|
||||||
|
(self) @constant
|
||||||
|
(super) @Identifier
|
||||||
|
|
||||||
|
(method_parameters (identifier) @Type)
|
||||||
|
(lambda_parameters (identifier) @Type)
|
||||||
|
(block_parameters (identifier) @Type)
|
||||||
|
(splat_parameter (identifier) @Type)
|
||||||
|
(hash_splat_parameter (identifier) @Type)
|
||||||
|
(optional_parameter (identifier) @Type)
|
||||||
|
(destructured_parameter (identifier) @Type)
|
||||||
|
(block_parameter (identifier) @Type)
|
||||||
|
(keyword_parameter (identifier) @Type)
|
||||||
|
|
||||||
|
((identifier) @function
|
||||||
|
(is-not? local))
|
||||||
|
|
||||||
|
; Literals
|
||||||
|
|
||||||
|
(string) @string
|
||||||
|
(bare_string) @string
|
||||||
|
(bare_symbol) @constant
|
||||||
|
(subshell) @string
|
||||||
|
(heredoc_beginning) @Delimiter
|
||||||
|
(heredoc_body) @string
|
||||||
|
(heredoc_end) @Delimiter
|
||||||
|
(symbol) @constant
|
||||||
|
(regex) @string
|
||||||
|
(escape_sequence) @Special
|
||||||
|
(integer) @number
|
||||||
|
(float) @number
|
||||||
|
|
||||||
|
(nil) @Identifier
|
||||||
|
(true) @Identifier
|
||||||
|
(false) @Identifier
|
||||||
|
|
||||||
|
(interpolation
|
||||||
|
"#{" @Delimiter
|
||||||
|
(identifier) @Identifier
|
||||||
|
"}" @Delimiter) @embedded
|
||||||
|
|
||||||
|
(comment) @comment
|
||||||
|
|
||||||
|
; Operators
|
||||||
|
|
||||||
|
"=" @operator
|
||||||
|
"=>" @operator
|
||||||
|
"->" @operator
|
||||||
|
"+" @operator
|
||||||
|
"-" @operator
|
||||||
|
"*" @operator
|
||||||
|
"/" @operator
|
||||||
|
|
||||||
|
"," @Normal
|
||||||
|
";" @Normal
|
||||||
|
"." @Normal
|
||||||
|
|
||||||
|
"(" @Normal
|
||||||
|
")" @Normal
|
||||||
|
"[" @Normal
|
||||||
|
"]" @Normal
|
||||||
|
"{" @Normal
|
||||||
|
"}" @Normal
|
||||||
|
"%w(" @Normal
|
||||||
|
"%i(" @Normal
|
||||||
45
queries/ruby/locals.scm
Normal file
45
queries/ruby/locals.scm
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
; The MIT License (MIT)
|
||||||
|
;
|
||||||
|
; Copyright (c) 2016 Rob Rix
|
||||||
|
;
|
||||||
|
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
; of this software and associated documentation files (the "Software"), to deal
|
||||||
|
; in the Software without restriction, including without limitation the rights
|
||||||
|
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
; copies of the Software, and to permit persons to whom the Software is
|
||||||
|
; furnished to do so, subject to the following conditions:
|
||||||
|
;
|
||||||
|
; The above copyright notice and this permission notice shall be included in all
|
||||||
|
; copies or substantial portions of the Software.
|
||||||
|
;
|
||||||
|
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
; SOFTWARE.
|
||||||
|
|
||||||
|
;;; DESCLARATIONS AND SCOPES
|
||||||
|
((method) @scope
|
||||||
|
(set! scope-inherits false))
|
||||||
|
|
||||||
|
(block) @scope
|
||||||
|
(do_block) @scope
|
||||||
|
|
||||||
|
(method_parameters (identifier) @definition)
|
||||||
|
(lambda_parameters (identifier) @definition)
|
||||||
|
(block_parameters (identifier) @definition)
|
||||||
|
(splat_parameter name: (identifier) @definition)
|
||||||
|
(hash_splat_parameter name: (identifier) @definition)
|
||||||
|
(optional_parameter name: (identifier) @definition)
|
||||||
|
(destructured_parameter name: (identifier) @definition)
|
||||||
|
(block_parameter name: (identifier) @definition)
|
||||||
|
(keyword_parameter name: (identifier) @definition)
|
||||||
|
|
||||||
|
(identifier) @reference
|
||||||
|
|
||||||
|
(assignment left:(identifier) @definition)
|
||||||
|
(left_assignment_list (identifier) @definition)
|
||||||
|
(rest_assignment (identifier) @definition)
|
||||||
|
(destructured_left_assignment (identifier) @definition)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue