diff --git a/src/tmux-manager.ts b/src/tmux-manager.ts index 9e2fd296..6c2cde4d 100644 --- a/src/tmux-manager.ts +++ b/src/tmux-manager.ts @@ -3863,9 +3863,14 @@ export class TmuxManager extends EventEmitter implements TerminalMultiplexer { try { const hasCarriageReturn = input.includes('\r'); - // Leading and trailing line breaks are dropped, so `"\nfix it\r"` does not paste - // an empty first line (nor `"fix it\n\r"` an empty last one). - const textPart = input.replace(/\r/g, '').replace(/^\n+/, '').trimEnd(); + // Leading and trailing blank lines are dropped, so neither `"\nfix it\r"` nor + // `" \nfix it\r"` pastes an empty first line (nor `"fix it\n\r"` an empty last + // one). The leading match ends at a line break, so the first real line keeps its + // indentation. + const textPart = input + .replace(/\r/g, '') + .replace(/^\s*\n/, '') + .trimEnd(); if (textPart && hasCarriageReturn) { // Send text first, then Enter as a SEPARATE tmux command after a short delay. diff --git a/test/tmux-submit-paste.test.ts b/test/tmux-submit-paste.test.ts index e76cf820..39eb1d55 100644 --- a/test/tmux-submit-paste.test.ts +++ b/test/tmux-submit-paste.test.ts @@ -261,6 +261,11 @@ describe('sendInput line breaks', () => { await multi.sendInput('s1', '\r\n\r\none\ntwo\r'); expect(bufferText(multi.ran[0])).toBe('one\ntwo'); + // A blank first line made of spaces is dropped too; the first real line keeps its indentation. + const spaced = managerWithSession(); + await spaced.sendInput('s1', ' \n\t\n fix it\nnow\r'); + expect(bufferText(spaced.ran[0])).toBe(' fix it\nnow'); + // Without an Enter, what is left is one line, so it is typed like any other. const typed = managerWithSession(); await typed.sendInput('s1', '\n\njust type');