mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-03-26 22:27:42 +08:00
set_color: Honor modifiers (bold, background..) with --print-colors
Fixes #7314
This commit is contained in:
parent
304649acc6
commit
58245b6fe7
@ -33,15 +33,53 @@
|
||||
|
||||
class parser_t;
|
||||
|
||||
static void print_colors(io_streams_t &streams) {
|
||||
outputter_t outp;
|
||||
static void print_modifiers(outputter_t &outp, bool bold, bool underline, bool italics, bool dim, bool reverse, rgb_color_t bg) {
|
||||
if (bold && enter_bold_mode) {
|
||||
// These casts are needed to work with different curses implementations.
|
||||
writembs_nofail(outp, tparm(const_cast<char *>(enter_bold_mode)));
|
||||
}
|
||||
|
||||
if (underline && enter_underline_mode) {
|
||||
writembs_nofail(outp, enter_underline_mode);
|
||||
}
|
||||
|
||||
if (italics && enter_italics_mode) {
|
||||
writembs_nofail(outp, enter_italics_mode);
|
||||
}
|
||||
|
||||
if (dim && enter_dim_mode) {
|
||||
writembs_nofail(outp, enter_dim_mode);
|
||||
}
|
||||
|
||||
if (reverse && enter_reverse_mode) {
|
||||
writembs_nofail(outp, enter_reverse_mode);
|
||||
} else if (reverse && enter_standout_mode) {
|
||||
writembs_nofail(outp, enter_standout_mode);
|
||||
}
|
||||
if (!bg.is_none() && bg.is_normal()) {
|
||||
writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void print_colors(io_streams_t &streams, bool bold, bool underline, bool italics, bool dim, bool reverse, rgb_color_t bg) {
|
||||
outputter_t outp;
|
||||
for (const auto &color_name : rgb_color_t::named_color_names()) {
|
||||
if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) {
|
||||
print_modifiers(outp, bold, underline, italics, dim, reverse, bg);
|
||||
rgb_color_t color = rgb_color_t(color_name);
|
||||
outp.set_color(color, rgb_color_t::none());
|
||||
if (!bg.is_none()) {
|
||||
outp.write_color(bg, false /* not is_fg */);
|
||||
}
|
||||
}
|
||||
outp.writestr(color_name);
|
||||
if (!bg.is_none()) {
|
||||
// If we have a background, stop it after the color
|
||||
// or it goes to the end of the line and looks ugly.
|
||||
writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
|
||||
}
|
||||
outp.writech(L'\n');
|
||||
} // conveniently, 'normal' is always the last color so we don't need to reset here
|
||||
|
||||
@ -96,7 +134,7 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
|
||||
}
|
||||
|
||||
const wchar_t *bgcolor = nullptr;
|
||||
bool bold = false, underline = false, italics = false, dim = false, reverse = false;
|
||||
bool bold = false, underline = false, italics = false, dim = false, reverse = false, print = false;
|
||||
|
||||
// Parse options to obtain the requested operation and the modifiers.
|
||||
int opt;
|
||||
@ -132,8 +170,8 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
print_colors(streams);
|
||||
return STATUS_CMD_OK;
|
||||
print = true;
|
||||
break;
|
||||
}
|
||||
case ':': {
|
||||
// We don't error here because "-b" is the only option that requires an argument,
|
||||
@ -149,6 +187,17 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
|
||||
}
|
||||
}
|
||||
|
||||
const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
|
||||
if (bgcolor && bg.is_none()) {
|
||||
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (print) {
|
||||
print_colors(streams, bold, underline, italics, dim, reverse, bg);
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
|
||||
// Remaining arguments are foreground color.
|
||||
std::vector<rgb_color_t> fgcolors;
|
||||
for (; w.woptind < argc; w.woptind++) {
|
||||
@ -165,12 +214,6 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
|
||||
const rgb_color_t fg = best_color(fgcolors, output_get_color_support());
|
||||
assert(fgcolors.empty() || !fg.is_none());
|
||||
|
||||
const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
|
||||
if (bgcolor && bg.is_none()) {
|
||||
streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
// Test if we have at least basic support for setting fonts, colors and related bits - otherwise
|
||||
// just give up...
|
||||
if (cur_term == nullptr || !exit_attribute_mode) {
|
||||
@ -178,28 +221,7 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
|
||||
}
|
||||
outputter_t outp;
|
||||
|
||||
if (bold && enter_bold_mode) {
|
||||
// These casts are needed to work with different curses implementations.
|
||||
writembs_nofail(outp, tparm(const_cast<char *>(enter_bold_mode)));
|
||||
}
|
||||
|
||||
if (underline && enter_underline_mode) {
|
||||
writembs_nofail(outp, enter_underline_mode);
|
||||
}
|
||||
|
||||
if (italics && enter_italics_mode) {
|
||||
writembs_nofail(outp, enter_italics_mode);
|
||||
}
|
||||
|
||||
if (dim && enter_dim_mode) {
|
||||
writembs_nofail(outp, enter_dim_mode);
|
||||
}
|
||||
|
||||
if (reverse && enter_reverse_mode) {
|
||||
writembs_nofail(outp, enter_reverse_mode);
|
||||
} else if (reverse && enter_standout_mode) {
|
||||
writembs_nofail(outp, enter_standout_mode);
|
||||
}
|
||||
print_modifiers(outp, bold, underline, italics, dim, reverse, bg);
|
||||
|
||||
if (bgcolor != nullptr && bg.is_normal()) {
|
||||
writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
|
||||
|
63
tests/pexpects/set_color.py
Normal file
63
tests/pexpects/set_color.py
Normal file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
from pexpect_helper import SpawnedProc
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
|
||||
env = os.environ.copy()
|
||||
env["TERM"] = "xterm"
|
||||
|
||||
sp = SpawnedProc(env=env)
|
||||
send, sendline, sleep, expect_prompt, expect_re, expect_str = (
|
||||
sp.send,
|
||||
sp.sendline,
|
||||
sp.sleep,
|
||||
sp.expect_prompt,
|
||||
sp.expect_re,
|
||||
sp.expect_str,
|
||||
)
|
||||
expect_prompt()
|
||||
|
||||
# See that --print-colors prints the colors colored.
|
||||
# Note that we don't check *all* of them, just a few.
|
||||
sendline("set_color --print-colors")
|
||||
expect_str("black")
|
||||
expect_str("blue")
|
||||
expect_str("brblack")
|
||||
expect_str("brblue")
|
||||
expect_str("brcyan")
|
||||
expect_str("brgreen")
|
||||
expect_str("brmagenta")
|
||||
expect_str("brred")
|
||||
expect_str("brwhite")
|
||||
expect_str("bryellow")
|
||||
expect_str("cyan")
|
||||
expect_str("green")
|
||||
expect_str("magenta")
|
||||
expect_str("\x1b[31mred")
|
||||
expect_str("\x1b[37mwhite")
|
||||
expect_str("\x1b[33myellow")
|
||||
expect_str("normal")
|
||||
expect_prompt()
|
||||
|
||||
sendline ("set_color --background blue --print-colors")
|
||||
expect_str("black")
|
||||
expect_str("blue")
|
||||
expect_str("brblack")
|
||||
expect_str("brblue")
|
||||
expect_str("brcyan")
|
||||
expect_str("brgreen")
|
||||
expect_str("brmagenta")
|
||||
expect_str("brred")
|
||||
expect_str("brwhite")
|
||||
expect_str("bryellow")
|
||||
expect_str("cyan")
|
||||
expect_str("green")
|
||||
expect_str("magenta")
|
||||
expect_str("\x1b[31m\x1b[44mred")
|
||||
expect_str("white")
|
||||
expect_str("yellow")
|
||||
expect_str("normal")
|
||||
expect_prompt()
|
||||
|
Loading…
x
Reference in New Issue
Block a user