@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 +50 -0
- package/README.md +4 -0
- package/package.json +1 -1
- package/plugins/README.md +1 -0
- package/plugins/audit_mode.ts +38 -34
- package/plugins/calculator.ts +6 -7
- package/plugins/clangd_support.ts +3 -4
- package/plugins/color_highlighter.ts +3 -4
- package/plugins/config-schema.json +7 -1
- package/plugins/diagnostics_panel.ts +2 -3
- package/plugins/examples/virtual_buffer_demo.ts +4 -4
- package/plugins/git_blame.ts +6 -7
- package/plugins/git_explorer.ts +3 -2
- package/plugins/git_find_file.ts +0 -1
- package/plugins/git_grep.ts +0 -1
- package/plugins/git_gutter.ts +1 -2
- package/plugins/git_log.ts +13 -14
- package/plugins/java-lsp.ts +65 -0
- package/plugins/latex-lsp.ts +65 -0
- package/plugins/lib/finder.ts +32 -32
- package/plugins/lib/fresh.d.ts +439 -21
- package/plugins/lib/panel-manager.ts +7 -7
- package/plugins/lib/search-utils.ts +13 -13
- package/plugins/lib/virtual-buffer-factory.ts +16 -14
- package/plugins/live_grep.ts +0 -1
- package/plugins/markdown_compose.ts +4 -5
- package/plugins/marksman-lsp.ts +65 -0
- package/plugins/merge_conflict.ts +23 -24
- package/plugins/path_complete.ts +0 -1
- package/plugins/search_replace.ts +6 -7
- package/plugins/templ-lsp.ts +65 -0
- package/plugins/theme_editor.ts +6 -6
- package/plugins/todo_highlighter.ts +0 -1
- package/plugins/vi_mode.i18n.json +39 -13
- package/plugins/vi_mode.ts +73 -25
- package/plugins/welcome.ts +0 -1
- package/plugins/zig-lsp.ts +65 -0
package/plugins/vi_mode.ts
CHANGED
|
@@ -795,7 +795,7 @@ globalThis.vi_visual_toggle_line = function (): void {
|
|
|
795
795
|
};
|
|
796
796
|
|
|
797
797
|
// Enter visual block mode (Ctrl-v)
|
|
798
|
-
globalThis.vi_visual_block = function (): void {
|
|
798
|
+
globalThis.vi_visual_block = async function (): Promise<void> {
|
|
799
799
|
// Store anchor position for block selection
|
|
800
800
|
state.visualAnchor = editor.getCursorPosition();
|
|
801
801
|
|
|
@@ -803,7 +803,7 @@ globalThis.vi_visual_block = function (): void {
|
|
|
803
803
|
const cursorPos = editor.getCursorPosition();
|
|
804
804
|
if (cursorPos !== null) {
|
|
805
805
|
const line = editor.getCursorLine() ?? 1;
|
|
806
|
-
const lineStart = editor.getLineStartPosition(line);
|
|
806
|
+
const lineStart = await editor.getLineStartPosition(line);
|
|
807
807
|
const col = lineStart !== null ? cursorPos - lineStart : 0;
|
|
808
808
|
state.visualBlockAnchor = { line, col };
|
|
809
809
|
}
|
|
@@ -1561,11 +1561,18 @@ editor.defineMode("vi-normal", null, [
|
|
|
1561
1561
|
|
|
1562
1562
|
// Command mode
|
|
1563
1563
|
[":", "vi_command_mode"],
|
|
1564
|
+
|
|
1565
|
+
// Pass through to standard editor shortcuts
|
|
1566
|
+
["C-p", "command_palette"],
|
|
1567
|
+
["C-q", "quit"],
|
|
1564
1568
|
], true); // read_only = true to prevent character insertion
|
|
1565
1569
|
|
|
1566
1570
|
// Define vi-insert mode - only Escape is special, other keys insert text
|
|
1567
1571
|
editor.defineMode("vi-insert", null, [
|
|
1568
1572
|
["Escape", "vi_escape"],
|
|
1573
|
+
// Pass through to standard editor shortcuts
|
|
1574
|
+
["C-p", "command_palette"],
|
|
1575
|
+
["C-q", "quit"],
|
|
1569
1576
|
], false); // read_only = false to allow normal typing
|
|
1570
1577
|
|
|
1571
1578
|
// Define vi-find-char mode - binds all printable chars to the handler
|
|
@@ -1769,6 +1776,10 @@ editor.defineMode("vi-visual", null, [
|
|
|
1769
1776
|
// Exit
|
|
1770
1777
|
["Escape", "vi_vis_escape"],
|
|
1771
1778
|
["v", "vi_vis_escape"], // v again exits visual mode
|
|
1779
|
+
|
|
1780
|
+
// Pass through to standard editor shortcuts
|
|
1781
|
+
["C-p", "command_palette"],
|
|
1782
|
+
["C-q", "quit"],
|
|
1772
1783
|
], true);
|
|
1773
1784
|
|
|
1774
1785
|
// Define vi-visual-line mode (line-wise)
|
|
@@ -1803,6 +1814,10 @@ editor.defineMode("vi-visual-line", null, [
|
|
|
1803
1814
|
// Exit
|
|
1804
1815
|
["Escape", "vi_vis_escape"],
|
|
1805
1816
|
["V", "vi_vis_escape"], // V again exits visual-line mode
|
|
1817
|
+
|
|
1818
|
+
// Pass through to standard editor shortcuts
|
|
1819
|
+
["C-p", "command_palette"],
|
|
1820
|
+
["C-q", "quit"],
|
|
1806
1821
|
], true);
|
|
1807
1822
|
|
|
1808
1823
|
// Define vi-visual-block mode (column/block selection)
|
|
@@ -1841,6 +1856,10 @@ editor.defineMode("vi-visual-block", null, [
|
|
|
1841
1856
|
// Exit
|
|
1842
1857
|
["Escape", "vi_vblock_escape"],
|
|
1843
1858
|
["C-v", "vi_vblock_escape"], // Ctrl-v again exits visual-block mode
|
|
1859
|
+
|
|
1860
|
+
// Pass through to standard editor shortcuts
|
|
1861
|
+
["C-p", "command_palette"],
|
|
1862
|
+
["C-q", "quit"],
|
|
1844
1863
|
], true);
|
|
1845
1864
|
|
|
1846
1865
|
// ============================================================================
|
|
@@ -2177,31 +2196,62 @@ async function executeCommand(
|
|
|
2177
2196
|
switch (command) {
|
|
2178
2197
|
case "write": {
|
|
2179
2198
|
// :w - save current file
|
|
2180
|
-
// :w filename - save
|
|
2199
|
+
// :w filename - save to specified filename
|
|
2181
2200
|
if (args) {
|
|
2182
|
-
|
|
2201
|
+
const bufferId = editor.getActiveBufferId();
|
|
2202
|
+
// Resolve path (could be relative or absolute)
|
|
2203
|
+
const path = args.startsWith("/") ? args : `${editor.getCwd()}/${args}`;
|
|
2204
|
+
editor.saveBufferToPath(bufferId, path);
|
|
2205
|
+
return { message: editor.t("status.file_saved") };
|
|
2183
2206
|
}
|
|
2184
2207
|
editor.executeAction("save");
|
|
2185
2208
|
return { message: editor.t("status.file_saved") };
|
|
2186
2209
|
}
|
|
2187
2210
|
|
|
2188
2211
|
case "quit": {
|
|
2189
|
-
// :q - quit (
|
|
2190
|
-
// :q! - force quit (discard changes)
|
|
2191
|
-
|
|
2192
|
-
|
|
2212
|
+
// :q - quit editor (like vim)
|
|
2213
|
+
// :q! - force quit (discard unsaved changes)
|
|
2214
|
+
if (force) {
|
|
2215
|
+
editor.executeAction("force_quit");
|
|
2216
|
+
return {};
|
|
2217
|
+
}
|
|
2218
|
+
// Check ALL buffers for unsaved changes
|
|
2219
|
+
const buffers = editor.listBuffers() as Array<{ id: number; modified: boolean }>;
|
|
2220
|
+
const hasModified = buffers.some((b) => b.modified);
|
|
2221
|
+
if (hasModified) {
|
|
2193
2222
|
return { error: editor.t("error.no_write_since_change", { cmd: ":q!" }) };
|
|
2194
2223
|
}
|
|
2195
|
-
editor.executeAction("
|
|
2224
|
+
editor.executeAction("force_quit");
|
|
2196
2225
|
return {};
|
|
2197
2226
|
}
|
|
2198
2227
|
|
|
2199
2228
|
case "wq":
|
|
2200
2229
|
case "xit":
|
|
2201
2230
|
case "exit": {
|
|
2202
|
-
// :wq or :x - save and quit
|
|
2203
|
-
|
|
2204
|
-
editor.
|
|
2231
|
+
// :wq or :x - save current buffer and quit
|
|
2232
|
+
// :wq filename - save to filename and quit
|
|
2233
|
+
const wqBufferId = editor.getActiveBufferId();
|
|
2234
|
+
|
|
2235
|
+
if (args) {
|
|
2236
|
+
// Save to specified filename
|
|
2237
|
+
const path = args.startsWith("/") ? args : `${editor.getCwd()}/${args}`;
|
|
2238
|
+
editor.saveBufferToPath(wqBufferId, path);
|
|
2239
|
+
} else {
|
|
2240
|
+
// Save to existing path
|
|
2241
|
+
const wqPath = editor.getBufferPath(wqBufferId);
|
|
2242
|
+
if (!wqPath) {
|
|
2243
|
+
return { error: editor.t("error.no_file_name") };
|
|
2244
|
+
}
|
|
2245
|
+
editor.executeAction("save");
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
// Check if any OTHER buffers have unsaved changes
|
|
2249
|
+
const allBuffers = editor.listBuffers() as Array<{ id: number; modified: boolean }>;
|
|
2250
|
+
const otherModified = allBuffers.some((b: { id: number; modified: boolean }) => b.id !== wqBufferId && b.modified);
|
|
2251
|
+
if (otherModified) {
|
|
2252
|
+
return { error: editor.t("error.other_buffers_modified", { cmd: ":wqa" }) };
|
|
2253
|
+
}
|
|
2254
|
+
editor.executeAction("force_quit");
|
|
2205
2255
|
return {};
|
|
2206
2256
|
}
|
|
2207
2257
|
|
|
@@ -2215,16 +2265,15 @@ async function executeCommand(
|
|
|
2215
2265
|
// :qa - quit all
|
|
2216
2266
|
// :qa! - force quit all
|
|
2217
2267
|
if (force) {
|
|
2218
|
-
editor.executeAction("
|
|
2268
|
+
editor.executeAction("force_quit");
|
|
2219
2269
|
} else {
|
|
2220
2270
|
// Check if any buffer is modified
|
|
2221
|
-
const
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
}
|
|
2271
|
+
const allBufs = editor.listBuffers() as Array<{ id: number; modified: boolean }>;
|
|
2272
|
+
const anyModified = allBufs.some((b) => b.modified);
|
|
2273
|
+
if (anyModified) {
|
|
2274
|
+
return { error: editor.t("error.no_write_since_change", { cmd: ":qa!" }) };
|
|
2226
2275
|
}
|
|
2227
|
-
editor.executeAction("
|
|
2276
|
+
editor.executeAction("force_quit");
|
|
2228
2277
|
}
|
|
2229
2278
|
return {};
|
|
2230
2279
|
}
|
|
@@ -2232,7 +2281,7 @@ async function executeCommand(
|
|
|
2232
2281
|
case "wqall": {
|
|
2233
2282
|
// :wqa or :xa - save all and quit
|
|
2234
2283
|
editor.executeAction("save_all");
|
|
2235
|
-
editor.executeAction("
|
|
2284
|
+
editor.executeAction("force_quit");
|
|
2236
2285
|
return {};
|
|
2237
2286
|
}
|
|
2238
2287
|
|
|
@@ -2307,7 +2356,7 @@ async function executeCommand(
|
|
|
2307
2356
|
if (!force && editor.isBufferModified(bufferId)) {
|
|
2308
2357
|
return { error: editor.t("error.no_write_since_change", { cmd: ":bd!" }) };
|
|
2309
2358
|
}
|
|
2310
|
-
editor.executeAction("
|
|
2359
|
+
editor.executeAction("close");
|
|
2311
2360
|
return {};
|
|
2312
2361
|
}
|
|
2313
2362
|
|
|
@@ -2421,7 +2470,7 @@ async function executeCommand(
|
|
|
2421
2470
|
if (!force && editor.isBufferModified(bufferId)) {
|
|
2422
2471
|
return { error: editor.t("error.no_write_since_change", { cmd: ":close!" }) };
|
|
2423
2472
|
}
|
|
2424
|
-
editor.executeAction("
|
|
2473
|
+
editor.executeAction("close");
|
|
2425
2474
|
return {};
|
|
2426
2475
|
}
|
|
2427
2476
|
|
|
@@ -2442,7 +2491,7 @@ async function executeCommand(
|
|
|
2442
2491
|
if (!force && editor.isBufferModified(bufferId)) {
|
|
2443
2492
|
return { error: editor.t("error.no_write_since_change", { cmd: ":tabclose!" }) };
|
|
2444
2493
|
}
|
|
2445
|
-
editor.executeAction("
|
|
2494
|
+
editor.executeAction("close");
|
|
2446
2495
|
return {};
|
|
2447
2496
|
}
|
|
2448
2497
|
|
|
@@ -2747,11 +2796,10 @@ editor.registerCommand(
|
|
|
2747
2796
|
"%cmd.toggle_vi_mode",
|
|
2748
2797
|
"%cmd.toggle_vi_mode_desc",
|
|
2749
2798
|
"vi_mode_toggle",
|
|
2750
|
-
|
|
2799
|
+
null, // Always visible - needed to enable vi mode in the first place
|
|
2751
2800
|
);
|
|
2752
2801
|
|
|
2753
2802
|
// ============================================================================
|
|
2754
2803
|
// Initialization
|
|
2755
2804
|
// ============================================================================
|
|
2756
2805
|
|
|
2757
|
-
editor.setStatus(editor.t("status.loaded"));
|
package/plugins/welcome.ts
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/// <reference path="./lib/fresh.d.ts" />
|
|
2
|
+
// Provides installation help when zls (Zig LSP) is not found
|
|
3
|
+
const editor = getEditor();
|
|
4
|
+
|
|
5
|
+
interface LspServerErrorData {
|
|
6
|
+
language: string;
|
|
7
|
+
server_command: string;
|
|
8
|
+
error_type: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface LspStatusClickedData {
|
|
13
|
+
language: string;
|
|
14
|
+
has_error: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ActionPopupResultData {
|
|
18
|
+
popup_id: string;
|
|
19
|
+
action_id: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const INSTALL_URL = "https://github.com/zigtools/zls#installation";
|
|
23
|
+
let zigLspError: { serverCommand: string; message: string } | null = null;
|
|
24
|
+
|
|
25
|
+
globalThis.on_zig_lsp_server_error = function (data: LspServerErrorData): void {
|
|
26
|
+
if (data.language !== "zig") return;
|
|
27
|
+
zigLspError = { serverCommand: data.server_command, message: data.message };
|
|
28
|
+
if (data.error_type === "not_found") {
|
|
29
|
+
editor.setStatus(`Zig LSP '${data.server_command}' not found. Click status bar for help.`);
|
|
30
|
+
} else {
|
|
31
|
+
editor.setStatus(`Zig LSP error: ${data.message}`);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
editor.on("lsp_server_error", "on_zig_lsp_server_error");
|
|
35
|
+
|
|
36
|
+
globalThis.on_zig_lsp_status_clicked = function (data: LspStatusClickedData): void {
|
|
37
|
+
if (data.language !== "zig" || !zigLspError) return;
|
|
38
|
+
editor.showActionPopup({
|
|
39
|
+
id: "zig-lsp-help",
|
|
40
|
+
title: "Zig Language Server Not Found",
|
|
41
|
+
message: `Install zls for code completion and diagnostics. Visit ${INSTALL_URL}`,
|
|
42
|
+
actions: [
|
|
43
|
+
{ id: "copy_url", label: "Copy install URL" },
|
|
44
|
+
{ id: "disable", label: "Disable Zig LSP" },
|
|
45
|
+
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
46
|
+
],
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
editor.on("lsp_status_clicked", "on_zig_lsp_status_clicked");
|
|
50
|
+
|
|
51
|
+
globalThis.on_zig_lsp_action_result = function (data: ActionPopupResultData): void {
|
|
52
|
+
if (data.popup_id !== "zig-lsp-help") return;
|
|
53
|
+
switch (data.action_id) {
|
|
54
|
+
case "copy_url":
|
|
55
|
+
editor.setClipboard(INSTALL_URL);
|
|
56
|
+
editor.setStatus("Copied: " + INSTALL_URL);
|
|
57
|
+
break;
|
|
58
|
+
case "disable":
|
|
59
|
+
editor.disableLspForLanguage("zig");
|
|
60
|
+
editor.setStatus("Zig LSP disabled");
|
|
61
|
+
zigLspError = null;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
editor.on("action_popup_result", "on_zig_lsp_action_result");
|