Files
dotfiles/.config/tmux/textobjs.sh
Julian Prein 120285c478 tmux:textobjs: Do not use scroll_region
scroll_region_{upper,lower} are only modified by the DECSTBM escape
sequence:

> This control function sets the top and bottom margins for the current
> page. You cannot perform scrolling outside the margins.

And are 0 and pane_height - 1 otherwise. Tmux implements these such that
command output can't be displayed outside these margins, but the cursor
in copy-mode can. This means that using them to check if the cursor is
at the very top or bottom can break in certain situation (even those
seem extremely rare since I have never heard of this escape sequence).

Get rid of them and just use 0 and the pane height.

[1]: https://vt100.net/docs/vt510-rm/DECSTBM.html
2024-07-05 14:26:05 +02:00

84 lines
1.8 KiB
Bash
Executable File

#!/bin/sh
# Support vim's text objects in tmux's copy-mode.
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
# cancel copy-mode when not in 'visual' mode (i.e. selection is present)
selection_present="$(get_var selection_present)"
if [ "$selection_present" -eq 0 ]; then
tmux send -X cancel
exit 0
fi
# get motion
motion="$(command_prompt "(operator-pending)")"
# TODO: Breaks when on the beginning or end of the object (except paragraphs)
case "$motion" in
w)
# send "boe"
tmux send -X previous-word
tmux send -X other-end
tmux send -X next-word-end
;;
W)
# send "BoE"
tmux send -X previous-space
tmux send -X other-end
tmux send -X next-space-end
;;
p)
# send "{j0o}k$"
tmux send -X previous-paragraph
scroll_pos="$(get_var scroll_position)"
hist_size="$(get_var history_size)"
cursor_y="$(get_var copy_cursor_y)"
# don't move down if we're at the very first paragraph
if [ "$scroll_pos" -lt "$hist_size" ] || [ "$cursor_y" -gt 0 ]
then
tmux send -X cursor-down
fi
tmux send -X start-of-line
tmux send -X other-end
tmux send -X next-paragraph
scroll_pos="$(get_var scroll_position)"
cursor_y="$(get_var copy_cursor_y)"
pane_height="$(get_var pane_height)"
: "$((pane_height -= 1))"
# don't move up if we're at the very last paragraph
if [ "$scroll_pos" -gt 0 ] || [ "$cursor_y" -lt "$pane_height" ]
then
tmux send -X cursor-up
fi
tmux send -X end-of-line
;;
\")
tmux send -X jump-to-backward '"'
tmux send -X other-end
tmux send -X jump-to-forward '"'
;;
\')
tmux send -X jump-to-backward "'"
tmux send -X other-end
tmux send -X jump-to-forward "'"
;;
esac