@fresh-editor/fresh-editor 0.2.17 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/package.json +1 -1
  3. package/plugins/astro-lsp.ts +118 -0
  4. package/plugins/bash-lsp.ts +161 -0
  5. package/plugins/clojure-lsp.ts +125 -0
  6. package/plugins/cmake-lsp.ts +138 -0
  7. package/plugins/config-schema.json +275 -29
  8. package/plugins/dart-lsp.ts +144 -0
  9. package/plugins/diagnostics_panel.ts +4 -12
  10. package/plugins/diff_nav.i18n.json +128 -0
  11. package/plugins/diff_nav.ts +196 -0
  12. package/plugins/elixir-lsp.ts +120 -0
  13. package/plugins/erlang-lsp.ts +121 -0
  14. package/plugins/fsharp-lsp.ts +125 -0
  15. package/plugins/git_gutter.ts +5 -0
  16. package/plugins/gleam-lsp.ts +124 -0
  17. package/plugins/graphql-lsp.ts +139 -0
  18. package/plugins/haskell-lsp.ts +125 -0
  19. package/plugins/julia-lsp.ts +111 -0
  20. package/plugins/kotlin-lsp.ts +162 -0
  21. package/plugins/lib/finder.ts +19 -12
  22. package/plugins/lib/fresh.d.ts +30 -1
  23. package/plugins/lua-lsp.ts +161 -0
  24. package/plugins/nim-lsp.ts +118 -0
  25. package/plugins/nix-lsp.ts +125 -0
  26. package/plugins/nushell-lsp.ts +144 -0
  27. package/plugins/ocaml-lsp.ts +119 -0
  28. package/plugins/perl-lsp.ts +118 -0
  29. package/plugins/php-lsp.ts +165 -0
  30. package/plugins/pkg.ts +37 -76
  31. package/plugins/protobuf-lsp.ts +144 -0
  32. package/plugins/r-lsp.ts +118 -0
  33. package/plugins/ruby-lsp.ts +165 -0
  34. package/plugins/scala-lsp.ts +119 -0
  35. package/plugins/schemas/package.schema.json +437 -272
  36. package/plugins/schemas/theme.schema.json +18 -0
  37. package/plugins/solidity-lsp.ts +130 -0
  38. package/plugins/sql-lsp.ts +129 -0
  39. package/plugins/svelte-lsp.ts +119 -0
  40. package/plugins/swift-lsp.ts +120 -0
  41. package/plugins/tailwindcss-lsp.ts +119 -0
  42. package/plugins/terraform-lsp.ts +144 -0
  43. package/plugins/theme_editor.i18n.json +70 -14
  44. package/plugins/theme_editor.ts +71 -39
  45. package/plugins/toml-lsp.ts +162 -0
  46. package/plugins/typst-lsp.ts +165 -0
  47. package/plugins/vue-lsp.ts +118 -0
  48. package/plugins/yaml-lsp.ts +163 -0
