fish_config: Add CLI-based theme selector

`fish_config theme`:

- `list` to list all available themes (files in the two theme
directories - either the web_config/themes one or
~/.config/fish/themes!)
- `show` to show select (or all) themes right in the terminal - this
starts another fish that reads the theme file and prints the sample
text, manually colored
- `choose` to load a theme *now*, setting the variables globally
- `save` to load a theme and save the variables universally
- `dump` to write the current theme in .theme format (to stdout)
- `demo` to display the current theme
This commit is contained in:
Fabian Homborg 2021-07-10 10:26:58 +02:00
parent fd35dc2aa1
commit 8223e6f23e
3 changed files with 224 additions and 69 deletions

View file

@ -11,6 +11,7 @@ Synopsis
fish_config
fish_config browse
fish_config prompt (choose | list | save | show)
fish_config theme (choose | demo | dump | list | save | show)
Description
-----------
@ -30,6 +31,19 @@ Available subcommands for the ``prompt`` command:
- ``save`` saves the current prompt to a file (via :ref:`funcsave <cmd-funcsave>`).
- ``show`` shows what the given sample prompts (or all) would look like.
With the ``theme`` command ``fish_config`` can be used to view and choose a theme (meaning a color scheme) inside the terminal.
Available subcommands for the ``theme`` command:
- ``choose`` loads a sample theme in the current session.
- ``demo`` displays some sample text in the current theme.
- ``dump`` prints the current theme in a loadable format.
- ``list`` lists the names of the available sample themes.
- ``save`` saves the current prompt to :ref:`universal variables <variables-universal>`.
- ``show`` shows what the given sample theme (or all) would look like.
The themes are loaded from the theme directory shipped with fish or a ``themes`` directory in the fish configuration directory (typically ``~/.config/fish/themes``).
Example
-------

View file

@ -1,5 +1,6 @@
complete fish_config -f
set -l prompt_commands choose save show list
set -l theme_commands choose demo dump save show list
complete fish_config -n '__fish_use_subcommand' -a prompt -d 'View and pick from the sample prompts'
complete fish_config -n "__fish_seen_subcommand_from prompt; and not __fish_seen_subcommand_from $prompt_commands" \
-a choose -d 'View and pick from the sample prompts'
@ -12,3 +13,18 @@ complete fish_config -n "__fish_seen_subcommand_from prompt; and not __fish_seen
complete fish_config -n '__fish_seen_subcommand_from prompt; and __fish_seen_subcommand_from choose save show' -a '(fish_config prompt list)'
complete fish_config -n '__fish_use_subcommand' -a browse -d 'Open the web-based UI'
complete fish_config -n '__fish_use_subcommand' -a theme -d 'View and pick from the sample themes'
complete fish_config -n '__fish_seen_subcommand_from theme; and __fish_seen_subcommand_from choose save show' -a '(fish_config theme list)'
complete fish_config -n "__fish_seen_subcommand_from theme; and not __fish_seen_subcommand_from $theme_commands" \
-a choose -d 'View and pick from the sample themes'
complete fish_config -n "__fish_seen_subcommand_from theme; and not __fish_seen_subcommand_from $theme_commands" \
-a show -d 'Show what theme would look like'
complete fish_config -n "__fish_seen_subcommand_from theme; and not __fish_seen_subcommand_from $theme_commands" \
-a list -d 'List all available themes'
complete fish_config -n "__fish_seen_subcommand_from theme; and not __fish_seen_subcommand_from $theme_commands" \
-a save -d 'Save the given theme as universal variables'
complete fish_config -n "__fish_seen_subcommand_from theme; and not __fish_seen_subcommand_from $theme_commands" \
-a demo -d 'Show example in the current theme'
complete fish_config -n "__fish_seen_subcommand_from theme; and not __fish_seen_subcommand_from $theme_commands" \
-a dump -d 'Print the current theme in .theme format'

View file

@ -32,99 +32,224 @@ function fish_config --description "Launch fish's web based configuration"
return 0
end
if not contains -- $cmd prompt
if not contains -- $cmd prompt theme
echo No such subcommand: $cmd >&2
return 1
end
# prompt - for prompt switching
set -l cmd $argv[1]
set -e argv[1]
if contains -- $cmd list; and set -q argv[1]
echo "Too many arguments" >&2
return 1
end
set -l prompt_dir $__fish_data_dir/sample_prompts $__fish_data_dir/tools/web_config/sample_prompts
switch $cmd
case show
set -l fish (status fish-path)
set -l prompts $prompt_dir/$argv.fish
set -q prompts[1]; or set prompts $prompt_dir/*.fish
for p in $prompts
if not test -e "$p"
continue
end
set -l promptname (string replace -r '.*/([^/]*).fish$' '$1' $p)
echo -s (set_color --underline) $promptname (set_color normal)
$fish -c "functions -e fish_right_prompt; source $p;
false
fish_prompt
echo (set_color normal)
if functions -q fish_right_prompt;
echo right prompt: (false; fish_right_prompt)
end"
echo
end
case list ''
string replace -r '.*/([^/]*).fish$' '$1' $prompt_dir/*.fish
return
case choose
if set -q argv[2]
case prompt
# prompt - for prompt switching
set -l cmd $argv[1]
set -e argv[1]
if contains -- $cmd list; and set -q argv[1]
echo "Too many arguments" >&2
return 1
end
if not set -q argv[1]
echo "Too few arguments" >&2
return 1
end
set -l have 0
for f in $prompt_dir/$argv[1].fish
if test -f $f
source $f
set have 1
break
end
end
if test $have -eq 0
echo "No such prompt: '$argv[1]'" >&2
return 1
end
case save
read -P"Overwrite prompt? [y/N]" -l yesno
if string match -riq 'y(es)?' -- $yesno
echo Overwriting
cp $__fish_config_dir/functions/fish_prompt.fish{,.bak}
set -l prompt_dir $__fish_data_dir/sample_prompts $__fish_data_dir/tools/web_config/sample_prompts
switch $cmd
case show
set -l fish (status fish-path)
set -l prompts $prompt_dir/$argv.fish
set -q prompts[1]; or set prompts $prompt_dir/*.fish
for p in $prompts
if not test -e "$p"
continue
end
set -l promptname (string replace -r '.*/([^/]*).fish$' '$1' $p)
echo -s (set_color --underline) $promptname (set_color normal)
$fish -c "functions -e fish_right_prompt; source $p;
false
fish_prompt
echo (set_color normal)
if functions -q fish_right_prompt;
echo right prompt: (false; fish_right_prompt)
end"
echo
end
case list ''
string replace -r '.*/([^/]*).fish$' '$1' $prompt_dir/*.fish
return
case choose
if set -q argv[2]
echo "Too many arguments" >&2
return 1
end
if not set -q argv[1]
echo "Too few arguments" >&2
return 1
end
if set -q argv[1]
set -l have 0
for f in $prompt_dir/$argv[1].fish
if test -f $f
set have 1
source $f
or return 2
set have 1
break
end
end
if test $have -eq 0
echo "No such prompt: '$argv[1]'" >&2
return 1
end
end
case save
read -P"Overwrite prompt? [y/N]" -l yesno
if string match -riq 'y(es)?' -- $yesno
echo Overwriting
cp $__fish_config_dir/functions/fish_prompt.fish{,.bak}
funcsave fish_prompt
or return
if set -q argv[1]
set -l have 0
for f in $prompt_dir/$argv[1].fish
if test -f $f
set have 1
source $f
or return 2
end
end
if test $have -eq 0
echo "No such prompt: '$argv[1]'" >&2
return 1
end
end
functions -q fish_right_prompt
and funcsave fish_right_prompt
funcsave fish_prompt
or return
return
else
echo Not overwriting
functions -q fish_right_prompt
and funcsave fish_right_prompt
return
else
echo Not overwriting
return 1
end
end
return 0
case theme
# Selecting themes
set -l cmd $argv[1]
set -e argv[1]
if contains -- $cmd list; and set -q argv[1]
echo "Too many arguments" >&2
return 1
end
end
return 0
set -l dir $__fish_config_dir/themes $__fish_data_dir/tools/web_config/themes
switch $cmd
case list ''
string replace -r '.*/([^/]*).theme$' '$1' $dir/*.theme
return
case demo
echo -ns (set_color $fish_color_command) /bright/vixens
echo -ns (set_color normal) ' '
echo -ns (set_color $fish_color_param) jump
echo -ns (set_color normal) ' '
echo -ns (set_color $fish_color_redirection) '|'
echo -ns (set_color normal) ' '
echo -ns (set_color $fish_color_quote) '"fowl"'
echo -ns (set_color normal) ' '
echo -ns (set_color $fish_color_redirection) '> quack'
echo -ns (set_color normal) ' '
echo -ns (set_color $fish_color_end) '&'
set_color normal
echo -s (set_color $fish_color_comment) ' # This is a comment'
set_color normal
echo -ns (set_color $fish_color_command) echo
echo -ns (set_color normal) ' '
echo -s (set_color $fish_color_error) "'Errors are the portal to discovery"
set_color normal
echo -ns (set_color $fish_color_command) Th
set_color normal
set_color $fish_color_autosuggestion
echo is is an autosuggestion
echo
case show
set -l fish (status fish-path)
set -l themes $dir/$argv.theme
set -q themes[1]; or set themes $dir/*.theme
set -l used_themes
echo -s (set_color normal; set_color --underline) Current (set_color normal)
fish_config theme demo
for t in $themes
not test -e "$t"
and continue
set -l themename (string replace -r '.*/([^/]*).theme$' '$1' $t)
contains -- $themename $used_themes
and continue
set -a used_themes $themename
echo -s (set_color normal; set_color --underline) $themename (set_color normal)
# Use a new, --no-config, fish to display the theme.
# So we can use this function, explicitly source it before anything else!
functions fish_config | $fish -C "source -" --no-config -c "
fish_config theme choose '$themename'
fish_config theme demo '$themename'
"
end
case choose save
set -l files $dir/$argv[1].theme
set -l file
set -l scope -g
if contains -- $cmd save
read -P"Overwrite theme? [y/N]" -l yesno
if not string match -riq 'y(es)?' -- $yesno
echo Not overwriting >&2
return 1
end
set scope -U
end
for f in $files
if test -e "$f"
set file $f
break
end
end
if not set -q file[1]
echo "No such theme: $argv[1]" >&2
echo "Dirs: $dir" >&2
return 1
end
set -l have_color 0
while read -lat toks
# We only allow color variables.
# Not the specific list, but something named *like* a color variable.
#
# This also takes care of empty lines and comment lines.
string match -rq '^fish_(?:pager_)?color.*$' -- $toks[1]
or continue
# Note: This can warn about global variables shadowing the universal
# versions we create.
# We want that warning to go through, because we *can't*
# permanently remove the globals.
set $scope $toks
set have_color 1
end < $file
# Return true if we changed at least one color
test $have_color -eq 1
return
case dump
# Write the current theme in .theme format, to stdout.
set -L | string match -r '^fish_(?:pager_)?color.*$'
case '*'
echo "No such command: $cmd" >&2
return 1
end
end
end