1{
2 lib,
3 pkgs,
4 ...
5}: let
6 # Helper function to create language server definitions
7 mkLspServer = name: {
8 command,
9 helix-command ? null,
10 args ? null,
11 config ? null,
12 }: {
13 inherit name command helix-command args config;
14 };
15
16 # Helper function to create formatter definitions
17 mkFormatter = name: {
18 type,
19 command ? null,
20 args ? null,
21 lspName ? null,
22 config ? null,
23 }: {
24 inherit name type command args lspName config;
25 };
26
27 # Helper function to create language definitions
28 mkLanguage = name: {
29 full-name ? name,
30 auto-format ? true,
31 file-types ? null,
32 language-servers ? [],
33 zed-only-language-servers ? [],
34 helix-only-language-servers ? [],
35 formatter ? null,
36 helix-formatter ? null,
37 code-actions-on-format ? null,
38 }: {
39 inherit name full-name auto-format file-types language-servers zed-only-language-servers helix-only-language-servers formatter helix-formatter code-actions-on-format;
40 };
41in {
42 options.mySnippets.editor = lib.mkOption {
43 type = lib.types.attrs;
44 default = {};
45 description = "Editor configuration data";
46 };
47
48 config.mySnippets.editor = {
49 # Language Servers
50 languageServers = {
51 biome = mkLspServer "biome" {
52 command = lib.getExe pkgs.biome;
53 args = ["lsp-proxy"];
54 };
55
56 tailwindcss-language-server = mkLspServer "tailwindcss-language-server" {
57 command = pkgs.writeScript "tailwindcss-language-server-bun" ''
58 #!${lib.getExe pkgs.bash} -e
59 exec ${lib.getExe pkgs.bun} ${lib.getExe pkgs.tailwindcss-language-server}
60 '';
61 helix-command = let
62 fd = lib.getExe pkgs.fd;
63 xargs = "${pkgs.uutils-findutils}/bin/xargs";
64 grep = lib.getExe pkgs.gnugrep;
65 bun = lib.getExe pkgs.bun;
66 twls = lib.getExe pkgs.tailwindcss-language-server;
67 in
68 pkgs.writeScript "tailwindcss-language-server-bun-helix" ''
69 #!${lib.getExe pkgs.bash} -euo
70
71 if ! ${fd} -H -I -E "node_modules" "package\\.json$" . | \
72 ${xargs} ${grep} -q '"tailwindcss"'; then
73
74 exit 0
75 fi
76
77 exec ${bun} ${twls}
78 '';
79 args = [];
80 config = {provideFormatter = false;};
81 };
82
83 vscode-html-language-server = mkLspServer "vscode-html-language-server" {
84 command = lib.getExe pkgs.bun;
85 args = ["${pkgs.vscode-langservers-extracted}/lib/node_modules/vscode-langservers-extracted/bin/vscode-html-language-server" "--stdio"];
86 };
87
88 superhtml = mkLspServer "superhtml" {
89 command = lib.getExe pkgs.superhtml;
90 args = ["lsp"];
91 };
92
93 css-language-server = mkLspServer "css-language-server" {
94 command = lib.getExe pkgs.bun;
95 args = ["${pkgs.vscode-css-languageserver}/lib/node_modules/vscode-css-languageserver/out/node/cssServerMain.js" "--stdio"];
96 };
97
98 json-language-server = mkLspServer "json-language-server" {
99 command = lib.getExe pkgs.bun;
100 args = ["${pkgs.vscode-json-languageserver}/lib/node_modules/vscode-json-languageserver/bin/vscode-json-languageserver" "--stdio"];
101 };
102
103 vtsls = mkLspServer "vtsls" {
104 command = lib.getExe pkgs.bun;
105 args = ["${pkgs.vtsls}/bin/vtsls" "--stdio"];
106 };
107
108 svelte-language-server = mkLspServer "svelte-language-server" {
109 command = lib.getExe pkgs.bun;
110 args = ["${pkgs.svelte-language-server}/lib/node_modules/svelte-language-server/bin/server.js" "--stdio"];
111 };
112
113 vue-language-server = mkLspServer "vue-language-server" {
114 command = lib.getExe pkgs.bun;
115 args = ["${pkgs.vue-language-server}/lib/language-tools/packages/language-server/bin/vue-language-server.js" "--stdio"];
116 };
117
118 bash-language-server = mkLspServer "bash-language-server" {
119 command = lib.getExe pkgs.bash-language-server;
120 args = ["start"];
121 };
122
123 fish-lsp = mkLspServer "fish-lsp" {
124 command = lib.getExe pkgs.fish-lsp;
125 args = ["start"];
126 };
127
128 nixd = mkLspServer "nixd" {
129 command = lib.getExe pkgs.nixd;
130 config.formatting.command = [(lib.getExe pkgs.alejandra) "--quiet" "--"];
131 };
132
133 nil = mkLspServer "nil" {
134 command = lib.getExe pkgs.nil;
135 args = ["--stdio"];
136 };
137
138 marksman = mkLspServer "marksman" {
139 command = lib.getExe pkgs.marksman;
140 args = ["server"];
141 };
142
143 gopls = mkLspServer "gopls" {
144 command = lib.getExe pkgs.gopls;
145 args = ["serve"];
146 };
147
148 rust-analyzer = mkLspServer "rust-analyzer" {
149 command = lib.getExe pkgs.rust-analyzer;
150 };
151
152 zls = mkLspServer "zls" {
153 command = lib.getExe pkgs.zls;
154 };
155
156 glsl_analyzer = mkLspServer "glsl_analyzer" {
157 command = lib.getExe pkgs.glsl_analyzer;
158 };
159
160 lua-language-server = mkLspServer "lua-language-server" {
161 command = lib.getExe pkgs.lua-language-server;
162 };
163
164 gleam = mkLspServer "gleam" {
165 command = lib.getExe pkgs.gleam;
166 args = ["lsp"];
167 };
168
169 gdscript-language-server = mkLspServer "gdscript-language-server" {
170 command = lib.getExe pkgs.netcat;
171 args = ["127.0.0.1" "6005"];
172 config = {language-id = "gdscript";};
173 };
174
175 solargraph = mkLspServer "solargraph" {
176 command = lib.getExe pkgs.rubyPackages.solargraph;
177 args = ["stdio"];
178 };
179
180 #rubocop = mkLspServer "rubocop" {
181 # command = lib.getExe pkgs.rubocop;
182 #};
183 };
184
185 # Formatters
186 formatters = {
187 biome = mkFormatter "biome" {
188 type = "lsp";
189 };
190
191 biomeHtml = mkFormatter "biomeHtml" {
192 type = "external";
193 command = lib.getExe pkgs.biome;
194 args = ["format" "--use-server" "--html-formatter-enabled=true" "--stdin-file-path" "{buffer_path}"];
195 };
196
197 shfmt = mkFormatter "shfmt" {
198 type = "external";
199 command = lib.getExe pkgs.shfmt;
200 args = ["-i" "2"];
201 };
202
203 alejandra = mkFormatter "alejandra" {
204 type = "external";
205 command = lib.getExe pkgs.alejandra;
206 };
207
208 mdformat = mkFormatter "mdformat" {
209 type = "external";
210 command = lib.getExe pkgs.mdformat;
211 };
212
213 stylua = mkFormatter "stylua" {
214 type = "external";
215 command = lib.getExe pkgs.stylua;
216 };
217
218 gdscript-formatter = mkFormatter "gdscript-formatter" {
219 type = "external";
220 command = lib.getExe pkgs.gdscript-formatter;
221 };
222
223 prettier = mkFormatter "prettier" {
224 type = "external";
225 command = lib.getExe pkgs.bun;
226 args = ["${pkgs.prettier}/bin/prettier.cjs" "--stdin-filepath" "{buffer_path}"];
227 };
228 };
229
230 # Languages
231 languages = {
232 html = mkLanguage "html" {
233 full-name = "HTML";
234 language-servers = ["vscode-html-language-server" "biome"];
235 zed-only-language-servers = ["!eslint" "..."];
236 helix-only-language-servers = ["tailwindcss-language-server"];
237 formatter = "biome";
238 helix-formatter = "biomeHtml";
239 code-actions-on-format = {
240 "source.fixAll.biome" = true;
241 "html.formatter.enabled.biome" = true;
242 };
243 };
244
245 css = mkLanguage "css" {
246 full-name = "CSS";
247 language-servers = ["css-language-server" "biome"];
248 zed-only-language-servers = ["..."];
249 helix-only-language-servers = ["tailwindcss-language-server"];
250 formatter = "biome";
251 code-actions-on-format = {
252 "source.fixAll.biome" = true;
253 "source.organizeImports.biome" = true;
254 };
255 };
256
257 javascript = mkLanguage "javascript" {
258 full-name = "JavaScript";
259 language-servers = ["vtsls" "biome"];
260 zed-only-language-servers = ["!eslint" "!typescript-language-server" "..."];
261 helix-only-language-servers = ["tailwindcss-language-server"];
262 formatter = "biome";
263 code-actions-on-format = {
264 "source.fixAll.biome" = true;
265 "source.organizeImports.biome" = true;
266 };
267 };
268
269 typescript = mkLanguage "typescript" {
270 full-name = "TypeScript";
271 language-servers = ["vtsls" "biome"];
272 zed-only-language-servers = ["!eslint" "!typescript-language-server" "..."];
273 helix-only-language-servers = ["tailwindcss-language-server"];
274 formatter = "biome";
275 code-actions-on-format = {
276 "source.fixAll.biome" = true;
277 "source.organizeImports.biome" = true;
278 };
279 };
280
281 jsx = mkLanguage "jsx" {
282 full-name = "JSX";
283 language-servers = ["vtsls" "biome"];
284 zed-only-language-servers = ["!eslint" "!typescript-language-server" "..."];
285 helix-only-language-servers = ["tailwindcss-language-server"];
286 formatter = "biome";
287 code-actions-on-format = {
288 "source.fixAll.biome" = true;
289 "source.organizeImports.biome" = true;
290 };
291 };
292
293 tsx = mkLanguage "tsx" {
294 full-name = "TSX";
295 language-servers = ["vtsls" "biome"];
296 zed-only-language-servers = ["!eslint" "!typescript-language-server" "..."];
297 helix-only-language-servers = ["tailwindcss-language-server"];
298 formatter = "biome";
299 code-actions-on-format = {
300 "source.fixAll.biome" = true;
301 "source.organizeImports.biome" = true;
302 };
303 };
304
305 svelte = mkLanguage "svelte" {
306 full-name = "Svelte";
307 language-servers = ["svelte-language-server" "vtsls" "biome"];
308 zed-only-language-servers = ["!eslint" "!typescript-language-server" "..."];
309 helix-only-language-servers = ["tailwindcss-language-server"];
310 formatter = "biome";
311 code-actions-on-format = {
312 "source.fixAll.biome" = true;
313 "source.organizeImports.biome" = true;
314 };
315 };
316
317 vue = mkLanguage "vue" {
318 full-name = "Vue.js";
319 language-servers = ["vue-language-server" "biome"];
320 zed-only-language-servers = ["!eslint" "!typescript-language-server" "..."];
321 helix-only-language-servers = ["tailwindcss-language-server"];
322 formatter = "biome";
323 code-actions-on-format = {
324 "source.fixAll.biome" = true;
325 "source.organizeImports.biome" = true;
326 };
327 };
328
329 json = mkLanguage "json" {
330 full-name = "JSON";
331 language-servers = ["json-language-server" "biome"];
332 formatter = "biome";
333 code-actions-on-format = {
334 "source.fixAll.biome" = true;
335 };
336 };
337
338 jsonc = mkLanguage "jsonc" {
339 full-name = "JSONC";
340 language-servers = ["json-language-server" "biome"];
341 formatter = "biome";
342 code-actions-on-format = {
343 "source.fixAll.biome" = true;
344 "source.organizeImports.biome" = true;
345 };
346 };
347
348 bash = mkLanguage "bash" {
349 full-name = "Shell Script";
350 file-types = ["sh" "bash" "dash" "ksh" "mksh"];
351 language-servers = ["bash-language-server"];
352 formatter = "shfmt";
353 };
354
355 fish = mkLanguage "fish" {
356 full-name = "Fish";
357 language-servers = ["fish-lsp"];
358 };
359
360 nix = mkLanguage "nix" {
361 full-name = "Nix";
362 language-servers = ["nixd" "nil"];
363 formatter = "alejandra";
364 };
365
366 markdown = mkLanguage "markdown" {
367 full-name = "Markdown";
368 language-servers = ["marksman"];
369 formatter = "prettier";
370 };
371
372 go = mkLanguage "go" {
373 full-name = "Go";
374 language-servers = ["gopls"];
375 };
376
377 rust = mkLanguage "rust" {
378 full-name = "Rust";
379 language-servers = ["rust-analyzer"];
380 };
381
382 zig = mkLanguage "zig" {
383 full-name = "Zig";
384 language-servers = ["zls"];
385 };
386
387 glsl = mkLanguage "glsl" {
388 full-name = "GLSL";
389 language-servers = ["glsl_analyzer"];
390 };
391
392 lua = mkLanguage "lua" {
393 full-name = "Lua";
394 language-servers = ["lua-language-server"];
395 formatter = "stylua";
396 };
397
398 gleam = mkLanguage "gleam" {
399 full-name = "Gleam";
400 language-servers = ["gleam"];
401 };
402
403 gdscript = mkLanguage "gdscript" {
404 full-name = "GDScript";
405 language-servers = ["gdscript-language-server"];
406 formatter = "gdscript-formatter";
407 };
408
409 #ruby = mkLanguage "ruby" {
410 # full-name = "Ruby";
411 # language-servers = ["solargraph" "rubocop"];
412 #};
413 };
414 };
415}