@@ -0,0 +1,121 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * Erlang LSP Helper Plugin
6
+ *
7
+ * Server: erlang_ls (github.com/erlang-ls/erlang_ls)
8
+ * VS Code: "Erlang LS" extension
9
+ * Neovim: nvim-lspconfig erlangls
10
+ * Requires: Erlang/OTP 24+, rebar3
11
+ * Note: erlang_ls is archived; consider ELP (Erlang Language Platform)
12
+ * by WhatsApp as the recommended successor
13
+ * ELP: github.com/WhatsApp/erlang-language-platform
14
+ */
15
+
16
+ interface LspServerErrorData {
17
+ language: string;
18
+ server_command: string;
19
+ error_type: string;
20
+ message: string;
21
+ }
22
+
23
+ interface LspStatusClickedData {
24
+ language: string;
25
+ has_error: boolean;
26
+ }
27
+
28
+ interface ActionPopupResultData {
29
+ popup_id: string;
30
+ action_id: string;
31
+ }
32
+
33
+ const INSTALL_COMMANDS = {
34
+ brew: "brew install erlang_ls",
35
+ build: "git clone https://github.com/erlang-ls/erlang_ls && cd erlang_ls && make && make install",
36
+ nix: "nix-env -iA nixpkgs.erlang-ls",
37
+ };
38
+
39
+ let erlangLspError: { serverCommand: string; message: string } | null = null;
40
+
41
+ function on_erlang_lsp_server_error(data: LspServerErrorData): void {
42
+ if (data.language !== "erlang") {
43
+ return;
44
+ }
45
+
46
+ editor.debug(`erlang-lsp: Server error - ${data.error_type}: ${data.message}`);
47
+
48
+ erlangLspError = {
49
+ serverCommand: data.server_command,
50
+ message: data.message,
51
+ };
52
+
53
+ if (data.error_type === "not_found") {
54
+ editor.setStatus(
55
+ `Erlang LSP server '${data.server_command}' not found. Click status bar for help.`
56
+ );
57
+ } else {
58
+ editor.setStatus(`Erlang LSP error: ${data.message}`);
59
+ }
60
+ }
61
+ registerHandler("on_erlang_lsp_server_error", on_erlang_lsp_server_error);
62
+ editor.on("lsp_server_error", "on_erlang_lsp_server_error");
63
+
64
+ function on_erlang_lsp_status_clicked(data: LspStatusClickedData): void {
65
+ if (data.language !== "erlang" || !erlangLspError) {
66
+ return;
67
+ }
68
+
69
+ editor.debug("erlang-lsp: Status clicked, showing help popup");
70
+
71
+ editor.showActionPopup({
72
+ id: "erlang-lsp-help",
73
+ title: "Erlang Language Server Not Found",
74
+ message: `"${erlangLspError.serverCommand}" provides completion, diagnostics, navigation, and code actions for Erlang. Requires Erlang/OTP 24+.\n\nNote: erlang_ls is archived. Consider ELP (Erlang Language Platform) by WhatsApp as the successor: https://github.com/WhatsApp/erlang-language-platform\nConfigure via erlang_ls.config in your project root.\nVS Code users: Install "Erlang LS" or "Erlang Language Platform" extension.\nSee: https://github.com/erlang-ls/erlang_ls`,
75
+ actions: [
76
+ { id: "copy_brew", label: `Copy: ${INSTALL_COMMANDS.brew}` },
77
+ { id: "copy_nix", label: `Copy: ${INSTALL_COMMANDS.nix}` },
78
+ { id: "disable", label: "Disable Erlang LSP" },
79
+ { id: "dismiss", label: "Dismiss (ESC)" },
80
+ ],
81
+ });
82
+ }
83
+ registerHandler("on_erlang_lsp_status_clicked", on_erlang_lsp_status_clicked);
84
+ editor.on("lsp_status_clicked", "on_erlang_lsp_status_clicked");
85
+
86
+ function on_erlang_lsp_action_result(data: ActionPopupResultData): void {
87
+ if (data.popup_id !== "erlang-lsp-help") {
88
+ return;
89
+ }
90
+
91
+ editor.debug(`erlang-lsp: Action selected - ${data.action_id}`);
92
+
93
+ switch (data.action_id) {
94
+ case "copy_brew":
95
+ editor.setClipboard(INSTALL_COMMANDS.brew);
96
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.brew);
97
+ break;
98
+
99
+ case "copy_nix":
100
+ editor.setClipboard(INSTALL_COMMANDS.nix);
101
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nix);
102
+ break;
103
+
104
+ case "disable":
105
+ editor.disableLspForLanguage("erlang");
106
+ editor.setStatus("Erlang LSP disabled");
107
+ erlangLspError = null;
108
+ break;
109
+
110
+ case "dismiss":
111
+ case "dismissed":
112
+ break;
113
+
114
+ default:
115
+ editor.debug(`erlang-lsp: Unknown action: ${data.action_id}`);
116
+ }
117
+ }
118
+ registerHandler("on_erlang_lsp_action_result", on_erlang_lsp_action_result);
119
+ editor.on("action_popup_result", "on_erlang_lsp_action_result");
120
+
121
+ editor.debug("erlang-lsp: Plugin loaded");
@@ -0,0 +1,125 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * F# LSP Helper Plugin
6
+ *
7
+ * Server: fsautocomplete (FsAutoComplete)
8
+ * VS Code: "Ionide-fsharp" extension (bundles fsautocomplete)
9
+ * Neovim: nvim-lspconfig fsautocomplete
10
+ * Install via: dotnet tool, brew, or nix
11
+ * Requires: .NET SDK installed
12
+ */
13
+
14
+ interface LspServerErrorData {
15
+ language: string;
16
+ server_command: string;
17
+ error_type: string;
18
+ message: string;
19
+ }
20
+
21
+ interface LspStatusClickedData {
22
+ language: string;
23
+ has_error: boolean;
24
+ }
25
+
26
+ interface ActionPopupResultData {
27
+ popup_id: string;
28
+ action_id: string;
29
+ }
30
+
31
+ const INSTALL_COMMANDS = {
32
+ dotnet: "dotnet tool install -g fsautocomplete",
33
+ brew: "brew install fsautocomplete",
34
+ nix: "nix-env -iA nixpkgs.fsautocomplete",
35
+ };
36
+
37
+ let fsharpLspError: { serverCommand: string; message: string } | null = null;
38
+
39
+ function on_fsharp_lsp_server_error(data: LspServerErrorData): void {
40
+ if (data.language !== "fsharp") {
41
+ return;
42
+ }
43
+
44
+ editor.debug(`fsharp-lsp: Server error - ${data.error_type}: ${data.message}`);
45
+
46
+ fsharpLspError = {
47
+ serverCommand: data.server_command,
48
+ message: data.message,
49
+ };
50
+
51
+ if (data.error_type === "not_found") {
52
+ editor.setStatus(
53
+ `F# LSP server '${data.server_command}' not found. Click status bar for help.`
54
+ );
55
+ } else {
56
+ editor.setStatus(`F# LSP error: ${data.message}`);
57
+ }
58
+ }
59
+ registerHandler("on_fsharp_lsp_server_error", on_fsharp_lsp_server_error);
60
+ editor.on("lsp_server_error", "on_fsharp_lsp_server_error");
61
+
62
+ function on_fsharp_lsp_status_clicked(data: LspStatusClickedData): void {
63
+ if (data.language !== "fsharp" || !fsharpLspError) {
64
+ return;
65
+ }
66
+
67
+ editor.debug("fsharp-lsp: Status clicked, showing help popup");
68
+
69
+ editor.showActionPopup({
70
+ id: "fsharp-lsp-help",
71
+ title: "F# Language Server Not Found",
72
+ message: `"${fsharpLspError.serverCommand}" (FsAutoComplete) provides completion, diagnostics, code actions, and refactoring for F#. Requires .NET SDK.\n\nVS Code users: Install "Ionide-fsharp" (bundles fsautocomplete).\nSee: https://github.com/fsharp/FsAutoComplete`,
73
+ actions: [
74
+ { id: "copy_dotnet", label: `Copy: ${INSTALL_COMMANDS.dotnet}` },
75
+ { id: "copy_brew", label: `Copy: ${INSTALL_COMMANDS.brew}` },
76
+ { id: "copy_nix", label: `Copy: ${INSTALL_COMMANDS.nix}` },
77
+ { id: "disable", label: "Disable F# LSP" },
78
+ { id: "dismiss", label: "Dismiss (ESC)" },
79
+ ],
80
+ });
81
+ }
82
+ registerHandler("on_fsharp_lsp_status_clicked", on_fsharp_lsp_status_clicked);
83
+ editor.on("lsp_status_clicked", "on_fsharp_lsp_status_clicked");
84
+
85
+ function on_fsharp_lsp_action_result(data: ActionPopupResultData): void {
86
+ if (data.popup_id !== "fsharp-lsp-help") {
87
+ return;
88
+ }
89
+
90
+ editor.debug(`fsharp-lsp: Action selected - ${data.action_id}`);
91
+
92
+ switch (data.action_id) {
93
+ case "copy_dotnet":
94
+ editor.setClipboard(INSTALL_COMMANDS.dotnet);
95
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.dotnet);
96
+ break;
97
+
98
+ case "copy_brew":
99
+ editor.setClipboard(INSTALL_COMMANDS.brew);
100
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.brew);
101
+ break;
102
+
103
+ case "copy_nix":
104
+ editor.setClipboard(INSTALL_COMMANDS.nix);
105
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nix);
106
+ break;
107
+
108
+ case "disable":
109
+ editor.disableLspForLanguage("fsharp");
110
+ editor.setStatus("F# LSP disabled");
111
+ fsharpLspError = null;
112
+ break;
113
+
114
+ case "dismiss":
115
+ case "dismissed":
116
+ break;
117
+
118
+ default:
119
+ editor.debug(`fsharp-lsp: Unknown action: ${data.action_id}`);
120
+ }
121
+ }
122
+ registerHandler("on_fsharp_lsp_action_result", on_fsharp_lsp_action_result);
123
+ editor.on("action_popup_result", "on_fsharp_lsp_action_result");
124
+
125
+ editor.debug("fsharp-lsp: Plugin loaded");
@@ -248,6 +248,8 @@ async function updateGitGutter(bufferId: number): Promise<void> {
248
248
  editor.debug("Git Gutter: file not tracked by git");
249
249
  editor.clearLineIndicators(bufferId, NAMESPACE);
250
250
  state.hunks = [];
251
+ // Signal to other plugins that git is not available for this buffer
252
+ editor.setViewState(bufferId, "git_gutter_hunks", null);
251
253
  return;
252
254
  }
