ul / kak-tree

Structural selections for Kakoune
The Unlicense
100 stars 10 forks source link
kakoune plugin rust tree-sitter

= Structural selections for Kakoune

kak-tree is a plugin for Kakoune which enables selection of syntax tree nodes. Parsing is performed with https://github.com/tree-sitter/tree-sitter[tree-sitter].

Status: proof of concept, interface and overall development direction could change drastically based on feedback.

== Installation

Replace "rust javascript" with a list of languages you need. Or use all to build all supported languages. Note that all build takes a long time, and resulting binary is quite fat which could have a negative impact on responsiveness.


git clone --recurse-submodules cargo install --path . --force --features "rust javascript" cp rc/tree.kak ~/.config/kak/autoload/

Look at Cargo.toml for a full list of supported languages.

It is possible to check programmaticaly if kak-tree was built with support for a given filetype:


kak-tree --do-you-understand rust

If language is supported then exit code is 0 otherwise it's non-zero (1 at the moment, but it is not guaranteed in future).

== Usage

Tree-sitter parsers produce very detailed syntax tree, many elements of which are not interesting for day-to-day selection purposes. kak-tree introduces the concept of a visible node. Node is visible when:

. Node is named in the tree-sitter grammar for the given language (as opposed to anonymous nodes, http://tree-sitter.github.io/tree-sitter/using-parsers#named-vs-anonymous-nodes[more]). . Either there is no white/blacklist for the given filetype or node kind is whitelisted or not blacklisted. See <> for details about white/blacklisting.

Most of the kak-tree commands operate on visible nodes and skip not visible ones.

[cols=2*] |===

| tree-select-parent-node [] | Select the closest visible ancestor or ancestor of KIND when provided.

| tree-select-next-node [] | Select the closest visible next sibling or next sibling of KIND when provided.

| tree-select-previous-node [] | Select the closest visible previous sibling or previous sibling of KIND when provided.

| tree-select-children [] | Select all immediate visible children or all descendants matching KIND when provided.

| tree-select-first-child [] | Select the first immediate visible children or the first descendant matching KIND when provided.

| tree-node-sexp | Show info box with a syntax tree of the main selection parent. |===

== Configuration

kak-tree supports configuration via a configuration file. As for now there is no default path to load the configuration file, and it must be given using CLI option --config or -c for short:


set global tree_cmd 'kak-tree -c /path/to/kak-tree.toml'

=== Filetype configuration

Configuration for specific filetypes should be provided like this:


[filetype.rust] blacklist = ["identifier", "scoped_identifier", "string_literal"] whitelist = ["function_item"] group.identifier = ["identifier", "scoped_identifier"] group.fn = ["function_item"]

[filetype.javascript] group.fn = ["function", "arrow_function"]

Configuration under the [filetype.default] key will be used for all filetypes without configuration. Specific filetype configuration doesn't extend default configuration but rather overwrites it.

==== White/blacklisting

If whitelist array is provided then kak-tree selection will skip nodes which kinds are not whitelisted. If blacklist array is provided then kak-tree selection will skip nodes which kinds are blacklisted.

NOTE: whitelist takes precedence over blacklist. In the Rust example above kak-tree would expand selection up to the function definition, ignoring other node kinds.

NOTE: tree-node-sexp command is useful for exploring node kinds which appear in the specific code.

Whitelisting or blacklisting node kinds could be tedious as tree-sitter parsers define many of them, but it also could be rewarding as you will be able to quickly modify selection in scopes which matter for you with fewer keystrokes.

==== Kind groups

Groups of node kinds serve a two-fold purpose:

. Groups allow matching functionally similar node kinds (i.e. identifier and scoped_identifier in Rust) by a single query.

. Groups allow matching functionally similar nodes across filetypes (i.e. function_item in Rust and function in JavaScript) as tree-sitter parsers don't use uniform node kind names.

NOTE: whitelist and blacklist options doesn't expand groups yet.

== License

For kak-tree see UNLICENSE file. For tree-sitter and its parsers look at their repositories.