Skip to content

Commit b45fc40

Browse files
authored
perf: open popup window and run hooks in a single execution (#46)
1 parent 53ff411 commit b45fc40

File tree

7 files changed

+80
-75
lines changed

7 files changed

+80
-75
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ follows <https://www.conventionalcommits.org/en/v1.0.0/> to track changes.
4343
[@szaffarano])
4444
- Support specifying the socket path for the popup server ([#43])
4545

46+
### Changed
47+
48+
- The `before-open` and `after-close` hooks are called in the same execution
49+
that opens a popup window. This should rarely have side effects ([#46])
50+
4651
### Fixed
4752

4853
- Support OSX's ancient Bash ([#44])
@@ -52,6 +57,7 @@ follows <https://www.conventionalcommits.org/en/v1.0.0/> to track changes.
5257
[#43]: https://github.com/loichyan/tmux-toggle-popup/pull/43
5358
[#44]: https://github.com/loichyan/tmux-toggle-popup/pull/44
5459
[#45]: https://github.com/loichyan/tmux-toggle-popup/pull/45
60+
[#46]: https://github.com/loichyan/tmux-toggle-popup/pull/46
5561
[NixOS/nixpkgs#428294]: https://github.com/NixOS/nixpkgs/pull/428294
5662
[@szaffarano]: https://github.com/szaffarano
5763

src/toggle.sh

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,45 +40,46 @@ usage() {
4040
EOF
4141
}
4242

43-
# Prepares the tmux commands to open a popup. After called,
43+
# Prepares the tmux commands to initialize a popup session. After called,
4444
#
45-
# - `open_cmds` is used to initialize the popup session
45+
# - `init_cmds` is used to initialize the popup session
4646
# - `on_cleanup` is used to undo temporary changes on the popup server
4747
# - `popup_id` is set to the name of the target popup session
48-
declare open_cmds=() on_cleanup=() popup_id
49-
prepare_open() {
48+
declare init_cmds=() on_cleanup=() popup_id
49+
prepare_init() {
5050
popup_id=${id:-$(interpolate popup_name="$name" "$id_format")}
5151
popup_id=$(escape_session_name "$popup_id")
5252
if [[ -n $open_dir ]]; then
53+
# Interpolate `{popup_caller_path}`, `{popup_caller_pane_path}`.
5354
open_args+=(-c "$(interpolate popup_caller_path="$caller_path" \
5455
popup_caller_pane_path="$caller_pane_path" "$open_dir")")
5556
fi
5657

57-
open_cmds=()
58+
init_cmds=()
5859
if [[ $1 == "open" ]]; then
59-
open_cmds+=(new -As "$popup_id" "${open_args[@]}" "${program[@]}" \;)
60+
init_cmds+=(new -As "$popup_id" "${open_args[@]}" "${program[@]}" \;)
6061
else
6162
if ! tmux has -t "$popup_id" 2>/dev/null; then
62-
open_cmds+=(new -ds "$popup_id" "${open_args[@]}" "${program[@]}" \;)
63+
init_cmds+=(new -ds "$popup_id" "${open_args[@]}" "${program[@]}" \;)
6364
fi
64-
open_cmds+=(switch -t "$popup_id" \;)
65+
init_cmds+=(switch -t "$popup_id" \;)
6566
fi
6667

6768
# Export internal variables
68-
open_cmds+=(set @__popup_name "$name" \;)
69-
open_cmds+=(set @__popup_id_format "$id_format" \;)
70-
open_cmds+=(set @__popup_caller_path "$caller_path" \;)
71-
open_cmds+=(set @__popup_caller_pane_path "$caller_pane_path" \;)
69+
init_cmds+=(set @__popup_name "$name" \;)
70+
init_cmds+=(set @__popup_id_format "$id_format" \;)
71+
init_cmds+=(set @__popup_caller_path "$caller_path" \;)
72+
init_cmds+=(set @__popup_caller_pane_path "$caller_pane_path" \;)
7273

7374
# Create temporary toggle keys in the opened popup
7475
# shellcheck disable=SC2206
7576
for k in "${toggle_keys[@]}"; do
76-
open_cmds+=(bind $k run "#{@popup-toggle} $(escape "${args[@]}")" \;)
77+
init_cmds+=(bind $k run "#{@popup-toggle} $(escape "${args[@]}")" \;)
7778
on_cleanup+=(unbind $k \;)
7879
done
7980

8081
if parse_cmds "$on_init"; then
81-
open_cmds+=("${cmds[@]}")
82+
init_cmds+=("${cmds[@]}")
8283
fi
8384
}
8485

@@ -153,8 +154,8 @@ main() {
153154
elif [[ $toggle_mode == "switch" ]]; then
154155
# Inherit the caller's ID format in switch mode
155156
id_format=${caller_id_format}
156-
prepare_open "switch"
157-
tmux "${open_cmds[@]}"
157+
prepare_init "switch"
158+
tmux "${init_cmds[@]}"
158159
return
159160
elif [[ $toggle_mode != "force-open" ]]; then
160161
die "illegal toggle mode: $toggle_mode"
@@ -169,37 +170,47 @@ main() {
169170
popup_server=${socket_name}
170171
fi
171172

172-
# Run hook: before-open
173-
if parse_cmds "$before_open"; then tmux "${cmds[@]}"; fi
173+
# Command sequence to open the popup window, including hooks.
174+
open_cmds=()
175+
176+
# Handle hook: before-open
177+
if parse_cmds "$before_open"; then open_cmds+=("${cmds[@]}" \;); fi
174178

175179
# This session is the caller, so use it's path
176180
caller_path=${session_path}
177181
caller_pane_path=${pane_path}
178-
prepare_open "open"
182+
prepare_init "open"
179183

184+
# Script to initialize the popup session inside a popup window.
180185
open_script=""
181-
# Revert to the user's default shell.
182-
open_script+="tmux set default-shell '$default_shell'"
183-
# Set $TMUX_POPUP_SERVER so as to identify the popup server,
184-
# and propagate user's default shell.
185-
open_script+="; export TMUX_POPUP_SERVER='$popup_server' SHELL='$default_shell'"
186-
# Suppress stdout to hide the `[detached] ...` message
187-
open_script+="; exec tmux $(escape "${popup_socket[@]}" "${open_cmds[@]}") >/dev/null"
188186

189187
# Starting from version 3.5, tmux uses the user's `default-shell` to execute
190188
# shell commands. However, our scripts require sh(1) and may not be parsed
191189
# correctly by some incompatible shells. In this case, we change the default
192190
# shell to `/bin/sh` and then revert it immediately.
193-
tmux set default-shell "/bin/sh" \; popup "${display_args[@]}" "$open_script"
191+
open_script+="tmux set default-shell '$default_shell' ;"
192+
open_cmds+=(set default-shell "/bin/sh" \;)
193+
194+
# Set $TMUX_POPUP_SERVER to identify the popup server.
195+
# Propagate user's default shell.
196+
open_script+="export TMUX_POPUP_SERVER='$popup_server' ;"
197+
open_script+="export SHELL='$default_shell' ;"
198+
199+
# Suppress stdout to hide the `[detached] ...` message
200+
open_script+="exec tmux $(escape "${popup_socket[@]}" "${init_cmds[@]}") >/dev/null"
201+
open_cmds+=(display-popup "${display_args[@]}" "$open_script" \;)
202+
203+
# Handle hook: after-close
204+
if parse_cmds "$after_close"; then open_cmds+=("${cmds[@]}" \;); fi
205+
206+
# Do open the popup window
207+
tmux "${open_cmds[@]}"
194208

195209
# Undo temporary changes on the popup server
196210
if [[ -z $opened_name && ${#on_cleanup} -gt 0 ]]; then
197211
# Ignore error if the server has already stopped
198212
tmux -N "${popup_socket[@]}" "${on_cleanup[@]}" 2>/dev/null || true
199213
fi
200-
201-
# Run hook: after-close
202-
if parse_cmds "$after_close"; then tmux "${cmds[@]}"; fi
203214
}
204215

205216
args=("$@")

src/toggle_tests/open_nested_popup.stdout

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@ before-open
44
;
55
run
66
#{@before_open}
7-
<<<TMUX:END(1)
8-
9-
>>>TMUX:BEGIN(2)
7+
;
108
set
119
default-shell
1210
/bin/sh
1311
;
14-
popup
15-
tmux set default-shell '/usr/bin/fish'; export TMUX_POPUP_SERVER='popup_server2' SHELL='/usr/bin/fish'; exec tmux -S socket/path/popup_server2 new -As pane/path/p_open_nested_2 \; set @__popup_name p_open_nested_2 \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; display on-init \; run \#\{@on_init\} >/dev/null
16-
<<<TMUX:END(2)
17-
18-
>>>TMUX:BEGIN(3)
12+
display-popup
13+
tmux set default-shell '/usr/bin/fish' ;export TMUX_POPUP_SERVER='popup_server2' ;export SHELL='/usr/bin/fish' ;exec tmux -S socket/path/popup_server2 new -As pane/path/p_open_nested_2 \; set @__popup_name p_open_nested_2 \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; display on-init \; run \#\{@on_init\} >/dev/null
14+
;
1915
display
2016
after-close
2117
;
2218
run
2319
#{@after_close}
24-
<<<TMUX:END(3)
20+
;
21+
<<<TMUX:END(1)
2522

src/toggle_tests/open_nested_with_toggle_key.stdout

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@ before-open
44
;
55
run
66
#{@before_open}
7-
<<<TMUX:END(1)
8-
9-
>>>TMUX:BEGIN(2)
7+
;
108
set
119
default-shell
1210
/bin/sh
1311
;
14-
popup
15-
tmux set default-shell '/usr/bin/fish'; export TMUX_POPUP_SERVER='popup_server2' SHELL='/usr/bin/fish'; exec tmux -S socket/path/popup_server2 new -As pane/path/p_nested_toggle_key_2 \; set @__popup_name p_nested_toggle_key_2 \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; bind -n M-o run \#\{@popup-toggle\}\ --name=p_nested_toggle_key_2\ --toggle-key=-n\\\ M-o\ \; display on-init \; run \#\{@on_init\} >/dev/null
16-
<<<TMUX:END(2)
17-
18-
>>>TMUX:BEGIN(3)
12+
display-popup
13+
tmux set default-shell '/usr/bin/fish' ;export TMUX_POPUP_SERVER='popup_server2' ;export SHELL='/usr/bin/fish' ;exec tmux -S socket/path/popup_server2 new -As pane/path/p_nested_toggle_key_2 \; set @__popup_name p_nested_toggle_key_2 \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; bind -n M-o run \#\{@popup-toggle\}\ --name=p_nested_toggle_key_2\ --toggle-key=-n\\\ M-o\ \; display on-init \; run \#\{@on_init\} >/dev/null
14+
;
1915
display
2016
after-close
2117
;
2218
run
2319
#{@after_close}
24-
<<<TMUX:END(3)
20+
;
21+
<<<TMUX:END(1)
2522

src/toggle_tests/open_popup.stdout

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@ before-open
44
;
55
run
66
#{@before_open}
7-
<<<TMUX:END(1)
8-
9-
>>>TMUX:BEGIN(2)
7+
;
108
set
119
default-shell
1210
/bin/sh
1311
;
14-
popup
15-
tmux set default-shell '/usr/bin/fish'; export TMUX_POPUP_SERVER='popup_server2' SHELL='/usr/bin/fish'; exec tmux -S socket/path/popup_server2 new -As pane/path/p_open \; set @__popup_name p_open \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; display on-init \; run \#\{@on_init\} >/dev/null
16-
<<<TMUX:END(2)
17-
18-
>>>TMUX:BEGIN(3)
12+
display-popup
13+
tmux set default-shell '/usr/bin/fish' ;export TMUX_POPUP_SERVER='popup_server2' ;export SHELL='/usr/bin/fish' ;exec tmux -S socket/path/popup_server2 new -As pane/path/p_open \; set @__popup_name p_open \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; display on-init \; run \#\{@on_init\} >/dev/null
14+
;
1915
display
2016
after-close
2117
;
2218
run
2319
#{@after_close}
24-
<<<TMUX:END(3)
20+
;
21+
<<<TMUX:END(1)
2522

src/toggle_tests/open_with_toggle_key.stdout

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,23 @@ before-open
44
;
55
run
66
#{@before_open}
7-
<<<TMUX:END(1)
8-
9-
>>>TMUX:BEGIN(2)
7+
;
108
set
119
default-shell
1210
/bin/sh
1311
;
14-
popup
15-
tmux set default-shell '/usr/bin/fish'; export TMUX_POPUP_SERVER='popup_server2' SHELL='/usr/bin/fish'; exec tmux -S socket/path/popup_server2 new -As pane/path/p_toggle_key \; set @__popup_name p_toggle_key \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; bind -T root M-p run \#\{@popup-toggle\}\ --name=p_toggle_key\ --toggle-key=-T\\\ root\\\ M-p\ --toggle-key=-n\\\ M-o\ \; bind -n M-o run \#\{@popup-toggle\}\ --name=p_toggle_key\ --toggle-key=-T\\\ root\\\ M-p\ --toggle-key=-n\\\ M-o\ \; display on-init \; run \#\{@on_init\} >/dev/null
16-
<<<TMUX:END(2)
12+
display-popup
13+
tmux set default-shell '/usr/bin/fish' ;export TMUX_POPUP_SERVER='popup_server2' ;export SHELL='/usr/bin/fish' ;exec tmux -S socket/path/popup_server2 new -As pane/path/p_toggle_key \; set @__popup_name p_toggle_key \; set @__popup_id_format pane/path/\{popup_name\} \; set @__popup_caller_path working/session/path \; set @__popup_caller_pane_path working/pane/path \; bind -T root M-p run \#\{@popup-toggle\}\ --name=p_toggle_key\ --toggle-key=-T\\\ root\\\ M-p\ --toggle-key=-n\\\ M-o\ \; bind -n M-o run \#\{@popup-toggle\}\ --name=p_toggle_key\ --toggle-key=-T\\\ root\\\ M-p\ --toggle-key=-n\\\ M-o\ \; display on-init \; run \#\{@on_init\} >/dev/null
14+
;
15+
display
16+
after-close
17+
;
18+
run
19+
#{@after_close}
20+
;
21+
<<<TMUX:END(1)
1722

18-
>>>TMUX:BEGIN(3)
23+
>>>TMUX:BEGIN(2)
1924
-N
2025
-S
2126
socket/path/popup_server2
@@ -28,13 +33,5 @@ unbind
2833
-n
2934
M-o
3035
;
31-
<<<TMUX:END(3)
32-
33-
>>>TMUX:BEGIN(4)
34-
display
35-
after-close
36-
;
37-
run
38-
#{@after_close}
39-
<<<TMUX:END(4)
36+
<<<TMUX:END(2)
4037

toggle-popup.tmux

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ handle_exports() {
2222
handle_autostart() {
2323
# Do not start itself within a popup server
2424
if [[ $autostart == "on" && -z $TMUX_POPUP_SERVER ]]; then
25-
# Set $TMUX_POPUP_SERVER so as to identify the popup server,
26-
# and propagate user's default shell.
25+
# Set $TMUX_POPUP_SERVER to identify the popup server.
26+
# Propagate user's default shell.
2727
env \
2828
TMUX_POPUP_SERVER="$socket_name" \
2929
SHELL="$default_shell" \

0 commit comments

Comments
 (0)