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

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

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/3943
Author: @j4james
Created: 12/13/2019
Status: Merged
Merged: 2/4/2020
Merged by: @undefined

Base: masterHead: feature-decawm


📝 Commits (10+)

  • 295b0e1 Make sure the "delay EOL wrap" behaviour is only applied when the ENABLE_WRAP_AT_EOL_OUTPUT mode is set.
  • 49d899f Add a private API in the ConGetSet interface to toggle the ENABLE_WRAP_AT_EOL_OUTPUT mode.
  • 16b0d8a Add support for DECAWM escape sequence to toggle the ENABLE_WRAP_AT_EOL_OUTPUT mode.
  • 036d2d1 Reenable the auto wrap mode when a DECSTR soft reset is triggered.
  • 552d37b Add a state machine test to confirm the DECAWM escape sequence is dispatched correctly.
  • 47bddbc Make sure the cursor is left in the last column of the row when wrapping is disabled in VT mode.
  • 7d5193d Add a screen buffer test to confirm that the output is wrapped or clamped appropriately for the mode.
  • 1a2bca4 Use WI_UpdateFlag instead of a conditional SetFlag and ClearFlag.
  • dc9a4b6 Make the TermDispatch::SetAutoWrapMode method noexcept, to pass the new audit mode.
  • a4c22cc Merge branch 'master' into feature-decawm

📊 Changes

14 files changed (+155 additions, -7 deletions)

View changed files

📝 src/host/_stream.cpp (+16 -6)
📝 src/host/getset.cpp (+16 -0)
📝 src/host/getset.h (+1 -0)
📝 src/host/outputStream.cpp (+13 -0)
📝 src/host/outputStream.hpp (+1 -0)
📝 src/host/ut_host/ScreenBufferTests.cpp (+45 -0)
📝 src/terminal/adapter/DispatchTypes.hpp (+1 -0)
📝 src/terminal/adapter/ITermDispatch.hpp (+1 -0)
📝 src/terminal/adapter/adaptDispatch.cpp (+21 -1)
📝 src/terminal/adapter/adaptDispatch.hpp (+1 -0)
📝 src/terminal/adapter/conGetSet.hpp (+1 -0)
📝 src/terminal/adapter/termDispatch.hpp (+1 -0)
📝 src/terminal/adapter/ut_adapter/adapterTest.cpp (+7 -0)
📝 src/terminal/parser/ut_parser/OutputEngineTest.cpp (+30 -0)

📄 Description

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.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/3943 **Author:** [@j4james](https://github.com/j4james) **Created:** 12/13/2019 **Status:** ✅ Merged **Merged:** 2/4/2020 **Merged by:** [@undefined](undefined) **Base:** `master` ← **Head:** `feature-decawm` --- ### 📝 Commits (10+) - [`295b0e1`](https://github.com/microsoft/terminal/commit/295b0e1923de3272761cad185f5f4ad200fb5e3b) Make sure the "delay EOL wrap" behaviour is only applied when the ENABLE_WRAP_AT_EOL_OUTPUT mode is set. - [`49d899f`](https://github.com/microsoft/terminal/commit/49d899f7ab343b29c6655babb8c442f618155282) Add a private API in the ConGetSet interface to toggle the ENABLE_WRAP_AT_EOL_OUTPUT mode. - [`16b0d8a`](https://github.com/microsoft/terminal/commit/16b0d8a29b032b1bcab1f2205dee0af97aa7a46a) Add support for DECAWM escape sequence to toggle the ENABLE_WRAP_AT_EOL_OUTPUT mode. - [`036d2d1`](https://github.com/microsoft/terminal/commit/036d2d14afca56cff9137386f8153210500bbaaf) Reenable the auto wrap mode when a DECSTR soft reset is triggered. - [`552d37b`](https://github.com/microsoft/terminal/commit/552d37b0da79601a5d239efa9773affdb3b6aae9) Add a state machine test to confirm the DECAWM escape sequence is dispatched correctly. - [`47bddbc`](https://github.com/microsoft/terminal/commit/47bddbceec82f7840ac92f4ef1bb2386d524cb2e) Make sure the cursor is left in the last column of the row when wrapping is disabled in VT mode. - [`7d5193d`](https://github.com/microsoft/terminal/commit/7d5193d09fc3db47a46af17ac52c743ca72e4571) Add a screen buffer test to confirm that the output is wrapped or clamped appropriately for the mode. - [`1a2bca4`](https://github.com/microsoft/terminal/commit/1a2bca46913a8e3b3191497409c3fd35062028fc) Use WI_UpdateFlag instead of a conditional SetFlag and ClearFlag. - [`dc9a4b6`](https://github.com/microsoft/terminal/commit/dc9a4b6adeaf847862c541762b73baa7aec1afff) Make the TermDispatch::SetAutoWrapMode method noexcept, to pass the new audit mode. - [`a4c22cc`](https://github.com/microsoft/terminal/commit/a4c22cccd6849b314bb8179b7fc3c74667c95f80) Merge branch 'master' into feature-decawm ### 📊 Changes **14 files changed** (+155 additions, -7 deletions) <details> <summary>View changed files</summary> 📝 `src/host/_stream.cpp` (+16 -6) 📝 `src/host/getset.cpp` (+16 -0) 📝 `src/host/getset.h` (+1 -0) 📝 `src/host/outputStream.cpp` (+13 -0) 📝 `src/host/outputStream.hpp` (+1 -0) 📝 `src/host/ut_host/ScreenBufferTests.cpp` (+45 -0) 📝 `src/terminal/adapter/DispatchTypes.hpp` (+1 -0) 📝 `src/terminal/adapter/ITermDispatch.hpp` (+1 -0) 📝 `src/terminal/adapter/adaptDispatch.cpp` (+21 -1) 📝 `src/terminal/adapter/adaptDispatch.hpp` (+1 -0) 📝 `src/terminal/adapter/conGetSet.hpp` (+1 -0) 📝 `src/terminal/adapter/termDispatch.hpp` (+1 -0) 📝 `src/terminal/adapter/ut_adapter/adapterTest.cpp` (+7 -0) 📝 `src/terminal/parser/ut_parser/OutputEngineTest.cpp` (+30 -0) </details> ### 📄 Description ## 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. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:10:21 +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#25570