FE 0.15.0
A C++23 toolkit for writing compiler/interpreter frontends.
Loading...
Searching...
No Matches
fe::term Namespace Reference

Lightweight stream-based terminal colors for diagnostics and CLI output. More...

Classes

class  Cited
 An owning message fragment that spells `citations` of its own; what format_cite yields. More...
class  Cite
 A borrowed fragment whose backticks stay markup; format_cite escapes every other argument. More...

Typedefs

using ScopedMode = Restore<Mode, &mode, &set_mode>
 Overrides the color mode for the duration of the scope.
template<class... Args>
using cite_string = std::format_string<detail::cite_arg_t<Args>...>
 A std::format_string whose backticks delimit a `citation` while those of its arguments are data.

Enumerations

enum class  Mode {
  Auto ,
  Never ,
  Always
}
 Controls whether color escape sequences are emitted. More...
enum class  FG {
  Black ,
  Red ,
  Green ,
  Yellow ,
  Blue ,
  Magenta ,
  Cyan ,
  Gray ,
  Grey = Gray ,
  Reset
}
 Foreground colors that can be streamed into an std::ostream. More...

Functions

FE_API Mode mode () noexcept
 Returns the current terminal color mode.
FE_API bool auto_detached () noexcept
 Whether Mode::Auto emits colors into a detached buffer - anything a std::formatter writes into.
FE_API void set_auto_detached (bool b) noexcept
 Overrides auto_detached.
FE_API bool use_color (std::ostream &os) noexcept
 Whether color escape sequences are emitted for os right now.
FE_API std::optional< size_t > width (std::ostream &os) noexcept
 Number of columns of the terminal os refers to.
FE_API void set_mode (Mode m) noexcept
 Overrides the current terminal color mode.
FE_API void resolve_mode (std::ostream &os=std::cerr) noexcept
 Decides Mode::Auto for detached buffers, depending on whether os refers to a terminal.
FE_API std::ostream & operator<< (std::ostream &os, FG color)
 Streams the ANSI escape sequence for color when colors are enabled for os.
template<class O>
escape_cite_to (O out, std::string_view str)
 Escapes str into out so that render_cite reproduces it verbatim instead of reading it as markup.
FE_API std::string escape_cite (std::string_view str)
 As above but into a fresh std::string.
template<class... Args>
Cited format_cite (cite_string< Args... > fmt, Args &&... args)
 std::format for a message that follows that convention; assemble a fragment of your own with it.
