tmux: Support repeatable yank motions via yank.sh

Implementing logic inside tmux's config starts to become tedious with
growing complexity. Introduce a shell script that handles the logic of
the (now also repeatable) vim-like bindings.
This commit is contained in:
2024-07-04 14:30:56 +02:00
parent 91d34358ec
commit ec637ad1c8
2 changed files with 56 additions and 17 deletions

54
.config/tmux/yank.sh Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/sh
get_var() {
tmux display-message -p "#{$1}"
}
command_prompt() {
tmux command-prompt -k -I "$2" -p "$1" 'display-message -p "%%"'
}
mode="$(get_var pane_mode)"
if [ "$mode" != copy-mode ]; then
>&2 printf "%s: Not in copy mode\n" "$0"
exit 1
fi
# Just yank if we have a selection already
selection_present="$(get_var selection_present)"
if [ "$selection_present" -eq 1 ]; then
tmux send -X copy-pipe
exit 0
fi
# get motion
motion="$(command_prompt "(operator-pending)")"
# accumulate repeat number
# NOTE: -N unfortunately does not work since the first non-numeric key press is
# lost then (TODO: is it really?)
while printf "%s" "$motion" | grep -q '^[0-9]$'; do
repeat="$repeat$motion"
motion="$(command_prompt "(operator-pending-repeat)" "$repeat")"
done
# default to 1 if no repeat was specified
: "${repeat:=1}"
# abort on Escape
[ "$motion" != "Escape" ] || exit 0
# choose between character or line-wise selection
case "$motion" in
y)
repeat="$((repeat - 1))"
motion="j"
tmux send -X select-line;;
j|k)
tmux send -X select-line;;
*)
tmux send -X begin-selection;;
esac
# move and yank
[ "$repeat" -eq 0 ] || tmux send -N "$repeat" "$motion"
tmux send -X copy-pipe