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:
@@ -132,23 +132,8 @@ bind -T copy-mode-vi C-v {
|
||||
send -X rectangle-toggle
|
||||
}
|
||||
|
||||
# Yank into system clipboard
|
||||
# TODO: This breaks on repeatable movements (e.g. `y2e`)
|
||||
bind -T copy-mode-vi y \
|
||||
if -F "#{selection_present}" {
|
||||
send -X copy-pipe
|
||||
} {
|
||||
command-prompt -k -p (operator-pending) {
|
||||
# do line-wise yank on yy
|
||||
if -F "#{==:%1,y}" {
|
||||
send -X select-line
|
||||
} {
|
||||
send -X begin-selection
|
||||
send "%1"
|
||||
}
|
||||
send -X copy-pipe
|
||||
}
|
||||
}
|
||||
# Yank into system clipboard with vim-like bindings
|
||||
bind -T copy-mode-vi y run-shell '${XDG_CONFIG_HOME:-$HOME/.config}/tmux/yank.sh'
|
||||
bind -T copy-mode-vi Y \
|
||||
if -F "#{selection_present}" { send -X copy-pipe-line } { send -X copy-pipe-end-of-line }
|
||||
|
||||
|
||||
54
.config/tmux/yank.sh
Executable file
54
.config/tmux/yank.sh
Executable 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
|
||||
Reference in New Issue
Block a user