Why: Every opinionated piece of this config (command shadows, startup side-effects, key/env overrides, terminal coupling) was previously mandatory. Task #3 makes the whole config usable as a "plain shell" by anyone — or selectively trimmed — without forking it.
What: All 56 cataloged components are now wrapped in guards routed through a new helper, functions/__fish_config_op_enabled.fish, which evaluates the master switch __fish_config_opinionated first, then the per-category opt-out variable — both via __fish_variable_check (falsy = 0/false/no/off/n disables; truthy, unset, or unrecognized keeps enabled).
Variable
Category
__fish_config_op_aliases
C1 — command shadows / flag injection
__fish_config_op_autoexec
C2 — startup side-effects
__fish_config_op_overrides
C3 — key bindings, env, prompt
__fish_config_op_integrations
C4 — terminal/tool coupling
__fish_config_opinionated
Master — all four at once
Key implementation points:
Guard placement: conf.d components gate at source time (new shells); autoloaded command shadows gate inside the function body (live toggle, no restart).
rm fallback: with C1 disabled, rm runs exact command rm $argv — no wrapper, no trash.
Bang-bang atomicity: tricks.fish bindings, abbr.fish abbreviations, puffer.fish intercepts, and all six expand_* functions gate together under C3.
Auto-exec safety: first_run.fish still sets __fish_config_first_run_complete when C2 is off, but skips the Fisher curl, fisher update, and theme apply; paru/yay wrappers return before any file writes.
CachyOS cleanup: the distro config ships its own copies of the bang-bang system, history override, and grep/ls/wget aliases (it's the origin of tricks.fish); config.fish now strips those per category and restores fish's stock history/ls functions.
Task #4 coordination:smart_exit falls back to builtin exit when C3 is off; comments mark where __fish_config_enable_logging will gate just the capture block.
Docs: new "Opinionated Components (Minimal Mode)" section in docs/fish-config.md (+ index keywords opinionated, minimal, opt-out, toggles), README "Minimal Mode" section, and a cross-reference from Section 1.
Manual Verification
set -U __fish_config_opinionated 0, open a new shell: prompt is stock fish (no starship), Emacs bindings, !/$ insert literally, :w/:t abbreviations don't expand, and rm prints rm: missing operand instead of listing trash.
Still in minimal mode: cat somefile outputs plain (no bat), ls is plain listing, cd does not learn directories for zoxide (z still works directly).
set -Ue __fish_config_opinionated, open a new shell: starship prompt, Vi mode, bang-bang, theme colors, and all wrappers return; FZF_DEFAULT_OPTS is restored automatically.
set -U __fish_config_op_integrations off, then run tab, split, or logs: each refuses with a red error naming the variable; erase the variable and they work again immediately.
set -U __fish_config_op_aliases off in a running shell (no restart): rm, cat, ls, ping immediately fall back to bare commands while bang-bang and the prompt stay active.
help config opinionated jumps straight to the new docs section.
## Summary
**Why:** Every opinionated piece of this config (command shadows, startup side-effects, key/env overrides, terminal coupling) was previously mandatory. Task #3 makes the whole config usable as a "plain shell" by anyone — or selectively trimmed — without forking it.
**What:** All 56 cataloged components are now wrapped in guards routed through a new helper, `functions/__fish_config_op_enabled.fish`, which evaluates the master switch `__fish_config_opinionated` first, then the per-category opt-out variable — both via `__fish_variable_check` (falsy = `0/false/no/off/n` disables; truthy, unset, or unrecognized keeps enabled).
| Variable | Category |
|---|---|
| `__fish_config_op_aliases` | C1 — command shadows / flag injection |
| `__fish_config_op_autoexec` | C2 — startup side-effects |
| `__fish_config_op_overrides` | C3 — key bindings, env, prompt |
| `__fish_config_op_integrations` | C4 — terminal/tool coupling |
| `__fish_config_opinionated` | Master — all four at once |
Key implementation points:
- **Guard placement:** conf.d components gate at source time (new shells); autoloaded command shadows gate inside the function body (live toggle, no restart).
- **`rm` fallback:** with C1 disabled, `rm` runs exact `command rm $argv` — no wrapper, no trash.
- **Bang-bang atomicity:** tricks.fish bindings, abbr.fish abbreviations, puffer.fish intercepts, and all six `expand_*` functions gate together under C3.
- **Auto-exec safety:** first_run.fish still sets `__fish_config_first_run_complete` when C2 is off, but skips the Fisher curl, `fisher update`, and theme apply; paru/yay wrappers return before any file writes.
- **CachyOS cleanup:** the distro config ships its own copies of the bang-bang system, `history` override, and grep/ls/wget aliases (it's the origin of tricks.fish); config.fish now strips those per category and restores fish's stock `history`/`ls` functions.
- **Task #4 coordination:** `smart_exit` falls back to `builtin exit` when C3 is off; comments mark where `__fish_config_enable_logging` will gate just the capture block.
Docs: new "Opinionated Components (Minimal Mode)" section in `docs/fish-config.md` (+ index keywords `opinionated`, `minimal`, `opt-out`, `toggles`), README "Minimal Mode" section, and a cross-reference from Section 1.
## Manual Verification
- [x] `set -U __fish_config_opinionated 0`, open a new shell: prompt is stock fish (no starship), Emacs bindings, `!`/`$` insert literally, `:w`/`:t` abbreviations don't expand, and `rm` prints `rm: missing operand` instead of listing trash.
- [x] Still in minimal mode: `cat somefile` outputs plain (no bat), `ls` is plain listing, `cd` does not learn directories for zoxide (`z` still works directly).
- [x] `set -Ue __fish_config_opinionated`, open a new shell: starship prompt, Vi mode, bang-bang, theme colors, and all wrappers return; `FZF_DEFAULT_OPTS` is restored automatically.
- [x] `set -U __fish_config_op_integrations off`, then run `tab`, `split`, or `logs`: each refuses with a red error naming the variable; erase the variable and they work again immediately.
- [x] `set -U __fish_config_op_aliases off` in a running shell (no restart): `rm`, `cat`, `ls`, `ping` immediately fall back to bare commands while bang-bang and the prompt stay active.
- [x] `help config opinionated` jumps straight to the new docs section.
C1 shadows (rm, cat, ls, less, du, bash, top, ping, ssh, rg, mkdir,
help) fall back to the bare command when __fish_config_op_aliases is
falsy; rm falls back to exact 'command rm' with no wrapper. C2 gates
the auto-venv PWD hook. C3 gates smart_exit (composing with Task #4
logging), fish_right_prompt, and all six expand_bang_*/expand_typo_sub
functions atomically with the bang-bang system. C4 integration commands
(spwin, tab, split, hist, logs, upgrade) refuse with a colored stderr
error when disabled. config.fish now also strips the CachyOS distro
config's own bang-bang bindings, history override, and alias opinions
per category, restoring fish stock functions where they exist.
Adds 'Opinionated Components (Minimal Mode)' to docs/fish-config.md
with index keywords (opinionated, minimal, minimal-mode, opt-out,
toggles) and a Minimal Mode section with toggle table to README.md.
AGENTS.md Task #3 checklist ticked locally (file is git-ignored).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Why: Every opinionated piece of this config (command shadows, startup side-effects, key/env overrides, terminal coupling) was previously mandatory. Task #3 makes the whole config usable as a "plain shell" by anyone — or selectively trimmed — without forking it.
What: All 56 cataloged components are now wrapped in guards routed through a new helper,
functions/__fish_config_op_enabled.fish, which evaluates the master switch__fish_config_opinionatedfirst, then the per-category opt-out variable — both via__fish_variable_check(falsy =0/false/no/off/ndisables; truthy, unset, or unrecognized keeps enabled).__fish_config_op_aliases__fish_config_op_autoexec__fish_config_op_overrides__fish_config_op_integrations__fish_config_opinionatedKey implementation points:
rmfallback: with C1 disabled,rmruns exactcommand rm $argv— no wrapper, no trash.expand_*functions gate together under C3.__fish_config_first_run_completewhen C2 is off, but skips the Fisher curl,fisher update, and theme apply; paru/yay wrappers return before any file writes.historyoverride, and grep/ls/wget aliases (it's the origin of tricks.fish); config.fish now strips those per category and restores fish's stockhistory/lsfunctions.smart_exitfalls back tobuiltin exitwhen C3 is off; comments mark where__fish_config_enable_loggingwill gate just the capture block.Docs: new "Opinionated Components (Minimal Mode)" section in
docs/fish-config.md(+ index keywordsopinionated,minimal,opt-out,toggles), README "Minimal Mode" section, and a cross-reference from Section 1.Manual Verification
set -U __fish_config_opinionated 0, open a new shell: prompt is stock fish (no starship), Emacs bindings,!/$insert literally,:w/:tabbreviations don't expand, andrmprintsrm: missing operandinstead of listing trash.cat somefileoutputs plain (no bat),lsis plain listing,cddoes not learn directories for zoxide (zstill works directly).set -Ue __fish_config_opinionated, open a new shell: starship prompt, Vi mode, bang-bang, theme colors, and all wrappers return;FZF_DEFAULT_OPTSis restored automatically.set -U __fish_config_op_integrations off, then runtab,split, orlogs: each refuses with a red error naming the variable; erase the variable and they work again immediately.set -U __fish_config_op_aliases offin a running shell (no restart):rm,cat,ls,pingimmediately fall back to bare commands while bang-bang and the prompt stay active.help config opinionatedjumps straight to the new docs section.