2026-08-13 19:44:48 -04:00
|
|
|
# ~/.config/zsh/keybinds.zsh — zle ports of fish_user_key_bindings.fish.
|
|
|
|
|
# Keys owned by kitty.conf never reach the shell and are NOT bound here:
|
|
|
|
|
# ctrl-h/j/k/l → vim-aware split nav (pass_keys.py).
|
|
|
|
|
|
|
|
|
|
bindkey -e # pin emacs keymap ($EDITOR containing "vi" would pick viins)
|
|
|
|
|
unsetopt flow_control # free ^Q/^S in zle so the ctrl-q exit bind fires
|
|
|
|
|
|
|
|
|
|
# Generic runner: widget `run-<cmd>` executes <cmd> (function or binary) with
|
|
|
|
|
# the tty as stdin, then repaints — fish's `commandline -f repaint`.
|
|
|
|
|
# cwd changes from gho/yy persist: widgets run in the shell process.
|
2026-09-30 11:14:14 -04:00
|
|
|
# gho, pj and `tv git-files` open television cables (~/.config/television/
|
|
|
|
|
# cable) — the same keys do the same in fish and bash.
|
2026-08-13 19:44:48 -04:00
|
|
|
_zle-run() {
|
|
|
|
|
local cmd=${WIDGET#run-}
|
|
|
|
|
zle -I
|
|
|
|
|
$cmd </dev/tty
|
|
|
|
|
zle reset-prompt
|
|
|
|
|
}
|
2026-08-13 19:45:50 -04:00
|
|
|
for _cmd in purple clip-last gho pj omp yy lazygit; do
|
2026-08-13 19:44:48 -04:00
|
|
|
zle -N "run-$_cmd" _zle-run
|
|
|
|
|
done
|
|
|
|
|
unset _cmd
|
|
|
|
|
|
2026-09-30 11:14:14 -04:00
|
|
|
# ctrl-e: tv git-files (bat preview, enter opens nvim).
|
|
|
|
|
_zle-tv-git-files() {
|
|
|
|
|
zle -I
|
|
|
|
|
tv git-files </dev/tty
|
|
|
|
|
zle reset-prompt
|
|
|
|
|
}
|
|
|
|
|
zle -N tv-git-files _zle-tv-git-files
|
|
|
|
|
bindkey '^E' tv-git-files
|
2026-08-13 19:44:48 -04:00
|
|
|
bindkey '^B' run-purple
|
|
|
|
|
bindkey '^Y' run-clip-last
|
|
|
|
|
bindkey '^O' run-gho
|
|
|
|
|
bindkey '^P' run-pj
|
|
|
|
|
bindkey '^A' run-omp
|
2026-09-30 11:14:14 -04:00
|
|
|
# ctrl-f: yazi; yy cd's to yazi's exit dir on quit.
|
2026-08-13 19:44:48 -04:00
|
|
|
bindkey '^F' run-yy
|
|
|
|
|
bindkey '^G' run-lazygit
|
|
|
|
|
|
2026-09-30 11:14:14 -04:00
|
|
|
# down: the pj cable on an idle, empty prompt; otherwise normal history /
|
|
|
|
|
# multiline movement (fish's _pj_bind_down). PJ_QUIET makes it a silent no-op
|
|
|
|
|
# outside projects.
|
|
|
|
|
_zle-pj-down() {
|
|
|
|
|
if [[ -n $BUFFER ]]; then
|
|
|
|
|
zle down-line-or-history
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
zle -I
|
|
|
|
|
PJ_QUIET=1 pj </dev/tty
|
|
|
|
|
zle reset-prompt
|
|
|
|
|
}
|
|
|
|
|
zle -N pj-down _zle-pj-down
|
|
|
|
|
bindkey '^[[B' pj-down
|
|
|
|
|
bindkey '^[OB' pj-down
|
|
|
|
|
|
2026-08-13 19:44:48 -04:00
|
|
|
# ctrl-q mirrors ctrl-d's preset (`exit`) — quit the shell.
|
|
|
|
|
_zle-exit() { exit }
|
|
|
|
|
zle -N _zle-exit
|
|
|
|
|
bindkey '^Q' _zle-exit
|
|
|
|
|
|
|
|
|
|
# ctrl-c at the prompt: wipe any typed text AND clear screen + kitty
|
|
|
|
|
# scrollback (2J/3J drops it, like the fish `clear` wrapper). ^C is the tty
|
|
|
|
|
# INTR char, so this lives in TRAPINT — bindkey '^C' would never fire.
|
|
|
|
|
# Mid-command SIGINT behaves normally (128+SIGINT). BUFFER is read-only in
|
|
|
|
|
# trap context, so builtin widgets are invoked via `zle .name` instead.
|
|
|
|
|
TRAPINT() {
|
|
|
|
|
if zle; then
|
|
|
|
|
zle .kill-buffer
|
|
|
|
|
printf '\033[2J\033[3J\033[1;1H'
|
|
|
|
|
zle .reset-prompt
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
return $(( 128 + $1 ))
|
|
|
|
|
}
|