feat(config): introduce __fish_user_dots_path universal variable

Allow users to customize the location of their private overlay directory
via `set -U __fish_user_dots_path /your/path`. Falls back to the previous
hardcoded default of `$XDG_CONFIG_HOME/.user-dots/fish` when unset.

Simplify the sourcing model: config.fish now sources only local.fish,
which is responsible for sourcing its own secrets.fish companion. The
redundant direct sourcing of secrets.fish from config.fish is removed.

Update docs/fish-config.md (Sections 1, 7, 10) and README.md to
document the new variable, the custom-path override pattern, and the
simplified sourcing model.
This commit is contained in:
2026-06-23 03:21:02 -04:00
parent bdf4581b28
commit 2a5aef2a64
3 changed files with 55 additions and 49 deletions
+16 -12
View File
@@ -155,7 +155,7 @@ git clone https://git.rootiest.dev/rootiest/fish-config.git ~/.config/fish
Then open a new Fish shell — Fisher will be installed automatically on first launch and the Catppuccin Mocha theme will be applied. All plugin functionality is bundled directly with this config and requires no additional installation.
A [chezmoi](https://www.chezmoi.io/) dotfile manager is also configured — secrets are sourced from `~/.config/.user-dots/fish/secrets.fish` and excluded from version control.
A [chezmoi](https://www.chezmoi.io/) dotfile manager is also configured — secrets are kept in a private overlay directory (see [Personalization](#personalization)) and excluded from version control.
> [!IMPORTANT]
> `config.fish` ends with a `return` sentinel guard. Any lines appended **after** it by a tool's setup command will silently have no effect. Many tools (starship, zoxide, mise, etc.) offer a setup command that appends an `init | source` line to your `config.fish` — all integrations are managed through `conf.d/` files instead. If you add a new tool and its shell integration appears to do nothing, check whether its setup command appended an init line to the bottom of `config.fish` and create a `conf.d/<tool>.fish` file for it instead.
@@ -174,12 +174,18 @@ Pull the latest changes from upstream without needing a configured git remote:
## Personalization
Sensitive credentials and machine-specific paths are kept out of version control via a secondary private directory at `~/.config/.user-dots/fish/`. Two files are sourced automatically by `config.fish` if they exist:
Sensitive credentials and machine-specific paths are kept out of version control via a private overlay directory. The path defaults to `~/.config/.user-dots/fish/` but can be changed by setting a universal variable:
```fish
set -U __fish_user_dots_path /path/to/your/dots/fish
```
`config.fish` sources `local.fish` from that directory. `local.fish` is responsible for sourcing its own `secrets.fish` companion:
```
~/.config/.user-dots/fish/
$__fish_user_dots_path/
├── secrets.fish # API keys, tokens, passwords, personal identifiers
└── local.fish # Machine-specific paths and environment variables
└── local.fish # Machine-specific paths, env vars, and sourcing secrets
```
### secrets.fish
@@ -231,16 +237,14 @@ abbr -a dcw 'docker context use work-server'
### How it works
`config.fish` sources both files with an existence check so the public config works cleanly on any machine that doesn't have the private repo:
`config.fish` sources only `local.fish` with an existence check so the public config works cleanly on any machine without the private repo. `local.fish` is responsible for sourcing its own `secrets.fish`:
```fish
if test -f $HOME/.config/.user-dots/fish/secrets.fish
source $HOME/.config/.user-dots/fish/secrets.fish
end
if test -f $HOME/.config/.user-dots/fish/local.fish
source $HOME/.config/.user-dots/fish/local.fish
end
# config.fish resolves the path, then sources local.fish
set -q __fish_user_dots_path
or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
test -f "$__fish_user_dots_path/local.fish"
and source "$__fish_user_dots_path/local.fish"
```
`fish_variables` (which fish auto-manages and may contain universal variable state) is excluded from this repo via `.gitignore`.
+16 -26
View File
@@ -139,16 +139,16 @@ end
# Adds common user bin directories to the PATH. The -mg --move option for cargo ensures that
# the cargo bin directory is moved to the end of the PATH, which can help avoid conflicts
# with system-installed Rust tools while still allowing user-installed cargo binaries to be found.
fish_add_path $HOME/.local/bin # Standard user-local executables (XDG spec)
fish_add_path $HOME/.local/share/../bin # Alternative/legacy path for local user binaries
fish_add_path $HOME/Applications # User-installed applications and standalone apps
fish_add_path $HOME/scripts # Custom personal shell scripts and automation
fish_add_path -mga $CARGO_HOME/bin # Rust binaries and tools installed via Cargo
fish_add_path $BUN_INSTALL/bin # Bun runtime executables and globally installed packages
fish_add_path $XDG_DATA_HOME/npm-global/bin # Global Node.js/npm packages (XDG compliant location)
fish_add_path $HOME/.lmstudio/bin # LM Studio CLI tools for local LLM management
fish_add_path $HOME/.resend/bin # Resend email service CLI tools
fish_add_path $HOME/.fzf/bin # Fuzzy Finder (fzf) core binary and helper scripts
fish_add_path $HOME/.local/bin # Standard user-local executables (XDG spec)
fish_add_path $HOME/.local/share/../bin # Alternative/legacy path for local user binaries
fish_add_path $HOME/Applications # User-installed applications and standalone apps
fish_add_path $HOME/scripts # Custom personal shell scripts and automation
fish_add_path -mga $CARGO_HOME/bin # Rust binaries and tools installed via Cargo
fish_add_path $BUN_INSTALL/bin # Bun runtime executables and globally installed packages
fish_add_path $XDG_DATA_HOME/npm-global/bin # Global Node.js/npm packages (XDG compliant location)
fish_add_path $HOME/.lmstudio/bin # LM Studio CLI tools for local LLM management
fish_add_path $HOME/.resend/bin # Resend email service CLI tools
fish_add_path $HOME/.fzf/bin # Fuzzy Finder (fzf) core binary and helper scripts
# ───────────────────────── CDPATH projects dir ──────────────────────────
# Allows cd-ing to directories within $HOME/projects or $HOME without needing to specify the full path.
@@ -215,23 +215,13 @@ if status is-interactive
# │ This is useful for machine-specific behavior or configurations. │
# ╰────────────────────────────── OVERRIDES ─────────────────────────────╯
#
# Define user-dots path variable for a more legible secrets/local config.
set -l dot_fish "$XDG_CONFIG_HOME/.user-dots/fish"
# ───────────────────────── Source user secrets ──────────────────────────
# Sources a secrets.fish file if it exists, which can be used to store
# sensitive environment variables and configurations that shouldn't be
# committed to version control.
# This allows you to keep things like API keys, database credentials,
# and other secrets out of your main config files and safely ignored by git.
test -f "$dot_fish/secrets.fish"; and source "$dot_fish/secrets.fish"
# Resolve user-dots path. Customize via: set -U __fish_user_dots_path /your/path
set -q __fish_user_dots_path
or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
# ─────────────────────── Source machine-local config ────────────────────
# Sources a local.fish file if it exists, which can be used for machine-specific
# variables and configurations that shouldn't be shared across machines.
# This allows you to have different settings on different machines without affecting
# your main config or secrets files. For example, you might want different PATH additions,
# aliases, or environment variables on your work laptop vs. your home desktop.
test -f "$dot_fish/local.fish"; and source "$dot_fish/local.fish"
# Sources local.fish if it exists. That file handles sourcing its own
# secrets.fish companion when needed.
test -f "$__fish_user_dots_path/local.fish"; and source "$__fish_user_dots_path/local.fish"
# ─────────────────── C6: Greeting & First-Run UI override ───────────────
# When the greeting category is disabled, stamp out any fish_greeting
+23 -11
View File
@@ -135,7 +135,7 @@ The configuration is split across:
# 1. CONFIGURATION VARIABLES
These variables are exported from config.fish on every interactive session.
Override them in ~/.config/.user-dots/fish/local.fish.
Override them in local.fish (see Section 10, Personalization).
## Environment Directories (XDG)
@@ -1559,20 +1559,26 @@ The install priority for each tool:
Place machine-specific settings that should not be committed to git in:
~/.config/.user-dots/fish/local.fish
$__fish_user_dots_path/local.fish
`__fish_user_dots_path` defaults to `~/.config/.user-dots/fish`. Set a
custom location with:
set -U __fish_user_dots_path /path/to/your/dots/fish
Typical uses: additional PATH entries, local aliases, hostname-specific env
vars, work-specific tool configs.
## Secrets and API Keys
~/.config/.user-dots/fish/secrets.fish
$__fish_user_dots_path/secrets.fish
Store API tokens, GPG keys, private credentials here. This file is never
committed.
committed. It is sourced by local.fish directly, not by config.fish.
Both files are sourced at the end of config.fish on every interactive
session, so they can override anything set earlier.
`local.fish` is sourced at the end of config.fish on every interactive
session, so it and its companion secrets.fish can override anything set
earlier.
## Overriding Configuration Variables
@@ -2087,12 +2093,17 @@ git output is suppressed. Run exec fish after a successful update to reload.
# 10. PERSONALIZATION
Sensitive credentials and machine-specific settings are kept out of version
control in a private directory at ~/.config/.user-dots/fish/. Two files are
sourced automatically by config.fish if they exist:
control in a private directory. The path defaults to
`~/.config/.user-dots/fish/` but can be overridden:
~/.config/.user-dots/fish/
set -U __fish_user_dots_path /path/to/your/dots/fish
config.fish sources local.fish from that directory on every interactive
session. local.fish is responsible for sourcing its own secrets.fish:
$__fish_user_dots_path/
├── secrets.fish API keys, tokens, passwords, personal identifiers
└── local.fish Machine-specific paths and environment variables
└── local.fish Machine-specific paths, env vars, and sourcing secrets
fish_variables (auto-managed by fish) is excluded from this repo via
.gitignore. Do not commit it.
@@ -2130,8 +2141,9 @@ wrong on any other system.
abbr -a dcr 'docker context use my-remote-server'
abbr -a dcw 'docker context use work-server'
Both files are sourced at the end of config.fish with an existence check so
local.fish is sourced at the end of config.fish with an existence check so
the public config works cleanly on any machine without the private repo.
local.fish in turn sources secrets.fish when it exists.
---