Merge pull request 'feat(config): user-dots convenience symlink with config-settings toggle' (#69) from feat-user-dots-symlink into main
Generate documentation / build-docs (push) Successful in 35s
Offline docs drift reminder / remind (push) Successful in 10s

Reviewed-on: #69
This commit was merged in pull request #69.
This commit is contained in:
2026-07-04 06:36:09 +00:00
8 changed files with 113 additions and 18 deletions
+1
View File
@@ -299,3 +299,4 @@ AGENTS/
docs/devlogs docs/devlogs
# ──────────────────────────────────────────────────────── # ────────────────────────────────────────────────────────
/.cache_ggshield /.cache_ggshield
user-dots
+4
View File
@@ -248,6 +248,10 @@ test -f "$__fish_user_dots_path/local.fish"
and source "$__fish_user_dots_path/local.fish" and source "$__fish_user_dots_path/local.fish"
``` ```
For convenience, a git-ignored `user-dots` symlink in the fish config directory is pointed at `$__fish_user_dots_path` on startup, so the overlay can be browsed from `~/.config/fish/`. It is recreated if missing and repointed if the path variable changes. Creation is a C2 startup side-effect (`__fish_config_op_autoexec`); it only ever manages a symlink and never clobbers a real file or directory at that path.
To opt out, set `__fish_user_dots_symlink` to a falsy value (or toggle **Dots link** off on the **Paths** page of `config-settings`). Disabling it stops the symlink being generated and removes any existing one immediately — honoured regardless of the C2 master switch.
`fish_variables` (which fish auto-manages and may contain universal variable state) is excluded from this repo via `.gitignore`. `fish_variables` (which fish auto-manages and may contain universal variable state) is excluded from this repo via `.gitignore`.
--- ---
+7
View File
@@ -226,6 +226,13 @@ if status is-interactive
# Resolve user-dots path. Customize via: set -U __fish_user_dots_path /your/path # Resolve user-dots path. Customize via: set -U __fish_user_dots_path /your/path
set -q __fish_user_dots_path set -q __fish_user_dots_path
or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish" or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
# ────────────────────── user-dots convenience symlink ───────────────────
# Keep $__fish_config_dir/user-dots tracking the resolved path so it can be
# browsed from the fish config dir. Git-ignored. Controlled by the
# __fish_user_dots_symlink toggle (config-settings → Paths); creation is a
# C2 side-effect, removal-on-opt-out is honoured regardless. See the helper.
__fish_user_dots_link
# ─────────────────────── Source machine-local config ──────────────────── # ─────────────────────── Source machine-local config ────────────────────
# Sources local.fish if it exists. That file handles sourcing its own # Sources local.fish if it exists. That file handles sourcing its own
# secrets.fish companion when needed. # secrets.fish companion when needed.
+2
View File
@@ -216,6 +216,8 @@ install-methods=## Install Methods
customization=# 7. CUSTOMIZATION customization=# 7. CUSTOMIZATION
customize=# 7. CUSTOMIZATION customize=# 7. CUSTOMIZATION
local=## Machine-local Configuration local=## Machine-local Configuration
user-dots=## Machine-local Configuration
dots-link=## Machine-local Configuration
secrets=## Secrets and API Keys secrets=## Secrets and API Keys
overrides=## Overriding Configuration Variables overrides=## Overriding Configuration Variables
universal=## Fish Universal Variables universal=## Fish Universal Variables
+21 -4
View File
@@ -1435,8 +1435,9 @@ Add -i (interactive confirmation) to destructive commands:
Sponge — sponge history-scrubbing settings: delay, successful exit Sponge — sponge history-scrubbing settings: delay, successful exit
codes, purge-only-on-exit, allow-previously-successful, and codes, purge-only-on-exit, allow-previously-successful, and
extra sensitive variable-name tokens extra sensitive variable-name tokens
Paths — scrollback log directory, scrollback max files, and the Paths — scrollback log directory, scrollback max files, the
user-dots path user-dots path, and the user-dots convenience symlink toggle
(Dots link)
Toggle rows use ← → (or h/l) along an OFF ← DEFAULT → ON scale; DEFAULT Toggle rows use ← → (or h/l) along an OFF ← DEFAULT → ON scale; DEFAULT
erases the variable so the master switch / built-in default applies. Value erases the variable so the master switch / built-in default applies. Value
@@ -1666,6 +1667,14 @@ custom location with:
Typical uses: additional PATH entries, local aliases, hostname-specific env Typical uses: additional PATH entries, local aliases, hostname-specific env
vars, work-specific tool configs. vars, work-specific tool configs.
For convenience, a git-ignored `user-dots` symlink in the fish config
directory tracks `$__fish_user_dots_path` so the overlay can be browsed from
`~/.config/fish/`. It is created if missing and repointed if the path changes.
Opt out by setting `__fish_user_dots_symlink` to a falsy value, or toggling
"Dots link" off on the config-settings Paths page — this stops generation and
removes any existing link. It only ever manages a symlink and never clobbers a
real file or directory at that path.
## Secrets and API Keys ## Secrets and API Keys
$__fish_user_dots_path/secrets.fish $__fish_user_dots_path/secrets.fish
@@ -1823,10 +1832,18 @@ __fish_config_op_autoexec prevents all of them.
Python venv activation On every cd Sources .venv/bin/activate.fish Python venv activation On every cd Sources .venv/bin/activate.fish
WakaTime command hook On every command Reports to WakaTime API WakaTime command hook On every command Reports to WakaTime API
Auto-pull fast-forward On entering a repo Background ff-only git pull Auto-pull fast-forward On entering a repo Background ff-only git pull
user-dots symlink Every startup Links $__fish_config_dir/user-dots
to $__fish_user_dots_path
When C2 is disabled: no Fisher install, no theme application, no paru/yay When C2 is disabled: no Fisher install, no theme application, no paru/yay
wrapper generation, no automatic venv activation, no WakaTime reporting, and wrapper generation, no automatic venv activation, no WakaTime reporting,
no auto-pull (the PWD handler is never registered). no auto-pull (the PWD handler is never registered), and the user-dots
convenience symlink is not created. The symlink is git-ignored and only ever
managed as a symlink — a real file or directory at that path is left untouched.
The symlink has its own opt-out independent of C2: set __fish_user_dots_symlink
to a falsy value (or toggle "Dots link" off on the config-settings Paths page)
to stop generating it and remove any existing link — honoured even when C2 is
enabled. Managed by the __fish_user_dots_link helper.
The first-run completion marker (__fish_config_first_run_complete) is still The first-run completion marker (__fish_config_first_run_complete) is still
set so the init does not re-run on subsequent shells. set so the init does not re-run on subsequent shells.
+4 -4
View File
@@ -57,10 +57,10 @@ function __config_settings_draw_value
else else
set title "Path Settings" set title "Path Settings"
set active_idx 3 set active_idx 3
set vars __fish_scrollback_history_dir __fish_scrollback_history_max_files __fish_user_dots_path set vars __fish_scrollback_history_dir __fish_scrollback_history_max_files __fish_user_dots_path __fish_user_dots_symlink
set labels "Log dir" "Log max" "Dots path" set labels "Log dir" "Log max" "Dots path" "Dots link"
set types path int path set types path int path bool
set hints "~/.terminal_history" 100 "(default)" set hints "~/.terminal_history" 100 "(default)" on
end end
set -l nrows (count $vars) set -l nrows (count $vars)
+53
View File
@@ -0,0 +1,53 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# __fish_user_dots_link
#
# DESCRIPTION
# Manages the git-ignored `user-dots` convenience symlink in the fish config
# directory ($__fish_config_dir/user-dots), pointing it at the resolved
# $__fish_user_dots_path so the private overlay can be browsed from
# ~/.config/fish/.
#
# Behaviour is controlled by the __fish_user_dots_symlink toggle:
# - explicit falsy (0/false/…) — remove our symlink if present and stop.
# Honoured regardless of C2, so opting out always cleans up.
# - unset or truthy (default) — create the link if missing and repoint it
# if the target changed. This is a C2 startup side-effect, so it only
# creates when __fish_config_op_autoexec is enabled.
#
# Only ever manages a symlink; a real file or directory at that path is left
# untouched.
#
# ARGUMENTS
# (none)
#
# RETURNS
# 0 Always
#
# EXAMPLE
# __fish_user_dots_link
function __fish_user_dots_link --description 'Manage the user-dots convenience symlink'
set -l link "$__fish_config_dir/user-dots"
set -q __fish_user_dots_path
or set -l __fish_user_dots_path "$XDG_CONFIG_HOME/.user-dots/fish"
# Explicit opt-out: remove our symlink (never a real file/dir) and stop.
__fish_variable_check __fish_user_dots_symlink
if test $status -eq 1
test -L "$link"; and rm -f "$link"
return 0
end
# Enabled: creation is a C2 startup side-effect.
__fish_config_op_enabled __fish_config_op_autoexec; or return 0
test -d "$__fish_user_dots_path"; or return 0
if test -L "$link"
test (readlink "$link") != "$__fish_user_dots_path"
and ln -sfn "$__fish_user_dots_path" "$link"
else if not test -e "$link"
ln -s "$__fish_user_dots_path" "$link"
end
end
+21 -10
View File
@@ -80,9 +80,9 @@ function config-settings --description 'Interactive TUI for managing fish config
set -l sponge_vars sponge_delay sponge_purge_only_on_exit sponge_allow_previously_successful sponge_successful_exit_codes __fish_sponge_extra_sensitive set -l sponge_vars sponge_delay sponge_purge_only_on_exit sponge_allow_previously_successful sponge_successful_exit_codes __fish_sponge_extra_sensitive
set -l sponge_types int bool bool list list set -l sponge_types int bool bool list list
set -l sponge_labels Delay "Purge@exit" "Allow prev" "OK codes" "Extra secret" set -l sponge_labels Delay "Purge@exit" "Allow prev" "OK codes" "Extra secret"
set -l paths_vars __fish_scrollback_history_dir __fish_scrollback_history_max_files __fish_user_dots_path set -l paths_vars __fish_scrollback_history_dir __fish_scrollback_history_max_files __fish_user_dots_path __fish_user_dots_symlink
set -l paths_types path int path set -l paths_types path int path bool
set -l paths_labels "Log dir" "Log max" "Dots path" set -l paths_labels "Log dir" "Log max" "Dots path" "Dots link"
# Reset/blank-edit target for each value row. A non-empty entry is written # Reset/blank-edit target for each value row. A non-empty entry is written
# verbatim (sponge reads sponge_delay / sponge_successful_exit_codes with no # verbatim (sponge reads sponge_delay / sponge_successful_exit_codes with no
@@ -91,10 +91,10 @@ function config-settings --description 'Interactive TUI for managing fish config
# extra-sensitive list all tolerate being unset). Bool rows are not reset # extra-sensitive list all tolerate being unset). Bool rows are not reset
# through this path — they are a 2-state true/false with no unset state. # through this path — they are a 2-state true/false with no unset state.
set -l sponge_defaults 2 '' '' 0 '' set -l sponge_defaults 2 '' '' 0 ''
set -l paths_defaults '' '' '' set -l paths_defaults '' '' '' ''
# Rows per page index 0..3 # Rows per page index 0..3
set -l page_rows 7 7 5 3 set -l page_rows 7 7 5 4
set -l cur_page 0 # 0=Universal 1=Session 2=Sponge 3=Paths set -l cur_page 0 # 0=Universal 1=Session 2=Sponge 3=Paths
set -l cur_row 0 set -l cur_row 0
@@ -162,12 +162,21 @@ function config-settings --description 'Interactive TUI for managing fish config
set -l next_val on set -l next_val on
test "$cur_val" = off; and set next_val DEFAULT test "$cur_val" = off; and set next_val DEFAULT
__config_settings_apply $varname $scope $next_val __config_settings_apply $varname $scope $next_val
else if test $cur_page -eq 2 else
# Sponge bool rows are 2-state (true/false) with no unset # Value pages: bool rows are 2-state (true/false). → sets
# state — sponge reads them with no fallback. → sets true. # true. Sponge reads its bools with no fallback; the Paths
# "Dots link" bool drives __fish_user_dots_link on change.
set -l v_vars $sponge_vars
set -l v_types $sponge_types
if test $cur_page -eq 3
set v_vars $paths_vars
set v_types $paths_types
end
set -l ridx (math $cur_row + 1) set -l ridx (math $cur_row + 1)
if test "$sponge_types[$ridx]" = bool if test "$v_types[$ridx]" = bool
set -U $sponge_vars[$ridx] true 2>/dev/null set -U $v_vars[$ridx] true 2>/dev/null
test "$v_vars[$ridx]" = __fish_user_dots_symlink
and __fish_user_dots_link
end end
end end
case left h case left h
@@ -196,6 +205,8 @@ function config-settings --description 'Interactive TUI for managing fish config
set -l vtype $v_types[$ridx] set -l vtype $v_types[$ridx]
if test "$vtype" = bool if test "$vtype" = bool
set -U $varname false 2>/dev/null set -U $varname false 2>/dev/null
test "$varname" = __fish_user_dots_symlink
and __fish_user_dots_link
else else
__config_settings_set_value $varname $vtype "$v_defaults[$ridx]" __config_settings_set_value $varname $vtype "$v_defaults[$ridx]"
end end