mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 19:10:24 +00:00
Add syntax highlighting and LSP (erlang_lsp) for Erlang (#7093)
This pull request implements support for the [Erlang Language](https://erlang.org/). **It adds:** * [tree-sitter-erlang](https://github.com/WhatsApp/tree-sitter-erlang) grammar highlights (Licensed under Apache-2 from WhatsApp which is compatible with Zed licensing model), folds and indents * Erlang file icon based on the [official one](https://www.erlang.org/doc/erlang-logo.png) * [erlang_ls](https://github.com/erlang-ls/erlang_ls) support Fixes https://github.com/zed-industries/zed/issues/4939, possibly a duplicate of https://github.com/zed-industries/zed/pull/7085 with more features. Suppose @wingyplus wants to join efforts here. **To complete (out of scope for this PR):** * Support for the ELP language server from WhatsApp. CC @robertoaloi * Better indentation handling, need something like `indentNextLinePattern` in VS Code **Screenshots:** ![Screenshot 2024-01-30 at 11 03 51 AM](https://github.com/zed-industries/zed/assets/168440/5289c245-9edd-46b8-b443-d7b3210f6510) ![Screenshot 2024-01-30 at 11 01 19 AM](https://github.com/zed-industries/zed/assets/168440/bd22b322-5344-44e6-b5f7-6e352fb3deef) ![Screenshot 2024-01-30 at 11 01 37 AM](https://github.com/zed-industries/zed/assets/168440/f28f6a15-383e-4719-8a87-fceae5062436) ![Screenshot 2024-01-30 at 11 02 03 AM](https://github.com/zed-industries/zed/assets/168440/980d5213-0367-4a08-86eb-5743dfa628eb) ![Screenshot 2024-01-30 at 11 02 19 AM](https://github.com/zed-industries/zed/assets/168440/ea998891-604d-48d6-929f-ae4c1bb3fae1) Outline: ![Screenshot 2024-01-31 at 9 09 36 AM](https://github.com/zed-industries/zed/assets/168440/46d56d94-21c3-414d-84fb-9251fa2506ab) **Release Notes:** * Added Erlang Support ([7093](https://github.com/zed-industries/zed/pull/7093)). --------- Signed-off-by: Thanabodee Charoenpiriyakij <wingyminus@gmail.com> Co-authored-by: Thanabodee Charoenpiriyakij <wingyminus@gmail.com>
This commit is contained in:
parent
3107ed847a
commit
97be0a930c
14 changed files with 398 additions and 4 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -8812,6 +8812,16 @@ dependencies = [
|
|||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-erlang"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93ced5145ebb17f83243bf055b74e108da7cc129e12faab4166df03f59b287f4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-gitcommit"
|
||||
version = "0.3.3"
|
||||
|
@ -10392,6 +10402,7 @@ dependencies = [
|
|||
"tree-sitter-elixir",
|
||||
"tree-sitter-elm",
|
||||
"tree-sitter-embedded-template",
|
||||
"tree-sitter-erlang",
|
||||
"tree-sitter-gitcommit",
|
||||
"tree-sitter-gleam",
|
||||
"tree-sitter-glsl",
|
||||
|
|
|
@ -142,6 +142,7 @@ tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev
|
|||
tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "a2861e88a730287a60c11ea9299c033c7d076e30" }
|
||||
tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40" }
|
||||
tree-sitter-embedded-template = "0.20.0"
|
||||
tree-sitter-erlang = "0.4.0"
|
||||
tree-sitter-gitcommit = { git = "https://github.com/gbprod/tree-sitter-gitcommit" }
|
||||
tree-sitter-gleam = { git = "https://github.com/gleam-lang/tree-sitter-gleam", rev = "58b7cac8fc14c92b0677c542610d8738c373fa81" }
|
||||
tree-sitter-glsl = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "2a56fb7bc8bb03a1892b4741279dd0a8758b7fb3" }
|
||||
|
|
1
assets/icons/file_icons/erlang.svg
Normal file
1
assets/icons/file_icons/erlang.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg height="64" viewBox="0 0 128 128" width="64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0" x2="128" y1="128" y2="0"><stop offset="0" stop-color="#333"/><stop offset="1" stop-color="#5d5d5d"/></linearGradient><path d="m12.239265 30.664279h14.960911c-5.59432 5.460938-7.654216 10.692785-10.342106 18.023379-3.200764 8.729348-.549141 29.987457 3.815534 37.55289 2.943384 5.101853 6.282685 8.994876 8.233522 11.095173h-16.667861zm89.614855 0h13.90661v66.671442h-13.55518c1.31391-1.750328 3.43934-4.534454 5.12085-6.426163 2.32782-2.618784 4.97023-6.978412 4.97023-6.978412l-16.015202-8.133112s-5.48977 11.600331-15.964999 15.964998c-10.475214 4.364666-19.784679-.838179-25.604243-7.530659-5.819578-6.692502-5.82371-22.14014-5.82371-22.14014h60.797524c1.16391-14.839892-2.63216-21.249816-4.66901-25.90547-.91799-2.098266-1.89261-3.810819-3.16287-5.522484zm-38.356164 1.757154c.35429-.01632.731685-.0092 1.104497 0 11.930114.290977 13.053143 12.802122 13.053143 12.802122h-27.311192s2.170772-12.298638 13.153552-12.802122z" fill="url(#a)"/></svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"suffixes": {
|
||||
"Emakefile": "erlang",
|
||||
"aac": "audio",
|
||||
"accdb": "storage",
|
||||
"app.src": "erlang",
|
||||
"avif": "image",
|
||||
"bak": "backup",
|
||||
"bash": "terminal",
|
||||
|
@ -23,6 +25,8 @@
|
|||
"doc": "document",
|
||||
"docx": "document",
|
||||
"eex": "elixir",
|
||||
"erl": "erlang",
|
||||
"escript": "erlang",
|
||||
"eslintrc": "eslint",
|
||||
"eslintrc.js": "eslint",
|
||||
"eslintrc.json": "eslint",
|
||||
|
@ -37,17 +41,18 @@
|
|||
"gif": "image",
|
||||
"gitattributes": "vcs",
|
||||
"gitignore": "vcs",
|
||||
"gitmodules": "vcs",
|
||||
"gitkeep": "vcs",
|
||||
"gitmodules": "vcs",
|
||||
"go": "go",
|
||||
"h": "code",
|
||||
"handlebars": "code",
|
||||
"hbs": "template",
|
||||
"heex": "elixir",
|
||||
"heif": "image",
|
||||
"hrl": "erlang",
|
||||
"hs": "haskell",
|
||||
"htm": "template",
|
||||
"html": "template",
|
||||
"hs": "haskell",
|
||||
"ib": "storage",
|
||||
"ico": "image",
|
||||
"ini": "settings",
|
||||
|
@ -85,6 +90,7 @@
|
|||
"psd": "image",
|
||||
"py": "python",
|
||||
"rb": "ruby",
|
||||
"rebar.config": "erlang",
|
||||
"rkt": "code",
|
||||
"rs": "rust",
|
||||
"rtf": "document",
|
||||
|
@ -104,13 +110,15 @@
|
|||
"txt": "document",
|
||||
"vue": "vue",
|
||||
"wav": "audio",
|
||||
"webp": "image",
|
||||
"webm": "video",
|
||||
"webp": "image",
|
||||
"xls": "document",
|
||||
"xlsx": "document",
|
||||
"xml": "template",
|
||||
"xrl": "erlang",
|
||||
"yaml": "yaml",
|
||||
"yml": "yaml",
|
||||
"yrl": "erlang",
|
||||
"zlogin": "terminal",
|
||||
"zsh": "terminal",
|
||||
"zsh_aliases": "terminal",
|
||||
|
@ -133,7 +141,7 @@
|
|||
"icon": "icons/file_icons/folder.svg"
|
||||
},
|
||||
"css": {
|
||||
"icon": "icons/file_icons/css.svg"
|
||||
"icon": "icons/file_icons/css.svg"
|
||||
},
|
||||
"default": {
|
||||
"icon": "icons/file_icons/file.svg"
|
||||
|
@ -144,6 +152,9 @@
|
|||
"elixir": {
|
||||
"icon": "icons/file_icons/elixir.svg"
|
||||
},
|
||||
"erlang": {
|
||||
"icon": "icons/file_icons/erlang.svg"
|
||||
},
|
||||
"eslint": {
|
||||
"icon": "icons/file_icons/eslint.svg"
|
||||
},
|
||||
|
|
|
@ -114,6 +114,7 @@ tree-sitter-css.workspace = true
|
|||
tree-sitter-elixir.workspace = true
|
||||
tree-sitter-elm.workspace = true
|
||||
tree-sitter-embedded-template.workspace = true
|
||||
tree-sitter-erlang.workspace = true
|
||||
tree-sitter-gitcommit.workspace = true
|
||||
tree-sitter-gleam.workspace = true
|
||||
tree-sitter-glsl.workspace = true
|
||||
|
|
|
@ -15,6 +15,7 @@ mod css;
|
|||
mod deno;
|
||||
mod elixir;
|
||||
mod elm;
|
||||
mod erlang;
|
||||
mod gleam;
|
||||
mod go;
|
||||
mod haskell;
|
||||
|
@ -113,6 +114,12 @@ pub fn init(
|
|||
),
|
||||
}
|
||||
language("gitcommit", tree_sitter_gitcommit::language(), vec![]);
|
||||
language(
|
||||
"erlang",
|
||||
tree_sitter_erlang::language(),
|
||||
vec![Arc::new(erlang::ErlangLspAdapter)],
|
||||
);
|
||||
|
||||
language(
|
||||
"gleam",
|
||||
tree_sitter_gleam::language(),
|
||||
|
|
58
crates/zed/src/languages/erlang.rs
Normal file
58
crates/zed/src/languages/erlang.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerBinary;
|
||||
use std::{any::Any, path::PathBuf};
|
||||
|
||||
pub struct ErlangLspAdapter;
|
||||
|
||||
#[async_trait]
|
||||
impl LspAdapter for ErlangLspAdapter {
|
||||
fn name(&self) -> LanguageServerName {
|
||||
LanguageServerName("erlang_ls".into())
|
||||
}
|
||||
|
||||
fn short_name(&self) -> &'static str {
|
||||
"erlang_ls"
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
&self,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Result<Box<dyn 'static + Send + Any>> {
|
||||
Ok(Box::new(()) as Box<_>)
|
||||
}
|
||||
|
||||
async fn fetch_server_binary(
|
||||
&self,
|
||||
_version: Box<dyn 'static + Send + Any>,
|
||||
_container_dir: PathBuf,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Result<LanguageServerBinary> {
|
||||
Err(anyhow!(
|
||||
"erlang_ls must be installed and available in your $PATH"
|
||||
))
|
||||
}
|
||||
|
||||
async fn cached_server_binary(
|
||||
&self,
|
||||
_: PathBuf,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
Some(LanguageServerBinary {
|
||||
path: "erlang_ls".into(),
|
||||
arguments: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
fn can_be_reinstalled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
|
||||
Some(LanguageServerBinary {
|
||||
path: "erlang_ls".into(),
|
||||
arguments: vec!["--version".into()],
|
||||
})
|
||||
}
|
||||
}
|
3
crates/zed/src/languages/erlang/brackets.scm
Normal file
3
crates/zed/src/languages/erlang/brackets.scm
Normal file
|
@ -0,0 +1,3 @@
|
|||
("(" @open ")" @close)
|
||||
("[" @open "]" @close)
|
||||
("{" @open "}" @close)
|
23
crates/zed/src/languages/erlang/config.toml
Normal file
23
crates/zed/src/languages/erlang/config.toml
Normal file
|
@ -0,0 +1,23 @@
|
|||
name = "Erlang"
|
||||
# TODO: support parsing rebar.config files
|
||||
# # https://github.com/WhatsApp/tree-sitter-erlang/issues/3
|
||||
path_suffixes = ["erl", "hrl", "app.src", "escript", "xrl", "yrl", "Emakefile", "rebar.config"]
|
||||
line_comments = ["% ", "%% ", "%%% "]
|
||||
autoclose_before = ";:.,=}])>"
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "<<", end = ">>", close = true, newline = false, not_in = ["string"] },
|
||||
{ start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
|
||||
{ start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
|
||||
]
|
||||
# Indent if a line ends brackets, "->" or most keywords. Also if prefixed
|
||||
# with "||". This should work with most formatting models.
|
||||
# The ([^%]).* is to ensure this doesn't match inside comments.
|
||||
increase_indent_pattern = "^([^%]).*([{(\\[]]|\\->|after|begin|case|catch|fun|if|of|try|when|maybe|else|(\\|\\|.*))\\s*$"
|
||||
|
||||
# Dedent after brackets, end or lone "->". The latter happens in a spec
|
||||
# with indented types, typically after "when". Only do this if it's _only_
|
||||
# preceded by whitespace.
|
||||
decrease_indent_pattern = "^\\s*([)}\\]]|end|else|\\->\\s*$)"
|
9
crates/zed/src/languages/erlang/folds.scm
Normal file
9
crates/zed/src/languages/erlang/folds.scm
Normal file
|
@ -0,0 +1,9 @@
|
|||
[
|
||||
(fun_decl)
|
||||
(anonymous_fun)
|
||||
(case_expr)
|
||||
(maybe_expr)
|
||||
(map_expr)
|
||||
(export_attribute)
|
||||
(export_type_attribute)
|
||||
] @fold
|
231
crates/zed/src/languages/erlang/highlights.scm
Normal file
231
crates/zed/src/languages/erlang/highlights.scm
Normal file
|
@ -0,0 +1,231 @@
|
|||
;; Copyright (c) Facebook, Inc. and its affiliates.
|
||||
;;
|
||||
;; Licensed under the Apache License, Version 2.0 (the "License");
|
||||
;; you may not use this file except in compliance with the License.
|
||||
;; You may obtain a copy of the License at
|
||||
;;
|
||||
;; http://www.apache.org/licenses/LICENSE-2.0
|
||||
;;
|
||||
;; Unless required by applicable law or agreed to in writing, software
|
||||
;; distributed under the License is distributed on an "AS IS" BASIS,
|
||||
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
;; See the License for the specific language governing permissions and
|
||||
;; limitations under the License.
|
||||
;; ---------------------------------------------------------------------
|
||||
|
||||
;; Based initially on the contents of https://github.com/WhatsApp/tree-sitter-erlang/issues/2 by @Wilfred
|
||||
;; and https://github.com/the-mikedavis/tree-sitter-erlang/blob/main/queries/highlights.scm
|
||||
;;
|
||||
;; The tests are also based on those in
|
||||
;; https://github.com/the-mikedavis/tree-sitter-erlang/tree/main/test/highlight
|
||||
;;
|
||||
|
||||
|
||||
;; First match wins in this file
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Attributes
|
||||
|
||||
;; module attribute
|
||||
(module_attribute
|
||||
name: (atom) @module)
|
||||
|
||||
;; behaviour
|
||||
(behaviour_attribute name: (atom) @module)
|
||||
|
||||
;; export
|
||||
|
||||
;; Import attribute
|
||||
(import_attribute
|
||||
module: (atom) @module)
|
||||
|
||||
;; export_type
|
||||
|
||||
;; optional_callbacks
|
||||
|
||||
;; compile
|
||||
(compile_options_attribute
|
||||
options: (tuple
|
||||
expr: (atom)
|
||||
expr: (list
|
||||
exprs: (binary_op_expr
|
||||
lhs: (atom)
|
||||
rhs: (integer)))))
|
||||
|
||||
;; file attribute
|
||||
|
||||
;; record
|
||||
(record_decl name: (atom) @type)
|
||||
(record_decl name: (macro_call_expr name: (var) @constant))
|
||||
(record_field name: (atom) @property)
|
||||
|
||||
;; type alias
|
||||
|
||||
;; opaque
|
||||
|
||||
;; Spec attribute
|
||||
(spec fun: (atom) @function)
|
||||
(spec
|
||||
module: (module name: (atom) @module)
|
||||
fun: (atom) @function)
|
||||
|
||||
;; callback
|
||||
(callback fun: (atom) @function)
|
||||
|
||||
;; fun decl
|
||||
|
||||
;; include/include_lib
|
||||
|
||||
;; ifdef/ifndef
|
||||
(pp_ifdef name: (_) @keyword.directive)
|
||||
(pp_ifndef name: (_) @keyword.directive)
|
||||
|
||||
;; define
|
||||
(pp_define
|
||||
lhs: (macro_lhs
|
||||
name: (_) @keyword.directive
|
||||
args: (var_args args: (var))))
|
||||
(pp_define
|
||||
lhs: (macro_lhs
|
||||
name: (var) @constant))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Functions
|
||||
(fa fun: (atom) @function)
|
||||
(type_name name: (atom) @function)
|
||||
(call expr: (atom) @function)
|
||||
(function_clause name: (atom) @function)
|
||||
(internal_fun fun: (atom) @function)
|
||||
|
||||
;; This is a fudge, we should check that the operator is '/'
|
||||
;; But our grammar does not (currently) provide it
|
||||
(binary_op_expr lhs: (atom) @function rhs: (integer))
|
||||
|
||||
;; Others
|
||||
(remote_module module: (atom) @module)
|
||||
(remote fun: (atom) @function)
|
||||
(macro_call_expr name: (var) @keyword.directive args: (_) )
|
||||
(macro_call_expr name: (var) @constant)
|
||||
(macro_call_expr name: (atom) @keyword.directive)
|
||||
(record_field_name name: (atom) @property)
|
||||
(record_name name: (atom) @type)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Reserved words
|
||||
[ "after"
|
||||
"and"
|
||||
"band"
|
||||
"begin"
|
||||
"behavior"
|
||||
"behaviour"
|
||||
"bnot"
|
||||
"bor"
|
||||
"bsl"
|
||||
"bsr"
|
||||
"bxor"
|
||||
"callback"
|
||||
"case"
|
||||
"catch"
|
||||
"compile"
|
||||
"define"
|
||||
"deprecated"
|
||||
"div"
|
||||
"elif"
|
||||
"else"
|
||||
"end"
|
||||
"endif"
|
||||
"export"
|
||||
"export_type"
|
||||
"file"
|
||||
"fun"
|
||||
"if"
|
||||
"ifdef"
|
||||
"ifndef"
|
||||
"import"
|
||||
"include"
|
||||
"include_lib"
|
||||
"maybe"
|
||||
"module"
|
||||
"of"
|
||||
"opaque"
|
||||
"optional_callbacks"
|
||||
"or"
|
||||
"receive"
|
||||
"record"
|
||||
"spec"
|
||||
"try"
|
||||
"type"
|
||||
"undef"
|
||||
"unit"
|
||||
"when"
|
||||
"xor"] @keyword
|
||||
|
||||
["andalso" "orelse"] @keyword.operator
|
||||
|
||||
;; Punctuation
|
||||
["," "." ";"] @punctuation.delimiter
|
||||
["(" ")" "{" "}" "[" "]" "<<" ">>"] @punctuation.bracket
|
||||
|
||||
;; Operators
|
||||
["!"
|
||||
"->"
|
||||
"<-"
|
||||
"#"
|
||||
"::"
|
||||
"|"
|
||||
":"
|
||||
"="
|
||||
"||"
|
||||
|
||||
"+"
|
||||
"-"
|
||||
"bnot"
|
||||
"not"
|
||||
|
||||
"/"
|
||||
"*"
|
||||
"div"
|
||||
"rem"
|
||||
"band"
|
||||
"and"
|
||||
|
||||
"+"
|
||||
"-"
|
||||
"bor"
|
||||
"bxor"
|
||||
"bsl"
|
||||
"bsr"
|
||||
"or"
|
||||
"xor"
|
||||
|
||||
"++"
|
||||
"--"
|
||||
|
||||
"=="
|
||||
"/="
|
||||
"=<"
|
||||
"<"
|
||||
">="
|
||||
">"
|
||||
"=:="
|
||||
"=/="
|
||||
] @operator
|
||||
|
||||
;;; Comments
|
||||
((var) @comment.discard
|
||||
(#match? @comment.discard "^_"))
|
||||
|
||||
(dotdotdot) @comment.discard
|
||||
(comment) @comment
|
||||
|
||||
;; Primitive types
|
||||
(string) @string
|
||||
(char) @constant
|
||||
(integer) @number
|
||||
(var) @variable
|
||||
(atom) @string.special.symbol
|
||||
|
||||
;; wild attribute (Should take precedence over atoms, otherwise they are highlighted as atoms)
|
||||
(wild_attribute name: (attr_name name: (_) @keyword))
|
3
crates/zed/src/languages/erlang/indents.scm
Normal file
3
crates/zed/src/languages/erlang/indents.scm
Normal file
|
@ -0,0 +1,3 @@
|
|||
(_ "[" "]" @end) @indent
|
||||
(_ "{" "}" @end) @indent
|
||||
(_ "(" ")" @end) @indent
|
31
crates/zed/src/languages/erlang/outline.scm
Normal file
31
crates/zed/src/languages/erlang/outline.scm
Normal file
|
@ -0,0 +1,31 @@
|
|||
(module_attribute
|
||||
"module" @context
|
||||
name: (_) @name) @item
|
||||
|
||||
(behaviour_attribute
|
||||
"behaviour" @context
|
||||
(atom) @name) @item
|
||||
|
||||
(type_alias
|
||||
"type" @context
|
||||
name: (_) @name) @item
|
||||
|
||||
(opaque
|
||||
"opaque" @context
|
||||
name: (_) @name) @item
|
||||
|
||||
(pp_define
|
||||
"define" @context
|
||||
lhs: (_) @name) @item
|
||||
|
||||
(record_decl
|
||||
"record" @context
|
||||
name: (_) @name) @item
|
||||
|
||||
(callback
|
||||
"callback" @context
|
||||
fun: (_) @function ( (_) @name)) @item
|
||||
|
||||
(fun_decl (function_clause
|
||||
name: (_) @name
|
||||
args: (_) @context)) @item
|
4
docs/src/languages/erlang.md
Normal file
4
docs/src/languages/erlang.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Erlang
|
||||
|
||||
- Tree Sitter: [tree-sitter-erlang](https://github.com/WhatsApp/tree-sitter-erlang)
|
||||
- Language Server: [erlang_ls](https://github.com/erlang-ls/erlang_ls)
|
Loading…
Reference in a new issue