@fractaal/pi-tui 0.85.4 → 0.86.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/README.md +175 -19
- package/dist/alt-screen-search.d.ts +46 -0
- package/dist/alt-screen-search.d.ts.map +1 -0
- package/dist/alt-screen-search.js +282 -0
- package/dist/alt-screen-search.js.map +1 -0
- package/dist/autocomplete.d.ts +2 -1
- package/dist/autocomplete.d.ts.map +1 -1
- package/dist/autocomplete.js +85 -24
- package/dist/autocomplete.js.map +1 -1
- package/dist/colors.d.ts +73 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +273 -0
- package/dist/colors.js.map +1 -0
- package/dist/components/alt-screen-flash.d.ts +13 -0
- package/dist/components/alt-screen-flash.d.ts.map +1 -0
- package/dist/components/alt-screen-flash.js +37 -0
- package/dist/components/alt-screen-flash.js.map +1 -0
- package/dist/components/box.d.ts +3 -1
- package/dist/components/box.d.ts.map +1 -1
- package/dist/components/box.js +38 -8
- package/dist/components/box.js.map +1 -1
- package/dist/components/cancellable-loader.d.ts.map +1 -1
- package/dist/components/cancellable-loader.js.map +1 -1
- package/dist/components/editor.d.ts +6 -1
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +118 -24
- package/dist/components/editor.js.map +1 -1
- package/dist/components/h-stack.d.ts +7 -0
- package/dist/components/h-stack.d.ts.map +1 -0
- package/dist/components/h-stack.js +43 -0
- package/dist/components/h-stack.js.map +1 -0
- package/dist/components/image.d.ts +12 -0
- package/dist/components/image.d.ts.map +1 -1
- package/dist/components/image.js +36 -3
- package/dist/components/image.js.map +1 -1
- package/dist/components/input.d.ts +12 -1
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +44 -5
- package/dist/components/input.js.map +1 -1
- package/dist/components/loader.d.ts +2 -0
- package/dist/components/loader.d.ts.map +1 -1
- package/dist/components/loader.js +10 -3
- package/dist/components/loader.js.map +1 -1
- package/dist/components/markdown.d.ts +5 -0
- package/dist/components/markdown.d.ts.map +1 -1
- package/dist/components/markdown.js +150 -9
- package/dist/components/markdown.js.map +1 -1
- package/dist/components/mouse-region.d.ts +12 -0
- package/dist/components/mouse-region.d.ts.map +1 -0
- package/dist/components/mouse-region.js +21 -0
- package/dist/components/mouse-region.js.map +1 -0
- package/dist/components/scroll-view.d.ts +59 -0
- package/dist/components/scroll-view.d.ts.map +1 -0
- package/dist/components/scroll-view.js +195 -0
- package/dist/components/scroll-view.js.map +1 -0
- package/dist/components/select-list.d.ts +4 -1
- package/dist/components/select-list.d.ts.map +1 -1
- package/dist/components/select-list.js +49 -2
- package/dist/components/select-list.js.map +1 -1
- package/dist/components/settings-list.d.ts +13 -3
- package/dist/components/settings-list.d.ts.map +1 -1
- package/dist/components/settings-list.js +82 -15
- package/dist/components/settings-list.js.map +1 -1
- package/dist/components/spacer.d.ts.map +1 -1
- package/dist/components/spacer.js.map +1 -1
- package/dist/components/stack.d.ts +32 -0
- package/dist/components/stack.d.ts.map +1 -0
- package/dist/components/stack.js +111 -0
- package/dist/components/stack.js.map +1 -0
- package/dist/components/text.d.ts.map +1 -1
- package/dist/components/text.js +7 -5
- package/dist/components/text.js.map +1 -1
- package/dist/components/truncated-text.d.ts.map +1 -1
- package/dist/components/truncated-text.js.map +1 -1
- package/dist/components/v-stack.d.ts +8 -0
- package/dist/components/v-stack.d.ts.map +1 -0
- package/dist/components/v-stack.js +26 -0
- package/dist/components/v-stack.js.map +1 -0
- package/dist/editor-component.d.ts.map +1 -1
- package/dist/fuzzy.d.ts.map +1 -1
- package/dist/fuzzy.js +23 -22
- package/dist/fuzzy.js.map +1 -1
- package/dist/index.d.ts +18 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -6
- package/dist/index.js.map +1 -1
- package/dist/keybindings.d.ts +82 -2
- package/dist/keybindings.d.ts.map +1 -1
- package/dist/keybindings.js +61 -2
- package/dist/keybindings.js.map +1 -1
- package/dist/keys.d.ts.map +1 -1
- package/dist/keys.js.map +1 -1
- package/dist/kill-ring.d.ts.map +1 -1
- package/dist/kill-ring.js.map +1 -1
- package/dist/latex.d.ts +10 -0
- package/dist/latex.d.ts.map +1 -0
- package/dist/latex.js +1378 -0
- package/dist/latex.js.map +1 -0
- package/dist/layout-node.d.ts +40 -0
- package/dist/layout-node.d.ts.map +1 -0
- package/dist/layout-node.js +6 -0
- package/dist/layout-node.js.map +1 -0
- package/dist/layout.d.ts +42 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +344 -0
- package/dist/layout.js.map +1 -0
- package/dist/native-modifiers.d.ts +2 -1
- package/dist/native-modifiers.d.ts.map +1 -1
- package/dist/native-modifiers.js +3 -43
- package/dist/native-modifiers.js.map +1 -1
- package/dist/native-module-path.d.ts +7 -0
- package/dist/native-module-path.d.ts.map +1 -0
- package/dist/native-module-path.js +19 -0
- package/dist/native-module-path.js.map +1 -0
- package/dist/native-platform.d.ts +20 -0
- package/dist/native-platform.d.ts.map +1 -0
- package/dist/native-platform.js +42 -0
- package/dist/native-platform.js.map +1 -0
- package/dist/oklab.d.ts +43 -0
- package/dist/oklab.d.ts.map +1 -0
- package/dist/oklab.js +210 -0
- package/dist/oklab.js.map +1 -0
- package/dist/stdin-buffer.d.ts +8 -2
- package/dist/stdin-buffer.d.ts.map +1 -1
- package/dist/stdin-buffer.js +7 -2
- package/dist/stdin-buffer.js.map +1 -1
- package/dist/terminal-colors.d.ts +19 -2
- package/dist/terminal-colors.d.ts.map +1 -1
- package/dist/terminal-colors.js +13 -8
- package/dist/terminal-colors.js.map +1 -1
- package/dist/terminal-image.d.ts +29 -1
- package/dist/terminal-image.d.ts.map +1 -1
- package/dist/terminal-image.js +223 -18
- package/dist/terminal-image.js.map +1 -1
- package/dist/terminal.d.ts +16 -0
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +62 -46
- package/dist/terminal.js.map +1 -1
- package/dist/tui-alt-screen.d.ts +166 -0
- package/dist/tui-alt-screen.d.ts.map +1 -0
- package/dist/tui-alt-screen.js +1546 -0
- package/dist/tui-alt-screen.js.map +1 -0
- package/dist/tui-main-screen.d.ts +39 -0
- package/dist/tui-main-screen.d.ts.map +1 -0
- package/dist/tui-main-screen.js +594 -0
- package/dist/tui-main-screen.js.map +1 -0
- package/dist/tui.d.ts +178 -60
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +303 -641
- package/dist/tui.js.map +1 -1
- package/dist/undo-stack.d.ts.map +1 -1
- package/dist/undo-stack.js.map +1 -1
- package/dist/utils.d.ts +22 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +245 -63
- package/dist/utils.js.map +1 -1
- package/dist/wheel-scroll.d.ts +23 -0
- package/dist/wheel-scroll.d.ts.map +1 -0
- package/dist/wheel-scroll.js +73 -0
- package/dist/wheel-scroll.js.map +1 -0
- package/dist/word-navigation.d.ts.map +1 -1
- package/dist/word-navigation.js.map +1 -1
- package/native/clipboard.h +208 -0
- package/native/darwin/README.md +22 -0
- package/native/darwin/build.sh +69 -0
- package/native/darwin/prebuilds/darwin-arm64/{darwin-modifiers.node → darwin-platform.node} +0 -0
- package/native/darwin/prebuilds/darwin-x64/darwin-platform.node +0 -0
- package/native/darwin/src/darwin-platform.m +132 -0
- package/native/linux/README.md +23 -0
- package/native/linux/build.sh +65 -0
- package/native/linux/prebuilds/linux-arm64/linux-platform-x11.node +0 -0
- package/native/linux/prebuilds/linux-x64/linux-platform-x11.node +0 -0
- package/native/linux/src/clipboard-worker.h +70 -0
- package/native/linux/src/linux-platform-x11.c +274 -0
- package/native/napi.h +91 -0
- package/native/win32/README.md +31 -0
- package/native/win32/build.mjs +232 -0
- package/native/win32/prebuilds/win32-arm64/win32-platform.node +0 -0
- package/native/win32/prebuilds/win32-x64/win32-platform.node +0 -0
- package/native/win32/src/win32-platform.c +241 -0
- package/package.json +19 -4
- package/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getKeybindings } from "../keybindings.js";
|
|
2
2
|
import { decodePrintableKey, matchesKey } from "../keys.js";
|
|
3
3
|
import { KillRing } from "../kill-ring.js";
|
|
4
|
-
import { CURSOR_MARKER } from "../tui.js";
|
|
4
|
+
import { CURSOR_MARKER, } from "../tui.js";
|
|
5
5
|
import { UndoStack } from "../undo-stack.js";
|
|
6
|
-
import { cjkBreakRegex, getGraphemeSegmenter, getWordSegmenter, isWhitespaceChar, sliceByColumn, visibleWidth, } from "../utils.js";
|
|
6
|
+
import { autocompleteBoundaryRegex, autocompleteSeparatorRegex, cjkBreakRegex, getGraphemeSegmenter, getWordSegmenter, isWhitespaceChar, sliceByColumn, visibleWidth, } from "../utils.js";
|
|
7
7
|
import { findWordBackward, findWordForward } from "../word-navigation.js";
|
|
8
8
|
import { SelectList } from "./select-list.js";
|
|
9
9
|
const graphemeSegmenter = getGraphemeSegmenter();
|
|
@@ -168,18 +168,28 @@ const SLASH_COMMAND_SELECT_LIST_LAYOUT = {
|
|
|
168
168
|
};
|
|
169
169
|
const ATTACHMENT_AUTOCOMPLETE_DEBOUNCE_MS = 20;
|
|
170
170
|
const DEFAULT_AUTOCOMPLETE_TRIGGER_CHARACTERS = ["@", "#"];
|
|
171
|
+
// Unquoted completions end at whitespace or CJK punctuation; quoted paths may contain either.
|
|
172
|
+
const unquotedAutocompleteSuffixRegex = new RegExp(`(?:(?!${autocompleteSeparatorRegex.source}).)*`, "u");
|
|
173
|
+
// Trigger tokens may be wrapped in prose, e.g. "(@src/foo" or "`@src/foo".
|
|
174
|
+
const autocompleteTokenStartSource = `${autocompleteBoundaryRegex.source}[([{<\`]*`;
|
|
171
175
|
function escapeCharacterClass(value) {
|
|
172
176
|
return value.replace(/[\\^$.*+?()[\]{}|-]/g, "\\$&");
|
|
173
177
|
}
|
|
174
178
|
function buildTriggerPattern(triggerCharacters) {
|
|
175
|
-
return new RegExp(
|
|
179
|
+
return new RegExp(`${autocompleteTokenStartSource}(?:@"[^"]*|[${triggerCharacters.map(escapeCharacterClass).join("")}]${unquotedAutocompleteSuffixRegex.source})$`, "u");
|
|
176
180
|
}
|
|
177
181
|
function buildDebouncePattern(triggerCharacters) {
|
|
178
182
|
const escapedWithoutAt = triggerCharacters.filter((character) => character !== "@").map(escapeCharacterClass);
|
|
179
|
-
return new RegExp(
|
|
183
|
+
return new RegExp(`${autocompleteTokenStartSource}(?:@(?:"[^"]*|${unquotedAutocompleteSuffixRegex.source})|[${escapedWithoutAt.join("")}]${unquotedAutocompleteSuffixRegex.source})$`, "u");
|
|
180
184
|
}
|
|
181
185
|
function createScrollBorder(direction, hiddenLineCount, width) {
|
|
182
186
|
const availableWidth = Math.max(0, width);
|
|
187
|
+
const label = ` ${direction} ${hiddenLineCount} more `;
|
|
188
|
+
const labelWidth = visibleWidth(label);
|
|
189
|
+
if (labelWidth + 2 <= availableWidth) {
|
|
190
|
+
const leftWidth = Math.floor((availableWidth - labelWidth) / 2);
|
|
191
|
+
return "─".repeat(leftWidth) + label + "─".repeat(availableWidth - leftWidth - labelWidth);
|
|
192
|
+
}
|
|
183
193
|
const indicator = `─── ${direction} ${hiddenLineCount} more `;
|
|
184
194
|
const remaining = availableWidth - visibleWidth(indicator);
|
|
185
195
|
if (remaining >= 0)
|
|
@@ -199,8 +209,10 @@ export class Editor {
|
|
|
199
209
|
tui;
|
|
200
210
|
theme;
|
|
201
211
|
paddingX = 0;
|
|
202
|
-
// Store last render
|
|
212
|
+
// Store last render geometry for cursor navigation and mouse hit-testing.
|
|
203
213
|
lastWidth = 80;
|
|
214
|
+
renderedVisibleLineCount = 1;
|
|
215
|
+
renderedAutocompleteHeight = 0;
|
|
204
216
|
// Vertical scrolling support
|
|
205
217
|
scrollOffset = 0;
|
|
206
218
|
// Border color (can be changed dynamically)
|
|
@@ -370,6 +382,14 @@ export class Editor {
|
|
|
370
382
|
invalidate() {
|
|
371
383
|
// No cached state to invalidate currently
|
|
372
384
|
}
|
|
385
|
+
renderTopBorder(width, hiddenLineCount) {
|
|
386
|
+
const border = hiddenLineCount > 0 ? createScrollBorder("↑", hiddenLineCount, width) : "─".repeat(width);
|
|
387
|
+
return this.borderColor(border);
|
|
388
|
+
}
|
|
389
|
+
renderBottomBorder(width, hiddenLineCount) {
|
|
390
|
+
const border = hiddenLineCount > 0 ? createScrollBorder("↓", hiddenLineCount, width) : "─".repeat(width);
|
|
391
|
+
return this.borderColor(border);
|
|
392
|
+
}
|
|
373
393
|
render(width) {
|
|
374
394
|
const maxPadding = Math.max(0, Math.floor((width - 1) / 2));
|
|
375
395
|
const paddingX = Math.min(this.paddingX, maxPadding);
|
|
@@ -379,7 +399,6 @@ export class Editor {
|
|
|
379
399
|
const layoutWidth = Math.max(1, contentWidth - (paddingX ? 0 : 1));
|
|
380
400
|
// Store for cursor navigation (must match wrapping width)
|
|
381
401
|
this.lastWidth = layoutWidth;
|
|
382
|
-
const horizontal = this.borderColor("─");
|
|
383
402
|
// Layout the text
|
|
384
403
|
const layoutLines = this.layoutText(layoutWidth);
|
|
385
404
|
// Calculate max visible lines: 30% of terminal height, minimum 5 lines
|
|
@@ -401,17 +420,12 @@ export class Editor {
|
|
|
401
420
|
this.scrollOffset = Math.max(0, Math.min(this.scrollOffset, maxScrollOffset));
|
|
402
421
|
// Get visible lines slice
|
|
403
422
|
const visibleLines = layoutLines.slice(this.scrollOffset, this.scrollOffset + maxVisibleLines);
|
|
423
|
+
this.renderedVisibleLineCount = visibleLines.length;
|
|
404
424
|
const result = [];
|
|
405
425
|
const leftPadding = " ".repeat(paddingX);
|
|
406
426
|
const rightPadding = leftPadding;
|
|
407
427
|
// Render top border (with scroll indicator if scrolled down)
|
|
408
|
-
|
|
409
|
-
const border = createScrollBorder("↑", this.scrollOffset, width);
|
|
410
|
-
result.push(this.borderColor(border));
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
result.push(horizontal.repeat(width));
|
|
414
|
-
}
|
|
428
|
+
result.push(this.renderTopBorder(width, this.scrollOffset));
|
|
415
429
|
// Render each visible layout line
|
|
416
430
|
// Emit hardware cursor marker when focused so TUI can position the
|
|
417
431
|
// hardware cursor for IME candidate-window placement even while
|
|
@@ -456,16 +470,12 @@ export class Editor {
|
|
|
456
470
|
}
|
|
457
471
|
// Render bottom border (with scroll indicator if more content below)
|
|
458
472
|
const linesBelow = layoutLines.length - (this.scrollOffset + visibleLines.length);
|
|
459
|
-
|
|
460
|
-
const border = createScrollBorder("↓", linesBelow, width);
|
|
461
|
-
result.push(this.borderColor(border));
|
|
462
|
-
}
|
|
463
|
-
else {
|
|
464
|
-
result.push(horizontal.repeat(width));
|
|
465
|
-
}
|
|
473
|
+
result.push(this.renderBottomBorder(width, linesBelow));
|
|
466
474
|
// Add autocomplete list if active
|
|
475
|
+
this.renderedAutocompleteHeight = 0;
|
|
467
476
|
if (this.autocompleteState && this.autocompleteList) {
|
|
468
477
|
const autocompleteResult = this.autocompleteList.render(contentWidth);
|
|
478
|
+
this.renderedAutocompleteHeight = autocompleteResult.length;
|
|
469
479
|
for (const line of autocompleteResult) {
|
|
470
480
|
const lineWidth = visibleWidth(line);
|
|
471
481
|
const linePadding = " ".repeat(Math.max(0, contentWidth - lineWidth));
|
|
@@ -474,6 +484,67 @@ export class Editor {
|
|
|
474
484
|
}
|
|
475
485
|
return result;
|
|
476
486
|
}
|
|
487
|
+
handleMouse(event) {
|
|
488
|
+
const autocompleteStartRow = this.renderedVisibleLineCount + 2;
|
|
489
|
+
if (this.autocompleteState &&
|
|
490
|
+
this.autocompleteList &&
|
|
491
|
+
event.y >= autocompleteStartRow &&
|
|
492
|
+
event.y < autocompleteStartRow + this.renderedAutocompleteHeight) {
|
|
493
|
+
const maxPadding = Math.max(0, Math.floor((event.width - 1) / 2));
|
|
494
|
+
const paddingX = Math.min(this.paddingX, maxPadding);
|
|
495
|
+
const contentWidth = Math.max(1, event.width - paddingX * 2);
|
|
496
|
+
const result = this.autocompleteList.handleMouse?.({
|
|
497
|
+
...event,
|
|
498
|
+
x: event.x - paddingX,
|
|
499
|
+
y: event.y - autocompleteStartRow,
|
|
500
|
+
width: contentWidth,
|
|
501
|
+
height: this.renderedAutocompleteHeight,
|
|
502
|
+
});
|
|
503
|
+
return result ? { ...result, focus: true } : undefined;
|
|
504
|
+
}
|
|
505
|
+
// Leave press/drag/release unhandled so the renderer's screen-level text
|
|
506
|
+
// selection can run over the editor rows (drag to select, release to copy).
|
|
507
|
+
// The renderer synthesizes a click when press and release land on the same
|
|
508
|
+
// cell without movement, which is the gesture that positions the cursor.
|
|
509
|
+
if (event.type !== "click" || event.button !== "left")
|
|
510
|
+
return undefined;
|
|
511
|
+
if (event.y <= 0 || event.y > this.renderedVisibleLineCount)
|
|
512
|
+
return { handled: true, focus: true };
|
|
513
|
+
const visualLines = this.buildVisualLineMap(this.lastWidth);
|
|
514
|
+
const visualLineIndex = this.scrollOffset + event.y - 1;
|
|
515
|
+
const visualLine = visualLines[visualLineIndex];
|
|
516
|
+
if (!visualLine)
|
|
517
|
+
return { handled: true, focus: true };
|
|
518
|
+
const logicalLine = this.state.lines[visualLine.logicalLine] ?? "";
|
|
519
|
+
const chunkEnd = visualLine.startCol + visualLine.length;
|
|
520
|
+
const chunk = logicalLine.slice(visualLine.startCol, chunkEnd);
|
|
521
|
+
const maxPadding = Math.max(0, Math.floor((event.width - 1) / 2));
|
|
522
|
+
const paddingX = Math.min(this.paddingX, maxPadding);
|
|
523
|
+
const targetColumn = Math.max(0, event.x - paddingX);
|
|
524
|
+
let visibleColumn = 0;
|
|
525
|
+
let targetIndex = chunk.length;
|
|
526
|
+
let lastGraphemeIndex = 0;
|
|
527
|
+
for (const grapheme of this.segment(chunk, "grapheme")) {
|
|
528
|
+
const nextColumn = visibleColumn + visibleWidth(grapheme.segment);
|
|
529
|
+
lastGraphemeIndex = grapheme.index;
|
|
530
|
+
if (targetColumn < nextColumn) {
|
|
531
|
+
targetIndex = grapheme.index;
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
visibleColumn = nextColumn;
|
|
535
|
+
}
|
|
536
|
+
const isLastSegment = visualLineIndex === visualLines.length - 1 ||
|
|
537
|
+
visualLines[visualLineIndex + 1]?.logicalLine !== visualLine.logicalLine;
|
|
538
|
+
if (!isLastSegment && targetIndex === chunk.length && chunk.length > 0)
|
|
539
|
+
targetIndex = lastGraphemeIndex;
|
|
540
|
+
this.state.cursorLine = visualLine.logicalLine;
|
|
541
|
+
this.setCursorCol(visualLine.startCol + targetIndex);
|
|
542
|
+
this.lastAction = null;
|
|
543
|
+
this.exitHistoryBrowsing();
|
|
544
|
+
if (this.autocompleteState)
|
|
545
|
+
this.updateAutocomplete();
|
|
546
|
+
return { handled: true, focus: true };
|
|
547
|
+
}
|
|
477
548
|
handleInput(data) {
|
|
478
549
|
const kb = getKeybindings();
|
|
479
550
|
// Handle character jump mode (awaiting next character to jump to)
|
|
@@ -613,6 +684,17 @@ export class Editor {
|
|
|
613
684
|
this.yankPop();
|
|
614
685
|
return;
|
|
615
686
|
}
|
|
687
|
+
// Dedicated history actions always browse entries instead of moving the cursor.
|
|
688
|
+
if (kb.matches(data, "tui.editor.historyPrevious")) {
|
|
689
|
+
this.cancelAutocomplete();
|
|
690
|
+
this.navigateHistory(-1);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
if (kb.matches(data, "tui.editor.historyNext")) {
|
|
694
|
+
this.cancelAutocomplete();
|
|
695
|
+
this.navigateHistory(1);
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
616
698
|
// Cursor movement actions
|
|
617
699
|
if (kb.matches(data, "tui.editor.cursorLineStart")) {
|
|
618
700
|
this.moveToLineStart();
|
|
@@ -943,13 +1025,12 @@ export class Editor {
|
|
|
943
1025
|
else if (this.autocompleteTriggerCharacters.includes(char)) {
|
|
944
1026
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
945
1027
|
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
946
|
-
|
|
947
|
-
if (textBeforeCursor.length === 1 || charBeforeSymbol === " " || charBeforeSymbol === "\t") {
|
|
1028
|
+
if (this.autocompleteTriggerPattern.test(textBeforeCursor)) {
|
|
948
1029
|
this.tryTriggerAutocomplete();
|
|
949
1030
|
}
|
|
950
1031
|
}
|
|
951
1032
|
// Also auto-trigger when typing letters in a slash command or symbol completion context
|
|
952
|
-
else if (/[a-zA-Z0-9.\-_]/.test(char)) {
|
|
1033
|
+
else if (/[a-zA-Z0-9.\-_]/.test(char) || cjkBreakRegex.test(char)) {
|
|
953
1034
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
954
1035
|
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
955
1036
|
// Check if we're in a slash command (with or without space for arguments)
|
|
@@ -1793,7 +1874,20 @@ export class Editor {
|
|
|
1793
1874
|
}
|
|
1794
1875
|
createAutocompleteList(prefix, items) {
|
|
1795
1876
|
const layout = prefix.startsWith("/") ? SLASH_COMMAND_SELECT_LIST_LAYOUT : undefined;
|
|
1796
|
-
|
|
1877
|
+
const list = new SelectList(items, this.autocompleteMaxVisible, this.theme.selectList, layout);
|
|
1878
|
+
list.onSelect = (selected) => {
|
|
1879
|
+
if (!this.autocompleteProvider)
|
|
1880
|
+
return;
|
|
1881
|
+
this.pushUndoSnapshot();
|
|
1882
|
+
this.lastAction = null;
|
|
1883
|
+
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
|
|
1884
|
+
this.state.lines = result.lines;
|
|
1885
|
+
this.state.cursorLine = result.cursorLine;
|
|
1886
|
+
this.setCursorCol(result.cursorCol);
|
|
1887
|
+
this.cancelAutocomplete();
|
|
1888
|
+
this.onChange?.(this.getText());
|
|
1889
|
+
};
|
|
1890
|
+
return list;
|
|
1797
1891
|
}
|
|
1798
1892
|
tryTriggerAutocomplete(explicitTab = false) {
|
|
1799
1893
|
this.requestAutocomplete({ force: false, explicitTab });
|