Refactor VT DEC/ANSI mode handling to avoid code duplication when we light up SM/RM #11651

Closed
opened 2026-01-31 02:53:40 +00:00 by claunia · 2 comments
Owner

Originally created by @DHowett on GitHub (Dec 2, 2020).

Originally assigned to: @DHowett on GitHub.

I was about to add SetAnsiMode/ResetAnsiMode for SM and RM when I
realized that we probably don't need yet another enum of mode types, set and
reset functions, and a mode helper for ANSI standard modes when we already have
one for DEC Private modes.

I'm proposing:

  1. We change the enum PrivateModeParams to just be ModeParams
  2. We differentiate ANSI Standard modes (IRM, KAM, SRM, ...) from DEC Private modes
    (DECCOLM, DECCKM, ...) using a flag bit set in the enum value[1].
  3. We introduce a helper class for constructing these values much like @j4james'
    VTID.
    • (I've already prototyped a FlaggedEnumValue template helper[2])
  4. We dispatch all mode set/reset through a common Set/Reset and _ModeHelper
    that uses the existing enum values.

[1] These modes are in separate namespaces with some overlap. We should
differentiate them at dispatch time to ensure that \e[2h and \e[?2h are
given different treatment, and ensure that \e[1000h doesn't activate xterm
mouse mode.

[2]

template <typename T, template Mask>
class FlaggedEnumValue { ... };

using ANSIStandardMode = FlaggedEnumValue<size_t, 0x00000000>;
using DECPrivateMode = FlaggedEnumValue<size_t, 0x01000000>;

// ...

enum Modes : size_t {
	IRM_InsertReplaceMode = ANSIStandardMode(2),
	DECCKM_CursorKeys     = DECPrivateMode(1),
	// ...
};
Originally created by @DHowett on GitHub (Dec 2, 2020). Originally assigned to: @DHowett on GitHub. I was about to add `SetAnsiMode`/`ResetAnsiMode` for `SM` and `RM` when I realized that we probably don't need yet another enum of mode types, set and reset functions, and a mode helper for ANSI standard modes when we already have one for DEC Private modes. I'm proposing: 1. We change the enum `PrivateModeParams` to just be `ModeParams` 2. We differentiate ANSI Standard modes (IRM, KAM, SRM, ...) from DEC Private modes (DECCOLM, DECCKM, ...) using a flag bit set in the enum value[1]. 3. We introduce a helper class for constructing these values much like @j4james' `VTID`. * (I've already prototyped a `FlaggedEnumValue` template helper[2]) 4. We dispatch all mode set/reset through a common Set/Reset and `_ModeHelper` that uses the existing enum values. [1] These modes are in separate namespaces with some overlap. We should differentiate them at dispatch time to ensure that `\e[2h` and `\e[?2h` are given different treatment, and ensure that `\e[1000h` doesn't activate xterm mouse mode. [2] ```c++ template <typename T, template Mask> class FlaggedEnumValue { ... }; using ANSIStandardMode = FlaggedEnumValue<size_t, 0x00000000>; using DECPrivateMode = FlaggedEnumValue<size_t, 0x01000000>; // ... enum Modes : size_t { IRM_InsertReplaceMode = ANSIStandardMode(2), DECCKM_CursorKeys = DECPrivateMode(1), // ... }; ```
claunia added the Product-ConhostResolution-Fix-CommittedIssue-TaskArea-VT labels 2026-01-31 02:53:40 +00:00
Author
Owner

@DHowett commented on GitHub (Dec 2, 2020):

(I am particularly pleased with how well FlaggedEnumValue lends itself to using definitions that make it clear/easy on the enum authoring side what's happening. The decision to do constant conversion from a custom class type was based on James' VTID, which I love.)

@DHowett commented on GitHub (Dec 2, 2020): (I am particularly pleased with how well `FlaggedEnumValue` lends itself to `using` definitions that make it clear/easy on the enum authoring side what's happening. The decision to do constant conversion from a custom class type was based on James' `VTID`, which I _love_.)
Author
Owner

@j4james commented on GitHub (Dec 2, 2020):

I like this. I had the same idea about merging the two modes, but I just couldn't think of a good way to handle the two enum sets. This looks like it should work out nicely though.

@j4james commented on GitHub (Dec 2, 2020): I like this. I had the same idea about merging the two modes, but I just couldn't think of a good way to handle the two enum sets. This looks like it should work out nicely though.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#11651