[PR #15084] Add support for horizontal margin sequences #30398

Closed
opened 2026-01-31 09:40:35 +00:00 by claunia · 0 comments
Owner

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

State: closed
Merged: Yes


This PR introduces two new escapes sequences: DECLRMM (Left Right
Margin Mode), which enables the horizontal margin support, and DECSLRM
(Set Left and Right Margins), which does exactly what the name suggests.

A whole lot of existing operations have then been updated to take those
horizontal margins into account.

Detailed Description of the Pull Request / Additional comments

The main complication was in figuring out in what way each operation is
affected, since there's a fair amount of variation.

  • When writing text to the buffer, we need to wrap within the horizontal
    margins, but only when the cursor is also within the vertical margins,
    otherwise we just wrap within the boundaries of the screen.

  • Not all cursor movement operations are constrained by the margins, but
    for those that are, we clamp within both the vertical and horizontal
    margins. But if the cursor is already outside the margins, it is just
    clamped at the edges of the screen.

  • The ICH and DCH operations are constrained by the horizontal
    margins, but only when inside the vertical margins. And if the cursor is
    outside the horizontal margins, these operations have no effect at all.

  • The rectangular area operations are clamped within the horizontal
    margins when in the origin mode, the same way they're clamped within the
    vertical margins.

  • The scrolling operations only scroll the area inside both horizontal
    and vertical margins. This includes the IL and DL operations, but
    they also won't have any effect at all unless the cursor is already
    inside the margin area.

  • CR returns to the left margin rather than the start of the line,
    unless the cursor is already left of that margin, or outside the
    vertical margins.

  • LF, VT, FF, and IND only trigger a scroll at the bottom margin
    if the cursor is already inside both vertical and horizontal margins.
    The same rules apply to RI when triggering a scroll at the top margin.

Another thing worth noting is the change to the ANSISYSSC operation.
Since that shares the same escape sequence as DECSLRM, they can't both
be active at the same time. However, the latter is only meant to be
active when DECLRMM is set, so by default ANSISYSC will still work,
but it'll no longer apply once the DECLRMM mode is enabled.

Validation Steps Performed

Thanks to @al20878, these operations have been extensively tested on a
number of DEC terminals and I've manually confirmed our implementation
matches their behavior.

I've also extended some of our existing unit tests to cover at least the
basic margin handling, although not all of the edge cases.

Closes #14876

**Original Pull Request:** https://github.com/microsoft/terminal/pull/15084 **State:** closed **Merged:** Yes --- This PR introduces two new escapes sequences: `DECLRMM` (Left Right Margin Mode), which enables the horizontal margin support, and `DECSLRM` (Set Left and Right Margins), which does exactly what the name suggests. A whole lot of existing operations have then been updated to take those horizontal margins into account. ## Detailed Description of the Pull Request / Additional comments The main complication was in figuring out in what way each operation is affected, since there's a fair amount of variation. * When writing text to the buffer, we need to wrap within the horizontal margins, but only when the cursor is also within the vertical margins, otherwise we just wrap within the boundaries of the screen. * Not all cursor movement operations are constrained by the margins, but for those that are, we clamp within both the vertical and horizontal margins. But if the cursor is already outside the margins, it is just clamped at the edges of the screen. * The `ICH` and `DCH` operations are constrained by the horizontal margins, but only when inside the vertical margins. And if the cursor is outside the horizontal margins, these operations have no effect at all. * The rectangular area operations are clamped within the horizontal margins when in the origin mode, the same way they're clamped within the vertical margins. * The scrolling operations only scroll the area inside both horizontal and vertical margins. This includes the `IL` and `DL` operations, but they also won't have any effect at all unless the cursor is already inside the margin area. * `CR` returns to the left margin rather than the start of the line, unless the cursor is already left of that margin, or outside the vertical margins. * `LF`, `VT`, `FF`, and `IND` only trigger a scroll at the bottom margin if the cursor is already inside both vertical and horizontal margins. The same rules apply to `RI` when triggering a scroll at the top margin. Another thing worth noting is the change to the `ANSISYSSC` operation. Since that shares the same escape sequence as `DECSLRM`, they can't both be active at the same time. However, the latter is only meant to be active when `DECLRMM` is set, so by default `ANSISYSC` will still work, but it'll no longer apply once the `DECLRMM` mode is enabled. ## Validation Steps Performed Thanks to @al20878, these operations have been extensively tested on a number of DEC terminals and I've manually confirmed our implementation matches their behavior. I've also extended some of our existing unit tests to cover at least the basic margin handling, although not all of the edge cases. Closes #14876
claunia added the pull-request label 2026-01-31 09:40:35 +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#30398