193 lines
4.1 KiB
Bash
193 lines
4.1 KiB
Bash
|
# config options
|
||
|
|
||
|
default_next_key="n"
|
||
|
tmux_option_next="@copycat_next"
|
||
|
|
||
|
default_prev_key="N"
|
||
|
tmux_option_prev="@copycat_prev"
|
||
|
|
||
|
# keeps track of number of panes in copycat mode
|
||
|
tmux_option_counter="@copycat_counter"
|
||
|
|
||
|
# === awk vs gawk ===
|
||
|
command_exists() {
|
||
|
command -v "$@" > /dev/null 2>&1
|
||
|
}
|
||
|
AWK_CMD='awk'
|
||
|
if command_exists gawk; then
|
||
|
AWK_CMD='gawk'
|
||
|
fi
|
||
|
|
||
|
# === general helpers ===
|
||
|
|
||
|
get_tmux_option() {
|
||
|
local option=$1
|
||
|
local default_value=$2
|
||
|
local option_value=$(tmux show-option -gqv "$option")
|
||
|
if [ -z "$option_value" ]; then
|
||
|
echo "$default_value"
|
||
|
else
|
||
|
echo "$option_value"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
set_tmux_option() {
|
||
|
local option=$1
|
||
|
local value=$2
|
||
|
tmux set-option -gq "$option" "$value"
|
||
|
}
|
||
|
|
||
|
tmux_copy_mode() {
|
||
|
tmux show-option -gwv mode-keys
|
||
|
}
|
||
|
|
||
|
tmux_copy_mode_string() {
|
||
|
if [ $(tmux_copy_mode) == 'vi' ]; then
|
||
|
echo copy-mode-vi
|
||
|
else
|
||
|
echo copy-mode
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# === copycat mode specific helpers ===
|
||
|
|
||
|
set_copycat_mode() {
|
||
|
set_tmux_option "$(_copycat_mode_var)" "true"
|
||
|
}
|
||
|
|
||
|
unset_copycat_mode() {
|
||
|
set_tmux_option "$(_copycat_mode_var)" "false"
|
||
|
}
|
||
|
|
||
|
in_copycat_mode() {
|
||
|
local copycat_mode=$(get_tmux_option "$(_copycat_mode_var)" "false")
|
||
|
[ "$copycat_mode" == "true" ]
|
||
|
}
|
||
|
|
||
|
not_in_copycat_mode() {
|
||
|
if in_copycat_mode; then
|
||
|
return 1
|
||
|
else
|
||
|
return 0
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# === copycat mode position ===
|
||
|
|
||
|
get_copycat_position() {
|
||
|
local copycat_position_variable=$(_copycat_position_var)
|
||
|
echo $(get_tmux_option "$copycat_position_variable" "0")
|
||
|
}
|
||
|
|
||
|
set_copycat_position() {
|
||
|
local position="$1"
|
||
|
local copycat_position_variable=$(_copycat_position_var)
|
||
|
set_tmux_option "$copycat_position_variable" "$position"
|
||
|
}
|
||
|
|
||
|
reset_copycat_position() {
|
||
|
set_copycat_position "0"
|
||
|
}
|
||
|
|
||
|
# === scrollback and results position ===
|
||
|
|
||
|
get_scrollback_filename() {
|
||
|
echo "$(_get_tmp_dir)/scrollback-$(_pane_unique_id)"
|
||
|
}
|
||
|
|
||
|
get_copycat_filename() {
|
||
|
echo "$(_get_tmp_dir)/results-$(_pane_unique_id)"
|
||
|
}
|
||
|
|
||
|
# Ensures a message is displayed for 5 seconds in tmux prompt.
|
||
|
# Does not override the 'display-time' tmux option.
|
||
|
display_message() {
|
||
|
local message="$1"
|
||
|
|
||
|
# display_duration defaults to 5 seconds, if not passed as an argument
|
||
|
if [ "$#" -eq 2 ]; then
|
||
|
local display_duration="$2"
|
||
|
else
|
||
|
local display_duration="5000"
|
||
|
fi
|
||
|
|
||
|
# saves user-set 'display-time' option
|
||
|
local saved_display_time=$(get_tmux_option "display-time" "750")
|
||
|
|
||
|
# sets message display time to 5 seconds
|
||
|
tmux set-option -gq display-time "$display_duration"
|
||
|
|
||
|
# displays message
|
||
|
tmux display-message "$message"
|
||
|
|
||
|
# restores original 'display-time' value
|
||
|
tmux set-option -gq display-time "$saved_display_time"
|
||
|
}
|
||
|
|
||
|
# === counter functions ===
|
||
|
|
||
|
copycat_increase_counter() {
|
||
|
local count=$(get_tmux_option "$tmux_option_counter" "0")
|
||
|
local new_count="$((count + 1))"
|
||
|
set_tmux_option "$tmux_option_counter" "$new_count"
|
||
|
}
|
||
|
|
||
|
copycat_decrease_counter() {
|
||
|
local count="$(get_tmux_option "$tmux_option_counter" "0")"
|
||
|
if [ "$count" -gt "0" ]; then
|
||
|
# decreasing the counter only if it won't go below 0
|
||
|
local new_count="$((count - 1))"
|
||
|
set_tmux_option "$tmux_option_counter" "$new_count"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
copycat_counter_zero() {
|
||
|
local count="$(get_tmux_option "$tmux_option_counter" "0")"
|
||
|
[ "$count" -eq "0" ]
|
||
|
}
|
||
|
|
||
|
# === key binding functions ===
|
||
|
|
||
|
copycat_next_key() {
|
||
|
echo "$(get_tmux_option "$tmux_option_next" "$default_next_key")"
|
||
|
}
|
||
|
|
||
|
copycat_prev_key() {
|
||
|
echo "$(get_tmux_option "$tmux_option_prev" "$default_prev_key")"
|
||
|
}
|
||
|
|
||
|
# function expected output: 'C-c Enter q'
|
||
|
copycat_quit_copy_mode_keys() {
|
||
|
local commands_that_quit_copy_mode="cancel"
|
||
|
local copy_mode="$(tmux_copy_mode_string)"
|
||
|
tmux list-keys -T "$copy_mode" |
|
||
|
\grep "$commands_that_quit_copy_mode" |
|
||
|
$AWK_CMD '{ print $4 }' |
|
||
|
sort -u |
|
||
|
sed 's/C-j//g' |
|
||
|
xargs echo
|
||
|
}
|
||
|
|
||
|
# === 'private' functions ===
|
||
|
|
||
|
_copycat_mode_var() {
|
||
|
local pane_id="$(_pane_unique_id)"
|
||
|
echo "@copycat_mode_$pane_id"
|
||
|
}
|
||
|
|
||
|
_copycat_position_var() {
|
||
|
local pane_id="$(_pane_unique_id)"
|
||
|
echo "@copycat_position_$pane_id"
|
||
|
}
|
||
|
|
||
|
_get_tmp_dir() {
|
||
|
echo "${TMPDIR:-/tmp}/tmux-$EUID-copycat"
|
||
|
}
|
||
|
|
||
|
# returns a string unique to current pane
|
||
|
# sed removes `$` sign because `session_id` contains is
|
||
|
_pane_unique_id() {
|
||
|
tmux display-message -p "#{session_id}-#{window_index}-#{pane_index}" |
|
||
|
sed 's/\$//'
|
||
|
}
|