[PR #3943] Add support for VT100 Auto Wrap Mode (DECAWM) #25575

Open
opened 2026-01-31 09:10:23 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/3943

State: closed
Merged: Yes


Summary of the Pull Request

This adds support for the DECAWM private mode escape sequence, which controls whether or not the output wraps to the next line when the cursor reaches the right edge of the screen. Tested manually, with Vttest, and with some new unit tests.

PR Checklist

Detailed Description of the Pull Request / Additional comments

The idea was to repurpose the existing ENABLE_WRAP_AT_EOL_OUTPUT mode, but the problem with that was it didn't work in VT mode - specifically, disabling it didn't prevent the wrapping from happening. This was because in VT mode the WC_DELAY_EOL_WRAP behaviour takes affect, and that bypasses the usual codepath where ENABLE_WRAP_AT_EOL_OUTPUT is checked,

To fix this, I had to add additional checks in the WriteCharsLegacy function (7dbefe06e41f191a0e83cfefe4896b66094c4089) to make sure the WC_DELAY_EOL_WRAP mode is only activated when ENABLE_WRAP_AT_EOL_OUTPUT is also set.

Once that was fixed, though, another issue came to light: the ENABLE_WRAP_AT_EOL_OUTPUT mode doesn't actually work as documented. According to the docs, "if this mode is disabled, the last character in the row is overwritten with any subsequent characters". What actually happens is the cursor jumps back to the position at the start of the write, which could be anywhere on the line.

This seems completely broken to me, but I've checked in the Windows XP, and it has the same behaviour, so it looks like that's the way it has always been. So I've added a fix for this (9df98497ca38f7d0ea42623b723a8e2ecf9a4ab9), but it is only applied in VT mode.

Once that basic functionality was in place, though, we just needed a private API in the ConGetSet interface to toggle the mode, and then that API could be called from the AdaptDispatch class when the DECAWM escape sequence was received.

One last thing was to reenable the mode in reponse to a DECSTR soft reset. Technically the auto wrap mode was disabled by default on many of the DEC terminals, and some documentation suggests that DECSTR should reset it to that state, But most modern terminals (including XTerm) expect the wrapping to be enabled by default, and DECSTR reenables that state, so that's the behaviour I've copied.

Validation Steps Performed

I've add a state machine test to confirm the DECAWM escape is dispatched correctly, and a screen buffer test to make sure the output is wrapped or clamped as appropriate for the two states.

I've also confirmed that the "wrap around" test is now working correctly in the Test of screen features in Vttest.

**Original Pull Request:** https://github.com/microsoft/terminal/pull/3943 **State:** closed **Merged:** Yes --- ## Summary of the Pull Request This adds support for the [`DECAWM`](https://vt100.net/docs/vt510-rm/DECAWM) private mode escape sequence, which controls whether or not the output wraps to the next line when the cursor reaches the right edge of the screen. Tested manually, with [Vttest](https://invisible-island.net/vttest/), and with some new unit tests. ## PR Checklist * [x] Closes #3826 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] Tests added/passed * [ ] Requires documentation to be updated * [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3826 ## Detailed Description of the Pull Request / Additional comments The idea was to repurpose the existing `ENABLE_WRAP_AT_EOL_OUTPUT` mode, but the problem with that was it didn't work in VT mode - specifically, disabling it didn't prevent the wrapping from happening. This was because in VT mode the `WC_DELAY_EOL_WRAP` behaviour takes affect, and that bypasses the usual codepath where `ENABLE_WRAP_AT_EOL_OUTPUT` is checked, To fix this, I had to add additional checks in the `WriteCharsLegacy` function (7dbefe06e41f191a0e83cfefe4896b66094c4089) to make sure the `WC_DELAY_EOL_WRAP` mode is only activated when `ENABLE_WRAP_AT_EOL_OUTPUT` is also set. Once that was fixed, though, another issue came to light: the `ENABLE_WRAP_AT_EOL_OUTPUT` mode doesn't actually work as documented. According to the docs, "if this mode is disabled, the last character in the row is overwritten with any subsequent characters". What actually happens is the cursor jumps back to the position at the start of the write, which could be anywhere on the line. This seems completely broken to me, but I've checked in the Windows XP, and it has the same behaviour, so it looks like that's the way it has always been. So I've added a fix for this (9df98497ca38f7d0ea42623b723a8e2ecf9a4ab9), but it is only applied in VT mode. Once that basic functionality was in place, though, we just needed a private API in the `ConGetSet` interface to toggle the mode, and then that API could be called from the `AdaptDispatch` class when the `DECAWM` escape sequence was received. One last thing was to reenable the mode in reponse to a `DECSTR` soft reset. Technically the auto wrap mode was disabled by default on many of the DEC terminals, and some documentation suggests that `DECSTR` should reset it to that state, But most modern terminals (including XTerm) expect the wrapping to be enabled by default, and `DECSTR` reenables that state, so that's the behaviour I've copied. ## Validation Steps Performed I've add a state machine test to confirm the `DECAWM` escape is dispatched correctly, and a screen buffer test to make sure the output is wrapped or clamped as appropriate for the two states. I've also confirmed that the "wrap around" test is now working correctly in the _Test of screen features_ in Vttest.
claunia added the pull-request label 2026-01-31 09:10:23 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#25575