mirror of
https://github.com/stevearc/aerial.nvim
synced 2024-09-16 14:34:08 +02:00
feat: add support for vim help files (#164)
This commit is contained in:
parent
c2487319c0
commit
817be1d211
6 changed files with 124 additions and 4 deletions
|
@ -119,6 +119,62 @@ M.markdown = {
|
|||
end,
|
||||
}
|
||||
|
||||
M.help = {
|
||||
_get_level = function(node)
|
||||
local level_str = node:type():match("^h(%d+)$")
|
||||
if level_str then
|
||||
return tonumber(level_str)
|
||||
else
|
||||
return 99
|
||||
end
|
||||
end,
|
||||
get_parent = function(stack, match, node)
|
||||
-- Fix the symbol nesting
|
||||
local level = M.help._get_level(node)
|
||||
for i = #stack, 1, -1 do
|
||||
local last = stack[i]
|
||||
if M.help._get_level(last.node) < level then
|
||||
return last.item, last.node, i
|
||||
else
|
||||
table.remove(stack, i)
|
||||
end
|
||||
end
|
||||
return nil, nil, 0
|
||||
end,
|
||||
postprocess = function(bufnr, item, match)
|
||||
-- The name node of headers only captures the final node.
|
||||
-- We need to get _all_ word nodes
|
||||
local pieces = {}
|
||||
local node = match.name.node
|
||||
if vim.startswith(match.type.node:type(), "h") then
|
||||
while node and node:type() == "word" do
|
||||
local row, col = node:start()
|
||||
table.insert(pieces, 1, get_node_text(node, bufnr))
|
||||
node = node:prev_sibling()
|
||||
item.lnum = row + 1
|
||||
item.col = col
|
||||
end
|
||||
item.name = table.concat(pieces, " ")
|
||||
end
|
||||
end,
|
||||
postprocess_symbols = function(bufnr, items)
|
||||
-- Sometimes helpfiles have a bunch of tags at the top in the same line. Collapse them.
|
||||
while #items > 1 and items[1].lnum == items[2].lnum do
|
||||
table.remove(items, 2)
|
||||
end
|
||||
-- Remove the first tag under a header IF that tag appears on the same line
|
||||
for _, item in ipairs(items) do
|
||||
if item.children and item.children[1] then
|
||||
local child = item.children[1]
|
||||
if child.lnum == item.lnum then
|
||||
table.remove(item.children, 1)
|
||||
end
|
||||
M.help.postprocess_symbols(bufnr, item.children)
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
M.rust = {
|
||||
postprocess = function(bufnr, item, match)
|
||||
if item.kind == "Class" then
|
||||
|
|
|
@ -62,12 +62,12 @@ M.fetch_symbols_sync = function(bufnr)
|
|||
local ext = extensions[lang]
|
||||
local kind_map = language_kind_map[lang]
|
||||
for match in query.iter_group_results(bufnr, "aerial", syntax_tree:root(), lang) do
|
||||
local name_node = (utils.get_at_path(match, "name") or {}).node
|
||||
local type_node = (utils.get_at_path(match, "type") or {}).node
|
||||
local name_node = (match.name or {}).node
|
||||
local type_node = (match.type or {}).node
|
||||
-- The location capture groups are optional. We default to the
|
||||
-- location of the @type capture
|
||||
local start_node = (utils.get_at_path(match, "start") or {}).node or type_node
|
||||
local end_node = (utils.get_at_path(match, "end") or {}).node or start_node
|
||||
local start_node = (match.start or {}).node or type_node
|
||||
local end_node = (match["end"] or {}).node or start_node
|
||||
local parent_item, parent_node, level = ext.get_parent(stack, match, type_node)
|
||||
-- Sometimes our queries will match the same node twice.
|
||||
-- Detect that (type_node == parent_node), and skip dupes.
|
||||
|
|
|
@ -38,6 +38,11 @@ return {
|
|||
method_declaration = "Method",
|
||||
struct_type = "Struct",
|
||||
},
|
||||
help = {
|
||||
h1 = "Interface",
|
||||
h2 = "Interface",
|
||||
tag = "Interface",
|
||||
},
|
||||
java = {
|
||||
class_declaration = "Class",
|
||||
enum_declaration = "Enum",
|
||||
|
|
13
queries/help/aerial.scm
Normal file
13
queries/help/aerial.scm
Normal file
|
@ -0,0 +1,13 @@
|
|||
(h1
|
||||
(word)+ @name @start
|
||||
(tag)
|
||||
) @type
|
||||
|
||||
(h2
|
||||
(word)+ @name @start
|
||||
(tag)
|
||||
) @type
|
||||
|
||||
(tag
|
||||
text: (word) @name
|
||||
) @type
|
37
tests/treesitter/help_spec.lua
Normal file
37
tests/treesitter/help_spec.lua
Normal file
|
@ -0,0 +1,37 @@
|
|||
local util = require("tests.test_util")
|
||||
|
||||
describe("treesitter help", function()
|
||||
it("parses all symbols correctly", function()
|
||||
util.test_file_symbols("treesitter", "./tests/treesitter/help_test.txt", {
|
||||
{
|
||||
kind = "Interface",
|
||||
name = "help_test.txt",
|
||||
level = 0,
|
||||
lnum = 1,
|
||||
col = 0,
|
||||
end_lnum = 1,
|
||||
end_col = 15,
|
||||
},
|
||||
{
|
||||
kind = "Interface",
|
||||
name = "TEST INTRO",
|
||||
level = 0,
|
||||
lnum = 3,
|
||||
col = 0,
|
||||
end_lnum = 3,
|
||||
end_col = 10,
|
||||
children = {
|
||||
{
|
||||
kind = "Interface",
|
||||
name = ":SomeCommand",
|
||||
level = 1,
|
||||
lnum = 5,
|
||||
col = 68,
|
||||
end_lnum = 5,
|
||||
end_col = 82,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
end)
|
||||
end)
|
9
tests/treesitter/help_test.txt
Normal file
9
tests/treesitter/help_test.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
*help_test.txt* *help_test*
|
||||
--------------------------------------------------------------------------------
|
||||
TEST INTRO *test-intro*
|
||||
|
||||
SomeCommand *:SomeCommand*
|
||||
Description of the command
|
||||
|
||||
================================================================================
|
||||
vim:tw=80:ts=2:ft=help:norl:syntax=help:
|
Loading…
Reference in a new issue