diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index d39ee8f2..5722faad 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -6,6 +6,7 @@ - Fixed TUI width calculation for regional indicator symbols (e.g. partial flag sequences like `🇨` during streaming) to prevent wrap drift and stale character artifacts in differential rendering. - Fixed Kitty CSI-u handling to ignore unsupported modifiers so modifier-only events do not insert stray printable characters ([#1807](https://github.com/badlogic/pi-mono/issues/1807)) +- Fixed single-line paste performance by inserting pasted text atomically instead of character-by-character, preventing repeated `@` autocomplete scans during paste ([#1812](https://github.com/badlogic/pi-mono/issues/1812)) ## [0.55.4] - 2026-03-02 diff --git a/packages/tui/src/components/editor.ts b/packages/tui/src/components/editor.ts index f6182e01..8eb5773d 100644 --- a/packages/tui/src/components/editor.ts +++ b/packages/tui/src/components/editor.ts @@ -1029,10 +1029,8 @@ export class Editor implements Component, Focusable { } if (pastedLines.length === 1) { - // Single line - insert character by character to trigger autocomplete - for (const char of filteredText) { - this.insertCharacter(char, true); - } + // Single line - insert atomically (do not trigger autocomplete during paste) + this.insertTextAtCursorInternal(filteredText); return; } diff --git a/packages/tui/test/editor.test.ts b/packages/tui/test/editor.test.ts index 4d02374c..1d6e1261 100644 --- a/packages/tui/test/editor.test.ts +++ b/packages/tui/test/editor.test.ts @@ -1496,6 +1496,26 @@ describe("Editor component", () => { assert.strictEqual(editor.getText(), "hello| world"); }); + it("does not trigger autocomplete during single-line paste", () => { + const editor = new Editor(createTestTUI(), defaultEditorTheme); + let suggestionCalls = 0; + + const mockProvider: AutocompleteProvider = { + getSuggestions: () => { + suggestionCalls += 1; + return null; + }, + applyCompletion, + }; + + editor.setAutocompleteProvider(mockProvider); + editor.handleInput("\x1b[200~look at @node_modules/react/index.js please\x1b[201~"); + + assert.strictEqual(editor.getText(), "look at @node_modules/react/index.js please"); + assert.strictEqual(suggestionCalls, 0); + assert.strictEqual(editor.isShowingAutocomplete(), false); + }); + it("undoes multi-line paste atomically", () => { const editor = new Editor(createTestTUI(), defaultEditorTheme);