feat(config): switch tv pickers to --inline and improve prompt redraw handling

This commit is contained in:
Prad Nukala committed 2026-09-30 11:54:14 -04:00
1 parent 19aeed21ac
commit a5bf3e9194
10 files changed
+173 -57

No files matched your search

+56 -21
View File
@@ -4,33 +4,67 @@
# ctrl-p → pj (pj cable) down → pj on an empty prompt
# ctrl-t → tv smart autocomplete (tv init bash ships no ctrl-t)
# Keys owned by kitty.conf never reach the shell: ctrl-h/j/k/l (pass_keys.py).
#
# Every picker runs tv --inline: it opens on the line below the prompt and
# leaves the cursor on that line when it exits. When nothing was printed
# below, the binding steps back up (_kb_up) so readline redraws the prompt in
# place after bind -x; output that must stay (a pj task) is left alone.
# bind -x runs in the shell process, so gho's cd persists — but readline keeps
# drawing the prompt it started with. Each key is therefore a macro: \C-xN
# stashes the typed line and runs the command, \C-m accepts the now-empty
# line (bash prints a fresh prompt for the new cwd; nothing reaches history),
# and \C-x0 restores the stash into the new line.
_kb_run() {
_kb_up() { printf '\033[A' >/dev/tty; }
# ctrl-e: enter opens nvim, which restores the cursor to tv's line.
_kb_git_files() {
tv git-files --inline </dev/tty
_kb_up
}
bind -x '"\C-e": _kb_git_files'
# ctrl-p, and down on an empty prompt. pj reports through $PJ_STATE: `open`
# = cancelled, `ran` = a task printed output, empty = no task sources.
_kb_pj() {
local state
state=$(mktemp) || return
PJ_STATE=$state pj "$@" </dev/tty
[ "$(<"$state")" = open ] && _kb_up
rm -f "$state"
}
bind -x '"\C-p": _kb_pj'
# ctrl-o: gho, split so the prompt is right. bind -x runs in the shell
# process, so the cd persists — but readline keeps drawing the prompt it
# started with. The macro runs \C-x1 (pick with tv, cd), then \C-x2 and \C-x3,
# which _kb_gho rebinds: after a cd, \C-x2 accepts the stashed-empty line
# (bash prints a fresh prompt for the new cwd; nothing reaches history) and
# \C-x3 does gho's clear + onefetch, after which readline redraws that fresh
# prompt below the output; when cancelled both just redraw. \C-x0 restores
# the typed text.
_kb_gho() {
local dir
_kb_line=$READLINE_LINE _kb_point=$READLINE_POINT
READLINE_LINE='' READLINE_POINT=0
"$@" </dev/tty
dir=$(tv ghq-repos --inline </dev/tty)
_kb_up
if [ -n "$dir" ] && cd "$dir"; then
READLINE_LINE='' READLINE_POINT=0
bind '"\C-x2": accept-line'
bind -x '"\C-x3": _kb_gho_show'
else
bind '"\C-x2": redraw-current-line'
bind '"\C-x3": redraw-current-line'
fi
}
_kb_gho_show() {
clear
if [ -d .git ]; then
onefetch
fi
}
_kb_restore() {
READLINE_LINE=${_kb_line-} READLINE_POINT=${_kb_point-0}
unset _kb_line _kb_point
}
bind -x '"\C-x1": _kb_gho'
bind -x '"\C-x0": _kb_restore'
# _kb_bind KEY SLOT COMMAND…
_kb_bind() {
local key=$1 slot=$2
shift 2
bind -x "\"\\C-x$slot\": _kb_run $*"
bind "\"$key\": \"\\C-x$slot\\C-m\\C-x0\""
}
_kb_bind '\C-o' 1 gho
_kb_bind '\C-e' 2 tv git-files
_kb_bind '\C-p' 3 pj
bind '"\C-o": "\C-x1\C-x2\C-x3\C-x0"'
# down: the pj cable on an idle, empty prompt, otherwise history search
# (fish's _pj_bind_down). bind -x can't call readline functions, so _kb_down
@@ -40,7 +74,7 @@ _kb_down() {
bind '"\C-x5": history-search-forward'
return
fi
PJ_QUIET=1 pj </dev/tty
PJ_QUIET=1 _kb_pj
bind '"\C-x5": redraw-current-line'
}
bind -x '"\C-x4": _kb_down'
@@ -51,7 +85,8 @@ bind '"\eOB": "\C-x4\C-x5"'
# (shell_integration.channel_triggers) and insert the picks there, quoted.
_kb_tv_autocomplete() {
local pre=${READLINE_LINE:0:READLINE_POINT} out item ins=''
out=$(tv --autocomplete-prompt "$pre" </dev/tty) || return
out=$(tv --autocomplete-prompt "$pre" --inline </dev/tty)
_kb_up
while IFS= read -r item; do
[ -n "$item" ] && ins+="$(printf '%q' "$item") "
done <<<"$out"