mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-18 18:08:07 +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",
|
"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]]
|
[[package]]
|
||||||
name = "try-lock"
|
name = "try-lock"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@ -9812,6 +9821,7 @@ dependencies = [
|
|||||||
"tree-sitter-uiua",
|
"tree-sitter-uiua",
|
||||||
"tree-sitter-vue",
|
"tree-sitter-vue",
|
||||||
"tree-sitter-yaml",
|
"tree-sitter-yaml",
|
||||||
|
"tree-sitter-zig",
|
||||||
"unindent",
|
"unindent",
|
||||||
"url",
|
"url",
|
||||||
"urlencoding",
|
"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-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-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-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]
|
[patch.crates-io]
|
||||||
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "31c40449749c4263a91a43593831b82229049a4c" }
|
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-nu.workspace = true
|
||||||
tree-sitter-vue.workspace = true
|
tree-sitter-vue.workspace = true
|
||||||
tree-sitter-uiua.workspace = true
|
tree-sitter-uiua.workspace = true
|
||||||
|
tree-sitter-zig.workspace = true
|
||||||
|
|
||||||
url = "2.2"
|
url = "2.2"
|
||||||
urlencoding = "2.1.2"
|
urlencoding = "2.1.2"
|
||||||
|
@ -31,6 +31,7 @@ mod typescript;
|
|||||||
mod uiua;
|
mod uiua;
|
||||||
mod vue;
|
mod vue;
|
||||||
mod yaml;
|
mod yaml;
|
||||||
|
mod zig;
|
||||||
|
|
||||||
// 1. Add tree-sitter-{language} parser to zed crate
|
// 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
|
// 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(),
|
tree_sitter_go::language(),
|
||||||
vec![Arc::new(go::GoLspAdapter)],
|
vec![Arc::new(go::GoLspAdapter)],
|
||||||
);
|
);
|
||||||
|
language(
|
||||||
|
"zig",
|
||||||
|
tree_sitter_zig::language(),
|
||||||
|
vec![Arc::new(zig::ZlsAdapter)],
|
||||||
|
);
|
||||||
language(
|
language(
|
||||||
"heex",
|
"heex",
|
||||||
tree_sitter_heex::language(),
|
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