@fresh-editor/fresh-editor 0.1.65 → 0.1.69
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 +106 -0
- package/README.md +4 -2
- package/package.json +1 -1
- package/plugins/audit_mode.i18n.json +380 -0
- package/plugins/audit_mode.ts +1813 -0
- package/plugins/buffer_modified.i18n.json +32 -0
- package/plugins/buffer_modified.ts +5 -3
- package/plugins/calculator.i18n.json +44 -0
- package/plugins/calculator.ts +6 -4
- package/plugins/clangd-lsp.ts +168 -0
- package/plugins/clangd_support.i18n.json +104 -0
- package/plugins/clangd_support.ts +18 -16
- package/plugins/color_highlighter.i18n.json +68 -0
- package/plugins/color_highlighter.ts +12 -10
- package/plugins/config-schema.json +79 -141
- package/plugins/csharp-lsp.ts +147 -0
- package/plugins/csharp_support.i18n.json +38 -0
- package/plugins/csharp_support.ts +6 -4
- package/plugins/css-lsp.ts +143 -0
- package/plugins/diagnostics_panel.i18n.json +110 -0
- package/plugins/diagnostics_panel.ts +19 -17
- package/plugins/find_references.i18n.json +128 -0
- package/plugins/find_references.ts +22 -20
- package/plugins/git_blame.i18n.json +230 -0
- package/plugins/git_blame.ts +39 -37
- package/plugins/git_find_file.i18n.json +146 -0
- package/plugins/git_find_file.ts +24 -22
- package/plugins/git_grep.i18n.json +80 -0
- package/plugins/git_grep.ts +15 -13
- package/plugins/git_gutter.i18n.json +44 -0
- package/plugins/git_gutter.ts +7 -5
- package/plugins/git_log.i18n.json +224 -0
- package/plugins/git_log.ts +41 -39
- package/plugins/go-lsp.ts +143 -0
- package/plugins/html-lsp.ts +145 -0
- package/plugins/json-lsp.ts +145 -0
- package/plugins/lib/fresh.d.ts +150 -14
- package/plugins/lib/index.ts +1 -1
- package/plugins/lib/navigation-controller.ts +3 -3
- package/plugins/lib/panel-manager.ts +15 -13
- package/plugins/lib/virtual-buffer-factory.ts +84 -112
- package/plugins/live_grep.i18n.json +80 -0
- package/plugins/live_grep.ts +15 -13
- package/plugins/markdown_compose.i18n.json +104 -0
- package/plugins/markdown_compose.ts +17 -15
- package/plugins/merge_conflict.i18n.json +380 -0
- package/plugins/merge_conflict.ts +72 -73
- package/plugins/path_complete.i18n.json +38 -0
- package/plugins/path_complete.ts +6 -4
- package/plugins/python-lsp.ts +162 -0
- package/plugins/rust-lsp.ts +166 -0
- package/plugins/search_replace.i18n.json +188 -0
- package/plugins/search_replace.ts +31 -29
- package/plugins/test_i18n.i18n.json +12 -0
- package/plugins/test_i18n.ts +18 -0
- package/plugins/theme_editor.i18n.json +1417 -0
- package/plugins/theme_editor.ts +73 -69
- package/plugins/todo_highlighter.i18n.json +86 -0
- package/plugins/todo_highlighter.ts +15 -13
- package/plugins/typescript-lsp.ts +167 -0
- package/plugins/vi_mode.i18n.json +716 -0
- package/plugins/vi_mode.ts +2747 -0
- package/plugins/welcome.i18n.json +110 -0
- package/plugins/welcome.ts +18 -16
package/plugins/git_log.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference path="../types/fresh.d.ts" />
|
|
2
|
+
const editor = getEditor();
|
|
3
|
+
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Git Log Plugin - Magit-style Git Log Interface
|
|
@@ -185,7 +187,7 @@ async function fetchGitLog(): Promise<GitCommit[]> {
|
|
|
185
187
|
const result = await editor.spawnProcess("git", args, cwd);
|
|
186
188
|
|
|
187
189
|
if (result.exit_code !== 0) {
|
|
188
|
-
editor.setStatus(
|
|
190
|
+
editor.setStatus(editor.t("status.git_error", { error: result.stderr }));
|
|
189
191
|
return [];
|
|
190
192
|
}
|
|
191
193
|
|
|
@@ -226,7 +228,7 @@ async function fetchCommitDiff(hash: string): Promise<string> {
|
|
|
226
228
|
], cwd);
|
|
227
229
|
|
|
228
230
|
if (result.exit_code !== 0) {
|
|
229
|
-
return
|
|
231
|
+
return editor.t("status.error_fetching_diff", { error: result.stderr });
|
|
230
232
|
}
|
|
231
233
|
|
|
232
234
|
return result.stdout;
|
|
@@ -265,13 +267,13 @@ function buildGitLogEntries(): TextPropertyEntry[] {
|
|
|
265
267
|
|
|
266
268
|
// Magit-style header
|
|
267
269
|
entries.push({
|
|
268
|
-
text: "
|
|
270
|
+
text: editor.t("panel.commits_header") + "\n",
|
|
269
271
|
properties: { type: "section-header" },
|
|
270
272
|
});
|
|
271
273
|
|
|
272
274
|
if (gitLogState.commits.length === 0) {
|
|
273
275
|
entries.push({
|
|
274
|
-
text: "
|
|
276
|
+
text: editor.t("panel.no_commits") + "\n",
|
|
275
277
|
properties: { type: "empty" },
|
|
276
278
|
});
|
|
277
279
|
} else {
|
|
@@ -301,7 +303,7 @@ function buildGitLogEntries(): TextPropertyEntry[] {
|
|
|
301
303
|
properties: { type: "blank" },
|
|
302
304
|
});
|
|
303
305
|
entries.push({
|
|
304
|
-
text:
|
|
306
|
+
text: editor.t("panel.log_footer", { count: String(gitLogState.commits.length) }) + "\n",
|
|
305
307
|
properties: { type: "footer" },
|
|
306
308
|
});
|
|
307
309
|
|
|
@@ -333,7 +335,7 @@ function applyGitLogHighlighting(): void {
|
|
|
333
335
|
const lineEnd = byteOffset + line.length;
|
|
334
336
|
|
|
335
337
|
// Highlight section header
|
|
336
|
-
if (line === "
|
|
338
|
+
if (line === editor.t("panel.commits_header")) {
|
|
337
339
|
editor.addOverlay(
|
|
338
340
|
bufferId,
|
|
339
341
|
"gitlog",
|
|
@@ -590,7 +592,7 @@ function buildCommitDetailEntries(commit: GitCommit, showOutput: string): TextPr
|
|
|
590
592
|
properties: { type: "blank" },
|
|
591
593
|
});
|
|
592
594
|
entries.push({
|
|
593
|
-
text:
|
|
595
|
+
text: editor.t("panel.detail_footer") + "\n",
|
|
594
596
|
properties: { type: "footer" },
|
|
595
597
|
});
|
|
596
598
|
|
|
@@ -737,11 +739,11 @@ function applyCommitDetailHighlighting(): void {
|
|
|
737
739
|
|
|
738
740
|
globalThis.show_git_log = async function(): Promise<void> {
|
|
739
741
|
if (gitLogState.isOpen) {
|
|
740
|
-
editor.setStatus("
|
|
742
|
+
editor.setStatus(editor.t("status.already_open"));
|
|
741
743
|
return;
|
|
742
744
|
}
|
|
743
745
|
|
|
744
|
-
editor.setStatus("
|
|
746
|
+
editor.setStatus(editor.t("status.loading"));
|
|
745
747
|
|
|
746
748
|
// Store the current split ID and buffer ID before opening git log
|
|
747
749
|
gitLogState.splitId = editor.getActiveSplitId();
|
|
@@ -751,7 +753,7 @@ globalThis.show_git_log = async function(): Promise<void> {
|
|
|
751
753
|
gitLogState.commits = await fetchGitLog();
|
|
752
754
|
|
|
753
755
|
if (gitLogState.commits.length === 0) {
|
|
754
|
-
editor.setStatus("
|
|
756
|
+
editor.setStatus(editor.t("status.no_commits"));
|
|
755
757
|
gitLogState.splitId = null;
|
|
756
758
|
return;
|
|
757
759
|
}
|
|
@@ -779,11 +781,11 @@ globalThis.show_git_log = async function(): Promise<void> {
|
|
|
779
781
|
// Apply syntax highlighting
|
|
780
782
|
applyGitLogHighlighting();
|
|
781
783
|
|
|
782
|
-
editor.setStatus(
|
|
784
|
+
editor.setStatus(editor.t("status.log_ready", { count: String(gitLogState.commits.length) }));
|
|
783
785
|
editor.debug("Git log panel opened");
|
|
784
786
|
} else {
|
|
785
787
|
gitLogState.splitId = null;
|
|
786
|
-
editor.setStatus("
|
|
788
|
+
editor.setStatus(editor.t("status.failed_open"));
|
|
787
789
|
}
|
|
788
790
|
};
|
|
789
791
|
|
|
@@ -807,7 +809,7 @@ globalThis.git_log_close = function(): void {
|
|
|
807
809
|
gitLogState.splitId = null;
|
|
808
810
|
gitLogState.sourceBufferId = null;
|
|
809
811
|
gitLogState.commits = [];
|
|
810
|
-
editor.setStatus("
|
|
812
|
+
editor.setStatus(editor.t("status.closed"));
|
|
811
813
|
};
|
|
812
814
|
|
|
813
815
|
// Cursor moved handler for git log - update highlighting and status
|
|
@@ -831,7 +833,7 @@ globalThis.on_git_log_cursor_moved = function(data: {
|
|
|
831
833
|
const commitIndex = cursorLine - headerLines;
|
|
832
834
|
|
|
833
835
|
if (commitIndex >= 0 && commitIndex < gitLogState.commits.length) {
|
|
834
|
-
editor.setStatus(
|
|
836
|
+
editor.setStatus(editor.t("status.commit_position", { current: String(commitIndex + 1), total: String(gitLogState.commits.length) }));
|
|
835
837
|
}
|
|
836
838
|
};
|
|
837
839
|
|
|
@@ -841,10 +843,10 @@ editor.on("cursor_moved", "on_git_log_cursor_moved");
|
|
|
841
843
|
globalThis.git_log_refresh = async function(): Promise<void> {
|
|
842
844
|
if (!gitLogState.isOpen) return;
|
|
843
845
|
|
|
844
|
-
editor.setStatus("
|
|
846
|
+
editor.setStatus(editor.t("status.refreshing"));
|
|
845
847
|
gitLogState.commits = await fetchGitLog();
|
|
846
848
|
updateGitLogView();
|
|
847
|
-
editor.setStatus(
|
|
849
|
+
editor.setStatus(editor.t("status.refreshed", { count: String(gitLogState.commits.length) }));
|
|
848
850
|
};
|
|
849
851
|
|
|
850
852
|
// Helper function to get commit at current cursor position
|
|
@@ -879,11 +881,11 @@ globalThis.git_log_show_commit = async function(): Promise<void> {
|
|
|
879
881
|
|
|
880
882
|
const commit = getCommitAtCursor();
|
|
881
883
|
if (!commit) {
|
|
882
|
-
editor.setStatus("
|
|
884
|
+
editor.setStatus(editor.t("status.move_to_commit"));
|
|
883
885
|
return;
|
|
884
886
|
}
|
|
885
887
|
|
|
886
|
-
editor.setStatus(
|
|
888
|
+
editor.setStatus(editor.t("status.loading_commit", { hash: commit.shortHash }));
|
|
887
889
|
|
|
888
890
|
// Fetch full commit info using git show (includes header and diff)
|
|
889
891
|
const showOutput = await fetchCommitDiff(commit.hash);
|
|
@@ -915,9 +917,9 @@ globalThis.git_log_show_commit = async function(): Promise<void> {
|
|
|
915
917
|
// Apply syntax highlighting
|
|
916
918
|
applyCommitDetailHighlighting();
|
|
917
919
|
|
|
918
|
-
editor.setStatus(
|
|
920
|
+
editor.setStatus(editor.t("status.commit_ready", { hash: commit.shortHash }));
|
|
919
921
|
} else {
|
|
920
|
-
editor.setStatus("
|
|
922
|
+
editor.setStatus(editor.t("status.failed_open_details"));
|
|
921
923
|
}
|
|
922
924
|
};
|
|
923
925
|
|
|
@@ -926,7 +928,7 @@ globalThis.git_log_copy_hash = function(): void {
|
|
|
926
928
|
|
|
927
929
|
const commit = getCommitAtCursor();
|
|
928
930
|
if (!commit) {
|
|
929
|
-
editor.setStatus("
|
|
931
|
+
editor.setStatus(editor.t("status.move_to_commit"));
|
|
930
932
|
return;
|
|
931
933
|
}
|
|
932
934
|
|
|
@@ -934,11 +936,11 @@ globalThis.git_log_copy_hash = function(): void {
|
|
|
934
936
|
// Try xclip first (Linux), then pbcopy (macOS), then xsel
|
|
935
937
|
editor.spawnProcess("sh", ["-c", `echo -n "${commit.hash}" | xclip -selection clipboard 2>/dev/null || echo -n "${commit.hash}" | pbcopy 2>/dev/null || echo -n "${commit.hash}" | xsel --clipboard 2>/dev/null`])
|
|
936
938
|
.then(() => {
|
|
937
|
-
editor.setStatus(
|
|
939
|
+
editor.setStatus(editor.t("status.hash_copied", { short: commit.shortHash, full: commit.hash }));
|
|
938
940
|
})
|
|
939
941
|
.catch(() => {
|
|
940
942
|
// If all clipboard commands fail, just show the hash
|
|
941
|
-
editor.setStatus(
|
|
943
|
+
editor.setStatus(editor.t("status.hash_display", { hash: commit.hash }));
|
|
942
944
|
});
|
|
943
945
|
};
|
|
944
946
|
|
|
@@ -968,7 +970,7 @@ globalThis.git_commit_detail_close = function(): void {
|
|
|
968
970
|
commitDetailState.splitId = null;
|
|
969
971
|
commitDetailState.commit = null;
|
|
970
972
|
|
|
971
|
-
editor.setStatus(
|
|
973
|
+
editor.setStatus(editor.t("status.log_ready", { count: String(gitLogState.commits.length) }));
|
|
972
974
|
};
|
|
973
975
|
|
|
974
976
|
// Close file view and go back to commit detail
|
|
@@ -996,7 +998,7 @@ globalThis.git_file_view_close = function(): void {
|
|
|
996
998
|
fileViewState.commitHash = null;
|
|
997
999
|
|
|
998
1000
|
if (commitDetailState.commit) {
|
|
999
|
-
editor.setStatus(
|
|
1001
|
+
editor.setStatus(editor.t("status.commit_ready", { hash: commitDetailState.commit.shortHash }));
|
|
1000
1002
|
}
|
|
1001
1003
|
};
|
|
1002
1004
|
|
|
@@ -1181,7 +1183,7 @@ globalThis.git_commit_detail_open_file = async function(): Promise<void> {
|
|
|
1181
1183
|
|
|
1182
1184
|
const commit = commitDetailState.commit;
|
|
1183
1185
|
if (!commit) {
|
|
1184
|
-
editor.setStatus("
|
|
1186
|
+
editor.setStatus(editor.t("status.move_to_commit"));
|
|
1185
1187
|
return;
|
|
1186
1188
|
}
|
|
1187
1189
|
|
|
@@ -1193,13 +1195,13 @@ globalThis.git_commit_detail_open_file = async function(): Promise<void> {
|
|
|
1193
1195
|
const line = props[0].line as number | undefined;
|
|
1194
1196
|
|
|
1195
1197
|
if (file) {
|
|
1196
|
-
editor.setStatus(
|
|
1198
|
+
editor.setStatus(editor.t("status.file_loading", { file, hash: commit.shortHash }));
|
|
1197
1199
|
|
|
1198
1200
|
// Fetch file content at this commit
|
|
1199
1201
|
const content = await fetchFileAtCommit(commit.hash, file);
|
|
1200
1202
|
|
|
1201
1203
|
if (content === null) {
|
|
1202
|
-
editor.setStatus(
|
|
1204
|
+
editor.setStatus(editor.t("status.file_not_found", { file, hash: commit.shortHash }));
|
|
1203
1205
|
return;
|
|
1204
1206
|
}
|
|
1205
1207
|
|
|
@@ -1238,15 +1240,15 @@ globalThis.git_commit_detail_open_file = async function(): Promise<void> {
|
|
|
1238
1240
|
applyFileViewHighlighting(bufferId, content, file);
|
|
1239
1241
|
|
|
1240
1242
|
const targetLine = line || 1;
|
|
1241
|
-
editor.setStatus(
|
|
1243
|
+
editor.setStatus(editor.t("status.file_view_ready", { file, hash: commit.shortHash, line: String(targetLine) }));
|
|
1242
1244
|
} else {
|
|
1243
|
-
editor.setStatus(
|
|
1245
|
+
editor.setStatus(editor.t("status.failed_open_file", { file }));
|
|
1244
1246
|
}
|
|
1245
1247
|
} else {
|
|
1246
|
-
editor.setStatus("
|
|
1248
|
+
editor.setStatus(editor.t("status.move_to_diff_with_context"));
|
|
1247
1249
|
}
|
|
1248
1250
|
} else {
|
|
1249
|
-
editor.setStatus("
|
|
1251
|
+
editor.setStatus(editor.t("status.move_to_diff"));
|
|
1250
1252
|
}
|
|
1251
1253
|
};
|
|
1252
1254
|
|
|
@@ -1255,22 +1257,22 @@ globalThis.git_commit_detail_open_file = async function(): Promise<void> {
|
|
|
1255
1257
|
// =============================================================================
|
|
1256
1258
|
|
|
1257
1259
|
editor.registerCommand(
|
|
1258
|
-
"
|
|
1259
|
-
"
|
|
1260
|
+
"%cmd.git_log",
|
|
1261
|
+
"%cmd.git_log_desc",
|
|
1260
1262
|
"show_git_log",
|
|
1261
1263
|
"normal"
|
|
1262
1264
|
);
|
|
1263
1265
|
|
|
1264
1266
|
editor.registerCommand(
|
|
1265
|
-
"
|
|
1266
|
-
"
|
|
1267
|
+
"%cmd.git_log_close",
|
|
1268
|
+
"%cmd.git_log_close_desc",
|
|
1267
1269
|
"git_log_close",
|
|
1268
1270
|
"normal"
|
|
1269
1271
|
);
|
|
1270
1272
|
|
|
1271
1273
|
editor.registerCommand(
|
|
1272
|
-
"
|
|
1273
|
-
"
|
|
1274
|
+
"%cmd.git_log_refresh",
|
|
1275
|
+
"%cmd.git_log_refresh_desc",
|
|
1274
1276
|
"git_log_refresh",
|
|
1275
1277
|
"normal"
|
|
1276
1278
|
);
|
|
@@ -1279,5 +1281,5 @@ editor.registerCommand(
|
|
|
1279
1281
|
// Plugin Initialization
|
|
1280
1282
|
// =============================================================================
|
|
1281
1283
|
|
|
1282
|
-
editor.setStatus("
|
|
1284
|
+
editor.setStatus(editor.t("status.ready", { count: "0" }));
|
|
1283
1285
|
editor.debug("Git Log plugin initialized - Use 'Git Log' command to open");
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/// <reference path="./lib/fresh.d.ts" />
|
|
2
|
+
const editor = getEditor();
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Go LSP Helper Plugin
|
|
7
|
+
*
|
|
8
|
+
* Provides user-friendly error handling for Go LSP server issues.
|
|
9
|
+
* When gopls fails to start, this plugin shows an actionable
|
|
10
|
+
* popup with installation instructions.
|
|
11
|
+
*
|
|
12
|
+
* Features:
|
|
13
|
+
* - Detects Go LSP server errors (gopls)
|
|
14
|
+
* - Shows popup with install commands
|
|
15
|
+
* - Allows copying install commands to clipboard
|
|
16
|
+
* - Provides option to disable Go LSP
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
interface LspServerErrorData {
|
|
20
|
+
language: string;
|
|
21
|
+
server_command: string;
|
|
22
|
+
error_type: string;
|
|
23
|
+
message: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface LspStatusClickedData {
|
|
27
|
+
language: string;
|
|
28
|
+
has_error: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface ActionPopupResultData {
|
|
32
|
+
popup_id: string;
|
|
33
|
+
action_id: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Install commands for Go LSP server (gopls)
|
|
37
|
+
// go install is the official recommended method
|
|
38
|
+
// See: https://pkg.go.dev/golang.org/x/tools/gopls
|
|
39
|
+
const INSTALL_COMMANDS = {
|
|
40
|
+
go: "go install golang.org/x/tools/gopls@latest",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Track error state for Go LSP
|
|
44
|
+
let goLspError: { serverCommand: string; message: string } | null = null;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Handle LSP server errors for Go
|
|
48
|
+
*/
|
|
49
|
+
globalThis.on_go_lsp_server_error = function (data: LspServerErrorData): void {
|
|
50
|
+
// Only handle Go language errors
|
|
51
|
+
if (data.language !== "go") {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
editor.debug(`go-lsp: Server error - ${data.error_type}: ${data.message}`);
|
|
56
|
+
|
|
57
|
+
// Store error state for later reference
|
|
58
|
+
goLspError = {
|
|
59
|
+
serverCommand: data.server_command,
|
|
60
|
+
message: data.message,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Show a status message for immediate feedback
|
|
64
|
+
if (data.error_type === "not_found") {
|
|
65
|
+
editor.setStatus(
|
|
66
|
+
`Go LSP server '${data.server_command}' not found. Click status bar for help.`
|
|
67
|
+
);
|
|
68
|
+
} else {
|
|
69
|
+
editor.setStatus(`Go LSP error: ${data.message}`);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Register hook for LSP server errors
|
|
74
|
+
editor.on("lsp_server_error", "on_go_lsp_server_error");
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Handle status bar click when there's a Go LSP error
|
|
78
|
+
*/
|
|
79
|
+
globalThis.on_go_lsp_status_clicked = function (
|
|
80
|
+
data: LspStatusClickedData
|
|
81
|
+
): void {
|
|
82
|
+
// Only handle Go language clicks when there's an error
|
|
83
|
+
if (data.language !== "go" || !goLspError) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
editor.debug("go-lsp: Status clicked, showing help popup");
|
|
88
|
+
|
|
89
|
+
// Show action popup with install options
|
|
90
|
+
editor.showActionPopup({
|
|
91
|
+
id: "go-lsp-help",
|
|
92
|
+
title: "Go Language Server Not Found",
|
|
93
|
+
message: `"${goLspError.serverCommand}" provides code completion, diagnostics, and navigation for Go files. Copy the command below to install it.`,
|
|
94
|
+
actions: [
|
|
95
|
+
{ id: "copy_go", label: `Copy: ${INSTALL_COMMANDS.go}` },
|
|
96
|
+
{ id: "disable", label: "Disable Go LSP" },
|
|
97
|
+
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
98
|
+
],
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// Register hook for status bar clicks
|
|
103
|
+
editor.on("lsp_status_clicked", "on_go_lsp_status_clicked");
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Handle action popup results for Go LSP help
|
|
107
|
+
*/
|
|
108
|
+
globalThis.on_go_lsp_action_result = function (
|
|
109
|
+
data: ActionPopupResultData
|
|
110
|
+
): void {
|
|
111
|
+
// Only handle our popup
|
|
112
|
+
if (data.popup_id !== "go-lsp-help") {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
editor.debug(`go-lsp: Action selected - ${data.action_id}`);
|
|
117
|
+
|
|
118
|
+
switch (data.action_id) {
|
|
119
|
+
case "copy_go":
|
|
120
|
+
editor.setClipboard(INSTALL_COMMANDS.go);
|
|
121
|
+
editor.setStatus("Copied: " + INSTALL_COMMANDS.go);
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
case "disable":
|
|
125
|
+
editor.disableLspForLanguage("go");
|
|
126
|
+
editor.setStatus("Go LSP disabled");
|
|
127
|
+
goLspError = null;
|
|
128
|
+
break;
|
|
129
|
+
|
|
130
|
+
case "dismiss":
|
|
131
|
+
case "dismissed":
|
|
132
|
+
// Just close the popup without action
|
|
133
|
+
break;
|
|
134
|
+
|
|
135
|
+
default:
|
|
136
|
+
editor.debug(`go-lsp: Unknown action: ${data.action_id}`);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Register hook for action popup results
|
|
141
|
+
editor.on("action_popup_result", "on_go_lsp_action_result");
|
|
142
|
+
|
|
143
|
+
editor.debug("go-lsp: Plugin loaded");
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/// <reference path="./lib/fresh.d.ts" />
|
|
2
|
+
const editor = getEditor();
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* HTML LSP Helper Plugin
|
|
7
|
+
*
|
|
8
|
+
* Provides user-friendly error handling for HTML LSP server issues.
|
|
9
|
+
* When the HTML language server fails to start, this plugin shows an
|
|
10
|
+
* actionable popup with installation instructions.
|
|
11
|
+
*
|
|
12
|
+
* Features:
|
|
13
|
+
* - Detects HTML LSP server errors
|
|
14
|
+
* - Shows popup with install commands (npm)
|
|
15
|
+
* - Allows copying install commands to clipboard
|
|
16
|
+
* - Provides option to disable HTML LSP
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
interface LspServerErrorData {
|
|
20
|
+
language: string;
|
|
21
|
+
server_command: string;
|
|
22
|
+
error_type: string;
|
|
23
|
+
message: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface LspStatusClickedData {
|
|
27
|
+
language: string;
|
|
28
|
+
has_error: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface ActionPopupResultData {
|
|
32
|
+
popup_id: string;
|
|
33
|
+
action_id: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Install commands for HTML LSP server
|
|
37
|
+
// vscode-langservers-extracted provides HTML, CSS, and JSON language servers
|
|
38
|
+
// See: https://www.npmjs.com/package/vscode-langservers-extracted
|
|
39
|
+
const INSTALL_COMMANDS = {
|
|
40
|
+
npm: "npm install -g vscode-langservers-extracted",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Track error state for HTML LSP
|
|
44
|
+
let htmlLspError: { serverCommand: string; message: string } | null = null;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Handle LSP server errors for HTML
|
|
48
|
+
*/
|
|
49
|
+
globalThis.on_html_lsp_server_error = function (
|
|
50
|
+
data: LspServerErrorData
|
|
51
|
+
): void {
|
|
52
|
+
// Only handle HTML language errors
|
|
53
|
+
if (data.language !== "html") {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
editor.debug(`html-lsp: Server error - ${data.error_type}: ${data.message}`);
|
|
58
|
+
|
|
59
|
+
// Store error state for later reference
|
|
60
|
+
htmlLspError = {
|
|
61
|
+
serverCommand: data.server_command,
|
|
62
|
+
message: data.message,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Show a status message for immediate feedback
|
|
66
|
+
if (data.error_type === "not_found") {
|
|
67
|
+
editor.setStatus(
|
|
68
|
+
`HTML LSP server '${data.server_command}' not found. Click status bar for help.`
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
editor.setStatus(`HTML LSP error: ${data.message}`);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Register hook for LSP server errors
|
|
76
|
+
editor.on("lsp_server_error", "on_html_lsp_server_error");
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Handle status bar click when there's an HTML LSP error
|
|
80
|
+
*/
|
|
81
|
+
globalThis.on_html_lsp_status_clicked = function (
|
|
82
|
+
data: LspStatusClickedData
|
|
83
|
+
): void {
|
|
84
|
+
// Only handle HTML language clicks when there's an error
|
|
85
|
+
if (data.language !== "html" || !htmlLspError) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
editor.debug("html-lsp: Status clicked, showing help popup");
|
|
90
|
+
|
|
91
|
+
// Show action popup with install options
|
|
92
|
+
editor.showActionPopup({
|
|
93
|
+
id: "html-lsp-help",
|
|
94
|
+
title: "HTML Language Server Not Found",
|
|
95
|
+
message: `"${htmlLspError.serverCommand}" provides code completion, diagnostics, and formatting for HTML files. Copy the command below to install it.`,
|
|
96
|
+
actions: [
|
|
97
|
+
{ id: "copy_npm", label: `Copy: ${INSTALL_COMMANDS.npm}` },
|
|
98
|
+
{ id: "disable", label: "Disable HTML LSP" },
|
|
99
|
+
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Register hook for status bar clicks
|
|
105
|
+
editor.on("lsp_status_clicked", "on_html_lsp_status_clicked");
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Handle action popup results for HTML LSP help
|
|
109
|
+
*/
|
|
110
|
+
globalThis.on_html_lsp_action_result = function (
|
|
111
|
+
data: ActionPopupResultData
|
|
112
|
+
): void {
|
|
113
|
+
// Only handle our popup
|
|
114
|
+
if (data.popup_id !== "html-lsp-help") {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
editor.debug(`html-lsp: Action selected - ${data.action_id}`);
|
|
119
|
+
|
|
120
|
+
switch (data.action_id) {
|
|
121
|
+
case "copy_npm":
|
|
122
|
+
editor.setClipboard(INSTALL_COMMANDS.npm);
|
|
123
|
+
editor.setStatus("Copied: " + INSTALL_COMMANDS.npm);
|
|
124
|
+
break;
|
|
125
|
+
|
|
126
|
+
case "disable":
|
|
127
|
+
editor.disableLspForLanguage("html");
|
|
128
|
+
editor.setStatus("HTML LSP disabled");
|
|
129
|
+
htmlLspError = null;
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case "dismiss":
|
|
133
|
+
case "dismissed":
|
|
134
|
+
// Just close the popup without action
|
|
135
|
+
break;
|
|
136
|
+
|
|
137
|
+
default:
|
|
138
|
+
editor.debug(`html-lsp: Unknown action: ${data.action_id}`);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// Register hook for action popup results
|
|
143
|
+
editor.on("action_popup_result", "on_html_lsp_action_result");
|
|
144
|
+
|
|
145
|
+
editor.debug("html-lsp: Plugin loaded");
|