obsidian/wiki/concepts/fish-abbr-patterns.md
2026-04-18 22:04:01 +01:00

102 lines
4 KiB
Markdown

---
title: "Fish Shell — abbr vs alias Patterns"
aliases: [fish-abbreviations, fish-abbr, fish-alias-vs-abbr]
tags: [fish, shell, dotfiles, terminal, abbr, alias]
sources:
- "daily/2026-04-17.md"
created: 2026-04-17
updated: 2026-04-17
---
# Fish Shell — abbr vs alias Patterns
Fish shell offers two ways to create command shortcuts: `abbr` (abbreviations) and `alias`. The choice between them affects transparency and interaction with third-party Fish plugins like forgit. Using `abbr` for expanded commands and `alias` for invisible substitutions is the idiomatic Fish pattern.
## Key Points
- **`abbr`** expands in the command line before execution — the user sees the full command in the prompt history, making actions transparent and auditable
- **`alias`** runs as a hidden substitution — the original alias name appears in history, not the underlying command
- Use `abbr` for git/docker/uv shortcuts where seeing the expanded command is useful; use `alias` for transparent replacements like `ls→lsd`, `cat→bat`
- Fish abbreviations can conflict with forgit plugin functions — forgit defines `gco`, `grb`, `glo`, etc. as interactive functions; naming an abbreviation the same will shadow the forgit function
- Resolve forgit conflicts by renaming your abbreviation (e.g., `gco``gch` for `git checkout`)
## Details
### abbr vs alias Decision Table
| Use case | Use | Why |
|----------|-----|-----|
| `git checkout``gch` | `abbr` | Expands visibly — you see `git checkout` in prompt |
| `docker compose``dc` | `abbr` | Expands — clear what's running |
| `ls``lsd` | `alias` | Should be invisible — `ls` stays in history |
| `cat``bat` | `alias` | Transparent replacement — looks like `cat` |
| `forgit` interactive commands | none | Provided by forgit plugin — don't shadow |
### Defining Abbreviations
```fish
# In ~/.config/fish/config.fish or ~/.config/fish/abbreviations.fish
# Git shortcuts (expand visibly)
abbr --add gst 'git status'
abbr --add gch 'git checkout' # not gco — conflicts with forgit
abbr --add gpl 'git pull'
abbr --add gps 'git push'
abbr --add glo 'git log --oneline' # renamed — forgit uses glo too
# Docker
abbr --add dc 'docker compose'
abbr --add dcu 'docker compose up -d'
abbr --add dcd 'docker compose down'
# uv (Python package manager)
abbr --add uvr 'uv run'
abbr --add uvs 'uv sync'
```
### Defining Aliases (Transparent Replacements)
```fish
# In ~/.config/fish/config.fish
# These should feel like the original command
alias ls='lsd'
alias cat='bat --paging=never'
alias grep='rg'
alias find='fd'
```
### Forgit Conflict Resolution
forgit (interactive git fzf plugin) defines these functions by default:
| forgit function | What it does |
|----------------|--------------|
| `gco` | Interactive `git checkout` |
| `grb` | Interactive `git rebase` |
| `glo` | Interactive `git log` |
| `gbl` | Interactive `git blame` |
| `gd` | Interactive `git diff` |
If you have abbreviations with the same names, the abbreviation wins on expansion but the forgit function is still reachable by full name. The practical fix: rename your abbreviation to avoid the conflict (`gco``gch`, `glo``glg`).
### Viewing All Current Abbreviations
```fish
abbr # list all abbreviations
alias # list all aliases
functions # list all functions (includes forgit)
```
### Persistence
Both `abbr` and `alias` defined in `config.fish` persist across sessions. `abbr --add` called interactively creates a universal variable that also persists — but storing abbreviations in `config.fish` is more portable for dotfiles repos.
## Related Concepts
- [[wiki/concepts/fish-shell-path-config]] — Fish PATH configuration and SSH aliases as Fish functions
- [[wiki/dotfiles/_index]] — full dotfiles topic: Kitty, Fish, WezTerm, LazyVim, Rust CLI tools
## Sources
- [[daily/2026-04-17.md]] — Fish abbreviations setup session; `abbr` chosen over `alias` for git/docker/uv commands; `gco/grb/glo` conflicts with forgit resolved by renaming abbreviations; transparent replacements (`ls→lsd`, `cat→bat`) kept as `alias`