mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-01 19:17:02 -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
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -79,19 +79,101 @@ bash [✗] 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
|
||||
|
||||
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:
|
||||
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 functionalities to it:
|
||||
Some of these features are :
|
||||
- [ ] Incremental selection
|
||||
- [x] Incremental selection
|
||||
- [ ] 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).
|
||||
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
|
||||
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 parsers = require'nvim-treesitter.parsers'
|
||||
local configs = require 'nvim-treesitter.configs'
|
||||
local install = require'nvim-treesitter.install'
|
||||
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 = {}
|
||||
|
||||
function M.available_parsers()
|
||||
return vim.tbl_keys(configs.repositories)
|
||||
end
|
||||
|
||||
-- This function sets up everythin needed for a given language
|
||||
-- this is the main interface through the plugin
|
||||
function M.setup(lang)
|
||||
if parsers.has_parser(lang) then
|
||||
local autocmd = "autocmd NvimTreesitter FileType %s lua require'nvim-treesitter.highlight'.setup()"
|
||||
api.nvim_command(string.format(autocmd, lang))
|
||||
utils.setup_commands('install', install.commands)
|
||||
utils.setup_commands('info', info.commands)
|
||||
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
|
||||
|
||||
-- This function initialize the plugin
|
||||
-- it is run at startup
|
||||
M._root = {}
|
||||
function M._root.setup()
|
||||
install.setup()
|
||||
function M.statusline(indicator_size)
|
||||
local indicator_size = indicator_size or 1000
|
||||
local expr = require"nvim-treesitter.utils".expression_at_point()
|
||||
local current_node =
|
||||
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
|
||||
|
||||
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 = {
|
||||
javascript = {
|
||||
parsers.javascript = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
c = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.c = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-c",
|
||||
files = { "src/parser.c" }
|
||||
},
|
||||
cpp = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.cpp = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-cpp",
|
||||
files = { "src/parser.c", "src/scanner.cc" }
|
||||
},
|
||||
rust = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.rust = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
lua = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.lua = {
|
||||
install_info = {
|
||||
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
||||
files = { "src/parser.c", "src/scanner.cc" }
|
||||
},
|
||||
python = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.python = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-python",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
go = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.go = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-go",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
ruby = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.ruby = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
bash = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.bash = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-bash",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
php = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.php = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-php",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
java = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.java = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-java",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
html = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.html = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-html",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
julia = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.julia = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
json = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.json = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-json",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
css = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.css = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-css",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
ocaml = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.ocaml = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
swift = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.swift = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
csharp = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.csharp = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
typescript = {
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
},
|
||||
tsx = {
|
||||
}
|
||||
}
|
||||
|
||||
parsers.tsx = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
location = "tree-sitter-tsx/tsx"
|
||||
}
|
||||
}
|
||||
|
||||
parsers.scala = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-scala",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.haskell = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-haskell",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.markdown = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-markdown",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.toml = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-toml",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.vue = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-vue",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.elm = {
|
||||
install_info = {
|
||||
url = "https://github.com//razzeee/tree-sitter-elm",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.yaml = {
|
||||
install_info = {
|
||||
url = "https://github.com/ikatyang/tree-sitter-yaml",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
parsers.nix = {
|
||||
install_info = {
|
||||
url = "https://github.com/cstrahan/tree-sitter-nix",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
}
|
||||
|
||||
-- @enable can be true or false
|
||||
-- @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
|
||||
|
|
|
|||
|
|
@ -3,6 +3,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 health_start = vim.fn["health#report_start"]
|
||||
|
|
@ -13,7 +14,7 @@ local health_error = vim.fn['health#report_error']
|
|||
|
||||
local M = {}
|
||||
|
||||
local function configs_health()
|
||||
local function install_health()
|
||||
if fn.executable('git') == 0 then
|
||||
health_error('`git` executable not found.', {
|
||||
'Install it with your package manager.',
|
||||
|
|
@ -34,15 +35,36 @@ local function configs_health()
|
|||
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
|
||||
function M.checkhealth()
|
||||
-- Installation dependency checks
|
||||
health_start('Installation')
|
||||
configs_health()
|
||||
install_health()
|
||||
|
||||
local missing_parsers = {}
|
||||
-- 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)
|
||||
|
||||
-- Only print informations about installed parsers
|
||||
|
|
@ -50,7 +72,8 @@ function M.checkhealth()
|
|||
health_start(parser_name .. " parser healthcheck")
|
||||
health_ok(parser_name .. " parser found.")
|
||||
|
||||
locals.checkhealth(parser_name)
|
||||
locals_health(parser_name)
|
||||
highlight_health(parser_name)
|
||||
elseif installed > 1 then
|
||||
health_warn(string.format("Multiple parsers found for %s, only %s will be used.", parser_name, installed[1]))
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,12 +1,53 @@
|
|||
local api = vim.api
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local ts = vim.treesitter
|
||||
local queries = require'nvim-treesitter.query'
|
||||
|
||||
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 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)
|
||||
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
|
||||
|
|
|
|||
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 fn = vim.fn
|
||||
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 = {}
|
||||
|
||||
|
|
@ -33,14 +35,16 @@ local function get_cache_dir()
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
local handle
|
||||
|
||||
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
|
||||
if code ~= 0 then return api.nvim_err_writeln(attr.err) end
|
||||
iter_cmd(cmd_list, i + 1, ft)
|
||||
end))
|
||||
end
|
||||
|
|
@ -75,12 +79,12 @@ local function run_install(cache_folder, package_path, ft, repo)
|
|||
args = vim.tbl_flatten({
|
||||
'-o',
|
||||
'parser.so',
|
||||
'-I./src',
|
||||
repo.files,
|
||||
'-shared',
|
||||
'-Os',
|
||||
'-lstdc++',
|
||||
'-fPIC',
|
||||
'-Os',
|
||||
'-I./src',
|
||||
repo.files
|
||||
}),
|
||||
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
|
||||
|
||||
-- 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
|
||||
end
|
||||
|
||||
local repository = repositories[ft]
|
||||
if not repository then
|
||||
local parser_config = parsers[ft]
|
||||
if not parser_config then
|
||||
return api.nvim_err_writeln('Parser not available for language '..ft)
|
||||
end
|
||||
|
||||
local install_info = parser_config.install_info
|
||||
vim.validate {
|
||||
url={ repository.url, 'string' },
|
||||
files={ repository.files, 'table' }
|
||||
url={ install_info.url, 'string' },
|
||||
files={ install_info.files, 'table' }
|
||||
}
|
||||
|
||||
if fn.executable('git') == 0 then
|
||||
|
|
@ -138,26 +143,27 @@ local function install(ft)
|
|||
local cache_folder, err = get_cache_dir()
|
||||
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
|
||||
|
||||
local function install_info()
|
||||
local max_len = 0
|
||||
for parser_name, _ in pairs(repositories) do
|
||||
if #parser_name > max_len then max_len = #parser_name end
|
||||
|
||||
M.ensure_installed = function(languages)
|
||||
if type(languages) == 'string' then
|
||||
if languages == 'all' then
|
||||
languages = configs.available_parsers()
|
||||
else
|
||||
languages = {languages}
|
||||
end
|
||||
end
|
||||
|
||||
for parser_name, _ in pairs(repositories) do
|
||||
local is_installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false) > 0
|
||||
api.nvim_out_write(parser_name..string.rep(' ', max_len - #parser_name + 1))
|
||||
if is_installed then
|
||||
api.nvim_out_write("[✓] installed\n")
|
||||
else
|
||||
api.nvim_out_write("[✗] not installed\n")
|
||||
for _, ft in ipairs(languages) do
|
||||
if not has_parser(ft) then
|
||||
install(ft)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
M.commands = {
|
||||
TSInstall = {
|
||||
run = install,
|
||||
|
|
@ -166,25 +172,7 @@ M.commands = {
|
|||
"-complete=custom,v:lua.ts_installable_parsers"
|
||||
},
|
||||
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
|
||||
|
|
|
|||
|
|
@ -10,22 +10,6 @@ local M = {
|
|||
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)
|
||||
local ft = api.nvim_buf_get_option(bufnr, "ft")
|
||||
if not ft then return end
|
||||
|
|
@ -69,7 +53,7 @@ function M.get_definitions(bufnr)
|
|||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc.definition then
|
||||
table.insert(defs, {definition=loc.definition, kind=loc.kind})
|
||||
table.insert(defs, loc.definition)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -82,8 +66,8 @@ function M.get_scopes(bufnr)
|
|||
local scopes = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc.scope then
|
||||
table.insert(scopes, loc.scope)
|
||||
if loc.scope and loc.scope.node then
|
||||
table.insert(scopes, loc.scope.node)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -96,8 +80,8 @@ function M.get_references(bufnr)
|
|||
local refs = {}
|
||||
|
||||
for _, loc in ipairs(locals) do
|
||||
if loc.reference then
|
||||
table.insert(refs, loc.reference)
|
||||
if loc.reference and loc.reference.node then
|
||||
table.insert(refs, loc.reference.node)
|
||||
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)
|
||||
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
|
||||
end
|
||||
|
||||
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 lang = lang or api.nvim_buf_get_option(buf, 'ft')
|
||||
if not M[buf] then
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
-- Utils collection for nvim-treesitter
|
||||
local api = vim.api
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local locals = require'nvim-treesitter.locals'
|
||||
|
||||
local M = {}
|
||||
|
||||
|
|
@ -63,4 +64,92 @@ function M.is_parent(dest, source)
|
|||
return false
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,17 +1,20 @@
|
|||
" Last Change: 2020 avril 19
|
||||
" Last Change: 2020 avril 25
|
||||
|
||||
if exists('g:loaded_nvim_treesitter')
|
||||
finish
|
||||
endif
|
||||
|
||||
lua << EOF
|
||||
ts_installable_parsers = function()
|
||||
return table.concat(require'nvim-treesitter'.available_parsers(), '\n')
|
||||
end
|
||||
require'nvim-treesitter'._root.setup()
|
||||
EOF
|
||||
augroup NvimTreesitter
|
||||
augroup END
|
||||
|
||||
let g:loaded_nvim_treesitter = 1
|
||||
|
||||
augroup NvimTreesitter
|
||||
augroup END
|
||||
lua << EOF
|
||||
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
|
||||
;; Keywords
|
||||
"local" @keyword
|
||||
"if" @keyword
|
||||
"then" @keyword
|
||||
"else" @keyword
|
||||
"elseif" @keyword
|
||||
"if" @conditional
|
||||
"then" @conditional
|
||||
"else" @conditional
|
||||
"elseif" @conditional
|
||||
"end" @keyword
|
||||
"return" @keyword
|
||||
"do" @keyword
|
||||
"while" @keyword
|
||||
"repeat" @keyword
|
||||
"for" @keyword
|
||||
"do" @repeat
|
||||
"while" @repeat
|
||||
"repeat" @repeat
|
||||
"for" @repeat
|
||||
(break_statement) @keyword
|
||||
"goto" @keyword
|
||||
|
||||
|
|
@ -43,15 +43,16 @@
|
|||
"#" @operator
|
||||
|
||||
;; Constants
|
||||
(false) @constant
|
||||
(true) @constant
|
||||
(nil) @constant
|
||||
(false) @boolean
|
||||
(true) @boolean
|
||||
(nil) @constant.builtin
|
||||
(spread) @constant ;; "..."
|
||||
|
||||
;; Nodes
|
||||
(function "function" @function "end" @function)
|
||||
(function_definition "function" @function "end" @function)
|
||||
(local_function "function" @function "end" @function)
|
||||
(table "{" @operator "}" @operator)
|
||||
(table "{" @constructor "}" @constructor)
|
||||
(comment) @comment
|
||||
(string) @string
|
||||
(number) @number
|
||||
|
|
|
|||
|
|
@ -2,25 +2,20 @@
|
|||
|
||||
;; Variable and field declarations
|
||||
((variable_declarator
|
||||
(identifier) @definition)
|
||||
(set! definition.kind "v"))
|
||||
(identifier) @definition.var))
|
||||
|
||||
((variable_declarator
|
||||
(field_expression object:(*) @definition.associated (property_identifier) @definition))
|
||||
(set! difinition.kind "v"))
|
||||
(field_expression object:(*) @definition.associated (property_identifier) @definition.var)))
|
||||
|
||||
;; Parameters
|
||||
((local_function
|
||||
(parameters (identifier) @definition))
|
||||
(set! definition.kind "v"))
|
||||
(parameters (identifier) @definition.var)))
|
||||
((function
|
||||
(parameters (identifier) @definition))
|
||||
(set! definition.kind "v"))
|
||||
(parameters (identifier) @definition.var)))
|
||||
|
||||
;; Loops
|
||||
((loop_expression
|
||||
(identifier) @definition)
|
||||
(set! definition.kind "v"))
|
||||
(identifier) @definition.var))
|
||||
|
||||
;; Function definitions
|
||||
;; Functions definitions creates both a definition and a new scope
|
||||
|
|
@ -28,16 +23,13 @@
|
|||
(function_name
|
||||
(function_name_field
|
||||
(identifier) @definition.associated
|
||||
(property_identifier) @definition))) @scope
|
||||
(set! definition.kind "m"))
|
||||
(property_identifier) @definition.method))) @scope)
|
||||
|
||||
((function
|
||||
(function_name (identifier) @definition)) @scope
|
||||
(set! definition.kind "f"))
|
||||
(function_name (identifier) @definition.function)) @scope)
|
||||
|
||||
((local_function
|
||||
(identifier) @definition) @scope
|
||||
(set! definition.kind "f"))
|
||||
(identifier) @definition.function) @scope)
|
||||
|
||||
((if_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