mirror of
https://github.com/stevearc/aerial.nvim
synced 2024-09-16 14:34:08 +02:00
feat(ts): Add support for elixir
This commit is contained in:
parent
17773f8e31
commit
897d4bd852
7 changed files with 287 additions and 1 deletions
|
@ -123,6 +123,7 @@ automatically fetch symbols from treesitter.
|
|||
- c_sharp
|
||||
- cpp
|
||||
- dart
|
||||
- elixir
|
||||
- go
|
||||
- java
|
||||
- javascript
|
||||
|
|
|
@ -61,6 +61,40 @@ local function set_end_range(bufnr, items, last_line)
|
|||
end
|
||||
end
|
||||
|
||||
M.elixir = {
|
||||
kind_map = {
|
||||
callback = "Function",
|
||||
def = "Function",
|
||||
defguard = "Function",
|
||||
defimpl = "Class",
|
||||
defmacro = "Function",
|
||||
defmacrop = "Function",
|
||||
defmodule = "Module",
|
||||
defp = "Function",
|
||||
defprotocol = "Interface",
|
||||
defstruct = "Struct",
|
||||
module_attribute = "Field",
|
||||
spec = "TypeParameter",
|
||||
},
|
||||
postprocess = function(bufnr, item, match)
|
||||
local identifier = (utils.get_at_path(match, "identifier") or {}).node
|
||||
if identifier then
|
||||
local name = get_node_text(identifier, bufnr) or "<parse error>"
|
||||
item.kind = M.elixir.kind_map[name] or item.kind
|
||||
if name == "callback" and item.parent then
|
||||
item.parent.kind = "Interface"
|
||||
elseif name == "defstruct" and item.parent then
|
||||
item.parent.kind = "Struct"
|
||||
return false
|
||||
elseif name == "defimpl" then
|
||||
local protocol = (utils.get_at_path(match, "protocol") or {}).node
|
||||
local protocol_name = get_node_text(protocol, bufnr) or "<parse error>"
|
||||
item.name = string.format("%s > %s", item.name, protocol_name)
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
M.markdown = {
|
||||
get_parent = function(stack, match, node)
|
||||
local level_node = (utils.get_at_path(match, "level") or {}).node
|
||||
|
|
|
@ -100,7 +100,9 @@ M.fetch_symbols_sync = function(bufnr)
|
|||
col = col,
|
||||
end_col = end_col,
|
||||
}
|
||||
ext.postprocess(bufnr, item, match)
|
||||
if ext.postprocess(bufnr, item, match) == false then
|
||||
goto continue
|
||||
end
|
||||
if item.parent then
|
||||
if not item.parent.children then
|
||||
item.parent.children = {}
|
||||
|
|
|
@ -28,6 +28,9 @@ return {
|
|||
method_signature = "Method",
|
||||
enum_declaration = "Enum",
|
||||
},
|
||||
elixir = {
|
||||
call = "Function",
|
||||
},
|
||||
go = {
|
||||
function_declaration = "Function",
|
||||
method_declaration = "Method",
|
||||
|
|
38
queries/elixir/aerial.scm
Normal file
38
queries/elixir/aerial.scm
Normal file
|
@ -0,0 +1,38 @@
|
|||
(call
|
||||
target: (identifier) @identifier (#any-of? @identifier "defmodule" "defprotocol")
|
||||
(arguments) @name) @type
|
||||
|
||||
(call
|
||||
target: (identifier) @identifier (#eq? @identifier "defimpl")
|
||||
(arguments
|
||||
(alias) @protocol
|
||||
(keywords (pair
|
||||
key: (keyword) @kw (#match? @kw "^for:")
|
||||
value: (alias) @name))
|
||||
)) @type
|
||||
|
||||
(call
|
||||
target: (identifier) @identifier (#any-of? @identifier "def" "defp" "defguard" "defmacro" "defmacrop")
|
||||
(arguments [
|
||||
(call target: (identifier) @name)
|
||||
(binary_operator left: (call target: (identifier) @name))
|
||||
])) @type
|
||||
|
||||
(unary_operator
|
||||
operand: (call
|
||||
target: (identifier) @identifier (#any-of? @identifier "callback" "spec")
|
||||
(arguments [
|
||||
(call target: (identifier) @name)
|
||||
(binary_operator left: (call target: (identifier) @name))
|
||||
])) @type) @start
|
||||
|
||||
(unary_operator
|
||||
operand: (call
|
||||
target: (identifier) @identifier (#eq? @identifier "module_attribute")
|
||||
(arguments) @name
|
||||
) @type
|
||||
) @start
|
||||
|
||||
(do_block
|
||||
(call
|
||||
target: (identifier) @identifier (#eq? @identifier "defstruct")) @type) @start
|
169
tests/treesitter/elixir_spec.lua
Normal file
169
tests/treesitter/elixir_spec.lua
Normal file
|
@ -0,0 +1,169 @@
|
|||
local util = require("tests.test_util")
|
||||
|
||||
describe("treesitter elixir", function()
|
||||
it("parses all symbols correctly", function()
|
||||
util.test_file_symbols("treesitter", "./tests/treesitter/elixir_test.exs", {
|
||||
{
|
||||
kind = "Module",
|
||||
name = "Example.Module",
|
||||
level = 0,
|
||||
lnum = 1,
|
||||
col = 0,
|
||||
end_lnum = 19,
|
||||
end_col = 3,
|
||||
children = {
|
||||
{
|
||||
kind = "Field",
|
||||
name = ":value",
|
||||
level = 1,
|
||||
lnum = 2,
|
||||
col = 2,
|
||||
end_lnum = 2,
|
||||
end_col = 26,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "public_function",
|
||||
level = 1,
|
||||
lnum = 4,
|
||||
col = 2,
|
||||
end_lnum = 5,
|
||||
end_col = 5,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "private_function",
|
||||
level = 1,
|
||||
lnum = 7,
|
||||
col = 2,
|
||||
end_lnum = 8,
|
||||
end_col = 5,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "public_guard",
|
||||
level = 1,
|
||||
lnum = 10,
|
||||
col = 2,
|
||||
end_lnum = 10,
|
||||
end_col = 42,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "private_guard",
|
||||
level = 1,
|
||||
lnum = 12,
|
||||
col = 2,
|
||||
end_lnum = 12,
|
||||
end_col = 43,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "public_macro",
|
||||
level = 1,
|
||||
lnum = 14,
|
||||
col = 2,
|
||||
end_lnum = 15,
|
||||
end_col = 5,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "private_macro",
|
||||
level = 1,
|
||||
lnum = 17,
|
||||
col = 2,
|
||||
end_lnum = 18,
|
||||
end_col = 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "Interface",
|
||||
name = "Example.Behaviour",
|
||||
level = 0,
|
||||
lnum = 21,
|
||||
col = 0,
|
||||
end_lnum = 23,
|
||||
end_col = 3,
|
||||
children = {
|
||||
{
|
||||
kind = "Function",
|
||||
name = "example_function",
|
||||
level = 1,
|
||||
lnum = 22,
|
||||
col = 2,
|
||||
end_lnum = 22,
|
||||
end_col = 46,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "Struct",
|
||||
name = "Example.Struct",
|
||||
level = 0,
|
||||
lnum = 25,
|
||||
col = 0,
|
||||
end_lnum = 27,
|
||||
end_col = 3,
|
||||
},
|
||||
{
|
||||
kind = "Interface",
|
||||
name = "Example.Protocol",
|
||||
level = 0,
|
||||
lnum = 29,
|
||||
col = 0,
|
||||
end_lnum = 32,
|
||||
end_col = 3,
|
||||
children = {
|
||||
{
|
||||
kind = "TypeParameter",
|
||||
name = "public_function_head",
|
||||
level = 1,
|
||||
lnum = 30,
|
||||
col = 2,
|
||||
end_lnum = 30,
|
||||
end_col = 50,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "public_function_head",
|
||||
level = 1,
|
||||
lnum = 31,
|
||||
col = 2,
|
||||
end_lnum = 31,
|
||||
end_col = 39,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "Class",
|
||||
name = "Map > Example.Protocol",
|
||||
level = 0,
|
||||
lnum = 34,
|
||||
col = 0,
|
||||
end_lnum = 39,
|
||||
end_col = 3,
|
||||
children = {
|
||||
{
|
||||
kind = "TypeParameter",
|
||||
name = "public_function_head",
|
||||
level = 1,
|
||||
lnum = 35,
|
||||
col = 2,
|
||||
end_lnum = 35,
|
||||
end_col = 56,
|
||||
},
|
||||
{
|
||||
kind = "Function",
|
||||
name = "public_function_head",
|
||||
level = 1,
|
||||
lnum = 36,
|
||||
col = 2,
|
||||
end_lnum = 38,
|
||||
end_col = 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
end)
|
||||
end)
|
39
tests/treesitter/elixir_test.exs
Normal file
39
tests/treesitter/elixir_test.exs
Normal file
|
@ -0,0 +1,39 @@
|
|||
defmodule Example.Module do
|
||||
@module_attribute :value
|
||||
|
||||
def public_function() do
|
||||
end
|
||||
|
||||
defp private_function() do
|
||||
end
|
||||
|
||||
defguard public_guard(x) when is_atom(x)
|
||||
|
||||
defguard private_guard(x) when is_atom(x)
|
||||
|
||||
defmacro public_macro() do
|
||||
end
|
||||
|
||||
defmacrop private_macro() do
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Example.Behaviour do
|
||||
@callback example_function(atom()) :: atom()
|
||||
end
|
||||
|
||||
defmodule Example.Struct do
|
||||
defstruct name: nil, age: nil
|
||||
end
|
||||
|
||||
defprotocol Example.Protocol do
|
||||
@spec public_function_head(t, atom()) :: boolean
|
||||
def public_function_head(target, opt)
|
||||
end
|
||||
|
||||
defimpl Example.Protocol, for: Map do
|
||||
@spec public_function_head(Map.t(), atom()) :: boolean
|
||||
def public_function_head(target, opt) do
|
||||
true
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue