Files
fish-config/functions/config-settings.fish
T
rootiest 43b3cf51f6 feat(config-settings): add path row event handling (Enter edit, LEFT clear, RIGHT no-op)
- Add __fish_user_dots_path as 8th entry in vars list
- Update panel_h from 14 to 16 (matches draw function's 16-line output)
- Clamp cur_row down to min(7, ...) to allow navigation to path row
- Add did_redraw flag (reset per iteration) to skip double-redraw after Enter
- Add Enter handler for row 7: erases panel, prompts for path, sets or clears
  __fish_user_dots_path universally, redraws, sets did_redraw
- Special-case RIGHT on row 7 as no-op (path is set via Enter only)
- Special-case LEFT on row 7 to clear path var via apply DEFAULT
- Add Enter key hint to --help navigation section
- Fix EXAMPLE block in __config_settings_draw docstring to include 8th arg
2026-06-23 14:02:03 -04:00

207 lines
9.0 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-settings [-h | --help]
#
# DESCRIPTION
# Opens an interactive full-screen TUI for managing fish config settings,
# including 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)
#
# 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 # 07
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