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-08-10 18:33:34 +02:00
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-07-27 09:23:42 -05:00
2020-09-10 13:57:42 -05:00

2020-07-27 20:59:51 -05:00
Traditional highlighting (left) vs Treesitter-based highlighting (right).
2020-09-18 17:20:17 -05:00
See more examples in [our gallery ](https://github.com/nvim-treesitter/nvim-treesitter/wiki/Gallery ).
2020-07-27 20:59:51 -05:00
2020-06-21 17:39:58 +02:00
**Warning: Treesitter and Treesitter highlighting are an experimental feature of nightly versions of Neovim.
Please consider the experience with this plug-in as experimental until Neovim 0.5 is released!**
2020-04-22 17:17:21 +02:00
# Quickstart
## Requirements
2020-07-27 09:23:42 -05:00
- Neovim [nightly ](https://github.com/neovim/neovim#install-from-source )
2020-10-15 22:36:59 +02:00
- `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 )).
2020-04-22 17:17:21 +02:00
## Installation
2020-04-23 12:51:00 -04:00
You can install `nvim-treesitter` with your favorite package manager, or using the default `pack` feature of Neovim!
2020-04-22 17:17:21 +02:00
### Using a package manager
2020-08-09 11:39:51 -05:00
If you are using [vim-plug ](https://github.com/junegunn/vim-plug ), put this in your `init.vim` file:
2020-07-27 09:23:42 -05:00
2020-04-22 17:17:21 +02:00
```vim
Plug 'nvim-treesitter/nvim-treesitter'
```
2020-07-27 20:59:51 -05:00
### Using Neovim `pack` feature
2020-04-22 17:17:21 +02:00
2020-04-22 19:36:10 +02:00
We highly recommend reading `:h packages` to learn more about this feature, but you can still follow these steps:
2020-07-27 09:23:42 -05:00
2020-04-22 17:17:21 +02:00
```sh
$ mkdir -p ~/.local/share/nvim/site/pack/nvim-treesitter/start
$ cd ~/.local/share/nvim/site/pack/nvim-treesitter/start
$ git clone https://github.com/nvim-treesitter/nvim-treesitter.git
```
## Adding 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}
```
This command supports tab expansion. You can also get a list of all available languages and their installation status with `:TSInstallInfo` .
2020-04-22 17:17:21 +02:00
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-07-27 09:23:42 -05:00
2020-11-21 20:32:24 +01:00
### Adding unsupported parsers
2020-04-22 17:17:21 +02:00
2020-11-21 20:32:24 +01:00
If you have a parser that is not on the list (either from a repository on Github or a local directory), you can add it manually for use by `nvim-treesitter` as follows:
2020-04-22 17:17:21 +02:00
2020-11-21 20:32:24 +01:00
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).
2020-11-21 18:56:53 +01:00
3. Add the following snippet to your `init.vim` :
2020-07-27 09:23:42 -05:00
2020-04-22 17:17:21 +02:00
```vim
2020-11-21 18:56:53 +01:00
lua < < EOF
2020-11-21 20:32:24 +01:00
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
2020-11-21 18:56:53 +01:00
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
}
2020-11-21 20:32:24 +01:00
EOF
2020-04-22 17:17:21 +02:00
```
2020-11-21 20:32:24 +01:00
4. Start `nvim` and `:TSInstall zimbu` .
2020-11-21 18:56:53 +01:00
2020-11-21 20:32:24 +01:00
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-04-22 17:17:21 +02:00
2020-11-21 20:32:24 +01:00
Note that this only installs the parser itself; using it for, e.g., highlighting also requires corresponding queries that need to be written and placed in the appropriate directory (e.g., as `queries/zimbu/highlights.scm` ).
2020-11-21 19:38:30 +01:00
2020-04-28 11:56:00 +02:00
## Setup
2020-07-27 20:59:51 -05:00
All modules are disabled by default,
2020-08-09 11:39:51 -05:00
so you'll need to activate them by putting this in your `init.vim` file:
2020-04-28 11:56:00 +02:00
2020-11-12 19:34:35 -03:00
```vim
2020-11-11 16:52:35 -03:00
lua < < EOF
2020-04-28 11:56:00 +02:00
require'nvim-treesitter.configs'.setup {
2020-09-27 12:13:11 +02:00
ensure_installed = "maintained", -- one of "all", "maintained" (parsers with maintainers), or a list of languages
2020-08-09 11:39:51 -05:00
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-08-09 11:39:51 -05:00
```
Check [`:h nvim-treesitter-modules` ](doc/nvim-treesitter.txt )
for a list of available modules and its options.
2020-09-16 07:03:22 -05:00
# Available modules
2020-08-09 11:39:51 -05:00
## Highlight
Consistent syntax highlighting.
2020-11-12 19:34:35 -03:00
```vim
lua < < EOF
2020-08-09 11:39:51 -05:00
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-04-28 11:56:00 +02:00
},
2020-08-09 11:39:51 -05:00
},
}
2020-11-12 19:34:35 -03:00
EOF
2020-08-09 11:39:51 -05:00
```
## Incremental selection
Incremental selection based on the named nodes from the grammar.
2020-11-12 19:34:35 -03:00
```vim
lua < < EOF
2020-08-09 11:39:51 -05:00
require'nvim-treesitter.configs'.setup {
incremental_selection = {
enable = true,
keymaps = {
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
2020-05-01 12:26:57 +02:00
},
2020-08-09 11:39:51 -05:00
},
}
2020-11-12 19:34:35 -03:00
EOF
2020-08-09 11:39:51 -05:00
```
2020-10-19 21:32:54 +02:00
## Indentation
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-09-16 07:03:22 -05:00
# External modules
Other modules can be installed as plugins.
2020-10-02 14:04:33 +02:00
- [refactor ](https://github.com/nvim-treesitter/nvim-treesitter-refactor ) - Refactoring and definition modules
2020-10-04 13:53:17 -07:00
- [textobjects ](https://github.com/nvim-treesitter/nvim-treesitter-textobjects ) - Textobjects defined by tree-sitter queries
2020-09-16 07:03:22 -05:00
- [playground ](https://github.com/nvim-treesitter/playground ) - Treesitter integrated playground
2020-10-19 05:56:49 -04:00
- [context ](https://github.com/romgrk/nvim-treesitter-context ) - Show parent code context in a popover
2020-08-09 11:39:51 -05:00
# Extra features
2020-09-07 11:41:37 -05:00
## Syntax based code folding
2020-08-09 11:39:51 -05:00
```vim
set foldmethod=expr
set foldexpr=nvim_treesitter#foldexpr ()
```
2020-09-07 11:41:37 -05:00
This will respect your `foldnestmax` setting.
## Statusline indicator
2020-08-09 11:39:51 -05:00
```vim
echo nvim_treesitter#statusline (90) " 90 can be any length
module->expression_statement->call->identifier
```
# Commands
2020-04-28 11:56:00 +02:00
Each feature can be enabled or disabled by different means:
2020-07-27 09:23:42 -05:00
2020-04-28 11:56:00 +02:00
```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
```
2020-08-09 11:39:51 -05:00
Check [`:h nvim-treesitter-commands` ](doc/nvim-treesitter.txt ) for a list of all available commands.
2020-04-22 17:17:21 +02:00
2020-11-21 20:32:24 +01:00
# <a name="supported"></a>Supported Languages
2020-07-27 09:23:42 -05:00
2020-08-09 11:39:51 -05:00
For `nvim-treesitter` to work, we need to use query files such as those you can find in
`queries/{lang}/{locals,highlights,textobjects}.scm`
2020-07-27 09:23:42 -05:00
2020-08-09 11:39:51 -05:00
We are looking for maintainers to write query files for their languages.
2020-04-22 17:17:21 +02:00
2020-08-09 11:39:51 -05:00
List of currently supported languages:
2020-04-22 17:17:21 +02:00
2020-08-30 14:29:10 +02:00
<!-- This section of the README is automatically updated by a CI job -->
2020-08-15 18:12:37 +02:00
<!-- 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 )
2020-11-09 19:06:52 +00:00
- [x] [clojure ](https://github.com/sogaiu/tree-sitter-clojure ) (maintained by @sogaiu )
2020-08-15 18:12:37 +02:00
- [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 )
2020-11-18 22:47:21 +00:00
- [x] [nix ](https://github.com/cstrahan/tree-sitter-nix ) (maintained by @leo60228 )
2020-08-15 18:12:37 +02:00
- [x] [ocaml ](https://github.com/tree-sitter/tree-sitter-ocaml ) (maintained by @undu )
2020-09-15 13:41:37 +00:00
- [x] [ocaml_interface ](https://github.com/tree-sitter/tree-sitter-ocaml ) (maintained by @undu )
2020-10-03 13:27:44 +00:00
- [x] [ocamllex ](https://github.com/atom-ocaml/tree-sitter-ocamllex ) (maintained by @undu )
2020-08-15 18:12:37 +02:00
- [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 )
2020-09-30 14:54:47 +00:00
- [x] [ql ](https://github.com/tree-sitter/tree-sitter-ql ) (maintained by @pwntester )
2020-08-15 18:12:37 +02:00
- [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 )
2020-10-10 13:25:02 +00:00
- [x] [teal ](https://github.com/euclidianAce/tree-sitter-teal ) (maintained by @euclidianAce )
2020-08-15 18:12:37 +02:00
- [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 )
2020-10-20 13:09:28 +00:00
- [x] [verilog ](https://github.com/tree-sitter/tree-sitter-verilog ) (maintained by @zegervdv )
2020-08-15 18:12:37 +02:00
- [ ] [vue ](https://github.com/ikatyang/tree-sitter-vue )
- [ ] [yaml ](https://github.com/ikatyang/tree-sitter-yaml )
<!-- parserinfo -->
2020-08-09 11:39:51 -05:00
# Roadmap
2020-06-29 09:58:51 -05:00
2020-08-09 11:39:51 -05:00
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.
You can find the roadmap [here ](https://github.com/nvim-treesitter/nvim-treesitter/projects/1 ).
The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated!
2020-06-29 09:58:51 -05:00
2020-08-09 11:39:51 -05:00
# Defining Modules
2020-07-02 10:26:53 -05:00
Users and plugin authors can take advantage of modules by creating their own. Modules provide:
- Treesitter language detection support
- Attach and detach to buffers
- Works with all nvim-treesitter commands
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
2020-08-09 11:39:51 -05:00
require'nvim-treesitter'.define_modules {
2020-07-02 10:26:53 -05:00
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-07-02 10:26:53 -05:00
```
Modules can consist of 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.
2020-07-27 09:23:42 -05:00
- `attach` : A function that attaches to a buffer. This is required if `module_path` is not provided.
2020-07-02 10:26:53 -05:00
- `detach` : A function that detaches from a buffer. This is required if `module_path` is not provided.
2020-08-09 11:39:51 -05:00
# Utils
2020-05-15 14:19:29 +02:00
2020-07-27 20:59:51 -05:00
You can get some utility functions with
2020-07-27 09:23:42 -05:00
2020-05-15 14:19:29 +02:00
```lua
2020-06-19 13:51:09 +02:00
local ts_utils = require 'nvim-treesitter.ts_utils'
2020-05-15 14:19:29 +02:00
```
2020-04-28 11:56:00 +02:00
2020-08-09 11:39:51 -05:00
Check [`:h nvim-treesitter-utils` ](doc/nvim-treesitter.txt ) for more information.
2020-04-28 11:56:00 +02:00
2020-08-09 11:39:51 -05:00
# User Query Extensions
2020-06-12 14:11:37 -05:00
2020-08-12 23:06:08 +02:00
Queries are what `nvim-treesitter` uses to extract informations from the syntax tree, and they are
located in the `queries/{lang}/*` runtime directories (like the `queries` folder of this plugin).
`nvim-treesitter` considers queries as any runtime file (see `:h rtp` ), that is :
- 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.
This hybrid approach is the most standard way, and according to that, here is some ideas on how to
use is :
2020-11-11 16:52:35 -03:00
2020-08-12 23:06:08 +02: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-04-28 11:56:00 +02:00
2020-08-09 11:39:51 -05:00
# Troubleshooting
2020-07-27 09:23:42 -05:00
2020-08-01 15:33:44 -05:00
Before doing anything make sure you have the latest version of this plugin and run `:checkhealth nvim_treesitter` .
This will help you find where the bug might come from.
2020-04-22 17:17:21 +02:00
2020-08-09 11:39:51 -05:00
## Feature `X` does not work for `{language}`...
2020-07-27 09:23:42 -05:00
2020-07-27 20:59:51 -05:00
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.
2020-04-22 17:17:21 +02:00
If everything is okay, then it might be an actual error.
2020-07-27 20:59:51 -05:00
In both cases, feel free to [open an issue here ](https://github.com/nvim-treesitter/nvim-treesitter/issues/new/choose ).
2020-07-15 09:24:57 +02:00
2020-09-18 17:47:20 -05:00
## I get `module 'vim.treesitter.query' not found`
Make sure you have the latest nightly version of Neovim.
2020-08-09 11:39:51 -05:00
## I get `Error detected while processing .../plugin/nvim-treesitter.vim` every time I open Neovim
2020-08-01 15:33:44 -05:00
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-08-09 11:39:51 -05:00
## I experience weird highlighting issues similar to [#78](https://github.com/nvim-treesitter/nvim-treesitter/issues/78)
2020-07-15 09:24:57 +02:00
2020-07-27 20:59:51 -05:00
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:
2020-07-27 09:23:42 -05:00
2020-07-15 09:24:57 +02:00
```vim
:write | edit | TSBufEnable highlight
```
2020-07-27 09:23:42 -05:00
This will save, restore and enable highlighting for the current buffer, fixing the issue.
2020-08-27 14:59:01 +02:00
## I experience bugs when using `nvim-treesitter`'s `foldexpr` similar to [#194](https://github.com/nvim-treesitter/nvim-treesitter/issues/194)
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.