Files
fish-config/functions/config-toggle.fish
T
rootiest 5a018fe975 fix(config-toggle): use valid -n read flag, stopping the busy redraw loop
The event loop used `read -k 1`, but `-k` is not a valid fish read option
(it errors with "unknown option", status 2). read therefore returned
instantly every iteration without consuming a keypress, so the loop
redrew the panel as fast as the terminal could render and ignored all
input. The nchars flag is `-n`, not `-k`.

Switch to `read -s -n 1` (one char, silent so keystrokes don't garble the
panel) and add `or break` so a read failure (EOF / non-tty stdin) exits
cleanly instead of spinning. Applies to the primary read and both escape
sequence continuation reads.
2026-06-11 02:56:12 -04:00

178 lines
7.2 KiB
Fish
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# config-toggle [-h | --help]
#
# DESCRIPTION
# Opens an interactive full-screen TUI for toggling the six opinionated
# component categories (C1C6) 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)
#
# Changes apply immediately on each Space keypress — 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-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""j k$c_reset Move cursor up / down"
echo " $c_flag""Space$c_reset Cycle: ON → OFF → DEFAULT → ON"
echo " $c_flag""Tab$c_reset Switch scope (Universal ↔ Session)"
echo " $c_flag""q$c_reset / $c_flag""Q$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 # 06
set -l cur_scope universal # or "session"
set -l panel_h 14 # total panel lines
# ── 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 ────────────────────────────────────────
# read -s -n 1 reads exactly one char without echoing it. Arrow keys send
# ESC+[+letter as a 3-byte burst — after reading the ESC we immediately
# read 2 more bytes which are already in the terminal buffer. Single-char
# keys ('j','k',' ','q', Tab) are returned right away with no extra
# blocking. NOTE: the nchars flag is -n; -k is not a valid read option.
while true
# Check for Ctrl-C signal (trap sets this flag)
if set -q __config_toggle_exit
set -eg __config_toggle_exit
break
end
# -n 1 reads exactly one char; -s suppresses echo so keystrokes do
# not garble the panel. If read fails (EOF / non-tty stdin) bail out
# instead of spinning the redraw loop.
read -s -n 1 -l key
or break
# Detect CSI escape sequences (arrow keys: ESC [ A/B)
if test "$key" = \e
read -s -n 1 -l key2
if test "$key2" = "["
read -s -n 1 -l key3
set key "$key$key2$key3" # \e[A or \e[B
else
# ESC + non-bracket (ALT+key or plain ESC): treat key2 as key
set key $key2
end
end
switch $key
case \e\[A # Up arrow
set cur_row (math "max(0, $cur_row - 1)")
case \e\[B # Down arrow
set cur_row (math "min(6, $cur_row + 1)")
case k
set cur_row (math "max(0, $cur_row - 1)")
case j
set cur_row (math "min(6, $cur_row + 1)")
case \t # Tab — switch scope
if test $cur_scope = universal
set cur_scope session
else
set cur_scope universal
end
case ' ' # Space — cycle and apply immediately
set -l varname $vars[(math $cur_row + 1)]
set -l cur_val (__config_toggle_get_val $varname $cur_scope)
set -l next_val ""
# Cycle: on → off → DEFAULT → on
switch $cur_val
case on
set next_val off
case off
set next_val DEFAULT
case '*' # DEFAULT or any unrecognised
set next_val on
end
# Apply immediately
switch $cur_scope
case universal
switch $next_val
case on
set -U $varname on
case off
set -U $varname off
case DEFAULT
set -Ue $varname
end
case session
switch $next_val
case on
set -g $varname on
case off
set -g $varname off
case DEFAULT
set -eg $varname
end
end
case q Q
break
end
# Redraw in place
printf '\e[%dA\e[J' $panel_h
__config_toggle_draw $cur_row $cur_scope $vars
end
# ── Cleanup ───────────────────────────────────────────
trap - INT # remove the signal handler
printf '\e[?25h' # restore cursor
end