ansiExecuteSgrSequence

Executes the SGR sequence found in input, and populates the passed in style based on the command sequence.

Anything directly provided by this library is supported.

The previous state of style is preserved unless specifically untoggled/reset via the command sequence (e.g. ESC[0m to reset everything).

If an error occurs during execution of the sequence, the given style is left completely unmodified.

@safe @nogc nothrow
string
ansiExecuteSgrSequence
(
const(char)[] input
,,
out size_t charsRead
)

Parameters

input const(char)[]

The slice containing the command sequence. The first character should be the start (ANSI_CSI) character of the sequence (\033), and characters will continue to be read until the command sequence has been finished. Any characters after the command sequence are left unread.

style AnsiStyleSet

A reference to an AnsiStyleSet to populate. As mentioned, this function will only untoggle styling, or reset the style if the command sequence specifies. This value is left unmodified if an error is encountered.

charsRead size_t

This value will be set to the amount of chars read from the given input, so the caller knows where to continue reading from (if applicable). This value is populated on both error and ok.

Return Value

Type: string

Either null on ok, or a string describing the error that was encountered.

Examples

static if(!BetterC)
{
    import std.conv : to;
    import std.traits : EnumMembers;

    void test(AnsiStyleSet sourceAndExpected)
    {
        char[AnsiStyleSet.MAX_CHARS_NEEDED] buffer;
        const sequence = ANSI_CSI~sourceAndExpected.toSequence(buffer)~ANSI_COLOUR_END;

        AnsiStyleSet got;
        size_t charsRead;
        const error = ansiExecuteSgrSequence(sequence, got, charsRead);
        if(error !is null)
            assert(false, error);

        assert(charsRead == sequence.length, "Read "~charsRead.to!string~" not "~sequence.length.to!string);
        assert(sourceAndExpected == got, "Expected "~sourceAndExpected.to!string~" got "~got.to!string);
    }

    test(AnsiStyleSet.init.fg(Ansi4BitColour.green));
    test(AnsiStyleSet.init.fg(Ansi4BitColour.brightGreen));
    test(AnsiStyleSet.init.bg(Ansi4BitColour.green));
    test(AnsiStyleSet.init.bg(Ansi4BitColour.brightGreen));
    test(AnsiStyleSet.init.fg(Ansi4BitColour.green).bg(Ansi4BitColour.brightRed));

    test(AnsiStyleSet.init.fg(20));
    test(AnsiStyleSet.init.bg(40));
    test(AnsiStyleSet.init.fg(20).bg(40));

    test(AnsiStyleSet.init.fg(AnsiRgbColour(255, 128, 64)));
    test(AnsiStyleSet.init.bg(AnsiRgbColour(255, 128, 64)));
    test(AnsiStyleSet.init.fg(AnsiRgbColour(255, 128, 64)).bg(AnsiRgbColour(64, 128, 255)));

    static foreach(member; EnumMembers!AnsiSgrStyle)
    static if(member != AnsiSgrStyle.none)
        test(AnsiStyleSet.init.style(AnsiStyle.init.set(member, true)));

    test(AnsiStyleSet.init.style(AnsiStyle.init.bold.underline.slowBlink.italic));
}

Meta