mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-07 20:39:04 +03:00
Add zig support
This commit is contained in:
parent
37647a67a7
commit
e5b71cc6ac
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -8716,6 +8716,15 @@ dependencies = [
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-zig"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/maxxnino/tree-sitter-zig?rev=0d08703e4c3f426ec61695d7617415fff97029bd#0d08703e4c3f426ec61695d7617415fff97029bd"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
@ -9812,6 +9821,7 @@ dependencies = [
|
||||
"tree-sitter-uiua",
|
||||
"tree-sitter-vue",
|
||||
"tree-sitter-yaml",
|
||||
"tree-sitter-zig",
|
||||
"unindent",
|
||||
"url",
|
||||
"urlencoding",
|
||||
|
@ -161,6 +161,7 @@ tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", re
|
||||
tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "26bbaecda0039df4067861ab38ea8ea169f7f5aa"}
|
||||
tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "6608d9d60c386f19d80af7d8132322fa11199c42"}
|
||||
tree-sitter-uiua = {git = "https://github.com/shnarazk/tree-sitter-uiua", rev = "9260f11be5900beda4ee6d1a24ab8ddfaf5a19b2"}
|
||||
tree-sitter-zig = { git = "https://github.com/maxxnino/tree-sitter-zig", rev = "0d08703e4c3f426ec61695d7617415fff97029bd" }
|
||||
|
||||
[patch.crates-io]
|
||||
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "31c40449749c4263a91a43593831b82229049a4c" }
|
||||
|
@ -142,6 +142,7 @@ tree-sitter-nix.workspace = true
|
||||
tree-sitter-nu.workspace = true
|
||||
tree-sitter-vue.workspace = true
|
||||
tree-sitter-uiua.workspace = true
|
||||
tree-sitter-zig.workspace = true
|
||||
|
||||
url = "2.2"
|
||||
urlencoding = "2.1.2"
|
||||
|
@ -31,6 +31,7 @@ mod typescript;
|
||||
mod uiua;
|
||||
mod vue;
|
||||
mod yaml;
|
||||
mod zig;
|
||||
|
||||
// 1. Add tree-sitter-{language} parser to zed crate
|
||||
// 2. Create a language directory in zed/crates/zed/src/languages and add the language to init function below
|
||||
@ -112,6 +113,11 @@ pub fn init(
|
||||
tree_sitter_go::language(),
|
||||
vec![Arc::new(go::GoLspAdapter)],
|
||||
);
|
||||
language(
|
||||
"zig",
|
||||
tree_sitter_zig::language(),
|
||||
vec![Arc::new(zig::ZlsAdapter)],
|
||||
);
|
||||
language(
|
||||
"heex",
|
||||
tree_sitter_heex::language(),
|
||||
|
125
crates/zed/src/languages/zig.rs
Normal file
125
crates/zed/src/languages/zig.rs
Normal file
@ -0,0 +1,125 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_compression::futures::bufread::GzipDecoder;
|
||||
use async_tar::Archive;
|
||||
use async_trait::async_trait;
|
||||
use futures::{io::BufReader, StreamExt};
|
||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerBinary;
|
||||
use smol::fs;
|
||||
use std::env::consts::ARCH;
|
||||
use std::{any::Any, path::PathBuf};
|
||||
use util::async_maybe;
|
||||
use util::github::latest_github_release;
|
||||
use util::{github::GitHubLspBinaryVersion, ResultExt};
|
||||
|
||||
pub struct ZlsAdapter;
|
||||
|
||||
#[async_trait]
|
||||
impl LspAdapter for ZlsAdapter {
|
||||
fn name(&self) -> LanguageServerName {
|
||||
LanguageServerName("zls".into())
|
||||
}
|
||||
|
||||
fn short_name(&self) -> &'static str {
|
||||
"zls"
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
) -> Result<Box<dyn 'static + Send + Any>> {
|
||||
let release = latest_github_release("zigtools/zls", false, delegate.http_client()).await?;
|
||||
let asset_name = format!("zls-{}-macos.tar.gz", ARCH);
|
||||
let asset = release
|
||||
.assets
|
||||
.iter()
|
||||
.find(|asset| asset.name == asset_name)
|
||||
.ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
|
||||
let version = GitHubLspBinaryVersion {
|
||||
name: release.name,
|
||||
url: asset.browser_download_url.clone(),
|
||||
};
|
||||
|
||||
Ok(Box::new(version) as Box<_>)
|
||||
}
|
||||
|
||||
async fn fetch_server_binary(
|
||||
&self,
|
||||
version: Box<dyn 'static + Send + Any>,
|
||||
container_dir: PathBuf,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
) -> Result<LanguageServerBinary> {
|
||||
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
|
||||
let binary_path = container_dir.join("bin/zls");
|
||||
|
||||
if fs::metadata(&binary_path).await.is_err() {
|
||||
let mut response = delegate
|
||||
.http_client()
|
||||
.get(&version.url, Default::default(), true)
|
||||
.await
|
||||
.context("error downloading release")?;
|
||||
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
|
||||
let archive = Archive::new(decompressed_bytes);
|
||||
archive.unpack(container_dir).await?;
|
||||
}
|
||||
|
||||
fs::set_permissions(
|
||||
&binary_path,
|
||||
<fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
|
||||
)
|
||||
.await?;
|
||||
Ok(LanguageServerBinary {
|
||||
path: binary_path,
|
||||
arguments: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
async fn cached_server_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir)
|
||||
.await
|
||||
.map(|mut binary| {
|
||||
binary.arguments = vec!["--help".into()];
|
||||
binary
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
let mut last_binary_path = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
let entry = entry?;
|
||||
if entry.file_type().await?.is_file()
|
||||
&& entry
|
||||
.file_name()
|
||||
.to_str()
|
||||
.map_or(false, |name| name == "zls")
|
||||
{
|
||||
last_binary_path = Some(entry.path());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(path) = last_binary_path {
|
||||
Ok(LanguageServerBinary {
|
||||
path,
|
||||
arguments: Vec::new(),
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("no cached binary"))
|
||||
}
|
||||
})
|
||||
.await
|
||||
.log_err()
|
||||
}
|
10
crates/zed/src/languages/zig/config.toml
Normal file
10
crates/zed/src/languages/zig/config.toml
Normal file
@ -0,0 +1,10 @@
|
||||
name = "Zig"
|
||||
path_suffixes = ["zig"]
|
||||
line_comment = "// "
|
||||
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 = true },
|
||||
]
|
16
crates/zed/src/languages/zig/folds.scm
Normal file
16
crates/zed/src/languages/zig/folds.scm
Normal file
@ -0,0 +1,16 @@
|
||||
[
|
||||
(Block)
|
||||
(ContainerDecl)
|
||||
(SwitchExpr)
|
||||
(InitList)
|
||||
(AsmExpr)
|
||||
(ErrorSetDecl)
|
||||
(LINESTRING)
|
||||
(
|
||||
[
|
||||
(IfPrefix)
|
||||
(WhilePrefix)
|
||||
(ForPrefix)
|
||||
]
|
||||
)
|
||||
] @fold
|
234
crates/zed/src/languages/zig/highlights.scm
Normal file
234
crates/zed/src/languages/zig/highlights.scm
Normal file
@ -0,0 +1,234 @@
|
||||
[
|
||||
(container_doc_comment)
|
||||
(doc_comment)
|
||||
(line_comment)
|
||||
] @comment
|
||||
|
||||
[
|
||||
variable: (IDENTIFIER)
|
||||
variable_type_function: (IDENTIFIER)
|
||||
] @variable
|
||||
|
||||
parameter: (IDENTIFIER) @parameter
|
||||
|
||||
[
|
||||
field_member: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
] @field
|
||||
|
||||
;; assume TitleCase is a type
|
||||
(
|
||||
[
|
||||
variable_type_function: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
parameter: (IDENTIFIER)
|
||||
] @type
|
||||
(#match? @type "^[A-Z]([a-z]+[A-Za-z0-9]*)*$")
|
||||
)
|
||||
;; assume camelCase is a function
|
||||
(
|
||||
[
|
||||
variable_type_function: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
parameter: (IDENTIFIER)
|
||||
] @function
|
||||
(#match? @function "^[a-z]+([A-Z][a-z0-9]*)+$")
|
||||
)
|
||||
|
||||
;; assume all CAPS_1 is a constant
|
||||
(
|
||||
[
|
||||
variable_type_function: (IDENTIFIER)
|
||||
field_access: (IDENTIFIER)
|
||||
] @constant
|
||||
(#match? @constant "^[A-Z][A-Z_0-9]+$")
|
||||
)
|
||||
|
||||
[
|
||||
function_call: (IDENTIFIER)
|
||||
function: (IDENTIFIER)
|
||||
] @function
|
||||
|
||||
exception: "!" @exception
|
||||
|
||||
(
|
||||
(IDENTIFIER) @variable.builtin
|
||||
(#eq? @variable.builtin "_")
|
||||
)
|
||||
|
||||
(PtrTypeStart "c" @variable.builtin)
|
||||
|
||||
(
|
||||
(ContainerDeclType
|
||||
[
|
||||
(ErrorUnionExpr)
|
||||
"enum"
|
||||
]
|
||||
)
|
||||
(ContainerField (IDENTIFIER) @constant)
|
||||
)
|
||||
|
||||
field_constant: (IDENTIFIER) @constant
|
||||
|
||||
(BUILTINIDENTIFIER) @keyword
|
||||
|
||||
; No idea why this doesnt work
|
||||
; ((BUILTINIDENTIFIER) @include
|
||||
; (#any-of? @include "@import" "@cImport"))
|
||||
|
||||
(INTEGER) @number
|
||||
|
||||
(FLOAT) @float
|
||||
|
||||
[
|
||||
"true"
|
||||
"false"
|
||||
] @boolean
|
||||
|
||||
[
|
||||
(LINESTRING)
|
||||
(STRINGLITERALSINGLE)
|
||||
] @string
|
||||
|
||||
(CHAR_LITERAL) @character
|
||||
(EscapeSequence) @string.escape
|
||||
(FormatSequence) @string.special
|
||||
|
||||
(BreakLabel (IDENTIFIER) @label)
|
||||
(BlockLabel (IDENTIFIER) @label)
|
||||
|
||||
[
|
||||
"asm"
|
||||
"defer"
|
||||
"errdefer"
|
||||
"test"
|
||||
"struct"
|
||||
"union"
|
||||
"enum"
|
||||
"opaque"
|
||||
"error"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"async"
|
||||
"await"
|
||||
"suspend"
|
||||
"nosuspend"
|
||||
"resume"
|
||||
] @keyword.coroutine
|
||||
|
||||
[
|
||||
"fn"
|
||||
] @keyword.function
|
||||
|
||||
[
|
||||
"and"
|
||||
"or"
|
||||
"orelse"
|
||||
] @keyword.operator
|
||||
|
||||
[
|
||||
"return"
|
||||
] @keyword.return
|
||||
|
||||
[
|
||||
"if"
|
||||
"else"
|
||||
"switch"
|
||||
] @conditional
|
||||
|
||||
[
|
||||
"for"
|
||||
"while"
|
||||
"break"
|
||||
"continue"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"usingnamespace"
|
||||
] @include
|
||||
|
||||
[
|
||||
"try"
|
||||
"catch"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"anytype"
|
||||
(BuildinTypeExpr)
|
||||
] @type.builtin
|
||||
|
||||
[
|
||||
"const"
|
||||
"var"
|
||||
"volatile"
|
||||
"allowzero"
|
||||
"noalias"
|
||||
] @type.qualifier
|
||||
|
||||
[
|
||||
"addrspace"
|
||||
"align"
|
||||
"callconv"
|
||||
"linksection"
|
||||
] @storageclass
|
||||
|
||||
[
|
||||
"comptime"
|
||||
"export"
|
||||
"extern"
|
||||
"inline"
|
||||
"noinline"
|
||||
"packed"
|
||||
"pub"
|
||||
"threadlocal"
|
||||
] @attribute
|
||||
|
||||
[
|
||||
"null"
|
||||
"unreachable"
|
||||
"undefined"
|
||||
] @constant.builtin
|
||||
|
||||
[
|
||||
(CompareOp)
|
||||
(BitwiseOp)
|
||||
(BitShiftOp)
|
||||
(AdditionOp)
|
||||
(AssignOp)
|
||||
(MultiplyOp)
|
||||
(PrefixOp)
|
||||
"*"
|
||||
"**"
|
||||
"->"
|
||||
".?"
|
||||
".*"
|
||||
"?"
|
||||
] @operator
|
||||
|
||||
[
|
||||
";"
|
||||
"."
|
||||
","
|
||||
":"
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
".."
|
||||
"..."
|
||||
] @punctuation.special
|
||||
|
||||
[
|
||||
"["
|
||||
"]"
|
||||
"("
|
||||
")"
|
||||
"{"
|
||||
"}"
|
||||
(Payload "|")
|
||||
(PtrPayload "|")
|
||||
(PtrIndexPayload "|")
|
||||
] @punctuation.bracket
|
||||
|
||||
; Error
|
||||
(ERROR) @error
|
22
crates/zed/src/languages/zig/indents.scm
Normal file
22
crates/zed/src/languages/zig/indents.scm
Normal file
@ -0,0 +1,22 @@
|
||||
[
|
||||
(Block)
|
||||
(ContainerDecl)
|
||||
(SwitchExpr)
|
||||
(InitList)
|
||||
] @indent
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @branch
|
||||
|
||||
[
|
||||
(line_comment)
|
||||
(container_doc_comment)
|
||||
(doc_comment)
|
||||
(LINESTRING)
|
||||
] @ignore
|
5
crates/zed/src/languages/zig/injections.scm
Normal file
5
crates/zed/src/languages/zig/injections.scm
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
(container_doc_comment)
|
||||
(doc_comment)
|
||||
(line_comment)
|
||||
] @comment
|
Loading…
Reference in New Issue
Block a user