@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# Release Notes
|
|
2
2
|
|
|
3
|
+
## 0.1.83
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
* **QuickJS Plugin Runtime**: Replaced Deno with QuickJS for the plugin system. Each plugin now runs in its own isolated context.
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **Cargo Workspace Architecture**: Refactored into modular crates (fresh-core, fresh-editor, fresh-languages, fresh-parser-js, fresh-plugin-runtime, fresh-plugin-api-macros).
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **Toggle Comment YAML**: Fixed toggle comment not working for YAML files by falling back to config-based language detection (#774).
|
|
16
|
+
* **Undo History Panic**: Fixed panic when undoing past a save point and making new edits caused out-of-bounds slice access (#776).
|
|
17
|
+
* **Sudo Save Prompt**: Fixed permission denied crash when saving files owned by another user; now shows sudo prompt correctly (#775).
|
|
18
|
+
* **Musl Plugin Support**: Plugins now work on musl target builds (x86_64/aarch64-unknown-linux-musl).
|
|
19
|
+
* **LSP Server Requests**: Fixed LSP server-to-client request handling not being dispatched to plugins.
|
|
20
|
+
* **Git Find File Selection**: Fixed race condition causing wrong file selection when pressing Enter quickly.
|
|
21
|
+
* **Plugin Cache**: Embedded plugins now cached in XDG cache dir instead of leaking temp directories.
|
|
22
|
+
|
|
23
|
+
### Internal
|
|
24
|
+
|
|
25
|
+
* Improved compile times via LLVM optimization flag.
|
|
26
|
+
* Cross-platform path handling fixes for Windows.
|
|
27
|
+
* Test reliability improvements.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 0.1.77
|
|
32
|
+
|
|
33
|
+
### Documentation
|
|
34
|
+
|
|
35
|
+
* **macOS Terminal Tips**: Added keyboard enhancement flags configuration guide.
|
|
36
|
+
|
|
37
|
+
### Features
|
|
38
|
+
|
|
39
|
+
* **LSP Semantic Highlighting** (@Asuka-Minato).
|
|
40
|
+
* **macOS Keybinding Display**: Native symbols (⌃, ⌥, ⇧) instead of Ctrl+/Alt+/Shift+.
|
|
41
|
+
* **Odin Language Support**: Syntax highlighting (sublime-syntax from @Tetralux) and OLS LSP configuration (@xoxorwr).
|
|
42
|
+
* **File Explorer Git Indicators**: Shows modified/added status for files and folders via new plugin (#526) (@Asuka-Minato).
|
|
43
|
+
* **Keyboard Enhancement Flags Config**: New config options for more granular control over kitty protocol usage (`keyboard_disambiguate_escape_codes`, `keyboard_report_event_types`, `keyboard_report_alternate_keys`, `keyboard_report_all_keys_as_escape_codes`).
|
|
44
|
+
|
|
45
|
+
### Bug Fixes
|
|
46
|
+
|
|
47
|
+
* **Menu Keybinding Display**: Consistent keybinding symbols in menus on macOS (#703).
|
|
48
|
+
* **Git Find File Popup**: Smart path truncation preserving filename (#707).
|
|
49
|
+
* **File Owner Preservation**: Preserve owner when saving files with group write privileges (#743).
|
|
50
|
+
|
|
51
|
+
### Internal
|
|
52
|
+
|
|
53
|
+
* Telemetry and update checks now debounce to once per day.
|
|
54
|
+
* Terminal mode handling refactored into dedicated module.
|
|
55
|
+
* Resolved ~300+ clippy warnings.
|
|
56
|
+
* Bumped url (2.5.8), libc (0.2.180) (@dependabot).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
3
60
|
## 0.1.76
|
|
4
61
|
|
|
5
62
|
### Features
|
package/README.md
CHANGED
|
@@ -71,6 +71,8 @@ Or, pick your preferred method:
|
|
|
71
71
|
|
|
72
72
|
On macOS and some linux distros (Bazzite/Bluefin/Aurora):
|
|
73
73
|
|
|
74
|
+
> **Note:** On macOS, see [macOS Terminal Tips](docs/USER_GUIDE.md#macos-terminal-tips) for recommended terminal configuration.
|
|
75
|
+
|
|
74
76
|
```bash
|
|
75
77
|
brew tap sinelaw/fresh
|
|
76
78
|
brew install fresh-editor
|
package/package.json
CHANGED
package/plugins/audit_mode.ts
CHANGED
|
@@ -1103,21 +1103,21 @@ globalThis.review_drill_down = async () => {
|
|
|
1103
1103
|
const oldBufferId = await editor.createVirtualBuffer({
|
|
1104
1104
|
name: `*OLD:${h.file}*`,
|
|
1105
1105
|
mode: "normal",
|
|
1106
|
-
|
|
1106
|
+
readOnly: true,
|
|
1107
1107
|
entries: oldEntries,
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1108
|
+
showLineNumbers: true,
|
|
1109
|
+
editingDisabled: true,
|
|
1110
|
+
hiddenFromTabs: true
|
|
1111
1111
|
});
|
|
1112
1112
|
|
|
1113
1113
|
const newBufferId = await editor.createVirtualBuffer({
|
|
1114
1114
|
name: `*NEW:${h.file}*`,
|
|
1115
1115
|
mode: "normal",
|
|
1116
|
-
|
|
1116
|
+
readOnly: true,
|
|
1117
1117
|
entries: newEntries,
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1118
|
+
showLineNumbers: true,
|
|
1119
|
+
editingDisabled: true,
|
|
1120
|
+
hiddenFromTabs: true
|
|
1121
1121
|
});
|
|
1122
1122
|
|
|
1123
1123
|
// Convert hunks to composite buffer format (parse counts from git diff)
|
|
@@ -1493,7 +1493,7 @@ globalThis.start_review_diff = async () => {
|
|
|
1493
1493
|
state.comments = []; // Reset comments for new session
|
|
1494
1494
|
|
|
1495
1495
|
const bufferId = await VirtualBufferFactory.create({
|
|
1496
|
-
name: "*Review Diff*", mode: "review-mode",
|
|
1496
|
+
name: "*Review Diff*", mode: "review-mode", readOnly: true,
|
|
1497
1497
|
entries: (await renderReviewStream()).entries, showLineNumbers: false
|
|
1498
1498
|
});
|
|
1499
1499
|
state.reviewBufferId = bufferId;
|
|
@@ -1666,21 +1666,21 @@ globalThis.side_by_side_diff_current_file = async () => {
|
|
|
1666
1666
|
const oldBufferId = await editor.createVirtualBuffer({
|
|
1667
1667
|
name: `*OLD:${filePath}*`,
|
|
1668
1668
|
mode: "normal",
|
|
1669
|
-
|
|
1669
|
+
readOnly: true,
|
|
1670
1670
|
entries: oldEntries,
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1671
|
+
showLineNumbers: true,
|
|
1672
|
+
editingDisabled: true,
|
|
1673
|
+
hiddenFromTabs: true
|
|
1674
1674
|
});
|
|
1675
1675
|
|
|
1676
1676
|
const newBufferId = await editor.createVirtualBuffer({
|
|
1677
1677
|
name: `*NEW:${filePath}*`,
|
|
1678
1678
|
mode: "normal",
|
|
1679
|
-
|
|
1679
|
+
readOnly: true,
|
|
1680
1680
|
entries: newEntries,
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1681
|
+
showLineNumbers: true,
|
|
1682
|
+
editingDisabled: true,
|
|
1683
|
+
hiddenFromTabs: true
|
|
1684
1684
|
});
|
|
1685
1685
|
|
|
1686
1686
|
// Convert hunks to composite buffer format
|
package/plugins/calculator.ts
CHANGED
|
@@ -765,6 +765,6 @@ editor.on("mouse_click", "onCalculatorMouseClick");
|
|
|
765
765
|
editor.on("mouse_move", "onCalculatorMouseMove");
|
|
766
766
|
|
|
767
767
|
// Register main command
|
|
768
|
-
editor.registerCommand("%cmd.calculator", "%cmd.calculator_desc", "calculator_open",
|
|
768
|
+
editor.registerCommand("%cmd.calculator", "%cmd.calculator_desc", "calculator_open", null);
|
|
769
769
|
|
|
770
770
|
editor.setStatus(editor.t("status.loaded"));
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"large_file_threshold_bytes": 1048576,
|
|
43
43
|
"estimated_line_length": 80,
|
|
44
44
|
"enable_inlay_hints": true,
|
|
45
|
+
"enable_semantic_tokens_full": false,
|
|
45
46
|
"recovery_enabled": true,
|
|
46
47
|
"auto_save_interval_secs": 2,
|
|
47
48
|
"highlight_context_bytes": 10000,
|
|
@@ -52,6 +53,10 @@
|
|
|
52
53
|
"file_tree_poll_interval_ms": 3000,
|
|
53
54
|
"default_line_ending": "lf",
|
|
54
55
|
"cursor_style": "default",
|
|
56
|
+
"keyboard_disambiguate_escape_codes": true,
|
|
57
|
+
"keyboard_report_event_types": false,
|
|
58
|
+
"keyboard_report_alternate_keys": true,
|
|
59
|
+
"keyboard_report_all_keys_as_escape_codes": false,
|
|
55
60
|
"quick_suggestions": true,
|
|
56
61
|
"show_menu_bar": true,
|
|
57
62
|
"show_tab_bar": true
|
|
@@ -225,7 +230,7 @@
|
|
|
225
230
|
"default": 100
|
|
226
231
|
},
|
|
227
232
|
"large_file_threshold_bytes": {
|
|
228
|
-
"description": "File size threshold in bytes for \"large file\" behavior\nFiles larger than this will:\n- Skip LSP features\n- Use constant-size scrollbar thumb (1 char)\nFiles smaller will count actual lines for accurate scrollbar rendering",
|
|
233
|
+
"description": "File size threshold in bytes for \"large file\" behavior\nFiles larger than this will:\n- Skip LSP features\n- Use constant-size scrollbar thumb (1 char)\n\nFiles smaller will count actual lines for accurate scrollbar rendering",
|
|
229
234
|
"type": "integer",
|
|
230
235
|
"format": "uint64",
|
|
231
236
|
"minimum": 0,
|
|
@@ -243,6 +248,11 @@
|
|
|
243
248
|
"type": "boolean",
|
|
244
249
|
"default": true
|
|
245
250
|
},
|
|
251
|
+
"enable_semantic_tokens_full": {
|
|
252
|
+
"description": "Whether to request full-document LSP semantic tokens.\nRange requests are still used when supported.\nDefault: false (range-only to avoid heavy full refreshes).",
|
|
253
|
+
"type": "boolean",
|
|
254
|
+
"default": false
|
|
255
|
+
},
|
|
246
256
|
"recovery_enabled": {
|
|
247
257
|
"description": "Whether to enable file recovery (Emacs-style auto-save)\nWhen enabled, buffers are periodically saved to recovery files\nso they can be recovered if the editor crashes.",
|
|
248
258
|
"type": "boolean",
|
|
@@ -305,6 +315,26 @@
|
|
|
305
315
|
"$ref": "#/$defs/CursorStyle",
|
|
306
316
|
"default": "default"
|
|
307
317
|
},
|
|
318
|
+
"keyboard_disambiguate_escape_codes": {
|
|
319
|
+
"description": "Enable keyboard enhancement: disambiguate escape codes using CSI-u sequences.\nThis allows unambiguous reading of Escape and modified keys.\nRequires terminal support (kitty keyboard protocol).\nDefault: true",
|
|
320
|
+
"type": "boolean",
|
|
321
|
+
"default": true
|
|
322
|
+
},
|
|
323
|
+
"keyboard_report_event_types": {
|
|
324
|
+
"description": "Enable keyboard enhancement: report key event types (repeat/release).\nAdds extra events when keys are autorepeated or released.\nRequires terminal support (kitty keyboard protocol).\nDefault: false",
|
|
325
|
+
"type": "boolean",
|
|
326
|
+
"default": false
|
|
327
|
+
},
|
|
328
|
+
"keyboard_report_alternate_keys": {
|
|
329
|
+
"description": "Enable keyboard enhancement: report alternate keycodes.\nSends alternate keycodes in addition to the base keycode.\nRequires terminal support (kitty keyboard protocol).\nDefault: true",
|
|
330
|
+
"type": "boolean",
|
|
331
|
+
"default": true
|
|
332
|
+
},
|
|
333
|
+
"keyboard_report_all_keys_as_escape_codes": {
|
|
334
|
+
"description": "Enable keyboard enhancement: report all keys as escape codes.\nRepresents all keyboard events as CSI-u sequences.\nRequired for repeat/release events on plain-text keys.\nRequires terminal support (kitty keyboard protocol).\nDefault: false",
|
|
335
|
+
"type": "boolean",
|
|
336
|
+
"default": false
|
|
337
|
+
},
|
|
308
338
|
"quick_suggestions": {
|
|
309
339
|
"description": "Enable quick suggestions (VS Code-like behavior).\nWhen enabled, completion suggestions appear automatically while typing,\nnot just on trigger characters (like `.` or `::`).\nDefault: true",
|
|
310
340
|
"type": "boolean",
|
|
@@ -787,7 +817,7 @@
|
|
|
787
817
|
}
|
|
788
818
|
},
|
|
789
819
|
"PluginConfig": {
|
|
790
|
-
"description": "Configuration for
|
|
820
|
+
"description": "Configuration for a single plugin",
|
|
791
821
|
"type": "object",
|
|
792
822
|
"properties": {
|
|
793
823
|
"enabled": {
|
package/plugins/git_blame.ts
CHANGED
|
@@ -481,12 +481,12 @@ globalThis.show_git_blame = async function(): Promise<void> {
|
|
|
481
481
|
const bufferId = await editor.createVirtualBufferInExistingSplit({
|
|
482
482
|
name: bufferName,
|
|
483
483
|
mode: "git-blame",
|
|
484
|
-
|
|
484
|
+
readOnly: true,
|
|
485
485
|
entries: entries,
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
486
|
+
splitId: blameState.splitId!,
|
|
487
|
+
showLineNumbers: true, // We DO want line numbers (headers won't have them due to source_offset: null)
|
|
488
|
+
showCursors: true,
|
|
489
|
+
editingDisabled: true,
|
|
490
490
|
});
|
|
491
491
|
|
|
492
492
|
if (bufferId !== null) {
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/// <reference path="../types/fresh.d.ts" />
|
|
2
|
+
const editor = getEditor();
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Git Explorer Decorations
|
|
6
|
+
*
|
|
7
|
+
* Adds VS Code-style status badges (M/A/U/D/...) to the file explorer.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const NAMESPACE = "git-explorer";
|
|
11
|
+
|
|
12
|
+
const COLORS = {
|
|
13
|
+
added: [80, 250, 123] as [number, number, number],
|
|
14
|
+
modified: [255, 184, 108] as [number, number, number],
|
|
15
|
+
deleted: [255, 85, 85] as [number, number, number],
|
|
16
|
+
renamed: [139, 233, 253] as [number, number, number],
|
|
17
|
+
untracked: [241, 250, 140] as [number, number, number],
|
|
18
|
+
conflicted: [255, 121, 198] as [number, number, number],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const PRIORITY = {
|
|
22
|
+
conflicted: 90,
|
|
23
|
+
deleted: 80,
|
|
24
|
+
added: 60,
|
|
25
|
+
modified: 50,
|
|
26
|
+
renamed: 40,
|
|
27
|
+
untracked: 30,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
let refreshInFlight = false;
|
|
31
|
+
|
|
32
|
+
function statusToDecoration(status: string, staged: boolean) {
|
|
33
|
+
switch (status) {
|
|
34
|
+
case "A":
|
|
35
|
+
return { symbol: "A", color: COLORS.added, priority: PRIORITY.added };
|
|
36
|
+
case "M":
|
|
37
|
+
return {
|
|
38
|
+
symbol: "M",
|
|
39
|
+
color: staged ? COLORS.added : COLORS.modified,
|
|
40
|
+
priority: PRIORITY.modified + (staged ? 2 : 0),
|
|
41
|
+
};
|
|
42
|
+
case "D":
|
|
43
|
+
return { symbol: "D", color: COLORS.deleted, priority: PRIORITY.deleted };
|
|
44
|
+
case "R":
|
|
45
|
+
return { symbol: "R", color: COLORS.renamed, priority: PRIORITY.renamed };
|
|
46
|
+
case "C":
|
|
47
|
+
return { symbol: "C", color: COLORS.renamed, priority: PRIORITY.renamed };
|
|
48
|
+
case "U":
|
|
49
|
+
return { symbol: "!", color: COLORS.conflicted, priority: PRIORITY.conflicted };
|
|
50
|
+
default:
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function parseStatusOutput(output: string, repoRoot: string) {
|
|
56
|
+
const separator = output.includes("\0") ? "\0" : "\n";
|
|
57
|
+
const entries = output
|
|
58
|
+
.split(separator)
|
|
59
|
+
.map((entry) => entry.replace(/\r$/, ""))
|
|
60
|
+
.filter((entry) => entry.length > 0);
|
|
61
|
+
const byPath = new Map<string, { path: string; symbol: string; color: [number, number, number]; priority: number }>();
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < entries.length; i++) {
|
|
64
|
+
const entry = entries[i];
|
|
65
|
+
if (entry.length < 3) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const x = entry[0];
|
|
69
|
+
const y = entry[1];
|
|
70
|
+
let path = entry.slice(3);
|
|
71
|
+
|
|
72
|
+
if ((x === "R" || x === "C") && separator === "\0" && i + 1 < entries.length) {
|
|
73
|
+
i += 1;
|
|
74
|
+
path = entries[i];
|
|
75
|
+
} else if (entry.includes(" -> ") && (x === "R" || x === "C" || y === "R" || y === "C")) {
|
|
76
|
+
path = entry.split(" -> ").pop() ?? path;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let decoration = null;
|
|
80
|
+
if (x === "?" && y === "?") {
|
|
81
|
+
decoration = { symbol: "U", color: COLORS.untracked, priority: PRIORITY.untracked };
|
|
82
|
+
} else if (x !== " " && x !== "?") {
|
|
83
|
+
decoration = statusToDecoration(x, true);
|
|
84
|
+
} else if (y !== " ") {
|
|
85
|
+
decoration = statusToDecoration(y, false);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!decoration) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const absolutePath = editor.pathJoin(repoRoot, path);
|
|
93
|
+
const existing = byPath.get(absolutePath);
|
|
94
|
+
if (!existing || decoration.priority >= existing.priority) {
|
|
95
|
+
byPath.set(absolutePath, { path: absolutePath, ...decoration });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return Array.from(byPath.values());
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function refreshGitExplorerDecorations() {
|
|
103
|
+
if (refreshInFlight) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
refreshInFlight = true;
|
|
107
|
+
try {
|
|
108
|
+
const cwd = editor.getCwd();
|
|
109
|
+
const rootResult = await editor.spawnProcess("git", ["rev-parse", "--show-toplevel"], cwd);
|
|
110
|
+
if (rootResult.exit_code !== 0) {
|
|
111
|
+
editor.clearFileExplorerDecorations(NAMESPACE);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const repoRoot = rootResult.stdout.trim();
|
|
115
|
+
if (!repoRoot) {
|
|
116
|
+
editor.clearFileExplorerDecorations(NAMESPACE);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const statusResult = await editor.spawnProcess(
|
|
121
|
+
"git",
|
|
122
|
+
["status", "--porcelain"],
|
|
123
|
+
repoRoot
|
|
124
|
+
);
|
|
125
|
+
if (statusResult.exit_code !== 0) {
|
|
126
|
+
editor.clearFileExplorerDecorations(NAMESPACE);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const decorations = parseStatusOutput(statusResult.stdout, repoRoot);
|
|
131
|
+
if (decorations.length === 0) {
|
|
132
|
+
editor.clearFileExplorerDecorations(NAMESPACE);
|
|
133
|
+
} else {
|
|
134
|
+
editor.setFileExplorerDecorations(NAMESPACE, decorations);
|
|
135
|
+
}
|
|
136
|
+
} catch (_err) {
|
|
137
|
+
editor.clearFileExplorerDecorations(NAMESPACE);
|
|
138
|
+
} finally {
|
|
139
|
+
refreshInFlight = false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
globalThis.onGitExplorerAfterFileOpen = () => {
|
|
144
|
+
refreshGitExplorerDecorations();
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
globalThis.onGitExplorerAfterFileSave = () => {
|
|
148
|
+
refreshGitExplorerDecorations();
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
globalThis.onGitExplorerEditorInitialized = () => {
|
|
152
|
+
refreshGitExplorerDecorations();
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
editor.on("after_file_open", "onGitExplorerAfterFileOpen");
|
|
156
|
+
editor.on("after_file_save", "onGitExplorerAfterFileSave");
|
|
157
|
+
editor.on("editor_initialized", "onGitExplorerEditorInitialized");
|
|
158
|
+
|
|
159
|
+
refreshGitExplorerDecorations();
|
package/plugins/git_find_file.ts
CHANGED
|
@@ -27,7 +27,11 @@ async function loadGitFiles(): Promise<string[]> {
|
|
|
27
27
|
const result = await editor.spawnProcess("git", ["ls-files"]);
|
|
28
28
|
|
|
29
29
|
if (result.exit_code === 0) {
|
|
30
|
-
|
|
30
|
+
// Split by newline and trim each line to handle \r\n on Windows
|
|
31
|
+
return result.stdout
|
|
32
|
+
.split("\n")
|
|
33
|
+
.map((line) => line.trim())
|
|
34
|
+
.filter((line) => line !== "");
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
editor.debug(`Failed to load git files: ${result.stderr}`);
|
|
@@ -58,14 +62,14 @@ editor.registerCommand(
|
|
|
58
62
|
"%cmd.find",
|
|
59
63
|
"%cmd.find_desc",
|
|
60
64
|
"start_git_find_file",
|
|
61
|
-
|
|
65
|
+
null
|
|
62
66
|
);
|
|
63
67
|
|
|
64
68
|
editor.registerCommand(
|
|
65
69
|
"%cmd.reload",
|
|
66
70
|
"%cmd.reload_desc",
|
|
67
71
|
"git_reload_files",
|
|
68
|
-
|
|
72
|
+
null
|
|
69
73
|
);
|
|
70
74
|
|
|
71
75
|
editor.debug("Git Find File plugin loaded (using Finder abstraction)");
|
package/plugins/git_grep.ts
CHANGED
|
@@ -67,7 +67,7 @@ globalThis.start_git_grep = function (): void {
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
// Register command
|
|
70
|
-
editor.registerCommand("%cmd.grep", "%cmd.grep_desc", "start_git_grep",
|
|
70
|
+
editor.registerCommand("%cmd.grep", "%cmd.grep_desc", "start_git_grep", null);
|
|
71
71
|
|
|
72
72
|
// Log that plugin loaded successfully
|
|
73
73
|
editor.debug("Git Grep plugin loaded (using Finder abstraction)");
|
package/plugins/git_log.ts
CHANGED
|
@@ -766,12 +766,12 @@ globalThis.show_git_log = async function(): Promise<void> {
|
|
|
766
766
|
const bufferId = await editor.createVirtualBufferInExistingSplit({
|
|
767
767
|
name: "*Git Log*",
|
|
768
768
|
mode: "git-log",
|
|
769
|
-
|
|
769
|
+
readOnly: true,
|
|
770
770
|
entries: entries,
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
771
|
+
splitId: gitLogState.splitId!,
|
|
772
|
+
showLineNumbers: false,
|
|
773
|
+
showCursors: true,
|
|
774
|
+
editingDisabled: true,
|
|
775
775
|
});
|
|
776
776
|
|
|
777
777
|
if (bufferId !== null) {
|
|
@@ -900,12 +900,12 @@ globalThis.git_log_show_commit = async function(): Promise<void> {
|
|
|
900
900
|
const bufferId = await editor.createVirtualBufferInExistingSplit({
|
|
901
901
|
name: `*Commit: ${commit.shortHash}*`,
|
|
902
902
|
mode: "git-commit-detail",
|
|
903
|
-
|
|
903
|
+
readOnly: true,
|
|
904
904
|
entries: entries,
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
905
|
+
splitId: gitLogState.splitId!,
|
|
906
|
+
showLineNumbers: false, // Disable line numbers for cleaner diff view
|
|
907
|
+
showCursors: true,
|
|
908
|
+
editingDisabled: true,
|
|
909
909
|
});
|
|
910
910
|
|
|
911
911
|
if (bufferId !== null) {
|
|
@@ -1213,12 +1213,12 @@ globalThis.git_commit_detail_open_file = async function(): Promise<void> {
|
|
|
1213
1213
|
const bufferId = await editor.createVirtualBufferInExistingSplit({
|
|
1214
1214
|
name: `${file} @ ${commit.shortHash}`,
|
|
1215
1215
|
mode: "git-file-view",
|
|
1216
|
-
|
|
1216
|
+
readOnly: true,
|
|
1217
1217
|
entries: entries,
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1218
|
+
splitId: commitDetailState.splitId!,
|
|
1219
|
+
showLineNumbers: true,
|
|
1220
|
+
showCursors: true,
|
|
1221
|
+
editingDisabled: true,
|
|
1222
1222
|
});
|
|
1223
1223
|
|
|
1224
1224
|
if (bufferId !== null) {
|
package/plugins/lib/finder.ts
CHANGED
|
@@ -465,7 +465,9 @@ export class Finder<T> {
|
|
|
465
465
|
options.initialQuery
|
|
466
466
|
);
|
|
467
467
|
} else {
|
|
468
|
-
this.editor.startPrompt
|
|
468
|
+
this.editor.debug(`[Finder] calling startPrompt with title="${options.title}", id="${this.config.id}"`);
|
|
469
|
+
const result = this.editor.startPrompt(options.title, this.config.id);
|
|
470
|
+
this.editor.debug(`[Finder] startPrompt returned: ${result}`);
|
|
469
471
|
}
|
|
470
472
|
this.editor.setStatus("Type to search...");
|
|
471
473
|
}
|
|
@@ -951,11 +953,11 @@ export class Finder<T> {
|
|
|
951
953
|
}
|
|
952
954
|
|
|
953
955
|
private closePreview(): void {
|
|
954
|
-
if (this.previewState.bufferId
|
|
956
|
+
if (this.previewState.bufferId || this.previewState.bufferId == 0) {
|
|
955
957
|
this.editor.closeBuffer(this.previewState.bufferId);
|
|
956
958
|
this.previewState.bufferId = null;
|
|
957
959
|
}
|
|
958
|
-
if (this.previewState.splitId
|
|
960
|
+
if (this.previewState.splitId || this.previewState.splitId == 0) {
|
|
959
961
|
this.editor.closeSplit(this.previewState.splitId);
|
|
960
962
|
this.previewState.splitId = null;
|
|
961
963
|
}
|