@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.
- package/CHANGELOG.md +144 -0
- package/package.json +1 -1
- package/plugins/astro-lsp.ts +118 -0
- package/plugins/bash-lsp.ts +161 -0
- package/plugins/clojure-lsp.ts +125 -0
- package/plugins/cmake-lsp.ts +138 -0
- package/plugins/config-schema.json +275 -29
- package/plugins/dart-lsp.ts +144 -0
- package/plugins/diagnostics_panel.ts +4 -12
- package/plugins/diff_nav.i18n.json +128 -0
- package/plugins/diff_nav.ts +196 -0
- package/plugins/elixir-lsp.ts +120 -0
- package/plugins/erlang-lsp.ts +121 -0
- package/plugins/fsharp-lsp.ts +125 -0
- package/plugins/git_gutter.ts +5 -0
- package/plugins/gleam-lsp.ts +124 -0
- package/plugins/graphql-lsp.ts +139 -0
- package/plugins/haskell-lsp.ts +125 -0
- package/plugins/julia-lsp.ts +111 -0
- package/plugins/kotlin-lsp.ts +162 -0
- package/plugins/lib/finder.ts +19 -12
- package/plugins/lib/fresh.d.ts +30 -1
- package/plugins/lua-lsp.ts +161 -0
- package/plugins/nim-lsp.ts +118 -0
- package/plugins/nix-lsp.ts +125 -0
- package/plugins/nushell-lsp.ts +144 -0
- package/plugins/ocaml-lsp.ts +119 -0
- package/plugins/perl-lsp.ts +118 -0
- package/plugins/php-lsp.ts +165 -0
- package/plugins/pkg.ts +37 -76
- package/plugins/protobuf-lsp.ts +144 -0
- package/plugins/r-lsp.ts +118 -0
- package/plugins/ruby-lsp.ts +165 -0
- package/plugins/scala-lsp.ts +119 -0
- package/plugins/schemas/package.schema.json +437 -272
- package/plugins/schemas/theme.schema.json +18 -0
- package/plugins/solidity-lsp.ts +130 -0
- package/plugins/sql-lsp.ts +129 -0
- package/plugins/svelte-lsp.ts +119 -0
- package/plugins/swift-lsp.ts +120 -0
- package/plugins/tailwindcss-lsp.ts +119 -0
- package/plugins/terraform-lsp.ts +144 -0
- package/plugins/theme_editor.i18n.json +70 -14
- package/plugins/theme_editor.ts +71 -39
- package/plugins/toml-lsp.ts +162 -0
- package/plugins/typst-lsp.ts +165 -0
- package/plugins/vue-lsp.ts +118 -0
- 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");
|