commit 33dda6a2910364b5781e9c2071d5a8d95e2bbad0 Author: Martino Ferrari Date: Thu May 7 15:24:36 2026 +0200 Initial zed_marte language extension diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24657b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Generated by Cargo +# will have compiled files and executables +debug +target + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Generated by cargo mutants +# Contains mutation testing data +**/mutants.out*/ + +# rustc will dump stack traces when hitting an internal compiler error to PWD +rustc-ice-*.txt + +# RustRover +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ef13428 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,341 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", + "serde", + "serde_core", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "spdx" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e17e880bafaeb362a7b751ec46bdc5b61445a188f80e0606e68167cd540fa3" +dependencies = [ + "smallvec", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "wasm-encoder" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9c7d2731df60006819b013f64ccc2019691deccf6e11a1804bc850cd6748f1a" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-metadata" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fd83062c17b9f4985d438603cde0a5e8c5c8198201a6937f778b607924c7da2" +dependencies = [ + "anyhow", + "indexmap", + "serde", + "serde_derive", + "serde_json", + "spdx", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" +dependencies = [ + "bitflags", + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288f992ea30e6b5c531b52cdd5f3be81c148554b09ea416f058d16556ba92c27" +dependencies = [ + "bitflags", + "wit-bindgen-rt", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e85e72719ffbccf279359ad071497e47eb0675fe22106dea4ed2d8a7fcb60ba4" +dependencies = [ + "anyhow", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb8738270f32a2d6739973cbbb7c1b6dd8959ce515578a6e19165853272ee64" + +[[package]] +name = "wit-bindgen-rust" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a39a15d1ae2077688213611209849cad40e9e5cccf6e61951a425850677ff3" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d376d3ae5850526dfd00d937faea0d81a06fa18f7ac1e26f386d760f241a8f4b" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421c0c848a0660a8c22e2fd217929a0191f14476b68962afd2af89fd22e39825" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196d3ecfc4b759a8573bf86a9b3f8996b304b3732e4c7de81655f875f6efdca6" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zed_extension_api" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "594fd10dd0f2f853eb243e2425e7c95938cef49adb81d9602921d002c5e6d9d9" +dependencies = [ + "serde", + "serde_json", + "wit-bindgen", +] + +[[package]] +name = "zed_marte" +version = "0.0.1" +dependencies = [ + "zed_extension_api", +] + +[[package]] +name = "zmij" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..17ea6a7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "zed_marte" +version = "0.0.1" +edition = "2021" +publish = false + +[lib] +path = "src/lib.rs" +crate-type = ["cdylib"] + +[dependencies] +zed_extension_api = "0.1.0" diff --git a/extension.toml b/extension.toml new file mode 100644 index 0000000..d55b7a5 --- /dev/null +++ b/extension.toml @@ -0,0 +1,32 @@ +id = "Marte" +name = "MARTe" +version = "0.0.6" +schema_version = 1 +description = "MARTe language support for Zed" +themes = [] +languages = ["languages/marte"] + +[lib] +kind = "Rust" +version = "0.2.0" + +[grammars.marte] +repository = "https://github.com/MARTe-Community/tree-sitter-marte" +rev = "1edbdc955fe6c0cf5bccd33368f0eb03a62d2682" + +[language_servers.mdt] +name = "mdt" +# MATCH THE CASING EXACTLY: +language = "MARTe" +languages = [] + +[language_servers.mdt.language_ids] +# Left side MUST exactly match the `name` field in config.toml +# Right side is what your specific LSP expects the language ID to be +MARTe = "MARTe" + +[context_servers] + +[slash_commands] + +[indexed_docs_providers] diff --git a/extension.wasm b/extension.wasm new file mode 100644 index 0000000..d0b35c7 Binary files /dev/null and b/extension.wasm differ diff --git a/grammars/marte b/grammars/marte new file mode 160000 index 0000000..1edbdc9 --- /dev/null +++ b/grammars/marte @@ -0,0 +1 @@ +Subproject commit 1edbdc955fe6c0cf5bccd33368f0eb03a62d2682 diff --git a/grammars/marte.wasm b/grammars/marte.wasm new file mode 100755 index 0000000..84a1f08 Binary files /dev/null and b/grammars/marte.wasm differ diff --git a/languages/marte/config.toml b/languages/marte/config.toml new file mode 100644 index 0000000..ce2c91e --- /dev/null +++ b/languages/marte/config.toml @@ -0,0 +1,11 @@ +name = "MARTe" +grammar = "marte" +path_suffixes = ["marte"] +line_comments = ["// "] +autoclose_before = "}])" +brackets = [ + { start = "(", end = ")", close = true, newline = true }, + { start = "[", end = "]", close = true, newline = true }, + { start = "{", end = "}", close = true, newline = true }, +] +language_servers = ["mdt"] diff --git a/languages/marte/highlights.scm b/languages/marte/highlights.scm new file mode 100644 index 0000000..6ad7955 --- /dev/null +++ b/languages/marte/highlights.scm @@ -0,0 +1,17 @@ +(property) @property +(attribute) @attribute +(marte_common) @keyword +(app) @function +(string_literal) @string +(definition) @constructor +(builtintype) @type.builtin +(number) @number +(comment) @comment +(assign) @operator +(obrace) @punctuation.bracket +(cbrace) @punctuation.bracket +(opar) @punctuation.bracket +(cpar) @punctuation.bracket +(vbar) @operator +(comma) @punctuation.delimiter + diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..afb9e0e --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,54 @@ +use zed_extension_api::{self as zed, Result}; + +struct Marte { + cached_binary_path: Option, +} + +impl Marte { + fn language_server_path( + &mut self, + _language_server_id: &zed::LanguageServerId, + worktree: &zed::Worktree, + ) -> Result { + // 1. Ask the worktree to resolve the binary in the system PATH + if let Some(path) = worktree.which("mdt") { + self.cached_binary_path = Some(path.clone()); + return Ok(path); + } + + // 2. Fallback to cache using zed::fs, NOT std::fs + if let Some(path) = &self.cached_binary_path { + // Note: in zed::fs, is_file is a boolean field, not a method + if std::fs::metadata(path).map_or(false, |stat| stat.is_file()) { + return Ok(path.clone()); + } + } + + Err("mdt executable not found in PATH. Please install it in /usr/bin/ or add it to your PATH.".to_string()) + } +} + +impl zed::Extension for Marte { + fn new() -> Self { + Self { + cached_binary_path: None, + } + } + + fn language_server_command( + &mut self, + language_server_id: &zed::LanguageServerId, + worktree: &zed::Worktree, + ) -> Result { + // Call the method to get the absolute path to /usr/bin/mdt + let path = self.language_server_path(language_server_id, worktree)?; + + Ok(zed::Command { + command: path, // Use the resolved absolute path here + args: vec!["lsp".to_string()], + env: Default::default(), + }) + } +} + +zed::register_extension!(Marte); diff --git a/test_layout.json b/test_layout.json new file mode 100644 index 0000000..4dc0e60 --- /dev/null +++ b/test_layout.json @@ -0,0 +1,138 @@ +{ + "Split": { + "direction": "Vertical", + "ratio": 0.5, + "left": { + "Leaf": { + "id": "view_0", + "title": "Main View", + "view_type": "Scope", + "signals": [ + "analog_1", + "analog_2" + ], + "signal_styles": { + "analog_2": { + "color": [ + 255, + 128, + 128 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": true + }, + "analog_1": { + "color": [ + 173, + 216, + 230 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": true + } + } + } + }, + "right": { + "Leaf": { + "id": "view_0_B", + "title": "Main View (Split)", + "view_type": "Logic", + "signals": [ + "digital_1", + "digital_2", + "digital_3", + "digital_4" + ], + "signal_styles": { + "digital_3": { + "color": [ + 144, + 238, + 144 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": false + }, + "digital_4": { + "color": [ + 255, + 215, + 0 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": false + }, + "analog_2": { + "color": [ + 255, + 128, + 128 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": false + }, + "analog_1": { + "color": [ + 173, + 216, + 230 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": false + }, + "digital_1": { + "color": [ + 173, + 216, + 230 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": false + }, + "digital_2": { + "color": [ + 255, + 128, + 128 + ], + "label": "", + "unit": "", + "scale": 1.0, + "offset": 0.0, + "line_style": "Solid", + "show_points": false + } + } + } + } + } +} \ No newline at end of file