fish_config theme choose: overwrite color-aware theme's vars also if called from config

Webconfig persists themes to ~/.config/fish/conf.d/fish_frozen_theme.fish
(the name is due to historical reasons).

That file's color variables have no "--theme=foo" annotations, which
means that fish_config can't distinguish them from other "user-set"
values.  We can change this in future, but that doesn't affect the
following fix.

A "fish_config theme choose foo" command is supposed to
overwrite all variables that are defined in "foo.theme".
If the theme is color-theme-aware *and* this command runs before
$fish_terminal_color_theme is initialized, we delay loading of the
theme until that initialization happens.  But the --on-variable
invocation won't have the override bit set, thus it will not touch
variables that don't have "--theme=*" value.  Fix this by clearing
immediately the variables mentioned in the theme.

Fixes #12278

While at it, tweak the error message for this command because it's
not an internal error:

	fish -c 'echo yes | fish_config theme save tomorrow'
This commit is contained in:
Johannes Altmanninger
2026-01-06 08:48:18 +01:00
parent c638401469
commit 6d8bb292ec
3 changed files with 48 additions and 11 deletions

View File

@@ -7,6 +7,7 @@ This release fixes the following problems identified in fish 4.3.0:
- Glitch with soft-wrapped autosuggestions and :doc:`cmds/fish_right_prompt` (:issue:`12255`).
- Spurious echo in tmux when typing a command really fast (:issue:`12261`).
- ``tomorrow`` theme always using the light variant (:issue:`12266`).
- ``fish_config theme choose`` sometimes not shadowing themes set by e.g. webconfig (:issue:`12278`).
- The sample prompts and themes are correctly installed (:issue:`12241`).
- Last line of command output could be hidden when missing newline (:issue:`12246`).

View File

@@ -321,10 +321,11 @@ function __fish_config_theme_choose
else
set desired_color_theme $fish_terminal_color_theme
if not set -q desired_color_theme[1]
echo >&2 "fish_config theme choose: internal error: \$fish_terminal_color_theme not yet initialized"
return 1
end
if not contains -- "[$desired_color_theme]" $theme_data
if test $scope = -U
echo >&2 "fish_config theme save: error: \$fish_terminal_color_theme not yet initialized"
return 1
end
else if not contains -- "[$desired_color_theme]" $theme_data
__fish_config_theme_choose_bad_color_theme $theme_name "$desired_color_theme" \$fish_terminal_color_theme = $desired_color_theme
echo >&2 "fish_config theme choose: hint: if your terminal does not report colors, pass --color-theme=light or --color-theme=dark when using color-theme-aware themes"
return 1
@@ -342,7 +343,7 @@ function __fish_config_theme_choose
set -l color_theme
string match -re -- (__fish_theme_variable_filter)'|^\[.*\]$' $theme_data |
while read -lat toks
if $theme_is_color_theme_aware
if $theme_is_color_theme_aware && set -q desired_color_theme[1]
for ct in $color_themes
if test "$toks" = [$ct]
set color_theme $ct
@@ -362,7 +363,11 @@ function __fish_config_theme_choose
set -eg $varname
end
if $override || not set -q $varname || string match -rq -- '--theme=.*' $$varname
set $scope $toks (test $scope != -U && echo --theme=$theme_name)
set $scope $toks[1] (
if not $theme_is_color_theme_aware || set -q desired_color_theme[1]
string join \n -- $toks[2..]
end
) (test $scope != -U && echo --theme=$theme_name)
end
end
if $override
@@ -376,12 +381,15 @@ function __fish_config_theme_choose
end
end
end
if test -n "$fish_terminal_color_theme" || not $need_hook
if set -q _flag_no_override[1]
__fish_apply_theme
else
__fish_override=true __fish_apply_theme
if not $need_hook || test -n "$fish_terminal_color_theme" ||
# comment to work around fish_indent bug
{
$theme_is_color_theme_aware && test -z "$fish_terminal_color_theme"
}
if not set -q _flag_no_override[1]
set -fx __fish_override true
end
__fish_apply_theme
end
end

View File

@@ -1,6 +1,8 @@
# RUN: %fish %s
# REQUIRES: command -v diff
set -g fish (status fish-path)
fish_config prompt list | string match -r '^(?:acidhub|disco|nim)$'
# CHECK: acidhub
# CHECK: disco
@@ -218,5 +220,31 @@ echo >$__fish_config_dir/themes/custom-from-userconf.theme \
# CHECK: $fish_color_normal[1]: |normal|
}
{
echo >$__fish_config_dir/conf.d/fish_frozen_theme.fish "\
set --global fish_color_command 0a0a0a
set --global fish_color_option 0b0b0b"
echo >$__fish_config_dir/themes/from-cli.theme "\
[light]
fish_color_command black
fish_color_param 0c0c0c
[dark]
fish_color_command white
fish_color_param c0c0c0"
$fish -c '
fish_config theme choose from-cli
echo $fish_color_command
# CHECK: --theme=from-cli
echo $fish_color_option
# CHECK: 0b0b0b
echo $fish_color_param
# CHECK: --theme=from-cli
echo yes | fish_config theme save from-cli
# CHECKERR: fish_config theme save: error: $fish_terminal_color_theme not yet initialized
and echo assertion failure
'
rm -f $__fish_config_dir/conf.d/fish_frozen_theme.fish
}
fish_config theme dump badarg
# CHECKERR: Too many arguments