@fresh-editor/fresh-editor 0.1.76 → 0.1.83
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 +57 -0
- package/README.md +2 -0
- package/package.json +1 -1
- package/plugins/audit_mode.ts +17 -17
- package/plugins/calculator.ts +1 -1
- package/plugins/config-schema.json +32 -2
- package/plugins/git_blame.ts +5 -5
- package/plugins/git_explorer.ts +159 -0
- package/plugins/git_find_file.ts +7 -3
- package/plugins/git_grep.ts +1 -1
- package/plugins/git_log.ts +15 -15
- package/plugins/lib/finder.ts +5 -3
- package/plugins/lib/fresh.d.ts +641 -1389
- package/plugins/lib/index.ts +9 -1
- package/plugins/lib/types.ts +14 -0
- package/plugins/live_grep.ts +1 -1
- package/plugins/odin-lsp.ts +135 -0
- package/plugins/search_replace.ts +1 -1
- package/plugins/theme_editor.ts +40 -8
- package/plugins/vi_mode.ts +6 -0
- package/plugins/welcome.ts +5 -5
- package/plugins/lib/results-panel.ts +0 -914
package/plugins/lib/index.ts
CHANGED
|
@@ -11,7 +11,15 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
// Types
|
|
14
|
-
export type {
|
|
14
|
+
export type {
|
|
15
|
+
RGB,
|
|
16
|
+
Location,
|
|
17
|
+
PanelOptions,
|
|
18
|
+
PanelState,
|
|
19
|
+
NavigationOptions,
|
|
20
|
+
HighlightPattern,
|
|
21
|
+
FileExplorerDecoration,
|
|
22
|
+
} from "./types.ts";
|
|
15
23
|
|
|
16
24
|
// Panel Management
|
|
17
25
|
export { PanelManager } from "./panel-manager.ts";
|
package/plugins/lib/types.ts
CHANGED
|
@@ -11,6 +11,20 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export type RGB = [number, number, number];
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* File explorer decoration metadata provided by plugins
|
|
16
|
+
*/
|
|
17
|
+
export interface FileExplorerDecoration {
|
|
18
|
+
/** Absolute or workspace-relative path to decorate */
|
|
19
|
+
path: string;
|
|
20
|
+
/** Symbol to display (single character recommended) */
|
|
21
|
+
symbol?: string;
|
|
22
|
+
/** RGB color for the symbol */
|
|
23
|
+
color?: RGB;
|
|
24
|
+
/** Priority for resolving conflicts (higher wins) */
|
|
25
|
+
priority?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
/**
|
|
15
29
|
* File location with line and column
|
|
16
30
|
*/
|
package/plugins/live_grep.ts
CHANGED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/// <reference path="./lib/fresh.d.ts" />
|
|
2
|
+
const editor = getEditor();
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Odin LSP Helper Plugin
|
|
7
|
+
*
|
|
8
|
+
* Provides user-friendly error handling for Odin LSP server issues.
|
|
9
|
+
* When ols (Odin Language Server) fails to start, this plugin shows an actionable
|
|
10
|
+
* popup with installation instructions.
|
|
11
|
+
*
|
|
12
|
+
* Features:
|
|
13
|
+
* - Detects Odin LSP server errors (ols)
|
|
14
|
+
* - Shows popup with build instructions
|
|
15
|
+
* - Allows copying build commands to clipboard
|
|
16
|
+
* - Provides option to disable Odin LSP
|
|
17
|
+
*
|
|
18
|
+
* OLS: https://github.com/DanielGavin/ols
|
|
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
|
+
// OLS GitHub repository
|
|
39
|
+
const OLS_URL = "https://github.com/DanielGavin/ols";
|
|
40
|
+
|
|
41
|
+
// Track error state for Odin LSP
|
|
42
|
+
let odinLspError: { serverCommand: string; message: string } | null = null;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Handle LSP server errors for Odin
|
|
46
|
+
*/
|
|
47
|
+
globalThis.on_odin_lsp_server_error = function (data: LspServerErrorData): void {
|
|
48
|
+
// Only handle Odin language errors
|
|
49
|
+
if (data.language !== "odin") {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
editor.debug(`odin-lsp: Server error - ${data.error_type}: ${data.message}`);
|
|
54
|
+
|
|
55
|
+
// Store error state for later reference
|
|
56
|
+
odinLspError = {
|
|
57
|
+
serverCommand: data.server_command,
|
|
58
|
+
message: data.message,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Show a status message for immediate feedback
|
|
62
|
+
if (data.error_type === "not_found") {
|
|
63
|
+
editor.setStatus(
|
|
64
|
+
`Odin LSP server '${data.server_command}' not found. Click status bar for help.`
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
editor.setStatus(`Odin LSP error: ${data.message}`);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Register hook for LSP server errors
|
|
72
|
+
editor.on("lsp_server_error", "on_odin_lsp_server_error");
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Handle status bar click when there's an Odin LSP error
|
|
76
|
+
*/
|
|
77
|
+
globalThis.on_odin_lsp_status_clicked = function (
|
|
78
|
+
data: LspStatusClickedData
|
|
79
|
+
): void {
|
|
80
|
+
// Only handle Odin language clicks when there's an error
|
|
81
|
+
if (data.language !== "odin" || !odinLspError) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
editor.debug("odin-lsp: Status clicked, showing help popup");
|
|
86
|
+
|
|
87
|
+
// Show action popup with install options
|
|
88
|
+
editor.showActionPopup({
|
|
89
|
+
id: "odin-lsp-help",
|
|
90
|
+
title: "Odin Language Server Not Found",
|
|
91
|
+
message: `"${odinLspError.serverCommand}" (OLS) provides code completion, diagnostics, and navigation for Odin files.\n\nInstallation: ${OLS_URL}`,
|
|
92
|
+
actions: [
|
|
93
|
+
{ id: "disable", label: "Disable Odin LSP" },
|
|
94
|
+
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// Register hook for status bar clicks
|
|
100
|
+
editor.on("lsp_status_clicked", "on_odin_lsp_status_clicked");
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Handle action popup results for Odin LSP help
|
|
104
|
+
*/
|
|
105
|
+
globalThis.on_odin_lsp_action_result = function (
|
|
106
|
+
data: ActionPopupResultData
|
|
107
|
+
): void {
|
|
108
|
+
// Only handle our popup
|
|
109
|
+
if (data.popup_id !== "odin-lsp-help") {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
editor.debug(`odin-lsp: Action selected - ${data.action_id}`);
|
|
114
|
+
|
|
115
|
+
switch (data.action_id) {
|
|
116
|
+
case "disable":
|
|
117
|
+
editor.disableLspForLanguage("odin");
|
|
118
|
+
editor.setStatus("Odin LSP disabled");
|
|
119
|
+
odinLspError = null;
|
|
120
|
+
break;
|
|
121
|
+
|
|
122
|
+
case "dismiss":
|
|
123
|
+
case "dismissed":
|
|
124
|
+
// Just close the popup without action
|
|
125
|
+
break;
|
|
126
|
+
|
|
127
|
+
default:
|
|
128
|
+
editor.debug(`odin-lsp: Unknown action: ${data.action_id}`);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Register hook for action popup results
|
|
133
|
+
editor.on("action_popup_result", "on_odin_lsp_action_result");
|
|
134
|
+
|
|
135
|
+
editor.debug("odin-lsp: Plugin loaded");
|
package/plugins/theme_editor.ts
CHANGED
|
@@ -484,10 +484,17 @@ function findThemesDir(): string {
|
|
|
484
484
|
*/
|
|
485
485
|
async function loadBuiltinThemes(): Promise<string[]> {
|
|
486
486
|
try {
|
|
487
|
-
|
|
487
|
+
editor.debug("[theme_editor] loadBuiltinThemes: calling editor.getBuiltinThemes()");
|
|
488
|
+
const rawThemes = editor.getBuiltinThemes();
|
|
489
|
+
editor.debug(`[theme_editor] loadBuiltinThemes: got rawThemes type=${typeof rawThemes}`);
|
|
490
|
+
// getBuiltinThemes returns a JSON string, need to parse it
|
|
491
|
+
const builtinThemes = typeof rawThemes === "string"
|
|
492
|
+
? JSON.parse(rawThemes) as Record<string, string>
|
|
493
|
+
: rawThemes as Record<string, string>;
|
|
494
|
+
editor.debug(`[theme_editor] loadBuiltinThemes: parsed ${Object.keys(builtinThemes).length} themes`);
|
|
488
495
|
return Object.keys(builtinThemes);
|
|
489
496
|
} catch (e) {
|
|
490
|
-
editor.debug(`Failed to load built-in themes list: ${e}`);
|
|
497
|
+
editor.debug(`[theme_editor] Failed to load built-in themes list: ${e}`);
|
|
491
498
|
throw e;
|
|
492
499
|
}
|
|
493
500
|
}
|
|
@@ -497,13 +504,17 @@ async function loadBuiltinThemes(): Promise<string[]> {
|
|
|
497
504
|
*/
|
|
498
505
|
async function loadThemeFile(name: string): Promise<Record<string, unknown> | null> {
|
|
499
506
|
try {
|
|
500
|
-
const
|
|
507
|
+
const rawThemes = editor.getBuiltinThemes();
|
|
508
|
+
// getBuiltinThemes returns a JSON string, need to parse it
|
|
509
|
+
const builtinThemes = typeof rawThemes === "string"
|
|
510
|
+
? JSON.parse(rawThemes) as Record<string, string>
|
|
511
|
+
: rawThemes as Record<string, string>;
|
|
501
512
|
if (name in builtinThemes) {
|
|
502
513
|
return JSON.parse(builtinThemes[name]);
|
|
503
514
|
}
|
|
504
515
|
return null;
|
|
505
516
|
} catch (e) {
|
|
506
|
-
editor.debug(`Failed to load theme data for '${name}': ${e}`);
|
|
517
|
+
editor.debug(`[theme_editor] Failed to load theme data for '${name}': ${e}`);
|
|
507
518
|
return null;
|
|
508
519
|
}
|
|
509
520
|
}
|
|
@@ -1190,7 +1201,12 @@ globalThis.onThemeSelectInitialPromptConfirmed = async function(args: {
|
|
|
1190
1201
|
selected_index: number | null;
|
|
1191
1202
|
input: string;
|
|
1192
1203
|
}): Promise<boolean> {
|
|
1193
|
-
|
|
1204
|
+
editor.debug(`[theme_editor] onThemeSelectInitialPromptConfirmed called with: ${JSON.stringify(args)}`);
|
|
1205
|
+
if (args.prompt_type !== "theme-select-initial") {
|
|
1206
|
+
editor.debug(`[theme_editor] prompt_type mismatch, expected 'theme-select-initial', got '${args.prompt_type}'`);
|
|
1207
|
+
return true;
|
|
1208
|
+
}
|
|
1209
|
+
editor.debug(`[theme_editor] prompt_type matched, processing selection...`);
|
|
1194
1210
|
|
|
1195
1211
|
const value = args.input.trim();
|
|
1196
1212
|
|
|
@@ -1252,7 +1268,9 @@ globalThis.onThemeSelectInitialPromptConfirmed = async function(args: {
|
|
|
1252
1268
|
}
|
|
1253
1269
|
|
|
1254
1270
|
// Now open the editor with loaded theme
|
|
1271
|
+
editor.debug(`[theme_editor] About to call doOpenThemeEditor()`);
|
|
1255
1272
|
await doOpenThemeEditor();
|
|
1273
|
+
editor.debug(`[theme_editor] doOpenThemeEditor() completed`);
|
|
1256
1274
|
|
|
1257
1275
|
return true;
|
|
1258
1276
|
};
|
|
@@ -1642,7 +1660,9 @@ globalThis.theme_editor_nav_prev_section = function(): void {
|
|
|
1642
1660
|
* Open the theme editor - prompts user to select theme first
|
|
1643
1661
|
*/
|
|
1644
1662
|
globalThis.open_theme_editor = async function(): Promise<void> {
|
|
1663
|
+
editor.debug("[theme_editor] open_theme_editor called");
|
|
1645
1664
|
if (isThemeEditorOpen()) {
|
|
1665
|
+
editor.debug("[theme_editor] already open, focusing");
|
|
1646
1666
|
// Focus the existing theme editor split
|
|
1647
1667
|
if (state.splitId !== null) {
|
|
1648
1668
|
editor.focusSplit(state.splitId);
|
|
@@ -1651,12 +1671,15 @@ globalThis.open_theme_editor = async function(): Promise<void> {
|
|
|
1651
1671
|
return;
|
|
1652
1672
|
}
|
|
1653
1673
|
|
|
1674
|
+
editor.debug("[theme_editor] saving context");
|
|
1654
1675
|
// Save context
|
|
1655
1676
|
state.sourceSplitId = editor.getActiveSplitId();
|
|
1656
1677
|
state.sourceBufferId = editor.getActiveBufferId();
|
|
1657
1678
|
|
|
1679
|
+
editor.debug("[theme_editor] loading builtin themes...");
|
|
1658
1680
|
// Load available themes
|
|
1659
1681
|
state.builtinThemes = await loadBuiltinThemes();
|
|
1682
|
+
editor.debug(`[theme_editor] loaded ${state.builtinThemes.length} builtin themes`);
|
|
1660
1683
|
|
|
1661
1684
|
// Get current theme name from config
|
|
1662
1685
|
const config = editor.getConfig() as Record<string, unknown>;
|
|
@@ -1704,10 +1727,13 @@ globalThis.open_theme_editor = async function(): Promise<void> {
|
|
|
1704
1727
|
* Actually open the theme editor with loaded theme data
|
|
1705
1728
|
*/
|
|
1706
1729
|
async function doOpenThemeEditor(): Promise<void> {
|
|
1730
|
+
editor.debug("[theme_editor] doOpenThemeEditor: building display entries");
|
|
1707
1731
|
// Build initial entries
|
|
1708
1732
|
const entries = buildDisplayEntries();
|
|
1733
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: built ${entries.length} entries`);
|
|
1709
1734
|
|
|
1710
1735
|
// Create virtual buffer in current split (no new split)
|
|
1736
|
+
editor.debug("[theme_editor] doOpenThemeEditor: calling createVirtualBuffer...");
|
|
1711
1737
|
const bufferId = await editor.createVirtualBuffer({
|
|
1712
1738
|
name: "*Theme Editor*",
|
|
1713
1739
|
mode: "theme-editor",
|
|
@@ -1717,13 +1743,20 @@ async function doOpenThemeEditor(): Promise<void> {
|
|
|
1717
1743
|
show_cursors: true,
|
|
1718
1744
|
editing_disabled: true,
|
|
1719
1745
|
});
|
|
1746
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: createVirtualBuffer returned bufferId=${bufferId}`);
|
|
1747
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: checking if bufferId !== null...`);
|
|
1720
1748
|
|
|
1721
1749
|
if (bufferId !== null) {
|
|
1750
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: bufferId is not null, setting state...`);
|
|
1722
1751
|
state.bufferId = bufferId;
|
|
1723
1752
|
state.splitId = null;
|
|
1724
1753
|
|
|
1754
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: calling applyHighlighting...`);
|
|
1725
1755
|
applyHighlighting();
|
|
1756
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: applyHighlighting completed`);
|
|
1757
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: calling setStatus...`);
|
|
1726
1758
|
editor.setStatus(editor.t("status.ready"));
|
|
1759
|
+
editor.debug(`[theme_editor] doOpenThemeEditor: completed successfully`);
|
|
1727
1760
|
} else {
|
|
1728
1761
|
editor.setStatus(editor.t("status.open_failed"));
|
|
1729
1762
|
}
|
|
@@ -2037,12 +2070,11 @@ globalThis.onThemeDeletePromptConfirmed = async function(args: {
|
|
|
2037
2070
|
// Command Registration
|
|
2038
2071
|
// =============================================================================
|
|
2039
2072
|
|
|
2040
|
-
// Main command to open theme editor (always available)
|
|
2073
|
+
// Main command to open theme editor (always available - no context restriction)
|
|
2041
2074
|
editor.registerCommand(
|
|
2042
2075
|
"%cmd.edit_theme",
|
|
2043
2076
|
"%cmd.edit_theme_desc",
|
|
2044
|
-
"open_theme_editor"
|
|
2045
|
-
"normal"
|
|
2077
|
+
"open_theme_editor"
|
|
2046
2078
|
);
|
|
2047
2079
|
|
|
2048
2080
|
// Buffer-scoped commands - only visible when a buffer with mode "theme-editor" is focused
|
package/plugins/vi_mode.ts
CHANGED
|
@@ -2724,17 +2724,23 @@ editor.on("prompt_confirmed", "vi_command_handler");
|
|
|
2724
2724
|
let viModeEnabled = false;
|
|
2725
2725
|
|
|
2726
2726
|
globalThis.vi_mode_toggle = function (): void {
|
|
2727
|
+
editor.debug("[vi_mode_toggle] called, viModeEnabled was: " + viModeEnabled);
|
|
2727
2728
|
viModeEnabled = !viModeEnabled;
|
|
2729
|
+
editor.debug("[vi_mode_toggle] viModeEnabled now: " + viModeEnabled);
|
|
2728
2730
|
|
|
2729
2731
|
if (viModeEnabled) {
|
|
2732
|
+
editor.debug("[vi_mode_toggle] enabling vi mode, calling switchMode('normal')");
|
|
2730
2733
|
switchMode("normal");
|
|
2734
|
+
editor.debug("[vi_mode_toggle] switchMode done, setting status");
|
|
2731
2735
|
editor.setStatus(editor.t("status.enabled"));
|
|
2732
2736
|
} else {
|
|
2737
|
+
editor.debug("[vi_mode_toggle] disabling vi mode");
|
|
2733
2738
|
editor.setEditorMode(null);
|
|
2734
2739
|
state.mode = "normal";
|
|
2735
2740
|
state.pendingOperator = null;
|
|
2736
2741
|
editor.setStatus(editor.t("status.disabled"));
|
|
2737
2742
|
}
|
|
2743
|
+
editor.debug("[vi_mode_toggle] done");
|
|
2738
2744
|
};
|
|
2739
2745
|
|
|
2740
2746
|
editor.registerCommand(
|
package/plugins/welcome.ts
CHANGED
|
@@ -15,14 +15,14 @@ editor.registerCommand(
|
|
|
15
15
|
"%cmd.open_help",
|
|
16
16
|
"%cmd.open_help_desc",
|
|
17
17
|
"show_help",
|
|
18
|
-
|
|
18
|
+
null
|
|
19
19
|
);
|
|
20
20
|
|
|
21
21
|
editor.registerCommand(
|
|
22
22
|
"%cmd.save_file",
|
|
23
23
|
"%cmd.save_file_desc",
|
|
24
24
|
"save",
|
|
25
|
-
|
|
25
|
+
null
|
|
26
26
|
);
|
|
27
27
|
|
|
28
28
|
// Register commands with custom TypeScript callbacks
|
|
@@ -36,7 +36,7 @@ editor.registerCommand(
|
|
|
36
36
|
"%cmd.say_hello",
|
|
37
37
|
"%cmd.say_hello_desc",
|
|
38
38
|
"plugin_say_hello",
|
|
39
|
-
|
|
39
|
+
null
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
globalThis.plugin_insert_time = function(): void {
|
|
@@ -50,7 +50,7 @@ editor.registerCommand(
|
|
|
50
50
|
"%cmd.insert_time",
|
|
51
51
|
"%cmd.insert_time_desc",
|
|
52
52
|
"plugin_insert_time",
|
|
53
|
-
|
|
53
|
+
null
|
|
54
54
|
);
|
|
55
55
|
|
|
56
56
|
globalThis.plugin_insert_comment = function(): void {
|
|
@@ -63,7 +63,7 @@ editor.registerCommand(
|
|
|
63
63
|
"%cmd.insert_comment",
|
|
64
64
|
"%cmd.insert_comment_desc",
|
|
65
65
|
"plugin_insert_comment",
|
|
66
|
-
|
|
66
|
+
null
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
// Debug output
|