Skip to content

Commit 6bcd4dc

Browse files
committed
Improve performance by binding copycat keys just once
All of the copycat scripts check to make sure we're in copycat mode, and if we're not they are essentially a no-op. This means we can safely leave the keys bound to those scripts even when we're not in copycat mode. The benefit of this is that we don't have to bind and unbind the keys every time we enter or leave copycat mode, which helps improve performance.
1 parent ca3d52d commit 6bcd4dc

File tree

5 files changed

+29
-46
lines changed

5 files changed

+29
-46
lines changed

copycat.tmux

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,14 @@ set_copycat_git_special_binding() {
6262
done
6363
}
6464

65+
set_copycat_mode_bindings() {
66+
"$CURRENT_DIR/scripts/copycat_mode_bindings.sh"
67+
}
68+
6569
main() {
6670
set_start_bindings
6771
set_copycat_search_binding
6872
set_copycat_git_special_binding
73+
set_copycat_mode_bindings
6974
}
7075
main

scripts/copycat_mode_bindings.sh

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,27 @@ fi
1414
extend_key() {
1515
local key="$1"
1616
local script="$2"
17-
local cmd
17+
local copy_mode
18+
copy_mode=$(tmux_copy_mode_string)
1819

19-
# 1. 'cmd' or 'key' is sent to tmux. This ensures the default key action is done.
20+
# 1. The default command for 'key' is sent to tmux. This ensures the
21+
# default key action is done.
2022
# 2. Script is executed.
21-
# 3. `true` command ensures an exit status 0 is returned. This ensures a
22-
# user never gets an error msg - even if the script file from step 2 is
23-
# deleted.
24-
# We fetch the current behavior of the 'key' mapping in
25-
# variable 'cmd'
26-
cmd=$(tmux list-keys -T $(tmux_copy_mode_string) | $AWK_CMD '$4 == "'$key'"' | $AWK_CMD '{ $1=""; $2=""; $3=""; $4=""; sub(" ", " "); print }')
27-
# If 'cmd' is already a copycat command, we do nothing
28-
if echo "$cmd" | grep -q copycat; then
29-
return
30-
fi
31-
# We save the previous mapping to a file in order to be able to recover
32-
# the previous mapping when we unbind
33-
tmux list-keys -T $(tmux_copy_mode_string) | $AWK_CMD '$4 == "'$key'"' >> "${TMPDIR:-/tmp}/copycat_$(whoami)_recover_keys"
34-
tmux bind-key -T $(tmux_copy_mode_string) "$key" run-shell "tmux $cmd; $script; true"
23+
# 3. `true` command ensures an exit status 0 is returned. This ensures
24+
# a user never gets an error msg - even if the script file from step 2
25+
# is deleted.
26+
tmux list-keys -T "$copy_mode" |
27+
"$AWK_CMD" '
28+
/copycat/ { next }
29+
$3 == "'"$copy_mode"'" && $4 == "'"$key"'" {
30+
$1=""
31+
$2=""
32+
$3=""
33+
$4=""
34+
gsub(";", "\\;", $0)
35+
cmd=$0
36+
system("tmux bind-key -T '"$copy_mode"' '"$key"' run-shell \"tmux " cmd "; '"$script"'; true\"")
37+
}'
3538
}
3639

3740
copycat_cancel_bindings() {

scripts/copycat_mode_quit.sh

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,11 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
44

55
source "$CURRENT_DIR/helpers.sh"
66

7-
unbind_cancel_bindings() {
8-
local cancel_mode_bindings=$(copycat_quit_copy_mode_keys)
9-
local key
10-
for key in $cancel_mode_bindings; do
11-
tmux unbind-key -n "$key"
12-
done
13-
}
14-
15-
unbind_prev_next_bindings() {
16-
tmux unbind-key -n "$(copycat_next_key)"
17-
tmux unbind-key -n "$(copycat_prev_key)"
18-
}
19-
20-
unbind_all_bindings() {
21-
grep -v copycat <"${TMPDIR:-/tmp}/copycat_$(whoami)_recover_keys" | while read -r key_cmd; do
22-
sh -c "tmux $key_cmd"
23-
done < /dev/stdin
24-
rm "${TMPDIR:-/tmp}/copycat_$(whoami)_recover_keys"
25-
}
26-
277
main() {
288
if in_copycat_mode; then
299
reset_copycat_position
3010
unset_copycat_mode
3111
copycat_decrease_counter
32-
# removing all bindings only if no panes are in copycat mode
33-
if copycat_counter_zero; then
34-
unbind_all_bindings
35-
fi
3612
fi
3713
}
3814
main

scripts/copycat_mode_start.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ main() {
1414
local pattern="$1"
1515
if supported_tmux_version_ok; then
1616
$CURRENT_DIR/copycat_generate_results.sh "$pattern" # will `exit 0` if no results
17-
$CURRENT_DIR/copycat_mode_bindings.sh
1817
$CURRENT_DIR/copycat_jump.sh 'next'
1918
fi
2019
}

scripts/helpers.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ tmux_copy_mode() {
4242
}
4343

4444
tmux_copy_mode_string() {
45-
if [ $(tmux_copy_mode) == 'vi' ]; then
46-
echo copy-mode-vi
47-
else
48-
echo copy-mode
49-
fi
45+
if [ $(tmux_copy_mode) == 'vi' ]; then
46+
echo copy-mode-vi
47+
else
48+
echo copy-mode
49+
fi
5050
}
5151

5252
# === copycat mode specific helpers ===

0 commit comments

Comments
 (0)