Skip to content

Commit feb92c7

Browse files
authored
Merge pull request #8107 from uinstinct/cli-paste-chars
fix(cli): pasting chunks of lesser than 50 characters
2 parents fec0510 + 9914cd2 commit feb92c7

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

extensions/cli/src/ui/TextBuffer.test.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,12 +526,31 @@ describe("TextBuffer", () => {
526526
buffer.handleInput(largeChunk, { ctrl: false, meta: false } as any);
527527

528528
// Small typed input should not be mixed into paste
529+
const smallChunk = "abc";
530+
buffer.handleInput(smallChunk, { ctrl: false, meta: false } as any);
531+
expect(buffer.text).toBe(""); // Both chunks buffered
532+
533+
buffer.flushPendingInput();
534+
expect(buffer.text).toBe(largeChunk + smallChunk);
535+
});
536+
537+
it("should allow typing after paste accumulation delay", () => {
538+
vi.useFakeTimers();
539+
540+
const largeChunk = "x".repeat(100);
541+
buffer.handleInput(largeChunk, { ctrl: false, meta: false } as any);
542+
543+
// Advance time to simulate user typing after a delay
544+
vi.advanceTimersByTime(60); // so that it is treated as typing
545+
529546
const typedChar = "a";
530547
buffer.handleInput(typedChar, { ctrl: false, meta: false } as any);
531-
expect(buffer.text).toBe("a");
548+
expect(buffer.text).toBe("a"); // Typed char inserted immediately
532549

533-
buffer.flushPendingInput();
550+
vi.advanceTimersByTime(250); // Finalize paste
534551
expect(buffer.text).toBe("a" + largeChunk);
552+
553+
vi.useRealTimers();
535554
});
536555

537556
it("should preserve all chunks when expanding (content loss fix)", () => {

extensions/cli/src/ui/TextBuffer.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -337,26 +337,24 @@ export class TextBuffer {
337337
const timeSinceLastInput = now - this._lastInputTime;
338338

339339
// If we're already in rapid input mode and this comes quickly, add to buffer
340-
// But only if it's a reasonably large chunk - small inputs are likely typing, not paste
341-
// This prevents typed characters from being mixed into paste content during accumulation
342-
if (
343-
this._rapidInputBuffer.length > 0 &&
344-
timeSinceLastInput < 200 &&
345-
input.length >= 50
346-
) {
347-
this._rapidInputBuffer += input;
348-
this._lastInputTime = now;
340+
if (this._rapidInputBuffer.length > 0 && timeSinceLastInput < 200) {
341+
const isLikelyTyping = input.length < 50 && timeSinceLastInput >= 50;
349342

350-
if (this._rapidInputTimer) {
351-
clearTimeout(this._rapidInputTimer);
352-
}
343+
if (!isLikelyTyping) {
344+
this._rapidInputBuffer += input;
345+
this._lastInputTime = now;
353346

354-
// Reset timer: 200ms pause indicates end of paste
355-
this._rapidInputTimer = setTimeout(() => {
356-
this.finalizeRapidInput();
357-
}, 200);
347+
if (this._rapidInputTimer) {
348+
clearTimeout(this._rapidInputTimer);
349+
}
358350

359-
return true;
351+
// Reset timer: 200ms pause indicates end of paste
352+
this._rapidInputTimer = setTimeout(() => {
353+
this.finalizeRapidInput();
354+
}, 200);
355+
356+
return true;
357+
}
360358
}
361359

362360
// Fallback paste detection: some terminals send large pastes as rapid chunks

0 commit comments

Comments
 (0)