Change:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.77.3 OS Version: Ubuntu 20.04.6 Steps to Reproduce: VSCode on an Ubuntu computer (or on Windows using WSL) the built-in terminal the command and paste the following 39-character string into nano: : nano shows the error message "Unknown Sequence". Can no longer interact with the terminal, need to kill it and open a new one More details: nano version 4.8 This does not happen in nano using an external terminal. Only in VSCode's built-in terminal This does not happen for any other length of string, even other multiples of 39 This does not happen in other CLI text editors, such as vim
I can confirm this issue on Windows using WSL.
It happens with other 39 long strings as well. It also happens when not using WSL. Copying more characters solves the problem. For us it also happens with multiples of 39 (e.g. 156 characters, line breaks included)
When trace logs are enabled this is the exact sequence we send: Compared to 1 less : Note that the 200/201 wrapped around it is bracketed paste mode (which I just a way to disable so that may help ). So this seems to be either a problem with one of nano, conpty or node-pty.
I also just ran into this. I'm on Windows 10, using Remote - SSH plugin to connect to an Ubuntu 22.04 server. Right-click to paste in Nano, terminal locks up, have to Kill it. Add/remove one character from the string and try again, works.
We closed this issue because we in the foreseeable future. If you disagree and feel that this issue is crucial: we are happy to listen and to reconsider. If you wonder what we are up to, please see our and . Thanks for your understanding, and happy coding!
i opened a bug on gnu nano's bugtracker:
I think I found a workaround, but haven't tested it: vscode , nano doesn't deal well with across writes and it is apparently difficult to fix in nano. vscode could split writes differently, using this algorithm that keeps escape sequences at the beginning and end unsplit (like bracketed pastes):
great info, we should definitely do this . I'll probably tweak your proposal a little to try catch escape sequences in the middle too.
I don't expect input sizes to be 50 bytes except when pasting, when pasting there should only ever be an escape sequence at the beginning and end, never in the middle (terminal apps are unlikely to deal well with pasting a string containing escape sequences anyway).
unless I missed something in the issue you linked, it's not that they need to be on the boundaries of the text but need to be included entirely in that string and not clipped?
yes, escape sequences need to be contained entirely in one write syscall. basically I am saying you shouldn't have escape sequences in the middle of a long input, so you don't need to look for them to avoid splitting them, they should only occur towards the ends of a long input or in a shorter input.
Nano's workaround was released in Nano 8.0:

Discussion:
rows: number; data: string; } <ins> const enum Constants { /** * Writing large amounts of data can be corrupted for some reason, after looking into this is * appears to be a race condition around writing to the FD which may be based on how powerful * the hardware is. The workaround for this is to space out when large amounts of data is being * written to the terminal. See https://github.com/microsoft/vscode/issues/38137 */ WriteMaxChunkSize = 50, } /** * Splits incoming pty data into chunks to try prevent data corruption that could occur when pasting * large amounts of data. */ export function chunkInput(data: string): string[] { const chunks: string[] = []; let nextChunkStartIndex = 0; for (let i = 0; i < data.length - 1; i++) { if ( // If the max chunk size is reached i - nextChunkStartIndex + 1 >= Constants.WriteMaxChunkSize || // If the next character is ESC, send the pending data to avoid splitting the escape // sequence. data[i + 1] === 'x1b' ) { chunks.push(data.substring(nextChunkStartIndex, i + 1)); nextChunkStartIndex = i + 1; // Skip the next character as the chunk would be a single character i++; } } // Push final chunk if (nextChunkStartIndex !== data.length) { chunks.push(data.substring(nextChunkStartIndex)); } return chunks; } </ins>

import { findExecutable, getShellIntegrationInjection, getWindowsBuildNumber, IShellIntegrationConfigInjection } from 'vs/platform/terminal/node/terminalEnvironment'; import { WindowsShellHelper } from 'vs/platform/terminal/node/windowsShellHelper'; import { IPty, IPtyForkOptions, IWindowsPtyForkOptions, spawn } from 'node-pty'; <ins> import { chunkInput } from 'vs/platform/terminal/common/terminalProcess'; </ins> const enum ShutdownConstants { /**

* interval. */ KillSpawnSpacingDuration = 50, <del> /** * Writing large amounts of data can be corrupted for some reason, after looking into this is * appears to be a race condition around writing to the FD which may be based on how powerful * the hardware is. The workaround for this is to space out when large amounts of data is being * written to the terminal. See https://github.com/microsoft/vscode/issues/38137 */ WriteMaxChunkSize = 50, </del> /** * How long to wait between chunk writes. */

} } <del> input(data: string, isBinary?: boolean): void { </del> <ins> input(data: string, isBinary: boolean = false): void { </ins> if (this._store.isDisposed || !this._ptyProcess) { return; } <del> for (let i = 0; i <= Math.floor(data.length / Constants.WriteMaxChunkSize); i++) { const obj = { isBinary: isBinary || false, data: data.substr(i * Constants.WriteMaxChunkSize, Constants.WriteMaxChunkSize) }; this._writeQueue.push(obj); } </del> <ins> this._writeQueue.push(...chunkInput(data).map(e => { return { isBinary, data: e }; })); </ins> this._startWrite(); }

<ins> /*--------------------------------------------------------------------------------------------- *  Copyright (c) Microsoft Corporation. All rights reserved. *  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { deepStrictEqual } from 'assert'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { chunkInput } from 'vs/platform/terminal/common/terminalProcess'; suite('platform - terminalProcess', () => { ensureNoDisposablesAreLeakedInTestSuite(); suite('chunkInput', () => { test('single chunk', () => { deepStrictEqual(chunkInput('foo bar'), ['foo bar']); }); test('multi chunk', () => { deepStrictEqual(chunkInput('foo'.repeat(50)), [ 'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo', 'ofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof', 'oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo' ]); }); test('small data with escapes', () => { deepStrictEqual(chunkInput('foo x1b[30mbar'), [ 'foo ', 'x1b[30mbar' ]); }); test('large data with escapes', () => { deepStrictEqual(chunkInput('foofoofoofoox1b[30mbarbarbarbarbarx1b[0m'.repeat(3)), [ 'foofoofoofoo', 'x1B[30mbarbarbarbarbar', 'x1B[0mfoofoofoofoo', 'x1B[30mbarbarbarbarbar', 'x1B[0mfoofoofoofoo', 'x1B[30mbarbarbarbarbar', 'x1B[0m' ]); }); }); }); </ins>