feat(config): add sub-category granularity to opinionated components #107
@@ -11,6 +11,8 @@ on:
|
|||||||
- "docs/verify-manual.py"
|
- "docs/verify-manual.py"
|
||||||
- "docs/site/**"
|
- "docs/site/**"
|
||||||
- "functions/**"
|
- "functions/**"
|
||||||
|
- "conf.d/**"
|
||||||
|
- "config.fish"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -76,7 +78,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git config user.name "Gitea Actions"
|
git config user.name "Gitea Actions"
|
||||||
git config user.email "actions@gitea"
|
git config user.email "actions@gitea"
|
||||||
git add docs/fish-config.md docs/fish-config.1
|
git add docs/fish-config.md docs/fish-config.1 conf.d/__fish_config_op_registry.fish
|
||||||
git diff --cached --quiet && echo "No changes to commit" && exit 0
|
git diff --cached --quiet && echo "No changes to commit" && exit 0
|
||||||
git commit -m "chore(docs): regenerate manual and man page"
|
git commit -m "chore(docs): regenerate manual, man page, and component registry"
|
||||||
git push
|
git push
|
||||||
|
|||||||
@@ -320,6 +320,14 @@ set -Ue __fish_config_op_greeting
|
|||||||
|
|
||||||
Command shadows react immediately; bindings, prompt, and abbreviations take effect in new shells. With aliases disabled, `rm` deletes permanently again instead of trashing. See `help config opinionated` for the full component list.
|
Command shadows react immediately; bindings, prompt, and abbreviations take effect in new shells. With aliases disabled, `rm` deletes permanently again instead of trashing. See `help config opinionated` for the full component list.
|
||||||
|
|
||||||
|
Each category further sub-divides into two to six sub-categories with
|
||||||
|
their own `__fish_config_op_<category>_<subcategory>` toggles (e.g.
|
||||||
|
`__fish_config_op_aliases_filesystem`), following the exact same
|
||||||
|
truthy/falsy/unset cascade one level deeper. Run `config-settings` and
|
||||||
|
press Enter on a category row to browse and toggle its sub-categories, or
|
||||||
|
see the [Components Reference](https://fish.rootiest.fyi/08-components-reference/)
|
||||||
|
for the full sub-category list per category.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# GENERATED FILE --- do not edit by hand.
|
||||||
|
# Regenerate with __fish_config_op_registry_rebuild after editing a
|
||||||
|
# # COMPONENT header, or automatically via docs/build-manual.py.
|
||||||
|
# Source: docs/generate_component_registry.py
|
||||||
|
#
|
||||||
|
# This file must be sourced before any other conf.d/*.fish file that
|
||||||
|
# calls the opinionated guard. That currently holds only because fish's
|
||||||
|
# glob-based conf.d loading happens to sort this filename first
|
||||||
|
# alphabetically among the guard-calling files -- do not rename it
|
||||||
|
# without preserving that ordering.
|
||||||
|
|
||||||
|
set -g __fish_config_op_registry_keys \
|
||||||
|
"__auto_source_fallback_venv:" \
|
||||||
|
"__fish_config_sync_logging:" \
|
||||||
|
"__fish_user_dots_link:" \
|
||||||
|
"_zellij_dump_log:" \
|
||||||
|
"abbr:abbr-integrations" \
|
||||||
|
"abbr:abbr-overrides" \
|
||||||
|
"agy:" \
|
||||||
|
"auto-pull:" \
|
||||||
|
"autopair:" \
|
||||||
|
"bash:" \
|
||||||
|
"bash_expands:" \
|
||||||
|
"cat:" \
|
||||||
|
"claude:" \
|
||||||
|
"config:cachyos-strip-aliases" \
|
||||||
|
"config:cachyos-strip-overrides" \
|
||||||
|
"config:cachyos-tricks" \
|
||||||
|
"config:cdpath" \
|
||||||
|
"config:exit-wiring" \
|
||||||
|
"config:greeting-stamp" \
|
||||||
|
"config:pager-editor-gpg" \
|
||||||
|
"config:path-setup" \
|
||||||
|
"config:vi-mode" \
|
||||||
|
"done:" \
|
||||||
|
"du:" \
|
||||||
|
"edit:" \
|
||||||
|
"first_run:first-run-bootstrap" \
|
||||||
|
"first_run:first-run-greeting" \
|
||||||
|
"fish_right_prompt:" \
|
||||||
|
"help:" \
|
||||||
|
"hist:" \
|
||||||
|
"key_bindings:" \
|
||||||
|
"kitty-logging:" \
|
||||||
|
"kitty-watcher-reminder:" \
|
||||||
|
"less:" \
|
||||||
|
"logs:" \
|
||||||
|
"ls:" \
|
||||||
|
"mkdir:" \
|
||||||
|
"mv:" \
|
||||||
|
"paru-wrapper:paru-autoexec" \
|
||||||
|
"paru-wrapper:paru-logging" \
|
||||||
|
"ping:" \
|
||||||
|
"puffer:" \
|
||||||
|
"rg:" \
|
||||||
|
"rm:" \
|
||||||
|
"smart_exit:exit-plain" \
|
||||||
|
"smart_exit:logging-guard" \
|
||||||
|
"split:" \
|
||||||
|
"spwin:" \
|
||||||
|
"ssh:" \
|
||||||
|
"starship:" \
|
||||||
|
"tab:" \
|
||||||
|
"theme:" \
|
||||||
|
"tmux-logging:" \
|
||||||
|
"top:" \
|
||||||
|
"tricks:aliases-tricks" \
|
||||||
|
"tricks:tricks-bang" \
|
||||||
|
"tricks:tricks-manpager" \
|
||||||
|
"upgrade:" \
|
||||||
|
"wakatime:wakatime-autoexec" \
|
||||||
|
"wakatime:wakatime-hook" \
|
||||||
|
"yay-wrapper:yay-autoexec" \
|
||||||
|
"yay-wrapper:yay-logging" \
|
||||||
|
"yt-dlp:" \
|
||||||
|
"zoxide:"
|
||||||
|
|
||||||
|
set -g __fish_config_op_registry_values \
|
||||||
|
"autoexec/venv" \
|
||||||
|
"logging/terminal-capture" \
|
||||||
|
"autoexec/sync" \
|
||||||
|
"logging/multiplexer-capture" \
|
||||||
|
"integrations/terminal-abbrs" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"aliases/dev-tools" \
|
||||||
|
"autoexec/sync" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"aliases/shell-tools" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"aliases/dev-tools" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"overrides/environment" \
|
||||||
|
"overrides/environment" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"greeting/greeting-message" \
|
||||||
|
"overrides/environment" \
|
||||||
|
"overrides/environment" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"integrations/notifications" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"aliases/dev-tools" \
|
||||||
|
"autoexec/plugin-management" \
|
||||||
|
"greeting/first-run" \
|
||||||
|
"overrides/prompt" \
|
||||||
|
"aliases/shell-tools" \
|
||||||
|
"integrations/history-logs" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"logging/terminal-capture" \
|
||||||
|
"logging/terminal-capture" \
|
||||||
|
"aliases/shell-tools" \
|
||||||
|
"integrations/history-logs" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"autoexec/pkg-wrappers" \
|
||||||
|
"logging/pkg-logs" \
|
||||||
|
"aliases/network" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"aliases/search" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"logging/terminal-capture" \
|
||||||
|
"integrations/window-mgmt" \
|
||||||
|
"integrations/window-mgmt" \
|
||||||
|
"aliases/network" \
|
||||||
|
"overrides/prompt" \
|
||||||
|
"integrations/window-mgmt" \
|
||||||
|
"overrides/prompt" \
|
||||||
|
"logging/multiplexer-capture" \
|
||||||
|
"aliases/monitor" \
|
||||||
|
"aliases/filesystem" \
|
||||||
|
"overrides/key-bindings" \
|
||||||
|
"overrides/environment" \
|
||||||
|
"integrations/pkg-upgrade" \
|
||||||
|
"autoexec/telemetry" \
|
||||||
|
"integrations/notifications" \
|
||||||
|
"autoexec/pkg-wrappers" \
|
||||||
|
"logging/pkg-logs" \
|
||||||
|
"aliases/network" \
|
||||||
|
"aliases/filesystem"
|
||||||
|
|
||||||
+7
-3
@@ -8,6 +8,10 @@
|
|||||||
# This file contains all the abbreviations for the terminal.
|
# This file contains all the abbreviations for the terminal.
|
||||||
# It is sourced by Fish on startup.
|
# It is sourced by Fish on startup.
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# site abbr-integrations: integrations/terminal-abbrs
|
||||||
|
# site abbr-overrides: overrides/key-bindings
|
||||||
|
|
||||||
# Neovim
|
# Neovim
|
||||||
# @category Editors
|
# @category Editors
|
||||||
# @desc nvim
|
# @desc nvim
|
||||||
@@ -155,7 +159,7 @@ abbr -a ag. agy .
|
|||||||
# @desc exit
|
# @desc exit
|
||||||
abbr -a /exit exit
|
abbr -a /exit exit
|
||||||
# Window-management abbreviations are opinionated (C4 integrations)
|
# Window-management abbreviations are opinionated (C4 integrations)
|
||||||
if __fish_config_op_enabled __fish_config_op_integrations
|
if __fish_config_op_enabled (status basename) abbr-integrations
|
||||||
if test "$TERM" = xterm-kitty
|
if test "$TERM" = xterm-kitty
|
||||||
# @category Terminal Windows, Tabs, and Panes
|
# @category Terminal Windows, Tabs, and Panes
|
||||||
# @desc Close current pane/window
|
# @desc Close current pane/window
|
||||||
@@ -208,7 +212,7 @@ abbr -a speedtest-fast fast-cli
|
|||||||
|
|
||||||
# Kitty/WezTerm window-management abbreviations are opinionated (C4
|
# Kitty/WezTerm window-management abbreviations are opinionated (C4
|
||||||
# integrations): they assume an active Kitty or WezTerm session.
|
# integrations): they assume an active Kitty or WezTerm session.
|
||||||
if __fish_config_op_enabled __fish_config_op_integrations
|
if __fish_config_op_enabled (status basename) abbr-integrations
|
||||||
# Window Creation (OS Windows)
|
# Window Creation (OS Windows)
|
||||||
if test "$TERM" = xterm-kitty
|
if test "$TERM" = xterm-kitty
|
||||||
# @category Terminal Windows, Tabs, and Panes
|
# @category Terminal Windows, Tabs, and Panes
|
||||||
@@ -666,7 +670,7 @@ abbr -a url-open open-url
|
|||||||
### History Expansions and Substitutions ###
|
### History Expansions and Substitutions ###
|
||||||
# Bash-style history expansion is opinionated (C3 overrides), gated atomically
|
# Bash-style history expansion is opinionated (C3 overrides), gated atomically
|
||||||
# with conf.d/tricks.fish, conf.d/puffer.fish, and functions/expand_*.fish.
|
# with conf.d/tricks.fish, conf.d/puffer.fish, and functions/expand_*.fish.
|
||||||
if __fish_config_op_enabled __fish_config_op_overrides
|
if __fish_config_op_enabled (status basename) abbr-overrides
|
||||||
# @category History Expansion
|
# @category History Expansion
|
||||||
# @name !^
|
# @name !^
|
||||||
# @desc Expand to the first argument of the previous command
|
# @desc Expand to the first argument of the previous command
|
||||||
|
|||||||
@@ -14,8 +14,11 @@
|
|||||||
# Manage the registry with: auto-pull add / remove / list / status
|
# Manage the registry with: auto-pull add / remove / list / status
|
||||||
|
|
||||||
# C2 guard: when auto-execution is disabled, do not register the handler.
|
# C2 guard: when auto-execution is disabled, do not register the handler.
|
||||||
__fish_config_op_enabled __fish_config_op_autoexec; or exit
|
__fish_config_op_enabled (status basename); or exit
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# autoexec/sync
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# __auto_pull_on_pwd (event handler, --on-variable PWD)
|
# __auto_pull_on_pwd (event handler, --on-variable PWD)
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
status is-interactive || exit
|
status is-interactive || exit
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# overrides/key-bindings
|
||||||
|
|
||||||
# Local modification: opinionated guard (AGENTS.md Task #3). Bracket
|
# Local modification: opinionated guard (AGENTS.md Task #3). Bracket
|
||||||
# auto-pairing intercepts single-character input, classified as C3 overrides.
|
# auto-pairing intercepts single-character input, classified as C3 overrides.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides || exit
|
__fish_config_op_enabled (status basename) || exit
|
||||||
|
|
||||||
set --global autopair_left "(" "[" "{" '"' "'"
|
set --global autopair_left "(" "[" "{" '"' "'"
|
||||||
set --global autopair_right ")" "]" "}" '"' "'"
|
set --global autopair_right ")" "]" "}" '"' "'"
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# overrides/key-bindings
|
||||||
|
|
||||||
# Provides bash-style history expansion functions for abbreviations.
|
# Provides bash-style history expansion functions for abbreviations.
|
||||||
# These functions are gated by the C3 overrides switch.
|
# These functions are gated by the C3 overrides switch.
|
||||||
|
|
||||||
# Execute expand_bang_all
|
# Execute expand_bang_all
|
||||||
function expand_bang_all --description 'Execute expand_bang_all'
|
function expand_bang_all --description 'Execute expand_bang_all'
|
||||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return 1
|
__fish_config_op_enabled (status basename); or return 1
|
||||||
|
|
||||||
set -l token $argv[1]
|
set -l token $argv[1]
|
||||||
if test -z "$token"; set token (commandline -t); end
|
if test -z "$token"; set token (commandline -t); end
|
||||||
@@ -23,7 +26,7 @@ end
|
|||||||
# Execute expand_bang_caret
|
# Execute expand_bang_caret
|
||||||
function expand_bang_caret --description 'Execute expand_bang_caret'
|
function expand_bang_caret --description 'Execute expand_bang_caret'
|
||||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return 1
|
__fish_config_op_enabled (status basename); or return 1
|
||||||
|
|
||||||
# Split the last history item into a list
|
# Split the last history item into a list
|
||||||
set -l tokens (string split -n ' ' -- $history[1])
|
set -l tokens (string split -n ' ' -- $history[1])
|
||||||
@@ -36,7 +39,7 @@ end
|
|||||||
# Execute expand_bang_minus_n
|
# Execute expand_bang_minus_n
|
||||||
function expand_bang_minus_n --description 'Execute expand_bang_minus_n'
|
function expand_bang_minus_n --description 'Execute expand_bang_minus_n'
|
||||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return 1
|
__fish_config_op_enabled (status basename); or return 1
|
||||||
|
|
||||||
set -l token $argv[1]
|
set -l token $argv[1]
|
||||||
if test -z "$token"; set token (commandline -t); end
|
if test -z "$token"; set token (commandline -t); end
|
||||||
@@ -58,7 +61,7 @@ end
|
|||||||
# Execute expand_bang_search
|
# Execute expand_bang_search
|
||||||
function expand_bang_search --description 'Execute expand_bang_search'
|
function expand_bang_search --description 'Execute expand_bang_search'
|
||||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return 1
|
__fish_config_op_enabled (status basename); or return 1
|
||||||
|
|
||||||
set -l token $argv[1]
|
set -l token $argv[1]
|
||||||
if test -z "$token"
|
if test -z "$token"
|
||||||
@@ -84,7 +87,7 @@ end
|
|||||||
# Execute expand_bang_string
|
# Execute expand_bang_string
|
||||||
function expand_bang_string --description 'Execute expand_bang_string'
|
function expand_bang_string --description 'Execute expand_bang_string'
|
||||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return 1
|
__fish_config_op_enabled (status basename); or return 1
|
||||||
|
|
||||||
# Fish 4.x passes the matched token as argv[1]
|
# Fish 4.x passes the matched token as argv[1]
|
||||||
set -l token $argv[1]
|
set -l token $argv[1]
|
||||||
@@ -112,7 +115,7 @@ end
|
|||||||
# Execute expand_typo_sub
|
# Execute expand_typo_sub
|
||||||
function expand_typo_sub --description 'Execute expand_typo_sub'
|
function expand_typo_sub --description 'Execute expand_typo_sub'
|
||||||
# Opinionated guard (C3): no expansion when overrides are disabled.
|
# Opinionated guard (C3): no expansion when overrides are disabled.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return 1
|
__fish_config_op_enabled (status basename); or return 1
|
||||||
|
|
||||||
# In newer Fish, the matched token is often passed as $argv[1]
|
# In newer Fish, the matched token is often passed as $argv[1]
|
||||||
# if the abbr is set up correctly. We'll fallback to commandline just in case.
|
# if the abbr is set up correctly. We'll fallback to commandline just in case.
|
||||||
|
|||||||
+4
-1
@@ -19,6 +19,9 @@
|
|||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# integrations/notifications
|
||||||
|
|
||||||
if not status is-interactive
|
if not status is-interactive
|
||||||
exit
|
exit
|
||||||
@@ -26,7 +29,7 @@ end
|
|||||||
|
|
||||||
# Local modification: opinionated guard (AGENTS.md Task #3). Desktop
|
# Local modification: opinionated guard (AGENTS.md Task #3). Desktop
|
||||||
# notifications assume a graphical session, classified as C4 integrations.
|
# notifications assume a graphical session, classified as C4 integrations.
|
||||||
__fish_config_op_enabled __fish_config_op_integrations; or exit
|
__fish_config_op_enabled (status basename); or exit
|
||||||
|
|
||||||
set -g __done_version 1.19.1
|
set -g __done_version 1.19.1
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
#
|
#
|
||||||
# Runs exactly once on the first interactive fish session after install.
|
# Runs exactly once on the first interactive fish session after install.
|
||||||
# To reset for testing, run: set -Ue __fish_config_first_run_complete
|
# To reset for testing, run: set -Ue __fish_config_first_run_complete
|
||||||
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# site first-run-greeting: greeting/first-run
|
||||||
|
# site first-run-bootstrap: autoexec/plugin-management
|
||||||
|
|
||||||
# Exit early in non-interactive shells (scripts, completions, subshells)
|
# Exit early in non-interactive shells (scripts, completions, subshells)
|
||||||
if not status is-interactive
|
if not status is-interactive
|
||||||
@@ -36,7 +40,7 @@ end
|
|||||||
# Printing a first-run welcome banner is opinionated (C6 greeting). The
|
# Printing a first-run welcome banner is opinionated (C6 greeting). The
|
||||||
# first-run state variable is already set unconditionally above, so
|
# first-run state variable is already set unconditionally above, so
|
||||||
# disabling the greeting never re-triggers this file.
|
# disabling the greeting never re-triggers this file.
|
||||||
if __fish_config_op_enabled __fish_config_op_greeting
|
if __fish_config_op_enabled (status basename) first-run-greeting
|
||||||
echo ""
|
echo ""
|
||||||
echo " Welcome to your fish shell configuration!"
|
echo " Welcome to your fish shell configuration!"
|
||||||
echo " Run 'help config' for offline documentation."
|
echo " Run 'help config' for offline documentation."
|
||||||
@@ -48,7 +52,7 @@ end
|
|||||||
# Startup side-effects below (Fisher curl, fisher update, theme apply) are
|
# Startup side-effects below (Fisher curl, fisher update, theme apply) are
|
||||||
# opinionated (C2 auto-execution). The first-run state variable is already
|
# opinionated (C2 auto-execution). The first-run state variable is already
|
||||||
# set above either way, so disabling auto-exec never re-triggers this file.
|
# set above either way, so disabling auto-exec never re-triggers this file.
|
||||||
if not __fish_config_op_enabled __fish_config_op_autoexec
|
if not __fish_config_op_enabled (status basename) first-run-bootstrap
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -5,6 +5,9 @@
|
|||||||
# │ help config wrapper │
|
# │ help config wrapper │
|
||||||
# ╰──────────────────────────────────────────────────────────╯
|
# ╰──────────────────────────────────────────────────────────╯
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/shell-tools
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# help [topic] [sub-topic...]
|
# help [topic] [sub-topic...]
|
||||||
# help config [section] [-w|--html] [-m|--man] [-h|--help]
|
# help config [section] [-w|--html] [-m|--man] [-h|--help]
|
||||||
@@ -50,7 +53,7 @@ end
|
|||||||
# --- Wrapper Definition ---
|
# --- Wrapper Definition ---
|
||||||
function help --wraps help --description "Custom wrapper to intercept 'help config'"
|
function help --wraps help --description "Custom wrapper to intercept 'help config'"
|
||||||
# Opinionated guard (C1): fall back to the native fish help when disabled.
|
# Opinionated guard (C1): fall back to the native fish help when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
__original_help $argv
|
__original_help $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
# This file defines custom key bindings for the Fish shell.
|
# This file defines custom key bindings for the Fish shell.
|
||||||
# It is sourced by Fish on startup.
|
# It is sourced by Fish on startup.
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# overrides/key-bindings
|
||||||
|
|
||||||
# ────────────────── Bind Prewious Path Head to Ctrl+G ─────────────────
|
# ────────────────── Bind Prewious Path Head to Ctrl+G ─────────────────
|
||||||
# Bindings to insert the previous path head into the command line
|
# Bindings to insert the previous path head into the command line
|
||||||
# Behaves like `!$:h` does in bash
|
# Behaves like `!$:h` does in bash
|
||||||
@@ -48,7 +51,11 @@ function fish_user_key_bindings
|
|||||||
|
|
||||||
# Custom key chords are opinionated (C3 overrides); skip them entirely
|
# Custom key chords are opinionated (C3 overrides); skip them entirely
|
||||||
# when overrides are disabled so stock bindings remain untouched.
|
# when overrides are disabled so stock bindings remain untouched.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return
|
# NOTE: (status basename), not (status current-function) -- this guard
|
||||||
|
# lives inside fish's own reserved fish_user_key_bindings function, whose
|
||||||
|
# name is not this file's identity; the registry key is this file's
|
||||||
|
# bare basename, key_bindings.
|
||||||
|
__fish_config_op_enabled (status basename); or return
|
||||||
|
|
||||||
# ───────────────────────────── Set Bindings ─────────────────────────────
|
# ───────────────────────────── Set Bindings ─────────────────────────────
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# logging/terminal-capture
|
||||||
|
|
||||||
#
|
#
|
||||||
# C5 — Logging & Capture: a non-blocking, per-session reminder shown inside Kitty
|
# C5 — Logging & Capture: a non-blocking, per-session reminder shown inside Kitty
|
||||||
# when the fish-config scrollback watcher is not yet set up. It never blocks the
|
# when the fish-config scrollback watcher is not yet set up. It never blocks the
|
||||||
@@ -10,7 +14,7 @@
|
|||||||
status is-interactive; or exit
|
status is-interactive; or exit
|
||||||
type -q kitty; or exit
|
type -q kitty; or exit
|
||||||
set -q KITTY_WINDOW_ID; or exit
|
set -q KITTY_WINDOW_ID; or exit
|
||||||
__fish_config_op_enabled __fish_config_op_logging; or exit
|
__fish_config_op_enabled (status basename); or exit
|
||||||
__fish_variable_check __fish_config_kitty_watcher_dismissed; and exit
|
__fish_variable_check __fish_config_kitty_watcher_dismissed; and exit
|
||||||
__kitty_logging_has_watcher; and exit
|
__kitty_logging_has_watcher; and exit
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,16 @@
|
|||||||
# bars are preserved, renders the captured animation to a clean static log
|
# bars are preserved, renders the captured animation to a clean static log
|
||||||
# (via scripts/clean_progress_log.py), and prunes old logs.
|
# (via scripts/clean_progress_log.py), and prunes old logs.
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# site paru-autoexec: autoexec/pkg-wrappers
|
||||||
|
# site paru-logging: logging/pkg-logs
|
||||||
|
|
||||||
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
||||||
# Wrapper generation is also gated by C5 (Logging & Capture).
|
# Wrapper generation is also gated by C5 (Logging & Capture).
|
||||||
__fish_config_op_enabled __fish_config_op_autoexec; or return
|
__fish_config_op_enabled (status basename) paru-autoexec; or return
|
||||||
|
|
||||||
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
||||||
if not __fish_config_op_enabled __fish_config_op_logging
|
if not __fish_config_op_enabled (status basename) paru-logging
|
||||||
if test -f "$HOME/.local/bin/paru"
|
if test -f "$HOME/.local/bin/paru"
|
||||||
and grep -q "# paru-wrapper-version:" "$HOME/.local/bin/paru" 2>/dev/null
|
and grep -q "# paru-wrapper-version:" "$HOME/.local/bin/paru" 2>/dev/null
|
||||||
rm -f "$HOME/.local/bin/paru"
|
rm -f "$HOME/.local/bin/paru"
|
||||||
|
|||||||
+4
-1
@@ -1,9 +1,12 @@
|
|||||||
status is-interactive || exit
|
status is-interactive || exit
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# overrides/key-bindings
|
||||||
|
|
||||||
# Local modification: opinionated guard (AGENTS.md Task #3). Puffer's key
|
# Local modification: opinionated guard (AGENTS.md Task #3). Puffer's key
|
||||||
# intercepts are part of the bang-bang system, gated atomically under C3
|
# intercepts are part of the bang-bang system, gated atomically under C3
|
||||||
# overrides with conf.d/tricks.fish, conf.d/abbr.fish, and expand_*.fish.
|
# overrides with conf.d/tricks.fish, conf.d/abbr.fish, and expand_*.fish.
|
||||||
__fish_config_op_enabled __fish_config_op_overrides || exit
|
__fish_config_op_enabled (status basename) || exit
|
||||||
|
|
||||||
function _puffer_fish_key_bindings --on-variable fish_key_bindings
|
function _puffer_fish_key_bindings --on-variable fish_key_bindings
|
||||||
set -l modes
|
set -l modes
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# overrides/prompt
|
||||||
|
|
||||||
#
|
#
|
||||||
# Defines fish_prompt only when starship is installed.
|
# Defines fish_prompt only when starship is installed.
|
||||||
# Without starship, fish's built-in prompt already emits OSC 133;A
|
# Without starship, fish's built-in prompt already emits OSC 133;A
|
||||||
# on the prompt line itself, so no wrapper is needed.
|
# on the prompt line itself, so no wrapper is needed.
|
||||||
|
|
||||||
# Replacing the prompt is opinionated (C3 overrides)
|
# Replacing the prompt is opinionated (C3 overrides)
|
||||||
__fish_config_op_enabled __fish_config_op_overrides; or return
|
__fish_config_op_enabled (status basename); or return
|
||||||
|
|
||||||
type -q starship; or return
|
type -q starship; or return
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -1,5 +1,9 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# overrides/prompt
|
||||||
|
|
||||||
#
|
#
|
||||||
# ╭──────────────────────────────────────────────────────────╮
|
# ╭──────────────────────────────────────────────────────────╮
|
||||||
# │ Fish Theme │
|
# │ Fish Theme │
|
||||||
@@ -9,7 +13,7 @@
|
|||||||
# Forcing theme colors and $FZF_DEFAULT_OPTS is opinionated (C3 overrides).
|
# Forcing theme colors and $FZF_DEFAULT_OPTS is opinionated (C3 overrides).
|
||||||
# The FZF variable is universal, so clean up our Catppuccin value if it
|
# The FZF variable is universal, so clean up our Catppuccin value if it
|
||||||
# lingers from a session where overrides were still enabled.
|
# lingers from a session where overrides were still enabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_overrides
|
if not __fish_config_op_enabled (status basename)
|
||||||
if set -q FZF_DEFAULT_OPTS; and string match -q '*#1E1E2E*' -- "$FZF_DEFAULT_OPTS"
|
if set -q FZF_DEFAULT_OPTS; and string match -q '*#1E1E2E*' -- "$FZF_DEFAULT_OPTS"
|
||||||
set --erase FZF_DEFAULT_OPTS
|
set --erase FZF_DEFAULT_OPTS
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# logging/multiplexer-capture
|
||||||
|
|
||||||
#
|
#
|
||||||
# C5 — Logging & Capture: starts a pipe-pane log for the current tmux pane
|
# C5 — Logging & Capture: starts a pipe-pane log for the current tmux pane
|
||||||
# when fish launches inside a tmux session. Each fish shell gets its own
|
# when fish launches inside a tmux session. Each fish shell gets its own
|
||||||
# timestamped log file in SCROLLBACK_HISTORY_DIR (default: ~/.terminal_history).
|
# timestamped log file in SCROLLBACK_HISTORY_DIR (default: ~/.terminal_history).
|
||||||
# Naming: tmux_<session>-w<window>-p<pane>_YYYY-MM-DD_HH-MM-SS.log
|
# Naming: tmux_<session>-w<window>-p<pane>_YYYY-MM-DD_HH-MM-SS.log
|
||||||
|
|
||||||
__fish_config_op_enabled __fish_config_op_logging; or exit
|
__fish_config_op_enabled (status basename); or exit
|
||||||
status is-interactive; or exit
|
status is-interactive; or exit
|
||||||
type -q tmux; or exit
|
type -q tmux; or exit
|
||||||
set -q TMUX; or exit
|
set -q TMUX; or exit
|
||||||
|
|||||||
+9
-4
@@ -7,6 +7,11 @@
|
|||||||
# │ system aliases, and history/backup utilities │
|
# │ system aliases, and history/backup utilities │
|
||||||
# ╰──────────────────────────────────────────────────────────╯
|
# ╰──────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# site aliases-tricks: aliases/filesystem
|
||||||
|
# site tricks-manpager: overrides/environment
|
||||||
|
# site tricks-bang: overrides/key-bindings
|
||||||
|
|
||||||
## Environment setup
|
## Environment setup
|
||||||
# Apply .profile: use this to put fish compatible .profile stuff in
|
# Apply .profile: use this to put fish compatible .profile stuff in
|
||||||
if test -f ~/.fish_profile
|
if test -f ~/.fish_profile
|
||||||
@@ -24,7 +29,7 @@ end
|
|||||||
|
|
||||||
# Format man pages using bat (only if bat is installed)
|
# Format man pages using bat (only if bat is installed)
|
||||||
# Overriding $MANPAGER is opinionated (C3 overrides)
|
# Overriding $MANPAGER is opinionated (C3 overrides)
|
||||||
if type -q bat; and __fish_config_op_enabled __fish_config_op_overrides
|
if type -q bat; and __fish_config_op_enabled (status basename) tricks-manpager
|
||||||
set -gx MANROFFOPT -c
|
set -gx MANROFFOPT -c
|
||||||
set -gx MANPAGER "sh -c 'col -bx | bat -l man -p'"
|
set -gx MANPAGER "sh -c 'col -bx | bat -l man -p'"
|
||||||
end
|
end
|
||||||
@@ -37,7 +42,7 @@ set -gx __done_notification_urgency_level low
|
|||||||
# Functions needed for !! and !$ https://github.com/oh-my-fish/plugin-bang-bang
|
# Functions needed for !! and !$ https://github.com/oh-my-fish/plugin-bang-bang
|
||||||
# The bang-bang system is opinionated (C3 overrides) and is gated atomically
|
# The bang-bang system is opinionated (C3 overrides) and is gated atomically
|
||||||
# here, in conf.d/abbr.fish, conf.d/puffer.fish, and functions/expand_*.fish.
|
# here, in conf.d/abbr.fish, conf.d/puffer.fish, and functions/expand_*.fish.
|
||||||
if __fish_config_op_enabled __fish_config_op_overrides
|
if __fish_config_op_enabled (status basename) tricks-bang
|
||||||
function __history_previous_command
|
function __history_previous_command
|
||||||
switch (commandline -t)
|
switch (commandline -t)
|
||||||
case "!"
|
case "!"
|
||||||
@@ -83,7 +88,7 @@ end
|
|||||||
# Fish command history override to show timestamps
|
# Fish command history override to show timestamps
|
||||||
# Shadowing the history command is opinionated (C1 aliasing); when disabled,
|
# Shadowing the history command is opinionated (C1 aliasing); when disabled,
|
||||||
# the function is never defined and fish's stock history behavior applies.
|
# the function is never defined and fish's stock history behavior applies.
|
||||||
if __fish_config_op_enabled __fish_config_op_aliases
|
if __fish_config_op_enabled (status basename) aliases-tricks
|
||||||
function history
|
function history
|
||||||
builtin history --show-time='%F %T '
|
builtin history --show-time='%F %T '
|
||||||
end
|
end
|
||||||
@@ -123,7 +128,7 @@ alias .....='cd ../../../..'
|
|||||||
alias ......='cd ../../../../..'
|
alias ......='cd ../../../../..'
|
||||||
|
|
||||||
# Silent flag injection into POSIX tools is opinionated (C1 aliasing)
|
# Silent flag injection into POSIX tools is opinionated (C1 aliasing)
|
||||||
if __fish_config_op_enabled __fish_config_op_aliases
|
if __fish_config_op_enabled (status basename) aliases-tricks
|
||||||
# Tools & Core command color overrides
|
# Tools & Core command color overrides
|
||||||
# @category Shell Aliases
|
# @category Shell Aliases
|
||||||
# @desc dir --color=auto
|
# @desc dir --color=auto
|
||||||
|
|||||||
@@ -5,11 +5,15 @@
|
|||||||
# see: https://github.com/ik11235/wakatime.fish
|
# see: https://github.com/ik11235/wakatime.fish
|
||||||
###
|
###
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# site wakatime-autoexec: autoexec/telemetry
|
||||||
|
# site wakatime-hook: integrations/notifications
|
||||||
|
|
||||||
# Local modification: opinionated guard (AGENTS.md Task #3). WakaTime
|
# Local modification: opinionated guard (AGENTS.md Task #3). WakaTime
|
||||||
# reporting is classified under both C2 auto-execution and C4 integrations;
|
# reporting is classified under both C2 auto-execution and C4 integrations;
|
||||||
# disabling either category skips registering the hook.
|
# disabling either category skips registering the hook.
|
||||||
__fish_config_op_enabled __fish_config_op_autoexec; or exit
|
__fish_config_op_enabled (status basename) wakatime-autoexec; or exit
|
||||||
__fish_config_op_enabled __fish_config_op_integrations; or exit
|
__fish_config_op_enabled (status basename) wakatime-hook; or exit
|
||||||
|
|
||||||
function __register_wakatime_fish_before_exec -e fish_postexec
|
function __register_wakatime_fish_before_exec -e fish_postexec
|
||||||
if set -q FISH_WAKATIME_DISABLED
|
if set -q FISH_WAKATIME_DISABLED
|
||||||
|
|||||||
@@ -6,12 +6,16 @@
|
|||||||
# bars are preserved, renders the captured animation to a clean static log
|
# bars are preserved, renders the captured animation to a clean static log
|
||||||
# (via scripts/clean_progress_log.py), and prunes old logs.
|
# (via scripts/clean_progress_log.py), and prunes old logs.
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# site yay-autoexec: autoexec/pkg-wrappers
|
||||||
|
# site yay-logging: logging/pkg-logs
|
||||||
|
|
||||||
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
|
||||||
# Wrapper generation is also gated by C5 (Logging & Capture).
|
# Wrapper generation is also gated by C5 (Logging & Capture).
|
||||||
__fish_config_op_enabled __fish_config_op_autoexec; or return
|
__fish_config_op_enabled (status basename) yay-autoexec; or return
|
||||||
|
|
||||||
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
|
||||||
if not __fish_config_op_enabled __fish_config_op_logging
|
if not __fish_config_op_enabled (status basename) yay-logging
|
||||||
if test -f "$HOME/.local/bin/yay"
|
if test -f "$HOME/.local/bin/yay"
|
||||||
and grep -q "# yay-wrapper-version:" "$HOME/.local/bin/yay" 2>/dev/null
|
and grep -q "# yay-wrapper-version:" "$HOME/.local/bin/yay" 2>/dev/null
|
||||||
rm -f "$HOME/.local/bin/yay"
|
rm -f "$HOME/.local/bin/yay"
|
||||||
|
|||||||
+4
-1
@@ -3,6 +3,9 @@
|
|||||||
# Adapted from icezyclon/zoxide.fish (MIT)
|
# Adapted from icezyclon/zoxide.fish (MIT)
|
||||||
# Heavily customized for Fish 4.x compatibility and performance
|
# Heavily customized for Fish 4.x compatibility and performance
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/filesystem
|
||||||
|
|
||||||
if status is-interactive
|
if status is-interactive
|
||||||
|
|
||||||
if type -q zoxide
|
if type -q zoxide
|
||||||
@@ -65,7 +68,7 @@ if status is-interactive
|
|||||||
|
|
||||||
# Shadowing cd with zoxide is opinionated (C1 aliasing); z and zi
|
# Shadowing cd with zoxide is opinionated (C1 aliasing); z and zi
|
||||||
# remain available either way.
|
# remain available either way.
|
||||||
if __fish_config_op_enabled __fish_config_op_aliases
|
if __fish_config_op_enabled (status basename)
|
||||||
alias cd=z
|
alias cd=z
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+21
-10
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
# ───────────────────── Opinionated component guards ─────────────────────
|
# ───────────────────── Opinionated component guards ─────────────────────
|
||||||
# Opinionated components (AGENTS.md Task #3) are wrapped in
|
# Opinionated components (AGENTS.md Task #3) are wrapped in
|
||||||
# __fish_config_op_enabled <category> guards throughout this file and conf.d/.
|
# __fish_config_op_enabled <identity> [<site>] guards throughout this file and conf.d/.
|
||||||
# The helper always evaluates the master switch __fish_config_opinionated
|
# The helper always evaluates the master switch __fish_config_opinionated
|
||||||
# first (falsy disables everything), then the per-category opt-out variable:
|
# first (falsy disables everything), then the per-category opt-out variable:
|
||||||
# __fish_config_op_aliases C1 — command shadows / flag injection
|
# __fish_config_op_aliases C1 — command shadows / flag injection
|
||||||
@@ -21,12 +21,23 @@
|
|||||||
# C5 is the one exception: it defaults to disabled and needs an explicit
|
# C5 is the one exception: it defaults to disabled and needs an explicit
|
||||||
# truthy value — set -U __fish_config_op_logging on
|
# truthy value — set -U __fish_config_op_logging on
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# site cachyos-tricks: overrides/environment
|
||||||
|
# site cachyos-strip-aliases: aliases/filesystem
|
||||||
|
# site cachyos-strip-overrides: overrides/key-bindings
|
||||||
|
# site pager-editor-gpg: overrides/environment
|
||||||
|
# site exit-wiring: overrides/key-bindings
|
||||||
|
# site path-setup: overrides/environment
|
||||||
|
# site cdpath: overrides/environment
|
||||||
|
# site vi-mode: overrides/key-bindings
|
||||||
|
# site greeting-stamp: greeting/greeting-message
|
||||||
|
|
||||||
# ──────────────────────── Source CachyOS configs ────────────────────────
|
# ──────────────────────── Source CachyOS configs ────────────────────────
|
||||||
if test -f /usr/share/cachyos-fish-config/cachyos-config.fish
|
if test -f /usr/share/cachyos-fish-config/cachyos-config.fish
|
||||||
source /usr/share/cachyos-fish-config/cachyos-config.fish
|
source /usr/share/cachyos-fish-config/cachyos-config.fish
|
||||||
# Surgically overriding the distro config is opinionated (C3 overrides):
|
# Surgically overriding the distro config is opinionated (C3 overrides):
|
||||||
# skip it entirely when overrides are disabled, keeping CachyOS defaults.
|
# skip it entirely when overrides are disabled, keeping CachyOS defaults.
|
||||||
if __fish_config_op_enabled __fish_config_op_overrides
|
if __fish_config_op_enabled (status basename) cachyos-tricks
|
||||||
# Source our tricks over the cachyOS config
|
# Source our tricks over the cachyOS config
|
||||||
test -f "$__fish_config_dir/conf.d/tricks.fish"
|
test -f "$__fish_config_dir/conf.d/tricks.fish"
|
||||||
and source "$__fish_config_dir/conf.d/tricks.fish"
|
and source "$__fish_config_dir/conf.d/tricks.fish"
|
||||||
@@ -41,7 +52,7 @@ if test -f /usr/share/cachyos-fish-config/cachyos-config.fish
|
|||||||
# The distro config ships opinionated pieces of its own (it is the origin
|
# The distro config ships opinionated pieces of its own (it is the origin
|
||||||
# of tricks.fish); strip them when the matching category is disabled so
|
# of tricks.fish); strip them when the matching category is disabled so
|
||||||
# the guards hold on CachyOS systems too.
|
# the guards hold on CachyOS systems too.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status basename) cachyos-strip-aliases
|
||||||
for _fname in grep fgrep egrep dir vdir wget
|
for _fname in grep fgrep egrep dir vdir wget
|
||||||
functions -q $_fname; and functions --erase $_fname
|
functions -q $_fname; and functions --erase $_fname
|
||||||
end
|
end
|
||||||
@@ -53,7 +64,7 @@ if test -f /usr/share/cachyos-fish-config/cachyos-config.fish
|
|||||||
and source $__fish_data_dir/functions/$_fname.fish
|
and source $__fish_data_dir/functions/$_fname.fish
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not __fish_config_op_enabled __fish_config_op_overrides
|
if not __fish_config_op_enabled (status basename) cachyos-strip-overrides
|
||||||
for _fname in __history_previous_command __history_previous_command_arguments
|
for _fname in __history_previous_command __history_previous_command_arguments
|
||||||
functions -q $_fname; and functions --erase $_fname
|
functions -q $_fname; and functions --erase $_fname
|
||||||
end
|
end
|
||||||
@@ -95,7 +106,7 @@ set -q WORDLIST; or set -gx WORDLIST "$XDG_CONFIG_HOME/hunspell_en_US"
|
|||||||
|
|
||||||
# ─────────────────────────── Pager variables ────────────────────────────
|
# ─────────────────────────── Pager variables ────────────────────────────
|
||||||
# Overriding $PAGER, $EDITOR, and $GPG_TTY is opinionated (C3 overrides)
|
# Overriding $PAGER, $EDITOR, and $GPG_TTY is opinionated (C3 overrides)
|
||||||
if __fish_config_op_enabled __fish_config_op_overrides
|
if __fish_config_op_enabled (status basename) pager-editor-gpg
|
||||||
if type -q ov
|
if type -q ov
|
||||||
set -gx PAGER ov
|
set -gx PAGER ov
|
||||||
else if type -q less
|
else if type -q less
|
||||||
@@ -136,7 +147,7 @@ and set -gx SCROLLBACK_HISTORY_MAX_FILES $__fish_scrollback_history_max_files
|
|||||||
# Wire up a clean exit function that won't fire on background subshells
|
# Wire up a clean exit function that won't fire on background subshells
|
||||||
# Replacing the exit builtin is opinionated (C3 overrides); smart_exit also
|
# Replacing the exit builtin is opinionated (C3 overrides); smart_exit also
|
||||||
# guards itself so a live toggle takes effect without restarting the shell.
|
# guards itself so a live toggle takes effect without restarting the shell.
|
||||||
if status is-interactive; and __fish_config_op_enabled __fish_config_op_overrides
|
if status is-interactive; and __fish_config_op_enabled (status basename) exit-wiring
|
||||||
function exit --description 'Safe interactive exit'
|
function exit --description 'Safe interactive exit'
|
||||||
# If the smart_exit file exists in our function path, invoke it explicitly
|
# If the smart_exit file exists in our function path, invoke it explicitly
|
||||||
if functions -q smart_exit
|
if functions -q smart_exit
|
||||||
@@ -153,7 +164,7 @@ end
|
|||||||
# the cargo bin directory is moved to the end of the PATH, which can help avoid conflicts
|
# 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.
|
# with system-installed Rust tools while still allowing user-installed cargo binaries to be found.
|
||||||
# PATH setup is opinionated (C3 overrides)
|
# PATH setup is opinionated (C3 overrides)
|
||||||
if __fish_config_op_enabled __fish_config_op_overrides
|
if __fish_config_op_enabled (status basename) path-setup
|
||||||
fish_add_path $HOME/.local/bin # Standard user-local executables (XDG spec)
|
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/.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/Applications # User-installed applications and standalone apps
|
||||||
@@ -176,7 +187,7 @@ end
|
|||||||
# so if you have a directory named 'myproject' in the current directory,
|
# so if you have a directory named 'myproject' in the current directory,
|
||||||
# running 'cd myproject' will take you there instead of $HOME/projects/myproject.
|
# running 'cd myproject' will take you there instead of $HOME/projects/myproject.
|
||||||
# CDPATH injection is opinionated (C3 overrides)
|
# CDPATH injection is opinionated (C3 overrides)
|
||||||
if __fish_config_op_enabled __fish_config_op_overrides
|
if __fish_config_op_enabled (status basename) cdpath
|
||||||
set -gx CDPATH . $HOME/projects $HOME
|
set -gx CDPATH . $HOME/projects $HOME
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -191,7 +202,7 @@ if status is-interactive
|
|||||||
# This is optional but can improve the user experience for those who prefer Vi-style key bindings.
|
# This is optional but can improve the user experience for those who prefer Vi-style key bindings.
|
||||||
# Global Vi mode is opinionated (C3 overrides); without it fish keeps its
|
# Global Vi mode is opinionated (C3 overrides); without it fish keeps its
|
||||||
# default Emacs-style bindings.
|
# default Emacs-style bindings.
|
||||||
if __fish_config_op_enabled __fish_config_op_overrides
|
if __fish_config_op_enabled (status basename) vi-mode
|
||||||
set -g fish_key_bindings fish_vi_key_bindings
|
set -g fish_key_bindings fish_vi_key_bindings
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -251,7 +262,7 @@ if status is-interactive
|
|||||||
# function that distro configs set (e.g., CachyOS defines it as fastfetch).
|
# function that distro configs set (e.g., CachyOS defines it as fastfetch).
|
||||||
# This runs last inside the interactive block so our empty definition wins
|
# This runs last inside the interactive block so our empty definition wins
|
||||||
# over whatever cachyos-config.fish or vendor conf.d installed.
|
# over whatever cachyos-config.fish or vendor conf.d installed.
|
||||||
if not __fish_config_op_enabled __fish_config_op_greeting
|
if not __fish_config_op_enabled (status basename) greeting-stamp
|
||||||
function fish_greeting
|
function fish_greeting
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import sys
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import manualtools as mt
|
import manualtools as mt
|
||||||
|
import generate_component_registry
|
||||||
|
|
||||||
DOCS = Path(__file__).parent
|
DOCS = Path(__file__).parent
|
||||||
MANUAL = DOCS / "manual"
|
MANUAL = DOCS / "manual"
|
||||||
@@ -840,6 +841,8 @@ def main() -> int:
|
|||||||
if not (args.concat or args.site):
|
if not (args.concat or args.site):
|
||||||
ap.error("nothing to do: pass --concat and/or --site")
|
ap.error("nothing to do: pass --concat and/or --site")
|
||||||
|
|
||||||
|
generate_component_registry.main()
|
||||||
|
|
||||||
if args.site:
|
if args.site:
|
||||||
src = DOCS / "site" / "src"
|
src = DOCS / "site" / "src"
|
||||||
out = src / "content" / "docs"
|
out = src / "content" / "docs"
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
"""Generate the committed opinionated-component registry.
|
||||||
|
|
||||||
|
Walks every `# COMPONENT` header in functions/*.fish, conf.d/*.fish, and
|
||||||
|
config.fish and writes conf.d/__fish_config_op_registry.fish, the fish
|
||||||
|
data file __fish_config_op_registry_lookup reads at shell startup.
|
||||||
|
|
||||||
|
Run manually (via __fish_config_op_registry_rebuild) after editing a
|
||||||
|
# COMPONENT header, and automatically as a pre-step in build-manual.py
|
||||||
|
before the manual is built.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import manualtools as mt
|
||||||
|
|
||||||
|
DOCS = Path(__file__).parent
|
||||||
|
REPO = DOCS.parent
|
||||||
|
OUTPUT = REPO / "conf.d" / "__fish_config_op_registry.fish"
|
||||||
|
|
||||||
|
|
||||||
|
def collect_components() -> dict[str, list[str]]:
|
||||||
|
"""Gather every `# COMPONENT` header across the whole repo.
|
||||||
|
|
||||||
|
Concatenates raw component lines when the same identity appears in
|
||||||
|
more than one source (e.g. functions/auto-pull.fish and
|
||||||
|
conf.d/auto-pull.fish both self-identify as "auto-pull" at runtime,
|
||||||
|
since the guard can only ever look up the bare status
|
||||||
|
current-function/basename string) rather than letting one silently
|
||||||
|
overwrite the other.
|
||||||
|
"""
|
||||||
|
out: dict[str, list[str]] = {}
|
||||||
|
for source in (
|
||||||
|
mt.parse_components(REPO / "functions"),
|
||||||
|
mt.parse_components(REPO / "conf.d"),
|
||||||
|
mt.parse_component_file(REPO / "config.fish"),
|
||||||
|
):
|
||||||
|
for identity, lines in source.items():
|
||||||
|
out.setdefault(identity, []).extend(lines)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def build_registry(components: dict[str, list[str]]) -> tuple[dict[str, list[str]], list[str]]:
|
||||||
|
"""Turn {identity: [raw COMPONENT lines]} into ({"identity:site": [tags]}, warnings).
|
||||||
|
|
||||||
|
A site with both always/on and always/off tagged is a contradiction:
|
||||||
|
both are stripped and a warning is emitted, but generation continues
|
||||||
|
-- any other real tag on that same site survives. A site whose
|
||||||
|
effective tag set is empty after stripping produces no registry entry
|
||||||
|
at all, which __fish_config_op_enabled already treats as always/on
|
||||||
|
(fail-open) at guard time -- see spec §4.5.
|
||||||
|
"""
|
||||||
|
registry: dict[str, list[str]] = {}
|
||||||
|
warnings: list[str] = []
|
||||||
|
for identity, raw_lines in components.items():
|
||||||
|
by_site: dict[str, list[str]] = {}
|
||||||
|
for site, tag in mt.parse_component_lines(raw_lines):
|
||||||
|
by_site.setdefault(site, []).append(tag)
|
||||||
|
for site, tags in by_site.items():
|
||||||
|
if "always/on" in tags and "always/off" in tags:
|
||||||
|
label = identity if not site else f"{identity}:{site}"
|
||||||
|
warnings.append(
|
||||||
|
f"{label}: both always/on and always/off tagged; ignoring both"
|
||||||
|
)
|
||||||
|
tags = [t for t in tags if t not in ("always/on", "always/off")]
|
||||||
|
if tags:
|
||||||
|
registry[f"{identity}:{site}"] = list(dict.fromkeys(tags))
|
||||||
|
return registry, warnings
|
||||||
|
|
||||||
|
|
||||||
|
def render(registry: dict[str, list[str]]) -> str:
|
||||||
|
keys = sorted(registry)
|
||||||
|
lines = [
|
||||||
|
"# Copyright (C) 2026 Rootiest",
|
||||||
|
"# SPDX-License-Identifier: AGPL-3.0-or-later",
|
||||||
|
"#",
|
||||||
|
"# GENERATED FILE --- do not edit by hand.",
|
||||||
|
"# Regenerate with __fish_config_op_registry_rebuild after editing a",
|
||||||
|
"# # COMPONENT header, or automatically via docs/build-manual.py.",
|
||||||
|
"# Source: docs/generate_component_registry.py",
|
||||||
|
"#",
|
||||||
|
"# This file must be sourced before any other conf.d/*.fish file that",
|
||||||
|
"# calls the opinionated guard. That currently holds only because fish's",
|
||||||
|
"# glob-based conf.d loading happens to sort this filename first",
|
||||||
|
"# alphabetically among the guard-calling files -- do not rename it",
|
||||||
|
"# without preserving that ordering.",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
if not keys:
|
||||||
|
lines.append("set -g __fish_config_op_registry_keys")
|
||||||
|
lines.append("set -g __fish_config_op_registry_values")
|
||||||
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
quoted_keys = [f'"{k}"' for k in keys]
|
||||||
|
lines.append("set -g __fish_config_op_registry_keys \\")
|
||||||
|
lines += [f" {k} \\" for k in quoted_keys[:-1]] + [f" {quoted_keys[-1]}"]
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
values = ['"' + " ".join(registry[k]) + '"' for k in keys]
|
||||||
|
lines.append("set -g __fish_config_op_registry_values \\")
|
||||||
|
lines += [f" {v} \\" for v in values[:-1]] + [f" {values[-1]}"]
|
||||||
|
lines.append("")
|
||||||
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
components = collect_components()
|
||||||
|
registry, warnings = build_registry(components)
|
||||||
|
for w in warnings:
|
||||||
|
print(f" WARN {w}", file=sys.stderr)
|
||||||
|
OUTPUT.write_text(render(registry))
|
||||||
|
print(f"wrote {OUTPUT} ({len(registry)} entries)", file=sys.stderr)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.path.insert(0, str(Path(__file__).parent))
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -145,6 +145,19 @@ NOTE:
|
|||||||
- Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them.
|
- Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them.
|
||||||
- On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well.
|
- On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well.
|
||||||
|
|
||||||
|
### Sub-categories
|
||||||
|
|
||||||
|
Each of the six categories further sub-divides into two to six
|
||||||
|
sub-categories, each with its own `__fish_config_op_<category>_<subcategory>`
|
||||||
|
variable (e.g. `__fish_config_op_aliases_filesystem`). These follow the
|
||||||
|
exact same truthy/falsy/unset cascade one level deeper: an explicit
|
||||||
|
sub-category value overrides the master switch and the parent category's
|
||||||
|
setting, and an unset sub-category inherits from its parent category (which
|
||||||
|
in turn inherits from `__fish_config_opinionated`). Run config-settings and
|
||||||
|
press Enter on a category row to browse and toggle its sub-categories
|
||||||
|
interactively. See [Components Reference](/08-components-reference/) for the
|
||||||
|
full sub-category breakdown of every category.
|
||||||
|
|
||||||
|
|
||||||
## Prompt and Theme
|
## Prompt and Theme
|
||||||
|
|
||||||
|
|||||||
@@ -31,3 +31,35 @@ all of these commands.
|
|||||||
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
|
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
|
||||||
are permanently deleted, not trashed. There is no intermediate safety net.
|
are permanently deleted, not trashed. There is no intermediate safety net.
|
||||||
|
|
||||||
|
## Sub-categories
|
||||||
|
|
||||||
|
`__fish_config_op_aliases` sub-divides into six sub-categories, each with
|
||||||
|
its own `__fish_config_op_aliases_<slug>` toggle:
|
||||||
|
|
||||||
|
## filesystem
|
||||||
|
|
||||||
|
`ls`, `cat`, `cd`, `du`, `mkdir`, `rm`, `mv`, and `cd`/zoxide navigation --
|
||||||
|
the everyday filesystem-inspection and -modification shadows.
|
||||||
|
|
||||||
|
## search
|
||||||
|
|
||||||
|
`rg`, with its Kitty hyperlink formatting.
|
||||||
|
|
||||||
|
## network
|
||||||
|
|
||||||
|
`ping`, `ssh`, and `yt-dlp` -- shadows that talk to the network.
|
||||||
|
|
||||||
|
## monitor
|
||||||
|
|
||||||
|
`top` -> `btop`.
|
||||||
|
|
||||||
|
## shell-tools
|
||||||
|
|
||||||
|
`bash` (XDG bashrc + `$SHELL` reset), `less` (`$PAGER` fallback chain),
|
||||||
|
and the `help config` interception.
|
||||||
|
|
||||||
|
## dev-tools
|
||||||
|
|
||||||
|
`claude` (AGENTS.md/CLAUDE.md auto-linking) and `edit` (multi-editor
|
||||||
|
launcher), plus `agy`.
|
||||||
|
|
||||||
|
|||||||
@@ -43,3 +43,28 @@ branches, or repos without a remote. The handler fires once per repo entry
|
|||||||
(not on every sub-directory `cd`). The registry is machine-local at
|
(not on every sub-directory `cd`). The registry is machine-local at
|
||||||
`$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed.
|
`$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed.
|
||||||
|
|
||||||
|
## Sub-categories
|
||||||
|
|
||||||
|
`__fish_config_op_autoexec` sub-divides into five sub-categories, each
|
||||||
|
with its own `__fish_config_op_autoexec_<slug>` toggle:
|
||||||
|
|
||||||
|
## plugin-management
|
||||||
|
|
||||||
|
Fisher bootstrap on first run.
|
||||||
|
|
||||||
|
## pkg-wrappers
|
||||||
|
|
||||||
|
`paru`/`yay` wrapper generation.
|
||||||
|
|
||||||
|
## venv
|
||||||
|
|
||||||
|
Automatic Python virtualenv activation.
|
||||||
|
|
||||||
|
## telemetry
|
||||||
|
|
||||||
|
The WakaTime hook's startup bootstrap.
|
||||||
|
|
||||||
|
## sync
|
||||||
|
|
||||||
|
Auto-pull background fast-forward, and the user-dots convenience symlink.
|
||||||
|
|
||||||
|
|||||||
@@ -33,3 +33,23 @@ When C3 is disabled, `exit` falls back to `builtin exit` with no scrollback
|
|||||||
capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block
|
capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block
|
||||||
is independently controlled by C5 (see below).
|
is independently controlled by C5 (see below).
|
||||||
|
|
||||||
|
## Sub-categories
|
||||||
|
|
||||||
|
`__fish_config_op_overrides` sub-divides into three sub-categories, each
|
||||||
|
with its own `__fish_config_op_overrides_<slug>` toggle:
|
||||||
|
|
||||||
|
## key-bindings
|
||||||
|
|
||||||
|
Vi mode, autopair, puffer key intercepts, bang-bang history expansion,
|
||||||
|
and `smart_exit`'s plain-exit path.
|
||||||
|
|
||||||
|
## environment
|
||||||
|
|
||||||
|
`$PATH`, `$PAGER`/`$EDITOR`/`$GPG_TTY`, and `$CDPATH`.
|
||||||
|
|
||||||
|
## prompt
|
||||||
|
|
||||||
|
Starship, the right prompt, Catppuccin syntax/prompt colors, and FZF
|
||||||
|
theming (`$FZF_DEFAULT_OPTS`) -- all driven by the same guard as a single
|
||||||
|
unit, not independently toggleable from each other.
|
||||||
|
|
||||||
|
|||||||
@@ -22,3 +22,28 @@ Disabled integration commands (`spwin`, `tab`, `split`, `hist`, `logs`, `upgrade
|
|||||||
a colored error to stderr naming the variable that disabled them rather than
|
a colored error to stderr naming the variable that disabled them rather than
|
||||||
silently failing.
|
silently failing.
|
||||||
|
|
||||||
|
## Sub-categories
|
||||||
|
|
||||||
|
`__fish_config_op_integrations` sub-divides into five sub-categories,
|
||||||
|
each with its own `__fish_config_op_integrations_<slug>` toggle:
|
||||||
|
|
||||||
|
## terminal-abbrs
|
||||||
|
|
||||||
|
The Kitty/WezTerm abbreviation set.
|
||||||
|
|
||||||
|
## window-mgmt
|
||||||
|
|
||||||
|
`spwin`, `tab`, `split`.
|
||||||
|
|
||||||
|
## notifications
|
||||||
|
|
||||||
|
`done`'s completion notifications, and the WakaTime activity hook.
|
||||||
|
|
||||||
|
## history-logs
|
||||||
|
|
||||||
|
`hist`, `logs`.
|
||||||
|
|
||||||
|
## pkg-upgrade
|
||||||
|
|
||||||
|
`upgrade`.
|
||||||
|
|
||||||
|
|||||||
@@ -112,3 +112,22 @@ Note: C3 and C5 compose independently. C3 controls whether the smart_exit
|
|||||||
wrapper is active at all; C5 controls only the scrollback-capture block
|
wrapper is active at all; C5 controls only the scrollback-capture block
|
||||||
inside it. With C3 disabled, exit is plain builtin exit regardless of C5.
|
inside it. With C3 disabled, exit is plain builtin exit regardless of C5.
|
||||||
|
|
||||||
|
## Sub-categories
|
||||||
|
|
||||||
|
`__fish_config_op_logging` sub-divides into three sub-categories, each
|
||||||
|
with its own `__fish_config_op_logging_<slug>` toggle (all still opt-in
|
||||||
|
by default, inherited from C5's own opt-in behavior -- see §3 of the
|
||||||
|
design spec):
|
||||||
|
|
||||||
|
## terminal-capture
|
||||||
|
|
||||||
|
Kitty watcher scrollback capture, and `smart_exit`'s logging-guard path.
|
||||||
|
|
||||||
|
## multiplexer-capture
|
||||||
|
|
||||||
|
tmux `pipe-pane` and zellij `dump-screen` capture.
|
||||||
|
|
||||||
|
## pkg-logs
|
||||||
|
|
||||||
|
`paru`/`yay` AUR log wrappers.
|
||||||
|
|
||||||
|
|||||||
@@ -13,3 +13,16 @@ When C6 is disabled, no greeting is printed by this config. Any greeting
|
|||||||
set by the distro or other configs runs normally — this config simply does
|
set by the distro or other configs runs normally — this config simply does
|
||||||
not override it.
|
not override it.
|
||||||
|
|
||||||
|
## Sub-categories
|
||||||
|
|
||||||
|
`__fish_config_op_greeting` sub-divides into two sub-categories, each
|
||||||
|
with its own `__fish_config_op_greeting_<slug>` toggle:
|
||||||
|
|
||||||
|
## first-run
|
||||||
|
|
||||||
|
The first-run welcome banner.
|
||||||
|
|
||||||
|
## greeting-message
|
||||||
|
|
||||||
|
The per-session `fish_greeting` override.
|
||||||
|
|
||||||
|
|||||||
@@ -18,3 +18,18 @@ category variable.
|
|||||||
C4 [Integrations](/08-components-reference/04-c4-terminal-and-tool-integration/) — Kitty/Wezterm integrations, starship hooks, fzf theme
|
C4 [Integrations](/08-components-reference/04-c4-terminal-and-tool-integration/) — Kitty/Wezterm integrations, starship hooks, fzf theme
|
||||||
C5 [Logging and Capture](/08-components-reference/05-c5-logging-and-capture/) — Session logs, command duration
|
C5 [Logging and Capture](/08-components-reference/05-c5-logging-and-capture/) — Session logs, command duration
|
||||||
C6 [Greeting & First-Run UI](/08-components-reference/06-c6-greeting-and-first-run-ui/) — Custom startup banner
|
C6 [Greeting & First-Run UI](/08-components-reference/06-c6-greeting-and-first-run-ui/) — Custom startup banner
|
||||||
|
|
||||||
|
Each category further sub-divides into two to six sub-categories (24 in
|
||||||
|
total) with their own `__fish_config_op_<category>_<subcategory>` toggles
|
||||||
|
-- see that category's page for its sub-category list.
|
||||||
|
|
||||||
|
## Per-function overrides: `C0`/`always`
|
||||||
|
|
||||||
|
Every guarded function or file can also carry a reserved `always/on` or
|
||||||
|
`always/off` tag in its `# COMPONENT` header, independent of every C1-C6
|
||||||
|
category and sub-category toggle and invisible to `config-settings`. An
|
||||||
|
`always/off` tag disables that function unconditionally; an `always/on`
|
||||||
|
tag enables it unconditionally, ignoring the state of every other tagged
|
||||||
|
sub-category. This is a per-function escape hatch for cases too granular
|
||||||
|
or too idiosyncratic to justify a taxonomy entry -- edit the header
|
||||||
|
directly and run `__fish_config_op_registry_rebuild` to apply the change.
|
||||||
|
|||||||
@@ -237,6 +237,13 @@ Re-enable everything:
|
|||||||
|
|
||||||
set -Ue __fish_config_opinionated
|
set -Ue __fish_config_opinionated
|
||||||
|
|
||||||
|
Each category also has two to six sub-categories (e.g.
|
||||||
|
`__fish_config_op_aliases_filesystem`) that can be checked, disabled, or
|
||||||
|
reset the same way — `set -U __fish_config_op_<category>_<subcategory> off`
|
||||||
|
and `set -Ue __fish_config_op_<category>_<subcategory>` work identically to
|
||||||
|
the category-level recipes above, just one level more granular. See
|
||||||
|
[Components Reference](/08-components-reference/) for the full list.
|
||||||
|
|
||||||
For an interactive alternative to setting these variables by hand, run `config-settings`.
|
For an interactive alternative to setting these variables by hand, run `config-settings`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+72
-5
@@ -62,6 +62,7 @@ HEADER_LABEL = re.compile(r"^#\s+([A-Z][A-Z ]*[A-Z])\s*$")
|
|||||||
FUNC_DEF = re.compile(r"^\s*function\s+(\S+)")
|
FUNC_DEF = re.compile(r"^\s*function\s+(\S+)")
|
||||||
SECTIONS = (
|
SECTIONS = (
|
||||||
"CATEGORY",
|
"CATEGORY",
|
||||||
|
"COMPONENT",
|
||||||
"DEPENDENCIES",
|
"DEPENDENCIES",
|
||||||
"SYNOPSIS",
|
"SYNOPSIS",
|
||||||
"DESCRIPTION",
|
"DESCRIPTION",
|
||||||
@@ -109,6 +110,19 @@ def _trailing_blanks(lines: list[str]) -> int:
|
|||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
def _block_identity(path: Path, lines: list[str], end: int, blocks_count: int) -> str:
|
||||||
|
"""Resolve a header block's associated name.
|
||||||
|
|
||||||
|
A file carrying exactly one header is associated with its own stem, so
|
||||||
|
a `function` nested inside a `type -q` guard still resolves. A file
|
||||||
|
with several headers walks forward to the next `function` definition.
|
||||||
|
"""
|
||||||
|
if blocks_count == 1:
|
||||||
|
return path.stem
|
||||||
|
after = (m.group(1) for ln in lines[end:] if (m := FUNC_DEF.match(ln)))
|
||||||
|
return next(after, path.stem)
|
||||||
|
|
||||||
|
|
||||||
def parse_functions(root: Path) -> dict[str, dict[str, list[str]]]:
|
def parse_functions(root: Path) -> dict[str, dict[str, list[str]]]:
|
||||||
"""Parse the comment header above every documented public function.
|
"""Parse the comment header above every documented public function.
|
||||||
|
|
||||||
@@ -128,11 +142,7 @@ def parse_functions(root: Path) -> dict[str, dict[str, list[str]]]:
|
|||||||
lines = path.read_text(encoding="utf-8").split("\n")
|
lines = path.read_text(encoding="utf-8").split("\n")
|
||||||
blocks = _header_blocks(lines)
|
blocks = _header_blocks(lines)
|
||||||
for end, sections in blocks:
|
for end, sections in blocks:
|
||||||
if len(blocks) == 1:
|
name = _block_identity(path, lines, end, len(blocks))
|
||||||
name = path.stem
|
|
||||||
else:
|
|
||||||
after = (m.group(1) for ln in lines[end:] if (m := FUNC_DEF.match(ln)))
|
|
||||||
name = next(after, path.stem)
|
|
||||||
if name.startswith("_") or "CATEGORY" not in sections:
|
if name.startswith("_") or "CATEGORY" not in sections:
|
||||||
continue
|
continue
|
||||||
out[name] = {
|
out[name] = {
|
||||||
@@ -185,6 +195,63 @@ def parse_abbreviations(root: Path) -> dict[str, list[dict]]:
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
SITE_LINE_RE = re.compile(r"^site\s+(\S+):\s*(\S+)$")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_component_lines(lines: list[str]) -> list[tuple[str, str]]:
|
||||||
|
"""Parse raw `# COMPONENT` body lines into (site, tag) pairs.
|
||||||
|
|
||||||
|
A line of the form `site <slug>: <tag>` scopes <tag> to that site; a
|
||||||
|
bare `<tag>` line belongs to the default (unnamed) site, keyed "".
|
||||||
|
Blank lines are skipped.
|
||||||
|
"""
|
||||||
|
out: list[tuple[str, str]] = []
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
m = SITE_LINE_RE.match(line)
|
||||||
|
if m:
|
||||||
|
out.append((m.group(1), m.group(2)))
|
||||||
|
else:
|
||||||
|
out.append(("", line))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_component_blocks(path: Path) -> dict[str, list[str]]:
|
||||||
|
"""Parse every `# COMPONENT` header block in one file.
|
||||||
|
|
||||||
|
Unlike parse_functions, there is no `# CATEGORY` gate and no
|
||||||
|
underscore exclusion: component classification applies to every
|
||||||
|
function/script, public or private, documented in the manual or not
|
||||||
|
-- the registry needs to see every guarded identity, not just the
|
||||||
|
ones that appear in the public function reference.
|
||||||
|
"""
|
||||||
|
lines = path.read_text(encoding="utf-8").split("\n")
|
||||||
|
blocks = _header_blocks(lines)
|
||||||
|
out: dict[str, list[str]] = {}
|
||||||
|
for end, sections in blocks:
|
||||||
|
if "COMPONENT" not in sections:
|
||||||
|
continue
|
||||||
|
name = _block_identity(path, lines, end, len(blocks))
|
||||||
|
body = sections["COMPONENT"]
|
||||||
|
out[name] = body[: len(body) - _trailing_blanks(body)]
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def parse_component_file(path: Path) -> dict[str, list[str]]:
|
||||||
|
"""Parse `# COMPONENT` header block(s) in one specific file (e.g. config.fish)."""
|
||||||
|
return _parse_component_blocks(path)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_components(root: Path) -> dict[str, list[str]]:
|
||||||
|
"""Parse `# COMPONENT` header blocks across every `*.fish` file under root."""
|
||||||
|
out: dict[str, list[str]] = {}
|
||||||
|
for path in sorted(root.glob("*.fish")):
|
||||||
|
out.update(_parse_component_blocks(path))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
def _sort_key(entry: Path) -> tuple:
|
def _sort_key(entry: Path) -> tuple:
|
||||||
"""Order by sidebar.order when present, else by filename. Stable."""
|
"""Order by sidebar.order when present, else by filename. Stable."""
|
||||||
target = entry / "index.md" if entry.is_dir() else entry
|
target = entry / "index.md" if entry.is_dir() else entry
|
||||||
|
|||||||
@@ -130,6 +130,38 @@ def _parsed_functions() -> dict[str, dict[str, list[str]]]:
|
|||||||
return mt.parse_functions(Path(__file__).parent.parent / "functions")
|
return mt.parse_functions(Path(__file__).parent.parent / "functions")
|
||||||
|
|
||||||
|
|
||||||
|
def _parsed_components() -> dict[str, list[str]]:
|
||||||
|
import generate_component_registry as gcr
|
||||||
|
|
||||||
|
return gcr.collect_components()
|
||||||
|
|
||||||
|
|
||||||
|
_C0_TAGS = {"always/on", "always/off"}
|
||||||
|
_TAXONOMY_FILES = {
|
||||||
|
"aliases": "01-c1-command-shadows.md",
|
||||||
|
"autoexec": "02-c2-startup-side-effects.md",
|
||||||
|
"overrides": "03-c3-key-and-environment-overrides.md",
|
||||||
|
"integrations": "04-c4-terminal-and-tool-integration.md",
|
||||||
|
"logging": "05-c5-logging-and-capture.md",
|
||||||
|
"greeting": "06-c6-greeting-and-first-run-ui.md",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _load_taxonomy() -> dict[str, set[str]]:
|
||||||
|
"""{category: {sub-category slugs}}, parsed from `## <slug>` headings
|
||||||
|
in each category's docs/manual/08-components-reference/ file."""
|
||||||
|
ref_root = Path(__file__).parent / "manual" / "08-components-reference"
|
||||||
|
taxonomy: dict[str, set[str]] = {}
|
||||||
|
for category, filename in _TAXONOMY_FILES.items():
|
||||||
|
_, body = mt.parse(ref_root / filename)
|
||||||
|
taxonomy[category] = {
|
||||||
|
m.group(1)
|
||||||
|
for ln in body.split("\n")
|
||||||
|
if (m := re.match(r"^## ([a-z][a-z0-9-]*)$", ln))
|
||||||
|
}
|
||||||
|
return taxonomy
|
||||||
|
|
||||||
|
|
||||||
def test_every_categorised_function_produces_one_entry():
|
def test_every_categorised_function_produces_one_entry():
|
||||||
import build_manual
|
import build_manual
|
||||||
|
|
||||||
@@ -184,6 +216,36 @@ def test_dependencies_resolve():
|
|||||||
assert not dangling, "unresolvable # DEPENDENCIES:\n " + "\n ".join(dangling)
|
assert not dangling, "unresolvable # DEPENDENCIES:\n " + "\n ".join(dangling)
|
||||||
|
|
||||||
|
|
||||||
|
def test_every_component_resolves_to_a_taxonomy_entry():
|
||||||
|
"""Every non-C0 # COMPONENT tag must resolve to a documented sub-category."""
|
||||||
|
taxonomy = _load_taxonomy()
|
||||||
|
unknown = []
|
||||||
|
for identity, raw_lines in _parsed_components().items():
|
||||||
|
for site, tag in mt.parse_component_lines(raw_lines):
|
||||||
|
if tag in _C0_TAGS:
|
||||||
|
continue
|
||||||
|
if "/" not in tag:
|
||||||
|
unknown.append(f"{identity}: malformed tag {tag!r}")
|
||||||
|
continue
|
||||||
|
category, subcat = tag.split("/", 1)
|
||||||
|
if category not in taxonomy or subcat not in taxonomy[category]:
|
||||||
|
unknown.append(f"{identity}: {tag}")
|
||||||
|
assert not unknown, "# COMPONENT tags with no taxonomy entry:\n " + "\n ".join(unknown)
|
||||||
|
|
||||||
|
|
||||||
|
def warn_c0_tags_never_combine_with_contradiction():
|
||||||
|
"""Warn -- never fail -- on always/on + always/off contradictions this
|
||||||
|
repo's own generator would warn about -- this is a direct repo-content
|
||||||
|
check, independent of running the generator, so CI surfaces them even
|
||||||
|
if someone forgets to regenerate. Warnings are non-fatal (spec §4.5);
|
||||||
|
this exists to print them prominently in CI output."""
|
||||||
|
from generate_component_registry import build_registry
|
||||||
|
|
||||||
|
_, warnings = build_registry(_parsed_components())
|
||||||
|
for w in warnings:
|
||||||
|
print(f" WARN {w}")
|
||||||
|
|
||||||
|
|
||||||
def warn_public_functions_without_category():
|
def warn_public_functions_without_category():
|
||||||
"""Warn — never fail — on a public function carrying no `# CATEGORY`.
|
"""Warn — never fail — on a public function carrying no `# CATEGORY`.
|
||||||
|
|
||||||
@@ -205,6 +267,63 @@ def warn_public_functions_without_category():
|
|||||||
print(" " + ", ".join(orphans))
|
print(" " + ", ".join(orphans))
|
||||||
|
|
||||||
|
|
||||||
|
# The guard's own supporting infrastructure: these files' bodies (function
|
||||||
|
# signature, SYNOPSIS/EXAMPLE prose) legitimately contain the literal text
|
||||||
|
# "__fish_config_op_enabled" without being a *caller* of the guard, so they
|
||||||
|
# are permanently exempt from warn_functions_without_component's substring
|
||||||
|
# check below.
|
||||||
|
_GUARD_INFRA_FILES = {
|
||||||
|
"__fish_config_op_enabled.fish",
|
||||||
|
"__fish_config_op_cascade.fish",
|
||||||
|
"__fish_config_op_registry_lookup.fish",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def warn_functions_without_component():
|
||||||
|
"""Warn -- never fail -- on a documented function calling the
|
||||||
|
opinionated guard but carrying no `# COMPONENT` section.
|
||||||
|
|
||||||
|
Mirrors warn_public_functions_without_category: a function that never
|
||||||
|
opted into the header convention at all (no # SYNOPSIS) is silently
|
||||||
|
out of scope, matching spec §4.5's fail-open tiering.
|
||||||
|
"""
|
||||||
|
repo = Path(__file__).parent.parent
|
||||||
|
components = _parsed_components()
|
||||||
|
orphans = []
|
||||||
|
for p in list((repo / "functions").glob("*.fish")) + list((repo / "conf.d").glob("*.fish")):
|
||||||
|
if p.name in _GUARD_INFRA_FILES:
|
||||||
|
continue
|
||||||
|
text = p.read_text(encoding="utf-8")
|
||||||
|
if "__fish_config_op_enabled" not in text or "# SYNOPSIS" not in text:
|
||||||
|
continue
|
||||||
|
if p.stem not in components:
|
||||||
|
orphans.append(str(p.relative_to(repo)))
|
||||||
|
if orphans:
|
||||||
|
print(f" WARN {len(orphans)} function(s) call the opinionated guard but lack # COMPONENT:")
|
||||||
|
print(" " + ", ".join(sorted(orphans)))
|
||||||
|
|
||||||
|
|
||||||
|
def warn_unused_taxonomy_entries():
|
||||||
|
"""Warn -- never fail -- on a documented sub-category with zero tagged functions."""
|
||||||
|
taxonomy = _load_taxonomy()
|
||||||
|
used: dict[str, set[str]] = {c: set() for c in taxonomy}
|
||||||
|
for raw_lines in _parsed_components().values():
|
||||||
|
for _site, tag in mt.parse_component_lines(raw_lines):
|
||||||
|
if tag in _C0_TAGS or "/" not in tag:
|
||||||
|
continue
|
||||||
|
category, subcat = tag.split("/", 1)
|
||||||
|
if category in used:
|
||||||
|
used[category].add(subcat)
|
||||||
|
unused = [
|
||||||
|
f"{category}/{subcat}"
|
||||||
|
for category, subcats in taxonomy.items()
|
||||||
|
for subcat in sorted(subcats - used[category])
|
||||||
|
]
|
||||||
|
if unused:
|
||||||
|
print(f" WARN {len(unused)} taxonomy entr{'y has' if len(unused) == 1 else 'ies have'} zero tagged functions:")
|
||||||
|
print(" " + ", ".join(unused))
|
||||||
|
|
||||||
|
|
||||||
def _without_section_5(text: str) -> str:
|
def _without_section_5(text: str) -> str:
|
||||||
"""Drop `# 5. FUNCTIONS REFERENCE` through the start of section 6.
|
"""Drop `# 5. FUNCTIONS REFERENCE` through the start of section 6.
|
||||||
|
|
||||||
@@ -827,6 +946,207 @@ def test_site_avoids_reserved_dir():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_component_lines_default_and_named_sites():
|
||||||
|
lines = [
|
||||||
|
"aliases/filesystem",
|
||||||
|
"site exit-plain: overrides/key-bindings",
|
||||||
|
"site logging-guard: logging/terminal-capture",
|
||||||
|
"",
|
||||||
|
" ",
|
||||||
|
]
|
||||||
|
got = mt.parse_component_lines(lines)
|
||||||
|
assert got == [
|
||||||
|
("", "aliases/filesystem"),
|
||||||
|
("exit-plain", "overrides/key-bindings"),
|
||||||
|
("logging-guard", "logging/terminal-capture"),
|
||||||
|
], f"unexpected parse: {got}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_components_includes_underscore_prefixed_and_uncategorised():
|
||||||
|
"""Unlike parse_functions, parse_components has no # CATEGORY gate and
|
||||||
|
no underscore exclusion -- every guarded identity must be visible."""
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
root = Path(d)
|
||||||
|
(root / "__private_helper.fish").write_text(
|
||||||
|
"# COMPONENT\n"
|
||||||
|
"# logging/terminal-capture\n"
|
||||||
|
"function __private_helper\n"
|
||||||
|
"end\n"
|
||||||
|
)
|
||||||
|
(root / "no_category.fish").write_text(
|
||||||
|
"# COMPONENT\n"
|
||||||
|
"# aliases/filesystem\n"
|
||||||
|
"#\n"
|
||||||
|
"# SYNOPSIS\n"
|
||||||
|
"# no_category\n"
|
||||||
|
"function no_category\n"
|
||||||
|
"end\n"
|
||||||
|
)
|
||||||
|
got = mt.parse_components(root)
|
||||||
|
assert got["__private_helper"] == ["logging/terminal-capture"]
|
||||||
|
assert got["no_category"] == ["aliases/filesystem"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_components_resolves_multi_header_file_to_function_name():
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
root = Path(d)
|
||||||
|
(root / "multi.fish").write_text(
|
||||||
|
"# COMPONENT\n"
|
||||||
|
"# aliases/filesystem\n"
|
||||||
|
"function first_fn\n"
|
||||||
|
"end\n"
|
||||||
|
"\n"
|
||||||
|
"# COMPONENT\n"
|
||||||
|
"# aliases/network\n"
|
||||||
|
"function second_fn\n"
|
||||||
|
"end\n"
|
||||||
|
)
|
||||||
|
got = mt.parse_components(root)
|
||||||
|
assert got == {
|
||||||
|
"first_fn": ["aliases/filesystem"],
|
||||||
|
"second_fn": ["aliases/network"],
|
||||||
|
}, f"unexpected resolution: {got}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_component_file_single_file():
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
path = Path(d) / "config.fish"
|
||||||
|
path.write_text(
|
||||||
|
"# COMPONENT\n"
|
||||||
|
"# site greeting-block: greeting/greeting-message\n"
|
||||||
|
)
|
||||||
|
got = mt.parse_component_file(path)
|
||||||
|
assert got == {"config": ["site greeting-block: greeting/greeting-message"]}
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_registry_strips_on_off_contradiction_with_warning():
|
||||||
|
import generate_component_registry as gcr
|
||||||
|
|
||||||
|
components = {"contradictory_fn": ["always/on", "always/off", "aliases/filesystem"]}
|
||||||
|
registry, warnings = gcr.build_registry(components)
|
||||||
|
assert registry["contradictory_fn:"] == ["aliases/filesystem"], (
|
||||||
|
f"the non-contradictory tag should survive: {registry}"
|
||||||
|
)
|
||||||
|
assert len(warnings) == 1 and "contradictory_fn" in warnings[0]
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_registry_drops_empty_effective_tag_sets():
|
||||||
|
import generate_component_registry as gcr
|
||||||
|
|
||||||
|
components = {"only_contradictory": ["always/on", "always/off"]}
|
||||||
|
registry, warnings = gcr.build_registry(components)
|
||||||
|
assert "only_contradictory:" not in registry, (
|
||||||
|
"a site stripped down to nothing must produce no registry entry "
|
||||||
|
"(fail-open: absence of an entry already means always/on at guard time)"
|
||||||
|
)
|
||||||
|
assert len(warnings) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_registry_keeps_sites_independent():
|
||||||
|
import generate_component_registry as gcr
|
||||||
|
|
||||||
|
components = {
|
||||||
|
"smart_exit": [
|
||||||
|
"site exit-plain: overrides/key-bindings",
|
||||||
|
"site logging-guard: logging/terminal-capture",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
registry, warnings = gcr.build_registry(components)
|
||||||
|
assert registry["smart_exit:exit-plain"] == ["overrides/key-bindings"]
|
||||||
|
assert registry["smart_exit:logging-guard"] == ["logging/terminal-capture"]
|
||||||
|
assert not warnings
|
||||||
|
|
||||||
|
|
||||||
|
def test_collect_components_merges_identity_collisions_across_sources():
|
||||||
|
"""functions/auto-pull.fish and conf.d/auto-pull.fish both self-identify
|
||||||
|
as "auto-pull" at runtime -- the guard only ever has the bare
|
||||||
|
status current-function/basename string to look up with -- so
|
||||||
|
collect_components must concatenate their raw COMPONENT lines
|
||||||
|
rather than letting conf.d's entry silently overwrite functions'."""
|
||||||
|
import generate_component_registry as gcr
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
root = Path(d)
|
||||||
|
(root / "functions").mkdir()
|
||||||
|
(root / "conf.d").mkdir()
|
||||||
|
(root / "functions" / "auto-pull.fish").write_text(
|
||||||
|
"# COMPONENT\n"
|
||||||
|
"# autoexec/sync\n"
|
||||||
|
"function auto-pull\n"
|
||||||
|
"end\n"
|
||||||
|
)
|
||||||
|
(root / "conf.d" / "auto-pull.fish").write_text(
|
||||||
|
"# COMPONENT\n"
|
||||||
|
"# autoexec/sync\n"
|
||||||
|
)
|
||||||
|
(root / "config.fish").write_text("")
|
||||||
|
|
||||||
|
orig_repo = gcr.REPO
|
||||||
|
try:
|
||||||
|
gcr.REPO = root
|
||||||
|
got = gcr.collect_components()
|
||||||
|
finally:
|
||||||
|
gcr.REPO = orig_repo
|
||||||
|
|
||||||
|
assert got["auto-pull"] == ["autoexec/sync", "autoexec/sync"], (
|
||||||
|
f"both sources' tags should survive the merge, not overwrite: {got}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_render_registry_is_valid_fish_and_round_trips():
|
||||||
|
"""Sourcing render()'s output must leave the two arrays in the exact
|
||||||
|
shape __fish_config_op_registry_lookup expects -- checked via the real
|
||||||
|
lookup helper (functions/__fish_config_op_registry_lookup.fish, Task
|
||||||
|
2) rather than re-parsing the generated text by hand."""
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import generate_component_registry as gcr
|
||||||
|
|
||||||
|
registry = {
|
||||||
|
"rm:": ["aliases/filesystem"],
|
||||||
|
"smart_exit:exit-plain": ["overrides/key-bindings"],
|
||||||
|
}
|
||||||
|
text = gcr.render(registry)
|
||||||
|
|
||||||
|
repo = Path(__file__).parent.parent
|
||||||
|
proc = subprocess.run(
|
||||||
|
[
|
||||||
|
"fish", "-c",
|
||||||
|
f"source {repo}/functions/__fish_config_op_registry_lookup.fish; "
|
||||||
|
"source /dev/stdin; "
|
||||||
|
"__fish_config_op_registry_lookup rm ''; echo status=$status",
|
||||||
|
],
|
||||||
|
input=text,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
assert "aliases/filesystem" in proc.stdout, f"unexpected output: {proc.stdout!r} {proc.stderr!r}"
|
||||||
|
assert "status=0" in proc.stdout, f"lookup did not report found: {proc.stdout!r}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_manual_regenerates_registry_before_building():
|
||||||
|
"""docs/build-manual.py must regenerate the registry as a pre-step."""
|
||||||
|
import build_manual
|
||||||
|
|
||||||
|
assert hasattr(build_manual, "generate_component_registry"), (
|
||||||
|
"build-manual.py must import generate_component_registry so its "
|
||||||
|
"main() can be called as a pre-step before --site/--concat run"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_committed_registry_matches_headers():
|
||||||
|
"""The committed conf.d/__fish_config_op_registry.fish must match what
|
||||||
|
generate_component_registry.py would produce right now from the current
|
||||||
|
`# COMPONENT` headers -- otherwise CI has nothing catching drift."""
|
||||||
|
import generate_component_registry as gcr
|
||||||
|
|
||||||
|
registry, _ = gcr.build_registry(gcr.collect_components())
|
||||||
|
assert gcr.render(registry) == gcr.OUTPUT.read_text(), (
|
||||||
|
"conf.d/__fish_config_op_registry.fish is stale — run "
|
||||||
|
"__fish_config_op_registry_rebuild"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
TESTS = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
|
TESTS = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
|
||||||
|
|
||||||
|
|
||||||
@@ -840,6 +1160,9 @@ def main() -> int:
|
|||||||
print(f" FAIL {t.__name__}: {e}", file=sys.stderr)
|
print(f" FAIL {t.__name__}: {e}", file=sys.stderr)
|
||||||
failed += 1
|
failed += 1
|
||||||
warn_public_functions_without_category()
|
warn_public_functions_without_category()
|
||||||
|
warn_functions_without_component()
|
||||||
|
warn_unused_taxonomy_entries()
|
||||||
|
warn_c0_tags_never_combine_with_contradiction()
|
||||||
print(f"\n{len(TESTS) - failed}/{len(TESTS)} passed")
|
print(f"\n{len(TESTS) - failed}/{len(TESTS)} passed")
|
||||||
return 1 if failed else 0
|
return 1 if failed else 0
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# autoexec/venv
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# __auto_source_fallback_venv
|
# __auto_source_fallback_venv
|
||||||
#
|
#
|
||||||
@@ -16,7 +19,7 @@ function __auto_source_fallback_venv --on-variable PWD
|
|||||||
status --is-command-substitution; and return
|
status --is-command-substitution; and return
|
||||||
|
|
||||||
# Opinionated guard (C2): no automatic venv activation when disabled.
|
# Opinionated guard (C2): no automatic venv activation when disabled.
|
||||||
__fish_config_op_enabled __fish_config_op_autoexec; or return
|
__fish_config_op_enabled (status current-function); or return
|
||||||
|
|
||||||
# 1. Skip if direnv is already managing this directory
|
# 1. Skip if direnv is already managing this directory
|
||||||
if set -q DIRENV_DIR; or test -e ".envrc"
|
if set -q DIRENV_DIR; or test -e ".envrc"
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ function __config_settings_draw
|
|||||||
|
|
||||||
# ── Keybind hint ──────────────────────────────────────────────────────
|
# ── Keybind hint ──────────────────────────────────────────────────────
|
||||||
# string pad is width-aware (arrows count as 1 column)
|
# string pad is width-aware (arrows count as 1 column)
|
||||||
set -l hint " ↑↓/kj move ←→/hl set Tab page q quit"
|
set -l hint " ↑↓/kj move ←→/hl set Enter sub-cats Tab pg q quit"
|
||||||
printf '%s│%s%s%s│\n' $p $c_dim (string pad -r -w $iw -- $hint) $c_reset
|
printf '%s│%s%s%s│\n' $p $c_dim (string pad -r -w $iw -- $hint) $c_reset
|
||||||
|
|
||||||
# ── Bottom border ─────────────────────────────────────────────────────
|
# ── Bottom border ─────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
# __config_settings_draw_subcat <cur_row> <cur_scope> <category_var>
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Renders the sub-category drill-down page for one C1-C6 category:
|
||||||
|
# the category's own toggle at the top (still meaningful as the cascade
|
||||||
|
# default for its sub-categories), then one row per sub-category from
|
||||||
|
# __config_settings_subcats, sized dynamically instead of the fixed
|
||||||
|
# 6-row layout __config_settings_draw uses for the category list.
|
||||||
|
# Follows the same width-tier and center-padding conventions as
|
||||||
|
# __config_settings_draw so the panel doesn't visibly jump between the
|
||||||
|
# two pages.
|
||||||
|
#
|
||||||
|
# Label and description fields are defensively truncated to their field
|
||||||
|
# width before padding (string pad only ever grows a string, never
|
||||||
|
# shrinks it) -- sub-category labels/descriptions are static data from
|
||||||
|
# __config_settings_subcats, not authored per width-tier the way
|
||||||
|
# __config_settings_draw's own category descriptions are, so a couple of
|
||||||
|
# them are longer than the narrower tiers' fields (e.g. "Notifications"
|
||||||
|
# is 13 chars against a 12-char label field; several descriptions run
|
||||||
|
# well past the 17-char field at the narrowest tier). Truncating keeps
|
||||||
|
# the box perfectly rectangular in every case instead of only in the
|
||||||
|
# cases the static text happens to fit.
|
||||||
|
#
|
||||||
|
# ARGUMENTS
|
||||||
|
# cur_row 0-based highlighted row (0 = the category's own toggle;
|
||||||
|
# 1..N = sub-category rows)
|
||||||
|
# cur_scope "universal" or "session"
|
||||||
|
# category_var One of the six __fish_config_op_<category> names
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 Always
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# __config_settings_draw_subcat 1 universal __fish_config_op_aliases
|
||||||
|
function __config_settings_draw_subcat
|
||||||
|
set -l cur_row $argv[1]
|
||||||
|
set -l cur_scope $argv[2]
|
||||||
|
set -l category_var $argv[3]
|
||||||
|
|
||||||
|
set -l c_ok (set_color green)
|
||||||
|
set -l c_err (set_color red)
|
||||||
|
set -l c_dim (set_color brblack)
|
||||||
|
set -l c_sel (set_color --bold magenta)
|
||||||
|
set -l c_head (set_color --bold cyan)
|
||||||
|
set -l c_reset (set_color normal)
|
||||||
|
|
||||||
|
set -l rows (__config_settings_subcats $category_var)
|
||||||
|
set -l n (count $rows)
|
||||||
|
|
||||||
|
# ── Width tier: matches __config_settings_draw's 6-col-per-side steps ──
|
||||||
|
set -l iw 50
|
||||||
|
if test "$COLUMNS" -ge 90
|
||||||
|
set iw 76
|
||||||
|
else if test "$COLUMNS" -ge 86
|
||||||
|
set iw 72
|
||||||
|
else if test "$COLUMNS" -ge 82
|
||||||
|
set iw 68
|
||||||
|
end
|
||||||
|
set -l HBR (string repeat -n $iw '─')
|
||||||
|
set -l p (string repeat -n (math --scale=0 "max(0, ($COLUMNS - ($iw + 2)) / 2)") ' ')
|
||||||
|
|
||||||
|
# Label field is 13 wide (one wider than __config_settings_draw's 12) --
|
||||||
|
# the longest real sub-category label ("Notifications") is 13 chars.
|
||||||
|
# Description field absorbs the difference so every row still totals
|
||||||
|
# iw+2, matching the surrounding box lines exactly.
|
||||||
|
set -l label_w 13
|
||||||
|
set -l desc_w (math $iw - 34)
|
||||||
|
|
||||||
|
set -l cat_label (string replace -r '^__fish_config_op_' '' -- $category_var)
|
||||||
|
# Scope indicator: toggling a row on this page writes -U (Universal,
|
||||||
|
# persistent) or -g (Session, this-shell-only) -- the title must say
|
||||||
|
# which, since it isn't otherwise visible anywhere on the page.
|
||||||
|
set -l scope_label Universal
|
||||||
|
test "$cur_scope" = session; and set scope_label Session
|
||||||
|
# Title layout is "┌─ Sub-categories: <label> (<scope>) ───┐"; the
|
||||||
|
# dash count must absorb every visible char added around cat_label so
|
||||||
|
# the line still totals iw+2, matching the surrounding box exactly --
|
||||||
|
# see the DESCRIPTION doc comment above for why this is hand-verified,
|
||||||
|
# not eyeballed.
|
||||||
|
set -l title_dashes (math $iw - (string length -- $cat_label) - (string length -- $scope_label) - 22)
|
||||||
|
printf '%s┌─%s Sub-categories: %s (%s)%s %s┐\n' \
|
||||||
|
$p $c_head "$cat_label" $scope_label "$c_reset" (string repeat -n (math "max(0, $title_dashes)") '─')
|
||||||
|
|
||||||
|
printf '%s│%s│\n' $p $HBR
|
||||||
|
|
||||||
|
# Row 0: the category's own toggle, still meaningful as the cascade
|
||||||
|
# default any DEFAULT-valued sub-category below falls back to.
|
||||||
|
set -l cat_val (__config_settings_get_val $category_var $cur_scope)
|
||||||
|
set -l cat_badge
|
||||||
|
switch $cat_val
|
||||||
|
case on
|
||||||
|
set cat_badge "$c_ok"" ON$c_reset"
|
||||||
|
case off
|
||||||
|
set cat_badge "$c_err""OFF $c_reset"
|
||||||
|
case '*'
|
||||||
|
set cat_badge "$c_dim""DEFAULT$c_reset"
|
||||||
|
end
|
||||||
|
set -l cat_curs " "
|
||||||
|
if test $cur_row -eq 0
|
||||||
|
set cat_curs "$c_sel▶$c_reset "
|
||||||
|
end
|
||||||
|
set -l cat_desc "cascade default"
|
||||||
|
if test $iw -ge 68
|
||||||
|
set cat_desc "default for all sub-cats below"
|
||||||
|
end
|
||||||
|
if test $iw -ge 72
|
||||||
|
set cat_desc "default for all sub-categories below"
|
||||||
|
end
|
||||||
|
printf '%s│ %s%s [ %s ] %s │\n' $p $cat_curs \
|
||||||
|
(string pad -r -w $label_w -- "(category)") $cat_badge \
|
||||||
|
(string pad -r -w $desc_w -- (string sub -l $desc_w -- $cat_desc))
|
||||||
|
|
||||||
|
printf '%s│ %s │\n' $p (string repeat -n (math $iw - 6) '─')
|
||||||
|
|
||||||
|
for i in (seq 1 $n)
|
||||||
|
set -l fields (string split -- \t $rows[$i])
|
||||||
|
set -l slug $fields[1]
|
||||||
|
set -l label $fields[2]
|
||||||
|
set -l desc $fields[3]
|
||||||
|
set -l subcat_var "$category_var"_(string replace -a -- '-' '_' $slug)
|
||||||
|
|
||||||
|
set -l val (__config_settings_get_val $subcat_var $cur_scope)
|
||||||
|
set -l badge
|
||||||
|
switch $val
|
||||||
|
case on
|
||||||
|
set badge "$c_ok"" ON$c_reset"
|
||||||
|
case off
|
||||||
|
set badge "$c_err""OFF $c_reset"
|
||||||
|
case '*'
|
||||||
|
set badge "$c_dim""DEFAULT$c_reset"
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l curs " "
|
||||||
|
if test $i -eq $cur_row
|
||||||
|
set curs "$c_sel▶$c_reset "
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l lpad (string pad -r -w $label_w -- (string sub -l $label_w -- $label))
|
||||||
|
set -l dpad (string pad -r -w $desc_w -- (string sub -l $desc_w -- $desc))
|
||||||
|
printf '%s│ %s%s [ %s ] %s │\n' $p $curs $lpad $badge $dpad
|
||||||
|
end
|
||||||
|
|
||||||
|
printf '%s│%s│\n' $p $HBR
|
||||||
|
set -l hint " ↑↓/kj move ←→/hl set Esc back q quit"
|
||||||
|
printf '%s│%s%s%s│\n' $p $c_dim (string pad -r -w $iw -- $hint) $c_reset
|
||||||
|
printf '%s└%s┘\n' $p $HBR
|
||||||
|
end
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
# __config_settings_subcats <category_variable>
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Prints the sub-category rows for one C1-C6 category, one per line as
|
||||||
|
# "<slug>\t<label>\t<description>". This is a fish-native copy of the
|
||||||
|
# taxonomy authored in docs/manual/08-components-reference/*.md (Task 9)
|
||||||
|
# -- kept here as a static table rather than parsed from markdown at
|
||||||
|
# draw time, since config-settings redraws on every keypress and every
|
||||||
|
# terminal resize.
|
||||||
|
#
|
||||||
|
# ARGUMENTS
|
||||||
|
# category_variable One of the six __fish_config_op_<category> names
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 Always
|
||||||
|
#
|
||||||
|
# RETURNS
|
||||||
|
# Tab-separated "<slug>\t<label>\t<description>" rows, one per line
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# __config_settings_subcats __fish_config_op_aliases
|
||||||
|
function __config_settings_subcats --description 'List the sub-categories for one opinionated-component category'
|
||||||
|
switch $argv[1]
|
||||||
|
case __fish_config_op_aliases
|
||||||
|
printf '%s\t%s\t%s\n' \
|
||||||
|
filesystem Filesystem "ls, cat, cd, du, mkdir, rm, mv, zoxide" \
|
||||||
|
search Search "rg" \
|
||||||
|
network Network "ping, ssh, yt-dlp" \
|
||||||
|
monitor Monitor "top" \
|
||||||
|
shell-tools Shell-tools "bash, less, help" \
|
||||||
|
dev-tools Dev-tools "claude, edit, agy"
|
||||||
|
case __fish_config_op_autoexec
|
||||||
|
printf '%s\t%s\t%s\n' \
|
||||||
|
plugin-management Plugins "Fisher bootstrap" \
|
||||||
|
pkg-wrappers Pkg-wrappers "paru/yay wrapper generation" \
|
||||||
|
venv Venv "Python auto-activation" \
|
||||||
|
telemetry Telemetry "WakaTime hook bootstrap" \
|
||||||
|
sync Sync "auto-pull, user-dots symlink"
|
||||||
|
case __fish_config_op_overrides
|
||||||
|
printf '%s\t%s\t%s\n' \
|
||||||
|
key-bindings Key-bindings "vi-mode, autopair, puffer, bang-bang" \
|
||||||
|
environment Environment "PATH, PAGER, EDITOR, CDPATH" \
|
||||||
|
prompt Prompt "Starship, right prompt, theme + FZF colors"
|
||||||
|
case __fish_config_op_integrations
|
||||||
|
printf '%s\t%s\t%s\n' \
|
||||||
|
terminal-abbrs Term-abbrs "Kitty/WezTerm abbreviations" \
|
||||||
|
window-mgmt Window-mgmt "spwin, tab, split" \
|
||||||
|
notifications Notifications "done, WakaTime hook" \
|
||||||
|
history-logs History-logs "hist, logs" \
|
||||||
|
pkg-upgrade Pkg-upgrade "upgrade"
|
||||||
|
case __fish_config_op_logging
|
||||||
|
printf '%s\t%s\t%s\n' \
|
||||||
|
terminal-capture Term-capture "Kitty watcher, smart_exit scrollback" \
|
||||||
|
multiplexer-capture Multiplexer "tmux, zellij" \
|
||||||
|
pkg-logs Pkg-logs "paru/yay AUR log wrappers"
|
||||||
|
case __fish_config_op_greeting
|
||||||
|
printf '%s\t%s\t%s\n' \
|
||||||
|
first-run First-run "welcome banner" \
|
||||||
|
greeting-message Greeting "fish_greeting override"
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
# __fish_config_op_cascade <category_variable> [<subcategory_variable>]
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Evaluates the opt-out cascade for one C1-C6 classification: an
|
||||||
|
# explicit truthy/falsy sub-category variable wins outright; otherwise
|
||||||
|
# falls back to the category variable; otherwise falls back to the
|
||||||
|
# master switch __fish_config_opinionated. A category in the opt-in
|
||||||
|
# list (currently just __fish_config_op_logging, C5) defaults to
|
||||||
|
# disabled when nothing in the chain is explicit, and the master switch
|
||||||
|
# cannot enable it -- this is data-driven here instead of a hardcoded
|
||||||
|
# string comparison, so any sub-category nested under an opt-in
|
||||||
|
# category inherits "off unless explicit" for free through the cascade,
|
||||||
|
# with no per-sub-category special-casing.
|
||||||
|
#
|
||||||
|
# ARGUMENTS
|
||||||
|
# category_variable Name (without $) of a C1-C6 category variable
|
||||||
|
# subcategory_variable Optional name (without $) of a sub-category
|
||||||
|
# variable nested under that category
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 Enabled
|
||||||
|
# 1 Disabled
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# __fish_config_op_cascade __fish_config_op_aliases
|
||||||
|
# __fish_config_op_cascade __fish_config_op_aliases __fish_config_op_aliases_filesystem
|
||||||
|
function __fish_config_op_cascade --description 'Evaluate the sub-category -> category -> master opt-out cascade'
|
||||||
|
set -l opt_in_categories __fish_config_op_logging
|
||||||
|
|
||||||
|
set -l chain $argv[1]
|
||||||
|
if test (count $argv) -ge 2 -a -n "$argv[2]"
|
||||||
|
set chain $argv[2] $argv[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
for var_name in $chain
|
||||||
|
__fish_variable_check $var_name
|
||||||
|
set -l s $status
|
||||||
|
if test $s -eq 0
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
if test $s -eq 1
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Every variable in the chain was unset/unrecognized. chain[-1] is
|
||||||
|
# always the category variable (present whether or not a
|
||||||
|
# sub-category was given) -- opt-in categories default to disabled
|
||||||
|
# and the master switch cannot override that.
|
||||||
|
if contains -- $chain[-1] $opt_in_categories
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
__fish_variable_check __fish_config_opinionated
|
||||||
|
if test $status -eq 1
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
return 0
|
||||||
|
end
|
||||||
@@ -2,63 +2,68 @@
|
|||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# __fish_config_op_enabled <category_variable>
|
# __fish_config_op_enabled <identity> [<site>]
|
||||||
#
|
#
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
# Guard predicate for opinionated components (AGENTS.md Task #3).
|
# Guard predicate for an opinionated component. <identity> is computed
|
||||||
# The category variable is evaluated first via __fish_variable_check:
|
# by the caller, never hand-typed as a category name: (status
|
||||||
# an explicit truthy value (1/true/yes/on/y) enables the component
|
# current-function) inside a function body, (status basename) at
|
||||||
# regardless of the master switch; an explicit falsy value
|
# top-level conf.d/*.fish or config.fish code (fish has no API for a
|
||||||
# (0/false/no/off/n) disables it regardless of the master switch.
|
# callee to introspect its own caller, so the caller must compute and
|
||||||
# Only when the category variable is unset or unrecognized (status 2
|
# pass its own identity -- see the spec's "A note on self-identifying").
|
||||||
# or 3) does the master switch __fish_config_opinionated apply: a
|
# A trailing .fish is stripped so a status-basename identity and a
|
||||||
# falsy master disables every unset-category component at once.
|
# status-current-function identity land in the same key space.
|
||||||
# Unset master with unset category → enabled (active by default).
|
|
||||||
#
|
#
|
||||||
# One exception: __fish_config_op_logging (C5) is opt-in, because it
|
# Looks up "<identity>:<site>" (site defaults to the empty/unnamed site)
|
||||||
# writes terminal output to disk. Unset or unrecognized means disabled,
|
# in the generated component registry. No registry entry (unclassified,
|
||||||
# and the master switch cannot enable it — only an explicit truthy
|
# or a doc header with no # COMPONENT section) resolves to enabled --
|
||||||
# value turns logging on.
|
# the same fail-open default as an explicit `always/on` tag, so
|
||||||
|
# user-authored and third-party functions that never call this guard in
|
||||||
|
# the first place are unaffected, and one that somehow does is never
|
||||||
|
# silently broken by a missing header. A found `always/off` tag
|
||||||
|
# disables unconditionally; a found `always/on` tag enables
|
||||||
|
# unconditionally, short-circuiting before any other tagged
|
||||||
|
# sub-category is evaluated. Otherwise every tagged sub-category must
|
||||||
|
# pass the cascade (AND semantics).
|
||||||
#
|
#
|
||||||
# ARGUMENTS
|
# ARGUMENTS
|
||||||
# category_variable Name (without $) of the category opt-out variable:
|
# identity (status current-function) or (status basename)
|
||||||
# __fish_config_op_aliases, __fish_config_op_autoexec,
|
# site Optional site slug (see # COMPONENT header grammar);
|
||||||
# __fish_config_op_overrides,
|
# omitted for the default/unnamed site
|
||||||
# __fish_config_op_integrations,
|
|
||||||
# __fish_config_op_logging, or
|
|
||||||
# __fish_config_op_greeting
|
|
||||||
#
|
#
|
||||||
# EXIT STATUS
|
# EXIT STATUS
|
||||||
# 0 Component enabled (category explicitly truthy; or category unset and master not falsy — except C5 logging, which requires an explicit truthy value)
|
# 0 Component enabled
|
||||||
# 1 Component disabled (category explicitly falsy; or category unset and master falsy; or C5 logging unset; or no argument with falsy master)
|
# 1 Component disabled
|
||||||
#
|
#
|
||||||
# EXAMPLE
|
# EXAMPLE
|
||||||
# if __fish_config_op_enabled __fish_config_op_aliases
|
# if not __fish_config_op_enabled (status current-function)
|
||||||
# alias grep='grep --color=auto'
|
# alias grep='grep --color=auto'
|
||||||
# end
|
# end
|
||||||
function __fish_config_op_enabled --description 'Check whether an opinionated component category is enabled'
|
# if not __fish_config_op_enabled (status current-function) exit-plain
|
||||||
__fish_variable_check $argv[1]
|
# builtin exit
|
||||||
set -l cat_status $status
|
# end
|
||||||
|
function __fish_config_op_enabled --description 'Guard for an opinionated component, identified by its own caller'
|
||||||
|
set -l identity (string replace -r '\.fish$' '' -- $argv[1])
|
||||||
|
set -l site $argv[2]
|
||||||
|
|
||||||
if test $cat_status -eq 0
|
set -l tags (__fish_config_op_registry_lookup $identity $site)
|
||||||
|
if test $status -ne 0
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
if test $cat_status -eq 1
|
if contains -- always/off $tags
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
if contains -- always/on $tags
|
||||||
# C5 logging is opt-in: it writes terminal output to disk, so an unset or
|
return 0
|
||||||
# unrecognized value means off — the master switch cannot enable it.
|
|
||||||
if test "$argv[1]" = __fish_config_op_logging
|
|
||||||
return 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Status 3 (garbage) defers to master — an unrecognized value is not an opt-out.
|
for tag in $tags
|
||||||
__fish_variable_check __fish_config_opinionated
|
set -l parts (string split -m 1 -- / $tag)
|
||||||
if test $status -eq 1
|
set -l category_var "__fish_config_op_$parts[1]"
|
||||||
return 1
|
set -l subcat_var "__fish_config_op_$parts[1]_"(string replace -a -- '-' '_' $parts[2])
|
||||||
|
__fish_config_op_cascade $category_var $subcat_var
|
||||||
|
or return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
# __fish_config_op_registry_lookup <identity> <site>
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Looks up the "<identity>:<site>" key in the generated component
|
||||||
|
# registry ($__fish_config_op_registry_keys /
|
||||||
|
# $__fish_config_op_registry_values, sourced from
|
||||||
|
# conf.d/__fish_config_op_registry.fish at shell startup) and prints its
|
||||||
|
# tags, one per line. <site> is empty string for the default/unnamed
|
||||||
|
# site.
|
||||||
|
#
|
||||||
|
# ARGUMENTS
|
||||||
|
# identity Function name (status current-function) or file basename
|
||||||
|
# with any trailing .fish stripped (status basename)
|
||||||
|
# site Site slug, or empty string for the default site
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 Found: tags printed to stdout
|
||||||
|
# 1 Not found: nothing printed
|
||||||
|
#
|
||||||
|
# RETURNS
|
||||||
|
# Matching tags, one per line, printed to stdout
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# set -l tags (__fish_config_op_registry_lookup rm "")
|
||||||
|
# or return 0 # unclassified: caller treats this as always-on
|
||||||
|
function __fish_config_op_registry_lookup --description 'Look up the COMPONENT tags for an identity:site pair'
|
||||||
|
set -l key "$argv[1]:$argv[2]"
|
||||||
|
set -l idx (contains -i -- $key $__fish_config_op_registry_keys)
|
||||||
|
if test -z "$idx"
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
string split ' ' -- $__fish_config_op_registry_values[$idx]
|
||||||
|
return 0
|
||||||
|
end
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
# __fish_config_op_registry_rebuild
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Regenerates conf.d/__fish_config_op_registry.fish from every
|
||||||
|
# # COMPONENT header in functions/*.fish, conf.d/*.fish, and
|
||||||
|
# config.fish, then re-sources it into the current session so the
|
||||||
|
# change takes effect immediately. Run manually after editing a
|
||||||
|
# # COMPONENT header; never run automatically at shell startup --
|
||||||
|
# parsing every header on every new shell would be wasted work on
|
||||||
|
# every session that isn't actively editing a header.
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 Registry regenerated
|
||||||
|
# 1 python3 is not available, or generation failed
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# __fish_config_op_registry_rebuild
|
||||||
|
function __fish_config_op_registry_rebuild --description 'Regenerate the opinionated-component registry from # COMPONENT headers'
|
||||||
|
if not type -q python3
|
||||||
|
echo "__fish_config_op_registry_rebuild: python3 not found" >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
python3 "$__fish_config_dir/docs/generate_component_registry.py"
|
||||||
|
or return 1
|
||||||
|
source "$__fish_config_dir/conf.d/__fish_config_op_registry.fish"
|
||||||
|
end
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# logging/terminal-capture
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# __fish_config_sync_logging
|
# __fish_config_sync_logging
|
||||||
#
|
#
|
||||||
@@ -29,7 +32,7 @@ function __fish_config_sync_logging --description 'Sync C5 logging state: sentin
|
|||||||
set -l yay_wrapper "$HOME/.local/bin/yay"
|
set -l yay_wrapper "$HOME/.local/bin/yay"
|
||||||
set -l wrapper_version 1
|
set -l wrapper_version 1
|
||||||
|
|
||||||
if __fish_config_op_enabled __fish_config_op_logging
|
if __fish_config_op_enabled (status current-function)
|
||||||
# Logging enabled: remove sentinel and regenerate wrappers if binaries exist
|
# Logging enabled: remove sentinel and regenerate wrappers if binaries exist
|
||||||
rm -f $sentinel
|
rm -f $sentinel
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# autoexec/sync
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# __fish_user_dots_link
|
# __fish_user_dots_link
|
||||||
#
|
#
|
||||||
@@ -41,7 +44,7 @@ function __fish_user_dots_link --description 'Manage the user-dots convenience s
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Enabled: creation is a C2 startup side-effect.
|
# Enabled: creation is a C2 startup side-effect.
|
||||||
__fish_config_op_enabled __fish_config_op_autoexec; or return 0
|
__fish_config_op_enabled (status current-function); or return 0
|
||||||
|
|
||||||
test -d "$__fish_user_dots_path"; or return 0
|
test -d "$__fish_user_dots_path"; or return 0
|
||||||
if test -L "$link"
|
if test -L "$link"
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# Copyright (C) 2026 Rootiest
|
# Copyright (C) 2026 Rootiest
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# COMPONENT
|
||||||
|
# logging/multiplexer-capture
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# _zellij_dump_log
|
# _zellij_dump_log
|
||||||
#
|
#
|
||||||
@@ -23,7 +26,7 @@
|
|||||||
# EXAMPLE
|
# EXAMPLE
|
||||||
# _zellij_dump_log
|
# _zellij_dump_log
|
||||||
function _zellij_dump_log --description 'Dump the current Zellij pane scrollback to a log file, with pruning'
|
function _zellij_dump_log --description 'Dump the current Zellij pane scrollback to a log file, with pruning'
|
||||||
__fish_config_op_enabled __fish_config_op_logging; or return 0
|
__fish_config_op_enabled (status current-function); or return 0
|
||||||
set -q ZELLIJ; or return 0
|
set -q ZELLIJ; or return 0
|
||||||
type -q zellij; or return 0
|
type -q zellij; or return 0
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 12-ai-and-developer-tools
|
# 12-ai-and-developer-tools
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/dev-tools
|
||||||
|
#
|
||||||
# DEPENDENCIES
|
# DEPENDENCIES
|
||||||
# agents-init
|
# agents-init
|
||||||
#
|
#
|
||||||
@@ -35,7 +38,7 @@
|
|||||||
# agy -i "initial prompt"
|
# agy -i "initial prompt"
|
||||||
# agy models
|
# agy models
|
||||||
function agy --wraps=agy --description 'agy wrapper: auto-initializes AGENTS/ sub-repo before launch'
|
function agy --wraps=agy --description 'agy wrapper: auto-initializes AGENTS/ sub-repo before launch'
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command agy $argv
|
command agy $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 04-git-and-version-control
|
# 04-git-and-version-control
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# autoexec/sync
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# auto-pull [list]
|
# auto-pull [list]
|
||||||
# auto-pull add [PATH]
|
# auto-pull add [PATH]
|
||||||
@@ -136,7 +139,7 @@ function auto-pull --description 'Manage the auto-pull repository registry'
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
case status
|
case status
|
||||||
if __fish_config_op_enabled __fish_config_op_autoexec
|
if __fish_config_op_enabled (status current-function)
|
||||||
echo "$c_ok""auto-pull: ENABLED$c_reset $c_dim(C2 auto-execution on)$c_reset"
|
echo "$c_ok""auto-pull: ENABLED$c_reset $c_dim(C2 auto-execution on)$c_reset"
|
||||||
else
|
else
|
||||||
echo "$c_warn""auto-pull: DISABLED$c_reset $c_dim(via __fish_config_op_autoexec)$c_reset"
|
echo "$c_warn""auto-pull: DISABLED$c_reset $c_dim(via __fish_config_op_autoexec)$c_reset"
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 14-miscellaneous
|
# 14-miscellaneous
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/shell-tools
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# bash [args...]
|
# bash [args...]
|
||||||
#
|
#
|
||||||
@@ -18,7 +21,7 @@
|
|||||||
# bash
|
# bash
|
||||||
function bash --wraps='bash' --description 'bash switches to bash shell'
|
function bash --wraps='bash' --description 'bash switches to bash shell'
|
||||||
# Opinionated guard (C1): fall back to bare command bash when disabled.
|
# Opinionated guard (C1): fall back to bare command bash when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command bash $argv
|
command bash $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 01-file-and-directory
|
# 01-file-and-directory
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/filesystem
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# cat [args...]
|
# cat [args...]
|
||||||
#
|
#
|
||||||
@@ -21,7 +24,7 @@
|
|||||||
# cat ~/projects/myapp
|
# cat ~/projects/myapp
|
||||||
function cat --wraps='bat' --description 'Use bat for files, ls for directories, and raw cat for ANSI logs'
|
function cat --wraps='bat' --description 'Use bat for files, ls for directories, and raw cat for ANSI logs'
|
||||||
# Opinionated guard (C1): fall back to bare command cat when disabled.
|
# Opinionated guard (C1): fall back to bare command cat when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command cat $argv
|
command cat $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 12-ai-and-developer-tools
|
# 12-ai-and-developer-tools
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/dev-tools
|
||||||
|
#
|
||||||
# DEPENDENCIES
|
# DEPENDENCIES
|
||||||
# agents-init
|
# agents-init
|
||||||
#
|
#
|
||||||
@@ -33,7 +36,7 @@
|
|||||||
# claude --resume
|
# claude --resume
|
||||||
# claude "Explain the recent changes"
|
# claude "Explain the recent changes"
|
||||||
function claude --wraps=claude --description 'claude wrapper: auto-links AGENTS.md as CLAUDE.md'
|
function claude --wraps=claude --description 'claude wrapper: auto-links AGENTS.md as CLAUDE.md'
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command claude $argv
|
command claude $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,7 +20,10 @@
|
|||||||
# path, and the user-dots convenience symlink toggle (Dots link)
|
# path, and the user-dots convenience symlink toggle (Dots link)
|
||||||
#
|
#
|
||||||
# Toggle rows use ← / → (or h / l) to step OFF ← DEFAULT → ON; DEFAULT erases
|
# Toggle rows use ← / → (or h / l) to step OFF ← DEFAULT → ON; DEFAULT erases
|
||||||
# the variable so the master switch / built-in default applies. Value rows
|
# the variable so the master switch / built-in default applies. On the
|
||||||
|
# Universal/Session pages, Enter on a category row (C1–C6) opens that
|
||||||
|
# category's sub-category drill-down page for finer-grained toggles;
|
||||||
|
# Escape backs out to the category list. Value rows
|
||||||
# (Sponge, Paths) use Enter to edit inline; ← / h clears to default. List rows
|
# (Sponge, Paths) use Enter to edit inline; ← / h clears to default. List rows
|
||||||
# (e.g. Extra secret, OK codes) accept values separated by commas and/or
|
# (e.g. Extra secret, OK codes) accept values separated by commas and/or
|
||||||
# whitespace — "A, B", "A,B" and "A B" all yield the same two entries.
|
# whitespace — "A, B", "A,B" and "A B" all yield the same two entries.
|
||||||
@@ -49,7 +52,10 @@
|
|||||||
# ↑ ↓ / k j Move cursor
|
# ↑ ↓ / k j Move cursor
|
||||||
# ← → / h l Toggle rows: OFF ← DEFAULT → ON
|
# ← → / h l Toggle rows: OFF ← DEFAULT → ON
|
||||||
# ← / h Value rows: clear to default
|
# ← / h Value rows: clear to default
|
||||||
# Enter Value rows: edit inline (Sponge / Paths pages)
|
# Enter Category rows (Universal/Session): open sub-category
|
||||||
|
# drill-down page. Value rows: edit inline (Sponge /
|
||||||
|
# Paths pages)
|
||||||
|
# Escape Sub-category page: back out to the category list
|
||||||
# Tab / S-Tab Next / previous page
|
# Tab / S-Tab Next / previous page
|
||||||
# q / Escape Exit
|
# q / Escape Exit
|
||||||
#
|
#
|
||||||
@@ -82,7 +88,8 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
echo "$c_head""Navigation:$c_reset"
|
echo "$c_head""Navigation:$c_reset"
|
||||||
echo " $c_flag↑ ↓$c_reset or $c_flag""k j$c_reset Move cursor up / down"
|
echo " $c_flag↑ ↓$c_reset or $c_flag""k j$c_reset Move cursor up / down"
|
||||||
echo " $c_flag← →$c_reset or $c_flag""h l$c_reset Toggle pages: OFF ← DEFAULT → ON"
|
echo " $c_flag← →$c_reset or $c_flag""h l$c_reset Toggle pages: OFF ← DEFAULT → ON"
|
||||||
echo " $c_flag""Enter$c_reset Edit value (Sponge / Paths pages)"
|
echo " $c_flag""Enter$c_reset Open sub-category page (Universal / Session);"
|
||||||
|
echo " edit value (Sponge / Paths pages)"
|
||||||
echo " $c_flag← / h$c_reset Clear value to default (value rows)"
|
echo " $c_flag← / h$c_reset Clear value to default (value rows)"
|
||||||
echo " $c_flag""Tab / S-Tab$c_reset Next / previous page"
|
echo " $c_flag""Tab / S-Tab$c_reset Next / previous page"
|
||||||
echo " $c_flag""q$c_reset / $c_flag""Esc$c_reset Exit"
|
echo " $c_flag""q$c_reset / $c_flag""Esc$c_reset Exit"
|
||||||
@@ -110,6 +117,12 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
__fish_config_op_greeting \
|
__fish_config_op_greeting \
|
||||||
__fish_config_opinionated
|
__fish_config_opinionated
|
||||||
|
|
||||||
|
# ── Drill-down navigation state (Universal/Session pages only) ────────
|
||||||
|
# in_subcat: 1 while viewing a category's sub-category page (Enter to
|
||||||
|
# open, Escape to back out). subcat_row: cursor row within that page.
|
||||||
|
set -l in_subcat 0
|
||||||
|
set -l subcat_row 0
|
||||||
|
|
||||||
# ── Value-page row metadata (parallel: var / type) ────────────────────
|
# ── Value-page row metadata (parallel: var / type) ────────────────────
|
||||||
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
|
||||||
@@ -140,16 +153,34 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
trap 'printf "\e[?25h"; set -g __config_settings_exit 1' INT
|
trap 'printf "\e[?25h"; set -g __config_settings_exit 1' INT
|
||||||
|
|
||||||
# ── Draw dispatch (page 0/1 = toggle table; 2/3 = value page) ─────────
|
# ── Draw dispatch (page 0/1 = toggle table; 2/3 = value page) ─────────
|
||||||
|
# Records the actual line count of whatever it just drew into panel_h,
|
||||||
|
# so every erase (redraw loop, inline editor, final cleanup) matches
|
||||||
|
# reality -- the sub-category page is n+7 lines (2-6 sub-categories:
|
||||||
|
# 9-13 lines), never the category list's fixed 16.
|
||||||
function __cs_dispatch_draw --no-scope-shadowing
|
function __cs_dispatch_draw --no-scope-shadowing
|
||||||
switch $cur_page
|
switch $cur_page
|
||||||
case 0
|
case 0
|
||||||
__config_settings_draw $cur_row universal $toggle_vars
|
if test $in_subcat -eq 1
|
||||||
|
__config_settings_draw_subcat $subcat_row universal $toggle_vars[(math $cur_row + 1)]
|
||||||
|
set panel_h (math 7 + (count (__config_settings_subcats $toggle_vars[(math $cur_row + 1)])))
|
||||||
|
else
|
||||||
|
__config_settings_draw $cur_row universal $toggle_vars
|
||||||
|
set panel_h 16
|
||||||
|
end
|
||||||
case 1
|
case 1
|
||||||
__config_settings_draw $cur_row session $toggle_vars
|
if test $in_subcat -eq 1
|
||||||
|
__config_settings_draw_subcat $subcat_row session $toggle_vars[(math $cur_row + 1)]
|
||||||
|
set panel_h (math 7 + (count (__config_settings_subcats $toggle_vars[(math $cur_row + 1)])))
|
||||||
|
else
|
||||||
|
__config_settings_draw $cur_row session $toggle_vars
|
||||||
|
set panel_h 16
|
||||||
|
end
|
||||||
case 2
|
case 2
|
||||||
__config_settings_draw_value $cur_row sponge
|
__config_settings_draw_value $cur_row sponge
|
||||||
|
set panel_h 16
|
||||||
case 3
|
case 3
|
||||||
__config_settings_draw_value $cur_row paths
|
__config_settings_draw_value $cur_row paths
|
||||||
|
set panel_h 16
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
__cs_dispatch_draw
|
__cs_dispatch_draw
|
||||||
@@ -174,24 +205,50 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
|
|
||||||
switch $key
|
switch $key
|
||||||
case up k
|
case up k
|
||||||
set cur_row (math "max(0, $cur_row - 1)")
|
if test $in_subcat -eq 1
|
||||||
|
set subcat_row (math "max(0, $subcat_row - 1)")
|
||||||
|
else
|
||||||
|
set cur_row (math "max(0, $cur_row - 1)")
|
||||||
|
end
|
||||||
case down j
|
case down j
|
||||||
# Hoist the page index: fish cannot expand a command-substitution
|
if test $in_subcat -eq 1
|
||||||
# index inside a quoted math string.
|
set -l n (count (__config_settings_subcats $toggle_vars[(math $cur_row + 1)]))
|
||||||
set -l pidx (math $cur_page + 1)
|
set subcat_row (math "min($n, $subcat_row + 1)")
|
||||||
set cur_row (math "min($page_rows[$pidx] - 1, $cur_row + 1)")
|
else
|
||||||
|
# Hoist the page index: fish cannot expand a command-substitution
|
||||||
|
# index inside a quoted math string.
|
||||||
|
set -l pidx (math $cur_page + 1)
|
||||||
|
set cur_row (math "min($page_rows[$pidx] - 1, $cur_row + 1)")
|
||||||
|
end
|
||||||
case tab
|
case tab
|
||||||
set cur_page (math "($cur_page + 1) % 4")
|
set cur_page (math "($cur_page + 1) % 4")
|
||||||
set cur_row 0
|
set cur_row 0
|
||||||
|
set in_subcat 0
|
||||||
case backtab
|
case backtab
|
||||||
set cur_page (math "($cur_page + 3) % 4")
|
set cur_page (math "($cur_page + 3) % 4")
|
||||||
set cur_row 0
|
set cur_row 0
|
||||||
|
set in_subcat 0
|
||||||
case right l
|
case right l
|
||||||
if test $cur_page -le 1
|
if test $cur_page -le 1
|
||||||
# Toggle page: step toward ON
|
# Toggle page: step toward ON
|
||||||
set -l scope universal
|
set -l scope universal
|
||||||
test $cur_page -eq 1; and set scope session
|
test $cur_page -eq 1; and set scope session
|
||||||
set -l varname $toggle_vars[(math $cur_row + 1)]
|
# Default: the category variable itself -- correct both
|
||||||
|
# when not in a sub-category page at all, and when in
|
||||||
|
# one but sitting on its row 0 (the category's own
|
||||||
|
# toggle). Only row >= 1 of a sub-category page
|
||||||
|
# resolves to a different, sub-category variable.
|
||||||
|
# Hoist the category variable into a plain local first --
|
||||||
|
# fish cannot expand a command-substitution index
|
||||||
|
# ("$toggle_vars[(math ...)]") inside a quoted string
|
||||||
|
# (same reason the down/j case above hoists $pidx).
|
||||||
|
set -l cvar $toggle_vars[(math $cur_row + 1)]
|
||||||
|
set -l varname $cvar
|
||||||
|
if test $in_subcat -eq 1 -a $subcat_row -ne 0
|
||||||
|
set -l rows (__config_settings_subcats $cvar)
|
||||||
|
set -l fields (string split -- \t $rows[$subcat_row])
|
||||||
|
set varname "$cvar"_(string replace -a -- '-' '_' $fields[1])
|
||||||
|
end
|
||||||
set -l cur_val (__config_settings_get_val $varname $scope)
|
set -l cur_val (__config_settings_get_val $varname $scope)
|
||||||
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
|
||||||
@@ -217,7 +274,17 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
if test $cur_page -le 1
|
if test $cur_page -le 1
|
||||||
set -l scope universal
|
set -l scope universal
|
||||||
test $cur_page -eq 1; and set scope session
|
test $cur_page -eq 1; and set scope session
|
||||||
set -l varname $toggle_vars[(math $cur_row + 1)]
|
# Same varname resolution as the right/l case above
|
||||||
|
# (hoisted local -- see the comment there for why the
|
||||||
|
# command-substitution index can't be inlined into the
|
||||||
|
# quoted string directly).
|
||||||
|
set -l cvar $toggle_vars[(math $cur_row + 1)]
|
||||||
|
set -l varname $cvar
|
||||||
|
if test $in_subcat -eq 1 -a $subcat_row -ne 0
|
||||||
|
set -l rows (__config_settings_subcats $cvar)
|
||||||
|
set -l fields (string split -- \t $rows[$subcat_row])
|
||||||
|
set varname "$cvar"_(string replace -a -- '-' '_' $fields[1])
|
||||||
|
end
|
||||||
set -l cur_val (__config_settings_get_val $varname $scope)
|
set -l cur_val (__config_settings_get_val $varname $scope)
|
||||||
set -l next_val off
|
set -l next_val off
|
||||||
test "$cur_val" = on; and set next_val DEFAULT
|
test "$cur_val" = on; and set next_val DEFAULT
|
||||||
@@ -246,7 +313,12 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
case enter
|
case enter
|
||||||
if test $cur_page -ge 2
|
if test $cur_page -le 1
|
||||||
|
if test $in_subcat -eq 0 -a $cur_row -le 5
|
||||||
|
set in_subcat 1
|
||||||
|
set subcat_row 0
|
||||||
|
end
|
||||||
|
else if test $cur_page -ge 2
|
||||||
set -l v_vars $sponge_vars
|
set -l v_vars $sponge_vars
|
||||||
set -l v_types $sponge_types
|
set -l v_types $sponge_types
|
||||||
set -l v_defaults $sponge_defaults
|
set -l v_defaults $sponge_defaults
|
||||||
@@ -313,8 +385,14 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
set did_redraw 1
|
set did_redraw 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
case q Q quit escape
|
case q Q quit
|
||||||
break
|
break
|
||||||
|
case escape
|
||||||
|
if test $in_subcat -eq 1
|
||||||
|
set in_subcat 0
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Skip redraw entirely when the key reader timed out with no resize
|
# Skip redraw entirely when the key reader timed out with no resize
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 01-file-and-directory
|
# 01-file-and-directory
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/filesystem
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# du [--disk|--dir|--dua] [args...]
|
# du [--disk|--dir|--dua] [args...]
|
||||||
#
|
#
|
||||||
@@ -23,7 +26,7 @@
|
|||||||
# du --disk
|
# du --disk
|
||||||
function du --description 'Execute du'
|
function du --description 'Execute du'
|
||||||
# Opinionated guard (C1): fall back to bare command du when disabled.
|
# Opinionated guard (C1): fall back to bare command du when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command du $argv
|
command du $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 03-editors-and-viewers
|
# 03-editors-and-viewers
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/dev-tools
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# edit [-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s] [FILE...]
|
# edit [-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s] [FILE...]
|
||||||
#
|
#
|
||||||
@@ -50,7 +53,7 @@ function edit --description 'Open files in a terminal or GUI editor with fallbac
|
|||||||
set -l c_reset (set_color normal)
|
set -l c_reset (set_color normal)
|
||||||
|
|
||||||
# Opinionated guard (C1): fall back to the legacy bare-editor behavior.
|
# Opinionated guard (C1): fall back to the legacy bare-editor behavior.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
if set -q EDITOR; and test -n "$EDITOR"
|
if set -q EDITOR; and test -n "$EDITOR"
|
||||||
$EDITOR $argv
|
$EDITOR $argv
|
||||||
else if type -q nvim
|
else if type -q nvim
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 08-terminal-management
|
# 08-terminal-management
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# overrides/prompt
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# fish_right_prompt
|
# fish_right_prompt
|
||||||
#
|
#
|
||||||
@@ -31,7 +34,7 @@ function fish_right_prompt
|
|||||||
# Docker context — only relevant alongside the starship prompt, and only
|
# Docker context — only relevant alongside the starship prompt, and only
|
||||||
# when docker is actually installed (guarded like every other optional
|
# when docker is actually installed (guarded like every other optional
|
||||||
# integration in this config).
|
# integration in this config).
|
||||||
if type -q docker; and type -q starship; and __fish_config_op_enabled __fish_config_op_overrides
|
if type -q docker; and type -q starship; and __fish_config_op_enabled (status current-function)
|
||||||
set -l docker_ctx (docker context show 2>/dev/null)
|
set -l docker_ctx (docker context show 2>/dev/null)
|
||||||
if test -n "$docker_ctx"; and test "$docker_ctx" != default
|
if test -n "$docker_ctx"; and test "$docker_ctx" != default
|
||||||
set_color blue
|
set_color blue
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 04-git-and-version-control
|
# 04-git-and-version-control
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# integrations/history-logs
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# hist
|
# hist
|
||||||
#
|
#
|
||||||
@@ -15,7 +18,7 @@
|
|||||||
# hist
|
# hist
|
||||||
function hist --description 'Search fish history and put it in the prompt'
|
function hist --description 'Search fish history and put it in the prompt'
|
||||||
# Opinionated guard (C4): integrations disabled
|
# Opinionated guard (C4): integrations disabled
|
||||||
if not __fish_config_op_enabled __fish_config_op_integrations
|
if not __fish_config_op_enabled (status current-function)
|
||||||
set -l c_err (set_color red)
|
set -l c_err (set_color red)
|
||||||
set -l c_reset (set_color normal)
|
set -l c_reset (set_color normal)
|
||||||
echo "$c_err"'hist: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
echo "$c_err"'hist: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 14-miscellaneous
|
# 14-miscellaneous
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# logging/terminal-capture
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# kitty-logging [install | uninstall | status | dismiss] [-h]
|
# kitty-logging [install | uninstall | status | dismiss] [-h]
|
||||||
#
|
#
|
||||||
@@ -97,7 +100,7 @@ function kitty-logging --description 'Install/manage the fish-config Kitty scrol
|
|||||||
else
|
else
|
||||||
echo " Watcher file: $c_warn""not installed$c_reset"
|
echo " Watcher file: $c_warn""not installed$c_reset"
|
||||||
end
|
end
|
||||||
if __fish_config_op_enabled __fish_config_op_logging
|
if __fish_config_op_enabled (status current-function)
|
||||||
echo " C5 logging: $c_ok""enabled$c_reset"
|
echo " C5 logging: $c_ok""enabled$c_reset"
|
||||||
else
|
else
|
||||||
echo " C5 logging: $c_warn""disabled$c_reset (capture is currently inert)"
|
echo " C5 logging: $c_warn""disabled$c_reset (capture is currently inert)"
|
||||||
@@ -143,7 +146,7 @@ function kitty-logging --description 'Install/manage the fish-config Kitty scrol
|
|||||||
end
|
end
|
||||||
echo "$c_ok""→ Installed.$c_reset Watcher wired into $conf"
|
echo "$c_ok""→ Installed.$c_reset Watcher wired into $conf"
|
||||||
echo " $c_dim""Restart Kitty (new windows) for it to take effect.$c_reset"
|
echo " $c_dim""Restart Kitty (new windows) for it to take effect.$c_reset"
|
||||||
if not __fish_config_op_enabled __fish_config_op_logging
|
if not __fish_config_op_enabled (status current-function)
|
||||||
echo " $c_warn""Note: C5 logging is disabled, so capture is currently inert.$c_reset"
|
echo " $c_warn""Note: C5 logging is disabled, so capture is currently inert.$c_reset"
|
||||||
end
|
end
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 03-editors-and-viewers
|
# 03-editors-and-viewers
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/shell-tools
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# less [args...]
|
# less [args...]
|
||||||
#
|
#
|
||||||
@@ -18,7 +21,7 @@
|
|||||||
# less /var/log/syslog
|
# less /var/log/syslog
|
||||||
function less --wraps='ov' --description 'Pager wrapper: $PAGER → ov → less → more → cat'
|
function less --wraps='ov' --description 'Pager wrapper: $PAGER → ov → less → more → cat'
|
||||||
# Opinionated guard (C1): fall back to bare command less when disabled.
|
# Opinionated guard (C1): fall back to bare command less when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command less $argv
|
command less $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 11-pager-and-logging
|
# 11-pager-and-logging
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# integrations/history-logs
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# logs [-h] [-c <category>]
|
# logs [-h] [-c <category>]
|
||||||
#
|
#
|
||||||
@@ -35,7 +38,7 @@
|
|||||||
# logs -c scrollback
|
# logs -c scrollback
|
||||||
function logs --description 'Browse terminal log files interactively with fzf'
|
function logs --description 'Browse terminal log files interactively with fzf'
|
||||||
# Opinionated guard (C4): integrations disabled
|
# Opinionated guard (C4): integrations disabled
|
||||||
if not __fish_config_op_enabled __fish_config_op_integrations
|
if not __fish_config_op_enabled (status current-function)
|
||||||
set -l c_err (set_color red)
|
set -l c_err (set_color red)
|
||||||
set -l c_reset (set_color normal)
|
set -l c_reset (set_color normal)
|
||||||
echo "$c_err"'logs: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
echo "$c_err"'logs: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 01-file-and-directory
|
# 01-file-and-directory
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/filesystem
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# ls [args...]
|
# ls [args...]
|
||||||
#
|
#
|
||||||
@@ -20,7 +23,7 @@
|
|||||||
# ls -a ~/projects
|
# ls -a ~/projects
|
||||||
function ls --description 'List all files'
|
function ls --description 'List all files'
|
||||||
# Opinionated guard (C1): fall back to bare command ls when disabled.
|
# Opinionated guard (C1): fall back to bare command ls when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command ls $argv
|
command ls $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 01-file-and-directory
|
# 01-file-and-directory
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/filesystem
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# mkdir [args...]
|
# mkdir [args...]
|
||||||
#
|
#
|
||||||
@@ -20,7 +23,7 @@
|
|||||||
# mkdir ~/projects/myapp/src
|
# mkdir ~/projects/myapp/src
|
||||||
function mkdir --description 'Execute mkdir'
|
function mkdir --description 'Execute mkdir'
|
||||||
# Opinionated guard (C1): fall back to bare command mkdir when disabled.
|
# Opinionated guard (C1): fall back to bare command mkdir when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command mkdir $argv
|
command mkdir $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 01-file-and-directory
|
# 01-file-and-directory
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/filesystem
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# mv [args...]
|
# mv [args...]
|
||||||
#
|
#
|
||||||
@@ -27,7 +30,7 @@
|
|||||||
# mv ~/.config/btop/themes/themes ~/.config/btop/themes
|
# mv ~/.config/btop/themes/themes ~/.config/btop/themes
|
||||||
function mv --wraps='mv' --description 'Move files with auto-collapse for nested directories'
|
function mv --wraps='mv' --description 'Move files with auto-collapse for nested directories'
|
||||||
# Opinionated guard (C1): fall back to bare command mv when disabled.
|
# Opinionated guard (C1): fall back to bare command mv when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command mv $argv
|
command mv $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 10-network
|
# 10-network
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/network
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# ping [args...]
|
# ping [args...]
|
||||||
#
|
#
|
||||||
@@ -21,7 +24,7 @@
|
|||||||
# ping --legend google.com
|
# ping --legend google.com
|
||||||
function ping --description 'prettyping with default nolegend'
|
function ping --description 'prettyping with default nolegend'
|
||||||
# Opinionated guard (C1): fall back to bare command ping when disabled.
|
# Opinionated guard (C1): fall back to bare command ping when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command ping $argv
|
command ping $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 01-file-and-directory
|
# 01-file-and-directory
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/search
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# rg [args...]
|
# rg [args...]
|
||||||
#
|
#
|
||||||
@@ -21,7 +24,7 @@
|
|||||||
# rg -l "TODO" ~/projects/myapp
|
# rg -l "TODO" ~/projects/myapp
|
||||||
function rg --description 'alias rg=rg --hyperlink-format=kitty'
|
function rg --description 'alias rg=rg --hyperlink-format=kitty'
|
||||||
# Opinionated guard (C1): fall back to bare command rg when disabled.
|
# Opinionated guard (C1): fall back to bare command rg when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command rg $argv
|
command rg $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 01-file-and-directory
|
# 01-file-and-directory
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/filesystem
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# rm [-e [options] | -S | args...]
|
# rm [-e [options] | -S | args...]
|
||||||
#
|
#
|
||||||
@@ -38,7 +41,7 @@
|
|||||||
# Falls back to /usr/bin/rm when trash is unavailable.
|
# Falls back to /usr/bin/rm when trash is unavailable.
|
||||||
function rm --description 'Ultimate rm: trash, list, empty, and secure-erase'
|
function rm --description 'Ultimate rm: trash, list, empty, and secure-erase'
|
||||||
# Opinionated guard (C1): fall back to bare command rm when disabled.
|
# Opinionated guard (C1): fall back to bare command rm when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command rm $argv
|
command rm $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 11-pager-and-logging
|
# 11-pager-and-logging
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# site exit-plain: overrides/key-bindings
|
||||||
|
# site logging-guard: logging/terminal-capture
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# smart_exit [-h] [-n]
|
# smart_exit [-h] [-n]
|
||||||
#
|
#
|
||||||
@@ -32,7 +36,7 @@ function smart_exit --description 'Capture colorized scrollback before exiting,
|
|||||||
# Opinionated guard (C3): exit plainly when overrides are disabled.
|
# Opinionated guard (C3): exit plainly when overrides are disabled.
|
||||||
# This composes with Task #4's __fish_config_enable_logging, which will
|
# This composes with Task #4's __fish_config_enable_logging, which will
|
||||||
# gate only the scrollback capture while leaving the exit wrapper active.
|
# gate only the scrollback capture while leaving the exit wrapper active.
|
||||||
if not __fish_config_op_enabled __fish_config_op_overrides
|
if not __fish_config_op_enabled (status current-function) exit-plain
|
||||||
builtin exit $argv
|
builtin exit $argv
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -60,7 +64,7 @@ function smart_exit --description 'Capture colorized scrollback before exiting,
|
|||||||
# C5 — Logging & Capture: skip all capture when logging is disabled.
|
# C5 — Logging & Capture: skip all capture when logging is disabled.
|
||||||
# When disabled, tell Kitty the window is handled so its watcher doesn't
|
# When disabled, tell Kitty the window is handled so its watcher doesn't
|
||||||
# capture either — belt-and-suspenders alongside the sentinel file.
|
# capture either — belt-and-suspenders alongside the sentinel file.
|
||||||
if not __fish_config_op_enabled __fish_config_op_logging
|
if not __fish_config_op_enabled (status current-function) logging-guard
|
||||||
if test -n "$KITTY_WINDOW_ID"
|
if test -n "$KITTY_WINDOW_ID"
|
||||||
kitty @ set-user-vars "logged_by_shell=true" 2>/dev/null
|
kitty @ set-user-vars "logged_by_shell=true" 2>/dev/null
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 08-terminal-management
|
# 08-terminal-management
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# integrations/window-mgmt
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# split [-h | -v] [command...]
|
# split [-h | -v] [command...]
|
||||||
#
|
#
|
||||||
@@ -27,7 +30,7 @@
|
|||||||
# split -v nvim README.md
|
# split -v nvim README.md
|
||||||
function split --description 'Run a command in a new terminal split'
|
function split --description 'Run a command in a new terminal split'
|
||||||
# Opinionated guard (C4): integrations disabled
|
# Opinionated guard (C4): integrations disabled
|
||||||
if not __fish_config_op_enabled __fish_config_op_integrations
|
if not __fish_config_op_enabled (status current-function)
|
||||||
set -l c_err (set_color red)
|
set -l c_err (set_color red)
|
||||||
set -l c_reset (set_color normal)
|
set -l c_reset (set_color normal)
|
||||||
echo "$c_err"'split: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
echo "$c_err"'split: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 08-terminal-management
|
# 08-terminal-management
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# integrations/window-mgmt
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# spwin [args...]
|
# spwin [args...]
|
||||||
#
|
#
|
||||||
@@ -22,7 +25,7 @@
|
|||||||
# spwin
|
# spwin
|
||||||
function spwin --wraps='~/.config/kitty/spawn-window.sh' --description 'spawn window in kitty or wezterm'
|
function spwin --wraps='~/.config/kitty/spawn-window.sh' --description 'spawn window in kitty or wezterm'
|
||||||
# Opinionated guard (C4): integrations disabled
|
# Opinionated guard (C4): integrations disabled
|
||||||
if not __fish_config_op_enabled __fish_config_op_integrations
|
if not __fish_config_op_enabled (status current-function)
|
||||||
set -l c_err (set_color red)
|
set -l c_err (set_color red)
|
||||||
set -l c_reset (set_color normal)
|
set -l c_reset (set_color normal)
|
||||||
echo "$c_err"'spwin: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
echo "$c_err"'spwin: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 08-terminal-management
|
# 08-terminal-management
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/network
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# ssh [args...]
|
# ssh [args...]
|
||||||
#
|
#
|
||||||
@@ -20,7 +23,7 @@
|
|||||||
# ssh user@host
|
# ssh user@host
|
||||||
function ssh --description 'Alias ssh to kitten ssh when using Kitty terminal'
|
function ssh --description 'Alias ssh to kitten ssh when using Kitty terminal'
|
||||||
# Opinionated guard (C1): fall back to bare command ssh when disabled.
|
# Opinionated guard (C1): fall back to bare command ssh when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command ssh $argv
|
command ssh $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 08-terminal-management
|
# 08-terminal-management
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# integrations/window-mgmt
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# tab [args...]
|
# tab [args...]
|
||||||
#
|
#
|
||||||
@@ -23,7 +26,7 @@
|
|||||||
# tab
|
# tab
|
||||||
function tab --description 'Spawn a new tab in the current terminal'
|
function tab --description 'Spawn a new tab in the current terminal'
|
||||||
# Opinionated guard (C4): integrations disabled
|
# Opinionated guard (C4): integrations disabled
|
||||||
if not __fish_config_op_enabled __fish_config_op_integrations
|
if not __fish_config_op_enabled (status current-function)
|
||||||
set -l c_err (set_color red)
|
set -l c_err (set_color red)
|
||||||
set -l c_reset (set_color normal)
|
set -l c_reset (set_color normal)
|
||||||
echo "$c_err"'tab: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
echo "$c_err"'tab: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 07-system-and-monitoring
|
# 07-system-and-monitoring
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/monitor
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# top [args...]
|
# top [args...]
|
||||||
#
|
#
|
||||||
@@ -18,7 +21,7 @@
|
|||||||
# top
|
# top
|
||||||
function top --wraps='btop' --description 'Use btop as a modern replacement for top'
|
function top --wraps='btop' --description 'Use btop as a modern replacement for top'
|
||||||
# Opinionated guard (C1): fall back to bare command top when disabled.
|
# Opinionated guard (C1): fall back to bare command top when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command top $argv
|
command top $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 05-package-management
|
# 05-package-management
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# integrations/pkg-upgrade
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# upgrade
|
# upgrade
|
||||||
#
|
#
|
||||||
@@ -19,7 +22,7 @@
|
|||||||
# upgrade
|
# upgrade
|
||||||
function upgrade --description 'Full system upgrade via paru or yay'
|
function upgrade --description 'Full system upgrade via paru or yay'
|
||||||
# Opinionated guard (C4): integrations disabled
|
# Opinionated guard (C4): integrations disabled
|
||||||
if not __fish_config_op_enabled __fish_config_op_integrations
|
if not __fish_config_op_enabled (status current-function)
|
||||||
set -l c_err (set_color red)
|
set -l c_err (set_color red)
|
||||||
set -l c_reset (set_color normal)
|
set -l c_reset (set_color normal)
|
||||||
echo "$c_err"'upgrade: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
echo "$c_err"'upgrade: disabled by __fish_config_op_integrations'"$c_reset" >&2
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
# CATEGORY
|
# CATEGORY
|
||||||
# 13-media-and-utilities
|
# 13-media-and-utilities
|
||||||
#
|
#
|
||||||
|
# COMPONENT
|
||||||
|
# aliases/network
|
||||||
|
#
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
# yt-dlp [args...] URL [URL...]
|
# yt-dlp [args...] URL [URL...]
|
||||||
#
|
#
|
||||||
@@ -29,7 +32,7 @@
|
|||||||
# yt-dlp --no-embed-thumbnail dQw4w9WgXcQ # drops our thumbnail default
|
# yt-dlp --no-embed-thumbnail dQw4w9WgXcQ # drops our thumbnail default
|
||||||
function yt-dlp --description 'yt-dlp with embedding + SponsorBlock defaults'
|
function yt-dlp --description 'yt-dlp with embedding + SponsorBlock defaults'
|
||||||
# Opinionated guard (C1): fall back to bare command yt-dlp when disabled.
|
# Opinionated guard (C1): fall back to bare command yt-dlp when disabled.
|
||||||
if not __fish_config_op_enabled __fish_config_op_aliases
|
if not __fish_config_op_enabled (status current-function)
|
||||||
command yt-dlp $argv
|
command yt-dlp $argv
|
||||||
return $status
|
return $status
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user