@fresh-editor/fresh-editor 0.3.0 → 0.3.1
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 +66 -2
- package/package.json +1 -1
- package/plugins/astro-lsp.ts +6 -12
- package/plugins/audit_mode.ts +106 -113
- package/plugins/bash-lsp.ts +15 -22
- package/plugins/clangd-lsp.ts +15 -24
- package/plugins/clojure-lsp.ts +9 -12
- package/plugins/cmake-lsp.ts +9 -12
- package/plugins/code-tour.ts +15 -16
- package/plugins/config-schema.json +10 -0
- package/plugins/csharp_support.ts +25 -30
- package/plugins/css-lsp.ts +15 -22
- package/plugins/dart-lsp.ts +9 -12
- package/plugins/dashboard.ts +118 -0
- package/plugins/devcontainer.i18n.json +84 -28
- package/plugins/devcontainer.ts +897 -170
- package/plugins/diagnostics_panel.ts +10 -17
- package/plugins/elixir-lsp.ts +9 -12
- package/plugins/erlang-lsp.ts +9 -12
- package/plugins/examples/bookmarks.ts +10 -16
- package/plugins/find_references.ts +5 -9
- package/plugins/flash.ts +577 -0
- package/plugins/fsharp-lsp.ts +9 -12
- package/plugins/git_explorer.ts +16 -20
- package/plugins/git_gutter.ts +65 -79
- package/plugins/git_log.ts +8 -8
- package/plugins/gleam-lsp.ts +9 -12
- package/plugins/go-lsp.ts +15 -22
- package/plugins/graphql-lsp.ts +9 -12
- package/plugins/haskell-lsp.ts +9 -12
- package/plugins/html-lsp.ts +15 -24
- package/plugins/java-lsp.ts +9 -12
- package/plugins/json-lsp.ts +15 -24
- package/plugins/julia-lsp.ts +9 -12
- package/plugins/kotlin-lsp.ts +15 -22
- package/plugins/latex-lsp.ts +9 -12
- package/plugins/lib/fresh.d.ts +378 -0
- package/plugins/lua-lsp.ts +15 -22
- package/plugins/markdown_compose.ts +78 -122
- package/plugins/markdown_source.ts +8 -10
- package/plugins/marksman-lsp.ts +9 -12
- package/plugins/merge_conflict.ts +15 -17
- package/plugins/nim-lsp.ts +9 -12
- package/plugins/nix-lsp.ts +9 -12
- package/plugins/nushell-lsp.ts +9 -12
- package/plugins/ocaml-lsp.ts +9 -12
- package/plugins/odin-lsp.ts +15 -22
- package/plugins/path_complete.ts +5 -6
- package/plugins/perl-lsp.ts +9 -12
- package/plugins/php-lsp.ts +15 -22
- package/plugins/pkg.ts +10 -21
- package/plugins/protobuf-lsp.ts +9 -12
- package/plugins/python-lsp.ts +15 -24
- package/plugins/r-lsp.ts +9 -12
- package/plugins/ruby-lsp.ts +15 -22
- package/plugins/rust-lsp.ts +18 -28
- package/plugins/scala-lsp.ts +9 -12
- package/plugins/schemas/theme.schema.json +18 -0
- package/plugins/search_replace.ts +10 -13
- package/plugins/solidity-lsp.ts +9 -12
- package/plugins/sql-lsp.ts +9 -12
- package/plugins/svelte-lsp.ts +9 -12
- package/plugins/swift-lsp.ts +9 -12
- package/plugins/tailwindcss-lsp.ts +9 -12
- package/plugins/templ-lsp.ts +9 -12
- package/plugins/terraform-lsp.ts +9 -12
- package/plugins/theme_editor.i18n.json +70 -14
- package/plugins/theme_editor.ts +152 -208
- package/plugins/toml-lsp.ts +15 -22
- package/plugins/tsconfig.json +100 -0
- package/plugins/typescript-lsp.ts +15 -24
- package/plugins/typst-lsp.ts +15 -22
- package/plugins/vi_mode.ts +77 -290
- package/plugins/vue-lsp.ts +9 -12
- package/plugins/yaml-lsp.ts +15 -22
- package/plugins/zig-lsp.ts +9 -12
package/plugins/cmake-lsp.ts
CHANGED
|
@@ -49,7 +49,8 @@ let cmakeLspError: { serverCommand: string; message: string } | null = null;
|
|
|
49
49
|
/**
|
|
50
50
|
* Handle LSP server errors for CMake
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
|
|
53
|
+
editor.on("lsp_server_error", (data) => {
|
|
53
54
|
if (data.language !== "cmake") {
|
|
54
55
|
return;
|
|
55
56
|
}
|
|
@@ -68,14 +69,13 @@ function on_cmake_lsp_server_error(data: LspServerErrorData): void {
|
|
|
68
69
|
} else {
|
|
69
70
|
editor.setStatus(`CMake LSP error: ${data.message}`);
|
|
70
71
|
}
|
|
71
|
-
}
|
|
72
|
-
registerHandler("on_cmake_lsp_server_error", on_cmake_lsp_server_error);
|
|
73
|
-
editor.on("lsp_server_error", "on_cmake_lsp_server_error");
|
|
72
|
+
});
|
|
74
73
|
|
|
75
74
|
/**
|
|
76
75
|
* Handle status bar click when there's a CMake LSP error
|
|
77
76
|
*/
|
|
78
|
-
|
|
77
|
+
|
|
78
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
79
79
|
if (data.language !== "cmake" || !cmakeLspError) {
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
@@ -93,14 +93,13 @@ function on_cmake_lsp_status_clicked(data: LspStatusClickedData): void {
|
|
|
93
93
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
94
94
|
],
|
|
95
95
|
});
|
|
96
|
-
}
|
|
97
|
-
registerHandler("on_cmake_lsp_status_clicked", on_cmake_lsp_status_clicked);
|
|
98
|
-
editor.on("lsp_status_clicked", "on_cmake_lsp_status_clicked");
|
|
96
|
+
});
|
|
99
97
|
|
|
100
98
|
/**
|
|
101
99
|
* Handle action popup results for CMake LSP help
|
|
102
100
|
*/
|
|
103
|
-
|
|
101
|
+
|
|
102
|
+
editor.on("action_popup_result", (data) => {
|
|
104
103
|
if (data.popup_id !== "cmake-lsp-help") {
|
|
105
104
|
return;
|
|
106
105
|
}
|
|
@@ -131,8 +130,6 @@ function on_cmake_lsp_action_result(data: ActionPopupResultData): void {
|
|
|
131
130
|
default:
|
|
132
131
|
editor.debug(`cmake-lsp: Unknown action: ${data.action_id}`);
|
|
133
132
|
}
|
|
134
|
-
}
|
|
135
|
-
registerHandler("on_cmake_lsp_action_result", on_cmake_lsp_action_result);
|
|
136
|
-
editor.on("action_popup_result", "on_cmake_lsp_action_result");
|
|
133
|
+
});
|
|
137
134
|
|
|
138
135
|
editor.debug("cmake-lsp: Plugin loaded");
|
package/plugins/code-tour.ts
CHANGED
|
@@ -123,22 +123,7 @@ interface ActionPopupResultData {
|
|
|
123
123
|
action_id: string;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
function tour_on_action_popup_result(data: ActionPopupResultData) : void {
|
|
127
|
-
if (data.popup_id !== TOUR_POPUP_ID) return;
|
|
128
126
|
|
|
129
|
-
switch (data.action_id) {
|
|
130
|
-
case "next":
|
|
131
|
-
nextStep();
|
|
132
|
-
break;
|
|
133
|
-
case "prev":
|
|
134
|
-
prevStep();
|
|
135
|
-
break;
|
|
136
|
-
case "exit":
|
|
137
|
-
exitTour();
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
registerHandler("tour_on_action_popup_result", tour_on_action_popup_result);
|
|
142
127
|
|
|
143
128
|
// ============================================================================
|
|
144
129
|
// Overlay Rendering
|
|
@@ -397,6 +382,20 @@ editor.registerCommand(
|
|
|
397
382
|
);
|
|
398
383
|
|
|
399
384
|
// Subscribe to action popup results for navigation buttons
|
|
400
|
-
editor.on("action_popup_result",
|
|
385
|
+
editor.on("action_popup_result", (data) => {
|
|
386
|
+
if (data.popup_id !== TOUR_POPUP_ID) return;
|
|
387
|
+
|
|
388
|
+
switch (data.action_id) {
|
|
389
|
+
case "next":
|
|
390
|
+
nextStep();
|
|
391
|
+
break;
|
|
392
|
+
case "prev":
|
|
393
|
+
prevStep();
|
|
394
|
+
break;
|
|
395
|
+
case "exit":
|
|
396
|
+
exitTour();
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
});
|
|
401
400
|
|
|
402
401
|
editor.debug("Code Tour plugin loaded");
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"description": "Editor behavior settings (indentation, line numbers, wrapping, etc.)",
|
|
31
31
|
"$ref": "#/$defs/EditorConfig",
|
|
32
32
|
"default": {
|
|
33
|
+
"animations": true,
|
|
33
34
|
"line_numbers": true,
|
|
34
35
|
"relative_line_numbers": false,
|
|
35
36
|
"highlight_current_line": true,
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
"show_status_bar": true,
|
|
46
47
|
"status_bar": {
|
|
47
48
|
"left": [
|
|
49
|
+
"{remote}",
|
|
48
50
|
"{filename}",
|
|
49
51
|
"{cursor}",
|
|
50
52
|
"{diagnostics}",
|
|
@@ -268,6 +270,12 @@
|
|
|
268
270
|
"description": "Editor behavior configuration",
|
|
269
271
|
"type": "object",
|
|
270
272
|
"properties": {
|
|
273
|
+
"animations": {
|
|
274
|
+
"description": "Enable frame-buffer animations (tab-switch slides, dashboard\nbringup, plugin-driven effects). When `false`, every animation\ncall is a no-op: the UI is fully static and each render lands\nthe final frame immediately. Useful on slow terminals, over\nSSH, or for users who prefer no motion.",
|
|
275
|
+
"type": "boolean",
|
|
276
|
+
"default": true,
|
|
277
|
+
"x-section": "Display"
|
|
278
|
+
},
|
|
271
279
|
"line_numbers": {
|
|
272
280
|
"description": "Show line numbers in the gutter (default for new buffers)",
|
|
273
281
|
"type": "boolean",
|
|
@@ -361,6 +369,7 @@
|
|
|
361
369
|
"$ref": "#/$defs/StatusBarConfig",
|
|
362
370
|
"default": {
|
|
363
371
|
"left": [
|
|
372
|
+
"{remote}",
|
|
364
373
|
"{filename}",
|
|
365
374
|
"{cursor}",
|
|
366
375
|
"{diagnostics}",
|
|
@@ -751,6 +760,7 @@
|
|
|
751
760
|
"$ref": "#/$defs/StatusBarElement"
|
|
752
761
|
},
|
|
753
762
|
"default": [
|
|
763
|
+
"{remote}",
|
|
754
764
|
"{filename}",
|
|
755
765
|
"{cursor}",
|
|
756
766
|
"{diagnostics}",
|
|
@@ -169,7 +169,10 @@ async function restoreProject(projectPath: string): Promise<void> {
|
|
|
169
169
|
/**
|
|
170
170
|
* Handle file open - set project root and restore packages
|
|
171
171
|
*/
|
|
172
|
-
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
// Register hook for file open
|
|
175
|
+
editor.on("after_file_open", async (data) => {
|
|
173
176
|
// Only handle .cs files
|
|
174
177
|
if (!data.path.endsWith(".cs")) {
|
|
175
178
|
return;
|
|
@@ -206,16 +209,15 @@ async function on_csharp_file_open(data: AfterFileOpenData) : Promise<void> {
|
|
|
206
209
|
await restoreProject(dir);
|
|
207
210
|
}
|
|
208
211
|
}
|
|
209
|
-
}
|
|
210
|
-
registerHandler("on_csharp_file_open", on_csharp_file_open);
|
|
211
|
-
|
|
212
|
-
// Register hook for file open
|
|
213
|
-
editor.on("after_file_open", "on_csharp_file_open");
|
|
212
|
+
});
|
|
214
213
|
|
|
215
214
|
/**
|
|
216
215
|
* Handle LSP server requests from C# language servers (Roslyn-based)
|
|
217
216
|
*/
|
|
218
|
-
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
// Register hook for LSP server requests
|
|
220
|
+
editor.on("lsp_server_request", (data) => {
|
|
219
221
|
// Only handle requests from C# language servers
|
|
220
222
|
if (data.server_command !== "csharp-ls" && data.server_command !== "csharp-language-server") {
|
|
221
223
|
return;
|
|
@@ -243,16 +245,15 @@ function on_csharp_lsp_server_request(data: LspServerRequestData) : void {
|
|
|
243
245
|
// Log unhandled requests for debugging
|
|
244
246
|
editor.debug(`csharp_support: Unhandled LSP request: ${data.method}`);
|
|
245
247
|
}
|
|
246
|
-
}
|
|
247
|
-
registerHandler("on_csharp_lsp_server_request", on_csharp_lsp_server_request);
|
|
248
|
-
|
|
249
|
-
// Register hook for LSP server requests
|
|
250
|
-
editor.on("lsp_server_request", "on_csharp_lsp_server_request");
|
|
248
|
+
});
|
|
251
249
|
|
|
252
250
|
/**
|
|
253
251
|
* Handle LSP server errors for C#
|
|
254
252
|
*/
|
|
255
|
-
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
// Register hook for LSP server errors
|
|
256
|
+
editor.on("lsp_server_error", (data) => {
|
|
256
257
|
// Only handle C# language errors
|
|
257
258
|
if (data.language !== "csharp") {
|
|
258
259
|
return;
|
|
@@ -274,16 +275,15 @@ function on_csharp_lsp_server_error(data: LspServerErrorData) : void {
|
|
|
274
275
|
} else {
|
|
275
276
|
editor.setStatus(`C# LSP error: ${data.message}`);
|
|
276
277
|
}
|
|
277
|
-
}
|
|
278
|
-
registerHandler("on_csharp_lsp_server_error", on_csharp_lsp_server_error);
|
|
279
|
-
|
|
280
|
-
// Register hook for LSP server errors
|
|
281
|
-
editor.on("lsp_server_error", "on_csharp_lsp_server_error");
|
|
278
|
+
});
|
|
282
279
|
|
|
283
280
|
/**
|
|
284
281
|
* Handle status bar click when there's a C# LSP error
|
|
285
282
|
*/
|
|
286
|
-
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
// Register hook for status bar clicks
|
|
286
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
287
287
|
// Only handle C# language clicks when there's an error
|
|
288
288
|
if (data.language !== "csharp" || !csharpLspError) {
|
|
289
289
|
return;
|
|
@@ -302,16 +302,15 @@ function on_csharp_lsp_status_clicked(data: LspStatusClickedData) : void {
|
|
|
302
302
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
303
303
|
],
|
|
304
304
|
});
|
|
305
|
-
}
|
|
306
|
-
registerHandler("on_csharp_lsp_status_clicked", on_csharp_lsp_status_clicked);
|
|
307
|
-
|
|
308
|
-
// Register hook for status bar clicks
|
|
309
|
-
editor.on("lsp_status_clicked", "on_csharp_lsp_status_clicked");
|
|
305
|
+
});
|
|
310
306
|
|
|
311
307
|
/**
|
|
312
308
|
* Handle action popup results for C# LSP help
|
|
313
309
|
*/
|
|
314
|
-
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
// Register hook for action popup results
|
|
313
|
+
editor.on("action_popup_result", (data) => {
|
|
315
314
|
// Only handle our popup
|
|
316
315
|
if (data.popup_id !== "csharp-lsp-help") {
|
|
317
316
|
return;
|
|
@@ -339,10 +338,6 @@ function on_csharp_lsp_action_result(data: ActionPopupResultData) : void {
|
|
|
339
338
|
default:
|
|
340
339
|
editor.debug(`csharp_support: Unknown action: ${data.action_id}`);
|
|
341
340
|
}
|
|
342
|
-
}
|
|
343
|
-
registerHandler("on_csharp_lsp_action_result", on_csharp_lsp_action_result);
|
|
344
|
-
|
|
345
|
-
// Register hook for action popup results
|
|
346
|
-
editor.on("action_popup_result", "on_csharp_lsp_action_result");
|
|
341
|
+
});
|
|
347
342
|
|
|
348
343
|
editor.debug("csharp_support: Plugin loaded");
|
package/plugins/css-lsp.ts
CHANGED
|
@@ -46,7 +46,10 @@ let cssLspError: { serverCommand: string; message: string } | null = null;
|
|
|
46
46
|
/**
|
|
47
47
|
* Handle LSP server errors for CSS
|
|
48
48
|
*/
|
|
49
|
-
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// Register hook for LSP server errors
|
|
52
|
+
editor.on("lsp_server_error", (data) => {
|
|
50
53
|
// Only handle CSS language errors
|
|
51
54
|
if (data.language !== "css") {
|
|
52
55
|
return;
|
|
@@ -68,18 +71,15 @@ function on_css_lsp_server_error(data: LspServerErrorData) : void {
|
|
|
68
71
|
} else {
|
|
69
72
|
editor.setStatus(`CSS LSP error: ${data.message}`);
|
|
70
73
|
}
|
|
71
|
-
}
|
|
72
|
-
registerHandler("on_css_lsp_server_error", on_css_lsp_server_error);
|
|
73
|
-
|
|
74
|
-
// Register hook for LSP server errors
|
|
75
|
-
editor.on("lsp_server_error", "on_css_lsp_server_error");
|
|
74
|
+
});
|
|
76
75
|
|
|
77
76
|
/**
|
|
78
77
|
* Handle status bar click when there's a CSS LSP error
|
|
79
78
|
*/
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
// Register hook for status bar clicks
|
|
82
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
83
83
|
// Only handle CSS language clicks when there's an error
|
|
84
84
|
if (data.language !== "css" || !cssLspError) {
|
|
85
85
|
return;
|
|
@@ -98,18 +98,15 @@ function on_css_lsp_status_clicked(
|
|
|
98
98
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
99
99
|
],
|
|
100
100
|
});
|
|
101
|
-
}
|
|
102
|
-
registerHandler("on_css_lsp_status_clicked", on_css_lsp_status_clicked);
|
|
103
|
-
|
|
104
|
-
// Register hook for status bar clicks
|
|
105
|
-
editor.on("lsp_status_clicked", "on_css_lsp_status_clicked");
|
|
101
|
+
});
|
|
106
102
|
|
|
107
103
|
/**
|
|
108
104
|
* Handle action popup results for CSS LSP help
|
|
109
105
|
*/
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
// Register hook for action popup results
|
|
109
|
+
editor.on("action_popup_result", (data) => {
|
|
113
110
|
// Only handle our popup
|
|
114
111
|
if (data.popup_id !== "css-lsp-help") {
|
|
115
112
|
return;
|
|
@@ -137,10 +134,6 @@ function on_css_lsp_action_result(
|
|
|
137
134
|
default:
|
|
138
135
|
editor.debug(`css-lsp: Unknown action: ${data.action_id}`);
|
|
139
136
|
}
|
|
140
|
-
}
|
|
141
|
-
registerHandler("on_css_lsp_action_result", on_css_lsp_action_result);
|
|
142
|
-
|
|
143
|
-
// Register hook for action popup results
|
|
144
|
-
editor.on("action_popup_result", "on_css_lsp_action_result");
|
|
137
|
+
});
|
|
145
138
|
|
|
146
139
|
editor.debug("css-lsp: Plugin loaded");
|
package/plugins/dart-lsp.ts
CHANGED
|
@@ -49,7 +49,8 @@ let dartLspError: { serverCommand: string; message: string } | null = null;
|
|
|
49
49
|
/**
|
|
50
50
|
* Handle LSP server errors for Dart
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
|
|
53
|
+
editor.on("lsp_server_error", (data) => {
|
|
53
54
|
if (data.language !== "dart") {
|
|
54
55
|
return;
|
|
55
56
|
}
|
|
@@ -68,14 +69,13 @@ function on_dart_lsp_server_error(data: LspServerErrorData): void {
|
|
|
68
69
|
} else {
|
|
69
70
|
editor.setStatus(`Dart LSP error: ${data.message}`);
|
|
70
71
|
}
|
|
71
|
-
}
|
|
72
|
-
registerHandler("on_dart_lsp_server_error", on_dart_lsp_server_error);
|
|
73
|
-
editor.on("lsp_server_error", "on_dart_lsp_server_error");
|
|
72
|
+
});
|
|
74
73
|
|
|
75
74
|
/**
|
|
76
75
|
* Handle status bar click when there's a Dart LSP error
|
|
77
76
|
*/
|
|
78
|
-
|
|
77
|
+
|
|
78
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
79
79
|
if (data.language !== "dart" || !dartLspError) {
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
@@ -94,14 +94,13 @@ function on_dart_lsp_status_clicked(data: LspStatusClickedData): void {
|
|
|
94
94
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
95
95
|
],
|
|
96
96
|
});
|
|
97
|
-
}
|
|
98
|
-
registerHandler("on_dart_lsp_status_clicked", on_dart_lsp_status_clicked);
|
|
99
|
-
editor.on("lsp_status_clicked", "on_dart_lsp_status_clicked");
|
|
97
|
+
});
|
|
100
98
|
|
|
101
99
|
/**
|
|
102
100
|
* Handle action popup results for Dart LSP help
|
|
103
101
|
*/
|
|
104
|
-
|
|
102
|
+
|
|
103
|
+
editor.on("action_popup_result", (data) => {
|
|
105
104
|
if (data.popup_id !== "dart-lsp-help") {
|
|
106
105
|
return;
|
|
107
106
|
}
|
|
@@ -137,8 +136,6 @@ function on_dart_lsp_action_result(data: ActionPopupResultData): void {
|
|
|
137
136
|
default:
|
|
138
137
|
editor.debug(`dart-lsp: Unknown action: ${data.action_id}`);
|
|
139
138
|
}
|
|
140
|
-
}
|
|
141
|
-
registerHandler("on_dart_lsp_action_result", on_dart_lsp_action_result);
|
|
142
|
-
editor.on("action_popup_result", "on_dart_lsp_action_result");
|
|
139
|
+
});
|
|
143
140
|
|
|
144
141
|
editor.debug("dart-lsp: Plugin loaded");
|
package/plugins/dashboard.ts
CHANGED
|
@@ -201,6 +201,55 @@ type RegisteredSection = {
|
|
|
201
201
|
let dashboardBufferId: number | null = null;
|
|
202
202
|
let fetchToken = 0; // bumped each open; late fetches from a prior open no-op.
|
|
203
203
|
|
|
204
|
+
// Id of the in-flight slide-in, so we can cancel it when starting a
|
|
205
|
+
// new one (on content change) or when the dashboard is closed
|
|
206
|
+
// mid-slide. Null once the animation settles or is cleared.
|
|
207
|
+
let activeAnimationId: number | null = null;
|
|
208
|
+
|
|
209
|
+
// Hash of all entries at the last paint (post-focus-highlight too —
|
|
210
|
+
// it's what ultimately lands in the virtual buffer). Used to decide
|
|
211
|
+
// whether setVirtualBufferContent needs to run at all: identical
|
|
212
|
+
// full hash AND identical focus → nothing changed, skip the VB
|
|
213
|
+
// round-trip entirely.
|
|
214
|
+
let lastPaintedFullKey: string | null = null;
|
|
215
|
+
|
|
216
|
+
// Hash of the entries with the clock stamp stripped. Animations only
|
|
217
|
+
// fire when THIS hash changes, so the 1 Hz clock tick on the top
|
|
218
|
+
// frame updates in place without re-sliding the whole dashboard.
|
|
219
|
+
// Keyboard focus changes don't move this hash either (the hash is
|
|
220
|
+
// taken before the focus overlay is laid on top), so Tab/Shift-Tab
|
|
221
|
+
// pan the highlight without re-animating.
|
|
222
|
+
let lastPaintedStructuralKey: string | null = null;
|
|
223
|
+
|
|
224
|
+
// focusedIndex the last successful setVirtualBufferContent ran with.
|
|
225
|
+
// Paired with the keys above so we can tell "focus moved but section
|
|
226
|
+
// data is the same" (update VB for the highlight, no animation).
|
|
227
|
+
let lastPaintedFocusedIndex = -1;
|
|
228
|
+
|
|
229
|
+
// Matches an HH:MM:SS clock stamp. Anything shaped like that is
|
|
230
|
+
// stripped from the structural hash so clock ticks don't animate.
|
|
231
|
+
// The frame renderer is the only dashboard author that emits such a
|
|
232
|
+
// string; if a third-party section happens to show a value in the
|
|
233
|
+
// same shape, the worst case is "we don't re-animate when that
|
|
234
|
+
// value changes" — acceptable noise floor.
|
|
235
|
+
const CLOCK_RE = /\d\d:\d\d:\d\d/g;
|
|
236
|
+
|
|
237
|
+
// Edge the slide-in enters from. Maps 1:1 to the plugin API's `from`
|
|
238
|
+
// field and is resolved from config (plugins.dashboard.slide_from) on
|
|
239
|
+
// each paint() so hot-reload of the setting Just Works. Defaults to
|
|
240
|
+
// "right" (new content pushes in from the right, old exits left).
|
|
241
|
+
type SlideFrom = "top" | "bottom" | "left" | "right";
|
|
242
|
+
function resolveSlideFrom(): SlideFrom {
|
|
243
|
+
const config = editor.getConfig() as Record<string, unknown> | null;
|
|
244
|
+
const plugins = config?.plugins as Record<string, unknown> | undefined;
|
|
245
|
+
const dashCfg = plugins?.dashboard as Record<string, unknown> | undefined;
|
|
246
|
+
const raw = dashCfg?.slide_from;
|
|
247
|
+
if (raw === "top" || raw === "bottom" || raw === "left" || raw === "right") {
|
|
248
|
+
return raw;
|
|
249
|
+
}
|
|
250
|
+
return "right";
|
|
251
|
+
}
|
|
252
|
+
|
|
204
253
|
// Registered sections, in render order. Built-ins are registered at
|
|
205
254
|
// plugin load (see the bottom of this file); third-party plugins
|
|
206
255
|
// append via the exported `registerSection` API.
|
|
@@ -726,6 +775,36 @@ function paint(dims?: { width: number; height: number }) {
|
|
|
726
775
|
((focusedIndex % targets.length) + targets.length) % targets.length;
|
|
727
776
|
}
|
|
728
777
|
|
|
778
|
+
// Two hashes, taken BEFORE the focus highlight goes on top:
|
|
779
|
+
// fullKey — everything including the clock. Drives the
|
|
780
|
+
// setVirtualBufferContent skip check, so the
|
|
781
|
+
// clock still redraws in place every second.
|
|
782
|
+
// structuralKey — clock stamps stripped. Drives the animation.
|
|
783
|
+
// A clock tick alone does not flip this, so it
|
|
784
|
+
// updates silently; a real section data change
|
|
785
|
+
// does, and the slide fires.
|
|
786
|
+
const fullKey = JSON.stringify(entries);
|
|
787
|
+
const structuralKey = fullKey.replace(CLOCK_RE, "##:##:##");
|
|
788
|
+
const fullChanged = fullKey !== lastPaintedFullKey;
|
|
789
|
+
const structuralChanged = structuralKey !== lastPaintedStructuralKey;
|
|
790
|
+
const focusChanged = focusedIndex !== lastPaintedFocusedIndex;
|
|
791
|
+
// A resize / viewport-shape change reshapes frame padding, dash
|
|
792
|
+
// runs, and centering, which flips the structural hash even when
|
|
793
|
+
// section data is unchanged. We repaint so the new layout takes
|
|
794
|
+
// effect but skip the slide — nothing NEW showed up, the user is
|
|
795
|
+
// just resizing a window. openDashboard clears lastPaintedW/H to
|
|
796
|
+
// -1 so the first paint after open doesn't trip this guard.
|
|
797
|
+
const dimsChanged =
|
|
798
|
+
lastPaintedW !== -1 &&
|
|
799
|
+
lastPaintedH !== -1 &&
|
|
800
|
+
(width !== lastPaintedW || height !== lastPaintedH);
|
|
801
|
+
|
|
802
|
+
// Identical render → short-circuit. Nothing to push to the
|
|
803
|
+
// buffer, nothing to animate.
|
|
804
|
+
if (!fullChanged && !focusChanged) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
|
|
729
808
|
// Paint the focus highlight by mutating the entry for the focused
|
|
730
809
|
// row: translate its visual col range into a byte range and push an
|
|
731
810
|
// inline overlay on top of whatever foreground/underline spans the
|
|
@@ -758,6 +837,26 @@ function paint(dims?: { width: number; height: number }) {
|
|
|
758
837
|
editor.setVirtualBufferContent(bufferId, entries);
|
|
759
838
|
lastPaintedW = width;
|
|
760
839
|
lastPaintedH = height;
|
|
840
|
+
lastPaintedFullKey = fullKey;
|
|
841
|
+
lastPaintedStructuralKey = structuralKey;
|
|
842
|
+
lastPaintedFocusedIndex = focusedIndex;
|
|
843
|
+
|
|
844
|
+
// Structural-change-driven re-animation: fire only when the
|
|
845
|
+
// section payload actually differs AND the dashboard isn't just
|
|
846
|
+
// reshaping in place (clock tick, focus move, and resize all
|
|
847
|
+
// land here without animating). Cancel any in-flight slide
|
|
848
|
+
// first so the new one snapshots the fresh content.
|
|
849
|
+
if (structuralChanged && !dimsChanged) {
|
|
850
|
+
if (activeAnimationId !== null) {
|
|
851
|
+
editor.cancelAnimation(activeAnimationId);
|
|
852
|
+
}
|
|
853
|
+
activeAnimationId = editor.animateVirtualBuffer(bufferId, {
|
|
854
|
+
kind: "slideIn",
|
|
855
|
+
from: resolveSlideFrom(),
|
|
856
|
+
durationMs: 520,
|
|
857
|
+
delayMs: 0,
|
|
858
|
+
});
|
|
859
|
+
}
|
|
761
860
|
}
|
|
762
861
|
|
|
763
862
|
// Open a URL in the user's browser via the platform's "open" helper.
|
|
@@ -1513,6 +1612,17 @@ async function openDashboard() {
|
|
|
1513
1612
|
}
|
|
1514
1613
|
}
|
|
1515
1614
|
|
|
1615
|
+
// Clear the content/focus keys and dims so the first paint after
|
|
1616
|
+
// open is treated as a content change and the slide-in fires.
|
|
1617
|
+
// Dim reset is needed because open is the one case where we DO
|
|
1618
|
+
// want the animation despite "dims changed" (there was no prior
|
|
1619
|
+
// dimension, so the change is really "buffer just appeared").
|
|
1620
|
+
lastPaintedFullKey = null;
|
|
1621
|
+
lastPaintedStructuralKey = null;
|
|
1622
|
+
lastPaintedFocusedIndex = -1;
|
|
1623
|
+
lastPaintedW = -1;
|
|
1624
|
+
lastPaintedH = -1;
|
|
1625
|
+
|
|
1516
1626
|
bootstrapDashboard(dashboardBufferId);
|
|
1517
1627
|
}
|
|
1518
1628
|
|
|
@@ -1584,6 +1694,10 @@ registerHandler(
|
|
|
1584
1694
|
// If the dashboard itself was closed, clear our handle so we'll
|
|
1585
1695
|
// re-open on the next "last tab closed" event.
|
|
1586
1696
|
if (dashboardBufferId !== null && e.buffer_id === dashboardBufferId) {
|
|
1697
|
+
if (activeAnimationId !== null) {
|
|
1698
|
+
editor.cancelAnimation(activeAnimationId);
|
|
1699
|
+
activeAnimationId = null;
|
|
1700
|
+
}
|
|
1587
1701
|
dashboardBufferId = null;
|
|
1588
1702
|
return;
|
|
1589
1703
|
}
|
|
@@ -1603,6 +1717,10 @@ registerHandler(
|
|
|
1603
1717
|
"dashboardOnAfterFileOpen",
|
|
1604
1718
|
(_e: { buffer_id: number; path: string }) => {
|
|
1605
1719
|
if (dashboardBufferId === null) return;
|
|
1720
|
+
if (activeAnimationId !== null) {
|
|
1721
|
+
editor.cancelAnimation(activeAnimationId);
|
|
1722
|
+
activeAnimationId = null;
|
|
1723
|
+
}
|
|
1606
1724
|
editor.closeBuffer(dashboardBufferId);
|
|
1607
1725
|
dashboardBufferId = null;
|
|
1608
1726
|
},
|