@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,125 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * Nix LSP Helper Plugin
6
+ *
7
+ * Server: nil (github.com/oxalica/nil)
8
+ * VS Code: "Nix IDE" extension (uses nil or nixd)
9
+ * Neovim: nvim-lspconfig nil_ls
10
+ * Alternative: nixd (richer completions, option evaluation, flake support)
11
+ * Note: rnix-lsp is deprecated, use nil or nixd instead
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
+ nix_profile: "nix profile install github:oxalica/nil",
33
+ nix_env: "nix-env -iA nixpkgs.nil",
34
+ nixd: "nix profile install nixpkgs#nixd",
35
+ };
36
+
37
+ let nixLspError: { serverCommand: string; message: string } | null = null;
38
+
39
+ function on_nix_lsp_server_error(data: LspServerErrorData): void {
40
+ if (data.language !== "nix") {
41
+ return;
42
+ }
43
+
44
+ editor.debug(`nix-lsp: Server error - ${data.error_type}: ${data.message}`);
45
+
46
+ nixLspError = {
47
+ serverCommand: data.server_command,
48
+ message: data.message,
49
+ };
50
+
51
+ if (data.error_type === "not_found") {
52
+ editor.setStatus(
53
+ `Nix LSP server '${data.server_command}' not found. Click status bar for help.`
54
+ );
55
+ } else {
56
+ editor.setStatus(`Nix LSP error: ${data.message}`);
57
+ }
58
+ }
59
+ registerHandler("on_nix_lsp_server_error", on_nix_lsp_server_error);
60
+ editor.on("lsp_server_error", "on_nix_lsp_server_error");
61
+
62
+ function on_nix_lsp_status_clicked(data: LspStatusClickedData): void {
63
+ if (data.language !== "nix" || !nixLspError) {
64
+ return;
65
+ }
66
+
67
+ editor.debug("nix-lsp: Status clicked, showing help popup");
68
+
69
+ editor.showActionPopup({
70
+ id: "nix-lsp-help",
71
+ title: "Nix Language Server Not Found",
72
+ message: `"${nixLspError.serverCommand}" provides completion, diagnostics, go-to-definition, and rename for Nix files.\n\nAlternative: nixd offers richer completions, option evaluation, and flake support.\nNote: rnix-lsp is deprecated.\nVS Code users: Install "Nix IDE" extension.\nSee: https://github.com/oxalica/nil`,
73
+ actions: [
74
+ { id: "copy_nix_profile", label: `Copy: ${INSTALL_COMMANDS.nix_profile}` },
75
+ { id: "copy_nix_env", label: `Copy: ${INSTALL_COMMANDS.nix_env}` },
76
+ { id: "copy_nixd", label: `Copy: ${INSTALL_COMMANDS.nixd}` },
77
+ { id: "disable", label: "Disable Nix LSP" },
78
+ { id: "dismiss", label: "Dismiss (ESC)" },
79
+ ],
80
+ });
81
+ }
82
+ registerHandler("on_nix_lsp_status_clicked", on_nix_lsp_status_clicked);
83
+ editor.on("lsp_status_clicked", "on_nix_lsp_status_clicked");
84
+
85
+ function on_nix_lsp_action_result(data: ActionPopupResultData): void {
86
+ if (data.popup_id !== "nix-lsp-help") {
87
+ return;
88
+ }
89
+
90
+ editor.debug(`nix-lsp: Action selected - ${data.action_id}`);
91
+
92
+ switch (data.action_id) {
93
+ case "copy_nix_profile":
94
+ editor.setClipboard(INSTALL_COMMANDS.nix_profile);
95
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nix_profile);
96
+ break;
97
+
98
+ case "copy_nix_env":
99
+ editor.setClipboard(INSTALL_COMMANDS.nix_env);
100
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nix_env);
101
+ break;
102
+
103
+ case "copy_nixd":
104
+ editor.setClipboard(INSTALL_COMMANDS.nixd);
105
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nixd);
106
+ break;
107
+
108
+ case "disable":
109
+ editor.disableLspForLanguage("nix");
110
+ editor.setStatus("Nix LSP disabled");
111
+ nixLspError = null;
112
+ break;
113
+
114
+ case "dismiss":
115
+ case "dismissed":
116
+ break;
117
+
118
+ default:
119
+ editor.debug(`nix-lsp: Unknown action: ${data.action_id}`);
120
+ }
121
+ }
122
+ registerHandler("on_nix_lsp_action_result", on_nix_lsp_action_result);
123
+ editor.on("action_popup_result", "on_nix_lsp_action_result");
124
+
125
+ editor.debug("nix-lsp: Plugin loaded");
@@ -0,0 +1,144 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * Nushell LSP Helper Plugin
6
+ *
7
+ * Provides user-friendly error handling for Nushell LSP server issues.
8
+ * The LSP server is built into the Nushell binary (nu --lsp).
9
+ *
10
+ * Features:
11
+ * - Detects Nushell LSP server errors
12
+ * - Shows popup with install instructions for Nushell
13
+ * - Provides option to disable Nushell LSP
14
+ *
15
+ * VS Code: "Nushell" extension (vscode-nushell-lang)
16
+ * Neovim: nvim-lspconfig nushell
17
+ * Note: The LSP server is built into the `nu` binary itself
18
+ * No separate LSP installation needed if Nushell is installed
19
+ */
20
+
21
+ interface LspServerErrorData {
22
+ language: string;
23
+ server_command: string;
24
+ error_type: string;
25
+ message: string;
26
+ }
27
+
28
+ interface LspStatusClickedData {
29
+ language: string;
30
+ has_error: boolean;
31
+ }
32
+
33
+ interface ActionPopupResultData {
34
+ popup_id: string;
35
+ action_id: string;
36
+ }
37
+
38
+ // Install commands for Nushell (which includes the language server)
39
+ // See: https://www.nushell.sh/book/installation.html
40
+ const INSTALL_COMMANDS = {
41
+ cargo: "cargo install nu",
42
+ brew: "brew install nushell",
43
+ winget: "winget install nushell",
44
+ };
45
+
46
+ // Track error state for Nushell LSP
47
+ let nushellLspError: { serverCommand: string; message: string } | null = null;
48
+
49
+ /**
50
+ * Handle LSP server errors for Nushell
51
+ */
52
+ function on_nushell_lsp_server_error(data: LspServerErrorData): void {
53
+ if (data.language !== "nushell") {
54
+ return;
55
+ }
56
+
57
+ editor.debug(`nushell-lsp: Server error - ${data.error_type}: ${data.message}`);
58
+
59
+ nushellLspError = {
60
+ serverCommand: data.server_command,
61
+ message: data.message,
62
+ };
63
+
64
+ if (data.error_type === "not_found") {
65
+ editor.setStatus(
66
+ `Nushell LSP server '${data.server_command}' not found. Click status bar for help.`
67
+ );
68
+ } else {
69
+ editor.setStatus(`Nushell LSP error: ${data.message}`);
70
+ }
71
+ }
72
+ registerHandler("on_nushell_lsp_server_error", on_nushell_lsp_server_error);
73
+ editor.on("lsp_server_error", "on_nushell_lsp_server_error");
74
+
75
+ /**
76
+ * Handle status bar click when there's a Nushell LSP error
77
+ */
78
+ function on_nushell_lsp_status_clicked(data: LspStatusClickedData): void {
79
+ if (data.language !== "nushell" || !nushellLspError) {
80
+ return;
81
+ }
82
+
83
+ editor.debug("nushell-lsp: Status clicked, showing help popup");
84
+
85
+ editor.showActionPopup({
86
+ id: "nushell-lsp-help",
87
+ title: "Nushell Language Server Not Found",
88
+ message: `The Nushell LSP server is built into the "nu" binary. Install Nushell to get LSP support. Visit https://www.nushell.sh/book/installation.html for platform-specific instructions.`,
89
+ actions: [
90
+ { id: "copy_cargo", label: `Copy: ${INSTALL_COMMANDS.cargo}` },
91
+ { id: "copy_brew", label: `Copy: ${INSTALL_COMMANDS.brew}` },
92
+ { id: "copy_winget", label: `Copy: ${INSTALL_COMMANDS.winget} (Windows)` },
93
+ { id: "disable", label: "Disable Nushell LSP" },
94
+ { id: "dismiss", label: "Dismiss (ESC)" },
95
+ ],
96
+ });
97
+ }
98
+ registerHandler("on_nushell_lsp_status_clicked", on_nushell_lsp_status_clicked);
99
+ editor.on("lsp_status_clicked", "on_nushell_lsp_status_clicked");
100
+
101
+ /**
102
+ * Handle action popup results for Nushell LSP help
103
+ */
104
+ function on_nushell_lsp_action_result(data: ActionPopupResultData): void {
105
+ if (data.popup_id !== "nushell-lsp-help") {
106
+ return;
107
+ }
108
+
109
+ editor.debug(`nushell-lsp: Action selected - ${data.action_id}`);
110
+
111
+ switch (data.action_id) {
112
+ case "copy_cargo":
113
+ editor.setClipboard(INSTALL_COMMANDS.cargo);
114
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.cargo);
115
+ break;
116
+
117
+ case "copy_brew":
118
+ editor.setClipboard(INSTALL_COMMANDS.brew);
119
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.brew);
120
+ break;
121
+
122
+ case "copy_winget":
123
+ editor.setClipboard(INSTALL_COMMANDS.winget);
124
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.winget);
125
+ break;
126
+
127
+ case "disable":
128
+ editor.disableLspForLanguage("nushell");
129
+ editor.setStatus("Nushell LSP disabled");
130
+ nushellLspError = null;
131
+ break;
132
+
133
+ case "dismiss":
134
+ case "dismissed":
135
+ break;
136
+
137
+ default:
138
+ editor.debug(`nushell-lsp: Unknown action: ${data.action_id}`);
139
+ }
140
+ }
141
+ registerHandler("on_nushell_lsp_action_result", on_nushell_lsp_action_result);
142
+ editor.on("action_popup_result", "on_nushell_lsp_action_result");
143
+
144
+ editor.debug("nushell-lsp: Plugin loaded");
@@ -0,0 +1,119 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * OCaml LSP Helper Plugin
6
+ *
7
+ * Server: ocaml-lsp-server (binary: ocamllsp)
8
+ * VS Code: "OCaml Platform" extension
9
+ * Neovim: nvim-lspconfig ocamllsp
10
+ * Install via: opam (OCaml package manager)
11
+ * Note: Requires opam switch with merlin 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
+ opam: "opam install ocaml-lsp-server",
33
+ brew_opam: "brew install opam && opam init && opam install ocaml-lsp-server",
34
+ nix: "nix-env -iA nixpkgs.ocaml-lsp",
35
+ };
36
+
37
+ let ocamlLspError: { serverCommand: string; message: string } | null = null;
38
+
39
+ function on_ocaml_lsp_server_error(data: LspServerErrorData): void {
40
+ if (data.language !== "ocaml") {
41
+ return;
42
+ }
43
+
44
+ editor.debug(`ocaml-lsp: Server error - ${data.error_type}: ${data.message}`);
45
+
46
+ ocamlLspError = {
47
+ serverCommand: data.server_command,
48
+ message: data.message,
49
+ };
50
+
51
+ if (data.error_type === "not_found") {
52
+ editor.setStatus(
53
+ `OCaml LSP server '${data.server_command}' not found. Click status bar for help.`
54
+ );
55
+ } else {
56
+ editor.setStatus(`OCaml LSP error: ${data.message}`);
57
+ }
58
+ }
59
+ registerHandler("on_ocaml_lsp_server_error", on_ocaml_lsp_server_error);
60
+ editor.on("lsp_server_error", "on_ocaml_lsp_server_error");
61
+
62
+ function on_ocaml_lsp_status_clicked(data: LspStatusClickedData): void {
63
+ if (data.language !== "ocaml" || !ocamlLspError) {
64
+ return;
65
+ }
66
+
67
+ editor.debug("ocaml-lsp: Status clicked, showing help popup");
68
+
69
+ editor.showActionPopup({
70
+ id: "ocaml-lsp-help",
71
+ title: "OCaml Language Server Not Found",
72
+ message: `"${ocamlLspError.serverCommand}" provides completion, diagnostics, type info, and refactoring for OCaml. Built on merlin.\n\nRequires opam (OCaml package manager). Install ocaml-lsp-server in your current opam switch.\nVS Code users: Install the "OCaml Platform" extension.\nSee: https://github.com/ocaml/ocaml-lsp`,
73
+ actions: [
74
+ { id: "copy_opam", label: `Copy: ${INSTALL_COMMANDS.opam}` },
75
+ { id: "copy_nix", label: `Copy: ${INSTALL_COMMANDS.nix}` },
76
+ { id: "disable", label: "Disable OCaml LSP" },
77
+ { id: "dismiss", label: "Dismiss (ESC)" },
78
+ ],
79
+ });
80
+ }
81
+ registerHandler("on_ocaml_lsp_status_clicked", on_ocaml_lsp_status_clicked);
82
+ editor.on("lsp_status_clicked", "on_ocaml_lsp_status_clicked");
83
+
84
+ function on_ocaml_lsp_action_result(data: ActionPopupResultData): void {
85
+ if (data.popup_id !== "ocaml-lsp-help") {
86
+ return;
87
+ }
88
+
89
+ editor.debug(`ocaml-lsp: Action selected - ${data.action_id}`);
90
+
91
+ switch (data.action_id) {
92
+ case "copy_opam":
93
+ editor.setClipboard(INSTALL_COMMANDS.opam);
94
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.opam);
95
+ break;
96
+
97
+ case "copy_nix":
98
+ editor.setClipboard(INSTALL_COMMANDS.nix);
99
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.nix);
100
+ break;
101
+
102
+ case "disable":
103
+ editor.disableLspForLanguage("ocaml");
104
+ editor.setStatus("OCaml LSP disabled");
105
+ ocamlLspError = null;
106
+ break;
107
+
108
+ case "dismiss":
109
+ case "dismissed":
110
+ break;
111
+
112
+ default:
113
+ editor.debug(`ocaml-lsp: Unknown action: ${data.action_id}`);
114
+ }
115
+ }
116
+ registerHandler("on_ocaml_lsp_action_result", on_ocaml_lsp_action_result);
117
+ editor.on("action_popup_result", "on_ocaml_lsp_action_result");
118
+
119
+ editor.debug("ocaml-lsp: Plugin loaded");
@@ -0,0 +1,118 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * Perl LSP Helper Plugin
6
+ *
7
+ * Server: PerlNavigator (github.com/bscan/PerlNavigator)
8
+ * VS Code: "Perl Navigator" extension
9
+ * Neovim: nvim-lspconfig perlnavigator
10
+ * Alternative: Perl::LanguageServer (cpan, older)
11
+ * Note: PerlNavigator includes perlcritic and perltidy integration
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
+ npm: "npm install -g perlnavigator-server",
33
+ cpan_alt: "cpanm Perl::LanguageServer",
34
+ };
35
+
36
+ let perlLspError: { serverCommand: string; message: string } | null = null;
37
+
38
+ function on_perl_lsp_server_error(data: LspServerErrorData): void {
39
+ if (data.language !== "perl") {
40
+ return;
41
+ }
42
+
43
+ editor.debug(`perl-lsp: Server error - ${data.error_type}: ${data.message}`);
44
+
45
+ perlLspError = {
46
+ serverCommand: data.server_command,
47
+ message: data.message,
48
+ };
49
+
50
+ if (data.error_type === "not_found") {
51
+ editor.setStatus(
52
+ `Perl LSP server '${data.server_command}' not found. Click status bar for help.`
53
+ );
54
+ } else {
55
+ editor.setStatus(`Perl LSP error: ${data.message}`);
56
+ }
57
+ }
58
+ registerHandler("on_perl_lsp_server_error", on_perl_lsp_server_error);
59
+ editor.on("lsp_server_error", "on_perl_lsp_server_error");
60
+
61
+ function on_perl_lsp_status_clicked(data: LspStatusClickedData): void {
62
+ if (data.language !== "perl" || !perlLspError) {
63
+ return;
64
+ }
65
+
66
+ editor.debug("perl-lsp: Status clicked, showing help popup");
67
+
68
+ editor.showActionPopup({
69
+ id: "perl-lsp-help",
70
+ title: "Perl Language Server Not Found",
71
+ message: `"${perlLspError.serverCommand}" (PerlNavigator) provides completion, diagnostics, navigation, and perlcritic/perltidy integration for Perl.\n\nAlternative: Perl::LanguageServer (older, via CPAN).\nVS Code users: Install the "Perl Navigator" extension.\nSee: https://github.com/bscan/PerlNavigator`,
72
+ actions: [
73
+ { id: "copy_npm", label: `Copy: ${INSTALL_COMMANDS.npm}` },
74
+ { id: "copy_cpan", label: `Copy: ${INSTALL_COMMANDS.cpan_alt}` },
75
+ { id: "disable", label: "Disable Perl LSP" },
76
+ { id: "dismiss", label: "Dismiss (ESC)" },
77
+ ],
78
+ });
79
+ }
80
+ registerHandler("on_perl_lsp_status_clicked", on_perl_lsp_status_clicked);
81
+ editor.on("lsp_status_clicked", "on_perl_lsp_status_clicked");
82
+
83
+ function on_perl_lsp_action_result(data: ActionPopupResultData): void {
84
+ if (data.popup_id !== "perl-lsp-help") {
85
+ return;
86
+ }
87
+
88
+ editor.debug(`perl-lsp: Action selected - ${data.action_id}`);
89
+
90
+ switch (data.action_id) {
91
+ case "copy_npm":
92
+ editor.setClipboard(INSTALL_COMMANDS.npm);
93
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.npm);
94
+ break;
95
+
96
+ case "copy_cpan":
97
+ editor.setClipboard(INSTALL_COMMANDS.cpan_alt);
98
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.cpan_alt);
99
+ break;
100
+
101
+ case "disable":
102
+ editor.disableLspForLanguage("perl");
103
+ editor.setStatus("Perl LSP disabled");
104
+ perlLspError = null;
105
+ break;
106
+
107
+ case "dismiss":
108
+ case "dismissed":
109
+ break;
110
+
111
+ default:
112
+ editor.debug(`perl-lsp: Unknown action: ${data.action_id}`);
113
+ }
114
+ }
115
+ registerHandler("on_perl_lsp_action_result", on_perl_lsp_action_result);
116
+ editor.on("action_popup_result", "on_perl_lsp_action_result");
117
+
118
+ editor.debug("perl-lsp: Plugin loaded");
@@ -0,0 +1,165 @@
1
+ /// <reference path="./lib/fresh.d.ts" />
2
+ const editor = getEditor();
3
+
4
+ /**
5
+ * PHP LSP Helper Plugin
6
+ *
7
+ * Provides user-friendly error handling for PHP LSP server issues.
8
+ * When phpactor fails to start, this plugin shows an actionable
9
+ * popup with installation instructions.
10
+ *
11
+ * Features:
12
+ * - Detects PHP LSP server errors (phpactor)
13
+ * - Shows popup with install commands (composer, brew)
14
+ * - Allows copying install commands to clipboard
15
+ * - Provides option to disable PHP LSP
16
+ *
17
+ * Alternatives:
18
+ * - Intelephense: Feature-rich PHP LSP (https://intelephense.com/) - npm i -g intelephense
19
+ * - PHPStan: Static analysis tool (https://phpstan.org/)
20
+ * - Psalm: PHP static analysis (https://psalm.dev/)
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 PHP LSP server (phpactor)
41
+ // See: https://phpactor.readthedocs.io/en/master/usage/getting-started.html
42
+ const INSTALL_COMMANDS = {
43
+ composer: "composer global require phpactor/phpactor",
44
+ brew: "brew install phpactor",
45
+ };
46
+
47
+ // Alternative LSP server
48
+ const ALT_INSTALL = "npm i -g intelephense";
49
+
50
+ // Track error state for PHP LSP
51
+ let phpLspError: { serverCommand: string; message: string } | null = null;
52
+
53
+ /**
54
+ * Handle LSP server errors for PHP
55
+ */
56
+ function on_php_lsp_server_error(data: LspServerErrorData): void {
57
+ // Only handle PHP language errors
58
+ if (data.language !== "php") {
59
+ return;
60
+ }
61
+
62
+ editor.debug(`php-lsp: Server error - ${data.error_type}: ${data.message}`);
63
+
64
+ // Store error state for later reference
65
+ phpLspError = {
66
+ serverCommand: data.server_command,
67
+ message: data.message,
68
+ };
69
+
70
+ // Show a status message for immediate feedback
71
+ if (data.error_type === "not_found") {
72
+ editor.setStatus(
73
+ `PHP LSP server '${data.server_command}' not found. Click status bar for help.`
74
+ );
75
+ } else {
76
+ editor.setStatus(`PHP LSP error: ${data.message}`);
77
+ }
78
+ }
79
+ registerHandler("on_php_lsp_server_error", on_php_lsp_server_error);
80
+
81
+ // Register hook for LSP server errors
82
+ editor.on("lsp_server_error", "on_php_lsp_server_error");
83
+
84
+ /**
85
+ * Handle status bar click when there's a PHP LSP error
86
+ */
87
+ function on_php_lsp_status_clicked(
88
+ data: LspStatusClickedData
89
+ ): void {
90
+ // Only handle PHP language clicks when there's an error
91
+ if (data.language !== "php" || !phpLspError) {
92
+ return;
93
+ }
94
+
95
+ editor.debug("php-lsp: Status clicked, showing help popup");
96
+
97
+ // Show action popup with install options
98
+ editor.showActionPopup({
99
+ id: "php-lsp-help",
100
+ title: "PHP Language Server Not Found",
101
+ message: `"${phpLspError.serverCommand}" provides code completion, diagnostics, and navigation for PHP files. Requires PHP and Composer. Copy a command below to install it, or visit https://phpactor.readthedocs.io for details. Alternative: Intelephense (https://intelephense.com/) is a popular Node.js-based PHP LSP.`,
102
+ actions: [
103
+ { id: "copy_composer", label: `Copy: ${INSTALL_COMMANDS.composer}` },
104
+ { id: "copy_brew", label: `Copy: ${INSTALL_COMMANDS.brew}` },
105
+ { id: "copy_alt", label: `Alternative: ${ALT_INSTALL}` },
106
+ { id: "disable", label: "Disable PHP LSP" },
107
+ { id: "dismiss", label: "Dismiss (ESC)" },
108
+ ],
109
+ });
110
+ }
111
+ registerHandler("on_php_lsp_status_clicked", on_php_lsp_status_clicked);
112
+
113
+ // Register hook for status bar clicks
114
+ editor.on("lsp_status_clicked", "on_php_lsp_status_clicked");
115
+
116
+ /**
117
+ * Handle action popup results for PHP LSP help
118
+ */
119
+ function on_php_lsp_action_result(
120
+ data: ActionPopupResultData
121
+ ): void {
122
+ // Only handle our popup
123
+ if (data.popup_id !== "php-lsp-help") {
124
+ return;
125
+ }
126
+
127
+ editor.debug(`php-lsp: Action selected - ${data.action_id}`);
128
+
129
+ switch (data.action_id) {
130
+ case "copy_composer":
131
+ editor.setClipboard(INSTALL_COMMANDS.composer);
132
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.composer);
133
+ break;
134
+
135
+ case "copy_brew":
136
+ editor.setClipboard(INSTALL_COMMANDS.brew);
137
+ editor.setStatus("Copied: " + INSTALL_COMMANDS.brew);
138
+ break;
139
+
140
+ case "copy_alt":
141
+ editor.setClipboard(ALT_INSTALL);
142
+ editor.setStatus("Copied: " + ALT_INSTALL);
143
+ break;
144
+
145
+ case "disable":
146
+ editor.disableLspForLanguage("php");
147
+ editor.setStatus("PHP LSP disabled");
148
+ phpLspError = null;
149
+ break;
150
+
151
+ case "dismiss":
152
+ case "dismissed":
153
+ // Just close the popup without action
154
+ break;
155
+
156
+ default:
157
+ editor.debug(`php-lsp: Unknown action: ${data.action_id}`);
158
+ }
159
+ }
160
+ registerHandler("on_php_lsp_action_result", on_php_lsp_action_result);
161
+
162
+ // Register hook for action popup results
163
+ editor.on("action_popup_result", "on_php_lsp_action_result");
164
+
165
+ editor.debug("php-lsp: Plugin loaded");