253
255
 
@@ -304,6 +306,9 @@ async function updateGitGutter(bufferId: number): Promise<void> {
304
306
  }
305
307
 
306
308
  state.hunks = hunks;
309
+
310
+ // Export hunks for other plugins (e.g. diff_nav) via shared view state
311
+ editor.setViewState(bufferId, "git_gutter_hunks", hunks);
307
312
  } finally {
308
313
  state.updating = false;
309
314
  }
@@ -0,0 +1,124 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * Gleam LSP Helper Plugin
6
+ *
7
+ * Server: Built into the Gleam compiler (gleam lsp)
8
+ * VS Code: "Gleam" extension
9
+ * Neovim: nvim-lspconfig gleam
10
+ * Note: LSP is bundled with the Gleam binary - install Gleam to get it
11
+ */
12
+
13
+ interface LspServerErrorData {
14
+ language: string;
15
+ server_command: string;
16
+ error_type: string;
17
+ message: string;
18
+ }
19
+
20
+ interface LspStatusClickedData {
21
+ language: string;
22
+ has_error: boolean;
23
+ }
24
+
25
+ interface ActionPopupResultData {
26
+ popup_id: string;
27
+ action_id: string;
28
+ }
29
+
30
+ const INSTALL_COMMANDS = {
31
+ brew: "brew install gleam",
32
+ cargo: "cargo install gleam",
33
+ nix: "nix-env -iA nixpkgs.gleam",
34
+ };
35
+
36
+ let gleamLspError: { serverCommand: string; message: string } | null = null;
37
+
38
+ function on_gleam_lsp_server_error(data: LspServerErrorData): void {
39
+ if (data.language !== "gleam") {
40
+ return;
41
+ }
42
+
43
+ editor.debug(`gleam-lsp: Server error - ${data.error_type}: ${data.message}`);
44
+
45
+ gleamLspError = {
46
+ serverCommand: data.server_command,
47
+ message: data.message,
48
+ };
49
+
50
+ if (data.error_type === "not_found") {
51
+ editor.setStatus(
52
+ `Gleam LSP server '${data.server_command}' not found. Click status bar for help.`
53
+ );
54
+ } else {
55
+ editor.setStatus(`Gleam LSP error: ${data.message}`);
56
+ }
57
+ }
58
+ registerHandler("on_gleam_lsp_server_error", on_gleam_lsp_server_error);
59
+ editor.on("lsp_server_error", "on_gleam_lsp_server_error");
60
+
61
+ function on_gleam_lsp_status_clicked(data: LspStatusClickedData): void {
62
+ if (data.language !== "gleam" || !gleamLspError) {
63
+ return;
64
+ }
65
+
66
+ editor.debug("gleam-lsp: Status clicked, showing help popup");
67
+
68
+ editor.showActionPopup({
69
+ id: "gleam-lsp-help",
70
+ title: "Gleam Language Server Not Found",
71
+ message: `The Gleam language server is built into the Gleam compiler binary. Install Gleam to get LSP support - no separate installation needed.\n\nProvides completion, diagnostics, hover, go-to-definition, and formatting.\nVS Code users: Install the "Gleam" extension.\nSee: https://gleam.run/getting-started/installing/`,
72
+ actions: [
73
+ { id: "copy_brew", label: `Copy: ${INSTALL_COMMANDS.brew}` },
74
+ { id: "copy_cargo", label: `Copy: ${INSTALL_COMMANDS.cargo}` },
75
+ { id: "copy_nix", label: `Copy: ${INSTALL_COMMANDS.nix}` },
76
+ { id: "disable", label: "Disable Gleam LSP" },
77
+ { id: "dismiss", label: "Dismiss (ESC)" },
78
+ ],
79
+ });
80
+ }
81
+ registerHandler("on_gleam_lsp_status_clicked", on_gleam_lsp_status_clicked);
82
+ editor.on("lsp_status_clicked", "on_gleam_lsp_status_clicked");
83
+
84
+ function on_gleam_lsp_action_result(data: ActionPopupResultData): void {
85
+ if (data.popup_id !== "gleam-lsp-help") {
86
+ return;
87
+ }
88
+
89
+ editor.debug(`gleam-lsp: Action selected - ${data.action_id}`);
90
+
91
+ switch (data.action_id) {
92
+ case "copy_brew":
93
+ editor.setClipboard(INSTALL_COMMANDS.brew);
94
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.brew);
95
+ break;
96
+
97
+ case "copy_cargo":
98
+ editor.setClipboard(INSTALL_COMMANDS.cargo);
99
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.cargo);
100
+ break;
101
+
102
+ case "copy_nix":
103
+ editor.setClipboard(INSTALL_COMMANDS.nix);
104
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nix);
105
+ break;
106
+
107
+ case "disable":
108
+ editor.disableLspForLanguage("gleam");
109
+ editor.setStatus("Gleam LSP disabled");
110
+ gleamLspError = null;
111
+ break;
112
+
113
+ case "dismiss":
114
+ case "dismissed":
115
+ break;
116
+
117
+ default:
118
+ editor.debug(`gleam-lsp: Unknown action: ${data.action_id}`);
119
+ }
120
+ }
121
+ registerHandler("on_gleam_lsp_action_result", on_gleam_lsp_action_result);
122
+ editor.on("action_popup_result", "on_gleam_lsp_action_result");
123
+
124
+ editor.debug("gleam-lsp: Plugin loaded");
@@ -0,0 +1,139 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * GraphQL LSP Helper Plugin
6
+ *
7
+ * Provides user-friendly error handling for GraphQL LSP server issues.
8
+ * When graphql-lsp fails to start, this plugin shows an actionable
9
+ * popup with installation instructions.
10
+ *
11
+ * Features:
12
+ * - Detects GraphQL LSP server errors (graphql-lsp)
13
+ * - Shows popup with install commands (npm)
14
+ * - Provides option to disable GraphQL LSP
15
+ *
16
+ * VS Code: "GraphQL: Language Feature Support" extension
17
+ * Neovim: nvim-lspconfig graphql
18
+ * Note: Requires a graphql-config file (.graphqlrc, graphql.config.js, etc.)
19
+ * Alternative: Apollo GraphQL extension (for Apollo users)
20
+ * Config docs: https://the-guild.dev/graphql/config
21
+ */
22
+
23
+ interface LspServerErrorData {
24
+ language: string;
25
+ server_command: string;
26
+ error_type: string;
27
+ message: string;
28
+ }
29
+
30
+ interface LspStatusClickedData {
31
+ language: string;
32
+ has_error: boolean;
33
+ }
34
+
35
+ interface ActionPopupResultData {
36
+ popup_id: string;
37
+ action_id: string;
38
+ }
39
+
40
+ // Install commands for GraphQL LSP server
41
+ // See: https://github.com/graphql/graphiql/tree/main/packages/graphql-language-service-cli
42
+ const INSTALL_COMMANDS = {
43
+ npm: "npm i -g graphql-language-service-cli",
44
+ yarn: "yarn global add graphql-language-service-cli",
45
+ };
46
+
47
+ // Track error state for GraphQL LSP
48
+ let graphqlLspError: { serverCommand: string; message: string } | null = null;
49
+
50
+ /**
51
+ * Handle LSP server errors for GraphQL
52
+ */
53
+ function on_graphql_lsp_server_error(data: LspServerErrorData): void {
54
+ if (data.language !== "graphql") {
55
+ return;
56
+ }
57
+
58
+ editor.debug(`graphql-lsp: Server error - ${data.error_type}: ${data.message}`);
59
+
60
+ graphqlLspError = {
61
+ serverCommand: data.server_command,
62
+ message: data.message,
63
+ };
64
+
65
+ if (data.error_type === "not_found") {
66
+ editor.setStatus(
67
+ `GraphQL LSP server '${data.server_command}' not found. Click status bar for help.`
68
+ );
69
+ } else {
70
+ editor.setStatus(`GraphQL LSP error: ${data.message}`);
71
+ }
72
+ }
73
+ registerHandler("on_graphql_lsp_server_error", on_graphql_lsp_server_error);
74
+ editor.on("lsp_server_error", "on_graphql_lsp_server_error");
75
+
76
+ /**
77
+ * Handle status bar click when there's a GraphQL LSP error
78
+ */
79
+ function on_graphql_lsp_status_clicked(data: LspStatusClickedData): void {
80
+ if (data.language !== "graphql" || !graphqlLspError) {
81
+ return;
82
+ }
83
+
84
+ editor.debug("graphql-lsp: Status clicked, showing help popup");
85
+
86
+ editor.showActionPopup({
87
+ id: "graphql-lsp-help",
88
+ title: "GraphQL Language Server Not Found",
89
+ message: `"${graphqlLspError.serverCommand}" provides code completion, validation, and hover info for GraphQL schemas and queries. Requires Node.js and a .graphqlrc config. Copy a command below to install it, or visit https://github.com/graphql/graphiql/tree/main/packages/graphql-language-service-cli for details.`,
90
+ actions: [
91
+ { id: "copy_npm", label: `Copy: ${INSTALL_COMMANDS.npm}` },
92
+ { id: "copy_yarn", label: `Copy: ${INSTALL_COMMANDS.yarn}` },
93
+ { id: "disable", label: "Disable GraphQL LSP" },
94
+ { id: "dismiss", label: "Dismiss (ESC)" },
95
+ ],
96
+ });
97
+ }
98
+ registerHandler("on_graphql_lsp_status_clicked", on_graphql_lsp_status_clicked);
99
+ editor.on("lsp_status_clicked", "on_graphql_lsp_status_clicked");
100
+
101
+ /**
102
+ * Handle action popup results for GraphQL LSP help
103
+ */
104
+ function on_graphql_lsp_action_result(data: ActionPopupResultData): void {
105
+ if (data.popup_id !== "graphql-lsp-help") {
106
+ return;
107
+ }
108
+
109
+ editor.debug(`graphql-lsp: Action selected - ${data.action_id}`);
110
+
111
+ switch (data.action_id) {
112
+ case "copy_npm":
113
+ editor.setClipboard(INSTALL_COMMANDS.npm);
114
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.npm);
115
+ break;
116
+
117
+ case "copy_yarn":
118
+ editor.setClipboard(INSTALL_COMMANDS.yarn);
119
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.yarn);
120
+ break;
121
+
122
+ case "disable":
123
+ editor.disableLspForLanguage("graphql");
124
+ editor.setStatus("GraphQL LSP disabled");
125
+ graphqlLspError = null;
126
+ break;
127
+
128
+ case "dismiss":
129
+ case "dismissed":
130
+ break;
131
+
132
+ default:
133
+ editor.debug(`graphql-lsp: Unknown action: ${data.action_id}`);
134
+ }
135
+ }
136
+ registerHandler("on_graphql_lsp_action_result", on_graphql_lsp_action_result);
137
+ editor.on("action_popup_result", "on_graphql_lsp_action_result");
138
+
139
+ editor.debug("graphql-lsp: Plugin loaded");
@@ -0,0 +1,125 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * Haskell LSP Helper Plugin
6
+ *
7
+ * Server: haskell-language-server (HLS)
8
+ * VS Code: "Haskell" extension (installs HLS via GHCup)
9
+ * Neovim: nvim-lspconfig hls
10
+ * Install via: GHCup (recommended), brew, nix
11
+ * Note: HLS must match your GHC version
12
+ */
13
+
14
+ interface LspServerErrorData {
15
+ language: string;
16
+ server_command: string;
17
+ error_type: string;
18
+ message: string;
19
+ }
20
+
21
+ interface LspStatusClickedData {
22
+ language: string;
23
+ has_error: boolean;
24
+ }
25
+
26
+ interface ActionPopupResultData {
27
+ popup_id: string;
28
+ action_id: string;
29
+ }
30
+
31
+ const INSTALL_COMMANDS = {
32
+ ghcup: "ghcup install hls",
33
+ brew: "brew install haskell-language-server",
34
+ nix: "nix-env -iA nixpkgs.haskell-language-server",
35
+ };
36
+
37
+ let haskellLspError: { serverCommand: string; message: string } | null = null;
38
+
39
+ function on_haskell_lsp_server_error(data: LspServerErrorData): void {
40
+ if (data.language !== "haskell") {
41
+ return;
42
+ }
43
+
44
+ editor.debug(`haskell-lsp: Server error - ${data.error_type}: ${data.message}`);
45
+
46
+ haskellLspError = {
47
+ serverCommand: data.server_command,
48
+ message: data.message,
49
+ };
50
+
51
+ if (data.error_type === "not_found") {
52
+ editor.setStatus(
53
+ `Haskell LSP server '${data.server_command}' not found. Click status bar for help.`
54
+ );
55
+ } else {
56
+ editor.setStatus(`Haskell LSP error: ${data.message}`);
57
+ }
58
+ }
59
+ registerHandler("on_haskell_lsp_server_error", on_haskell_lsp_server_error);
60
+ editor.on("lsp_server_error", "on_haskell_lsp_server_error");
61
+
62
+ function on_haskell_lsp_status_clicked(data: LspStatusClickedData): void {
63
+ if (data.language !== "haskell" || !haskellLspError) {
64
+ return;
65
+ }
66
+
67
+ editor.debug("haskell-lsp: Status clicked, showing help popup");
68
+
69
+ editor.showActionPopup({
70
+ id: "haskell-lsp-help",
71
+ title: "Haskell Language Server Not Found",
72
+ message: `"${haskellLspError.serverCommand}" (HLS) provides completion, diagnostics, code actions, and refactoring for Haskell. HLS must match your GHC version.\n\nRecommended: Install via GHCup (manages GHC + HLS versions).\nInstall GHCup: curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh\nVS Code users: Install the "Haskell" extension (auto-installs HLS via GHCup).\nSee: https://haskell-language-server.readthedocs.io`,
73
+ actions: [
74
+ { id: "copy_ghcup", label: `Copy: ${INSTALL_COMMANDS.ghcup}` },
75
+ { id: "copy_brew", label: `Copy: ${INSTALL_COMMANDS.brew}` },
76
+ { id: "copy_nix", label: `Copy: ${INSTALL_COMMANDS.nix}` },
77
+ { id: "disable", label: "Disable Haskell LSP" },
78
+ { id: "dismiss", label: "Dismiss (ESC)" },
79
+ ],
80
+ });
81
+ }
82
+ registerHandler("on_haskell_lsp_status_clicked", on_haskell_lsp_status_clicked);
83
+ editor.on("lsp_status_clicked", "on_haskell_lsp_status_clicked");
84
+
85
+ function on_haskell_lsp_action_result(data: ActionPopupResultData): void {
86
+ if (data.popup_id !== "haskell-lsp-help") {
87
+ return;
88
+ }
89
+
90
+ editor.debug(`haskell-lsp: Action selected - ${data.action_id}`);
91
+
92
+ switch (data.action_id) {
93
+ case "copy_ghcup":
94
+ editor.setClipboard(INSTALL_COMMANDS.ghcup);
95
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.ghcup);
96
+ break;
97
+
98
+ case "copy_brew":
99
+ editor.setClipboard(INSTALL_COMMANDS.brew);
100
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.brew);
101
+ break;
102
+
103
+ case "copy_nix":
104
+ editor.setClipboard(INSTALL_COMMANDS.nix);
105
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nix);
106
+ break;
107
+
108
+ case "disable":
109
+ editor.disableLspForLanguage("haskell");
110
+ editor.setStatus("Haskell LSP disabled");
111
+ haskellLspError = null;
112
+ break;
113
+
114
+ case "dismiss":
115
+ case "dismissed":
116
+ break;
117
+
118
+ default:
119
+ editor.debug(`haskell-lsp: Unknown action: ${data.action_id}`);
120
+ }
121
+ }
122
+ registerHandler("on_haskell_lsp_action_result", on_haskell_lsp_action_result);
123
+ editor.on("action_popup_result", "on_haskell_lsp_action_result");
124
+
125
+ editor.debug("haskell-lsp: Plugin loaded");