diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ccf37e985..e5a551d02 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -26,6 +26,11 @@ Deprecations and removed features set -Ua fish_features no-ignore-terminfo - The `--install` option when fish is built as self-installable was removed. If you need to write out fish's data you can use the new `status list-files` and `status get-file` subcommands, but it should no longer be necessary. (:issue:`11143`) +- RGB colors (``set_color ff0000``) now default to using 24-bit RGB true-color commands, even if the terminal does not advertise support via ``COLORTERM``. + - To go back to using the nearest match from the 256-color palette, use ``set fish_term24bit 0`` or ``set COLORTERM 0``. + - To make the nearest-match logic use the 16 color palette instead, use ``set fish_term256 0``. + - Inside macOS Terminal.app, fish makes an attempt to still use the palette colors. + If that doesn't work, use ``set fish_term24bit 0``. Scripting improvements ---------------------- diff --git a/doc_src/cmds/set_color.rst b/doc_src/cmds/set_color.rst index ccda9b158..0d66d5cb6 100644 --- a/doc_src/cmds/set_color.rst +++ b/doc_src/cmds/set_color.rst @@ -22,7 +22,13 @@ Valid colors include: The *br*- (as in 'bright') forms are full-brightness variants of the 8 standard-brightness colors on many terminals. **brblack** has higher brightness than **black** - towards gray. -An RGB value with three or six hex digits, such as A0FF33 or f2f can be used. Fish will choose the closest supported color. A three digit value is equivalent to specifying each digit twice; e.g., ``set_color 2BC`` is the same as ``set_color 22BBCC``. Hexadecimal RGB values can be in lower or uppercase. Depending on the capabilities of your terminal (and the level of support ``set_color`` has for it) the actual color may be approximated by a nearby matching reserved color. +An RGB value with three or six hex digits, such as A0FF33 or f2f can be used. +A three digit value is equivalent to specifying each digit twice; e.g., ``set_color 2BC`` is the same as ``set_color 22BBCC``. +Hexadecimal RGB values can be in lower or uppercase. + +If :envvar:`fish_term24bit` is set to 0, fish will translate RGB values to the nearest color on the 256-color palette. +If :envvar:`fish_term256` is also set to 0, fish will translate them to the 16-color palette instead. +Fish launched as ``fish -d term_support`` will include diagnostic messages that indicate the color support mode in use. A second color may be given as a desired fallback color. e.g. ``set_color 124212 brblue`` will instruct set_color to use *brblue* if a terminal is not capable of the exact shade of grey desired. This is very useful when an 8 or 16 color terminal might otherwise not use a color. @@ -72,17 +78,3 @@ Examples set_color blue; echo "Violets are blue" set_color 62A; echo "Eggplants are dark purple" set_color normal; echo "Normal is nice" # Resets the background too - - -Terminal Capability Detection ------------------------------ - -Fish uses some heuristics to determine what colors a terminal supports to avoid sending sequences that it won't understand. - -In particular it will: - -- Enable 24-bit ("true-color") even if the $TERM entry only reports 256 colors. This includes modern xterm, VTE-based terminals like Gnome Terminal, Konsole and iTerm2. - -To force true-color support on or off, set :envvar:`fish_term24bit` to "1" for on and 0 for off - ``set -g fish_term24bit 1``. - -Fish launched as ``fish -d term_support`` will include diagnostic messages that indicate the color support mode in use. diff --git a/doc_src/language.rst b/doc_src/language.rst index 8694619c0..8d9745de3 100644 --- a/doc_src/language.rst +++ b/doc_src/language.rst @@ -1566,12 +1566,12 @@ You can change the settings of fish by changing the values of certain variables. .. envvar:: fish_term24bit - If this is set to 1, fish will assume the terminal understands 24-bit RGB color sequences, and won't translate them to the 256 or 16 color palette. - This is often detected automatically. + If this is set to 0, fish will not output 24-bit RGB true-color sequences but the nearest color on the 256 color palette (or the 16 color palette, if :envvar:`fish_term256` is 0). .. envvar:: fish_term256 - If this is set to 0, fish will not output 256 colors, but translate colors down to the 16 color palette. + If this is set to 0 and :envvar:`fish_term24bit` is 0, translate RGB colors down to the 16 color palette. + Also, if this is set to 0, :doc:`set_color `/` commands such as ``set_color ff0000 red`` will prefer the named color. .. envvar:: fish_ambiguous_width diff --git a/src/env_dispatch.rs b/src/env_dispatch.rs index 9af9b0121..6481192f4 100644 --- a/src/env_dispatch.rs +++ b/src/env_dispatch.rs @@ -382,6 +382,7 @@ fn update_fish_color_support(vars: &EnvStack) { let term = vars.get_unless_empty(L!("TERM")); let term = term.as_ref().map_or(L!(""), |term| &term.as_list()[0]); + let is_xterm_16color = term == "xterm-16color"; let supports_256color = if let Some(fish_term256) = vars.get(L!("fish_term256")) { let ok = crate::wcstringutil::bool_from_string(&fish_term256.as_string()); @@ -392,10 +393,10 @@ fn update_fish_color_support(vars: &EnvStack) { ); ok } else { - term != "xterm-16color" + !is_xterm_16color }; - let mut supports_24bit = false; + let supports_24bit; if let Some(fish_term24bit) = vars.get(L!("fish_term24bit")).map(|v| v.as_string()) { // $fish_term24bit supports_24bit = crate::wcstringutil::bool_from_string(&fish_term24bit); @@ -408,19 +409,14 @@ fn update_fish_color_support(vars: &EnvStack) { "disabled" } ); - } else if vars.get(L!("STY")).is_some() || term.starts_with(L!("eterm")) { - // Screen and emacs' ansi-term swallow true-color sequences, so we ignore them unless - // force-enabled. + } else if vars.get(L!("STY")).is_some() { + // Screen requires "truecolor on" to enable true-color sequences, so we ignore them + // unless force-enabled. supports_24bit = false; - FLOG!( - term_support, - "True-color support: disabled for eterm/screen" - ); + FLOG!(term_support, "True-color support: disabled for screen"); } else if let Some(ct) = vars.get(L!("COLORTERM")).map(|v| v.as_string()) { // If someone sets $COLORTERM, that's the sort of color they want. - if ct == "truecolor" || ct == "24bit" { - supports_24bit = true; - } + supports_24bit = ct == "truecolor" || ct == "24bit"; FLOG!( term_support, "True-color support", @@ -432,32 +428,20 @@ fn update_fish_color_support(vars: &EnvStack) { "per $COLORTERM", ct ); - } else if vars.get(L!("KONSOLE_VERSION")).is_some() - || vars.get(L!("KONSOLE_PROFILE_NAME")).is_some() - { - // All Konsole versions that use $KONSOLE_VERSION are new enough to support this, so no - // check is needed. - supports_24bit = true; - FLOG!(term_support, "True-color support: enabled for Konsole"); - } else if let Some(it) = vars.get(L!("ITERM_SESSION_ID")).map(|v| v.as_string()) { - // Supporting versions of iTerm include a colon here. - // We assume that if this is iTerm it can't also be st, so having this check inside is okay. - if !it.contains(':') { - supports_24bit = true; - FLOG!(term_support, "True-color support: enabled for iTerm"); - } - } else if term.starts_with("st-") { - supports_24bit = true; - FLOG!(term_support, "True-color support: enabling for st"); - } else if let Some(vte) = vars.get(L!("VTE_VERSION")).map(|v| v.as_string()) { - if fish_wcstoi(&vte).unwrap_or(0) > 3600 { - supports_24bit = true; - FLOG!( - term_support, - "True-color support: enabled for VTE version", - vte - ); - } + } else { + supports_24bit = !is_xterm_16color + && !vars + .get_unless_empty(L!("TERM_PROGRAM")) + .is_some_and(|term| term.as_list()[0] == "Apple_Terminal"); + FLOG!( + term_support, + "True-color support", + if supports_24bit { + "enabled" + } else { + "disabled" + }, + ); } let mut color_support = ColorSupport::default();