Skip to content

Commit

Permalink
unify the closest node and node of kind selection commands; better docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ul committed Jan 2, 2019
1 parent 6d23cfa commit 06e96e1
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 118 deletions.
65 changes: 31 additions & 34 deletions README.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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, API and overall development direction could change drastically based on feedback.
Status: proof of concept, interface and overall development direction could change drastically based on feedback.

== Installation

Expand Down Expand Up @@ -30,46 +30,39 @@ guaranteed in future).

== Usage

NOTE: "The deepest enclosing node" means the one which matters. It means that node is named (does
have name in the language grammar definition) and is either whitelisted (if whitelist is defined)
or not blacklisted (if blacklist is defined). See Configuration section to learn more about
white/blacklisting.
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:

[cols=2*]
|===
| tree-select-parent-node
| Extend selections to the deepest enclosing nodes. If any selection is equal to node range, then
extend to one's parent range.
. 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 <<Configuration>> for details about white/blacklisting.

| tree-select-next-node
| Select the deepest enclosing nodes' next siblings.
Most of the kak-tree commands operate on _visible_ nodes and skip not _visible_ ones.

| tree-select-prev-node
| Select the deepest enclosing nodes' previous siblings.
[cols=2*]
|===

| tree-node-sexp
| Show info box with a syntax tree of the deepest enclosing node of the main selection. This time
"deepest" means "deepest", including anonymous and blacklisted nodes, without any filter applied.
| tree-select-parent-node [<KIND>]
| Select the closest visible ancestor or ancestor of KIND when provided.

| tree-select-first-child
| Find the deepest enclosing nodes of selections and then select each node's first child. If node
has no children then keep selection on node.
| tree-select-next-node [<KIND>]
| Select the closest visible next sibling or next sibling of KIND when provided.

| tree-select-children
| Find the deepest enclosing nodes of selections and then select each node's children. If node has
no children then keep selection on node.
| tree-select-previous-node [<KIND>]
| Select the closest visible previous sibling or previous sibling of KIND when provided.

| tree-select-kind <KIND>
| Selects all the KIND nodes wholly contained within an existing selection.
| tree-select-children [<KIND>]
| Select all immediate visible children or all descendants matching KIND when provided.

| tree-select-parent-kind <KIND>
| Select the closest ancestors of KIND of selections' deepest enclosing nodes. If any of selections
don't have such ancestor, remove that selection.
| tree-select-first-child [<KIND>]
| 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.
|===

More commands to come.

== Configuration

kak-tree supports configuration via a configuration file. As for now there is no default path to
Expand All @@ -94,23 +87,27 @@ group.fn = ["function_item"]
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 example above kak-tree would expand
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.
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 when using commands like `tree-select-kind` and
`tree-select-parent-kind`:
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.
Expand Down
67 changes: 55 additions & 12 deletions rc/tree.kak
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# Path to the kak-tree executable.
# To load config: set-option global tree_cmd "kak-tree --config /path/to/kak-tree.toml"
# To enable debug logging: set-option global tree_cmd "kak-tree -vvv"
declare-option str tree_cmd "kak-tree"

# Path to the log file.
declare-option str tree_log "/tmp/kak-tree.log"

# Option to store draft of the current buffer before passing to shell.
declare-option -hidden str tree_draft

define-command -hidden tree-command -params 1..2 %{
define-command -hidden tree-command -params 1..2 -docstring %{
tree-command <OP_TYPE> [<OP_PARAMS>]
Send request to kak-tree and evaluate response.
} %{
evaluate-commands -draft -no-hooks %{exec '%'; set buffer tree_draft %val{selection}}
evaluate-commands %sh{
Expand All @@ -12,25 +21,59 @@ tree_draft=$(printf '%s.' "${kak_opt_tree_draft}" | sed 's/\\/\\\\/g' | sed 's/"
tree_draft=${tree_draft%.}
printf '
op = "%s"
param = "%s"
filetype = "%s"
selections_desc = "%s"
content = """
%s"""
' $1 "$2" "${kak_opt_filetype}" "${kak_selections_desc}" "${tree_draft}" | ${kak_opt_tree_cmd} 2>${kak_opt_tree_log}
[op]
type = "%s"
%s
' "${kak_opt_filetype}" "${kak_selections_desc}" "${tree_draft}" $1 "$2" | ${kak_opt_tree_cmd} 2>${kak_opt_tree_log}
}
}


define-command -hidden tree-command-with-optional-kind -params 1..2 -docstring %{
tree-command-with-optional-kind <OP_TYPE> [<KIND>]
Send request which optionally takes node kind.
} %{
tree-command %arg{1} %sh{
if [ -n "$2" ]; then
printf 'kind = "%s"' "$2"
fi
}
}

define-command tree-select-parent-node -params ..1 -docstring %{
tree-select-parent-node [<KIND>]
Select the closest visible ancestor or ancestor of KIND when provided.
} %{ tree-command-with-optional-kind SelectParentNode %arg{1} }

define-command tree-select-next-node -params ..1 -docstring %{
tree-select-next-node [<KIND>]
Select the closest visible next sibling or next sibling of KIND when provided.
} %{ tree-command-with-optional-kind SelectNextNode %arg{1} }

define-command tree-select-previous-node -params ..1 -docstring %{
tree-select-previous-node [<KIND>]
Select the closest visible previous sibling or previous sibling of KIND when provided.
} %{ tree-command-with-optional-kind SelectPreviousNode %arg{1} }

define-command tree-select-parent-node %{ tree-command SelectParentNode }
define-command tree-select-next-node %{ tree-command SelectNextNode }
define-command tree-select-prev-node %{ tree-command SelectPrevNode }
define-command tree-select-first-child %{ tree-command SelectFirstChild }
define-command tree-select-children %{ tree-command SelectChildren }
define-command tree-node-sexp %{ tree-command NodeSExp }
define-command tree-select-kind -params 1 %{ tree-command SelectKind %arg{1} }
define-command tree-select-parent-kind -params 1 %{ tree-command SelectParentKind %arg{1} }
define-command tree-select-children -params ..1 -docstring %{
tree-select-children [<KIND>]
Select all immediate visible children or all descendants matching KIND when provided.
} %{ tree-command-with-optional-kind SelectChildren %arg{1} }

define-command tree-node-sexp -docstring %{
tree-node-sexp
Show info box with a syntax tree of the main selection parent.
} %{ tree-command NodeSExp }

define-command tree-select-first-child -params ..1 -docstring %{
tree-select-first-child [<KIND>]
Select the first immediate visible children or the first descendant matching KIND when provided.
} %{
tree-command-with-optional-kind SelectChildren %arg{1}
execute-keys <space>
}

Loading

0 comments on commit 06e96e1

Please sign in to comment.