mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-04 07:21:14 -03:00
set_color: add --foreground and --reset options
`--foreground` has two purposes: - allow resetting the foreground color to its default, without also resetting the other colors and modes - improve readibility and unify the `set_color` arguments `--reset` also has two purposes: - provide a more intuitive way to reset the text formatting - allow setting the colors and modes from a clean state without requiring two calls to `set_color` Part 3/3 of #12495 Closes #12507
This commit is contained in:
committed by
Johannes Altmanninger
parent
4e41d142fd
commit
eb7ea0ef9b
@@ -5,6 +5,7 @@ Notable improvements and fixes
|
||||
------------------------------
|
||||
- New Spanish translations (:issue:`12489`).
|
||||
- ``set_color`` is able to turn off italics, reverse mode, strikethrough and underline individually (e.g. ``--italics=off``).
|
||||
- ``set_color`` learned the foreground (``--foreground`` or ``-f``) and reset (``--reset``) modifiers.
|
||||
|
||||
For distributors and developers
|
||||
-------------------------------
|
||||
|
||||
@@ -6,7 +6,7 @@ Synopsis
|
||||
|
||||
.. synopsis::
|
||||
|
||||
set_color [OPTIONS] VALUE
|
||||
set_color [OPTIONS] [VALUE]
|
||||
|
||||
Description
|
||||
-----------
|
||||
@@ -33,6 +33,11 @@ However if :envvar:`fish_term256` is set to 0, fish prefers the first named colo
|
||||
|
||||
The following options are available:
|
||||
|
||||
**-f** or **--foreground** *COLOR*
|
||||
Sets the foreground color.
|
||||
This is equivalent to calling ``set_color COLOR`` with the exception that the keyword **normal** will only reset the foreground color to its default, instead of all colors and modes.
|
||||
It cannot be used with *VALUE* or **--print-colors**.
|
||||
|
||||
**-b** or **--background** *COLOR*
|
||||
Sets the background color.
|
||||
|
||||
@@ -41,6 +46,7 @@ The following options are available:
|
||||
|
||||
**-c** or **--print-colors**
|
||||
Prints the given colors or a colored list of the 16 named colors.
|
||||
It cannot be used with **--foreground**.
|
||||
|
||||
**-o** or **--bold**
|
||||
Sets bold mode.
|
||||
@@ -60,6 +66,10 @@ The following options are available:
|
||||
**-u** or **--underline**, or **-uSTYLE** or **--underline=STYLE**
|
||||
Set the underline mode; supported styles are **single** (default), **double**, **curly**, **dotted**, **dashed** and **off**.
|
||||
|
||||
**--reset**
|
||||
Reset the text formatting to the terminal defaults before applying the new colors and modes.
|
||||
This is equivalent to calling ``set_color normal`` except that it is possible to set the foreground color in the same call (e.g. ``set_color --reset green``)
|
||||
|
||||
**--theme=THEME**
|
||||
Ignored.
|
||||
:ref:`Color variables <variables-color>` that contain only this option are treated like missing / empty color variables,
|
||||
@@ -75,10 +85,11 @@ The following options are available:
|
||||
Notes
|
||||
-----
|
||||
|
||||
1. Using **set_color normal** will reset all colors and modes to the terminal's default.
|
||||
2. Setting the background color only affects subsequently written characters. Fish provides no way to set the background color for the entire terminal window. Configuring the window background color (and other attributes such as its opacity) has to be done using whatever mechanisms the terminal provides. Look for a config option.
|
||||
3. Some terminals use the ``--bold`` escape sequence to switch to a brighter color set rather than increasing the weight of text.
|
||||
4. ``set_color`` works by printing sequences of characters to standard output. If used in command substitution or a pipe, these characters will also be captured. This may or may not be desirable. Checking the exit status of ``isatty stdout`` before using ``set_color`` can be useful to decide not to colorize output in a script.
|
||||
1. Using ``set_color normal`` will reset all colors and modes to the terminal's default.
|
||||
2. In contrast, ``set_color --foreground normal`` will only reset the foreground color and leave all the other colors and modes unchanged.
|
||||
3. Setting the background color only affects subsequently written characters. Fish provides no way to set the background color for the entire terminal window. Configuring the window background color (and other attributes such as its opacity) has to be done using whatever mechanisms the terminal provides. Look for a config option.
|
||||
4. Some terminals use the ``--bold`` escape sequence to switch to a brighter color set rather than increasing the weight of text.
|
||||
5. ``set_color`` works by printing sequences of characters to standard output. If used in command substitution or a pipe, these characters will also be captured. This may or may not be desirable. Checking the exit status of ``isatty stdout`` before using ``set_color`` can be useful to decide not to colorize output in a script.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
@@ -155,6 +155,9 @@ Optional Commands
|
||||
* - ``\e[48;2; Ps ; Ps ; Ps m``
|
||||
-
|
||||
- Select background color from 24-bit RGB colors.
|
||||
* - ``\e[39m``
|
||||
-
|
||||
- Reset foreground color to the terminal's default.
|
||||
* - ``\e[49m``
|
||||
-
|
||||
- Reset background color to the terminal's default.
|
||||
|
||||
@@ -215,6 +215,10 @@ msgstr "%s: %s: ungültiger Unterbefehl"
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr ""
|
||||
|
||||
@@ -215,6 +215,10 @@ msgstr ""
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr ""
|
||||
|
||||
@@ -215,6 +215,10 @@ msgstr "%s: %s: subcomando no válido"
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr "%s: %s: nombre de variable no válido. Consulte `help %s`"
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr "%s: %s: la opción no acepta un argumento"
|
||||
|
||||
@@ -344,6 +344,10 @@ msgstr "%s : %s : sous-commande invalide"
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr "%s : %s : nom de variable invalide. Voir « help %s »"
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr "%s : %s : cette option ne prend pas d’argument"
|
||||
|
||||
@@ -211,6 +211,10 @@ msgstr ""
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr ""
|
||||
|
||||
@@ -216,6 +216,10 @@ msgstr ""
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr ""
|
||||
|
||||
@@ -212,6 +212,10 @@ msgstr ""
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr ""
|
||||
|
||||
@@ -236,6 +236,10 @@ msgstr "%s: %s: 无效的子命令"
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr "%s: %s: 无效的变量名。参见 `help %s`"
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr "%s: %s: 选项不接受参数"
|
||||
|
||||
@@ -209,6 +209,10 @@ msgstr "%s:%s:無效的子命令"
|
||||
msgid "%s: %s: invalid variable name. See `help %s`"
|
||||
msgstr "%s:%s:無效的變數名稱。參見「help %s」"
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option cannot be used with a non-option argument"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%s: %s: option does not take an argument"
|
||||
msgstr "%s:%s:選項不需要引數"
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
use crate::common::bytes2wcstring;
|
||||
use crate::screen::{is_dumb, only_grayscale};
|
||||
use crate::terminal::Outputter;
|
||||
use crate::text_face::{
|
||||
self, PrintColorsArgs, SpecifiedTextFace, TextFace, TextStyling, parse_text_face_and_options,
|
||||
};
|
||||
use crate::text_face::{self, PrintColorsArgs, TextFace, TextStyling, parse_text_face_and_options};
|
||||
use fish_color::Color;
|
||||
|
||||
fn print_colors(
|
||||
@@ -63,73 +61,88 @@ pub fn set_color(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -
|
||||
|
||||
use text_face::ParseError::*;
|
||||
use text_face::ParsedArgs::*;
|
||||
let (specified_face, with_reset) =
|
||||
match parse_text_face_and_options(argv, /*is_builtin=*/ true) {
|
||||
Ok(SetFace(face)) => (face, false),
|
||||
Ok(ResetFace) => (SpecifiedTextFace::default(), true),
|
||||
Ok(PrintColors(PrintColorsArgs {
|
||||
fg_args,
|
||||
bg,
|
||||
underline_color,
|
||||
style,
|
||||
})) => {
|
||||
print_colors(streams, fg_args, style, bg, underline_color);
|
||||
return Ok(SUCCESS);
|
||||
}
|
||||
Ok(PrintHelp) => {
|
||||
builtin_print_help(parser, streams, argv[0]);
|
||||
return Ok(SUCCESS);
|
||||
}
|
||||
Err(MissingOptArg) => {
|
||||
// Either "--background" or "--underline-color" are missing an argument.
|
||||
// Don't print an error, for consistency with "set_color".
|
||||
// In future we change both to actually print an error.
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnexpectedOptArg(option_index)) => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
L!("set_color"),
|
||||
argv[option_index],
|
||||
true, /* print_hints */
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(InvalidOptArg(name, value)) => {
|
||||
streams.err.appendln(&wgettext_fmt!(
|
||||
"%s: %s: invalid option argument: %s",
|
||||
argv[0],
|
||||
name,
|
||||
value
|
||||
));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnknownColor(arg)) => {
|
||||
streams
|
||||
.err
|
||||
.appendln(&wgettext_fmt!("%s: Unknown color '%s'", argv[0], arg));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnknownUnderlineStyle(arg)) => {
|
||||
streams.err.appendln(&wgettext_fmt!(
|
||||
"%s: invalid underline style: %s",
|
||||
argv[0],
|
||||
arg
|
||||
));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnknownOption(unknown_option_index)) => {
|
||||
builtin_unknown_option(
|
||||
parser,
|
||||
streams,
|
||||
L!("set_color"),
|
||||
argv[unknown_option_index],
|
||||
true, /* print_hints */
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
};
|
||||
let specified_face = match parse_text_face_and_options(argv, /*is_builtin=*/ true) {
|
||||
Ok(SetFace(face)) => face,
|
||||
Ok(PrintColors(PrintColorsArgs {
|
||||
fg_args,
|
||||
bg,
|
||||
underline_color,
|
||||
style,
|
||||
})) => {
|
||||
print_colors(streams, fg_args, style, bg, underline_color);
|
||||
return Ok(SUCCESS);
|
||||
}
|
||||
Ok(PrintHelp) => {
|
||||
builtin_print_help(parser, streams, argv[0]);
|
||||
return Ok(SUCCESS);
|
||||
}
|
||||
Err(MissingOptArg) => {
|
||||
// Either "--background" or "--underline-color" are missing an argument.
|
||||
// Don't print an error, for consistency with "set_color".
|
||||
// In future we change both to actually print an error.
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnexpectedOptArg(option_index)) => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
L!("set_color"),
|
||||
argv[option_index],
|
||||
true, /* print_hints */
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(InvalidOptArg(name, value)) => {
|
||||
streams.err.appendln(&wgettext_fmt!(
|
||||
"%s: %s: invalid option argument: %s",
|
||||
argv[0],
|
||||
name,
|
||||
value
|
||||
));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnknownColor(arg)) => {
|
||||
streams
|
||||
.err
|
||||
.appendln(&wgettext_fmt!("%s: Unknown color '%s'", argv[0], arg));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnknownUnderlineStyle(arg)) => {
|
||||
streams.err.appendln(&wgettext_fmt!(
|
||||
"%s: invalid underline style: %s",
|
||||
argv[0],
|
||||
arg
|
||||
));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnknownOption(unknown_option_index)) => {
|
||||
builtin_unknown_option(
|
||||
parser,
|
||||
streams,
|
||||
L!("set_color"),
|
||||
argv[unknown_option_index],
|
||||
true, /* print_hints */
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(InvalidFgArgCombination) => {
|
||||
streams.err.appendln(&wgettext_fmt!(
|
||||
"%s: %s: option cannot be used with a non-option argument",
|
||||
argv[0],
|
||||
"--foreground",
|
||||
));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(InvalidFgPrintColorCombination) => {
|
||||
streams.err.appendln(&wgettext_fmt!(
|
||||
BUILTIN_ERR_COMBO2_EXCLUSIVE,
|
||||
argv[0],
|
||||
"--foreground",
|
||||
"--print-colors",
|
||||
));
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
};
|
||||
|
||||
let mut outp = Outputter::new_buffering_no_assume_normal();
|
||||
|
||||
@@ -142,7 +155,7 @@ pub fn set_color(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -
|
||||
specified_face.underline_color.unwrap_or(Color::None),
|
||||
specified_face.style,
|
||||
),
|
||||
with_reset,
|
||||
specified_face.reset,
|
||||
);
|
||||
|
||||
if specified_face.fg.is_some() && outp.contents().is_empty() {
|
||||
|
||||
@@ -1911,8 +1911,11 @@ fn test_parse_text_face_for_highlight_fully_specified() {
|
||||
);
|
||||
};
|
||||
|
||||
assert_all_set(vec![L!("--reset").into()]);
|
||||
assert_all_set(vec![L!("normal").into()]);
|
||||
assert_all_set(vec![L!("green").into()]);
|
||||
assert_all_set(vec![L!("--foreground=normal").into()]);
|
||||
assert_all_set(vec![L!("--foreground=green").into()]);
|
||||
assert_all_set(vec![L!("--background=normal").into()]);
|
||||
assert_all_set(vec![L!("--background=green").into()]);
|
||||
assert_all_set(vec![L!("--underline-color=normal").into()]);
|
||||
|
||||
@@ -60,6 +60,7 @@ pub(crate) enum SgrTerminalCommand {
|
||||
// Colors
|
||||
SelectPaletteColor(Paintable, u8),
|
||||
SelectRgbColor(Paintable, Color24),
|
||||
DefaultForegroundColor,
|
||||
DefaultBackgroundColor,
|
||||
DefaultUnderlineColor,
|
||||
}
|
||||
@@ -376,9 +377,10 @@ fn set_text_face_internal(
|
||||
let style = face.style;
|
||||
|
||||
use SgrTerminalCommand::{
|
||||
DefaultBackgroundColor, DefaultUnderlineColor, EnterBoldMode, EnterDimMode,
|
||||
EnterItalicsMode, EnterReverseMode, EnterStrikethroughMode, EnterUnderlineMode,
|
||||
ExitItalicsMode, ExitReverseMode, ExitStrikethroughMode, ExitUnderlineMode,
|
||||
DefaultBackgroundColor, DefaultForegroundColor, DefaultUnderlineColor, EnterBoldMode,
|
||||
EnterDimMode, EnterItalicsMode, EnterReverseMode, EnterStrikethroughMode,
|
||||
EnterUnderlineMode, ExitItalicsMode, ExitReverseMode, ExitStrikethroughMode,
|
||||
ExitUnderlineMode,
|
||||
};
|
||||
|
||||
let mut style_writer = self.style_writer();
|
||||
@@ -411,12 +413,12 @@ fn set_text_face_internal(
|
||||
|
||||
if !fg.is_none() && fg != style_writer.last().fg {
|
||||
if fg.is_normal() {
|
||||
style_writer.reset_text_face();
|
||||
style_writer.write_command(DefaultForegroundColor);
|
||||
} else {
|
||||
assert!(!fg.is_special());
|
||||
style_writer.write_color(Paintable::Foreground, fg);
|
||||
style_writer.last().fg = fg;
|
||||
}
|
||||
style_writer.last().fg = fg;
|
||||
}
|
||||
|
||||
if !bg.is_none() && bg != style_writer.last().bg {
|
||||
@@ -680,6 +682,7 @@ pub(crate) fn write_command(&mut self, cmd: SgrTerminalCommand) -> bool {
|
||||
ExitUnderlineMode => self.write_param_str(1, b"24"),
|
||||
SelectPaletteColor(paintable, idx) => self.write_palette_color(paintable, idx),
|
||||
SelectRgbColor(paintable, rgb) => self.write_rgb_color(paintable, rgb),
|
||||
DefaultForegroundColor => self.write_param_str(1, b"39"),
|
||||
DefaultBackgroundColor => self.write_param_str(1, b"49"),
|
||||
DefaultUnderlineColor => self.write_param_str(1, b"59"),
|
||||
}
|
||||
|
||||
@@ -191,6 +191,7 @@ pub(crate) struct SpecifiedTextFace {
|
||||
pub(crate) bg: Option<Color>,
|
||||
pub(crate) underline_color: Option<Color>,
|
||||
pub(crate) style: TextStyling,
|
||||
pub(crate) reset: bool,
|
||||
}
|
||||
|
||||
impl Default for SpecifiedTextFace {
|
||||
@@ -200,6 +201,7 @@ fn default() -> Self {
|
||||
bg: Default::default(),
|
||||
underline_color: Default::default(),
|
||||
style: TextStyling::unknown(),
|
||||
reset: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +215,7 @@ pub(crate) fn parse_text_face(arguments: &[WString]) -> SpecifiedTextFace {
|
||||
match parse_text_face_and_options(&mut argv, /*is_builtin=*/ false) {
|
||||
Ok(SetFace(specified_face)) => specified_face,
|
||||
Err(_) => Default::default(),
|
||||
Ok(ResetFace) | Ok(PrintColors(_)) | Ok(PrintHelp) => unreachable!(),
|
||||
Ok(PrintColors(_)) | Ok(PrintHelp) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +228,6 @@ pub(crate) struct PrintColorsArgs<'argarray, 'args> {
|
||||
|
||||
pub(crate) enum ParsedArgs<'argarray, 'args> {
|
||||
SetFace(SpecifiedTextFace),
|
||||
ResetFace,
|
||||
PrintHelp,
|
||||
PrintColors(PrintColorsArgs<'argarray, 'args>),
|
||||
}
|
||||
@@ -238,6 +239,8 @@ pub(crate) enum ParseError<'args> {
|
||||
UnknownColor(&'args wstr),
|
||||
UnknownUnderlineStyle(&'args wstr),
|
||||
UnknownOption(usize),
|
||||
InvalidFgArgCombination,
|
||||
InvalidFgPrintColorCombination,
|
||||
}
|
||||
|
||||
fn parse_resettable_style<'a>(w: &WGetopter<'_, 'a, '_>) -> Result<ResettableStyle, &'a wstr> {
|
||||
@@ -258,9 +261,10 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
is_builtin: bool,
|
||||
) -> Result<ParsedArgs<'argarray, 'args>, ParseError<'args>> {
|
||||
let builtin_extra_args = if is_builtin { 0 } else { "hc".len() };
|
||||
let short_options = L!("b:oi::dr::s::u::ch");
|
||||
let short_options = L!("f:b:oi::dr::s::u::ch");
|
||||
let short_options = &short_options[..short_options.len() - builtin_extra_args];
|
||||
let long_options: &[WOption] = &[
|
||||
wopt(L!("foreground"), ArgType::RequiredArgument, 'f'),
|
||||
wopt(L!("background"), ArgType::RequiredArgument, 'b'),
|
||||
wopt(L!("underline-color"), ArgType::RequiredArgument, '\x02'),
|
||||
wopt(L!("bold"), ArgType::NoArgument, 'o'),
|
||||
@@ -270,6 +274,7 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
wopt(L!("reverse"), ArgType::OptionalArgument, 'r'),
|
||||
wopt(L!("strikethrough"), ArgType::OptionalArgument, 's'),
|
||||
wopt(L!("theme"), ArgType::RequiredArgument, '\x01'),
|
||||
wopt(L!("reset"), ArgType::NoArgument, '\x03'),
|
||||
wopt(L!("help"), ArgType::NoArgument, 'h'),
|
||||
wopt(L!("print-colors"), ArgType::NoArgument, 'c'),
|
||||
];
|
||||
@@ -289,14 +294,21 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
}
|
||||
};
|
||||
|
||||
let mut fg_colors = vec![];
|
||||
let mut bg_colors = vec![];
|
||||
let mut underline_colors = vec![];
|
||||
let mut style = TextStyling::unknown();
|
||||
let mut print_color_mode = false;
|
||||
let mut reset = false;
|
||||
|
||||
let mut w = WGetopter::new(short_options, long_options, argv);
|
||||
while let Some(c) = w.next_opt() {
|
||||
match c {
|
||||
'f' => {
|
||||
if let Some(fg) = parse_color(w.woptarg.unwrap())? {
|
||||
fg_colors.push(fg);
|
||||
}
|
||||
}
|
||||
'b' => {
|
||||
if let Some(bg) = parse_color(w.woptarg.unwrap())? {
|
||||
bg_colors.push(bg);
|
||||
@@ -308,6 +320,9 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
underline_colors.push(underline_color);
|
||||
}
|
||||
}
|
||||
'\x03' => {
|
||||
reset = true;
|
||||
}
|
||||
'h' => {
|
||||
assert!(is_builtin);
|
||||
return Ok(PrintHelp);
|
||||
@@ -362,6 +377,9 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
}
|
||||
|
||||
let fg_args = &w.argv[w.wopt_index..];
|
||||
if !fg_args.is_empty() && !fg_colors.is_empty() {
|
||||
return Err(InvalidFgArgCombination);
|
||||
}
|
||||
|
||||
let best_color =
|
||||
|colors: Vec<Color>| terminal::best_color(colors.into_iter(), get_color_support());
|
||||
@@ -370,6 +388,9 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
let underline_color = best_color(underline_colors);
|
||||
|
||||
if print_color_mode {
|
||||
if !fg_colors.is_empty() {
|
||||
return Err(InvalidFgPrintColorCombination);
|
||||
}
|
||||
return Ok(PrintColors(PrintColorsArgs {
|
||||
fg_args,
|
||||
bg,
|
||||
@@ -380,15 +401,21 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
|
||||
// Historical behavior: reset only applies if it's the first argument.
|
||||
if is_builtin && fg_args.first().is_some_and(|fg| fg == "reset") {
|
||||
return Ok(ResetFace);
|
||||
return Ok(SetFace(SpecifiedTextFace {
|
||||
reset: true,
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
let mut fg_colors = Vec::with_capacity(fg_args.len());
|
||||
fg_colors.reserve(fg_args.len());
|
||||
for fg in fg_args {
|
||||
if is_builtin && fg == "reset" {
|
||||
continue;
|
||||
}
|
||||
if let Some(fg) = parse_color(fg)? {
|
||||
if fg == Color::Normal {
|
||||
reset = true;
|
||||
}
|
||||
fg_colors.push(fg);
|
||||
}
|
||||
}
|
||||
@@ -399,6 +426,7 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
bg,
|
||||
underline_color,
|
||||
style,
|
||||
reset,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -420,6 +448,7 @@ fn test_parse_text_face() {
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
style: TextStyling::unknown(),
|
||||
reset: false
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ end
|
||||
|
||||
# ==========
|
||||
# Verify that `functions --details` works as expected when given too many args.
|
||||
functions --details f1 f2
|
||||
functions --details f1 f2
|
||||
#CHECKERR: functions: --details: expected 1 arguments; got 2
|
||||
|
||||
# Verify that it still mentions "--details" even if it isn't the last option.
|
||||
functions --details --verbose f1 f2
|
||||
functions --details --verbose f1 f2
|
||||
#CHECKERR: functions: --details: expected 1 arguments; got 2
|
||||
|
||||
# ==========
|
||||
@@ -210,7 +210,8 @@ functions --description ""
|
||||
# CHECKERR: ^
|
||||
# CHECKERR: (Type 'help functions' for related documentation)
|
||||
|
||||
function foo --on-variable foo; end
|
||||
function foo --on-variable foo
|
||||
end
|
||||
# This should print *everything*
|
||||
functions --handlers-type "" | string match 'Event *'
|
||||
# CHECK: Event signal
|
||||
@@ -250,5 +251,5 @@ functions --no-details --color=never test_color_option
|
||||
|
||||
string escape (functions --no-details --color=always test_color_option)
|
||||
# CHECK: function\ \e\[36mtest_color_option\e\[32m
|
||||
# CHECK: \e\[m\ \ \ \ echo\ \e\[36mhello\e\[32m
|
||||
# CHECK: \e\[mend\e\[32m\e\[m
|
||||
# CHECK: \e\[39m\ \ \ \ echo\ \e\[36mhello\e\[32m
|
||||
# CHECK: \e\[39mend\e\[32m\e\[39m
|
||||
|
||||
@@ -550,7 +550,7 @@ echo 'PATH={$PATH[echo " "' | $fish_indent --ansi
|
||||
fish_config theme choose "ayu Dark"
|
||||
echo -n 'echo hello' | builtin fish_indent --ansi
|
||||
echo end
|
||||
# CHECK: {{\x1b\[38;2;57;186;230mecho\x1b\[38;2;179;177;173m hello\x1b\[38;2;242;150;104m\x1b\[m}}
|
||||
# CHECK: {{\x1b\[38;2;57;186;230mecho\x1b\[38;2;179;177;173m hello\x1b\[38;2;242;150;104m\x1b\[39m}}
|
||||
# CHECK: end
|
||||
|
||||
echo a\> | $fish_indent
|
||||
|
||||
@@ -4,12 +4,33 @@ string escape (set_color normal)
|
||||
# CHECK: \e\[m
|
||||
string escape (set_color reset)
|
||||
# CHECK: \e\[m
|
||||
string escape (set_color --reset)
|
||||
# CHECK: \e\[m
|
||||
|
||||
string escape (set_color red yellow)
|
||||
# CHECK: \e\[31m
|
||||
string escape (set_color red reset yellow)
|
||||
# CHECK: \e\[31m
|
||||
|
||||
string escape (set_color -fred)
|
||||
# CHECK: \e\[31m
|
||||
string escape (set_color --foreground red)
|
||||
# CHECK: \e\[31m
|
||||
string escape (set_color --foreground normal)
|
||||
# CHECK: \e\[39m
|
||||
string escape (set_color --foreground reset)
|
||||
# CHECKERR: set_color: Unknown color 'reset'
|
||||
|
||||
string escape (set_color --foreground=f00 --foreground=green --foreground=00f)
|
||||
# CHECK: \e\[38\;2\;255\;0\;0m
|
||||
fish_term256=0 string escape (set_color --foreground=f00 --foreground=green --foreground=00f)
|
||||
# CHECK: \e\[32m
|
||||
|
||||
string escape (set_color --foreground red red)
|
||||
# CHECKERR: set_color: --foreground: option cannot be used with a non-option argument
|
||||
string escape (set_color --foreground red --print-colors)
|
||||
# CHECKERR: set_color: --foreground --print-colors: options cannot be used together
|
||||
|
||||
string escape (set_color --background=reset)
|
||||
# CHECKERR: set_color: Unknown color 'reset'
|
||||
|
||||
@@ -139,5 +160,5 @@ string escape (set_color --underline=dashed)
|
||||
string escape (set_color --underline=off)
|
||||
# CHECK: \e\[24m
|
||||
|
||||
string escape (set_color f00 --background=00f --underline-color=0f0 --bold --dim --italics --reverse --strikethrough --underline=curly)
|
||||
# CHECK: \e\[38\;2\;255\;0\;0\;48\;2\;0\;0\;255\;58:2::0:255:0\;1\;4:3\;2\;3\;7m\e\[9m
|
||||
string escape (set_color --reset f00 --background=00f --underline-color=0f0 --bold --dim --italics --reverse --strikethrough --underline=curly)
|
||||
# CHECK: \e\[\;38\;2\;255\;0\;0\;48\;2\;0\;0\;255\;58:2::0:255:0\;1\;4:3\;2\;3m\e\[7\;9m
|
||||
|
||||
Reference in New Issue
Block a user