History

Add zig support

Allan Calix committed 2 years ago

Commit e5b71cc1 parent 37647a610 files · +430 −0Browse files

Unified · Split

10 files
  1. Cargo.lock +10 −0
  2. Cargo.toml +1 −0
  3. crates/zed/Cargo.toml +1 −0
  4. crates/zed/src/languages.rs +6 −0
  5. crates/zed/src/languages/zig.rs +125 −0
  6. crates/zed/src/languages/zig/config.toml +10 −0
  7. crates/zed/src/languages/zig/folds.scm +16 −0
  8. crates/zed/src/languages/zig/highlights.scm +234 −0
  9. crates/zed/src/languages/zig/indents.scm +22 −0
  10. crates/zed/src/languages/zig/injections.scm +5 −0
Cargo.lock+10−0
@@ -8716,6 +8716,15 @@ dependencies = [ · 8715 unmodified lines
8716 "tree-sitter",8716 "tree-sitter",
8717]8717]
8718 8718
8719[[package]]
8720name = "tree-sitter-zig"
8721version = "0.0.1"
8722source = "git+https://github.com/maxxnino/tree-sitter-zig?rev=0d08703e4c3f426ec61695d7617415fff97029bd#0d08703e4c3f426ec61695d7617415fff97029bd"
8723dependencies = [
8724 "cc",
8725 "tree-sitter",
8726]
8727
8719[[package]]8728[[package]]
8720name = "try-lock"8729name = "try-lock"
8721version = "0.2.4"8730version = "0.2.4"
@@ -9812,6 +9821,7 @@ dependencies = [ · 1090 unmodified lines
9812 "tree-sitter-uiua",9821 "tree-sitter-uiua",
9813 "tree-sitter-vue",9822 "tree-sitter-vue",
9814 "tree-sitter-yaml",9823 "tree-sitter-yaml",
9824 "tree-sitter-zig",
9815 "unindent",9825 "unindent",
9816 "url",9826 "url",
9817 "urlencoding",9827 "urlencoding",
Cargo.toml+1−0
@@ -161,6 +161,7 @@ tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", re · 160 unmodified lines
161tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "26bbaecda0039df4067861ab38ea8ea169f7f5aa"}161tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "26bbaecda0039df4067861ab38ea8ea169f7f5aa"}
162tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "6608d9d60c386f19d80af7d8132322fa11199c42"}162tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "6608d9d60c386f19d80af7d8132322fa11199c42"}
163tree-sitter-uiua = {git = "https://github.com/shnarazk/tree-sitter-uiua", rev = "9260f11be5900beda4ee6d1a24ab8ddfaf5a19b2"}163tree-sitter-uiua = {git = "https://github.com/shnarazk/tree-sitter-uiua", rev = "9260f11be5900beda4ee6d1a24ab8ddfaf5a19b2"}
164tree-sitter-zig = { git = "https://github.com/maxxnino/tree-sitter-zig", rev = "0d08703e4c3f426ec61695d7617415fff97029bd" }
164 165
165[patch.crates-io]166[patch.crates-io]
166tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "31c40449749c4263a91a43593831b82229049a4c" }167tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "31c40449749c4263a91a43593831b82229049a4c" }
crates/zed/Cargo.toml+1−0
@@ -142,6 +142,7 @@ tree-sitter-nix.workspace = true · 141 unmodified lines
142tree-sitter-nu.workspace = true142tree-sitter-nu.workspace = true
143tree-sitter-vue.workspace = true143tree-sitter-vue.workspace = true
144tree-sitter-uiua.workspace = true144tree-sitter-uiua.workspace = true
145tree-sitter-zig.workspace = true
145 146
146url = "2.2"147url = "2.2"
147urlencoding = "2.1.2"148urlencoding = "2.1.2"
crates/zed/src/languages.rs+6−0
@@ -31,6 +31,7 @@ mod typescript; · 30 unmodified lines
31mod uiua;31mod uiua;
32mod vue;32mod vue;
33mod yaml;33mod yaml;
34mod zig;
34 35
35// 1. Add tree-sitter-{language} parser to zed crate36// 1. Add tree-sitter-{language} parser to zed crate
36// 2. Create a language directory in zed/crates/zed/src/languages and add the language to init function below37// 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( · 75 unmodified lines
112 tree_sitter_go::language(),113 tree_sitter_go::language(),
113 vec![Arc::new(go::GoLspAdapter)],114 vec![Arc::new(go::GoLspAdapter)],
114 );115 );
116 language(
117 "zig",
118 tree_sitter_zig::language(),
119 vec![Arc::new(zig::ZlsAdapter)],
120 );
115 language(121 language(
116 "heex",122 "heex",
117 tree_sitter_heex::language(),123 tree_sitter_heex::language(),
crates/zed/src/languages/zig.rs+125−0
@@ -0,0 +1,125 @@
1use anyhow::{anyhow, Context, Result};
2use async_compression::futures::bufread::GzipDecoder;
3use async_tar::Archive;
4use async_trait::async_trait;
5use futures::{io::BufReader, StreamExt};
6use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
7use lsp::LanguageServerBinary;
8use smol::fs;
9use std::env::consts::ARCH;
10use std::{any::Any, path::PathBuf};
11use util::async_maybe;
12use util::github::latest_github_release;
13use util::{github::GitHubLspBinaryVersion, ResultExt};
14
15pub struct ZlsAdapter;
16
17#[async_trait]
18impl LspAdapter for ZlsAdapter {
19 fn name(&self) -> LanguageServerName {
20 LanguageServerName("zls".into())
21 }
22
23 fn short_name(&self) -> &'static str {
24 "zls"
25 }
26
27 async fn fetch_latest_server_version(
28 &self,
29 delegate: &dyn LspAdapterDelegate,
30 ) -> Result<Box<dyn 'static + Send + Any>> {
31 let release = latest_github_release("zigtools/zls", false, delegate.http_client()).await?;
32 let asset_name = format!("zls-{}-macos.tar.gz", ARCH);
33 let asset = release
34 .assets
35 .iter()
36 .find(|asset| asset.name == asset_name)
37 .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
38 let version = GitHubLspBinaryVersion {
39 name: release.name,
40 url: asset.browser_download_url.clone(),
41 };
42
43 Ok(Box::new(version) as Box<_>)
44 }
45
46 async fn fetch_server_binary(
47 &self,
48 version: Box<dyn 'static + Send + Any>,
49 container_dir: PathBuf,
50 delegate: &dyn LspAdapterDelegate,
51 ) -> Result<LanguageServerBinary> {
52 let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
53 let binary_path = container_dir.join("bin/zls");
54
55 if fs::metadata(&binary_path).await.is_err() {
56 let mut response = delegate
57 .http_client()
58 .get(&version.url, Default::default(), true)
59 .await
60 .context("error downloading release")?;
61 let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
62 let archive = Archive::new(decompressed_bytes);
63 archive.unpack(container_dir).await?;
64 }
65
66 fs::set_permissions(
67 &binary_path,
68 <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
69 )
70 .await?;
71 Ok(LanguageServerBinary {
72 path: binary_path,
73 arguments: vec![],
74 })
75 }
76
77 async fn cached_server_binary(
78 &self,
79 container_dir: PathBuf,
80 _: &dyn LspAdapterDelegate,
81 ) -> Option<LanguageServerBinary> {
82 get_cached_server_binary(container_dir).await
83 }
84
85 async fn installation_test_binary(
86 &self,
87 container_dir: PathBuf,
88 ) -> Option<LanguageServerBinary> {
89 get_cached_server_binary(container_dir)
90 .await
91 .map(|mut binary| {
92 binary.arguments = vec!["--help".into()];
93 binary
94 })
95 }
96}
97
98async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
99 async_maybe!({
100 let mut last_binary_path = None;
101 let mut entries = fs::read_dir(&container_dir).await?;
102 while let Some(entry) = entries.next().await {
103 let entry = entry?;
104 if entry.file_type().await?.is_file()
105 && entry
106 .file_name()
107 .to_str()
108 .map_or(false, |name| name == "zls")
109 {
110 last_binary_path = Some(entry.path());
111 }
112 }
113
114 if let Some(path) = last_binary_path {
115 Ok(LanguageServerBinary {
116 path,
117 arguments: Vec::new(),
118 })
119 } else {
120 Err(anyhow!("no cached binary"))
121 }
122 })
123 .await
124 .log_err()
125}
crates/zed/src/languages/zig/config.toml+10−0
@@ -0,0 +1,10 @@
1name = "Zig"
2path_suffixes = ["zig"]
3line_comment = "// "
4autoclose_before = ";:.,=}])>"
5brackets = [
6 { start = "{", end = "}", close = true, newline = true },
7 { start = "[", end = "]", close = true, newline = true },
8 { start = "(", end = ")", close = true, newline = true },
9 { start = "<", end = ">", close = true, newline = true },
10]
crates/zed/src/languages/zig/folds.scm+16−0
@@ -0,0 +1,16 @@
1[
2 (Block)
3 (ContainerDecl)
4 (SwitchExpr)
5 (InitList)
6 (AsmExpr)
7 (ErrorSetDecl)
8 (LINESTRING)
9 (
10 [
11 (IfPrefix)
12 (WhilePrefix)
13 (ForPrefix)
14 ]
15 )
16] @fold
crates/zed/src/languages/zig/highlights.scm+234−0
@@ -0,0 +1,234 @@
1[
2 (container_doc_comment)
3 (doc_comment)
4 (line_comment)
5] @comment
6
7[
8 variable: (IDENTIFIER)
9 variable_type_function: (IDENTIFIER)
10] @variable
11
12parameter: (IDENTIFIER) @parameter
13
14[
15 field_member: (IDENTIFIER)
16 field_access: (IDENTIFIER)
17] @field
18
19;; assume TitleCase is a type
20(
21 [
22 variable_type_function: (IDENTIFIER)
23 field_access: (IDENTIFIER)
24 parameter: (IDENTIFIER)
25 ] @type
26 (#match? @type "^[A-Z]([a-z]+[A-Za-z0-9]*)*$")
27)
28;; assume camelCase is a function
29(
30 [
31 variable_type_function: (IDENTIFIER)
32 field_access: (IDENTIFIER)
33 parameter: (IDENTIFIER)
34 ] @function
35 (#match? @function "^[a-z]+([A-Z][a-z0-9]*)+$")
36)
37
38;; assume all CAPS_1 is a constant
39(
40 [
41 variable_type_function: (IDENTIFIER)
42 field_access: (IDENTIFIER)
43 ] @constant
44 (#match? @constant "^[A-Z][A-Z_0-9]+$")
45)
46
47[
48 function_call: (IDENTIFIER)
49 function: (IDENTIFIER)
50] @function
51
52exception: "!" @exception
53
54(
55 (IDENTIFIER) @variable.builtin
56 (#eq? @variable.builtin "_")
57)
58
59(PtrTypeStart "c" @variable.builtin)
60
61(
62 (ContainerDeclType
63 [
64 (ErrorUnionExpr)
65 "enum"
66 ]
67 )
68 (ContainerField (IDENTIFIER) @constant)
69)
70
71field_constant: (IDENTIFIER) @constant
72
73(BUILTINIDENTIFIER) @keyword
74
75; No idea why this doesnt work
76; ((BUILTINIDENTIFIER) @include
77; (#any-of? @include "@import" "@cImport"))
78
79(INTEGER) @number
80
81(FLOAT) @float
82
83[
84 "true"
85 "false"
86] @boolean
87
88[
89 (LINESTRING)
90 (STRINGLITERALSINGLE)
91] @string
92
93(CHAR_LITERAL) @character
94(EscapeSequence) @string.escape
95(FormatSequence) @string.special
96
97(BreakLabel (IDENTIFIER) @label)
98(BlockLabel (IDENTIFIER) @label)
99
100[
101 "asm"
102 "defer"
103 "errdefer"
104 "test"
105 "struct"
106 "union"
107 "enum"
108 "opaque"
109 "error"
110] @keyword
111
112[
113 "async"
114 "await"
115 "suspend"
116 "nosuspend"
117 "resume"
118] @keyword.coroutine
119
120[
121 "fn"
122] @keyword.function
123
124[
125 "and"
126 "or"
127 "orelse"
128] @keyword.operator
129
130[
131 "return"
132] @keyword.return
133
134[
135 "if"
136 "else"
137 "switch"
138] @conditional
139
140[
141 "for"
142 "while"
143 "break"
144 "continue"
145] @keyword
146
147[
148 "usingnamespace"
149] @include
150
151[
152 "try"
153 "catch"
154] @keyword
155
156[
157 "anytype"
158 (BuildinTypeExpr)
159] @type.builtin
160
161[
162 "const"
163 "var"
164 "volatile"
165 "allowzero"
166 "noalias"
167] @type.qualifier
168
169[
170 "addrspace"
171 "align"
172 "callconv"
173 "linksection"
174] @storageclass
175
176[
177 "comptime"
178 "export"
179 "extern"
180 "inline"
181 "noinline"
182 "packed"
183 "pub"
184 "threadlocal"
185] @attribute
186
187[
188 "null"
189 "unreachable"
190 "undefined"
191] @constant.builtin
192
193[
194 (CompareOp)
195 (BitwiseOp)
196 (BitShiftOp)
197 (AdditionOp)
198 (AssignOp)
199 (MultiplyOp)
200 (PrefixOp)
201 "*"
202 "**"
203 "->"
204 ".?"
205 ".*"
206 "?"
207] @operator
208
209[
210 ";"
211 "."
212 ","
213 ":"
214] @punctuation.delimiter
215
216[
217 ".."
218 "..."
219] @punctuation.special
220
221[
222 "["
223 "]"
224 "("
225 ")"
226 "{"
227 "}"
228 (Payload "|")
229 (PtrPayload "|")
230 (PtrIndexPayload "|")
231] @punctuation.bracket
232
233; Error
234(ERROR) @error
crates/zed/src/languages/zig/indents.scm+22−0
@@ -0,0 +1,22 @@
1[
2 (Block)
3 (ContainerDecl)
4 (SwitchExpr)
5 (InitList)
6] @indent
7
8[
9 "("
10 ")"
11 "["
12 "]"
13 "{"
14 "}"
15] @branch
16
17[
18 (line_comment)
19 (container_doc_comment)
20 (doc_comment)
21 (LINESTRING)
22] @ignore
crates/zed/src/languages/zig/injections.scm+5−0
@@ -0,0 +1,5 @@
1[
2 (container_doc_comment)
3 (doc_comment)
4 (line_comment)
5] @comment