Skip to content

ANSI escape sequences: a possible path forward #162

@sunfishcode

Description

@sunfishcode

ANSI escape sequences are really useful, but we need a plan, both for portability and security, as escape sequences can cause a variety of havoc. Here's a skeleton of a plan; feedback welcome!

When output is connected to a terminal, by default:

  • With only a few exceptions, control characters should be sanitized, perhaps replaced by control pictures.
  • Control characters which are permitted are:
    • LF, but with the "newline" interpretation
    • BS, CR (for pretty progress indicators etc.). Output devices that don't support these may interpret CR the same as LF above, and emit (or ?) in place of BS. Applications should avoid displaying progress indicators when the libc function isatty returns false (TODO: this isn't a simple topic), and should prefer CR to BS for progress indicators in general as CR translates better to log output.
    • HT (aka TAB).

(One could argue BEL could be included here too; I omitted it for aesthetic reasons. Feel free to disagree!). VT and FF are omitted because they aren't very useful and would add complexity.

Notably, this would neutralize ESC and thus ANSI escape sequences.

Then, we add a rights flag on a file descriptor indicating the right to use these features. When WASI gains the ability for programs to request capabilities (some early discussion here), programs could then request the ability to use ANSI escape sequences. And implementations should reset the terminal to normal settings when the program starts and terminates.

Then, we identify the escape sequences that are the most useful -- color, cursor positioning, and possibly other things. Then we have a choice -- either:

  • Add an explicit API for those things, with functions that change the current color, set the cursor position, etc., or
  • Allow applications to write ANSI escape sequences and interpret those that are recognized, and continue suppress those that are not. Platforms whose terminal applications don't natively support ANSI escape sequences would have to emulate them.

An API is simpler, and it makes it straightforward for applications to feature-detect which functions are available. And it makes a clean break from the ANSI escape sequence encoding, freeing us from some legacy concerns. On the other hand, just allowing select ANSI codes to go through would be better for compatibility.

As for TERM, terminfo, termcap, there's a lot of legacy there that it'd be nice to avoid carrying forward. If we define the semantics of output to a terminal, it seems like it ought to be possible to avoid supporting these interfaces at the WASI level (they could still be emulated in libc for compatibility).

For NO_COLOR, this could be implemented by wasm engines rather than by applications, either by making color a distinct rights flag, or by just stripping (or translating to gray-scale, if the output supports that) color.

There are surely a lot more details to be figured out, but I wanted to put some ideas out there to start a discussion.

[Edits: add HT (TAB), discuss VT and FF, mention that implementations should reset the terminal on startup, and add some advice for applications implementing progress bars.]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions