Merge pull request 'refactor(functions): consolidate 198 duplicate color declarations into one helper' (#131) from refactor/shared-color-palette into main
CI / github-mirror (push) Skipped
CI / test (push) Successful in 1m59s
CI / build-docs (push) Failing after 1m14s

This commit was merged in pull request #131.
This commit is contained in:
2026-09-08 05:44:16 +00:00
41 changed files with 386 additions and 242 deletions
+1 -7
View File
@@ -38,13 +38,7 @@ function __config_settings_draw
set -l cur_scope $argv[2]
set -l vars $argv[3..]
set -l c_ok (set_color green)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_sel (set_color --bold magenta)
set -l c_hi (set_color --bold white)
set -l c_head (set_color --bold cyan)
set -l c_reset (set_color normal)
__fish_palette
set -l labels Aliases Auto-exec Overrides Integrations Logging Greeting Master
+1 -6
View File
@@ -41,12 +41,7 @@ function __config_settings_draw_subcat
set -l cur_scope $argv[2]
set -l category_var $argv[3]
set -l c_ok (set_color green)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_sel (set_color --bold magenta)
set -l c_head (set_color --bold cyan)
set -l c_reset (set_color normal)
__fish_palette
set -l rows (__config_settings_subcats $category_var)
set -l n (count $rows)
+1 -6
View File
@@ -33,12 +33,7 @@ function __config_settings_draw_value
set -l edit_mode $argv[3]
set -l edit_buf $argv[4]
set -l c_ok (set_color green)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_sel (set_color --bold magenta)
set -l c_head (set_color --bold cyan)
set -l c_reset (set_color normal)
__fish_palette
# ── Page row metadata (parallel lists) ────────────────────────────────
set -l title
+1 -2
View File
@@ -27,8 +27,7 @@ function __config_settings_pagetab
set -l active $argv[1]
set -l iw $argv[2]
set -l c_hi (set_color --bold white)
set -l c_reset (set_color normal)
__fish_palette
set -l names Universal Session Sponge Paths
set -l strip ' '
+63
View File
@@ -0,0 +1,63 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# __fish_palette
#
# DESCRIPTION
# Defines the shared terminal-output colour roles used by the
# user-facing functions in this configuration. Declared
# --no-scope-shadowing and using a bare `set`, so the variables are
# created in the CALLER's scope -- a consumer just calls it and then
# interpolates $c_head, $c_err and friends exactly as it did when the
# declarations were inline.
#
# Call it where the local declarations used to sit, once per contiguous
# block that needs the palette. set_color runs at call time, so the
# values track $TERM exactly as inline declarations did. (Measured:
# set_color output is identical across every TERM tested except
# TERM=dumb, which yields empty strings, and is unaffected by whether
# stdout is a tty or a pipe.)
#
# A role is a semantic slot, not a colour. c_flag and c_warn are both
# yellow but stay separate, as do c_ok and c_accent (both green) --
# merging either pair would foreclose ever restyling one without the
# other. c_accent is the command name in logs and smart_exit, which
# style it green where the rest of the config styles it bold.
#
# ARGUMENTS
# none
#
# EXIT STATUS
# 0 always
#
# EXAMPLE
# function mytool
# __fish_palette
# echo "$c_head""Usage:$c_reset $c_cmd""mytool$c_reset"
# end
#
# NOTES
# Calling this at top level (outside any function) creates GLOBAL
# variables. Every consumer calls it from inside a function, where the
# variables stay function-local and do not leak.
#
# functions/fish_prompt.fish deliberately does NOT use this palette. Its
# c_* values are Catppuccin hex strings passed as ARGUMENTS to set_color
# (`set_color --bold $c_green`), not captured escape sequences -- colour
# inputs rather than rendered output, a different concern.
function __fish_palette --no-scope-shadowing --description 'Define the shared output colour palette in the caller scope'
set c_reset (set_color normal)
set c_head (set_color --bold cyan)
set c_cmd (set_color --bold)
set c_arg (set_color cyan)
set c_flag (set_color yellow)
set c_warn (set_color yellow)
set c_err (set_color red)
set c_ok (set_color green)
set c_accent (set_color green)
set c_dim (set_color brblack)
set c_sel (set_color --bold magenta)
set c_hi (set_color --bold white)
end
+1 -2
View File
@@ -31,8 +31,7 @@
# EXAMPLE
# _agents_init_ensure_gitignore /home/user/myproject "agents-init" "AGENTS/" "/AGENTS.md"
function _agents_init_ensure_gitignore
set -l c_ok (set_color green)
set -l c_reset (set_color normal)
__fish_palette
if test (count $argv) -lt 3
echo (set_color red)"_agents_init_ensure_gitignore: requires <root> <label> <pattern>..."(set_color normal) >&2
+1 -8
View File
@@ -85,14 +85,7 @@
# agents-init --plugins
# agents-init --quiet
function agents-init --description 'scaffold AGENTS/ sub-repo with agent spec files and plugin dirs'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
argparse h/help a/agents p/plugins v/verbose q/quiet s/silent -- $argv
or return 1
+1 -8
View File
@@ -186,14 +186,7 @@
# throwaway directory and leave a dangling symlink behind, which is
# strictly worse than having had no backup at all.
function agents-vault --description 'track curated agent memory in a host-scoped vault repo'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
argparse h/help link push restore status 'adopt=' 'remote=' \
v/verbose q/quiet s/silent -- $argv
+1 -8
View File
@@ -42,14 +42,7 @@
# auto-pull list
# auto-pull remove qmk_firmware
function auto-pull --description 'Manage the auto-pull repository registry'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
set -q __fish_config_dir; or set -l __fish_config_dir $XDG_CONFIG_HOME/fish
set -q __fish_user_dots_path; or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
+1 -4
View File
@@ -27,10 +27,7 @@ function bkg --description 'Execute bkg'
# Check if a command was provided as an argument.
if test -z "$argv[1]"
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_arg (set_color cyan)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""bkg$c_reset $c_arg""<command> [arguments...]$c_reset"
return 1
end
+1 -6
View File
@@ -69,12 +69,7 @@
# EXAMPLE
# config-settings
function config-settings --description 'Interactive TUI for managing fish config settings'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
# ── Argument parsing ──────────────────────────────────
for arg in $argv
+1 -8
View File
@@ -27,14 +27,7 @@
# config-update --dry-run
# config-update --force
function config-update --description 'Pull latest fish config from upstream'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
set -l REMOTE_URL https://git.rootiest.dev/rootiest/fish-config.git
set -l CONFIG_DIR ~/.config/fish
+1 -5
View File
@@ -25,11 +25,7 @@
# EXAMPLE
# detach rsync -a ./data remote:/backup/
function detach --description 'Execute detach'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_arg (set_color cyan)
set -l c_reset (set_color normal)
__fish_palette
set -l show_help 0
set -l args
+1 -5
View File
@@ -38,11 +38,7 @@ function dng2avif --description 'Convert DNG raw to 10-bit HDR AVIF'
# Help Screen
if set -q _flag_help; or test (count $argv) -eq 0 -a -z "$_flag_input"
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""dng2avif$c_reset $c_flag""[options]$c_reset $c_dim""[input.dng]$c_reset"
echo ""
echo "$c_head""Options:$c_reset"
+1 -5
View File
@@ -30,11 +30,7 @@ function dockup --description 'Pull and restart docker compose containers'
# Handle help flags
if contains -- -h $argv; or contains -- --help $argv
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""dockup$c_reset $c_dim""[DIRECTORY]$c_reset"
echo ""
echo "$c_head""Options:$c_reset"
+1 -6
View File
@@ -45,12 +45,7 @@
# edit --editor=code --clipboard
# edit --text="hello world"
function edit --description 'Open files in a terminal or GUI editor with fallbacks'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
# Opinionated guard (C1): fall back to the legacy bare-editor behavior.
if not __fish_config_op_enabled (status current-function)
+1 -5
View File
@@ -100,11 +100,7 @@ end
# EXAMPLE
# __fish_deps_help
function __fish_deps_help
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""fish-deps$c_reset — manage fish shell dependencies"
echo ""
+1 -2
View File
@@ -25,8 +25,7 @@ function hist --description 'Search fish history and put it in the prompt'
# Opinionated guard (C4): integrations disabled
if not __fish_config_op_enabled (status current-function)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_err"'hist: disabled by __fish_config_op_integrations'"$c_reset" >&2
return 1
end
+1 -8
View File
@@ -51,14 +51,7 @@
# redirections must be wrapped explicitly, e.g.
# jobrunner run sync fish -c 'a | b'.
function jobrunner --description 'Manage detached background jobs with tmux or GNU screen'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_arg (set_color cyan)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
set -l subcmds run list attach kill logs help \
-r --run -l --list -a --attach -k --kill -o --output -h --help
+1 -8
View File
@@ -38,14 +38,7 @@
# kitty-logging install
# kitty-logging status
function kitty-logging --description 'Install/manage the fish-config Kitty scrollback watcher'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
set -l cmd $argv[1]
+9 -13
View File
@@ -39,8 +39,7 @@
function logs --description 'Browse terminal log files interactively with fzf'
# Opinionated guard (C4): integrations disabled
if not __fish_config_op_enabled (status current-function)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_err"'logs: disabled by __fish_config_op_integrations'"$c_reset" >&2
return 1
end
@@ -50,24 +49,21 @@ function logs --description 'Browse terminal log files interactively with fzf'
or return 1
if set -q _flag_help
set -l c_accent (set_color green)
set -l c_primary (set_color cyan)
set -l c_bold (set_color --bold)
set -l c_reset (set_color normal)
echo "Usage: "$c_accent"logs"$c_reset" ["$c_primary"OPTIONS"$c_reset"]"
__fish_palette
echo "Usage: "$c_accent"logs"$c_reset" ["$c_arg"OPTIONS"$c_reset"]"
echo ""
echo "Browse and open terminal log files interactively."
echo "Logs sorted newest-first. Type to fuzzy-filter by date or category."
echo ""
echo "Options:"
echo " "$c_primary"-h, --help"$c_reset" Show this help"
echo " "$c_primary"-c, --category"$c_reset" Limit to one category: scrollback, paru, yay"
echo " "$c_arg"-h, --help"$c_reset" Show this help"
echo " "$c_arg"-c, --category"$c_reset" Limit to one category: scrollback, paru, yay"
echo ""
echo "Keys in fzf:"
echo " "$c_primary"Enter"$c_reset" Open in \$PAGER"
echo " "$c_primary"Ctrl-E"$c_reset" Open in \$EDITOR"
echo " "$c_primary"Ctrl-D"$c_reset" Delete selected log"
echo " "$c_primary"Ctrl-C"$c_reset" Quit"
echo " "$c_arg"Enter"$c_reset" Open in \$PAGER"
echo " "$c_arg"Ctrl-E"$c_reset" Open in \$EDITOR"
echo " "$c_arg"Ctrl-D"$c_reset" Delete selected log"
echo " "$c_arg"Ctrl-C"$c_reset" Quit"
return 0
end
+13 -21
View File
@@ -26,31 +26,23 @@
# mkcd ~/projects/myapp
# mkcd ~/projects/newapp/src
function mkcd --description 'Create a directory (with parents) and cd into it'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_arg (set_color cyan)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_rst (set_color normal)
__fish_palette
if contains -- -h $argv; or contains -- --help $argv; or test (count $argv) -eq 0
echo "$c_head""Usage:$c_rst $c_cmd""mkcd$c_rst $c_arg""<dir>$c_rst"
echo "$c_head""Usage:$c_reset $c_cmd""mkcd$c_reset $c_arg""<dir>$c_reset"
echo
echo " Create $c_arg""<dir>$c_rst (including missing parents) and cd into it."
echo " Create $c_arg""<dir>$c_reset (including missing parents) and cd into it."
echo
echo "$c_head""Arguments:$c_rst"
echo " $c_arg""<dir>$c_rst Directory to create and enter"
echo "$c_head""Arguments:$c_reset"
echo " $c_arg""<dir>$c_reset Directory to create and enter"
echo
echo "$c_head""Flags:$c_rst"
echo " $c_flag-h$c_rst, $c_flag--help$c_rst Show this help message"
echo " $c_flag-s$c_rst, $c_flag--silent$c_rst Suppress directory creation output"
echo "$c_head""Flags:$c_reset"
echo " $c_flag-h$c_reset, $c_flag--help$c_reset Show this help message"
echo " $c_flag-s$c_reset, $c_flag--silent$c_reset Suppress directory creation output"
echo
echo "$c_head""Examples:$c_rst"
echo " $c_cmd""mkcd$c_rst $c_arg~/projects/myapp$c_rst"
echo " $c_cmd""mkcd$c_rst $c_arg~/projects/myapp$c_rst""$c_dim""; git init$c_rst"
echo "$c_head""Examples:$c_reset"
echo " $c_cmd""mkcd$c_reset $c_arg~/projects/myapp$c_reset"
echo " $c_cmd""mkcd$c_reset $c_arg~/projects/myapp$c_reset""$c_dim""; git init$c_reset"
return 0
end
@@ -77,8 +69,8 @@ function mkcd --description 'Create a directory (with parents) and cd into it'
or return $status
if test $is_new -eq 1
echo "$c_ok""$c_rst Created and entered $c_arg$dir$c_rst"
echo "$c_ok""$c_reset Created and entered $c_arg$dir$c_reset"
else
echo "$c_warn""$c_rst $c_arg$dir$c_rst already exists — entered"
echo "$c_warn""$c_reset $c_arg$dir$c_reset already exists — entered"
end
end
+1 -5
View File
@@ -41,11 +41,7 @@
# NOTES
# Typo abbreviation: url-open (expands to open-url on space/enter).
function open-url --description 'Open a URL in the best available web browser'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_arg (set_color cyan)
set -l c_reset (set_color normal)
__fish_palette
argparse h/help s/silent v/verbose -- $argv
or return 1
+1 -5
View File
@@ -28,11 +28,7 @@
function p --description 'Put from clipboard'
# Check for help flag
if contains -- -h $argv; or contains -- --help $argv
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""p$c_reset $c_flag""[OPTIONS]$c_reset"
echo ""
echo " Pastes content from the system clipboard to stdout."
+1 -8
View File
@@ -46,14 +46,7 @@ function pkg --description 'Install or remove packages via the system package ma
end
# ── Colour palette ───────────────────────────────────────────
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_ok (set_color green)
set -l c_warn (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
# ── Installed-check helper ───────────────────────────────────
# Uses only its own arguments — safe to define as an inner function.
+1 -5
View File
@@ -36,11 +36,7 @@
# play-media
# play-media --player mpv
function play-media --description 'Pick audio/video files with fzf and play them'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
argparse h/help p/player= -- $argv
or return 1
+9 -14
View File
@@ -32,26 +32,21 @@
if type -q aichat
function qc --wraps aichat --description 'Quick-chat wrapper around aichat (cli role)'
if contains -- -h $argv; or contains -- --help $argv
set -l c_ttl (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_txt (set_color normal)
set -l c_dim (set_color brblack)
set -l c_rst (set_color normal)
__fish_palette
set -l w 59
set -l bar (string repeat -n $w)
# Title line, padded to the box width (plain form drives the math).
set -l title " qc — quick-chat: a thin aichat wrapper"
set -l pad (string repeat -n (math $w - (string length -- $title)) ' ')
echo "$c_dim$bar$c_rst"
echo "$c_dim$c_rst $c_ttl""qc$c_rst $c_dim$c_rst quick-chat: a thin $c_cmd""aichat$c_rst wrapper$pad$c_dim$c_rst"
echo "$c_dim$bar$c_rst"
echo " Defaults to the $c_flag'cli'$c_rst role — an AI system prompt tuned"
echo " for concise, $c_txt""terminal-friendly$c_rst output."
echo "$c_dim$bar$c_reset"
echo "$c_dim$c_reset $c_head""qc$c_reset $c_dim$c_reset quick-chat: a thin $c_cmd""aichat$c_reset wrapper$pad$c_dim$c_reset"
echo "$c_dim$bar$c_reset"
echo " Defaults to the $c_flag'cli'$c_reset role — an AI system prompt tuned"
echo " for concise, $c_reset""terminal-friendly$c_reset output."
echo
echo " Accepts every $c_cmd""aichat$c_rst flag; passing $c_flag--role$c_rst/$c_flag-r$c_rst overrides"
echo " the default role. $c_cmd""aichat$c_rst's own help follows:"
echo "$c_dim$bar$c_rst"
echo " Accepts every $c_cmd""aichat$c_reset flag; passing $c_flag--role$c_reset/$c_flag-r$c_reset overrides"
echo " the default role. $c_cmd""aichat$c_reset's own help follows:"
echo "$c_dim$bar$c_reset"
aichat --help | string replace -a aichat qc
return 0
end
+14 -18
View File
@@ -38,31 +38,27 @@
# Falls back to random choice if GNU shuf is missing, but shuf is
# much faster for files with >1000 lines.
function rand_string --description 'Generate random, memorable strings from curated word databases'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_arg (set_color cyan)
set -l c_flag (set_color yellow)
set -l c_rst (set_color normal)
__fish_palette
if set -q argv[1]; and contains -- $argv[1] -h --help
echo "$c_head""Usage:$c_rst $c_cmd""rand_string$c_rst $c_arg""[COMPONENTS/MODIFIERS]...$c_rst"
echo "$c_head""Usage:$c_reset $c_cmd""rand_string$c_reset $c_arg""[COMPONENTS/MODIFIERS]...$c_reset"
echo
echo " Generate random, memorable strings from curated word databases."
echo
echo "$c_head""Components:$c_rst"
echo " $c_arg<category>$c_rst A bundled word list (e.g. adjective, animal, color, name, noun, verb)"
echo " $c_arg""digits=<N>$c_rst N random digits (e.g. digits=3 -> 842)"
echo " $c_arg""literal=<text>$c_rst A static string component for prefixes/suffixes (e.g. literal=TEST)"
echo "$c_head""Components:$c_reset"
echo " $c_arg<category>$c_reset A bundled word list (e.g. adjective, animal, color, name, noun, verb)"
echo " $c_arg""digits=<N>$c_reset N random digits (e.g. digits=3 -> 842)"
echo " $c_arg""literal=<text>$c_reset A static string component for prefixes/suffixes (e.g. literal=TEST)"
echo
echo "$c_head""Modifiers:$c_rst"
echo " $c_flag-s$c_rst, $c_flag--separator=<sep>$c_rst Delimiter for subsequent words (dash, underscore, dot, none)"
echo " $c_flag-c$c_rst, $c_flag--case=<casing>$c_rst Casing for subsequent words (lower, upper, title)"
echo " $c_flag-h$c_rst, $c_flag--help$c_rst Show usage help"
echo "$c_head""Modifiers:$c_reset"
echo " $c_flag-s$c_reset, $c_flag--separator=<sep>$c_reset Delimiter for subsequent words (dash, underscore, dot, none)"
echo " $c_flag-c$c_reset, $c_flag--case=<casing>$c_reset Casing for subsequent words (lower, upper, title)"
echo " $c_flag-h$c_reset, $c_flag--help$c_reset Show usage help"
echo
echo "$c_head""Examples:$c_rst"
echo " $c_cmd""rand_string$c_rst adjective animal"
echo " $c_cmd""rand_string$c_rst --case=title color animal --separator=dot digits=4"
echo " $c_cmd""rand_string$c_rst literal=TEST --separator=underscore verb noun"
echo "$c_head""Examples:$c_reset"
echo " $c_cmd""rand_string$c_reset adjective animal"
echo " $c_cmd""rand_string$c_reset --case=title color animal --separator=dot digits=4"
echo " $c_cmd""rand_string$c_reset literal=TEST --separator=underscore verb noun"
return 0
end
+1 -5
View File
@@ -27,11 +27,7 @@ function replay --description 'Run Bash commands replaying changes in Fish'
case -v --version
echo "replay, version 1.2.1"
case "" -h --help
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_arg (set_color cyan)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""replay$c_reset $c_arg""<commands>$c_reset Run Bash commands replaying changes in Fish"
echo "$c_head""Options:$c_reset"
echo " $c_flag-v$c_reset or $c_flag--version$c_reset Print version"
+1 -4
View File
@@ -52,10 +52,7 @@
# NOTES
# Typo abbreviation: open-repo (expands to repo-open on space/enter).
function repo-open --description 'Open the origin remote of the current repo in a browser'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_reset (set_color normal)
__fish_palette
argparse -X 0 h/help p/print r/root -- $argv
or return 1
+1 -4
View File
@@ -63,10 +63,7 @@ function scrub --description 'Recursively purge OS, editor, and compiler garbage
# Helper function for help menu text
function _scrub_help
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""scrub$c_reset $c_flag""[options]$c_reset"
echo
+5 -9
View File
@@ -44,20 +44,16 @@ function smart_exit --description 'Capture colorized scrollback before exiting,
argparse $options -- $argv
or return 1
set -l c_primary (set_color cyan)
set -l c_accent (set_color green)
set -l c_warn (set_color yellow)
set -l c_bold (set_color --bold)
set -l c_reset (set_color normal)
__fish_palette
if set -q _flag_help
echo -e "Usage: $c_accent"exit"$c_reset [$c_primary""OPTIONS""$c_reset]"
echo -e "Usage: $c_accent"exit"$c_reset [$c_arg""OPTIONS""$c_reset]"
echo ""
echo "Closes the current shell session, automatically archiving the window scrollback."
echo ""
echo "Options:"
echo -e " $c_primary""-h, --help""$c_reset Show this help message"
echo -e " $c_primary""-n, --no-log""$c_reset Exit immediately $c_bold""without""$c_reset saving a scrollback history log"
echo -e " $c_arg""-h, --help""$c_reset Show this help message"
echo -e " $c_arg""-n, --no-log""$c_reset Exit immediately $c_cmd""without""$c_reset saving a scrollback history log"
return 0
end
@@ -112,7 +108,7 @@ function smart_exit --description 'Capture colorized scrollback before exiting,
end
end
else
echo -e "$c_warn""➔""$c_reset Exiting discreetly; $c_bold""no history logs saved.""$c_reset"
echo -e "$c_warn""➔""$c_reset Exiting discreetly; $c_cmd""no history logs saved.""$c_reset"
sleep 0.4
end
+1 -5
View File
@@ -29,11 +29,7 @@ function spark --description 'Sparklines'
if set --query _flag_version[1]
echo "spark, version 1.1.0"
else if set --query _flag_help[1]
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_flag (set_color yellow)
set -l c_arg (set_color cyan)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""spark$c_reset $c_arg""<numbers ...>$c_reset"
echo " stdin | $c_cmd""spark$c_reset"
echo "$c_head""Options:$c_reset"
+1 -2
View File
@@ -35,8 +35,7 @@ function split --description 'Run a command in a new terminal split'
# Opinionated guard (C4): integrations disabled
if not __fish_config_op_enabled (status current-function)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_err"'split: disabled by __fish_config_op_integrations'"$c_reset" >&2
return 1
end
+1 -2
View File
@@ -28,8 +28,7 @@ function spwin --wraps='~/.config/kitty/spawn-window.sh' --description 'spawn wi
# Opinionated guard (C4): integrations disabled
if not __fish_config_op_enabled (status current-function)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_err"'spwin: disabled by __fish_config_op_integrations'"$c_reset" >&2
return 1
end
+1 -2
View File
@@ -29,8 +29,7 @@ function tab --description 'Spawn a new tab in the current terminal'
# Opinionated guard (C4): integrations disabled
if not __fish_config_op_enabled (status current-function)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_err"'tab: disabled by __fish_config_op_integrations'"$c_reset" >&2
return 1
end
+1 -2
View File
@@ -25,8 +25,7 @@ function upgrade --description 'Full system upgrade via paru or yay'
# Opinionated guard (C4): integrations disabled
if not __fish_config_op_enabled (status current-function)
set -l c_err (set_color red)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_err"'upgrade: disabled by __fish_config_op_integrations'"$c_reset" >&2
return 1
end
+1 -4
View File
@@ -25,10 +25,7 @@ function wake-lock --description 'Run a command while inhibiting system sleep'
__fish_help_header (status current-function) $argv; and return 0
if test (count $argv) -eq 0
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_arg (set_color cyan)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""wake-lock$c_reset $c_arg""[command] [args...]$c_reset"
return 1
end
+1 -5
View File
@@ -25,11 +25,7 @@
function y --description 'Yank to clipboard'
# Check for help flag
if contains -- -h $argv; or contains -- --help $argv
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold)
set -l c_arg (set_color cyan)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
__fish_palette
echo "$c_head""Usage:$c_reset $c_cmd""y$c_reset $c_arg""[TEXT]$c_reset or $c_arg""[COMMAND]$c_reset | $c_cmd""y$c_reset"
echo ""
echo "$c_head""Examples:$c_reset"
+162
View File
@@ -0,0 +1,162 @@
#!/usr/bin/env fish
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# Byte-identity harness for the shared output palette (__fish_palette).
#
# Compares rendered output of every colour-bearing function between a
# pristine checkout of a baseline git ref and the current working tree.
# This is a one-time acceptance harness, not part of run-tests.fish's
# permanent suite -- the permanent check lives in tests/functional.fish.
#
# Usage:
# fish tests/palette-bytes.fish [--baseline REF] byte-diff stdout+stderr
# fish tests/palette-bytes.fish --structural diff-shape assertion
# fish tests/palette-bytes.fish --startup startup medians
#
# Both sandboxes get an isolated XDG_CONFIG_HOME carrying a copy of the
# working tree's fish_variables. That file is gitignored, so `git archive`
# omits it; without it __fish_config_op_enabled is unresolvable and every
# opinionated-guarded function silently short-circuits.
set -l repo (realpath (dirname (status filename))/..)
set -l mode bytes
set -l baseline main
for i in (seq (count $argv))
switch $argv[$i]
case --structural; set mode structural
case --startup; set mode startup
case --baseline; set baseline $argv[(math $i + 1)]
end
end
set -l tmp (mktemp -d)
function __pb_cleanup --on-event fish_exit --inherit-variable tmp
test -n "$tmp"; and rm -rf $tmp
end
# ── Build the two sandboxes ────────────────────────────────────────────
set -l A $tmp/base/fish # pristine baseline ref
set -l B $tmp/work/fish # current working tree
mkdir -p $A $B
git -C $repo archive $baseline | tar -x -C $A
or begin
echo "palette-bytes: cannot archive baseline ref '$baseline'" >&2
exit 2
end
for d in functions conf.d completions integrations themes data
test -d $repo/$d; and cp -r $repo/$d $B/
end
cp $repo/config.fish $B/ 2>/dev/null
# fish_variables is gitignored -- copy it into BOTH sandboxes by hand.
for d in $A $B
cp $repo/fish_variables $d/ 2>/dev/null
end
# qc --help shells out to aichat; stub it so its colour path is reachable.
set -l stub $tmp/stub
mkdir -p $stub
printf '#!/bin/sh\necho "aichat stub"\n' >$stub/aichat
chmod +x $stub/aichat
# ── The cases ──────────────────────────────────────────────────────────
# 25 --help paths (every converted function that has one) plus 4 error
# paths, two of which write to stderr. Side-effect-free by construction:
# --help returns before doing work, and each error path fails on argument
# validation. Do NOT add a case that mutates the filesystem.
set -l cases \
"agents-init --help" "agents-vault --help" "auto-pull --help" \
"config-settings --help" "config-update --help" "detach --help" \
"dng2avif --help" "dockup --help" "edit --help" "jobrunner --help" \
"kitty-logging --help" "logs --help" "mkcd --help" "open-url --help" \
"p --help" "pkg --help" "play-media --help" "qc --help" \
"rand_string --help" "replay --help" "repo-open --help" "scrub --help" \
"smart_exit --help" "spark --help" "y --help" \
"mkcd" "auto-pull remove __no_such_repo__" \
"agents-init --no-such-flag" "pkg __no_such_subcommand__"
function __pb_run --argument-names cfg stub cmd out
env XDG_CONFIG_HOME=(dirname $cfg) PATH="$stub:$PATH" TERM=xterm-256color \
HOME=$HOME fish -c "$cmd" >$out.out 2>$out.err
end
# ── Mode: bytes ────────────────────────────────────────────────────────
if test $mode = bytes
echo "== palette byte-identity vs $baseline =="
set -l failed 0
set -l n 0
for cmd in $cases
set n (math $n + 1)
__pb_run $A $stub "$cmd" $tmp/a$n
__pb_run $B $stub "$cmd" $tmp/b$n
set -l so ok
set -l se ok
cmp -s $tmp/a$n.out $tmp/b$n.out; or set so DIFF
cmp -s $tmp/a$n.err $tmp/b$n.err; or set se DIFF
if test $so = DIFF -o $se = DIFF
set failed (math $failed + 1)
printf ' FAIL %-34s stdout=%s stderr=%s\n' "$cmd" $so $se
test $so = DIFF; and diff -u (xxd $tmp/a$n.out | psub) (xxd $tmp/b$n.out | psub) | head -12
test $se = DIFF; and diff -u (xxd $tmp/a$n.err | psub) (xxd $tmp/b$n.err | psub) | head -12
else
printf ' ok %-34s (%s B out, %s B err)\n' "$cmd" (wc -c <$tmp/a$n.out | string trim) (wc -c <$tmp/a$n.err | string trim)
end
end
echo (math $n - $failed)"/$n cases byte-identical"
test $failed -eq 0
exit $status
end
# ── Mode: structural ───────────────────────────────────────────────────
# For files converted WITHOUT drift renames, the whole diff must be
# declaration removals plus inserted __fish_palette calls. If that holds,
# the file's output strings are provably untouched.
if test $mode = structural
echo "== structural diff shape vs $baseline =="
set -l bad 0
for f in (git -C $repo diff --name-only $baseline -- functions/)
# fish_prompt.fish keeps its own hex palette -- see Task 10.
string match -q '*fish_prompt.fish' $f; and continue
# __fish_palette.fish is the palette itself: a new file, so its diff
# is 100% additions and can never be "purely structural". Skipping it
# is not a loosening -- it declares the colours rather than rendering
# any, and tests/functional.fish asserts its 12 roles directly.
string match -q '*__fish_palette.fish' $f; and continue
set -l offenders
for line in (git -C $repo diff -U0 $baseline -- $f | string match -r '^[+-][^+-].*')
set -l body (string sub -s 2 -- $line)
string match -qr '^\s*set -l c_[a-z]+\s+\(set_color[^)]*\)\s*$' -- $body; and continue
string match -qr '^\s*__fish_palette\s*$' -- $body; and continue
set -a offenders $line
end
if test (count $offenders) -gt 0
set bad (math $bad + 1)
echo " NOT PURELY STRUCTURAL $f"
printf ' %s\n' $offenders[1..3]
end
end
if test $bad -eq 0
echo " all changed files are purely structural"
else
echo " $bad file(s) changed rendering text -- expected only for the drift-rename batch"
end
test $bad -eq 0
exit $status
end
# ── Mode: startup ──────────────────────────────────────────────────────
echo "== fish -c true, 31 interleaved pairs, median =="
set -l ta
set -l tb
for i in (seq 31)
set -l s (date +%s%N)
env XDG_CONFIG_HOME=$tmp/base fish -c true >/dev/null 2>&1
set -a ta (math "("(date +%s%N)" - $s) / 1000")
set s (date +%s%N)
env XDG_CONFIG_HOME=$tmp/work fish -c true >/dev/null 2>&1
set -a tb (math "("(date +%s%N)" - $s) / 1000")
end
set -l sa (printf '%s\n' $ta | sort -n)
set -l sb (printf '%s\n' $tb | sort -n)
printf ' baseline median=%.2f ms p10=%.2f p90=%.2f\n' (math $sa[16]/1000) (math $sa[4]/1000) (math $sa[28]/1000)
printf ' working median=%.2f ms p10=%.2f p90=%.2f\n' (math $sb[16]/1000) (math $sb[4]/1000) (math $sb[28]/1000)
echo " (p10-p90 spread is ~15 ms; treat any delta inside it as noise)"
+78
View File
@@ -85,3 +85,81 @@ check "conf.d guards stay out of non-interactive scripts" 0 $status
# Positive counterpart to the assertion above: the guard must not over-fire.
check "fish_user_key_bindings still defined in-session" true (functions -q fish_user_key_bindings; and echo true; or echo false)
section "session: shared output palette"
function test_palette_roles_defined
functions -q __fish_palette
or begin
echo " __fish_palette is not defined"
return 1
end
# Called from inside a function, the palette must land in THIS scope.
__fish_palette
set -l missing
for role in c_reset c_head c_cmd c_arg c_flag c_warn c_err c_ok \
c_accent c_dim c_sel c_hi
if not set -q $role; or test -z "$$role"
set -a missing $role
end
end
if test (count $missing) -gt 0
echo " palette roles empty or unset: $missing"
return 1
end
# Nothing may leak to global scope.
if set -q -g c_reset
echo " __fish_palette leaked c_reset into global scope"
return 1
end
return 0
end
check "palette roles all defined, non-empty, and scoped to the caller" true (test_palette_roles_defined; and echo true; or echo false)
# Every user-facing function that renders a coloured --help must still emit
# escape sequences.
#
# This is deliberately a RUNTIME check, never a static grep for
# __fish_palette. Measured on a deliberately broken functions/logs.fish --
# the palette call de-duplicated per indentation depth instead of per
# contiguous run, so the --help block lost its declarations without gaining
# a call:
#
# fish tests/palette-bytes.fish
# FAIL logs --help stdout=DIFF stderr=ok
# baseline 431 B -> broken 150 B (every escape stripped)
#
# fish -n functions/logs.fish -> exit 0 (lint PASSES)
# grep -c '__fish_palette' logs.fish -> 1 (grep PASSES)
#
# Both cheap checks are green on a file whose help output has lost all of
# its colour. Only running the function and looking for an \e byte catches
# it.
#
# functions/fish_prompt.fish is excluded BY NAME. It interpolates $c_dim
# from its own Catppuccin hex palette -- those are colour arguments passed
# to set_color, not captured escapes -- so it legitimately never calls
# __fish_palette and would otherwise look unconverted forever.
#
# qc is absent from the list on purpose: its --help shells out to aichat,
# which is not installed in CI, so its colour path is unreachable here.
# tests/palette-bytes.fish stubs aichat and does cover it.
function test_functions_keep_their_palette
set -l colored agents-init agents-vault auto-pull config-settings \
config-update detach dng2avif dockup edit jobrunner kitty-logging \
logs mkcd open-url p pkg play-media rand_string replay repo-open \
scrub smart_exit spark y
set -l uncolored
for fn in $colored
functions -q $fn; or continue
if not $fn --help 2>&1 | string match -qr \e
set -a uncolored $fn
end
end
if test (count $uncolored) -gt 0
echo " --help lost its colour: $uncolored"
return 1
end
return 0
end
check "colored --help output keeps its escape sequences" true (test_functions_keep_their_palette; and echo true; or echo false)