FE_API void render_cite (std::ostream &os, std::string_view str, bool color)
 Streams str into os, coloring each `citation` and dropping its backticks - or keeping them verbatim without color; \` is a literal backtick and \\ a literal backslash.
FE_API void render_cite (std::ostream &os, std::string_view str)
 As above but lets os decide the coloring; mirrors cite_width.
FE_API size_t cite_width (std::string_view str, bool color)
 Number of columns str actually occupies once render_cite renders it with color - fewer than str.size() by the backticks/backslashes render_cite drops.

Detailed Description

Lightweight stream-based terminal colors for diagnostics and CLI output.

Include fe/term.h and stream a fe::term::FG value into an std::ostream:

std::cerr << fe::term::FG::Red << "error: " << fe::term::FG::Reset << "unexpected token\n";

The current behavior is controlled via fe::term::Mode and can be overridden with fe::term::set_mode. In fe::term::Mode::Auto, colors are emitted only for std::cout, std::cerr, std::clog, or streams sharing those buffers when they refer to terminals. FE also respects the common environment conventions NO_COLOR, CLICOLOR=0, and CLICOLOR_FORCE (unless it is set to 0).

Note that a std::formatter never sees the destination stream - it formats into a detached buffer. Hence, embedding a fe::term::FG value in a std::format/std::print format string resolves fe::term::Mode::Auto to "no color". If you emit colors this way, call fe::term::resolve_mode once at startup to decide fe::term::Mode::Auto up front based on a representative stream.

The mode and fe::term::auto_detached live in the fe library rather than in this header, so a shared library loaded via fe::dl sees whatever the host set instead of starting over from the defaults.

Use fe::term::use_color to branch on whether color will actually be emitted, e.g. to keep a plain-text fallback in sync with the colored rendering.

Typedef Documentation

◆ cite_string

template<class... Args>
using fe::term::cite_string = std::format_string<detail::cite_arg_t<Args>...>

A std::format_string whose backticks delimit a `citation` while those of its arguments are data.

Definition at line 242 of file term.h.

◆ ScopedMode

Overrides the color mode for the duration of the scope.

Warning
The mode is global, so this affects every stream - and every thread - while it is alive.

Definition at line 151 of file term.h.

Enumeration Type Documentation

◆ FG

enum class fe::term::FG
strong

Foreground colors that can be streamed into an std::ostream.

Enumerator
Black 
Red 
Green 
Yellow 
Blue 
Magenta 
Cyan 
Gray 
Grey 
Reset 

Definition at line 50 of file term.h.

◆ Mode

enum class fe::term::Mode
strong

Controls whether color escape sequences are emitted.

Enumerator
Auto 
Never 
Always 

Definition at line 43 of file term.h.

Function Documentation

◆ auto_detached()

FE_API bool fe::term::auto_detached ( )
noexcept

Whether Mode::Auto emits colors into a detached buffer - anything a std::formatter writes into.

resolve_mode is the usual way to decide this.

References auto_detached().

Referenced by auto_detached().

◆ cite_width()

FE_API size_t fe::term::cite_width ( std::string_view str,
bool color )

Number of columns str actually occupies once render_cite renders it with color - fewer than str.size() by the backticks/backslashes render_cite drops.

References cite_width().

Referenced by cite_width().

◆ escape_cite()

FE_API std::string fe::term::escape_cite ( std::string_view str)

As above but into a fresh std::string.

References escape_cite().

Referenced by escape_cite().

◆ escape_cite_to()

template<class O>
O fe::term::escape_cite_to ( O out,
std::string_view str )

Escapes str into out so that render_cite reproduces it verbatim instead of reading it as markup.

Escaping the backslashes as well keeps a trailing one from swallowing the backtick that follows it.

Definition at line 170 of file term.h.

References escape_cite_to().

Referenced by escape_cite_to().

◆ format_cite()

template<class... Args>
Cited fe::term::format_cite ( cite_string< Args... > fmt,
Args &&... args )

std::format for a message that follows that convention; assemble a fragment of your own with it.

The Cited it yields is markup wherever it is used as an argument again - no re-wrapping needed.

Definition at line 247 of file term.h.

References fe::Cited::Cited(), and format_cite().

Referenced by format_cite().

◆ mode()

FE_API Mode fe::term::mode ( )
noexcept

Returns the current terminal color mode.

References mode().

Referenced by mode().

◆ operator<<()

FE_API std::ostream & fe::term::operator<< ( std::ostream & os,
FG color )

Streams the ANSI escape sequence for color when colors are enabled for os.

◆ render_cite() [1/2]

FE_API void fe::term::render_cite ( std::ostream & os,
std::string_view str )

As above but lets os decide the coloring; mirrors cite_width.

References render_cite().

◆ render_cite() [2/2]

FE_API void fe::term::render_cite ( std::ostream & os,
std::string_view str,
bool color )

Streams str into os, coloring each `citation` and dropping its backticks - or keeping them verbatim without color; \` is a literal backtick and \\ a literal backslash.

This is the convention fe::CodeDiag renders a diagnostic message with; use it to apply the same convention elsewhere, e.g. fe::Cli::help.

References render_cite().

Referenced by render_cite(), render_cite(), and fe::throwf().

◆ resolve_mode()

FE_API void fe::term::resolve_mode ( std::ostream & os = std::cerr)
noexcept

Decides Mode::Auto for detached buffers, depending on whether os refers to a terminal.

A std::formatter cannot see its destination stream, so FG values embedded in a std::format/std::print format string never detect a terminal on their own. Call this once at startup to make formatted output colored as well:

fe::term::resolve_mode(); // decide based on stderr
std::print(std::cerr, "{}error:{} ...", fe::term::FG::Red, fe::term::FG::Reset);
FE_API void resolve_mode(std::ostream &os=std::cerr) noexcept
Decides Mode::Auto for detached buffers, depending on whether os refers to a terminal.

A real stream still decides on its own, and explicit modes are left untouched.

References resolve_mode().

Referenced by resolve_mode().

◆ set_auto_detached()

FE_API void fe::term::set_auto_detached ( bool b)
noexcept

Overrides auto_detached.

References set_auto_detached().

Referenced by set_auto_detached().

◆ set_mode()

FE_API void fe::term::set_mode ( Mode m)
noexcept

Overrides the current terminal color mode.

References set_mode().

Referenced by set_mode().

◆ use_color()

FE_API bool fe::term::use_color ( std::ostream & os)
noexcept

Whether color escape sequences are emitted for os right now.

In Mode::Auto this is decided by whether os refers to a terminal, while a detached buffer (anything a std::formatter writes into) follows resolve_mode. Use this to keep a plain-text fallback in sync with what operator<<(std::ostream&, FG) will emit, e.g. to spell out a marker only when it cannot be conveyed by color.

References use_color().

Referenced by use_color().

◆ width()

FE_API std::optional< size_t > fe::term::width ( std::ostream & os)
noexcept

Number of columns of the terminal os refers to.

Unlike use_color, this ignores Mode and always asks the actual stream.

Returns
std::nullopt if os is not a terminal or its size cannot be determined.

References width().

Referenced by width().