@elizaos/tui 2.0.0-alpha.10
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/README.md +761 -0
- package/dist/autocomplete.d.ts +48 -0
- package/dist/autocomplete.d.ts.map +1 -0
- package/dist/autocomplete.js +555 -0
- package/dist/components/box.d.ts +22 -0
- package/dist/components/box.d.ts.map +1 -0
- package/dist/components/box.js +103 -0
- package/dist/components/cancellable-loader.d.ts +22 -0
- package/dist/components/cancellable-loader.d.ts.map +1 -0
- package/dist/components/cancellable-loader.js +34 -0
- package/dist/components/editor/history.d.ts +38 -0
- package/dist/components/editor/history.d.ts.map +1 -0
- package/dist/components/editor/history.js +76 -0
- package/dist/components/editor/index.d.ts +18 -0
- package/dist/components/editor/index.d.ts.map +1 -0
- package/dist/components/editor/index.js +21 -0
- package/dist/components/editor/kill-ring.d.ts +41 -0
- package/dist/components/editor/kill-ring.d.ts.map +1 -0
- package/dist/components/editor/kill-ring.js +81 -0
- package/dist/components/editor/layout.d.ts +40 -0
- package/dist/components/editor/layout.d.ts.map +1 -0
- package/dist/components/editor/layout.js +205 -0
- package/dist/components/editor/types.d.ts +68 -0
- package/dist/components/editor/types.d.ts.map +1 -0
- package/dist/components/editor/types.js +4 -0
- package/dist/components/editor/undo.d.ts +46 -0
- package/dist/components/editor/undo.d.ts.map +1 -0
- package/dist/components/editor/undo.js +58 -0
- package/dist/components/editor.d.ts +196 -0
- package/dist/components/editor.d.ts.map +1 -0
- package/dist/components/editor.js +1707 -0
- package/dist/components/image.d.ts +28 -0
- package/dist/components/image.d.ts.map +1 -0
- package/dist/components/image.js +68 -0
- package/dist/components/input.d.ts +19 -0
- package/dist/components/input.d.ts.map +1 -0
- package/dist/components/input.js +195 -0
- package/dist/components/loader.d.ts +21 -0
- package/dist/components/loader.d.ts.map +1 -0
- package/dist/components/loader.js +49 -0
- package/dist/components/markdown/index.d.ts +13 -0
- package/dist/components/markdown/index.d.ts.map +1 -0
- package/dist/components/markdown/index.js +9 -0
- package/dist/components/markdown/inline-renderer.d.ts +22 -0
- package/dist/components/markdown/inline-renderer.d.ts.map +1 -0
- package/dist/components/markdown/inline-renderer.js +88 -0
- package/dist/components/markdown/list-renderer.d.ts +33 -0
- package/dist/components/markdown/list-renderer.d.ts.map +1 -0
- package/dist/components/markdown/list-renderer.js +110 -0
- package/dist/components/markdown/table-renderer.d.ts +43 -0
- package/dist/components/markdown/table-renderer.d.ts.map +1 -0
- package/dist/components/markdown/table-renderer.js +184 -0
- package/dist/components/markdown/types.d.ts +57 -0
- package/dist/components/markdown/types.d.ts.map +1 -0
- package/dist/components/markdown/types.js +13 -0
- package/dist/components/markdown.d.ts +44 -0
- package/dist/components/markdown.d.ts.map +1 -0
- package/dist/components/markdown.js +319 -0
- package/dist/components/progress-bar.d.ts +67 -0
- package/dist/components/progress-bar.d.ts.map +1 -0
- package/dist/components/progress-bar.js +124 -0
- package/dist/components/select-list.d.ts +32 -0
- package/dist/components/select-list.d.ts.map +1 -0
- package/dist/components/select-list.js +151 -0
- package/dist/components/settings-list.d.ts +50 -0
- package/dist/components/settings-list.d.ts.map +1 -0
- package/dist/components/settings-list.js +184 -0
- package/dist/components/spacer.d.ts +12 -0
- package/dist/components/spacer.d.ts.map +1 -0
- package/dist/components/spacer.js +22 -0
- package/dist/components/text.d.ts +19 -0
- package/dist/components/text.d.ts.map +1 -0
- package/dist/components/text.js +88 -0
- package/dist/components/toast.d.ts +73 -0
- package/dist/components/toast.d.ts.map +1 -0
- package/dist/components/toast.js +119 -0
- package/dist/components/truncated-text.d.ts +13 -0
- package/dist/components/truncated-text.d.ts.map +1 -0
- package/dist/components/truncated-text.js +50 -0
- package/dist/constants.d.ts +97 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +126 -0
- package/dist/core/container.d.ts +32 -0
- package/dist/core/container.d.ts.map +1 -0
- package/dist/core/container.js +49 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/overlay.d.ts +44 -0
- package/dist/core/overlay.d.ts.map +1 -0
- package/dist/core/overlay.js +171 -0
- package/dist/core/types.d.ts +116 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +14 -0
- package/dist/editor-component.d.ts +37 -0
- package/dist/editor-component.d.ts.map +1 -0
- package/dist/editor-component.js +1 -0
- package/dist/fuzzy.d.ts +16 -0
- package/dist/fuzzy.d.ts.map +1 -0
- package/dist/fuzzy.js +108 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/keybindings.d.ts +39 -0
- package/dist/keybindings.d.ts.map +1 -0
- package/dist/keybindings.js +113 -0
- package/dist/keys.d.ts +153 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +951 -0
- package/dist/stdin-buffer.d.ts +48 -0
- package/dist/stdin-buffer.d.ts.map +1 -0
- package/dist/stdin-buffer.js +316 -0
- package/dist/terminal-image.d.ts +68 -0
- package/dist/terminal-image.d.ts.map +1 -0
- package/dist/terminal-image.js +287 -0
- package/dist/terminal.d.ts +71 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +216 -0
- package/dist/themes/index.d.ts +103 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +161 -0
- package/dist/tui.d.ts +90 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +745 -0
- package/dist/types/marked-tokens.d.ts +57 -0
- package/dist/types/marked-tokens.d.ts.map +1 -0
- package/dist/types/marked-tokens.js +17 -0
- package/dist/utils/cursor-movement.d.ts +127 -0
- package/dist/utils/cursor-movement.d.ts.map +1 -0
- package/dist/utils/cursor-movement.js +251 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/paste-handler.d.ts +86 -0
- package/dist/utils/paste-handler.d.ts.map +1 -0
- package/dist/utils/paste-handler.js +121 -0
- package/dist/utils.d.ts +75 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +796 -0
- package/package.json +53 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text layout and word wrapping utilities for the Editor component.
|
|
3
|
+
*/
|
|
4
|
+
import { getSegmenter, isWhitespaceChar, visibleWidth } from "../../utils.js";
|
|
5
|
+
const segmenter = getSegmenter();
|
|
6
|
+
/**
|
|
7
|
+
* Split a line into word-wrapped chunks.
|
|
8
|
+
* Wraps at word boundaries when possible, falling back to character-level
|
|
9
|
+
* wrapping for words longer than the available width.
|
|
10
|
+
*
|
|
11
|
+
* @param line - The text line to wrap
|
|
12
|
+
* @param maxWidth - Maximum visible width per chunk
|
|
13
|
+
* @returns Array of chunks with text and position information
|
|
14
|
+
*/
|
|
15
|
+
export function wordWrapLine(line, maxWidth) {
|
|
16
|
+
if (!line || maxWidth <= 0) {
|
|
17
|
+
return [{ text: "", startIndex: 0, endIndex: 0 }];
|
|
18
|
+
}
|
|
19
|
+
const lineWidth = visibleWidth(line);
|
|
20
|
+
if (lineWidth <= maxWidth) {
|
|
21
|
+
return [{ text: line, startIndex: 0, endIndex: line.length }];
|
|
22
|
+
}
|
|
23
|
+
const chunks = [];
|
|
24
|
+
const segments = [...segmenter.segment(line)];
|
|
25
|
+
let currentWidth = 0;
|
|
26
|
+
let chunkStart = 0;
|
|
27
|
+
// Wrap opportunity: the position after the last whitespace before a non-whitespace
|
|
28
|
+
// grapheme, i.e. where a line break is allowed.
|
|
29
|
+
let wrapOppIndex = -1;
|
|
30
|
+
let wrapOppWidth = 0;
|
|
31
|
+
for (let i = 0; i < segments.length; i++) {
|
|
32
|
+
const seg = segments[i];
|
|
33
|
+
const grapheme = seg.segment;
|
|
34
|
+
const gWidth = visibleWidth(grapheme);
|
|
35
|
+
const charIndex = seg.index;
|
|
36
|
+
const isWs = isWhitespaceChar(grapheme);
|
|
37
|
+
// Overflow check before advancing.
|
|
38
|
+
if (currentWidth + gWidth > maxWidth) {
|
|
39
|
+
if (wrapOppIndex >= 0) {
|
|
40
|
+
// Backtrack to last wrap opportunity.
|
|
41
|
+
chunks.push({ text: line.slice(chunkStart, wrapOppIndex), startIndex: chunkStart, endIndex: wrapOppIndex });
|
|
42
|
+
chunkStart = wrapOppIndex;
|
|
43
|
+
currentWidth -= wrapOppWidth;
|
|
44
|
+
}
|
|
45
|
+
else if (chunkStart < charIndex) {
|
|
46
|
+
// No wrap opportunity: force-break at current position.
|
|
47
|
+
chunks.push({ text: line.slice(chunkStart, charIndex), startIndex: chunkStart, endIndex: charIndex });
|
|
48
|
+
chunkStart = charIndex;
|
|
49
|
+
currentWidth = 0;
|
|
50
|
+
}
|
|
51
|
+
wrapOppIndex = -1;
|
|
52
|
+
}
|
|
53
|
+
// Advance.
|
|
54
|
+
currentWidth += gWidth;
|
|
55
|
+
// Record wrap opportunity: whitespace followed by non-whitespace.
|
|
56
|
+
// Multiple spaces join (no break between them); the break point is
|
|
57
|
+
// after the last space before the next word.
|
|
58
|
+
const next = segments[i + 1];
|
|
59
|
+
if (isWs && next && !isWhitespaceChar(next.segment)) {
|
|
60
|
+
wrapOppIndex = next.index;
|
|
61
|
+
wrapOppWidth = currentWidth;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Push final chunk.
|
|
65
|
+
chunks.push({ text: line.slice(chunkStart), startIndex: chunkStart, endIndex: line.length });
|
|
66
|
+
return chunks;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Layout text into visual lines for rendering.
|
|
70
|
+
*
|
|
71
|
+
* @param state - Current editor state
|
|
72
|
+
* @param contentWidth - Maximum width for content
|
|
73
|
+
* @returns Array of layout lines ready for rendering
|
|
74
|
+
*/
|
|
75
|
+
export function layoutText(state, contentWidth) {
|
|
76
|
+
const layoutLines = [];
|
|
77
|
+
if (state.lines.length === 0 || (state.lines.length === 1 && state.lines[0] === "")) {
|
|
78
|
+
// Empty editor
|
|
79
|
+
layoutLines.push({
|
|
80
|
+
text: "",
|
|
81
|
+
hasCursor: true,
|
|
82
|
+
cursorPos: 0,
|
|
83
|
+
});
|
|
84
|
+
return layoutLines;
|
|
85
|
+
}
|
|
86
|
+
// Process each logical line
|
|
87
|
+
for (let i = 0; i < state.lines.length; i++) {
|
|
88
|
+
const line = state.lines[i];
|
|
89
|
+
const isCurrentLine = i === state.cursorLine;
|
|
90
|
+
const lineVisibleWidth = visibleWidth(line);
|
|
91
|
+
if (lineVisibleWidth <= contentWidth) {
|
|
92
|
+
// Line fits in one layout line
|
|
93
|
+
if (isCurrentLine) {
|
|
94
|
+
layoutLines.push({
|
|
95
|
+
text: line,
|
|
96
|
+
hasCursor: true,
|
|
97
|
+
cursorPos: state.cursorCol,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
layoutLines.push({
|
|
102
|
+
text: line,
|
|
103
|
+
hasCursor: false,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Line needs wrapping - use word-aware wrapping
|
|
109
|
+
const chunks = wordWrapLine(line, contentWidth);
|
|
110
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
111
|
+
const chunk = chunks[chunkIndex];
|
|
112
|
+
if (!chunk)
|
|
113
|
+
continue;
|
|
114
|
+
const cursorPos = state.cursorCol;
|
|
115
|
+
const isLastChunk = chunkIndex === chunks.length - 1;
|
|
116
|
+
// Determine if cursor is in this chunk
|
|
117
|
+
let hasCursorInChunk = false;
|
|
118
|
+
let adjustedCursorPos = 0;
|
|
119
|
+
if (isCurrentLine) {
|
|
120
|
+
if (isLastChunk) {
|
|
121
|
+
// Last chunk: cursor belongs here if >= startIndex
|
|
122
|
+
hasCursorInChunk = cursorPos >= chunk.startIndex;
|
|
123
|
+
adjustedCursorPos = cursorPos - chunk.startIndex;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// Non-last chunk: cursor belongs here if in range [startIndex, endIndex)
|
|
127
|
+
hasCursorInChunk = cursorPos >= chunk.startIndex && cursorPos < chunk.endIndex;
|
|
128
|
+
if (hasCursorInChunk) {
|
|
129
|
+
adjustedCursorPos = cursorPos - chunk.startIndex;
|
|
130
|
+
// Clamp to text length (in case cursor was in trimmed whitespace)
|
|
131
|
+
if (adjustedCursorPos > chunk.text.length) {
|
|
132
|
+
adjustedCursorPos = chunk.text.length;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
layoutLines.push({
|
|
138
|
+
text: chunk.text,
|
|
139
|
+
hasCursor: hasCursorInChunk,
|
|
140
|
+
cursorPos: hasCursorInChunk ? adjustedCursorPos : undefined,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return layoutLines;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build a mapping from visual lines to logical positions.
|
|
149
|
+
*
|
|
150
|
+
* @param state - Current editor state
|
|
151
|
+
* @param width - Maximum width for content
|
|
152
|
+
* @returns Array where each element represents a visual line
|
|
153
|
+
*/
|
|
154
|
+
export function buildVisualLineMap(state, width) {
|
|
155
|
+
const visualLines = [];
|
|
156
|
+
for (let i = 0; i < state.lines.length; i++) {
|
|
157
|
+
const line = state.lines[i];
|
|
158
|
+
const lineVisWidth = visibleWidth(line);
|
|
159
|
+
if (line.length === 0) {
|
|
160
|
+
// Empty line still takes one visual line
|
|
161
|
+
visualLines.push({ logicalLine: i, startCol: 0, length: 0 });
|
|
162
|
+
}
|
|
163
|
+
else if (lineVisWidth <= width) {
|
|
164
|
+
visualLines.push({ logicalLine: i, startCol: 0, length: line.length });
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
// Line needs wrapping - use word-aware wrapping
|
|
168
|
+
const chunks = wordWrapLine(line, width);
|
|
169
|
+
for (const chunk of chunks) {
|
|
170
|
+
visualLines.push({
|
|
171
|
+
logicalLine: i,
|
|
172
|
+
startCol: chunk.startIndex,
|
|
173
|
+
length: chunk.endIndex - chunk.startIndex,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return visualLines;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Find the visual line index for the current cursor position.
|
|
182
|
+
*
|
|
183
|
+
* @param visualLines - Visual line mappings
|
|
184
|
+
* @param cursorLine - Current logical line
|
|
185
|
+
* @param cursorCol - Current column position
|
|
186
|
+
* @returns Visual line index
|
|
187
|
+
*/
|
|
188
|
+
export function findCurrentVisualLine(visualLines, cursorLine, cursorCol) {
|
|
189
|
+
for (let i = 0; i < visualLines.length; i++) {
|
|
190
|
+
const vl = visualLines[i];
|
|
191
|
+
if (!vl)
|
|
192
|
+
continue;
|
|
193
|
+
if (vl.logicalLine === cursorLine) {
|
|
194
|
+
const colInSegment = cursorCol - vl.startCol;
|
|
195
|
+
// Cursor is in this segment if it's within range
|
|
196
|
+
// For the last segment of a logical line, cursor can be at length (end position)
|
|
197
|
+
const isLastSegmentOfLine = i === visualLines.length - 1 || visualLines[i + 1]?.logicalLine !== vl.logicalLine;
|
|
198
|
+
if (colInSegment >= 0 && (colInSegment < vl.length || (isLastSegmentOfLine && colInSegment <= vl.length))) {
|
|
199
|
+
return i;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Fallback: return last visual line
|
|
204
|
+
return visualLines.length - 1;
|
|
205
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Editor component.
|
|
3
|
+
*/
|
|
4
|
+
import type { SelectListTheme } from "../select-list.js";
|
|
5
|
+
/**
|
|
6
|
+
* Editor state containing the text content and cursor position.
|
|
7
|
+
*/
|
|
8
|
+
export interface EditorState {
|
|
9
|
+
/** Lines of text in the editor */
|
|
10
|
+
lines: string[];
|
|
11
|
+
/** Current logical line index (0-based) */
|
|
12
|
+
cursorLine: number;
|
|
13
|
+
/** Current column position within the line */
|
|
14
|
+
cursorCol: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A single layout line after word wrapping.
|
|
18
|
+
*/
|
|
19
|
+
export interface LayoutLine {
|
|
20
|
+
/** The text content of this layout line */
|
|
21
|
+
text: string;
|
|
22
|
+
/** Whether this line contains the cursor */
|
|
23
|
+
hasCursor: boolean;
|
|
24
|
+
/** Position of cursor within this line (if hasCursor is true) */
|
|
25
|
+
cursorPos?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Theme configuration for the Editor component.
|
|
29
|
+
*/
|
|
30
|
+
export interface EditorTheme {
|
|
31
|
+
/** Function to apply border color styling */
|
|
32
|
+
borderColor: (str: string) => string;
|
|
33
|
+
/** Theme for the autocomplete dropdown */
|
|
34
|
+
selectList: SelectListTheme;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Options for the Editor component.
|
|
38
|
+
*/
|
|
39
|
+
export interface EditorOptions {
|
|
40
|
+
/** Horizontal padding (default: 0) */
|
|
41
|
+
paddingX?: number;
|
|
42
|
+
/** Maximum visible items in autocomplete dropdown (default: 5) */
|
|
43
|
+
autocompleteMaxVisible?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Represents a chunk of text for word-wrap layout.
|
|
47
|
+
* Tracks both the text content and its position in the original line.
|
|
48
|
+
*/
|
|
49
|
+
export interface TextChunk {
|
|
50
|
+
/** The text content of this chunk */
|
|
51
|
+
text: string;
|
|
52
|
+
/** Starting index in the original line */
|
|
53
|
+
startIndex: number;
|
|
54
|
+
/** Ending index in the original line */
|
|
55
|
+
endIndex: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Visual line mapping for cursor navigation.
|
|
59
|
+
*/
|
|
60
|
+
export interface VisualLineMapping {
|
|
61
|
+
/** Index into the logical lines array */
|
|
62
|
+
logicalLine: number;
|
|
63
|
+
/** Starting column in the logical line */
|
|
64
|
+
startCol: number;
|
|
65
|
+
/** Length of this visual line segment */
|
|
66
|
+
length: number;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/editor/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,6CAA6C;IAC7C,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,0CAA0C;IAC1C,UAAU,EAAE,eAAe,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Undo/redo support for the Editor component.
|
|
3
|
+
*/
|
|
4
|
+
import type { EditorState } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Manages undo stack for the Editor.
|
|
7
|
+
*/
|
|
8
|
+
export declare class UndoManager {
|
|
9
|
+
private stack;
|
|
10
|
+
/**
|
|
11
|
+
* Capture a snapshot of the current state.
|
|
12
|
+
*
|
|
13
|
+
* @param state - Current editor state
|
|
14
|
+
* @returns Deep clone of the state
|
|
15
|
+
*/
|
|
16
|
+
captureSnapshot(state: EditorState): EditorState;
|
|
17
|
+
/**
|
|
18
|
+
* Push a snapshot onto the undo stack.
|
|
19
|
+
*
|
|
20
|
+
* @param state - Current editor state to save
|
|
21
|
+
*/
|
|
22
|
+
push(state: EditorState): void;
|
|
23
|
+
/**
|
|
24
|
+
* Pop and return the most recent snapshot.
|
|
25
|
+
*
|
|
26
|
+
* @returns The previous state, or undefined if stack is empty
|
|
27
|
+
*/
|
|
28
|
+
pop(): EditorState | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Check if there are any undo snapshots available.
|
|
31
|
+
*/
|
|
32
|
+
canUndo(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Clear the undo stack.
|
|
35
|
+
*/
|
|
36
|
+
clear(): void;
|
|
37
|
+
get length(): number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Restore an undo snapshot to the target state object.
|
|
41
|
+
*
|
|
42
|
+
* @param target - State object to restore to
|
|
43
|
+
* @param snapshot - Snapshot to restore
|
|
44
|
+
*/
|
|
45
|
+
export declare function restoreSnapshot(target: EditorState, snapshot: EditorState): void;
|
|
46
|
+
//# sourceMappingURL=undo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undo.d.ts","sourceRoot":"","sources":["../../../src/components/editor/undo.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,KAAK,CAAqB;IAElC;;;;;OAKG;IACH,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW;IAIhD;;;;OAIG;IACH,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAI9B;;;;OAIG;IACH,GAAG,IAAI,WAAW,GAAG,SAAS;IAI9B;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb,IAAI,MAAM,IAAI,MAAM,CAEnB;CACD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,GAAG,IAAI,CAEhF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Undo/redo support for the Editor component.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Manages undo stack for the Editor.
|
|
6
|
+
*/
|
|
7
|
+
export class UndoManager {
|
|
8
|
+
stack = [];
|
|
9
|
+
/**
|
|
10
|
+
* Capture a snapshot of the current state.
|
|
11
|
+
*
|
|
12
|
+
* @param state - Current editor state
|
|
13
|
+
* @returns Deep clone of the state
|
|
14
|
+
*/
|
|
15
|
+
captureSnapshot(state) {
|
|
16
|
+
return structuredClone(state);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Push a snapshot onto the undo stack.
|
|
20
|
+
*
|
|
21
|
+
* @param state - Current editor state to save
|
|
22
|
+
*/
|
|
23
|
+
push(state) {
|
|
24
|
+
this.stack.push(this.captureSnapshot(state));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Pop and return the most recent snapshot.
|
|
28
|
+
*
|
|
29
|
+
* @returns The previous state, or undefined if stack is empty
|
|
30
|
+
*/
|
|
31
|
+
pop() {
|
|
32
|
+
return this.stack.pop();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if there are any undo snapshots available.
|
|
36
|
+
*/
|
|
37
|
+
canUndo() {
|
|
38
|
+
return this.stack.length > 0;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Clear the undo stack.
|
|
42
|
+
*/
|
|
43
|
+
clear() {
|
|
44
|
+
this.stack.length = 0;
|
|
45
|
+
}
|
|
46
|
+
get length() {
|
|
47
|
+
return this.stack.length;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Restore an undo snapshot to the target state object.
|
|
52
|
+
*
|
|
53
|
+
* @param target - State object to restore to
|
|
54
|
+
* @param snapshot - Snapshot to restore
|
|
55
|
+
*/
|
|
56
|
+
export function restoreSnapshot(target, snapshot) {
|
|
57
|
+
Object.assign(target, structuredClone(snapshot));
|
|
58
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import type { AutocompleteProvider } from "../autocomplete.js";
|
|
2
|
+
import { type Component, type Focusable, type TUI } from "../tui.js";
|
|
3
|
+
export { DEFAULT_HISTORY_LIMIT, EditorHistory } from "./editor/history.js";
|
|
4
|
+
export { KillRing } from "./editor/kill-ring.js";
|
|
5
|
+
export { buildVisualLineMap, findCurrentVisualLine, layoutText, wordWrapLine, } from "./editor/layout.js";
|
|
6
|
+
export type { EditorOptions, EditorState, EditorTheme, LayoutLine, TextChunk, VisualLineMapping, } from "./editor/types.js";
|
|
7
|
+
export { restoreSnapshot, UndoManager } from "./editor/undo.js";
|
|
8
|
+
import type { EditorOptions, EditorTheme } from "./editor/types.js";
|
|
9
|
+
export declare class Editor implements Component, Focusable {
|
|
10
|
+
private state;
|
|
11
|
+
/** Get line at index, returns empty string for invalid indices */
|
|
12
|
+
private getLine;
|
|
13
|
+
/** Get current line at cursor */
|
|
14
|
+
private get currentLine();
|
|
15
|
+
/** Focusable interface - set by TUI when focus changes */
|
|
16
|
+
focused: boolean;
|
|
17
|
+
protected tui: TUI;
|
|
18
|
+
private theme;
|
|
19
|
+
private paddingX;
|
|
20
|
+
private lastWidth;
|
|
21
|
+
private scrollOffset;
|
|
22
|
+
borderColor: (str: string) => string;
|
|
23
|
+
private autocompleteProvider?;
|
|
24
|
+
private autocompleteList?;
|
|
25
|
+
private autocompleteState;
|
|
26
|
+
private autocompletePrefix;
|
|
27
|
+
private autocompleteMaxVisible;
|
|
28
|
+
private pastes;
|
|
29
|
+
private pasteCounter;
|
|
30
|
+
private pasteBuffer;
|
|
31
|
+
private isInPaste;
|
|
32
|
+
private history;
|
|
33
|
+
private historyIndex;
|
|
34
|
+
private killRing;
|
|
35
|
+
private lastAction;
|
|
36
|
+
private jumpMode;
|
|
37
|
+
private preferredVisualCol;
|
|
38
|
+
private undoStack;
|
|
39
|
+
onSubmit?: (text: string) => void;
|
|
40
|
+
onChange?: (text: string) => void;
|
|
41
|
+
disableSubmit: boolean;
|
|
42
|
+
constructor(tui: TUI, theme: EditorTheme, options?: EditorOptions);
|
|
43
|
+
getPaddingX(): number;
|
|
44
|
+
setPaddingX(padding: number): void;
|
|
45
|
+
getAutocompleteMaxVisible(): number;
|
|
46
|
+
setAutocompleteMaxVisible(maxVisible: number): void;
|
|
47
|
+
setAutocompleteProvider(provider: AutocompleteProvider): void;
|
|
48
|
+
/**
|
|
49
|
+
* Add a prompt to history for up/down arrow navigation.
|
|
50
|
+
* Called after successful submission.
|
|
51
|
+
*/
|
|
52
|
+
addToHistory(text: string): void;
|
|
53
|
+
private isEditorEmpty;
|
|
54
|
+
private isOnFirstVisualLine;
|
|
55
|
+
private isOnLastVisualLine;
|
|
56
|
+
private navigateHistory;
|
|
57
|
+
/** Internal setText that doesn't reset history state - used by navigateHistory */
|
|
58
|
+
private setTextInternal;
|
|
59
|
+
invalidate(): void;
|
|
60
|
+
render(width: number): string[];
|
|
61
|
+
handleInput(data: string): void;
|
|
62
|
+
private layoutText;
|
|
63
|
+
getText(): string;
|
|
64
|
+
/**
|
|
65
|
+
* Get text with paste markers expanded to their actual content.
|
|
66
|
+
* Use this when you need the full content (e.g., for external editor).
|
|
67
|
+
*/
|
|
68
|
+
getExpandedText(): string;
|
|
69
|
+
getLines(): string[];
|
|
70
|
+
getCursor(): {
|
|
71
|
+
line: number;
|
|
72
|
+
col: number;
|
|
73
|
+
};
|
|
74
|
+
setText(text: string): void;
|
|
75
|
+
/**
|
|
76
|
+
* Insert text at the current cursor position.
|
|
77
|
+
* Used for programmatic insertion (e.g., clipboard image markers).
|
|
78
|
+
* This is atomic for undo - single undo restores entire pre-insert state.
|
|
79
|
+
*/
|
|
80
|
+
insertTextAtCursor(text: string): void;
|
|
81
|
+
/**
|
|
82
|
+
* Internal text insertion at cursor. Handles single and multi-line text.
|
|
83
|
+
* Does not push undo snapshots or trigger autocomplete - caller is responsible.
|
|
84
|
+
* Normalizes line endings and calls onChange once at the end.
|
|
85
|
+
*/
|
|
86
|
+
private insertTextAtCursorInternal;
|
|
87
|
+
private insertCharacter;
|
|
88
|
+
private handlePaste;
|
|
89
|
+
private addNewLine;
|
|
90
|
+
private shouldSubmitOnBackslashEnter;
|
|
91
|
+
private submitValue;
|
|
92
|
+
private handleBackspace;
|
|
93
|
+
/**
|
|
94
|
+
* Set cursor column and clear preferredVisualCol.
|
|
95
|
+
* Use this for all non-vertical cursor movements to reset sticky column behavior.
|
|
96
|
+
*/
|
|
97
|
+
private setCursorCol;
|
|
98
|
+
/**
|
|
99
|
+
* Move cursor to a target visual line, applying sticky column logic.
|
|
100
|
+
* Shared by moveCursor() and pageScroll().
|
|
101
|
+
*/
|
|
102
|
+
private moveToVisualLine;
|
|
103
|
+
/**
|
|
104
|
+
* Compute the target visual column for vertical cursor movement.
|
|
105
|
+
* Implements the sticky column decision table:
|
|
106
|
+
*
|
|
107
|
+
* | P | S | T | U | Scenario | Set Preferred | Move To |
|
|
108
|
+
* |---|---|---|---| ---------------------------------------------------- |---------------|-------------|
|
|
109
|
+
* | 0 | * | 0 | - | Start nav, target fits | null | current |
|
|
110
|
+
* | 0 | * | 1 | - | Start nav, target shorter | current | target end |
|
|
111
|
+
* | 1 | 0 | 0 | 0 | Clamped, target fits preferred | null | preferred |
|
|
112
|
+
* | 1 | 0 | 0 | 1 | Clamped, target longer but still can't fit preferred | keep | target end |
|
|
113
|
+
* | 1 | 0 | 1 | - | Clamped, target even shorter | keep | target end |
|
|
114
|
+
* | 1 | 1 | 0 | - | Rewrapped, target fits current | null | current |
|
|
115
|
+
* | 1 | 1 | 1 | - | Rewrapped, target shorter than current | current | target end |
|
|
116
|
+
*
|
|
117
|
+
* Where:
|
|
118
|
+
* - P = preferred col is set
|
|
119
|
+
* - S = cursor in middle of source line (not clamped to end)
|
|
120
|
+
* - T = target line shorter than current visual col
|
|
121
|
+
* - U = target line shorter than preferred col
|
|
122
|
+
*/
|
|
123
|
+
private computeVerticalMoveColumn;
|
|
124
|
+
private moveToLineStart;
|
|
125
|
+
private moveToLineEnd;
|
|
126
|
+
private deleteToStartOfLine;
|
|
127
|
+
private deleteToEndOfLine;
|
|
128
|
+
private deleteWordBackwards;
|
|
129
|
+
private deleteWordForward;
|
|
130
|
+
private handleForwardDelete;
|
|
131
|
+
/**
|
|
132
|
+
* Build a mapping from visual lines to logical positions.
|
|
133
|
+
* Returns an array where each element represents a visual line with:
|
|
134
|
+
* - logicalLine: index into this.state.lines
|
|
135
|
+
* - startCol: starting column in the logical line
|
|
136
|
+
* - length: length of this visual line segment
|
|
137
|
+
*/
|
|
138
|
+
private buildVisualLineMap;
|
|
139
|
+
/**
|
|
140
|
+
* Find the visual line index for the current cursor position.
|
|
141
|
+
*/
|
|
142
|
+
private findCurrentVisualLine;
|
|
143
|
+
private moveCursor;
|
|
144
|
+
/**
|
|
145
|
+
* Scroll by a page (direction: -1 for up, 1 for down).
|
|
146
|
+
* Moves cursor by the page size while keeping it in bounds.
|
|
147
|
+
*/
|
|
148
|
+
private pageScroll;
|
|
149
|
+
private moveWordBackwards;
|
|
150
|
+
/**
|
|
151
|
+
* Yank (paste) the most recent kill ring entry at cursor position.
|
|
152
|
+
*/
|
|
153
|
+
private yank;
|
|
154
|
+
/**
|
|
155
|
+
* Cycle through kill ring (only works immediately after yank or yank-pop).
|
|
156
|
+
* Replaces the last yanked text with the previous entry in the ring.
|
|
157
|
+
*/
|
|
158
|
+
private yankPop;
|
|
159
|
+
/**
|
|
160
|
+
* Insert text at cursor position (used by yank operations).
|
|
161
|
+
*/
|
|
162
|
+
private insertYankedText;
|
|
163
|
+
/**
|
|
164
|
+
* Delete the previously yanked text (used by yank-pop).
|
|
165
|
+
* The yanked text is derived from killRing[end] since it hasn't been rotated yet.
|
|
166
|
+
*/
|
|
167
|
+
private deleteYankedText;
|
|
168
|
+
/**
|
|
169
|
+
* Add text to the kill ring.
|
|
170
|
+
* If lastAction is "kill", accumulates with the previous entry.
|
|
171
|
+
* @param text - The text to add
|
|
172
|
+
* @param prepend - If accumulating, prepend (true) or append (false) to existing entry
|
|
173
|
+
*/
|
|
174
|
+
private addToKillRing;
|
|
175
|
+
private captureUndoSnapshot;
|
|
176
|
+
private restoreUndoSnapshot;
|
|
177
|
+
private pushUndoSnapshot;
|
|
178
|
+
private undo;
|
|
179
|
+
/**
|
|
180
|
+
* Jump to the first occurrence of a character in the specified direction.
|
|
181
|
+
* Multi-line search. Case-sensitive. Skips the current cursor position.
|
|
182
|
+
*/
|
|
183
|
+
private jumpToChar;
|
|
184
|
+
private moveWordForwards;
|
|
185
|
+
private isSlashMenuAllowed;
|
|
186
|
+
private isAtStartOfMessage;
|
|
187
|
+
private isInSlashCommandContext;
|
|
188
|
+
private tryTriggerAutocomplete;
|
|
189
|
+
private handleTabCompletion;
|
|
190
|
+
private handleSlashCommandCompletion;
|
|
191
|
+
private forceFileAutocomplete;
|
|
192
|
+
private cancelAutocomplete;
|
|
193
|
+
isShowingAutocomplete(): boolean;
|
|
194
|
+
private updateAutocomplete;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/components/editor.ts"],"names":[],"mappings":"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"}
|