@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.
Files changed (2) hide show
  1. package/dist/ui.js +47 -3
  2. 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 insert = (text) => {
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 / multi-char sequence
786
- insert(str);
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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxecli/oxe",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },