Gleam-authored Zed extension (Gleam → Wasm guest) for Gleam LSP + highlighting
6.2 kB
194 lines
1{
2 description = "Gleam Zed extension (Gleam → Wasm guest)";
3
4 inputs = {
5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
6 systems.url = "github:nix-systems/default";
7
8 # Wasm-capable Gleam (Zed extension export). Override locally with:
9 # nix build --override-input gleam path:../gleam
10 gleam = {
11 url = "git+https://tangled.org/nandi.uk/gleam?ref=wasm";
12 inputs.nixpkgs.follows = "nixpkgs";
13 };
14 };
15
16 outputs =
17 {
18 self,
19 nixpkgs,
20 systems,
21 gleam,
22 ...
23 }:
24 let
25 forEachSystem = nixpkgs.lib.genAttrs (import systems);
26 in
27 {
28 packages = forEachSystem (
29 system:
30 let
31 pkgs = nixpkgs.legacyPackages.${system};
32 inherit (pkgs) lib;
33
34 gleamToml = lib.importTOML ./gleam.toml;
35
36 # Wasm-capable gleam from the flake input.
37 gleamBin = gleam.packages.${system}.gleam;
38
39 # Prebuilt extension for Install Dev Extension (no cargo rebuild).
40 zed-extension = pkgs.stdenv.mkDerivation {
41 pname = "zed-gleam";
42 version = gleamToml.version;
43
44 src = lib.cleanSourceWith {
45 src = ./.;
46 filter =
47 path: type:
48 let
49 base = baseNameOf path;
50 in
51 lib.cleanSourceFilter path type
52 && base != "target"
53 && base != "build"
54 && base != "grammars"
55 && base != "result"
56 && base != "result-zed"
57 && !(lib.hasSuffix ".wasm" base)
58 && base != "Cargo.lock";
59 };
60
61 nativeBuildInputs = [
62 gleamBin
63 ];
64
65 buildPhase = ''
66 runHook preBuild
67 export HOME=$TMPDIR
68 # `gleam export zed-extension` writes extension.wasm in the package root.
69 gleam export zed-extension
70 runHook postBuild
71 '';
72
73 installPhase = ''
74 runHook preInstall
75 mkdir -p $out
76 cp extension.wasm $out/
77 cp -r languages $out/
78
79 # No [lib] section: Install Dev Extension must not run cargo.
80 # Prebuilt extension.wasm is the Gleam guest.
81 cat > $out/extension.toml <<'EOF'
82 id = "gleam"
83 name = "Gleam"
84 description = "Gleam support (Gleam Wasm guest)."
85 version = "0.6.0"
86 schema_version = 1
87 authors = ["Marshall Bowers <elliott.codes@gmail.com>", "nandi"]
88 repository = "https://tangled.org/nandi.uk/zed-gleam-native"
89
90 [language_servers.gleam]
91 name = "Gleam LSP"
92 language = "Gleam"
93
94 [grammars.gleam]
95 repository = "https://github.com/gleam-lang/tree-sitter-gleam"
96 commit = "0153f8b875cd02034b553f3a84a2f5ee67a80364"
97
98 [slash_commands.gleam-project]
99 description = "Returns information about the current Gleam project."
100 requires_argument = false
101 EOF
102
103 cat > $out/README.txt <<EOF
104 Gleam Zed extension (Gleam Wasm guest)
105 Built with: ${gleamBin}
106
107 Install:
108 nix run .#install-zed-extension -- ~/zed-gleam-dev
109 # then Zed → Extensions → Install Dev Extension → ~/zed-gleam-dev
110 EOF
111 runHook postInstall
112 '';
113
114 meta = {
115 description = "Prebuilt Gleam Zed extension (extension.wasm from Gleam)";
116 homepage = "https://tangled.org/nandi.uk/zed-gleam-native";
117 license = lib.licenses.asl20;
118 };
119 };
120 in
121 {
122 default = zed-extension;
123 inherit zed-extension;
124 inherit gleamBin;
125 gleam = gleamBin;
126 }
127 );
128
129 apps = forEachSystem (
130 system:
131 let
132 pkgs = nixpkgs.legacyPackages.${system};
133 zed = self.packages.${system}.zed-extension;
134 installScript = pkgs.writeShellApplication {
135 name = "install-zed-extension";
136 text = ''
137 set -euo pipefail
138 dest="''${1:-$HOME/zed-gleam-dev}"
139 echo "Installing Gleam Zed extension → $dest"
140 mkdir -p "$dest"
141 # Store path is immutable; copy so Zed can re-scan / write if needed.
142 cp -a ${zed}/. "$dest/"
143 chmod -R u+w "$dest"
144 echo "Done. In Zed: Extensions → Install Dev Extension → $dest"
145 echo " (prebuilt extension.wasm; no cargo rebuild required if Zed accepts the tree)"
146 '';
147 };
148 in
149 {
150 default = {
151 type = "app";
152 program = "${installScript}/bin/install-zed-extension";
153 };
154 install-zed-extension = {
155 type = "app";
156 program = "${installScript}/bin/install-zed-extension";
157 };
158 }
159 );
160
161 devShells = forEachSystem (
162 system:
163 let
164 pkgs = nixpkgs.legacyPackages.${system};
165 gleamBin = self.packages.${system}.gleam;
166 in
167 {
168 default = pkgs.mkShell {
169 packages = with pkgs; [
170 gleamBin
171 rustc
172 cargo
173 ];
174 GLEAM = "${gleamBin}/bin/gleam";
175 shellHook = ''
176 echo "zed-gleam-native dev shell"
177 echo " GLEAM=$GLEAM (wasm-capable, for cargo driver / gleam export)"
178 echo " gleam export zed-extension"
179 echo " cargo build --release --target wasm32-wasip2"
180 echo " nix build .#zed-extension"
181 echo " nix run .#install-zed-extension"
182 '';
183 };
184 }
185 );
186
187 checks = forEachSystem (system: {
188 # Builds gleam from the Tangled input, then exports the extension.
189 zed-extension = self.packages.${system}.zed-extension;
190 });
191
192 formatter = forEachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style);
193 };
194}