@oxecli/oxe 1.0.14 → 1.0.15
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/dist/ui.js +47 -3
- package/package.json +1 -1
package/dist/ui.js
CHANGED
|
@@ -670,12 +670,37 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
670
670
|
return;
|
|
671
671
|
}
|
|
672
672
|
};
|
|
673
|
-
const
|
|
673
|
+
const shiftSpansAfterInsert = (pos, delta) => {
|
|
674
|
+
const newSpans = [];
|
|
675
|
+
for (const [s, e] of pasteSpans) {
|
|
676
|
+
if (pos <= s)
|
|
677
|
+
newSpans.push([s + delta, e + delta]);
|
|
678
|
+
else if (pos >= e)
|
|
679
|
+
newSpans.push([s, e]);
|
|
680
|
+
else {
|
|
681
|
+
newSpans.push([s, pos]);
|
|
682
|
+
newSpans.push([pos + delta, e + delta]);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return newSpans;
|
|
686
|
+
};
|
|
687
|
+
const insert = (text, isPaste = false) => {
|
|
674
688
|
if (histIdx !== hist.length) {
|
|
675
689
|
draft = { buffer, cursor, spans: pasteSpans.slice() };
|
|
676
690
|
histIdx = hist.length;
|
|
677
691
|
}
|
|
692
|
+
const pasteStart = cursor;
|
|
678
693
|
buffer = buffer.slice(0, cursor) + text + buffer.slice(cursor);
|
|
694
|
+
// Keep existing paste spans valid across the insertion point.
|
|
695
|
+
pasteSpans = shiftSpansAfterInsert(cursor, text.length);
|
|
696
|
+
// A real paste records a span so the prompt box can collapse it (mirrors
|
|
697
|
+
// Python's handle_paste). splitBlocks only collapses segments inside a
|
|
698
|
+
// span that meet the threshold, so small pastes stay expanded but remain
|
|
699
|
+
// tagged for cursor/backspace handling.
|
|
700
|
+
if (isPaste) {
|
|
701
|
+
pasteSpans.push([pasteStart, pasteStart + text.length]);
|
|
702
|
+
pasteSpans.sort((a, b) => a[0] - b[0]);
|
|
703
|
+
}
|
|
679
704
|
cursor += text.length;
|
|
680
705
|
};
|
|
681
706
|
const backspace = () => {
|
|
@@ -689,7 +714,25 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
689
714
|
const before = Array.from(buffer.slice(0, cursor));
|
|
690
715
|
before.pop();
|
|
691
716
|
buffer = before.join("") + buffer.slice(cursor);
|
|
717
|
+
const deletedAt = cursor - 1;
|
|
692
718
|
cursor -= 1;
|
|
719
|
+
// Adjust spans: shrink any span covering the deleted char, shift spans
|
|
720
|
+
// that start after it left by one.
|
|
721
|
+
const adjusted = [];
|
|
722
|
+
for (const [s, e] of pasteSpans) {
|
|
723
|
+
if (deletedAt >= s && deletedAt < e) {
|
|
724
|
+
const ne = e - 1;
|
|
725
|
+
if (s < ne)
|
|
726
|
+
adjusted.push([s, ne]);
|
|
727
|
+
}
|
|
728
|
+
else if (deletedAt < s) {
|
|
729
|
+
adjusted.push([s - 1, e - 1]);
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
adjusted.push([s, e]);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
pasteSpans = adjusted.filter(([s, e]) => s < e);
|
|
693
736
|
};
|
|
694
737
|
const moveLeft = () => {
|
|
695
738
|
if (cursor > 0)
|
|
@@ -782,8 +825,9 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
782
825
|
return;
|
|
783
826
|
}
|
|
784
827
|
if (str) {
|
|
785
|
-
// paste
|
|
786
|
-
|
|
828
|
+
// Multi-char sequence = a paste (single-char typed keys arrive one per
|
|
829
|
+
// event). Tag it so the prompt box collapses it when it meets the rules.
|
|
830
|
+
insert(str, str.length > 1);
|
|
787
831
|
repaint();
|
|
788
832
|
}
|
|
789
833
|
};
|