Loading...
Loading...
Fish shell configuration: config.fish, functions, abbreviations, variable scoping, conf.d modules, and PATH management. Use when user's $SHELL is fish, editing .fish files, working in ~/.config/fish/, or migrating from Bash. Use for "fish config", "fish function", "abbr", "conf.d", "fish_add_path", or "funcsave". Do NOT use for Bash/Zsh-only scripts, POSIX shell portability, or non-shell configuration tasks.
npx skill4agent add notque/claude-code-toolkit fish-shell-configVAR=value[[ ]]export$var"$var"testtest[[ ]][ ]setset VAR valueVAR=valuefunctions/foo.fishfunction fooconf.d/config.fishfish_add_pathset PATHif status is-interactivetype -q00-10-20-conf.d/-Ureferences/bash-migration.md~/.config/fish/$SHELLfish.fish~/.config/fish/$()&&||~/.config/fish/
├── config.fish # Minimal — interactive-only init
├── fish_variables # Auto-managed by Fish (never edit)
├── conf.d/ # Auto-sourced in alphabetical order
│ ├── 00-path.fish
│ ├── 10-env.fish
│ └── 20-abbreviations.fish
├── functions/ # Autoloaded functions (one per file)
│ ├── fish_prompt.fish
│ └── mkcd.fish
└── completions/ # Custom completions
└── mycommand.fish| What you're writing | Where it goes |
|---|---|
| PATH additions | |
| Environment variables | |
| Abbreviations | |
| Tool integrations | |
| Named function | |
| Custom prompt | |
| Completions | |
| One-time interactive init | |
set -l VAR value # Local — current block only
set -f VAR value # Function — entire function scope
set -g VAR value # Global — current session
set -U VAR value # Universal — persists across sessions
set -x VAR value # Export — visible to child processes
set -gx VAR value # Global + Export (typical for env vars)
set -e VAR # Erase variable
set -q VAR # Test if set (silent, for conditionals)# CORRECT: fish_add_path handles deduplication and persistence
fish_add_path ~/.local/bin
fish_add_path ~/.cargo/bin
fish_add_path -P ~/go/bin # -P = session only, no persist
# CORRECT: Direct manipulation when needed (session only)
set -gx PATH ~/custom/bin $PATH
# WRONG: Colon-separated string — Fish PATH is a list
# set PATH "$PATH:/new/path"# ~/.config/fish/functions/mkcd.fish
function mkcd --description "Create directory and cd into it"
mkdir -p $argv[1]
and cd $argv[1]
endfunction backup --description "Create timestamped backup"
argparse 'd/dest=' 'h/help' -- $argv
or return
if set -q _flag_help
echo "Usage: backup [-d destination] file..."
return 0
end
set -l dest (set -q _flag_dest; and echo $_flag_dest; or echo ".")
for file in $argv
set -l ts (date +%Y%m%d_%H%M%S)
cp $file $dest/(basename $file).$ts.bak
end
end| Use Case | Mechanism | Why |
|---|---|---|
| Simple shortcut | | Expands in-place, visible in history |
| Needs arguments/logic | | Full programming, works in scripts |
| Wrapping a command | | Convenience; creates function internally |
# Always guard abbreviations
if status is-interactive
abbr -a g git
abbr -a ga "git add"
abbr -a gc "git commit"
abbr -a gst "git status"
abbr -a dc "docker compose"
end# Conditionals — use 'test', not [[ ]]
if test -f config.json
echo "exists"
else if test -d config
echo "is directory"
end
# Command chaining (both styles work in Fish 3.0+)
mkdir build && cd build && cmake ..
mkdir build; and cd build; and cmake ..
# Loops
for file in *.fish
echo "Processing $file"
end
# Switch
switch $argv[1]
case start
echo "Starting..."
case stop
echo "Stopping..."
case "*"
echo "Unknown: $argv[1]"
return 1
endtype -q# ~/.config/fish/conf.d/30-tools.fish
if type -q starship
starship init fish | source
end
if type -q direnv
direnv hook fish | source
end
if type -q fzf
fzf --fish | source
end
# Homebrew (macOS)
if test -x /opt/homebrew/bin/brew
eval (/opt/homebrew/bin/brew shellenv)
end
# Nix
if test -e /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish
source /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish
endfish -n <file>status is-interactivefish --no-configsource <file>~/.config/fish/conf.d/00-path.fishconf.d/10-env.fishconf.d/20-abbreviations.fish.bash_aliasesconf.d/functions/functions/foo.fishfunction fooset -gx PATHfish_add_pathfish_user_pathsfish_add_path /new/pathset -U fish_user_paths /path $fish_user_pathsabbrfunctions/-xsetset -gx VAR valueset --show VARVAR=valueexport VAR=value.fishset VAR valueset -gx VAR valueset PATH "$PATH:/new/path"fish_add_path /new/pathset PATH $PATH /new/pathconfig.fishconf.d/functions/if [[ -f file ]]if [ -f file ][[ ]][ ]/bin/[if test -f file"$var"$var"$var"| Rationalization | Why It's Wrong | Required Action |
|---|---|---|
| "Quotes won't hurt in Fish" | Masks misunderstanding of Fish semantics | Learn Fish variable expansion rules |
| "Just put it all in config.fish" | Monolithic config is an anti-pattern | Use conf.d/ and functions/ |
| "Bash syntax is close enough" | Fish is not POSIX; Bash-isms cause errors | Use Fish-native syntax only |
| "I'll use [ ] since it works" | Calls external binary, slower than test | Use |
${CLAUDE_SKILL_DIR}/references/bash-migration.md${CLAUDE_SKILL_DIR}/references/fish-quick-reference.md