nvim-treesitter/README.md

377 lines
17 KiB
Markdown
Raw Normal View History

2020-09-10 13:57:42 -05:00
<div align="center">
<h1>nvim-treesitter</h1>
<p>
<a href="https://nvim-treesitter.zulipchat.com/">
<img alt="Zulip Chat" src="https://img.shields.io/badge/zulip-join_chat-brightgreen.svg" />
</a>
<a href="https://github.com/nvim-treesitter/nvim-treesitter/actions?query=workflow%3A%22Linting+and+style+checking%22+branch%3Amaster">
<img alt="Linting and Style" src="https://github.com/nvim-treesitter/nvim-treesitter/workflows/Linting%20and%20style%20checking/badge.svg" />
</a>
<a href="https://github.com/nvim-treesitter/nvim-treesitter/actions?query=workflow%3A%22Check+loading+of+syntax+files%22+branch%3Amaster">
<img alt="Syntax files" src="https://github.com/nvim-treesitter/nvim-treesitter/workflows/Check%20loading%20of%20syntax%20files/badge.svg" />
</a>
</p>
</div>
2020-09-10 13:57:42 -05:00
<div align="center">
<p>
<img src="assets/logo.png" align="center" alt="Logo" />
</p>
<p>
<a href="https://github.com/tree-sitter/tree-sitter">Treesitter</a>
configurations and abstraction layer for
<a href="https://github.com/neovim/neovim/">Neovim</a>.
</p>
<p>
<i>
Logo by <a href="https://github.com/steelsojka">@steelsojka</a>
</i>
</p>
</div>
2020-11-21 22:07:17 +01:00
The goal of `nvim-treesitter` is both to provide a simple and easy way to use the interface for [tree-sitter](https://github.com/tree-sitter/tree-sitter) in Neovim and to provide some basic functionality such as highlighting based on on it:
2020-09-10 13:57:42 -05:00
![cpp example](assets/example-cpp.png)
Traditional highlighting (left) vs Treesitter-based highlighting (right).
2020-11-21 22:07:17 +01:00
More examples can be found in [our gallery](https://github.com/nvim-treesitter/nvim-treesitter/wiki/Gallery).
**Warning: Treesitter and nvim-treesitter highlighting are an experimental feature of nightly versions of Neovim.
Please consider the experience with this plug-in as experimental until Neovim 0.5 is released!
You can find the current roadmap [here](https://github.com/nvim-treesitter/nvim-treesitter/projects/1).
The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated!**
2020-11-21 22:07:17 +01:00
Nvim-treesitter is based on three interlocking features: [**language parsers**](#parsers), [**queries**](#queries), and [**modules**](#modules), where *modules* provide features -- such as highlighting -- based on *queries* for syntax objects specified by language *parsers*. Users will generally only need to interact with parsers and modules as explained in the next section. For more detailed information on setting these up, see ["Advanced setup"](#advanced).
2020-06-21 17:39:58 +02:00
# Quickstart
## Requirements
- Neovim [nightly](https://github.com/neovim/neovim#install-from-source)
- `tar` and `curl` in your path (or alternativly `git`)
- A C compiler in your path and libstdc++ installed ([Windows users please read this!](https://github.com/nvim-treesitter/nvim-treesitter/wiki/Windows-support)).
## Installation
2020-11-21 22:07:17 +01:00
You can install `nvim-treesitter` with your favorite package manager (or using the native `package` feature of vim, see `:h packages`).
2020-11-21 22:07:17 +01:00
E.g., if you are using [vim-plug](https://github.com/junegunn/vim-plug), put this in your `init.vim` file:
```vim
Plug 'nvim-treesitter/nvim-treesitter'
```
2020-11-21 22:07:17 +01:00
## Language parsers
2020-11-21 18:56:53 +01:00
Treesitter uses a different _parser_ for every language, which needs to be generated via `tree-sitter-cli` from a `grammar.js` file, then compiled to a `.so` library that needs to be placed in neovim's `runtimepath` (typically under `parser/{lang}.so`). To simplify this, `nvim-treesitter`
2020-11-21 20:32:24 +01:00
provides commands to automate this process. If the language is already [supported by `nvim-treesitter`](#supported), you can install it with
```vim
:TSInstall {language}
```
2020-11-21 21:00:38 +01:00
This command supports tab expansion. You can also get a list of all available languages and their installation status with `:TSInstallInfo`. Parsers not on this list can be added manually by following the steps described under ["Adding unsupported parsers"](#unsupported) below.
2020-11-21 20:32:24 +01:00
If you update `nvim-treesitter` and want to make sure the parser is at the latest compatible version (as specified in `nvim-treesitter`'s `lockfile.json`), use `:TSUpdate {language}`. To update all parsers unconditionally, use `:TSUpdate all` or just `:TSUpdate`.
2020-11-21 22:07:17 +01:00
## Modules
Each modules provide a distinct feature based on treesitter such as [highlighting](#highlighting), [indentation](#indentation), or [folding](#folding); see [`:h nvim-treesitter-modules`](doc/nvim-treesitter.txt) or see ["Modules"](#modules) below for a list of available modules and their options.
2020-11-21 22:07:17 +01:00
All modules are disabled by default and need to be activated explicitly in your `init.vim`:
2020-11-12 19:34:35 -03:00
```vim
2020-11-11 16:52:35 -03:00
lua <<EOF
require'nvim-treesitter.configs'.setup {
ensure_installed = "maintained", -- one of "all", "maintained" (parsers with maintainers), or a list of languages
highlight = {
enable = true, -- false will disable the whole extension
disable = { "c", "rust" }, -- list of language that will be disabled
},
}
2020-11-11 16:52:35 -03:00
EOF
```
2020-11-21 22:07:17 +01:00
Each module can also be enabled or disabled interactively through the following commands:
```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
```
Check [`:h nvim-treesitter-commands`](doc/nvim-treesitter.txt) for a list of all available commands. It may be necessary to reload the buffer (e.g., via `:e`) after enabling a module.
# <a name="supported"></a>Supported languages
For `nvim-treesitter` to support a specific feature for a specific language requires both a parser for this language and an appropriate query file for that language and that feature.
The following is a list of languages for which a parser can be installed through `:TSInstall`; a checked box means that `nvim-treesitter` also contains queries at least for the `highlight` module.
We are looking for maintainers to add more parsers and to write query files for their languages.
<!--This section of the README is automatically updated by a CI job-->
<!--parserinfo-->
- [x] [bash](https://github.com/tree-sitter/tree-sitter-bash) (maintained by @TravonteD)
- [x] [c](https://github.com/tree-sitter/tree-sitter-c) (maintained by @vigoux)
- [x] [c_sharp](https://github.com/tree-sitter/tree-sitter-c-sharp) (maintained by @svermeulen)
- [x] [clojure](https://github.com/sogaiu/tree-sitter-clojure) (maintained by @sogaiu)
- [x] [cpp](https://github.com/tree-sitter/tree-sitter-cpp) (maintained by @theHamsta)
- [x] [css](https://github.com/tree-sitter/tree-sitter-css) (maintained by @TravonteD)
- [x] [dart](https://github.com/UserNobody14/tree-sitter-dart) (maintained by @Akin909)
- [ ] [elm](https://github.com/razzeee/tree-sitter-elm)
- [x] [fennel](https://github.com/travonted/tree-sitter-fennel) (maintained by @TravonteD)
- [x] [go](https://github.com/tree-sitter/tree-sitter-go) (maintained by @theHamsta, @WinWisely268)
- [ ] [haskell](https://github.com/tree-sitter/tree-sitter-haskell)
- [x] [html](https://github.com/tree-sitter/tree-sitter-html) (maintained by @TravonteD)
- [x] [java](https://github.com/tree-sitter/tree-sitter-java) (maintained by @p00f)
- [x] [javascript](https://github.com/tree-sitter/tree-sitter-javascript) (maintained by @steelsojka)
- [x] [jsdoc](https://github.com/tree-sitter/tree-sitter-jsdoc) (maintained by @steelsojka)
- [x] [json](https://github.com/tree-sitter/tree-sitter-json) (maintained by @steelsojka)
- [ ] [julia](https://github.com/tree-sitter/tree-sitter-julia)
- [x] [lua](https://github.com/nvim-treesitter/tree-sitter-lua) (maintained by @vigoux)
- [x] [nix](https://github.com/cstrahan/tree-sitter-nix) (maintained by @leo60228)
- [x] [ocaml](https://github.com/tree-sitter/tree-sitter-ocaml) (maintained by @undu)
- [x] [ocaml_interface](https://github.com/tree-sitter/tree-sitter-ocaml) (maintained by @undu)
- [x] [ocamllex](https://github.com/atom-ocaml/tree-sitter-ocamllex) (maintained by @undu)
- [x] [php](https://github.com/tree-sitter/tree-sitter-php) (maintained by @tk-shirasaka)
- [x] [python](https://github.com/tree-sitter/tree-sitter-python) (maintained by @stsewd, @theHamsta)
- [x] [ql](https://github.com/tree-sitter/tree-sitter-ql) (maintained by @pwntester)
- [x] [Tree-sitter query language](https://github.com/nvim-treesitter/tree-sitter-query) (maintained by @steelsojka)
- [x] [regex](https://github.com/tree-sitter/tree-sitter-regex) (maintained by @theHamsta)
- [x] [rst](https://github.com/stsewd/tree-sitter-rst) (maintained by @stsewd)
- [x] [ruby](https://github.com/tree-sitter/tree-sitter-ruby) (maintained by @TravonteD)
- [x] [rust](https://github.com/tree-sitter/tree-sitter-rust) (maintained by @vigoux)
- [ ] [scala](https://github.com/tree-sitter/tree-sitter-scala)
- [ ] [swift](https://github.com/tree-sitter/tree-sitter-swift)
- [x] [teal](https://github.com/euclidianAce/tree-sitter-teal) (maintained by @euclidianAce)
- [x] [toml](https://github.com/ikatyang/tree-sitter-toml) (maintained by @tk-shirasaka)
- [ ] [tsx](https://github.com/tree-sitter/tree-sitter-typescript)
- [x] [typescript](https://github.com/tree-sitter/tree-sitter-typescript) (maintained by @steelsojka)
- [x] [verilog](https://github.com/tree-sitter/tree-sitter-verilog) (maintained by @zegervdv)
- [ ] [vue](https://github.com/ikatyang/tree-sitter-vue)
- [ ] [yaml](https://github.com/ikatyang/tree-sitter-yaml)
<!--parserinfo-->
# <a name="modules"></a> Available modules
2020-11-21 22:07:17 +01:00
Modules provide the top-level features of `nvim-treesitter`. These can be implemented either as part of `nvim-treesitter` or as an external plugin.
2020-11-21 22:07:17 +01:00
## Included modules
The following is a list of modules included in `nvim-treesitter`. Note that not all modules work for all languages (depending on the queries available for them).
#### <a name="highlighting"></a> Highlight
Consistent syntax highlighting.
2020-11-12 19:34:35 -03:00
```vim
lua <<EOF
require'nvim-treesitter.configs'.setup {
highlight = {
enable = true,
custom_captures = {
-- Highlight the @foo.bar capture group with the "Identifier" highlight group.
["foo.bar"] = "Identifier",
},
},
}
2020-11-12 19:34:35 -03:00
EOF
```
2020-11-21 22:07:17 +01:00
#### Incremental selection
Incremental selection based on the named nodes from the grammar.
2020-11-12 19:34:35 -03:00
```vim
lua <<EOF
require'nvim-treesitter.configs'.setup {
incremental_selection = {
enable = true,
keymaps = {
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
},
},
}
2020-11-12 19:34:35 -03:00
EOF
```
2020-11-21 22:07:17 +01:00
#### <a name="indentation"></a> Indentation
2020-10-19 21:32:54 +02:00
Treesitter based indentation (`=` vim behavior)
2020-11-12 19:34:35 -03:00
```vim
lua <<EOF
2020-10-19 21:32:54 +02:00
require'nvim-treesitter.config'.setup {
indent = {
enable = true
}
}
2020-11-12 19:34:35 -03:00
EOF
2020-10-19 21:32:54 +02:00
```
2020-11-21 22:07:17 +01:00
#### <a name="folding"></a> Folding
```vim
set foldmethod=expr
set foldexpr=nvim_treesitter#foldexpr()
```
This will respect your `foldnestmax` setting.
2020-11-21 22:07:17 +01:00
## External modules
2020-11-21 22:07:17 +01:00
Other modules can be installed as plugins, such as
2020-11-21 22:07:17 +01:00
- [refactor](https://github.com/nvim-treesitter/nvim-treesitter-refactor) - Refactoring and definition modules
- [textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects) - Textobjects defined by tree-sitter queries
- [playground](https://github.com/nvim-treesitter/playground) - Treesitter integrated playground
- [context](https://github.com/romgrk/nvim-treesitter-context) - Show parent code context in a popover
2020-11-21 22:07:17 +01:00
# <a name="advanced"></a> Advanced setup
2020-11-21 22:07:17 +01:00
## <a name="unsupported"></a> Adding parsers
2020-11-21 21:00:38 +01:00
If you have a parser that is not on this list (either from a repository on Github or a local directory), you can add it manually for use by `nvim-treesitter` as follows:
1. Clone the repository or [create a new project](https://tree-sitter.github.io/tree-sitter/creating-parsers#project-setup) in, say, `~/projects/tree-sitter-zimbu`. Make sure that the `tree-sitter-cli` executable is installed and in your path; see https://tree-sitter.github.io/tree-sitter/creating-parsers#installation for installation instructions.
2. Run `tree-sitter generate` in this directory (followed by `tree-sitter test` for good measure).
3. Add the following snippet to your `init.vim`:
```vim
lua <<EOF
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
parser_config.zimbu = {
install_info = {
url = "~/projects/tree-sitter-zimbu", -- local path or git repo
files = {"src/parser.c"}
},
filetype = "zu", -- if filetype does not agrees with parser name
used_by = {"bar", "baz"} -- additional filetypes that use this parser
}
EOF
```
4. Start `nvim` and `:TSInstall zimbu`.
You can also skip step 2 and use `:TSInstallFromGrammar zimbu` to install straight from `grammar.js`. Once the parser is installed, you can update it (from the latest revision of the `main` branch if `url` is a Github repository) with `:TSUpdate zimbu`.
2020-11-21 22:07:17 +01:00
## <a name="queries"></a> Adding queries
Queries are what `nvim-treesitter` uses to extract informations from the syntax tree; they are
located in the `queries/{language}/*` runtime directories (like the `queries` folder of this plugin), e.g., `queries/{language}/{locals,highlights,textobjects}.scm`. Other modules may require additional queries such as `folding.scm`.
`nvim-treesitter` considers queries as any runtime file (see `:h rtp`), that is :
2020-11-21 21:00:38 +01:00
2020-11-21 22:07:17 +01:00
- if the file is in any `after/queries/` folder, then it will be used to extend the already defined
queries.
- Otherwise, it will be used as a base to define the query, the first query found (with the highest
priority) will be the only one to be used.
2020-11-21 22:07:17 +01:00
This hybrid approach is the most standard way; in this case
2020-11-21 22:07:17 +01:00
- if you want to rewrite (or write) a query, don't use `after/queries`;
- if you want to override a part of a query (only one match for example), use the `after/queries`
directory.
2020-11-21 22:07:17 +01:00
## Adding modules
2020-11-21 22:07:17 +01:00
If you wish you write your own module, you need to support
2020-11-21 22:07:17 +01:00
- tree-sitter language detection support;
- attaching and detaching to buffers;
- all nvim-treesitter commands.
2020-11-21 22:07:17 +01:00
At the top level, you can use the `define_modules` function to define one or more modules or module groups:
2020-11-12 19:34:35 -03:00
```vim
lua <<EOF
require'nvim-treesitter'.define_modules {
my_cool_plugin = {
attach = function(bufnr, lang)
-- Do cool stuff here
end,
detach = function(bufnr)
-- Undo cool stuff here
end,
is_supported = function(lang)
-- Check if the language is supported
end
}
}
2020-11-12 19:34:35 -03:00
EOF
```
2020-11-21 22:07:17 +01:00
with the following properties
- `module_path`: A require path (string) that exports a module with an `attach` and `detach` function. This is not required if the functions are on this definition.
- `enable`: Determines if the module is enabled by default. This is usually overridden by the user.
- `disable`: A list of languages that this module is disabled for. This is usually overridden by the user.
- `is_supported`: A function that takes a language and determines if this module supports that language.
- `attach`: A function that attaches to a buffer. This is required if `module_path` is not provided.
- `detach`: A function that detaches from a buffer. This is required if `module_path` is not provided.
2020-11-21 22:07:17 +01:00
# Extra features
### Statusline indicator
```vim
echo nvim_treesitter#statusline(90) " 90 can be any length
module->expression_statement->call->identifier
```
### Utilities
You can get some utility functions with
```lua
2020-06-19 13:51:09 +02:00
local ts_utils = require 'nvim-treesitter.ts_utils'
```
Check [`:h nvim-treesitter-utils`](doc/nvim-treesitter.txt) for more information.
# Troubleshooting
2020-11-21 22:07:17 +01:00
Before doing anything make sure you have the latest version of this plugin and run `:checkhealth nvim_treesitter`. It can also help to update the parsers via `:TSUpdate`.
This will help you find where the bug might come from.
2020-11-21 22:07:17 +01:00
* **Feature `X` does not work for `{language}`...**
First, check the `## {language} parser healthcheck` section of `:checkhealth` if you have any warning.
2020-04-22 19:36:10 +02:00
If you do, it's highly possible that this is the cause of the problem.
If everything is okay, then it might be an actual error.
In both cases, feel free to [open an issue here](https://github.com/nvim-treesitter/nvim-treesitter/issues/new/choose).
2020-11-21 22:07:17 +01:00
* **I get `module 'vim.treesitter.query' not found`**
Make sure you have the latest nightly version of Neovim.
2020-11-21 22:07:17 +01:00
* **I get `Error detected while processing .../plugin/nvim-treesitter.vim` every time I open Neovim**
This is probably due to a change in a parser's grammar or its queries.
Try updating the parser that you suspect has changed (`:TSUpdate {language}`) or all of them (`:TSUpdate`).
If the error persists after updating all parsers,
please [open an issue](https://github.com/nvim-treesitter/nvim-treesitter/issues/new/choose).
2020-11-21 22:07:17 +01:00
* **I experience weird highlighting issues similar to [#78](https://github.com/nvim-treesitter/nvim-treesitter/issues/78)**
This is a well known issue, which arise when the tree and the buffer are getting out of sync.
2020-07-21 18:15:20 +02:00
As this issue comes from upstream, we don't have any finite fix. To get around this, you can force reparsing the buffer with this command:
```vim
:write | edit | TSBufEnable highlight
```
This will save, restore and enable highlighting for the current buffer, fixing the issue.
2020-08-27 14:59:01 +02:00
2020-11-21 22:07:17 +01:00
* **I experience bugs when using `nvim-treesitter`'s `foldexpr` similar to [#194](https://github.com/nvim-treesitter/nvim-treesitter/issues/194)**
2020-08-27 14:59:01 +02:00
This might happen, and is known to happen with `vim-clap`, to avoid those kind of errors, please use
`setlocal` instead of `set` for the appropriate filetypes.