diff --git a/README.md b/README.md index 740a021..8401fc5 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ This config layers on top of the CachyOS base Fish configuration and adds: > set -U __fish_config_op_logging off > ``` > -> Or run **`config-toggle`** for an interactive menu to flip logging (and any +> Or run **`config-settings`** for an interactive menu to flip logging (and any > other opinionated category) on or off — no variable names to remember. > > This takes effect immediately in every open shell. See [Session Logging](#session-logging) @@ -89,7 +89,7 @@ set -U __fish_config_op_logging off # disable; takes effect in every open shel set -Ue __fish_config_op_logging # re-enable (erase the override) ``` -Prefer an interactive interface? Run **`config-toggle`** for a full-screen +Prefer an interactive interface? Run **`config-settings`** for a full-screen picker that flips logging — and every other opinionated category — on or off per session or universally, without memorizing variable names. @@ -255,7 +255,7 @@ test -f "$__fish_user_dots_path/local.fish" Everything opinionated in this config — command shadows, startup side-effects, key and environment overrides, terminal integrations, logging, and the first-run greeting — is active by default but can be switched off. -> **The easy way — `config-toggle`:** Run `config-toggle` for an interactive TUI that flips every setting below on, off, or back to default — per-session or universally — without typing a single variable name. Use the arrow keys (or `h`/`j`/`k`/`l`) to navigate and adjust, `Tab` to switch scope, and `q` to quit. Changes apply instantly. The panel auto-sizes to your terminal width (four tiers from 52- to 78-wide with a 6-column margin), centers itself horizontally, and redraws within ~0.3 s of a resize. +> **The easy way — `config-settings`:** Run `config-settings` for an interactive TUI that flips every setting below on, off, or back to default — per-session or universally — without typing a single variable name. Use the arrow keys (or `h`/`j`/`k`/`l`) to navigate and adjust, `Tab` to switch scope, and `q` to quit. Changes apply instantly. The panel auto-sizes to your terminal width (four tiers from 52- to 78-wide with a 6-column margin), centers itself horizontally, and redraws within ~0.3 s of a resize. If you'd rather set them by hand, each category is controlled by a universal variable. Six category toggles and one master switch are available: diff --git a/docs/fish-config.index b/docs/fish-config.index index e214baf..561b157 100644 --- a/docs/fish-config.index +++ b/docs/fish-config.index @@ -155,8 +155,9 @@ yt-dlp=### yt-dlp miscfns=## 5.14 Miscellaneous config-help=### config-help config-update=### config-update -config-toggle=### config-toggle -toggle=### config-toggle +config-settings=### config-settings +config-toggle=### config-settings +toggle=### config-settings bash=### bash cheat=### cheat dockup=### dockup diff --git a/docs/fish-config.md b/docs/fish-config.md index b2c135a..d23ac9f 100644 --- a/docs/fish-config.md +++ b/docs/fish-config.md @@ -48,7 +48,7 @@ A production-grade Fish shell configuration targeting Fish 4.x. It provides: > your machine, but the files persist locally. > > - Disable all logging with: `set -U __fish_config_op_logging off` -> - Prefer a menu? Run the interactive picker: `config-toggle` +> - Prefer a menu? Run the interactive picker: `config-settings` > - See Section 7 (C5 - Logging and Capture) for the full breakdown. The configuration is split across: @@ -1347,19 +1347,24 @@ Add -i (interactive confirmation) to destructive commands: config-update --dry-run config-update --force -### config-toggle +### config-settings - Synopsis: config-toggle [-h] + Synopsis: config-settings [-h] - Opens an interactive TUI for toggling the six opinionated component - categories (C1–C6) and the master disable variable without having to - type or remember variable names. Two scope tabs allow independent - per-scope configuration: + Opens an interactive TUI for managing fish configuration settings. Handles + the six opinionated component categories (C1–C6), the master disable + variable, and the __fish_user_dots_path path variable — without having to + type or remember variable names. Two scope tabs allow independent per-scope + configuration for category toggles: Universal — persists across all sessions (set -U) Session — current shell only (set -g) - Changes apply immediately on each value keypress. Always available + The Dots Path row always operates on the universal scope regardless of the + active tab. + + Changes to category toggles apply immediately on each keypress. Changes to + the path variable use an inline edit prompt (Enter). Always available regardless of the __fish_config_opinionated master state. The panel adapts to the terminal width automatically, selecting from @@ -1374,17 +1379,30 @@ Add -i (interactive confirmation) to destructive commands: Navigation: ↑ ↓ / k j Move cursor - ← → / h l Set value: OFF ← DEFAULT → ON (clamped) + ← → / h l Set value: OFF ← DEFAULT → ON (toggle rows); LEFT clears path + Enter Edit the Dots Path (path row only) Tab Switch scope (Universal ↔ Session) q / Escape Exit - Left/Right (or vim-style h/l) move the highlighted value one step along - the OFF–DEFAULT–ON scale and stop at the ends. DEFAULT erases the - variable so the master switch / built-in default applies. + Left/Right (or vim-style h/l) move the highlighted toggle value one step + along the OFF–DEFAULT–ON scale and stop at the ends. DEFAULT erases the + variable so the master switch / built-in default applies. On the Dots Path + row, LEFT/h clears the universal variable; RIGHT/l is a no-op (use Enter). + + Dots Path row [U] tag: the tag confirms this row always writes to the + universal scope, regardless of which tab is active. Setting it per-session + would have no effect on startup sourcing. Flags: --help / -h Show usage. + config-settings + +### config-toggle (deprecated) + + Deprecated alias for config-settings. Prints a deprecation notice to + stderr, then delegates all arguments to config-settings. + config-toggle ### bash @@ -1659,7 +1677,7 @@ Examples: # (erase both to go back to full-flavor defaults) For an interactive alternative to setting these variables by hand, run -config-toggle — a full-screen TUI that flips any category (including C5 +config-settings — a full-screen TUI that flips any category (including C5 logging) on or off, per session or universally. See its entry in Section 5. Notes: @@ -2098,6 +2116,10 @@ control in a private directory. The path defaults to set -U __fish_user_dots_path /path/to/your/dots/fish +Or use the interactive TUI — run `config-settings` and navigate to the +"Dots Path" row (last row). Press Enter to type a new path, or ← / h to +reset to the default. + config.fish sources local.fish from that directory on every interactive session. local.fish is responsible for sourcing its own secrets.fish: diff --git a/functions/__config_toggle_apply.fish b/functions/__config_settings_apply.fish similarity index 78% rename from functions/__config_toggle_apply.fish rename to functions/__config_settings_apply.fish index b04f961..4357041 100644 --- a/functions/__config_toggle_apply.fish +++ b/functions/__config_settings_apply.fish @@ -2,11 +2,11 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # SYNOPSIS -# __config_toggle_apply +# __config_settings_apply # # DESCRIPTION # Applies a state value to an opinionated-component variable in the given -# scope, immediately and persistently. Used by config-toggle's Left/Right +# scope, immediately and persistently. Used by config-settings's Left/Right # (and vim h/l) directional handlers so the set/erase logic lives in one # place. A value of "DEFAULT" erases the variable in that scope so the # master switch / built-in default takes over again. @@ -17,15 +17,15 @@ # ARGUMENTS # varname Variable name without the $ prefix # scope "universal" or "session" -# value "on", "off", or "DEFAULT" +# value "on", "off", "DEFAULT", or any arbitrary string (universal scope only) # # RETURNS # 0 Always # # EXAMPLE -# __config_toggle_apply __fish_config_op_aliases universal off -# __config_toggle_apply __fish_config_op_greeting session DEFAULT -function __config_toggle_apply +# __config_settings_apply __fish_config_op_aliases universal off +# __config_settings_apply __fish_config_op_greeting session DEFAULT +function __config_settings_apply set -l varname $argv[1] set -l scope $argv[2] set -l value $argv[3] @@ -33,7 +33,7 @@ function __config_toggle_apply # stderr is suppressed because setting a value in one scope while the # other scope already holds the same variable makes interactive fish # emit a shadowing warning ("set: successfully set universal 'X'; but a - # global by that name shadows it"). config-toggle intentionally edits + # global by that name shadows it"). config-settings intentionally edits # both scopes independently, so the warning is expected noise — and if # it reached the terminal it would push the cursor down a row and # corrupt the in-place panel redraw (leaving a stacked top border @@ -48,6 +48,8 @@ function __config_toggle_apply set -U $varname off 2>/dev/null case DEFAULT set -Ue $varname 2>/dev/null + case '*' + set -U $varname $value 2>/dev/null end case session switch $value diff --git a/functions/__config_toggle_draw.fish b/functions/__config_settings_draw.fish similarity index 80% rename from functions/__config_toggle_draw.fish rename to functions/__config_settings_draw.fish index 340c36b..b7d1551 100644 --- a/functions/__config_toggle_draw.fish +++ b/functions/__config_settings_draw.fish @@ -2,10 +2,10 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # SYNOPSIS -# __config_toggle_draw ... +# __config_settings_draw ... # # DESCRIPTION -# Renders the 14-line config-toggle TUI panel to stdout. Panel width and +# Renders the 16-line config-settings TUI panel to stdout. Panel width and # horizontal position are chosen automatically from $COLUMNS each call, # so a terminal resize takes effect on the next keypress without any # extra bookkeeping. Four width tiers with a 6-col buffer per side: @@ -16,24 +16,24 @@ # COLUMNS < 82 → 52-wide (IW=50, desc=17 chars) ← default # # The box is horizontally centered via a left-padding prefix on every -# output line. \e[14A\e[J erases by line count so the horizontal offset +# output line. \e[16A\e[J erases by line count so the horizontal offset # does not interfere with the redraw loop. # # ARGUMENTS -# cur_row 0–6, the currently highlighted row +# cur_row 0–7, the currently highlighted row # cur_scope "universal" or "session" -# var1–var7 Variable names for rows 0–6 (in order per Variable Reference) +# var1–var8 Variable names for rows 0–7 (in order per Variable Reference) # # RETURNS # 0 Always # # EXAMPLE -# __config_toggle_draw 0 universal \ +# __config_settings_draw 0 universal \ # __fish_config_op_aliases __fish_config_op_autoexec \ # __fish_config_op_overrides __fish_config_op_integrations \ # __fish_config_op_logging __fish_config_op_greeting \ -# __fish_config_opinionated -function __config_toggle_draw +# __fish_config_opinionated __fish_user_dots_path +function __config_settings_draw set -l cur_row $argv[1] set -l cur_scope $argv[2] set -l vars $argv[3..] @@ -50,7 +50,7 @@ function __config_toggle_draw # ── Width tier: 6-col buffer per side before stepping up ────────────── # IW = inner width (chars between │ │); desc field = IW - 33. - # All four layouts are exactly 14 lines tall — panel_h in caller stays 14. + # All four layouts are exactly 16 lines tall — panel_h in caller stays 16. set -l iw 50 set -l descs \ "cmd shadows" \ @@ -131,7 +131,7 @@ function __config_toggle_draw set -l label $labels[$idx] set -l desc $descs[$idx] - set -l val (__config_toggle_get_val $var $cur_scope) + set -l val (__config_settings_get_val $var $cur_scope) # Badge: 7 visible chars, coloured set -l badge @@ -161,7 +161,7 @@ function __config_toggle_draw printf '%s│ %s │\n' $p (string repeat -n (math $iw - 6) '─') # ── Master row (index 6) ────────────────────────────────────────────── - set -l val (__config_toggle_get_val $vars[7] $cur_scope) + set -l val (__config_settings_get_val $vars[7] $cur_scope) set -l badge switch $val case on @@ -181,12 +181,42 @@ function __config_toggle_draw $badge \ (string pad -r -w (math $iw - 33) -- $descs[7]) + # ── Separator before Path Settings ─────────────────────────────────── + printf '%s│ %s │\n' $p (string repeat -n (math $iw - 6) '─') + + # ── Path row (index 7) — always universal scope ─────────────────────── + set -l path_var $vars[8] + set -l raw_path (__config_settings_get_val $path_var universal) + + set -l path_badge + set -l path_dpad + if test "$raw_path" = DEFAULT + set path_badge "$c_dim""DEFAULT$c_reset" + set path_dpad (string pad -r -w (math $iw - 33) -- "—default— [U]") + else + set path_badge "$c_ok"" PATH $c_reset" + set -l max_path (math $iw - 37) + set -l truncated (string shorten -m $max_path -- "$raw_path") + set path_dpad (string pad -r -w (math $iw - 33) -- "$truncated [U]") + end + + set -l path_curs " " + if test $cur_row -eq 7 + set path_curs "$c_sel▶$c_reset " + end + + printf '%s│ %s%s [ %s ] %s │\n' \ + $p $path_curs \ + (string pad -r -w 12 -- "Dots Path") \ + $path_badge \ + $path_dpad + # ── Bottom divider ──────────────────────────────────────────────────── printf '%s│%s│\n' $p $HBR # ── Keybind hint ────────────────────────────────────────────────────── # string pad is width-aware (arrows count as 1 column) - set -l hint " ↑↓/kj move ←→/hl set Tab scope q quit" + set -l hint " ↑↓/kj move ←→/hl set Enter edit path q quit" printf '%s│%s%s%s│\n' $p $c_dim (string pad -r -w $iw -- $hint) $c_reset # ── Bottom border ───────────────────────────────────────────────────── diff --git a/functions/__config_toggle_get_val.fish b/functions/__config_settings_get_val.fish similarity index 88% rename from functions/__config_toggle_get_val.fish rename to functions/__config_settings_get_val.fish index 376551a..c2dbede 100644 --- a/functions/__config_toggle_get_val.fish +++ b/functions/__config_settings_get_val.fish @@ -2,7 +2,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # SYNOPSIS -# __config_toggle_get_val +# __config_settings_get_val # # DESCRIPTION # Returns the current value of a named variable in the specified scope by @@ -18,9 +18,9 @@ # 0 Always; prints "on", "off", or "DEFAULT" to stdout # # EXAMPLE -# set result (__config_toggle_get_val __fish_config_op_aliases universal) +# set result (__config_settings_get_val __fish_config_op_aliases universal) # # result == "on" | "off" | "DEFAULT" -function __config_toggle_get_val +function __config_settings_get_val set -l varname $argv[1] set -l scope $argv[2] diff --git a/functions/__config_toggle_read_key.fish b/functions/__config_settings_read_key.fish similarity index 96% rename from functions/__config_toggle_read_key.fish rename to functions/__config_settings_read_key.fish index 4bafc78..0109064 100644 --- a/functions/__config_toggle_read_key.fish +++ b/functions/__config_settings_read_key.fish @@ -2,7 +2,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # SYNOPSIS -# __config_toggle_read_key +# __config_settings_read_key # # DESCRIPTION # Reads a single keypress directly from the controlling terminal in raw @@ -31,13 +31,13 @@ # 1 The terminal could not be put into raw mode (stdin is not a TTY) # # EXAMPLE -# set -l key (__config_toggle_read_key) +# set -l key (__config_settings_read_key) # or return # not a TTY — bail # switch $key # case up; echo "moved up" # case space; echo "toggled" # end -function __config_toggle_read_key +function __config_settings_read_key # Snapshot current terminal settings; failure means stdin is not a TTY. set -l saved (stty -g /dev/null) or return 1 diff --git a/functions/config-settings.fish b/functions/config-settings.fish new file mode 100644 index 0000000..b4b8e37 --- /dev/null +++ b/functions/config-settings.fish @@ -0,0 +1,206 @@ +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later + +# SYNOPSIS +# config-settings [-h | --help] +# +# DESCRIPTION +# Opens an interactive full-screen TUI for managing fish config settings, +# including the six opinionated component categories (C1–C6) and the master +# disable variable, without having to remember variable names. Two scope +# tabs allow independent per-scope configuration: +# +# Universal — persists across all sessions (set -U / set -Ue) +# Session — active for the current shell only (set -g / set -eg) +# +# Values are changed directionally with the arrow keys (or vim-style h/l) +# along an OFF ← DEFAULT → ON scale, and apply immediately — no confirm +# step. Always available regardless of __fish_config_opinionated state. +# +# ARGUMENTS +# -h, --help Print usage and exit +# +# RETURNS +# 0 Exited normally (q or Escape pressed) +# 1 Unknown flag passed +# +# EXAMPLE +# config-settings +function config-settings --description 'Interactive TUI for managing fish config settings' + set -l c_head (set_color --bold cyan) + set -l c_cmd (set_color --bold white) + set -l c_flag (set_color yellow) + set -l c_dim (set_color brblack) + set -l c_err (set_color red) + set -l c_reset (set_color normal) + + # ── Argument parsing ────────────────────────────────── + for arg in $argv + switch $arg + case -h --help + echo "$c_head""Usage:$c_reset $c_cmd""config-settings$c_reset $c_flag""[-h]$c_reset" + echo + echo " Interactive TUI for managing fish config settings." + echo " Changes apply immediately — no confirm step required." + echo + 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""h l$c_reset Set value: OFF ← DEFAULT → ON" + echo " $c_flag""Tab$c_reset Switch scope (Universal ↔ Session)" + echo " $c_flag""Enter$c_reset Edit path (on Dots Path row)" + echo " $c_flag""q$c_reset / $c_flag""Esc$c_reset Exit" + echo + echo "$c_head""Scopes:$c_reset" + echo " $c_flag""Universal$c_reset Persistent across all sessions ($c_dim""set -U$c_reset)" + echo " $c_flag""Session$c_reset Current session only ($c_dim""set -g$c_reset)" + return 0 + case '*' + echo "$c_err""Unknown option: $arg$c_reset" >&2 + echo "Run $c_cmd""config-settings --help$c_reset for usage." >&2 + return 1 + end + end + + # ── Variable list (matches Panel Layout Reference) ──── + set -l vars \ + __fish_config_op_aliases \ + __fish_config_op_autoexec \ + __fish_config_op_overrides \ + __fish_config_op_integrations \ + __fish_config_op_logging \ + __fish_config_op_greeting \ + __fish_config_opinionated \ + __fish_user_dots_path + + set -l cur_row 0 # 0–7 + set -l cur_scope universal # or "session" + set -l panel_h 16 # total panel lines (all width tiers are 16 lines) + set -l last_cols $COLUMNS # COLUMNS at the time of the last draw + + # ── Terminal setup ──────────────────────────────────── + printf '\e[?25l' # hide cursor + trap 'printf "\e[?25h"; set -g __config_settings_exit 1' INT + + # ── Initial draw ────────────────────────────────────── + __config_settings_draw $cur_row $cur_scope $vars + + # ── Event loop ──────────────────────────────────────── + # __config_settings_read_key reads a single keypress from /dev/tty in raw + # mode and returns a normalized token (up/down/tab/space/escape/quit or a + # literal char). It bypasses fish's `read`, whose line editor swallows Tab + # and arrow keys and prints a `read> ` prompt — unusable for a TUI. + while true + # Check for Ctrl-C signal (trap sets this flag during redraw, when the + # terminal is briefly back in cooked mode and SIGINT can fire). + if set -q __config_settings_exit + set -eg __config_settings_exit + break + end + + set -l key (__config_settings_read_key) + or break # not a TTY — exit instead of spinning + + set -l did_redraw 0 + + switch $key + case up k + set cur_row (math "max(0, $cur_row - 1)") + case down j + set cur_row (math "min(7, $cur_row + 1)") + case tab # Tab — switch scope + if test $cur_scope = universal + set cur_scope session + else + set cur_scope universal + end + case enter + if test $cur_row -eq 7 + # Erase panel (wrap-aware, same formula as cleanup) + set -l prev_max_lw (math --scale=0 "($last_cols + 78) / 2") + set -l erase_h (math --scale=0 "$panel_h * max(1, ceil($prev_max_lw / $COLUMNS))") + printf '\e[%dA\e[J' $erase_h + printf '\e[?25h' # restore cursor + + printf 'User Dots Path (leave blank to reset to default): ' + read -l new_path + + if test -n "$new_path" + set -U __fish_user_dots_path $new_path + else + set -Ue __fish_user_dots_path + end + + printf '\e[?25l' # hide cursor + set last_cols $COLUMNS + __config_settings_draw $cur_row $cur_scope $vars + set did_redraw 1 + end + case right l # → / l — step toward ON (clamped, no wrap) + if test $cur_row -eq 7 + # no-op for path var; use Enter to set + else + set -l varname $vars[(math $cur_row + 1)] + set -l cur_val (__config_settings_get_val $varname $cur_scope) + + set -l next_val on + switch $cur_val + case off + set next_val DEFAULT + case on + set next_val on + case '*' + set next_val on + end + __config_settings_apply $varname $cur_scope $next_val + end + case left h # ← / h — step toward OFF (clamped, no wrap) + if test $cur_row -eq 7 + # Clear the universal path var (restore default) + __config_settings_apply __fish_user_dots_path universal DEFAULT + else + set -l varname $vars[(math $cur_row + 1)] + set -l cur_val (__config_settings_get_val $varname $cur_scope) + + set -l next_val off + switch $cur_val + case on + set next_val DEFAULT + case off + set next_val off + case '*' + set next_val off + end + __config_settings_apply $varname $cur_scope $next_val + end + case q Q quit escape + break + end + + # Skip redraw entirely when the key reader timed out with no resize + if test -z "$key" -a "$COLUMNS" = "$last_cols" + continue + end + + # Skip redraw if the Enter handler already redrew (e.g. after path edit) + if test $did_redraw -eq 1 + continue + end + + # Wrap-aware erase: a panel drawn on a wider terminal has longer lines + # (due to center-padding) that wrap into extra physical rows when the + # terminal narrows. 78 = widest box (IW=76+2); the formula gives the + # worst-case old line width for any tier drawn at last_cols. + set -l prev_max_lw (math --scale=0 "($last_cols + 78) / 2") + set -l erase_h (math --scale=0 "$panel_h * max(1, ceil($prev_max_lw / $COLUMNS))") + printf '\e[%dA\e[J' $erase_h + set last_cols $COLUMNS + __config_settings_draw $cur_row $cur_scope $vars + end + + # ── Cleanup ─────────────────────────────────────────── + trap - INT # remove the signal handler + set -l prev_max_lw (math --scale=0 "($last_cols + 78) / 2") + set -l erase_h (math --scale=0 "$panel_h * max(1, ceil($prev_max_lw / $COLUMNS))") + printf '\e[%dA\e[J' $erase_h # erase the panel (wrap-aware) + printf '\e[?25h' # restore cursor +end diff --git a/functions/config-toggle.fish b/functions/config-toggle.fish index c5d922c..cea3fd1 100644 --- a/functions/config-toggle.fish +++ b/functions/config-toggle.fish @@ -2,167 +2,21 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # SYNOPSIS -# config-toggle [-h | --help] +# config-toggle [args...] # # DESCRIPTION -# Opens an interactive full-screen TUI for toggling the six opinionated -# component categories (C1–C6) and the master disable variable without -# having to remember variable names. Two scope tabs allow independent -# per-scope configuration: -# -# Universal — persists across all sessions (set -U / set -Ue) -# Session — active for the current shell only (set -g / set -eg) -# -# Values are changed directionally with the arrow keys (or vim-style h/l) -# along an OFF ← DEFAULT → ON scale, and apply immediately — no confirm -# step. Always available regardless of __fish_config_opinionated state. +# Deprecated alias for config-settings. Prints a one-line deprecation +# notice to stderr, then delegates all arguments to config-settings. # # ARGUMENTS -# -h, --help Print usage and exit +# args Passed through verbatim to config-settings # # RETURNS -# 0 Exited normally (q or Escape pressed) -# 1 Unknown flag passed +# Same as config-settings # # EXAMPLE -# config-toggle -function config-toggle --description 'Interactive TUI for toggling opinionated component settings' - set -l c_head (set_color --bold cyan) - set -l c_cmd (set_color --bold white) - set -l c_flag (set_color yellow) - set -l c_dim (set_color brblack) - set -l c_err (set_color red) - set -l c_reset (set_color normal) - - # ── Argument parsing ────────────────────────────────── - for arg in $argv - switch $arg - case -h --help - echo "$c_head""Usage:$c_reset $c_cmd""config-toggle$c_reset $c_flag""[-h]$c_reset" - echo - echo " Interactive TUI for toggling opinionated component categories." - echo " Changes apply immediately — no confirm step required." - echo - 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""h l$c_reset Set value: OFF ← DEFAULT → ON" - echo " $c_flag""Tab$c_reset Switch scope (Universal ↔ Session)" - echo " $c_flag""q$c_reset / $c_flag""Esc$c_reset Exit" - echo - echo "$c_head""Scopes:$c_reset" - echo " $c_flag""Universal$c_reset Persistent across all sessions ($c_dim""set -U$c_reset)" - echo " $c_flag""Session$c_reset Current session only ($c_dim""set -g$c_reset)" - return 0 - case '*' - echo "$c_err""Unknown option: $arg$c_reset" >&2 - echo "Run $c_cmd""config-toggle --help$c_reset for usage." >&2 - return 1 - end - end - - # ── Variable list (matches Panel Layout Reference) ──── - set -l vars \ - __fish_config_op_aliases \ - __fish_config_op_autoexec \ - __fish_config_op_overrides \ - __fish_config_op_integrations \ - __fish_config_op_logging \ - __fish_config_op_greeting \ - __fish_config_opinionated - - set -l cur_row 0 # 0–6 - set -l cur_scope universal # or "session" - set -l panel_h 14 # total panel lines (all width tiers are 14 lines) - set -l last_cols $COLUMNS # COLUMNS at the time of the last draw - - # ── Terminal setup ──────────────────────────────────── - printf '\e[?25l' # hide cursor - trap 'printf "\e[?25h"; set -g __config_toggle_exit 1' INT - - # ── Initial draw ────────────────────────────────────── - __config_toggle_draw $cur_row $cur_scope $vars - - # ── Event loop ──────────────────────────────────────── - # __config_toggle_read_key reads a single keypress from /dev/tty in raw - # mode and returns a normalized token (up/down/tab/space/escape/quit or a - # literal char). It bypasses fish's `read`, whose line editor swallows Tab - # and arrow keys and prints a `read> ` prompt — unusable for a TUI. - while true - # Check for Ctrl-C signal (trap sets this flag during redraw, when the - # terminal is briefly back in cooked mode and SIGINT can fire). - if set -q __config_toggle_exit - set -eg __config_toggle_exit - break - end - - set -l key (__config_toggle_read_key) - or break # not a TTY — exit instead of spinning - - switch $key - case up k - set cur_row (math "max(0, $cur_row - 1)") - case down j - set cur_row (math "min(6, $cur_row + 1)") - case tab # Tab — switch scope - if test $cur_scope = universal - set cur_scope session - else - set cur_scope universal - end - case right l # → / l — step toward ON (clamped, no wrap) - set -l varname $vars[(math $cur_row + 1)] - set -l cur_val (__config_toggle_get_val $varname $cur_scope) - - # Order: OFF ← DEFAULT → ON - set -l next_val on - switch $cur_val - case off - set next_val DEFAULT - case on - set next_val on # already at the right end - case '*' # DEFAULT or unrecognised - set next_val on - end - __config_toggle_apply $varname $cur_scope $next_val - case left h # ← / h — step toward OFF (clamped, no wrap) - set -l varname $vars[(math $cur_row + 1)] - set -l cur_val (__config_toggle_get_val $varname $cur_scope) - - # Order: OFF ← DEFAULT → ON - set -l next_val off - switch $cur_val - case on - set next_val DEFAULT - case off - set next_val off # already at the left end - case '*' # DEFAULT or unrecognised - set next_val off - end - __config_toggle_apply $varname $cur_scope $next_val - case q Q quit escape - break - end - - # Skip redraw entirely when the key reader timed out with no resize - if test -z "$key" -a "$COLUMNS" = "$last_cols" - continue - end - - # Wrap-aware erase: a panel drawn on a wider terminal has longer lines - # (due to center-padding) that wrap into extra physical rows when the - # terminal narrows. 78 = widest box (IW=76+2); the formula gives the - # worst-case old line width for any tier drawn at last_cols. - set -l prev_max_lw (math --scale=0 "($last_cols + 78) / 2") - set -l erase_h (math --scale=0 "$panel_h * max(1, ceil($prev_max_lw / $COLUMNS))") - printf '\e[%dA\e[J' $erase_h - set last_cols $COLUMNS - __config_toggle_draw $cur_row $cur_scope $vars - end - - # ── Cleanup ─────────────────────────────────────────── - trap - INT # remove the signal handler - set -l prev_max_lw (math --scale=0 "($last_cols + 78) / 2") - set -l erase_h (math --scale=0 "$panel_h * max(1, ceil($prev_max_lw / $COLUMNS))") - printf '\e[%dA\e[J' $erase_h # erase the panel (wrap-aware) - printf '\e[?25h' # restore cursor +# config-toggle # opens config-settings with a deprecation notice +function config-toggle --description 'Deprecated alias for config-settings' + echo "config-toggle is deprecated, use config-settings instead" >&2 + config-settings $argv end