Add support for linked windows
parent
e3f05dd34f
commit
319c129cbd
|
@ -272,6 +272,34 @@ restore_pane_layout_for_each_window() {
|
|||
done
|
||||
}
|
||||
|
||||
restore_linked_windows() {
|
||||
\grep '^link' $(last_resurrect_file) |
|
||||
while IFS=$d read line_type session_name window_number window_source; do
|
||||
if session_exists "$session_name"; then
|
||||
tmux link-window -s "${window_source}" -t "${session_name}:${window_number}"
|
||||
else
|
||||
# Create session if it doesn't exist. This situation occurs
|
||||
# when a session only contains linked windows. Otherwise the
|
||||
# session will have been created at some point while
|
||||
# restoring the panes.
|
||||
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name"
|
||||
|
||||
local created_window_num="$(first_window_num)"
|
||||
# If the window number we created is the same as our target
|
||||
# window, we move it up by 1
|
||||
if [ $created_window_num -eq $window_number ]; then
|
||||
original_window_num=$created_window_num
|
||||
let created_window_num=$original_window_num+1
|
||||
tmux move-window -s "${session_name}:${original_window_num}" -t "${session_name}:${created_window_num}"
|
||||
fi
|
||||
tmux link-window -s "${window_source}" -t "${session_name}:${window_number}"
|
||||
# We keep the window around to the end so that the session
|
||||
# doesn't disappear
|
||||
tmux kill-window -t "${session_name}:${created_window_num}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
restore_shell_history() {
|
||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ { print $2, $3, $7, $10; }' $(last_resurrect_file) |
|
||||
while IFS=$d read session_name window_number pane_index pane_command; do
|
||||
|
@ -359,6 +387,7 @@ main() {
|
|||
restore_active_pane_for_each_window
|
||||
restore_zoomed_windows
|
||||
restore_grouped_sessions # also restores active and alt windows for grouped sessions
|
||||
restore_linked_windows
|
||||
restore_active_and_alternate_windows
|
||||
restore_active_and_alternate_sessions
|
||||
execute_hook "post-restore-all"
|
||||
|
|
|
@ -50,6 +50,8 @@ pane_format() {
|
|||
format+="#{pane_pid}"
|
||||
format+="${delimiter}"
|
||||
format+="#{history_size}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_id}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
|
@ -66,6 +68,8 @@ window_format() {
|
|||
format+=":#{window_flags}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_layout}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_id}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
|
@ -79,6 +83,35 @@ state_format() {
|
|||
echo "$format"
|
||||
}
|
||||
|
||||
set_canonical_window() {
|
||||
# We store the canonical window targets using variables named based on the
|
||||
# window id, because Bash <4.0 doesn't support associative arrays. This
|
||||
# technique is based on https://stackoverflow.com/a/11776875.
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_id_num="${3:1}"
|
||||
local window_target="${session_name}:${window_number}"
|
||||
|
||||
printf -v "CANONICAL_WINDOW__${window_id_num}" %s "$window_target"
|
||||
}
|
||||
|
||||
get_canonical_window() {
|
||||
local window_id_num="${1:1}"
|
||||
|
||||
var_name="CANONICAL_WINDOW__${window_id_num}"
|
||||
echo "${!var_name}"
|
||||
}
|
||||
|
||||
is_canonical_window() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_id="$3"
|
||||
local window_target="${session_name}:${window_number}"
|
||||
|
||||
canonical_window=$(get_canonical_window "$window_id")
|
||||
[[ "$canonical_window" == "$window_target" ]]
|
||||
}
|
||||
|
||||
dump_panes_raw() {
|
||||
tmux list-panes -a -F "$(pane_format)"
|
||||
}
|
||||
|
@ -223,15 +256,40 @@ fetch_and_dump_grouped_sessions(){
|
|||
fi
|
||||
}
|
||||
|
||||
set_canonical_windows() {
|
||||
# When multiple windows are linked via link-window, they will all share the
|
||||
# same window_id. For each window_id, we arbitrarily pick one of the linked
|
||||
# window locations (session_name:window_number) to be the canonical window. We
|
||||
# will only output information for that window, and output a link line for all
|
||||
# other windows linked to the given id.
|
||||
|
||||
# NB: We use bash process substitution instead of piping into the while
|
||||
# loop to avoid losing the variables set in set_canonical_window. See
|
||||
# http://mywiki.wooledge.org/BashFAQ/024 for more info.
|
||||
while IFS=$d read line_type session_name window_index window_active window_flags window_layout window_id; do
|
||||
# not saving windows from grouped sessions
|
||||
if is_session_grouped "$session_name"; then
|
||||
continue
|
||||
fi
|
||||
# We run this for every window, so that for any given window_id, the
|
||||
# final time we encounter it will be the location we call canonical.
|
||||
# This is arbitrary, so just picked easiest to implement.
|
||||
set_canonical_window "$session_name" "$window_index" "$window_id"
|
||||
done < <(dump_windows_raw)
|
||||
}
|
||||
|
||||
# translates pane pid to process command running inside a pane
|
||||
dump_panes() {
|
||||
local full_command
|
||||
dump_panes_raw |
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size; do
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size window_id; do
|
||||
# not saving panes from grouped sessions
|
||||
if is_session_grouped "$session_name"; then
|
||||
continue
|
||||
fi
|
||||
if ! is_canonical_window "$session_name" "$window_number" "$window_id"; then
|
||||
continue
|
||||
fi
|
||||
full_command="$(pane_full_command $pane_pid)"
|
||||
dir=$(echo $dir | sed 's/ /\\ /') # escape all spaces in directory path
|
||||
echo "${line_type}${d}${session_name}${d}${window_number}${d}${window_name}${d}${window_active}${d}${window_flags}${d}${pane_index}${d}${dir}${d}${pane_active}${d}${pane_command}${d}:${full_command}"
|
||||
|
@ -240,12 +298,17 @@ dump_panes() {
|
|||
|
||||
dump_windows() {
|
||||
dump_windows_raw |
|
||||
while IFS=$d read line_type session_name window_index window_active window_flags window_layout; do
|
||||
while IFS=$d read line_type session_name window_index window_active window_flags window_layout window_id; do
|
||||
# not saving windows from grouped sessions
|
||||
if is_session_grouped "$session_name"; then
|
||||
continue
|
||||
fi
|
||||
echo "${line_type}${d}${session_name}${d}${window_index}${d}${window_active}${d}${window_flags}${d}${window_layout}"
|
||||
if is_canonical_window "$session_name" "$window_index" "$window_id"; then
|
||||
echo "${line_type}${d}${session_name}${d}${window_index}${d}${window_active}${d}${window_flags}${d}${window_layout}"
|
||||
else
|
||||
canonical_window=$(get_canonical_window "$window_id")
|
||||
echo "link${d}${session_name}${d}${window_index}${d}${canonical_window}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -256,7 +319,7 @@ dump_state() {
|
|||
dump_pane_contents() {
|
||||
local pane_contents_area="$(get_tmux_option "$pane_contents_area_option" "$default_pane_contents_area")"
|
||||
dump_panes_raw |
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size; do
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size window_id; do
|
||||
capture_pane_contents "${session_name}:${window_number}.${pane_index}" "$history_size" "$pane_contents_area"
|
||||
done
|
||||
}
|
||||
|
@ -281,6 +344,7 @@ save_all() {
|
|||
local last_resurrect_file="$(last_resurrect_file)"
|
||||
mkdir -p "$(resurrect_dir)"
|
||||
fetch_and_dump_grouped_sessions > "$resurrect_file_path"
|
||||
set_canonical_windows
|
||||
dump_panes >> "$resurrect_file_path"
|
||||
dump_windows >> "$resurrect_file_path"
|
||||
dump_state >> "$resurrect_file_path"
|
||||
|
|
Loading…
Reference in New Issue