strip escape characters when pasting. (#386)

This commit is contained in:
Jacob Richman 2025-05-16 13:17:48 -07:00 committed by GitHub
parent 1728bf3f44
commit 8b959c2060
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 3 deletions

1
package-lock.json generated
View File

@ -8162,6 +8162,7 @@
"read-package-up": "^11.0.0", "read-package-up": "^11.0.0",
"shell-quote": "^1.8.2", "shell-quote": "^1.8.2",
"string-width": "^7.1.0", "string-width": "^7.1.0",
"strip-ansi": "^7.1.0",
"yargs": "^17.7.2" "yargs": "^17.7.2"
}, },
"bin": { "bin": {

View File

@ -43,8 +43,9 @@
"react": "^18.3.1", "react": "^18.3.1",
"read-package-up": "^11.0.0", "read-package-up": "^11.0.0",
"shell-quote": "^1.8.2", "shell-quote": "^1.8.2",
"yargs": "^17.7.2", "string-width": "^7.1.0",
"string-width": "^7.1.0" "strip-ansi": "^7.1.0",
"yargs": "^17.7.2"
}, },
"devDependencies": { "devDependencies": {
"@testing-library/react": "^14.0.0", "@testing-library/react": "^14.0.0",

View File

@ -495,6 +495,14 @@ describe('useTextBuffer', () => {
act(() => result.current.handleInput(undefined, { rightArrow: true })); // cursor [0,2] act(() => result.current.handleInput(undefined, { rightArrow: true })); // cursor [0,2]
expect(getBufferState(result).cursor).toEqual([0, 2]); expect(getBufferState(result).cursor).toEqual([0, 2]);
}); });
it('should strip ANSI escape codes when pasting text', () => {
const { result } = renderHook(() => useTextBuffer({ viewport }));
const textWithAnsi = '\x1B[31mHello\x1B[0m \x1B[32mWorld\x1B[0m';
// Simulate pasting by calling handleInput with a string longer than 1 char
act(() => result.current.handleInput(textWithAnsi, {}));
expect(getBufferState(result).text).toBe('Hello World');
});
}); });
// More tests would be needed for: // More tests would be needed for:

View File

@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
import stripAnsi from 'strip-ansi';
import { spawnSync } from 'child_process'; import { spawnSync } from 'child_process';
import fs from 'fs'; import fs from 'fs';
import os from 'os'; import os from 'os';
@ -1127,7 +1128,12 @@ export function useTextBuffer({
) )
backspace(); backspace();
else if (key['delete']) del(); else if (key['delete']) del();
else if (input && !key['ctrl'] && !key['meta']) insert(input); else if (input && !key['ctrl'] && !key['meta']) {
// Heuristic for paste: if input is longer than 1 char (potential paste)
// strip ANSI escape codes.
const cleanedInput = input.length > 1 ? stripAnsi(input) : input;
insert(cleanedInput);
}
const textChanged = text !== beforeText; const textChanged = text !== beforeText;
// After operations, visualCursor might not be immediately updated if the change // After operations, visualCursor might not be immediately updated if the change