terminal: implement DECSTR soft reset (CSI ! p)#13333
Conversation
mitchellh
left a comment
There was a problem hiding this comment.
Seems reasonable to support, obviously not widely used but also low risk to do. I'd be curious to know what other terminals do with some verification (because LLMs will make that shit up).
| } | ||
|
|
||
| /// Soft terminal reset (DECSTR, `CSI ! p`). Unlike `fullReset` (RIS), resets | ||
| /// programmable state to power-up defaults without clearing the screen or |
There was a problem hiding this comment.
I think this comment needs some work, e.g. "power-up defaults" is confusing in the context of a non-hardware terminal. I'd be clearer about what the spec says (probably this) and what the practical implementation is for terminal emulators.
|
Some extra context that I didn't want to land in the body of the commit in case this gets merged: Re: verification — every claim below is a permalink pinned to a commit SHA, quoting the line it rests on, so none of it has to be taken on faith.
Takeaway: the spec resets autowrap OFF, but every emulator that implements DECSTR resets it ON. This PR sides with the implementers. None of them clear the screen or move the cursor, matching us. xterm documents this deviation deliberatelyThe clearest statement of spec-vs-practice comes from xterm itself:
So it's a deliberate compatibility choice, not an oversight — which is why I'd rather match it than the letter of the spec. Spec (VT510)The DECSTR table lists DECAWM as "No autowrap", alongside DECTCEM "Cursor enabled", IRM "Replace mode", DECOM "Absolute", DECSCA "Normal (erasable by DECSEL and DECSED)", DECSTBM "Top margin = 1; bottom margin = page length", DECSC "Home position". (Citing the VT510 manual specifically; xterm cites DEC STD 070 p. 14-9 for the same sequence.) xterm — ON
VTE — ON (with a caveat worth flagging)
constexpr Private() : Self{eDEC_AUTOWRAP, eDEC_TEXT_CURSOR, ...}Caveat, because it looks like a contradiction if you go looking: conhost / Windows Terminal — ON_api.SetSystemMode(ITerminalApi::Mode::AutoWrap, true); // Wrap at end of line.No clear, no cursor move. It also resets only the active saved-cursor slot, matching xterm's alt-buffer behaviour (GH#19918) — same as this PR. kitty — ON, as of todayAdded in One honest caveat: kitty's soft reset is broader than the others (it also resets tabstops, colours, selections, and the parser), so "kitty matches" holds for autowrap/clear/cursor but they aren't identical implementations. Kovid's own commit message notes the sequence "is largely undefined ... Do what I feel is sensible in these cases." |
CSI ! p was logged as unimplemented and ignored, so mode, SGR, charset, and scroll-region state set by a program leaked past a soft reset. Reset the programmable state to its defaults (cursor visible, replace mode, absolute origin, autowrap on, default SGR, ASCII charsets, full scrolling region, unprotected, cleared saved cursor) without touching the screen contents or the cursor position. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
33a6b17 to
24efbab
Compare
The CSI exclamation point p sequence, known as DECSTR or soft terminal reset, was logged as unimplemented and simply ignored.
Because of that, any settings a program had applied, such as the scroll region, origin mode, SGR attributes, or character set, stayed in effect.
Later output then appeared in the wrong position, with the wrong color, or in the wrong character set until a full reset with RIS or the reset command fixed it.DECSTR resets the terminal's programmable state back to power-up defaults according to DEC STD 070. This includes making the cursor visible, switching to replace mode, using absolute origin, turning autowrap on, applying default SGR, selecting ASCII character sets, setting the full scrolling region, removing protection, and clearing the saved cursor position. Unlike RIS, it leaves the screen contents untouched and does not move the cursor.
Repro
Drop the
\e[!pto see today's behavior: the text lands mangled in theleftover scroll region, DEC line-drawing charset, and SGR.
Before / after
Same reproducer fed through the terminal model. Left:
CSI ! pignored, sostate leaks past the reset. Right: with this change.
xterm, VTE, and conhost all implement this. Test included.
Note: DEC STD 070 lists autowrap as reset-off; this matches xterm/conhost in
resetting it to the default (on).