From 2a5aef2a6490b12fdcef94e95e067af73668feca Mon Sep 17 00:00:00 2001 From: rootiest Date: Tue, 23 Jun 2026 03:21:02 -0400 Subject: [PATCH] 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. --- README.md | 28 ++++++++++++++++------------ config.fish | 42 ++++++++++++++++-------------------------- docs/fish-config.md | 34 +++++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index e6b58fd..740a021 100644 --- a/README.md +++ b/README.md @@ -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/.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`. diff --git a/config.fish b/config.fish index 8234511..58857de 100644 --- a/config.fish +++ b/config.fish @@ -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 diff --git a/docs/fish-config.md b/docs/fish-config.md index 96b21b2..b2c135a 100644 --- a/docs/fish-config.md +++ b/docs/fish-config.md @@ -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. ---