@fresh-editor/fresh-editor 0.1.83 → 0.1.87

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 CHANGED
@@ -1,5 +1,55 @@
1
1
  # Release Notes
2
2
 
3
+ ## 0.1.87
4
+
5
+ ### Features
6
+
7
+ * **Language Support**: Added LSP configurations and syntax highlighting for Zig, Java, LaTeX, Markdown, and Templ.
8
+ * **Git File Highlighting**: Syntax highlighting for git-related files (.gitignore, .gitattributes, .gitmodules).
9
+ * **Plugin Type Safety**: TypeScript type definitions for plugin API with compile-time validation.
10
+
11
+ ### Bug Fixes
12
+
13
+ * **Hover Popup**: Fixed scrolling to bottom, dismiss on click outside, block clicks inside popup.
14
+ * **Settings UI**: Fixed overwriting manual config.json edits when saving from Settings UI (#806).
15
+ * **Windows Terminal**: Fixed truecolor detection and 256-color grayscale conversion overflow.
16
+ * **Composite Buffers**: Fixed mouse click sync, deserialization errors, and cursor positioning.
17
+ * **Plugin Stability**: Plugin thread panics now propagate to main thread for proper error handling.
18
+ * **Review Diff Plugin**: Fixed side-by-side diff commands not appearing in command palette.
19
+
20
+ ---
21
+
22
+ ## 0.1.86
23
+
24
+ ### Features
25
+
26
+ * **Popup Text Selection**: Select and copy text from LSP hover popups and tooltips. Click and drag to select, Ctrl+C to copy.
27
+ * **File Explorer Status Tooltips**: Hover over git status indicators (M, U, A) to see detailed explanations and diff stats. Directory tooltips show list of modified files.
28
+ * **Terminal Background Transparency**: New `use_terminal_bg` config option allows terminal transparency or custom backgrounds to show through the editor (#640).
29
+ * **Vi Mode Improvements**: Added `:w filename` to save to path, `:wq filename` to save and quit, `:q!` to force quit without saving. Added Ctrl+P (command palette) and Ctrl+Q (quit) to all vi modes.
30
+
31
+ ### Bug Fixes
32
+
33
+ * **Settings UI Add Button**: Fixed "Add New" button not appearing for LSP and Languages maps in Settings UI.
34
+ * **LSP Hover Markdown**: Improved markdown rendering - soft breaks now create newlines (fixing Python docstring formatting), inline code rendered without visible backticks.
35
+ * **Symlink Directories**: Fixed symlinks to directories not showing expand marker and causing "Is a directory" error when opened (#787).
36
+ * **Live Grep Preview**: Fixed preview not updating when navigating through search results (#636).
37
+ * **Terminal Keyboard State**: Fixed arrow keys and Enter not working after exiting the editor due to Kitty keyboard protocol cleanup issue (#773).
38
+ * **Plugin Commands Visibility**: Fixed many plugin commands (Toggle Vi Mode, Git Blame, Diagnostics Panel, etc.) not appearing in command palette.
39
+
40
+ ### UI Changes
41
+
42
+ * **File Explorer Layout**: Git status indicators moved to rightmost column, matching VS Code's layout. Removed file size and item count for cleaner appearance.
43
+ * **Quieter Startup**: Removed plugin "ready/loaded" status messages that cluttered the status bar on startup.
44
+
45
+ ### Internal
46
+
47
+ * Separated I/O from pure types in theme and grammar modules for better testability and future WASM compatibility.
48
+ * Fixed workspace crate dependencies for crates.io publishing.
49
+ * Improved install.sh reliability for containers and edge cases.
50
+
51
+ ---
52
+
3
53
  ## 0.1.83
4
54
 
5
55
  ### Breaking Changes
package/README.md CHANGED
@@ -241,6 +241,10 @@ Thanks for contributing!
241
241
 
242
242
  7. **LSP**: Ensure LSP interactions follow the correct lifecycle (e.g., `didOpen` must always precede other requests to avoid server-side errors). Use the appropriate existing helpers for this pattern.
243
243
 
244
+ 8. **Regenerate plugin types**: After modifying the plugin API, run `cargo test -p fresh-plugin-runtime write_fresh_dts_file -- --ignored`
245
+
246
+ 9. **Type check plugins**: Run `crates/fresh-editor/plugins/check-types.sh` (requires `tsc`)
247
+
244
248
  **Tip**: You can use tmux + send-keys + render-pane to script ad-hoc tests on the UI, for example when trying to reproduce an issue.
245
249
 
246
250
  ## Privacy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fresh-editor/fresh-editor",
3
- "version": "0.1.83",
3
+ "version": "0.1.87",
4
4
  "description": "A modern terminal-based text editor with plugin support",
5
5
  "repository": {
6
6
  "type": "git",
package/plugins/README.md CHANGED
@@ -69,3 +69,4 @@ For plugin development guides, see:
69
69
  - **API Reference:** [`docs/plugin-api.md`](../docs/plugin-api.md)
70
70
  - **Examples:** [`examples/README.md`](examples/README.md)
71
71
  - **Clangd Plugin:** [`clangd_support.md`](clangd_support.md)
72
+
@@ -551,7 +551,7 @@ async function renderReviewStream(): Promise<{ entries: TextPropertyEntry[], hig
551
551
  * Updates the buffer UI (text and highlights) based on current state.hunks
552
552
  */
553
553
  async function updateReviewUI() {
554
- if (state.reviewBufferId !== null) {
554
+ if (state.reviewBufferId != null) {
555
555
  const { entries, highlights } = await renderReviewStream();
556
556
  editor.setVirtualBufferContent(state.reviewBufferId, entries);
557
557
 
@@ -677,12 +677,12 @@ globalThis.on_viewport_changed = (data: any) => {
677
677
 
678
678
  const { oldSplitId, newSplitId, oldLineByteOffsets, newLineByteOffsets } = activeSideBySideState;
679
679
 
680
- if (data.split_id === oldSplitId && newLineByteOffsets.length > 0) {
680
+ if (data.splitId === oldSplitId && newLineByteOffsets.length > 0) {
681
681
  // OLD pane scrolled - find which line it's on and sync NEW pane to same line
682
682
  const lineNum = findLineForByte(oldLineByteOffsets, data.top_byte);
683
683
  const targetByte = newLineByteOffsets[Math.min(lineNum, newLineByteOffsets.length - 1)];
684
684
  (editor as any).setSplitScroll(newSplitId, targetByte);
685
- } else if (data.split_id === newSplitId && oldLineByteOffsets.length > 0) {
685
+ } else if (data.splitId === newSplitId && oldLineByteOffsets.length > 0) {
686
686
  // NEW pane scrolled - find which line it's on and sync OLD pane to same line
687
687
  const lineNum = findLineForByte(newLineByteOffsets, data.top_byte);
688
688
  const targetByte = oldLineByteOffsets[Math.min(lineNum, oldLineByteOffsets.length - 1)];
@@ -1100,7 +1100,7 @@ globalThis.review_drill_down = async () => {
1100
1100
  }));
1101
1101
 
1102
1102
  // Create source buffers (hidden from tabs, used by composite)
1103
- const oldBufferId = await editor.createVirtualBuffer({
1103
+ const oldResult = await editor.createVirtualBuffer({
1104
1104
  name: `*OLD:${h.file}*`,
1105
1105
  mode: "normal",
1106
1106
  readOnly: true,
@@ -1109,8 +1109,9 @@ globalThis.review_drill_down = async () => {
1109
1109
  editingDisabled: true,
1110
1110
  hiddenFromTabs: true
1111
1111
  });
1112
+ const oldBufferId = oldResult.bufferId;
1112
1113
 
1113
- const newBufferId = await editor.createVirtualBuffer({
1114
+ const newResult = await editor.createVirtualBuffer({
1114
1115
  name: `*NEW:${h.file}*`,
1115
1116
  mode: "normal",
1116
1117
  readOnly: true,
@@ -1119,6 +1120,7 @@ globalThis.review_drill_down = async () => {
1119
1120
  editingDisabled: true,
1120
1121
  hiddenFromTabs: true
1121
1122
  });
1123
+ const newBufferId = newResult.bufferId;
1122
1124
 
1123
1125
  // Convert hunks to composite buffer format (parse counts from git diff)
1124
1126
  const compositeHunks: TsCompositeHunk[] = fileHunks.map(fh => {
@@ -1130,10 +1132,10 @@ globalThis.review_drill_down = async () => {
1130
1132
  else if (line.startsWith(' ')) { oldCount++; newCount++; }
1131
1133
  }
1132
1134
  return {
1133
- old_start: fh.oldRange.start - 1, // Convert to 0-indexed
1134
- old_count: oldCount || 1,
1135
- new_start: fh.range.start - 1, // Convert to 0-indexed
1136
- new_count: newCount || 1
1135
+ oldStart: fh.oldRange.start - 1, // Convert to 0-indexed
1136
+ oldCount: oldCount || 1,
1137
+ newStart: fh.range.start - 1, // Convert to 0-indexed
1138
+ newCount: newCount || 1
1137
1139
  };
1138
1140
  });
1139
1141
 
@@ -1142,27 +1144,27 @@ globalThis.review_drill_down = async () => {
1142
1144
  name: `*Diff: ${h.file}*`,
1143
1145
  mode: "diff-view",
1144
1146
  layout: {
1145
- layout_type: "side-by-side",
1147
+ type: "side-by-side",
1146
1148
  ratios: [0.5, 0.5],
1147
- show_separator: true
1149
+ showSeparator: true
1148
1150
  },
1149
1151
  sources: [
1150
1152
  {
1151
- buffer_id: oldBufferId,
1153
+ bufferId: oldBufferId,
1152
1154
  label: "OLD (HEAD)",
1153
1155
  editable: false,
1154
1156
  style: {
1155
- remove_bg: [80, 40, 40],
1156
- gutter_style: "diff-markers"
1157
+ removeBg: [80, 40, 40],
1158
+ gutterStyle: "diff-markers"
1157
1159
  }
1158
1160
  },
1159
1161
  {
1160
- buffer_id: newBufferId,
1162
+ bufferId: newBufferId,
1161
1163
  label: "NEW (Working)",
1162
1164
  editable: false,
1163
1165
  style: {
1164
- add_bg: [40, 80, 40],
1165
- gutter_style: "diff-markers"
1166
+ addBg: [40, 80, 40],
1167
+ gutterStyle: "diff-markers"
1166
1168
  }
1167
1169
  }
1168
1170
  ],
@@ -1518,7 +1520,7 @@ globalThis.on_review_buffer_activated = (data: any) => {
1518
1520
  };
1519
1521
 
1520
1522
  globalThis.on_review_buffer_closed = (data: any) => {
1521
- if (data.buffer_id === state.reviewBufferId) stop_review_diff();
1523
+ if (data.buffer_id === state.reviewBufferId) globalThis.stop_review_diff();
1522
1524
  };
1523
1525
 
1524
1526
  // Side-by-side diff for current file using composite buffers
@@ -1663,7 +1665,7 @@ globalThis.side_by_side_diff_current_file = async () => {
1663
1665
  }));
1664
1666
 
1665
1667
  // Create source buffers (hidden from tabs, used by composite)
1666
- const oldBufferId = await editor.createVirtualBuffer({
1668
+ const oldResult = await editor.createVirtualBuffer({
1667
1669
  name: `*OLD:${filePath}*`,
1668
1670
  mode: "normal",
1669
1671
  readOnly: true,
@@ -1672,8 +1674,9 @@ globalThis.side_by_side_diff_current_file = async () => {
1672
1674
  editingDisabled: true,
1673
1675
  hiddenFromTabs: true
1674
1676
  });
1677
+ const oldBufferId = oldResult.bufferId;
1675
1678
 
1676
- const newBufferId = await editor.createVirtualBuffer({
1679
+ const newResult = await editor.createVirtualBuffer({
1677
1680
  name: `*NEW:${filePath}*`,
1678
1681
  mode: "normal",
1679
1682
  readOnly: true,
@@ -1682,13 +1685,14 @@ globalThis.side_by_side_diff_current_file = async () => {
1682
1685
  editingDisabled: true,
1683
1686
  hiddenFromTabs: true
1684
1687
  });
1688
+ const newBufferId = newResult.bufferId;
1685
1689
 
1686
1690
  // Convert hunks to composite buffer format
1687
1691
  const compositeHunks: TsCompositeHunk[] = fileHunks.map(h => ({
1688
- old_start: h.oldRange.start - 1, // Convert to 0-indexed
1689
- old_count: h.oldRange.end - h.oldRange.start + 1,
1690
- new_start: h.range.start - 1, // Convert to 0-indexed
1691
- new_count: h.range.end - h.range.start + 1
1692
+ oldStart: h.oldRange.start - 1, // Convert to 0-indexed
1693
+ oldCount: h.oldRange.end - h.oldRange.start + 1,
1694
+ newStart: h.range.start - 1, // Convert to 0-indexed
1695
+ newCount: h.range.end - h.range.start + 1
1692
1696
  }));
1693
1697
 
1694
1698
  // Create composite buffer with side-by-side layout
@@ -1696,27 +1700,27 @@ globalThis.side_by_side_diff_current_file = async () => {
1696
1700
  name: `*Diff: ${filePath}*`,
1697
1701
  mode: "diff-view",
1698
1702
  layout: {
1699
- layout_type: "side-by-side",
1703
+ type: "side-by-side",
1700
1704
  ratios: [0.5, 0.5],
1701
- show_separator: true
1705
+ showSeparator: true
1702
1706
  },
1703
1707
  sources: [
1704
1708
  {
1705
- buffer_id: oldBufferId,
1709
+ bufferId: oldBufferId,
1706
1710
  label: "OLD (HEAD)",
1707
1711
  editable: false,
1708
1712
  style: {
1709
- remove_bg: [80, 40, 40],
1710
- gutter_style: "diff-markers"
1713
+ removeBg: [80, 40, 40],
1714
+ gutterStyle: "diff-markers"
1711
1715
  }
1712
1716
  },
1713
1717
  {
1714
- buffer_id: newBufferId,
1718
+ bufferId: newBufferId,
1715
1719
  label: "NEW (Working)",
1716
1720
  editable: false,
1717
1721
  style: {
1718
- add_bg: [40, 80, 40],
1719
- gutter_style: "diff-markers"
1722
+ addBg: [40, 80, 40],
1723
+ gutterStyle: "diff-markers"
1720
1724
  }
1721
1725
  }
1722
1726
  ],
@@ -1746,10 +1750,10 @@ globalThis.side_by_side_diff_current_file = async () => {
1746
1750
  };
1747
1751
 
1748
1752
  // Register Modes and Commands
1749
- editor.registerCommand("%cmd.review_diff", "%cmd.review_diff_desc", "start_review_diff", "global");
1753
+ editor.registerCommand("%cmd.review_diff", "%cmd.review_diff_desc", "start_review_diff", null);
1750
1754
  editor.registerCommand("%cmd.stop_review_diff", "%cmd.stop_review_diff_desc", "stop_review_diff", "review-mode");
1751
1755
  editor.registerCommand("%cmd.refresh_review_diff", "%cmd.refresh_review_diff_desc", "review_refresh", "review-mode");
1752
- editor.registerCommand("%cmd.side_by_side_diff", "%cmd.side_by_side_diff_desc", "side_by_side_diff_current_file", "global");
1756
+ editor.registerCommand("%cmd.side_by_side_diff", "%cmd.side_by_side_diff_desc", "side_by_side_diff_current_file", null);
1753
1757
 
1754
1758
  // Review Comment Commands
1755
1759
  editor.registerCommand("%cmd.add_comment", "%cmd.add_comment_desc", "review_add_comment", "review-mode");
@@ -711,16 +711,16 @@ globalThis.calculator_open = async function (): Promise<void> {
711
711
 
712
712
  const entries = renderCalculator();
713
713
 
714
- state.bufferId = await editor.createVirtualBuffer({
714
+ const result = await editor.createVirtualBuffer({
715
715
  name: "*Calculator*",
716
716
  mode: "calculator",
717
- read_only: true,
717
+ readOnly: true,
718
718
  entries,
719
- show_line_numbers: false,
720
- show_cursors: false,
721
- editing_disabled: true,
719
+ showLineNumbers: false,
720
+ showCursors: false,
721
+ editingDisabled: true,
722
722
  });
723
-
723
+ state.bufferId = result.bufferId;
724
724
  state.splitId = editor.getActiveSplitId();
725
725
 
726
726
  editor.setStatus(editor.t("status.opened"));
@@ -767,4 +767,3 @@ editor.on("mouse_move", "onCalculatorMouseMove");
767
767
  // Register main command
768
768
  editor.registerCommand("%cmd.calculator", "%cmd.calculator_desc", "calculator_open", null);
769
769
 
770
- editor.setStatus(editor.t("status.loaded"));
@@ -251,7 +251,7 @@ editor.registerCommand(
251
251
  "%cmd.project_setup",
252
252
  "%cmd.project_setup_desc",
253
253
  "clangdProjectSetup",
254
- ""
254
+ null
255
255
  );
256
256
 
257
257
  globalThis.clangdOpenProjectConfig = function(): void {
@@ -287,17 +287,16 @@ editor.registerCommand(
287
287
  "%cmd.switch_source_header",
288
288
  "%cmd.switch_source_header_desc",
289
289
  "clangdSwitchSourceHeader",
290
- "normal"
290
+ null
291
291
  );
292
292
 
293
293
  editor.registerCommand(
294
294
  "%cmd.open_project_config",
295
295
  "%cmd.open_project_config_desc",
296
296
  "clangdOpenProjectConfig",
297
- "normal"
297
+ null
298
298
  );
299
299
 
300
- setClangdStatus(editor.t("status.plugin_loaded"));
301
300
 
302
301
  globalThis.onClangdCustomNotification = function(payload: {
303
302
  language: string;
@@ -285,23 +285,22 @@ editor.registerCommand(
285
285
  "%cmd.enable",
286
286
  "%cmd.enable_desc",
287
287
  "colorHighlighterEnable",
288
- "normal"
288
+ null
289
289
  );
290
290
 
291
291
  editor.registerCommand(
292
292
  "%cmd.disable",
293
293
  "%cmd.disable_desc",
294
294
  "colorHighlighterDisable",
295
- "normal"
295
+ null
296
296
  );
297
297
 
298
298
  editor.registerCommand(
299
299
  "%cmd.toggle",
300
300
  "%cmd.toggle_desc",
301
301
  "colorHighlighterToggle",
302
- "normal"
302
+ null
303
303
  );
304
304
 
305
305
  // Initialization
306
- editor.setStatus(editor.t("status.loaded"));
307
306
  editor.debug("Color Highlighter initialized - supports hex, rgb, hsl, and Rust Color::Rgb");
@@ -59,7 +59,8 @@
59
59
  "keyboard_report_all_keys_as_escape_codes": false,
60
60
  "quick_suggestions": true,
61
61
  "show_menu_bar": true,
62
- "show_tab_bar": true
62
+ "show_tab_bar": true,
63
+ "use_terminal_bg": false
63
64
  }
64
65
  },
65
66
  "file_explorer": {
@@ -349,6 +350,11 @@
349
350
  "description": "Whether the tab bar is visible by default.\nThe tab bar shows open files in each split pane.\nCan be toggled at runtime via command palette or keybinding.\nDefault: true",
350
351
  "type": "boolean",
351
352
  "default": true
353
+ },
354
+ "use_terminal_bg": {
355
+ "description": "Use the terminal's default background color instead of the theme's editor background.\nWhen enabled, the editor background inherits from the terminal emulator,\nallowing transparency or custom terminal backgrounds to show through.\nDefault: false",
356
+ "type": "boolean",
357
+ "default": false
352
358
  }
353
359
  }
354
360
  },
@@ -255,16 +255,15 @@ editor.registerCommand(
255
255
  "%cmd.show_diagnostics_panel",
256
256
  "%cmd.show_diagnostics_panel_desc",
257
257
  "show_diagnostics_panel",
258
- "normal"
258
+ null
259
259
  );
260
260
 
261
261
  editor.registerCommand(
262
262
  "%cmd.toggle_diagnostics_panel",
263
263
  "%cmd.toggle_diagnostics_panel_desc",
264
264
  "toggle_diagnostics_panel",
265
- "normal"
265
+ null
266
266
  );
267
267
 
268
268
  // Initialization
269
- editor.setStatus(editor.t("status.loaded"));
270
269
  editor.debug("Diagnostics Panel plugin initialized (using Finder abstraction)");
@@ -97,12 +97,12 @@ globalThis.show_virtual_buffer_demo = async () => {
97
97
  const bufferId = await editor.createVirtualBufferInSplit({
98
98
  name: "*Demo Diagnostics*",
99
99
  mode: "demo-list",
100
- read_only: true,
100
+ readOnly: true,
101
101
  entries: entries,
102
102
  ratio: 0.7, // Original pane takes 70%, demo buffer takes 30%
103
- panel_id: "demo-diagnostics",
104
- show_line_numbers: false,
105
- show_cursors: true,
103
+ panelId: "demo-diagnostics",
104
+ showLineNumbers: false,
105
+ showCursors: true,
106
106
  });
107
107
 
108
108
  editor.setStatus(`Created demo virtual buffer (ID: ${bufferId}) with ${entries.length} items - Press RET to jump to location`);
@@ -478,7 +478,7 @@ globalThis.show_git_blame = async function(): Promise<void> {
478
478
  }
479
479
 
480
480
  // Create virtual buffer with the file content
481
- const bufferId = await editor.createVirtualBufferInExistingSplit({
481
+ const result = await editor.createVirtualBufferInExistingSplit({
482
482
  name: bufferName,
483
483
  mode: "git-blame",
484
484
  readOnly: true,
@@ -489,9 +489,9 @@ globalThis.show_git_blame = async function(): Promise<void> {
489
489
  editingDisabled: true,
490
490
  });
491
491
 
492
- if (bufferId !== null) {
492
+ if (result !== null) {
493
493
  blameState.isOpen = true;
494
- blameState.bufferId = bufferId;
494
+ blameState.bufferId = result.bufferId;
495
495
 
496
496
  // Add virtual lines for blame headers (persistent state model)
497
497
  addBlameHeaders();
@@ -677,26 +677,25 @@ editor.registerCommand(
677
677
  "%cmd.git_blame",
678
678
  "%cmd.git_blame_desc",
679
679
  "show_git_blame",
680
- "normal"
680
+ null
681
681
  );
682
682
 
683
683
  editor.registerCommand(
684
684
  "%cmd.git_blame_close",
685
685
  "%cmd.git_blame_close_desc",
686
686
  "git_blame_close",
687
- "normal"
687
+ null
688
688
  );
689
689
 
690
690
  editor.registerCommand(
691
691
  "%cmd.git_blame_go_back",
692
692
  "%cmd.git_blame_go_back_desc",
693
693
  "git_blame_go_back",
694
- "normal"
694
+ null
695
695
  );
696
696
 
697
697
  // =============================================================================
698
698
  // Plugin Initialization
699
699
  // =============================================================================
700
700
 
701
- editor.setStatus(editor.t("status.ready"));
702
701
  editor.debug("Git Blame plugin initialized - Use 'Git Blame' command to open");
@@ -1,4 +1,4 @@
1
- /// <reference path="../types/fresh.d.ts" />
1
+ /// <reference path="./lib/fresh.d.ts" />
2
2
  const editor = getEditor();
3
3
 
4
4
  /**
@@ -133,8 +133,9 @@ async function refreshGitExplorerDecorations() {
133
133
  } else {
134
134
  editor.setFileExplorerDecorations(NAMESPACE, decorations);
135
135
  }
136
- } catch (_err) {
136
+ } catch (err) {
137
137
  editor.clearFileExplorerDecorations(NAMESPACE);
138
+ throw err;
138
139
  } finally {
139
140
  refreshInFlight = false;
140
141
  }
@@ -73,4 +73,3 @@ editor.registerCommand(
73
73
  );
74
74
 
75
75
  editor.debug("Git Find File plugin loaded (using Finder abstraction)");
76
- editor.setStatus(editor.t("status.ready"));
@@ -71,4 +71,3 @@ 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)");
74
- editor.setStatus(editor.t("status.ready"));
@@ -458,7 +458,7 @@ editor.registerCommand(
458
458
  "%cmd.refresh",
459
459
  "%cmd.refresh_desc",
460
460
  "git_gutter_refresh",
461
- "normal"
461
+ null
462
462
  );
463
463
 
464
464
  // Initialize for the current buffer
@@ -474,4 +474,3 @@ if (initPath && initPath !== "") {
474
474
  }
475
475
 
476
476
  editor.debug("Git Gutter plugin loaded");
477
- editor.setStatus(editor.t("status.ready"));
@@ -763,7 +763,7 @@ globalThis.show_git_log = async function(): Promise<void> {
763
763
  gitLogState.cachedContent = entriesToContent(entries);
764
764
 
765
765
  // Create virtual buffer in the current split (replacing current buffer)
766
- const bufferId = await editor.createVirtualBufferInExistingSplit({
766
+ const result = await editor.createVirtualBufferInExistingSplit({
767
767
  name: "*Git Log*",
768
768
  mode: "git-log",
769
769
  readOnly: true,
@@ -774,9 +774,9 @@ globalThis.show_git_log = async function(): Promise<void> {
774
774
  editingDisabled: true,
775
775
  });
776
776
 
777
- if (bufferId !== null) {
777
+ if (result !== null) {
778
778
  gitLogState.isOpen = true;
779
- gitLogState.bufferId = bufferId;
779
+ gitLogState.bufferId = result.bufferId;
780
780
 
781
781
  // Apply syntax highlighting
782
782
  applyGitLogHighlighting();
@@ -897,7 +897,7 @@ globalThis.git_log_show_commit = async function(): Promise<void> {
897
897
  commitDetailState.cachedContent = entriesToContent(entries);
898
898
 
899
899
  // Create virtual buffer in the current split (replacing git log view)
900
- const bufferId = await editor.createVirtualBufferInExistingSplit({
900
+ const result = await editor.createVirtualBufferInExistingSplit({
901
901
  name: `*Commit: ${commit.shortHash}*`,
902
902
  mode: "git-commit-detail",
903
903
  readOnly: true,
@@ -908,9 +908,9 @@ globalThis.git_log_show_commit = async function(): Promise<void> {
908
908
  editingDisabled: true,
909
909
  });
910
910
 
911
- if (bufferId !== null) {
911
+ if (result !== null) {
912
912
  commitDetailState.isOpen = true;
913
- commitDetailState.bufferId = bufferId;
913
+ commitDetailState.bufferId = result.bufferId;
914
914
  commitDetailState.splitId = gitLogState.splitId;
915
915
  commitDetailState.commit = commit;
916
916
 
@@ -1210,7 +1210,7 @@ globalThis.git_commit_detail_open_file = async function(): Promise<void> {
1210
1210
  }
1211
1211
 
1212
1212
  // Create a read-only virtual buffer with the file content
1213
- const bufferId = await editor.createVirtualBufferInExistingSplit({
1213
+ const result = await editor.createVirtualBufferInExistingSplit({
1214
1214
  name: `${file} @ ${commit.shortHash}`,
1215
1215
  mode: "git-file-view",
1216
1216
  readOnly: true,
@@ -1221,16 +1221,16 @@ globalThis.git_commit_detail_open_file = async function(): Promise<void> {
1221
1221
  editingDisabled: true,
1222
1222
  });
1223
1223
 
1224
- if (bufferId !== null) {
1224
+ if (result !== null) {
1225
1225
  // Track file view state so we can navigate back
1226
1226
  fileViewState.isOpen = true;
1227
- fileViewState.bufferId = bufferId;
1227
+ fileViewState.bufferId = result.bufferId;
1228
1228
  fileViewState.splitId = commitDetailState.splitId;
1229
1229
  fileViewState.filePath = file;
1230
1230
  fileViewState.commitHash = commit.hash;
1231
1231
 
1232
1232
  // Apply syntax highlighting based on file type
1233
- applyFileViewHighlighting(bufferId, content, file);
1233
+ applyFileViewHighlighting(result.bufferId, content, file);
1234
1234
 
1235
1235
  const targetLine = line || 1;
1236
1236
  editor.setStatus(editor.t("status.file_view_ready", { file, hash: commit.shortHash, line: String(targetLine) }));
@@ -1253,26 +1253,25 @@ editor.registerCommand(
1253
1253
  "%cmd.git_log",
1254
1254
  "%cmd.git_log_desc",
1255
1255
  "show_git_log",
1256
- "normal"
1256
+ null
1257
1257
  );
1258
1258
 
1259
1259
  editor.registerCommand(
1260
1260
  "%cmd.git_log_close",
1261
1261
  "%cmd.git_log_close_desc",
1262
1262
  "git_log_close",
1263
- "normal"
1263
+ null
1264
1264
  );
1265
1265
 
1266
1266
  editor.registerCommand(
1267
1267
  "%cmd.git_log_refresh",
1268
1268
  "%cmd.git_log_refresh_desc",
1269
1269
  "git_log_refresh",
1270
- "normal"
1270
+ null
1271
1271
  );
1272
1272
 
1273
1273
  // =============================================================================
1274
1274
  // Plugin Initialization
1275
1275
  // =============================================================================
1276
1276
 
1277
- editor.setStatus(editor.t("status.ready", { count: "0" }));
1278
1277
  editor.debug("Git Log plugin initialized - Use 'Git Log' command to open");