Skip to content

Feature Request: implement XTPUSHSGR / XTPOPSGR #1796

@jazzdelightsme

Description

@jazzdelightsme

Summary of the new feature/enhancement

I would like to add at least partial support for the control sequences "XTPUSHSGR" and "XTPOPSGR" (as well as their aliases). Summarized from xterm's ctlseqs doc:

XTPUSHSGR

CSI # {
          Push video attributes onto stack (XTPUSHSGR), xterm.  [...]
          If no parameters are given, all of the video attributes are
          saved.  The stack is limited to 10 levels.
CSI # p
          Push video attributes onto stack (XTPUSHSGR), xterm.  This is
          an alias for CSI # { .

XTPOPSGR

CSI # }   Pop video attributes from stack (XTPOPSGR), xterm.  Popping
          restores the video-attributes which were saved using XTPUSHSGR
          to their previous state.
CSI # q   Pop video attributes from stack (XTPOPSGR), xterm.  This is an
          alias for CSI # } .

The problem this helps with is composability of content.

Suppose you have code that emits text that contains SGR control sequences to colorize it. You will find that your text is not easily composable--that is, you may have a format string like "The name is: %s, the position is: %s", and then you want to sprintf some inserts into that. Then that whole string you may want to insert into another, and so forth.

The problem is that to have SGR sequences in that one has to have sort of a global awareness of content and associated coloring for that to work out.

With SGR push/pop, though, you can do things like:

<fgBlack>   : CSI 3 0 m
<fgGreen>   : CSI 3 2 m
<fgYellow>  : CSI 3 3 m
<fgMagenta> : CSI 3 5 m
<fgWhite>   : CSI 3 7 m
<bgBlack>   : CSI 4 0 m
<bgYellow>  : CSI 4 3 m
<bgWhite>   : CSI 4 7 m
<pushSgr>   : CSI # {
<popSgr>    : CSI # }

name = "Dan <pushSgr><fgBlack><bgWhite>Thompson<popSgr>"
position = "<pushSgr><fgMagenta><bgYellow>Developer at Large<popSgr>"
line1 = "<pushSgr><bgBlack><fgWhite>The name is: %s, the position is: %s<popSgr>"

And then you can printf(line1, name, position), and have it all work out.

Without a push/pop mechanism, composing strings like that cannot be done that way at all, unless you do your own custom rendering pass to handle the pushes and pops.

Xterm supports saving/restoring of individual attributes, but this most essential "composability" scenario only requires saving and restoring them all together, and should be simplest to implement.

Proposed technical implementation details (optional)

The "business logic" of these commands is not too complicated... it's just a stack.

Pull Request

PR is here: #1978

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-VTVirtual Terminal sequence supportIssue-TaskIt's a feature request, but it doesn't really need a major design.Needs-Tag-FixDoesn't match tag requirementsProduct-ConhostFor issues in the Console codebaseResolution-Fix-CommittedFix is checked in, but it might be 3-4 weeks until a release.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions