feat(config-settings): inline in-field value editor (no fish read prompt)
Replace the fish `read` prompt (which showed an unstyled `read>` and left the prompt line behind on redraw) with an in-place editor built on the raw key reader. The value is edited directly in its UI field with a block caret; the panel redraws each keystroke and cleans up on exit. Pre-fills the current value; Backspace deletes, Enter saves (empty reverts to default), Esc cancels. - __config_settings_read_key: decode Backspace (bytes 8/127) - __config_settings_draw_value: edit-mode field with caret + edit hint line - config-settings: inline edit loop replaces the read-based prompt block
This commit is contained in:
@@ -28,6 +28,10 @@
|
|||||||
function __config_settings_draw_value
|
function __config_settings_draw_value
|
||||||
set -l cur_row $argv[1]
|
set -l cur_row $argv[1]
|
||||||
set -l page $argv[2]
|
set -l page $argv[2]
|
||||||
|
# Inline-edit state: when argv[3] is "edit", the cur_row field renders the
|
||||||
|
# live input buffer (argv[4]) with a caret instead of its stored value.
|
||||||
|
set -l edit_mode $argv[3]
|
||||||
|
set -l edit_buf $argv[4]
|
||||||
|
|
||||||
set -l c_ok (set_color green)
|
set -l c_ok (set_color green)
|
||||||
set -l c_err (set_color red)
|
set -l c_err (set_color red)
|
||||||
@@ -126,13 +130,36 @@ function __config_settings_draw_value
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Inline edit: render the active row's field as the live buffer with a
|
||||||
|
# block caret, tail-anchored so the caret stays visible as text grows.
|
||||||
|
if test "$edit_mode" = edit -a $i -eq $cur_row
|
||||||
|
set -l fw (math $iw - 33)
|
||||||
|
set -l avail (math $fw - 1)
|
||||||
|
set -l shown "$edit_buf"
|
||||||
|
set -l blen (string length -- "$edit_buf")
|
||||||
|
if test $blen -gt $avail
|
||||||
|
set shown (string sub -s (math $blen - $avail + 1) -- "$edit_buf")
|
||||||
|
end
|
||||||
|
set badge "$c_head"" EDIT $c_reset"
|
||||||
|
set field "$shown"(set_color --reverse)" "(set_color normal)
|
||||||
|
end
|
||||||
|
|
||||||
set -l curs " "
|
set -l curs " "
|
||||||
if test $i -eq $cur_row
|
if test $i -eq $cur_row
|
||||||
set curs "$c_sel▶$c_reset "
|
set curs "$c_sel▶$c_reset "
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set -l fw (math $iw - 33)
|
||||||
set -l lpad (string pad -r -w 12 -- $label)
|
set -l lpad (string pad -r -w 12 -- $label)
|
||||||
set -l fpad (string pad -r -w (math $iw - 33) -- (string shorten -m (math $iw - 33) -- "$field"))
|
# The edit field is already length-constrained and contains a reverse
|
||||||
|
# caret; running it through `string shorten` miscounts the escapes, so
|
||||||
|
# pad it directly. Non-edit fields still shorten to add an ellipsis.
|
||||||
|
set -l fpad
|
||||||
|
if test "$edit_mode" = edit -a $i -eq $cur_row
|
||||||
|
set fpad (string pad -r -w $fw -- "$field")
|
||||||
|
else
|
||||||
|
set fpad (string pad -r -w $fw -- (string shorten -m $fw -- "$field"))
|
||||||
|
end
|
||||||
printf '%s│ %s%s [ %s ] %s │\n' $p $curs $lpad $badge $fpad
|
printf '%s│ %s%s [ %s ] %s │\n' $p $curs $lpad $badge $fpad
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -145,8 +172,11 @@ function __config_settings_draw_value
|
|||||||
# ── Bottom divider ────────────────────────────────────────────────────
|
# ── Bottom divider ────────────────────────────────────────────────────
|
||||||
printf '%s│%s│\n' $p $HBR
|
printf '%s│%s│\n' $p $HBR
|
||||||
|
|
||||||
# ── Hint line ─────────────────────────────────────────────────────────
|
# ── Hint line (changes while editing) ─────────────────────────────────
|
||||||
set -l hint_line " ↑↓ move Enter edit ←/h clear Tab page q quit"
|
set -l hint_line " ↑↓ move Enter edit ←/h clear Tab page q quit"
|
||||||
|
if test "$edit_mode" = edit
|
||||||
|
set hint_line " type value Enter save Esc cancel ⌫ delete"
|
||||||
|
end
|
||||||
printf '%s│%s%s%s│\n' $p $c_dim (string pad -r -w $iw -- $hint_line) $c_reset
|
printf '%s│%s%s%s│\n' $p $c_dim (string pad -r -w $iw -- $hint_line) $c_reset
|
||||||
|
|
||||||
# ── Bottom border ─────────────────────────────────────────────────────
|
# ── Bottom border ─────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
# RETURNS
|
# RETURNS
|
||||||
# 0 A key was read; one of these tokens is printed to stdout:
|
# 0 A key was read; one of these tokens is printed to stdout:
|
||||||
# up down left right arrow keys
|
# up down left right arrow keys
|
||||||
# space tab backtab enter escape
|
# space tab backtab enter escape backspace
|
||||||
# quit Ctrl-C (byte 3) in raw mode
|
# quit Ctrl-C (byte 3) in raw mode
|
||||||
# <char> any other single printable character
|
# <char> any other single printable character
|
||||||
# "" nothing decodable was read
|
# "" nothing decodable was read
|
||||||
@@ -74,6 +74,8 @@ function __config_settings_read_key
|
|||||||
echo space
|
echo space
|
||||||
case 10 13
|
case 10 13
|
||||||
echo enter
|
echo enter
|
||||||
|
case 8 127
|
||||||
|
echo backspace
|
||||||
case 3
|
case 3
|
||||||
echo quit
|
echo quit
|
||||||
case ''
|
case ''
|
||||||
|
|||||||
@@ -204,35 +204,65 @@ function config-settings --description 'Interactive TUI for managing fish config
|
|||||||
if test $cur_page -ge 2
|
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_labels $sponge_labels
|
|
||||||
set -l v_defaults $sponge_defaults
|
set -l v_defaults $sponge_defaults
|
||||||
if test $cur_page -eq 3
|
if test $cur_page -eq 3
|
||||||
set v_vars $paths_vars
|
set v_vars $paths_vars
|
||||||
set v_types $paths_types
|
set v_types $paths_types
|
||||||
set v_labels $paths_labels
|
|
||||||
set v_defaults $paths_defaults
|
set v_defaults $paths_defaults
|
||||||
end
|
end
|
||||||
set -l ridx (math $cur_row + 1)
|
set -l ridx (math $cur_row + 1)
|
||||||
set -l varname $v_vars[$ridx]
|
set -l varname $v_vars[$ridx]
|
||||||
set -l vtype $v_types[$ridx]
|
set -l vtype $v_types[$ridx]
|
||||||
set -l vlabel $v_labels[$ridx]
|
|
||||||
# Only path/int/list rows are editable; bool rows toggle with ←/→.
|
# Only path/int/list rows are editable; bool rows toggle with ←/→.
|
||||||
if test "$vtype" != toggle -a "$vtype" != bool
|
if test "$vtype" != toggle -a "$vtype" != bool
|
||||||
# Erase panel, drop to cooked mode, prompt, redraw.
|
# Inline editor: edit in-place in the row's value field
|
||||||
set -l prev_max_lw (math --scale=0 "($last_cols + 78) / 2")
|
# using the raw key reader — no fish `read` / `read>`
|
||||||
set -l erase_h (math --scale=0 "$panel_h * max(1, ceil($prev_max_lw / $COLUMNS))")
|
# prompt, and the panel cleans itself up on exit. The
|
||||||
printf '\e[%dA\e[J' $erase_h
|
# buffer is pre-filled with the current value; clearing it
|
||||||
printf '\e[?25h'
|
# and pressing Enter reverts to the row's default.
|
||||||
printf '%s (blank = reset to default): ' "$vlabel"
|
set -l page sponge
|
||||||
read -l new_val
|
test $cur_page -eq 3; and set page paths
|
||||||
# Blank / Escape reverts to the row's default (a value, or
|
set -l buf (__config_settings_get_raw $varname)
|
||||||
# erase when the var tolerates unset) — never leaves it empty.
|
test "$buf" = DEFAULT; and set buf ""
|
||||||
if test -n "$new_val"
|
set -l committed 0
|
||||||
__config_settings_set_value $varname $vtype "$new_val"
|
while true
|
||||||
else
|
set -l pml (math --scale=0 "($last_cols + 78) / 2")
|
||||||
__config_settings_set_value $varname $vtype "$v_defaults[$ridx]"
|
set -l eh (math --scale=0 "$panel_h * max(1, ceil($pml / $COLUMNS))")
|
||||||
|
printf '\e[%dA\e[J' $eh
|
||||||
|
set last_cols $COLUMNS
|
||||||
|
__config_settings_draw_value $cur_row $page edit "$buf"
|
||||||
|
|
||||||
|
set -l ek (__config_settings_read_key)
|
||||||
|
or break
|
||||||
|
switch $ek
|
||||||
|
case enter
|
||||||
|
set committed 1
|
||||||
|
break
|
||||||
|
case escape
|
||||||
|
break
|
||||||
|
case backspace
|
||||||
|
set buf (string sub -s 1 -e -1 -- "$buf")
|
||||||
|
case space
|
||||||
|
set buf "$buf "
|
||||||
|
case up down left right tab backtab quit ''
|
||||||
|
# ignored while editing
|
||||||
|
case '*'
|
||||||
|
set buf "$buf$ek"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
printf '\e[?25l'
|
if test $committed -eq 1
|
||||||
|
# Empty buffer reverts to the row default (a value, or
|
||||||
|
# erase when the var tolerates being unset).
|
||||||
|
if test -n "$buf"
|
||||||
|
__config_settings_set_value $varname $vtype "$buf"
|
||||||
|
else
|
||||||
|
__config_settings_set_value $varname $vtype "$v_defaults[$ridx]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Redraw the normal panel in place of the editor.
|
||||||
|
set -l pml (math --scale=0 "($last_cols + 78) / 2")
|
||||||
|
set -l eh (math --scale=0 "$panel_h * max(1, ceil($pml / $COLUMNS))")
|
||||||
|
printf '\e[%dA\e[J' $eh
|
||||||
set last_cols $COLUMNS
|
set last_cols $COLUMNS
|
||||||
__cs_dispatch_draw
|
__cs_dispatch_draw
|
||||||
set did_redraw 1
|
set did_redraw 1
|
||||||
|
|||||||
Reference in New Issue
Block a user