mirror of
https://github.com/stevearc/aerial.nvim
synced 2024-09-16 14:34:08 +02:00
feat: set scope from node captures and add basic query documentation (#318)
* Process scope captures This lets us avoid complex querying when extracting scope. As long as the capture includes a scoping node in a `@scope` capture, its text will be extracted and used as a scope value. If "public" is named differently in some language, `#set @scope "text" "public"` will do the trick for a cost of an additional query. * Add basic query documentation to readme and vimdoc * Add reusable language extensions info to readme
This commit is contained in:
parent
21e3358617
commit
2d169d3497
6 changed files with 75 additions and 18 deletions
20
README.md
20
README.md
|
@ -15,6 +15,8 @@ A code outline window for skimming and quick navigation
|
|||
- [Lualine](#lualine)
|
||||
- [Highlight](#highlight)
|
||||
- [API](#api)
|
||||
- [TreeSitter queries](#treesitter-queries)
|
||||
- [Language extensions](#language-extensions)
|
||||
- [FAQ](#faq)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
@ -724,6 +726,24 @@ hi AerialGuide2 guifg=Blue
|
|||
|
||||
<!-- /API -->
|
||||
|
||||
## TreeSitter queries
|
||||
|
||||
When writing queries, the following captures and metadata are used by Aerial:
|
||||
|
||||
- `@symbol` - **required** capture for the logical region being captured
|
||||
- `kind` - **required** metadata, a string value matching one of `vim.lsp.protocol.SymbolKind`
|
||||
- `@name` - capture to extract a name from its text
|
||||
- `@start` - a start of the match, influences matching of cursor position to aerial tree, defaults to `@symbol`
|
||||
- `@end` - an end of the match, influences matching of cursor position to aerial tree, defaults to `@start`
|
||||
- `@selection` - position to jump to when using Aerial for navigation, falls back to `@name` and `@symbol`
|
||||
- `@scope` - a node naming a scope for the match, its text is used to generate a custom "Comment" linked highlight for the entry, with exception of "public"
|
||||
|
||||
A `@scope` node with text "developers" will result in its entry in the tree having an "AerialDevelopers" highlight applied to it.
|
||||
|
||||
- `scope` - a metadata value serving the same role as `@scope` capture, overriding aforementioned capture
|
||||
|
||||
Note: a capture's text can be set or modified with `#set!` and `#gsub!` respectively.
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: I accidentally opened a file into the aerial window and it looks bad. How can I prevent this from happening?**
|
||||
|
|
|
@ -710,6 +710,31 @@ for each of these, but a migration cheat-sheet is provided below.
|
|||
close_behavior = "close" --> close_automatic_events = { "switch_buffer" }
|
||||
<
|
||||
|
||||
*aerial-treesitter-queries*
|
||||
|
||||
Aerial utilizes the following captures and metadata from its queries:
|
||||
|
||||
`@type` **required** capture for the logical region being captured
|
||||
`kind` **required** metadata, a string value matching one of
|
||||
`vim.lsp.protocol.SymbolKind`
|
||||
`@name` capture to extract a name from its text
|
||||
`@start` a start of the match, influences matching of cursor position
|
||||
to aerial tree, defaults to `@type`
|
||||
`@end` an end of the match, influences matching of cursor position
|
||||
to aerial tree, defaults to `@start`
|
||||
`@selection` position to jump to when using Aerial for navigation, only used
|
||||
if `treesitter.experimental_selection_range` is enabled,
|
||||
falls back to `@name` and `@type`
|
||||
`@scope` a scope for the match, its text is used to generate a custom
|
||||
"Comment" linked highlight for the entry, with exception of "public"
|
||||
For example:
|
||||
A `@scope` node with text `developers` will result in its entry
|
||||
in the tree having an "AerialDevelopers" highlight applied to it.
|
||||
`scope` a metadata value serving the same role as `@scope` capture,
|
||||
overriding aforementioned capture
|
||||
|
||||
Note: a capture's text can be set or modified with `#set!` and `#gsub!` respectively.
|
||||
|
||||
*SymbolKind* *symbol*
|
||||
A quick note on SymbolKind. An authoritative list of valid SymbolKinds can be
|
||||
found in the LSP spec:
|
||||
|
|
|
@ -78,6 +78,8 @@ M.elixir = {
|
|||
module_attribute = "Field",
|
||||
spec = "TypeParameter",
|
||||
},
|
||||
---@note Additionally processes the following captures:
|
||||
--- `@protocol` - extends the name to "@name > @protocol"
|
||||
postprocess = function(bufnr, item, match)
|
||||
local identifier = node_from_match(match, "identifier")
|
||||
if identifier then
|
||||
|
@ -131,6 +133,8 @@ M.markdown = {
|
|||
}
|
||||
|
||||
M.go = {
|
||||
---@note Additionally processes the following captures:
|
||||
--- `@receiver` - extends the name to "@receiver @name"
|
||||
postprocess = function(bufnr, item, match)
|
||||
local receiver = node_from_match(match, "receiver")
|
||||
if receiver then
|
||||
|
@ -218,6 +222,8 @@ M.rust = {
|
|||
}
|
||||
|
||||
M.ruby = {
|
||||
---@note Additionally processes the following captures:
|
||||
--- `@method`, `@receiver`, `@separator` - extends the name to "@method @reciever[@separator]@name", with @separator defaulting to "."
|
||||
postprocess = function(bufnr, item, match)
|
||||
-- Reciever modification comes first, as we intend for it to generate a ruby-like `reciever.name`
|
||||
local receiver = node_from_match(match, "receiver")
|
||||
|
@ -255,6 +261,8 @@ M.lua = {
|
|||
}
|
||||
|
||||
M.javascript = {
|
||||
---@note Additionally processes the following captures:
|
||||
--- `@method`, `@string`, and `@modifier` - replaces name with "@method[.@modifier] @string"
|
||||
postprocess = function(bufnr, item, match)
|
||||
local method = node_from_match(match, "method")
|
||||
local modifier = node_from_match(match, "modifier")
|
||||
|
@ -327,6 +335,8 @@ M.rst = {
|
|||
}
|
||||
|
||||
M.typescript = {
|
||||
---@note Additionally processes the following captures:
|
||||
--- `@method`, `@string`, and `@modifier` - replaces name with "@method[.@modifier] @string"
|
||||
postprocess = function(bufnr, item, match)
|
||||
local value_node = node_from_match(match, "var_type")
|
||||
if value_node then
|
||||
|
|
|
@ -117,14 +117,20 @@ M.fetch_symbols_sync = function(bufnr)
|
|||
else
|
||||
name = "<Anonymous>"
|
||||
end
|
||||
local scope
|
||||
if match.scope and match.scope.node then -- we've got a node capture on our hands
|
||||
scope = get_node_text(match.scope.node, bufnr, match.scope)
|
||||
else
|
||||
scope = match.scope
|
||||
end
|
||||
---@type aerial.Symbol
|
||||
local item = {
|
||||
kind = kind,
|
||||
name = name,
|
||||
level = level,
|
||||
parent = parent_item,
|
||||
scope = match.scope,
|
||||
selection_range = selection_range,
|
||||
scope = scope,
|
||||
}
|
||||
for k, v in pairs(range) do
|
||||
item[k] = v
|
||||
|
|
|
@ -3,37 +3,30 @@
|
|||
(#set! "kind" "Class")
|
||||
) @symbol
|
||||
|
||||
(method
|
||||
name: (_) @name
|
||||
(#set! "kind" "Method")
|
||||
) @symbol
|
||||
|
||||
(call
|
||||
(identifier) @scope_switch
|
||||
(#any-of? @scope_switch "private" "protected")
|
||||
|
||||
(
|
||||
(identifier) @scope
|
||||
(#any-of? @scope "private" "protected" "public")
|
||||
)?
|
||||
.
|
||||
(argument_list
|
||||
(method
|
||||
name: (_) @name
|
||||
(#set! "kind" "Method")
|
||||
(#set! "scope" "private")
|
||||
) @symbol
|
||||
)
|
||||
)
|
||||
|
||||
(body_statement
|
||||
(identifier) @scope @later_scope
|
||||
(#any-of? @scope "private" "protected")
|
||||
.
|
||||
[
|
||||
(_)
|
||||
((identifier) @later_scope (#not-eq? @later_scope "public"))
|
||||
((identifier) @scope
|
||||
(#any-of? @scope "private" "protected" "public"))
|
||||
]*
|
||||
.
|
||||
(method
|
||||
name: (_) @name
|
||||
(#set! "kind" "Method")
|
||||
(#set! "scope" "private")
|
||||
) @symbol
|
||||
)
|
||||
|
||||
|
|
|
@ -443,7 +443,7 @@
|
|||
"level": 1,
|
||||
"lnum": 64,
|
||||
"name": "protected_1",
|
||||
"scope": "private",
|
||||
"scope": "protected",
|
||||
"selection_range": {
|
||||
"col": 6,
|
||||
"end_col": 17,
|
||||
|
@ -474,7 +474,7 @@
|
|||
"level": 1,
|
||||
"lnum": 73,
|
||||
"name": "protected_2",
|
||||
"scope": "private",
|
||||
"scope": "protected",
|
||||
"selection_range": {
|
||||
"col": 6,
|
||||
"end_col": 17,
|
||||
|
@ -490,6 +490,7 @@
|
|||
"level": 1,
|
||||
"lnum": 76,
|
||||
"name": "inline_public",
|
||||
"scope": "public",
|
||||
"selection_range": {
|
||||
"col": 13,
|
||||
"end_col": 26,
|
||||
|
@ -505,7 +506,7 @@
|
|||
"level": 1,
|
||||
"lnum": 79,
|
||||
"name": "protected_3",
|
||||
"scope": "private",
|
||||
"scope": "protected",
|
||||
"selection_range": {
|
||||
"col": 6,
|
||||
"end_col": 17,
|
||||
|
@ -521,6 +522,7 @@
|
|||
"level": 1,
|
||||
"lnum": 83,
|
||||
"name": "public_2",
|
||||
"scope": "public",
|
||||
"selection_range": {
|
||||
"col": 6,
|
||||
"end_col": 14,
|
||||
|
@ -536,6 +538,7 @@
|
|||
"level": 1,
|
||||
"lnum": 86,
|
||||
"name": "public_setter=",
|
||||
"scope": "public",
|
||||
"selection_range": {
|
||||
"col": 6,
|
||||
"end_col": 20,
|
||||
|
|
Loading…
Reference in a new issue