Co-authored-by: Georgi Chochev <georgi.chochev@siteground.com>
This commit is contained in:
@@ -1088,8 +1088,20 @@ export class Editor implements Component, Focusable {
|
|||||||
|
|
||||||
this.pushUndoSnapshot();
|
this.pushUndoSnapshot();
|
||||||
|
|
||||||
|
// Some terminals (e.g. tmux popups with extended-keys-format=csi-u) re-encode
|
||||||
|
// control bytes inside bracketed paste as CSI-u Ctrl+<letter> sequences
|
||||||
|
// (ESC [ <codepoint> ; 5 u). Decode those back to their literal byte so the
|
||||||
|
// per-char filter below preserves newlines instead of stripping ESC and
|
||||||
|
// leaking the printable tail (e.g. "[106;5u") into the editor.
|
||||||
|
const decodedText = pastedText.replace(/\x1b\[(\d+);5u/g, (match, code) => {
|
||||||
|
const cp = Number(code);
|
||||||
|
if (cp >= 97 && cp <= 122) return String.fromCharCode(cp - 96);
|
||||||
|
if (cp >= 65 && cp <= 90) return String.fromCharCode(cp - 64);
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
|
||||||
// Clean the pasted text: normalize line endings, expand tabs
|
// Clean the pasted text: normalize line endings, expand tabs
|
||||||
const cleanText = this.normalizeText(pastedText);
|
const cleanText = this.normalizeText(decodedText);
|
||||||
|
|
||||||
// Filter out non-printable characters except newlines
|
// Filter out non-printable characters except newlines
|
||||||
let filteredText = cleanText
|
let filteredText = cleanText
|
||||||
|
|||||||
@@ -1677,6 +1677,16 @@ describe("Editor component", () => {
|
|||||||
assert.strictEqual(editor.isShowingAutocomplete(), false);
|
assert.strictEqual(editor.isShowingAutocomplete(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("decodes CSI-u Ctrl+letter sequences inside bracketed paste (tmux popup)", () => {
|
||||||
|
const editor = new Editor(createTestTUI(), defaultEditorTheme);
|
||||||
|
|
||||||
|
// tmux popups with extended-keys-format=csi-u re-encode \n in pastes as
|
||||||
|
// \x1b[106;5u (Ctrl+J). Without decoding, the per-char filter strips ESC
|
||||||
|
// and leaks "[106;5u" between lines. See issue #3599.
|
||||||
|
editor.handleInput("\x1b[200~line1\x1b[106;5uline2\x1b[106;5uline3\x1b[201~");
|
||||||
|
assert.strictEqual(editor.getText(), "line1\nline2\nline3");
|
||||||
|
});
|
||||||
|
|
||||||
it("undoes multi-line paste atomically", () => {
|
it("undoes multi-line paste atomically", () => {
|
||||||
const editor = new Editor(createTestTUI(), defaultEditorTheme);
|
const editor = new Editor(createTestTUI(), defaultEditorTheme);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user