Use curly underlines for errors in default themes

Given that this curly underline will also be red, it should be widely
understood as error.

Since fish always renders immediately (and synchronously), typing "echo"
will briefly show an intermediate curly line.  Maybe fish should redraw
after a timer elapses? This is probably unrelated to this patch.

As mentioned in cc9849c279 (Curly underlines in set_color and fish_color_*,
2025-04-13), there are still some terminals that interpret "\e[4:3m" as
something other than curly underline.

Some of them interpret it as background/foreground color, and some terminal
multiplexers downgrade it to straight underlines (which often happens due
to a false positive).  I want to change this in multiplexers where possible
(see https://github.com/orgs/tmux/discussions/4477) but for now, disable
this feature in multiplexers (there are just a handful).

In a few years, those terminals will maybe agree with XTerm.  Until then,
use XTGETTCAP as a temporary stepping stone. We could also read the terminfo
database but that will give only very few true positives, and lots of false
negatives.  Better implement XTGETTCAP in the relevant terminals.

Note that if the universal variables use the "--track" flag (from the
grandparent commit), then

	rm -rf /tmp/newhome
	foot -e env $HOME=/tmp/newhome fish
	xterm -e env $HOME=/tmp/newhome fish

will "magically work". For foot, $fish_color_error will have --underline=curly.
For xterm, it will not, due to the call to "fish_config theme update".
But of course since it's a universal variable, running fish in xterm
would also downgrade the fish running in other terminals.

Add a "fish_config theme save --yes" flag because "status xtgettcap"
requires stdin to be a terminal.  I'd probably drop this requirement, and
make "status xtgettcap" always use fish's stdin and not its own.  That'd be
cheating because an external command can't do that but I don't think this
change would be hurting anyone.
This commit is contained in:
Johannes Altmanninger
2025-04-13 15:55:21 +02:00
parent 3453565a41
commit ba2ad33a81
32 changed files with 81 additions and 39 deletions

View File

@@ -69,6 +69,9 @@ Improved terminal support
^^^^^^^^^^^^^^^^^^^^^^^^^
- Support for curly underlines in `fish_color_*` variables and :doc:`set_color <cmds/set_color>` (:issue:`10957`).
- Underlines can now be colored independent of text (:issue:`7619`).
- Errors are now highlighted with curly underlines in the default themes.
For compatibility with terminals that interpret the curly-underline escape sequence in an unexpected way,
the default themes enable this only if the terminal advertises support for the ``Su`` capability via XTGETTCAP.
- New documentation page `Terminal Compatibility <terminal-compatibility.html>`_ (also accessible via ``man fish-terminal-compatibility``) lists required and optional terminal control sequences used by fish.
- :doc:`status <cmds/status>` learned the ``xtgettcap`` subcommand, to query terminfo capabilities via XTGETTCAP commands.
- :doc:`status <cmds/status>` learned the ``xtversion`` subcommand, to show the terminal's name and version (as reported by via the XTVERSION command).

View File

@@ -30,7 +30,7 @@ if status is-interactive
# Commands to run in interactive sessions can go here
end" >$__fish_config_dir/config.fish
echo yes | fish_config theme save "fish default" --track
fish_config theme save "fish default" --yes --track
set -Ue fish_color_keyword fish_color_option
end
if test $__fish_initialized -lt 3800 && test "$fish_color_search_match[1]" = bryellow

View File

@@ -0,0 +1,3 @@
function __fish_in_gnu_screen
test -n "$STY" || contains -- $TERM screen screen-256color
end

View File

@@ -0,0 +1,9 @@
function __fish_in_terminal_multiplexer
set -l terminal_name "(status xtversion | string match -r '^\S*')"
string match -q -- tmux $terminal_name ||
__fish_in_gnu_screen ||
# Emacs does probably not support multiplexing between multiple parent
# terminals, but it is affected by the same issues. Same for Vim's
# :terminal TODO detect that before they implement XTGETTCAP.
contains -- $TERM dvtm-256color eterm eterm-color
end

View File

@@ -78,9 +78,7 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod
bind --preset $argv alt-o __fish_preview_current_file
bind --preset $argv alt-w __fish_whatis_current_token
bind --preset $argv ctrl-l (
if test -z "$STY"
and not string match -qr -- '^(screen|screen-256color)$' $TERM
and __fish_xtgettcap indn
if not __fish_in_gnu_screen && and __fish_xtgettcap indn
echo scrollback-push
end
) clear-screen

View File

@@ -5,7 +5,7 @@ function fish_config --description "Launch fish's web based configuration" \
--inherit-variable theme_var_filter
set -l _flag_track
argparse h/help track -- $argv
argparse h/help track yes -- $argv
or return
if set -q _flag_help
@@ -20,6 +20,10 @@ function fish_config --description "Launch fish's web based configuration" \
echo >&2 fish_config: --track: unknown option
return 1
end
if set -q _flag_yes[1] && not { contains "$cmd" prompt theme && test "$argv[1]" = save }
echo >&2 fish_config: --yes: unknown option
return 1
end
set -q cmd[1]
or set cmd browse
@@ -152,8 +156,8 @@ function fish_config --description "Launch fish's web based configuration" \
functions --erase fish_right_prompt
end
case save
read -P"Overwrite prompt? [y/N]" -l yesno
if string match -riq 'y(es)?' -- $yesno
if set -q _flag_yes[1] ||
{ read -P"Overwrite prompt? [y/N]" -l yesno; string match -riq 'y(es)?' -- $yesno }
echo Overwriting
# Skip the cp if unnecessary,
# or we'd throw an error on a stock fish.
@@ -282,8 +286,10 @@ function fish_config --description "Launch fish's web based configuration" \
set -l have_colors
if contains -- $cmd save
read -P"Overwrite your current theme? [y/N] " -l yesno
if not string match -riq 'y(es)?' -- $yesno
if not set -q _flag_yes &&
{ read -P"Overwrite your current theme? [y/N] " -l yesno
not string match -riq 'y(es)?' -- $yesno
}
echo Not overwriting >&2
return 1
end
@@ -362,10 +368,14 @@ function __fish_config_theme_get
set -l dirs $__fish_config_dir/themes $__fish_data_dir/tools/web_config/themes
set -l files $dirs/$argv[1].theme
set -l file
set -l is_default_theme false
for f in $files
if test -e "$f"
set file $f
if test $f = $__fish_data_dir/tools/web_config/themes/$argv[1].theme
set is_default_theme true
end
break
end
end
@@ -373,6 +383,7 @@ function __fish_config_theme_get
if not set -q file[1]
if status list-files tools/web_config/themes/$argv[1].theme &>/dev/null
set file tools/web_config/themes/$argv[1].theme
set is_default_theme true
else
echo "No such theme: $argv[1]" >&2
echo "Searched directories: $dirs" >&2
@@ -380,11 +391,18 @@ function __fish_config_theme_get
end
end
if string match -qr '^tools/' -- $file
status get-file $file
else
string join \n <$file
set -l content (
if string match -qr '^tools/' -- $file
status get-file $file
else
string join \n <$file
end
)
if $is_default_theme && not __fish_in_gnu_screen && not __fish_xtgettcap Su && not __fish_in_terminal_multiplexer
set content (string replace -- --underline=curly "" $content)
end
string join \n $content
end
function __fish_config_show_tracked_color_vars

View File

@@ -10,7 +10,7 @@ fish_color_comment f7ca88
fish_color_cwd green
fish_color_cwd_root red
fish_color_end ba8baf
fish_color_error ab4642
fish_color_error ab4642 --underline=curly
fish_color_escape 86c1b9
fish_color_history_current --bold
fish_color_host normal

View File

@@ -10,7 +10,7 @@ fish_color_comment f7ca88
fish_color_cwd green
fish_color_cwd_root red
fish_color_end ba8baf
fish_color_error ab4642
fish_color_error ab4642 --underline=curly
fish_color_escape 86c1b9
fish_color_history_current --bold
fish_color_host normal

View File

@@ -10,7 +10,7 @@ fish_color_comment ffcc66
fish_color_cwd green
fish_color_cwd_root red
fish_color_end cc99cc
fish_color_error f2777a
fish_color_error f2777a --underline=curly
fish_color_escape 66cccc
fish_color_history_current --bold
fish_color_host normal

View File

@@ -9,7 +9,7 @@ fish_color_comment FF9640
fish_color_cwd green
fish_color_cwd_root red
fish_color_end FFB273
fish_color_error FF7400
fish_color_error FF7400 --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -21,7 +21,7 @@ fish_color_comment 6272a4
fish_color_cwd 50fa7b
fish_color_cwd_root red
fish_color_end ffb86c
fish_color_error ff5555
fish_color_error ff5555 --underline=curly
fish_color_escape ff79c6
fish_color_history_current --bold
fish_color_host bd93f9

View File

@@ -9,7 +9,7 @@ fish_color_comment FFE100
fish_color_cwd green
fish_color_cwd_root red
fish_color_end 8D003B
fish_color_error EC3B86
fish_color_error EC3B86 --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -9,7 +9,7 @@ fish_color_comment B0B0B0
fish_color_cwd green
fish_color_cwd_root red
fish_color_end 969696
fish_color_error FFA779
fish_color_error FFA779 --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -6,7 +6,7 @@ fish_color_command FF9400
fish_color_quote BF9C30
fish_color_redirection BF5B30
fish_color_end FF4C00
fish_color_error FFDD73
fish_color_error FFDD73 --underline=curly
fish_color_param FFC000
fish_color_comment A63100
fish_color_selection white --background=brblack --bold

View File

@@ -9,7 +9,7 @@ fish_color_comment 4e4e4e
fish_color_cwd green
fish_color_cwd_root red
fish_color_end 767676
fish_color_error b2b2b2
fish_color_error b2b2b2 --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -6,7 +6,7 @@ fish_color_command ffffff
fish_color_quote a8a8a8
fish_color_redirection 808080
fish_color_end 949494
fish_color_error 585858
fish_color_error 585858 --underline=curly
fish_color_param d7d7d7
fish_color_comment bcbcbc
fish_color_selection white --background=brblack --bold

View File

@@ -9,7 +9,7 @@ fish_color_comment
fish_color_cwd normal
fish_color_cwd_root normal
fish_color_end
fish_color_error
fish_color_error --underline=curly
fish_color_escape
fish_color_history_current
fish_color_host normal

View File

@@ -11,7 +11,7 @@ fish_color_comment 4c566a --italics
fish_color_cwd 5e81ac
fish_color_cwd_root bf616a
fish_color_end 81a1c1
fish_color_error bf616a
fish_color_error bf616a --underline=curly
fish_color_escape ebcb8b
fish_color_history_current e5e9f0 --bold
fish_color_host a3be8c

View File

@@ -9,7 +9,7 @@ fish_color_comment 30BE30
fish_color_cwd green
fish_color_cwd_root red
fish_color_end FF7B7B
fish_color_error A40000
fish_color_error A40000 --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -9,7 +9,7 @@ fish_color_comment 5C9900
fish_color_cwd green
fish_color_cwd_root red
fish_color_end 8EEB00
fish_color_error 60B9CE
fish_color_error 60B9CE --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -6,7 +6,7 @@ fish_color_command 164CC9
fish_color_quote 4C3499
fish_color_redirection 248E8E
fish_color_end 02BDBD
fish_color_error 9177E5
fish_color_error 9177E5 --underline=curly
fish_color_param 4319CC
fish_color_comment 007B7B
fish_color_selection white --background=brblack --bold

View File

@@ -10,7 +10,7 @@ fish_color_comment 586e75
fish_color_cwd green
fish_color_cwd_root red
fish_color_end 268bd2
fish_color_error dc322f
fish_color_error dc322f --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -7,7 +7,7 @@ fish_color_command 586e75
fish_color_quote 839496
fish_color_redirection 6c71c4
fish_color_end 268bd2
fish_color_error dc322f
fish_color_error dc322f --underline=curly
fish_color_param 657b83
fish_color_comment 93a1a1
fish_color_selection white --background=brblack --bold

View File

@@ -10,7 +10,7 @@ fish_color_comment e7c547
fish_color_cwd green
fish_color_cwd_root red
fish_color_end c397d8
fish_color_error d54e53
fish_color_error d54e53 --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -7,7 +7,7 @@ fish_color_command b294bb
fish_color_quote b5bd68
fish_color_redirection 8abeb7
fish_color_end b294bb
fish_color_error cc6666
fish_color_error cc6666 --underline=curly
fish_color_param 81a2be
fish_color_comment f0c674
fish_color_selection white --background=brblack --bold

View File

@@ -10,7 +10,7 @@ fish_color_comment eab700
fish_color_cwd green
fish_color_cwd_root red
fish_color_end 8959a8
fish_color_error c82829
fish_color_error c82829 --underline=curly
fish_color_escape 00a6b2
fish_color_history_current --bold
fish_color_host normal

View File

@@ -7,7 +7,7 @@ fish_color_command 39BAE6
fish_color_quote C2D94C
fish_color_redirection FFEE99
fish_color_end F29668
fish_color_error FF3333
fish_color_error FF3333 --underline=curly
fish_color_param B3B1AD
fish_color_comment 626A73
fish_color_selection --background=E6B450 --bold

View File

@@ -10,7 +10,7 @@ fish_color_comment ABB0B6
fish_color_cwd 399EE6
fish_color_cwd_root red
fish_color_end ED9366
fish_color_error F51818
fish_color_error F51818 --underline=curly
fish_color_escape 4CBF99
fish_color_history_current --bold
fish_color_host normal

View File

@@ -10,7 +10,7 @@ fish_color_comment 5C6773
fish_color_cwd 73D0FF
fish_color_cwd_root red
fish_color_end F29E74
fish_color_error FF3333
fish_color_error FF3333 --underline=curly
fish_color_escape 95E6CB
fish_color_history_current --bold
fish_color_host normal

View File

@@ -9,7 +9,7 @@ fish_color_comment '888' '--italics'
fish_color_cwd 0A0
fish_color_cwd_root A00
fish_color_end 009900
fish_color_error F22
fish_color_error F22 --underline=curly
fish_color_escape 0AA
fish_color_history_current 0AA
fish_color_host normal

View File

@@ -11,7 +11,7 @@ fish_color_comment red
fish_color_cwd green
fish_color_cwd_root red
fish_color_end green
fish_color_error brred
fish_color_error brred --underline=curly
fish_color_escape brcyan
fish_color_history_current --bold
fish_color_host normal

View File

@@ -1,7 +1,10 @@
#RUN: %fish %s
mkdir $__fish_config_dir/themes
echo >$__fish_config_dir/themes/foo.theme 'fish_color_normal cyan'
echo >$__fish_config_dir/themes/foo.theme '
fish_color_normal cyan
fish_color_error brred --underline=curly
'
set -g fish_pager_color_secondary_background custom-value
fish_config theme choose foo
@@ -12,6 +15,14 @@ set -S fish_color_normal
set -S fish_pager_color_secondary_background
# CHECK: $fish_pager_color_secondary_background: set in global scope, unexported, with 0 elements
# Not a default theme, so we allow --underline=curly even if we don't run inside a terminal that
# advertises support via XTGETTCAP.
set -S fish_color_error
# CHECK: $fish_color_error: set in global scope, unexported, with 2 elements
# CHECK: $fish_color_error[1]: |brred|
# CHECK: $fish_color_error[2]: |--underline=curly|
function change-theme
echo >$__fish_config_dir/themes/fake-default.theme 'fish_color_command' $argv
end