Tuesday, November 12, 2024

macos – When pasting in Terminal.app, `00~` is pasted at the start and `01~` at the end

Short answer: Run the command printf '\e[?2004l'. This sends an escape sequence to the terminal that tells it to stop sending bracketed paste sequences.

Other options: In Terminal.app, you can also reset it with CommandOptionR (or Shell menu > Reset). In iTerm2.app, it’s CommandR or Session menu > Reset. In either app, this also resets a number of other weird modes it might get into, which can be handy.

You can also mostly eliminate the problem by either switching your interactive shell to zsh, or installing a newer version of bash (at least v5.1) and switching to that. These use and understand bracketed pastes, and also reset it before each command, so it can’t get stuck on (well, past the current command anyway).

Long answer: “Bracketed pastes” are a feature that lets the terminal notify the various programs running in the terminal when data is being pasted (as opposed to being typed in like normal). Basically, it sends special “beginning of paste” and “end of paste” escape sequences (\e[200~ and \e[201~ respectively, where \e represents an ASCII escape character). This is so that, for example, the program can treat a pasted multiline document as a single item rather than seeing each line as a separate item. I also have some shell scripts that use it so they can accept a drag-and-dropped item without my having to switch to the terminal window and hit return to indicate the item’s complete.

Generally, when a program understands these sequences and wants to receive them, it’ll send another escape sequence to the terminal (\e[?2004h) to tell it to start sending them. It should send another sequence to turn them off (\e[?2004l) when it exits, but if fails to do that, gets disconnected without exiting cleanly, or some other program runs inside of it, or… then you get these sequences being sent to a program that has no idea what they are, and just interprets them as gibberish.

zsh and bash v5.1+ use bracketed paste mode themselves, and therefore 1) don’t get confused by the escape sequences, and 2) send the sequence to turn bracketed paste off every time you run another program (/command) and the sequence to turn it back on after each program exits, so it’s constantly getting reset to the right state.

(The situation with bash is a bit complicated. macOS only includes bash v3.2.57 by default. Support for bracketed paste was added in v4.4 (with readline 7.0), but seems to be off by default until v5.1. So if you install bash v5.1 or later, and use that as your interactive shell, you shouldn’t have trouble with this.)

Related Articles

Latest Articles