@fresh-editor/fresh-editor 0.2.25 → 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 +216 -0
- package/README.md +6 -0
- package/package.json +1 -1
- package/plugins/astro-lsp.ts +6 -12
- package/plugins/audit_mode.i18n.json +14 -14
- package/plugins/audit_mode.ts +182 -146
- 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 +79 -6
- 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 +1903 -0
- package/plugins/devcontainer.i18n.json +1472 -0
- package/plugins/devcontainer.ts +2793 -0
- 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.i18n.json +14 -42
- package/plugins/git_log.ts +19 -9
- 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 +603 -0
- package/plugins/lua-lsp.ts +15 -22
- package/plugins/markdown_compose.ts +132 -128
- 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 +126 -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 +98 -14
- package/plugins/theme_editor.ts +156 -209
- 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/themes/high-contrast.json +2 -2
- package/themes/nord.json +4 -0
- package/themes/solarized-dark.json +4 -0
package/plugins/lua-lsp.ts
CHANGED
|
@@ -49,7 +49,10 @@ let luaLspError: { serverCommand: string; message: string } | null = null;
|
|
|
49
49
|
/**
|
|
50
50
|
* Handle LSP server errors for Lua
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// Register hook for LSP server errors
|
|
55
|
+
editor.on("lsp_server_error", (data) => {
|
|
53
56
|
// Only handle Lua language errors
|
|
54
57
|
if (data.language !== "lua") {
|
|
55
58
|
return;
|
|
@@ -71,18 +74,15 @@ function on_lua_lsp_server_error(data: LspServerErrorData): void {
|
|
|
71
74
|
} else {
|
|
72
75
|
editor.setStatus(`Lua LSP error: ${data.message}`);
|
|
73
76
|
}
|
|
74
|
-
}
|
|
75
|
-
registerHandler("on_lua_lsp_server_error", on_lua_lsp_server_error);
|
|
76
|
-
|
|
77
|
-
// Register hook for LSP server errors
|
|
78
|
-
editor.on("lsp_server_error", "on_lua_lsp_server_error");
|
|
77
|
+
});
|
|
79
78
|
|
|
80
79
|
/**
|
|
81
80
|
* Handle status bar click when there's a Lua LSP error
|
|
82
81
|
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// Register hook for status bar clicks
|
|
85
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
86
86
|
// Only handle Lua language clicks when there's an error
|
|
87
87
|
if (data.language !== "lua" || !luaLspError) {
|
|
88
88
|
return;
|
|
@@ -103,18 +103,15 @@ function on_lua_lsp_status_clicked(
|
|
|
103
103
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
104
104
|
],
|
|
105
105
|
});
|
|
106
|
-
}
|
|
107
|
-
registerHandler("on_lua_lsp_status_clicked", on_lua_lsp_status_clicked);
|
|
108
|
-
|
|
109
|
-
// Register hook for status bar clicks
|
|
110
|
-
editor.on("lsp_status_clicked", "on_lua_lsp_status_clicked");
|
|
106
|
+
});
|
|
111
107
|
|
|
112
108
|
/**
|
|
113
109
|
* Handle action popup results for Lua LSP help
|
|
114
110
|
*/
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
// Register hook for action popup results
|
|
114
|
+
editor.on("action_popup_result", (data) => {
|
|
118
115
|
// Only handle our popup
|
|
119
116
|
if (data.popup_id !== "lua-lsp-help") {
|
|
120
117
|
return;
|
|
@@ -152,10 +149,6 @@ function on_lua_lsp_action_result(
|
|
|
152
149
|
default:
|
|
153
150
|
editor.debug(`lua-lsp: Unknown action: ${data.action_id}`);
|
|
154
151
|
}
|
|
155
|
-
}
|
|
156
|
-
registerHandler("on_lua_lsp_action_result", on_lua_lsp_action_result);
|
|
157
|
-
|
|
158
|
-
// Register hook for action popup results
|
|
159
|
-
editor.on("action_popup_result", "on_lua_lsp_action_result");
|
|
152
|
+
});
|
|
160
153
|
|
|
161
154
|
editor.debug("lua-lsp: Plugin loaded");
|
|
@@ -966,6 +966,23 @@ function concealedText(text: string): string {
|
|
|
966
966
|
|
|
967
967
|
const MIN_COL_W = 3;
|
|
968
968
|
|
|
969
|
+
/**
|
|
970
|
+
* Return the effective compose width for layout: the configured compose
|
|
971
|
+
* width clamped to the available viewport width.
|
|
972
|
+
*
|
|
973
|
+
* When `config.composeWidth` is explicitly set (e.g. 80) but the editor
|
|
974
|
+
* content area is smaller (e.g. after the File Explorer sidebar opens),
|
|
975
|
+
* using the configured value verbatim overflows the viewport. The Rust
|
|
976
|
+
* render layer already clamps the compose area the same way in
|
|
977
|
+
* `calculate_compose_layout`; plugin-side computations (table column
|
|
978
|
+
* allocation, soft-wrap width) need to match.
|
|
979
|
+
*/
|
|
980
|
+
function effectiveComposeWidth(viewportWidth: number): number {
|
|
981
|
+
const cw = config.composeWidth;
|
|
982
|
+
if (cw == null) return viewportWidth;
|
|
983
|
+
return Math.min(cw, viewportWidth);
|
|
984
|
+
}
|
|
985
|
+
|
|
969
986
|
/**
|
|
970
987
|
* W3C-inspired column width distribution.
|
|
971
988
|
* Constrains columns to fit within `available` width, distributing space
|
|
@@ -1142,6 +1159,26 @@ function processLineConceals(
|
|
|
1142
1159
|
if (lineContent[i] === '|') pipePositions.push(i);
|
|
1143
1160
|
}
|
|
1144
1161
|
|
|
1162
|
+
// Precompute which cells will be truncated. Per-character conceals
|
|
1163
|
+
// that land inside a truncated cell must be suppressed — the cell-
|
|
1164
|
+
// wide truncate conceal already renders the replacement. When both
|
|
1165
|
+
// fire, the per-char conceal at the cell's first byte emits its
|
|
1166
|
+
// replacement, and the cell-wide conceal emits its replacement one
|
|
1167
|
+
// byte later, producing a cell one character wider than allocated.
|
|
1168
|
+
const truncatedCellCharRanges: Array<{start: number; end: number}> = [];
|
|
1169
|
+
if (!cursorStrictlyOnLine && colWidths) {
|
|
1170
|
+
for (let ci = 0; ci < Math.min(cells.length, colWidths.length); ci++) {
|
|
1171
|
+
const cellText = concealedText(cells[ci]);
|
|
1172
|
+
if (cellText.length > colWidths[ci]) {
|
|
1173
|
+
const prevPipe = pipePositions[ci];
|
|
1174
|
+
const nextPipe = pipePositions[ci + 1];
|
|
1175
|
+
if (prevPipe !== undefined && nextPipe !== undefined) {
|
|
1176
|
+
truncatedCellCharRanges.push({ start: prevPipe + 1, end: nextPipe });
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1145
1182
|
// Track which pipe index we're on (0 = leading pipe)
|
|
1146
1183
|
let pipeIdx = 0;
|
|
1147
1184
|
for (let i = 0; i < lineContent.length; i++) {
|
|
@@ -1161,11 +1198,15 @@ function processLineConceals(
|
|
|
1161
1198
|
const allocatedWidth = colWidths[cellIdx];
|
|
1162
1199
|
|
|
1163
1200
|
if (cellWidth > allocatedWidth) {
|
|
1164
|
-
// Truncate: conceal entire cell content and replace with truncated text
|
|
1201
|
+
// Truncate: conceal entire cell content and replace with truncated text.
|
|
1202
|
+
// Separator rows use box-drawing ─ to match the non-truncated path
|
|
1203
|
+
// (per-char conceals replace source `-` with ─ and pad via pipe replacement).
|
|
1165
1204
|
const prevPipeCharPos = pipePositions[pipeIdx - 1];
|
|
1166
1205
|
const cellByteStart = charToByte(lineContent, prevPipeCharPos + 1, byteStart);
|
|
1167
1206
|
const cellByteEnd = pipeByte;
|
|
1168
|
-
const truncated =
|
|
1207
|
+
const truncated = isSeparator
|
|
1208
|
+
? '─'.repeat(allocatedWidth)
|
|
1209
|
+
: cellText.slice(0, allocatedWidth - 1) + '-';
|
|
1169
1210
|
editor.addConceal(bufferId, "md-syntax", cellByteStart, cellByteEnd, truncated);
|
|
1170
1211
|
truncatedByteRanges.push({start: cellByteStart, end: cellByteEnd});
|
|
1171
1212
|
} else {
|
|
@@ -1188,6 +1229,10 @@ function processLineConceals(
|
|
|
1188
1229
|
}
|
|
1189
1230
|
pipeIdx++;
|
|
1190
1231
|
} else if (isSeparator && lineContent[i] === '-') {
|
|
1232
|
+
// Skip per-character conceals that land inside a truncated cell;
|
|
1233
|
+
// the cell-wide truncate conceal already handles the rendering.
|
|
1234
|
+
const inTruncated = truncatedCellCharRanges.some(r => i >= r.start && i < r.end);
|
|
1235
|
+
if (inTruncated) continue;
|
|
1191
1236
|
const db = charToByte(lineContent, i, byteStart);
|
|
1192
1237
|
editor.addConceal(bufferId, "md-syntax", db, charToByte(lineContent, i + 1, byteStart), "─");
|
|
1193
1238
|
}
|
|
@@ -1292,7 +1337,7 @@ function processLineSoftBreaks(
|
|
|
1292
1337
|
|
|
1293
1338
|
const viewport = editor.getViewport();
|
|
1294
1339
|
if (!viewport) return;
|
|
1295
|
-
const width =
|
|
1340
|
+
const width = effectiveComposeWidth(viewport.width);
|
|
1296
1341
|
|
|
1297
1342
|
// Parse this single line to get block structure
|
|
1298
1343
|
const blocks = parseMarkdownBlocks(lineContent);
|
|
@@ -1516,9 +1561,12 @@ function processTableAlignment(
|
|
|
1516
1561
|
mergeWith(widthMap.get(ln)!.maxW);
|
|
1517
1562
|
}
|
|
1518
1563
|
|
|
1519
|
-
// Compute allocated widths constrained to viewport
|
|
1564
|
+
// Compute allocated widths constrained to viewport. Clamp the
|
|
1565
|
+
// configured compose width to the actual viewport — otherwise a
|
|
1566
|
+
// large configured width overflows when the editor area shrinks
|
|
1567
|
+
// (e.g. when the File Explorer sidebar opens).
|
|
1520
1568
|
const viewport = editor.getViewport();
|
|
1521
|
-
const composeW =
|
|
1569
|
+
const composeW = effectiveComposeWidth(viewport ? viewport.width : 80);
|
|
1522
1570
|
const numCols = merged.length;
|
|
1523
1571
|
const available = composeW - (numCols + 1); // subtract pipe/box-drawing characters
|
|
1524
1572
|
const allocated = distributeColumnWidths(merged, available);
|
|
@@ -1562,15 +1610,40 @@ function processTableAlignment(
|
|
|
1562
1610
|
}
|
|
1563
1611
|
|
|
1564
1612
|
// lines_changed: called for newly visible or invalidated lines
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1613
|
+
|
|
1614
|
+
|
|
1615
|
+
// after_insert: no-op for conceals/overlays.
|
|
1616
|
+
// The edit automatically invalidates seen_byte_ranges for affected lines,
|
|
1617
|
+
// causing lines_changed to fire on the next render. processLineConceals
|
|
1618
|
+
// handles clearing and rebuilding atomically.
|
|
1619
|
+
// Marker-based positions auto-adjust with buffer edits, so existing conceals
|
|
1620
|
+
// remain visually correct until lines_changed rebuilds them.
|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
// after_delete: no-op for conceals/overlays (same reasoning as after_insert).
|
|
1624
|
+
|
|
1625
|
+
|
|
1626
|
+
// cursor_moved: update cursor-aware reveal/conceal for old and new cursor lines
|
|
1627
|
+
|
|
1628
|
+
|
|
1629
|
+
// view_transform_request is no longer needed — soft wrapping is handled by
|
|
1630
|
+
// marker-based soft breaks (computed in lines_changed), and layout hints
|
|
1631
|
+
// are set directly via setLayoutHints. This eliminates the one-frame flicker
|
|
1632
|
+
// caused by the async view_transform round-trip.
|
|
1633
|
+
|
|
1634
|
+
// Handle buffer close events - clean up compose mode tracking
|
|
1635
|
+
|
|
1636
|
+
|
|
1637
|
+
// viewport_changed: recalculate table column widths on terminal resize
|
|
1638
|
+
|
|
1639
|
+
|
|
1640
|
+
// Re-enable compose mode for buffers restored from a saved session.
|
|
1641
|
+
// The Rust side restores ViewMode::Compose and compose_width, but the plugin
|
|
1642
|
+
// needs to re-apply line numbers, line wrap, and layout hints when activated.
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
// Register hooks
|
|
1646
|
+
editor.on("lines_changed", (data) => {
|
|
1574
1647
|
if (!isComposingInAnySplit(data.buffer_id)) return;
|
|
1575
1648
|
const lineNums = data.lines.map(l => `${l.line_number}(${l.byte_start}..${l.byte_end})`).join(', ');
|
|
1576
1649
|
editor.debug(`[mc] lines_changed: ${data.lines.length} lines: [${lineNums}]`);
|
|
@@ -1605,49 +1678,16 @@ function onMarkdownLinesChanged(data: {
|
|
|
1605
1678
|
if (tableWidthsGrew) {
|
|
1606
1679
|
editor.refreshLines(data.buffer_id);
|
|
1607
1680
|
}
|
|
1608
|
-
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
// after_insert: no-op for conceals/overlays.
|
|
1612
|
-
// The edit automatically invalidates seen_byte_ranges for affected lines,
|
|
1613
|
-
// causing lines_changed to fire on the next render. processLineConceals
|
|
1614
|
-
// handles clearing and rebuilding atomically.
|
|
1615
|
-
// Marker-based positions auto-adjust with buffer edits, so existing conceals
|
|
1616
|
-
// remain visually correct until lines_changed rebuilds them.
|
|
1617
|
-
function onMarkdownAfterInsert(data: {
|
|
1618
|
-
buffer_id: number;
|
|
1619
|
-
position: number;
|
|
1620
|
-
text: string;
|
|
1621
|
-
affected_start: number;
|
|
1622
|
-
affected_end: number;
|
|
1623
|
-
}): void {
|
|
1681
|
+
});
|
|
1682
|
+
editor.on("after_insert", (data) => {
|
|
1624
1683
|
if (!isComposingInAnySplit(data.buffer_id)) return;
|
|
1625
1684
|
editor.debug(`[mc] after_insert: pos=${data.position} text="${data.text.replace(/\n/g,'\\n')}" affected=${data.affected_start}..${data.affected_end}`);
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
// after_delete: no-op for conceals/overlays (same reasoning as after_insert).
|
|
1630
|
-
function onMarkdownAfterDelete(data: {
|
|
1631
|
-
buffer_id: number;
|
|
1632
|
-
start: number;
|
|
1633
|
-
end: number;
|
|
1634
|
-
deleted_text: string;
|
|
1635
|
-
affected_start: number;
|
|
1636
|
-
deleted_len: number;
|
|
1637
|
-
}): void {
|
|
1685
|
+
});
|
|
1686
|
+
editor.on("after_delete", (data) => {
|
|
1638
1687
|
if (!isComposingInAnySplit(data.buffer_id)) return;
|
|
1639
1688
|
editor.debug(`[mc] after_delete: start=${data.start} end=${data.end} deleted="${data.deleted_text.replace(/\n/g,'\\n')}" affected_start=${data.affected_start} deleted_len=${data.deleted_len}`);
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
// cursor_moved: update cursor-aware reveal/conceal for old and new cursor lines
|
|
1644
|
-
function onMarkdownCursorMoved(data: {
|
|
1645
|
-
buffer_id: number;
|
|
1646
|
-
cursor_id: number;
|
|
1647
|
-
old_position: number;
|
|
1648
|
-
new_position: number;
|
|
1649
|
-
line: number;
|
|
1650
|
-
}): void {
|
|
1689
|
+
});
|
|
1690
|
+
editor.on("cursor_moved", (data) => {
|
|
1651
1691
|
if (!isComposingInAnySplit(data.buffer_id)) return;
|
|
1652
1692
|
|
|
1653
1693
|
const prevLine = editor.getViewState(data.buffer_id, "last-cursor-line") as number | undefined;
|
|
@@ -1659,28 +1699,12 @@ function onMarkdownCursorMoved(data: {
|
|
|
1659
1699
|
// auto-expose is span-level (cursor entering/leaving an emphasis or link
|
|
1660
1700
|
// span within the same line must toggle its syntax markers).
|
|
1661
1701
|
editor.refreshLines(data.buffer_id);
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
// view_transform_request is no longer needed — soft wrapping is handled by
|
|
1666
|
-
// marker-based soft breaks (computed in lines_changed), and layout hints
|
|
1667
|
-
// are set directly via setLayoutHints. This eliminates the one-frame flicker
|
|
1668
|
-
// caused by the async view_transform round-trip.
|
|
1669
|
-
|
|
1670
|
-
// Handle buffer close events - clean up compose mode tracking
|
|
1671
|
-
function onMarkdownBufferClosed(data: { buffer_id: number }) : void {
|
|
1702
|
+
});
|
|
1703
|
+
// view_transform_request hook no longer needed — wrapping is handled by soft breaks
|
|
1704
|
+
editor.on("buffer_closed", (data) => {
|
|
1672
1705
|
// View state is cleaned up automatically when the buffer is removed from keyed_states
|
|
1673
|
-
}
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
// viewport_changed: recalculate table column widths on terminal resize
|
|
1677
|
-
function onMarkdownViewportChanged(data: {
|
|
1678
|
-
split_id: number;
|
|
1679
|
-
buffer_id: number;
|
|
1680
|
-
top_byte: number;
|
|
1681
|
-
width: number;
|
|
1682
|
-
height: number;
|
|
1683
|
-
}): void {
|
|
1706
|
+
});
|
|
1707
|
+
editor.on("viewport_changed", (data) => {
|
|
1684
1708
|
if (!isComposingInAnySplit(data.buffer_id)) return;
|
|
1685
1709
|
if (data.width === lastViewportWidth) return;
|
|
1686
1710
|
lastViewportWidth = data.width;
|
|
@@ -1688,7 +1712,7 @@ function onMarkdownViewportChanged(data: {
|
|
|
1688
1712
|
// Recompute allocated table column widths for new viewport width
|
|
1689
1713
|
const bufWidths = getTableWidths(data.buffer_id);
|
|
1690
1714
|
if (bufWidths) {
|
|
1691
|
-
const composeW =
|
|
1715
|
+
const composeW = effectiveComposeWidth(data.width);
|
|
1692
1716
|
const seen = new Set<string>(); // Track by JSON key to deduplicate shared TableWidthInfo
|
|
1693
1717
|
for (const [lineNum, info] of bufWidths) {
|
|
1694
1718
|
const key = info.maxW.join(",");
|
|
@@ -1701,13 +1725,39 @@ function onMarkdownViewportChanged(data: {
|
|
|
1701
1725
|
setTableWidths(data.buffer_id, bufWidths);
|
|
1702
1726
|
}
|
|
1703
1727
|
editor.refreshLines(data.buffer_id);
|
|
1704
|
-
}
|
|
1705
|
-
|
|
1728
|
+
});
|
|
1729
|
+
editor.on("prompt_confirmed", (args) => {
|
|
1730
|
+
if (args.prompt_type !== "markdown-compose-width") return;
|
|
1706
1731
|
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1732
|
+
const input = args.input.trim();
|
|
1733
|
+
if (input.toLowerCase() === "none") {
|
|
1734
|
+
config.composeWidth = null;
|
|
1735
|
+
editor.setStatus(editor.t("status.width_none"));
|
|
1736
|
+
|
|
1737
|
+
const bufferId = editor.getActiveBufferId();
|
|
1738
|
+
if (isComposing(bufferId)) {
|
|
1739
|
+
editor.setLayoutHints(bufferId, null, {});
|
|
1740
|
+
editor.refreshLines(bufferId);
|
|
1741
|
+
}
|
|
1742
|
+
return;
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
const width = parseInt(input, 10);
|
|
1746
|
+
if (!isNaN(width) && width > 20 && width < 300) {
|
|
1747
|
+
config.composeWidth = width;
|
|
1748
|
+
editor.setStatus(editor.t("status.width_set", { width: String(width) }));
|
|
1749
|
+
|
|
1750
|
+
// Re-process active buffer if in compose mode
|
|
1751
|
+
const bufferId = editor.getActiveBufferId();
|
|
1752
|
+
if (isComposing(bufferId)) {
|
|
1753
|
+
editor.setLayoutHints(bufferId, null, { composeWidth: config.composeWidth ?? undefined });
|
|
1754
|
+
editor.refreshLines(bufferId); // Trigger soft break recomputation
|
|
1755
|
+
}
|
|
1756
|
+
} else {
|
|
1757
|
+
editor.setStatus(editor.t("status.invalid_width"));
|
|
1758
|
+
}
|
|
1759
|
+
});
|
|
1760
|
+
editor.on("buffer_activated", (data) => {
|
|
1711
1761
|
const bufferId = data.buffer_id;
|
|
1712
1762
|
|
|
1713
1763
|
const info = editor.getBufferInfo(bufferId);
|
|
@@ -1726,19 +1776,7 @@ function onMarkdownBufferActivated(data: { buffer_id: number }) : void {
|
|
|
1726
1776
|
// markdown buffers that aren't already in compose mode.
|
|
1727
1777
|
enableMarkdownCompose(bufferId);
|
|
1728
1778
|
}
|
|
1729
|
-
}
|
|
1730
|
-
registerHandler("onMarkdownBufferActivated", onMarkdownBufferActivated);
|
|
1731
|
-
|
|
1732
|
-
// Register hooks
|
|
1733
|
-
editor.on("lines_changed", "onMarkdownLinesChanged");
|
|
1734
|
-
editor.on("after_insert", "onMarkdownAfterInsert");
|
|
1735
|
-
editor.on("after_delete", "onMarkdownAfterDelete");
|
|
1736
|
-
editor.on("cursor_moved", "onMarkdownCursorMoved");
|
|
1737
|
-
// view_transform_request hook no longer needed — wrapping is handled by soft breaks
|
|
1738
|
-
editor.on("buffer_closed", "onMarkdownBufferClosed");
|
|
1739
|
-
editor.on("viewport_changed", "onMarkdownViewportChanged");
|
|
1740
|
-
editor.on("prompt_confirmed", "onMarkdownComposeWidthConfirmed");
|
|
1741
|
-
editor.on("buffer_activated", "onMarkdownBufferActivated");
|
|
1779
|
+
});
|
|
1742
1780
|
|
|
1743
1781
|
// Set compose width command - starts interactive prompt
|
|
1744
1782
|
function markdownSetComposeWidth() : void {
|
|
@@ -1753,41 +1791,7 @@ function markdownSetComposeWidth() : void {
|
|
|
1753
1791
|
registerHandler("markdownSetComposeWidth", markdownSetComposeWidth);
|
|
1754
1792
|
|
|
1755
1793
|
// Handle compose width prompt confirmation
|
|
1756
|
-
function onMarkdownComposeWidthConfirmed(args: {
|
|
1757
|
-
prompt_type: string;
|
|
1758
|
-
input: string;
|
|
1759
|
-
}): void {
|
|
1760
|
-
if (args.prompt_type !== "markdown-compose-width") return;
|
|
1761
|
-
|
|
1762
|
-
const input = args.input.trim();
|
|
1763
|
-
if (input.toLowerCase() === "none") {
|
|
1764
|
-
config.composeWidth = null;
|
|
1765
|
-
editor.setStatus(editor.t("status.width_none"));
|
|
1766
|
-
|
|
1767
|
-
const bufferId = editor.getActiveBufferId();
|
|
1768
|
-
if (isComposing(bufferId)) {
|
|
1769
|
-
editor.setLayoutHints(bufferId, null, {});
|
|
1770
|
-
editor.refreshLines(bufferId);
|
|
1771
|
-
}
|
|
1772
|
-
return;
|
|
1773
|
-
}
|
|
1774
1794
|
|
|
1775
|
-
const width = parseInt(input, 10);
|
|
1776
|
-
if (!isNaN(width) && width > 20 && width < 300) {
|
|
1777
|
-
config.composeWidth = width;
|
|
1778
|
-
editor.setStatus(editor.t("status.width_set", { width: String(width) }));
|
|
1779
|
-
|
|
1780
|
-
// Re-process active buffer if in compose mode
|
|
1781
|
-
const bufferId = editor.getActiveBufferId();
|
|
1782
|
-
if (isComposing(bufferId)) {
|
|
1783
|
-
editor.setLayoutHints(bufferId, null, { composeWidth: config.composeWidth ?? undefined });
|
|
1784
|
-
editor.refreshLines(bufferId); // Trigger soft break recomputation
|
|
1785
|
-
}
|
|
1786
|
-
} else {
|
|
1787
|
-
editor.setStatus(editor.t("status.invalid_width"));
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
registerHandler("onMarkdownComposeWidthConfirmed", onMarkdownComposeWidthConfirmed);
|
|
1791
1795
|
|
|
1792
1796
|
// Register commands
|
|
1793
1797
|
editor.registerCommand(
|
|
@@ -343,17 +343,15 @@ function updateMarkdownMode(): void {
|
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
-
function md_src_on_buffer_activated() : void {
|
|
347
|
-
updateMarkdownMode();
|
|
348
|
-
}
|
|
349
|
-
registerHandler("md_src_on_buffer_activated", md_src_on_buffer_activated);
|
|
350
346
|
|
|
351
|
-
function md_src_on_language_changed() : void {
|
|
352
|
-
updateMarkdownMode();
|
|
353
|
-
}
|
|
354
|
-
registerHandler("md_src_on_language_changed", md_src_on_language_changed);
|
|
355
347
|
|
|
356
|
-
|
|
357
|
-
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
editor.on("buffer_activated", () => {
|
|
351
|
+
updateMarkdownMode();
|
|
352
|
+
});
|
|
353
|
+
editor.on("language_changed", () => {
|
|
354
|
+
updateMarkdownMode();
|
|
355
|
+
});
|
|
358
356
|
|
|
359
357
|
editor.debug("markdown_source plugin loaded");
|
package/plugins/marksman-lsp.ts
CHANGED
|
@@ -22,7 +22,8 @@ interface ActionPopupResultData {
|
|
|
22
22
|
const INSTALL_URL = "https://github.com/artempyanykh/marksman#how-to-install";
|
|
23
23
|
let markdownLspError: { serverCommand: string; message: string } | null = null;
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
editor.on("lsp_server_error", (data) => {
|
|
26
27
|
if (data.language !== "markdown") return;
|
|
27
28
|
markdownLspError = { serverCommand: data.server_command, message: data.message };
|
|
28
29
|
if (data.error_type === "not_found") {
|
|
@@ -30,11 +31,10 @@ function on_markdown_lsp_server_error(data: LspServerErrorData) : void {
|
|
|
30
31
|
} else {
|
|
31
32
|
editor.setStatus(`Markdown LSP error: ${data.message}`);
|
|
32
33
|
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
editor.on("lsp_server_error", "on_markdown_lsp_server_error");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
38
38
|
if (data.language !== "markdown" || !markdownLspError) return;
|
|
39
39
|
editor.showActionPopup({
|
|
40
40
|
id: "marksman-lsp-help",
|
|
@@ -46,11 +46,10 @@ function on_markdown_lsp_status_clicked(data: LspStatusClickedData) : void {
|
|
|
46
46
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
47
47
|
],
|
|
48
48
|
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
editor.on("lsp_status_clicked", "on_markdown_lsp_status_clicked");
|
|
49
|
+
});
|
|
50
|
+
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
editor.on("action_popup_result", (data) => {
|
|
54
53
|
if (data.popup_id !== "marksman-lsp-help") return;
|
|
55
54
|
switch (data.action_id) {
|
|
56
55
|
case "copy_url":
|
|
@@ -63,6 +62,4 @@ function on_markdown_lsp_action_result(data: ActionPopupResultData) : void {
|
|
|
63
62
|
markdownLspError = null;
|
|
64
63
|
break;
|
|
65
64
|
}
|
|
66
|
-
}
|
|
67
|
-
registerHandler("on_markdown_lsp_action_result", on_markdown_lsp_action_result);
|
|
68
|
-
editor.on("action_popup_result", "on_markdown_lsp_action_result");
|
|
65
|
+
});
|
|
@@ -1700,7 +1700,18 @@ registerHandler("merge_show_help", merge_show_help);
|
|
|
1700
1700
|
/**
|
|
1701
1701
|
* Handle buffer activation - check for conflict markers
|
|
1702
1702
|
*/
|
|
1703
|
-
|
|
1703
|
+
|
|
1704
|
+
|
|
1705
|
+
/**
|
|
1706
|
+
* Handle file open - check for conflict markers
|
|
1707
|
+
*/
|
|
1708
|
+
|
|
1709
|
+
|
|
1710
|
+
// =============================================================================
|
|
1711
|
+
// Hook Registration
|
|
1712
|
+
// =============================================================================
|
|
1713
|
+
|
|
1714
|
+
editor.on("buffer_activated", async (data) => {
|
|
1704
1715
|
// Don't trigger if already in merge mode
|
|
1705
1716
|
if (mergeState.isActive) return;
|
|
1706
1717
|
|
|
@@ -1724,13 +1735,8 @@ async function onMergeBufferActivated(data: { buffer_id: number }) : Promise<voi
|
|
|
1724
1735
|
} catch (e) {
|
|
1725
1736
|
// Not in git repo or other error, ignore
|
|
1726
1737
|
}
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
/**
|
|
1731
|
-
* Handle file open - check for conflict markers
|
|
1732
|
-
*/
|
|
1733
|
-
async function onMergeAfterFileOpen(data: { buffer_id: number; path: string }) : Promise<void> {
|
|
1738
|
+
});
|
|
1739
|
+
editor.on("after_file_open", async (data) => {
|
|
1734
1740
|
// Don't trigger if already in merge mode
|
|
1735
1741
|
if (mergeState.isActive) return;
|
|
1736
1742
|
|
|
@@ -1750,15 +1756,7 @@ async function onMergeAfterFileOpen(data: { buffer_id: number; path: string }) :
|
|
|
1750
1756
|
} catch (e) {
|
|
1751
1757
|
// Not in git repo or other error, ignore
|
|
1752
1758
|
}
|
|
1753
|
-
}
|
|
1754
|
-
registerHandler("onMergeAfterFileOpen", onMergeAfterFileOpen);
|
|
1755
|
-
|
|
1756
|
-
// =============================================================================
|
|
1757
|
-
// Hook Registration
|
|
1758
|
-
// =============================================================================
|
|
1759
|
-
|
|
1760
|
-
editor.on("buffer_activated", "onMergeBufferActivated");
|
|
1761
|
-
editor.on("after_file_open", "onMergeAfterFileOpen");
|
|
1759
|
+
});
|
|
1762
1760
|
|
|
1763
1761
|
// =============================================================================
|
|
1764
1762
|
// Command Registration - Dynamic based on merge mode state
|
package/plugins/nim-lsp.ts
CHANGED
|
@@ -35,7 +35,8 @@ const INSTALL_COMMANDS = {
|
|
|
35
35
|
|
|
36
36
|
let nimLspError: { serverCommand: string; message: string } | null = null;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
editor.on("lsp_server_error", (data) => {
|
|
39
40
|
if (data.language !== "nim") {
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
@@ -54,11 +55,10 @@ function on_nim_lsp_server_error(data: LspServerErrorData): void {
|
|
|
54
55
|
} else {
|
|
55
56
|
editor.setStatus(`Nim LSP error: ${data.message}`);
|
|
56
57
|
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
editor.on("lsp_server_error", "on_nim_lsp_server_error");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
62
62
|
if (data.language !== "nim" || !nimLspError) {
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
@@ -76,11 +76,10 @@ function on_nim_lsp_status_clicked(data: LspStatusClickedData): void {
|
|
|
76
76
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
77
77
|
],
|
|
78
78
|
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
editor.on("lsp_status_clicked", "on_nim_lsp_status_clicked");
|
|
79
|
+
});
|
|
80
|
+
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
editor.on("action_popup_result", (data) => {
|
|
84
83
|
if (data.popup_id !== "nim-lsp-help") {
|
|
85
84
|
return;
|
|
86
85
|
}
|
|
@@ -111,8 +110,6 @@ function on_nim_lsp_action_result(data: ActionPopupResultData): void {
|
|
|
111
110
|
default:
|
|
112
111
|
editor.debug(`nim-lsp: Unknown action: ${data.action_id}`);
|
|
113
112
|
}
|
|
114
|
-
}
|
|
115
|
-
registerHandler("on_nim_lsp_action_result", on_nim_lsp_action_result);
|
|
116
|
-
editor.on("action_popup_result", "on_nim_lsp_action_result");
|
|
113
|
+
});
|
|
117
114
|
|
|
118
115
|
editor.debug("nim-lsp: Plugin loaded");
|
package/plugins/nix-lsp.ts
CHANGED
|
@@ -36,7 +36,8 @@ const INSTALL_COMMANDS = {
|
|
|
36
36
|
|
|
37
37
|
let nixLspError: { serverCommand: string; message: string } | null = null;
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
editor.on("lsp_server_error", (data) => {
|
|
40
41
|
if (data.language !== "nix") {
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
@@ -55,11 +56,10 @@ function on_nix_lsp_server_error(data: LspServerErrorData): void {
|
|
|
55
56
|
} else {
|
|
56
57
|
editor.setStatus(`Nix LSP error: ${data.message}`);
|
|
57
58
|
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
editor.on("lsp_server_error", "on_nix_lsp_server_error");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
editor.on("lsp_status_clicked", (data) => {
|
|
63
63
|
if (data.language !== "nix" || !nixLspError) {
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
@@ -78,11 +78,10 @@ function on_nix_lsp_status_clicked(data: LspStatusClickedData): void {
|
|
|
78
78
|
{ id: "dismiss", label: "Dismiss (ESC)" },
|
|
79
79
|
],
|
|
80
80
|
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
editor.on("lsp_status_clicked", "on_nix_lsp_status_clicked");
|
|
81
|
+
});
|
|
82
|
+
|
|
84
83
|
|
|
85
|
-
|
|
84
|
+
editor.on("action_popup_result", (data) => {
|
|
86
85
|
if (data.popup_id !== "nix-lsp-help") {
|
|
87
86
|
return;
|
|
88
87
|
}
|
|
@@ -118,8 +117,6 @@ function on_nix_lsp_action_result(data: ActionPopupResultData): void {
|
|
|
118
117
|
default:
|
|
119
118
|
editor.debug(`nix-lsp: Unknown action: ${data.action_id}`);
|
|
120
119
|
}
|
|
121
|
-
}
|
|
122
|
-
registerHandler("on_nix_lsp_action_result", on_nix_lsp_action_result);
|
|
123
|
-
editor.on("action_popup_result", "on_nix_lsp_action_result");
|
|
120
|
+
});
|
|
124
121
|
|
|
125
122
|
editor.debug("nix-lsp: Plugin loaded");
|