mirror of
https://github.com/tmux-plugins/tmux-resurrect.git
synced 2025-09-10 21:23:09 +00:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
e38eed7dae | |||
a35d5f9b90 | |||
0b496dd228 | |||
ad52ade4bf | |||
3ba092459a | |||
6a6d65b98a | |||
f3fe4acc39 | |||
8684d4592b | |||
8328de41d8 | |||
94985fc500 | |||
81982b5114 | |||
a73c465e47 | |||
4ba0e398b9 | |||
8fd38588c0 | |||
a7fe9dcac3 | |||
ec9f68cad5 | |||
94594efdb0 | |||
1b79eb2f63 | |||
8ebda79f68 | |||
ae9083e695 | |||
9f7050aaae | |||
99abfa5f13 |
12
CHANGELOG.md
12
CHANGELOG.md
@ -2,6 +2,18 @@
|
|||||||
|
|
||||||
### master
|
### master
|
||||||
|
|
||||||
|
### v1.4.0, 2014-10-25
|
||||||
|
- plugin now uses strategies when fetching pane full command. Implemented
|
||||||
|
'default' strategy.
|
||||||
|
- save command strategy: 'pgrep'. It's here only if fallback is needed.
|
||||||
|
- save command strategy: 'gdb'
|
||||||
|
- rename default strategy name to 'ps'
|
||||||
|
- create `expect` script that can fully restore tmux environment
|
||||||
|
- fix default save command strategy `ps` command flags. Flags are different for
|
||||||
|
FreeBSD.
|
||||||
|
- add bash history saving and restoring (@rburny)
|
||||||
|
- preserving layout of zoomed windows across restores (@Azrael3000)
|
||||||
|
|
||||||
### v1.3.0, 2014-09-20
|
### v1.3.0, 2014-09-20
|
||||||
- remove dependency on `pgrep` command. Use `ps` for fetching process names.
|
- remove dependency on `pgrep` command. Use `ps` for fetching process names.
|
||||||
|
|
||||||
|
31
README.md
31
README.md
@ -20,10 +20,10 @@ It even (optionally) [restores vim sessions](#restoring-vim-sessions)!
|
|||||||
|
|
||||||
### Key bindings
|
### Key bindings
|
||||||
|
|
||||||
- `prefix + Ctrl-s` or `prefix + Alt-s` - save
|
- `prefix + Ctrl-s` - save
|
||||||
- `prefix + Ctrl-r` or `prefix + Alt-r` - restore
|
- `prefix + Ctrl-r` - restore
|
||||||
|
|
||||||
Some people can't get `Alt` key mappings to work so they are deprecated.
|
`prefix + Alt-s` and `prefix + Alt-r` key bindings are now deprecated.
|
||||||
|
|
||||||
For custom key bindings, add to `.tmux.conf`:
|
For custom key bindings, add to `.tmux.conf`:
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ This plugin goes to great lengths to save and restore all the details from your
|
|||||||
|
|
||||||
- all sessions, windows, panes and their order
|
- all sessions, windows, panes and their order
|
||||||
- current working directory for each pane
|
- current working directory for each pane
|
||||||
- **exact pane layouts** within windows
|
- **exact pane layouts** within windows (even when zoomed)
|
||||||
- active and alternative session
|
- active and alternative session
|
||||||
- active and alternative window for each session
|
- active and alternative window for each session
|
||||||
- windows with focus
|
- windows with focus
|
||||||
@ -46,6 +46,8 @@ This plugin goes to great lengths to save and restore all the details from your
|
|||||||
[configuration section](#configuration).
|
[configuration section](#configuration).
|
||||||
- restoring vim sessions (optional). More details in
|
- restoring vim sessions (optional). More details in
|
||||||
[restoring vim sessions](#restoring-vim-sessions).
|
[restoring vim sessions](#restoring-vim-sessions).
|
||||||
|
- restoring bash history (optional, *experimental*). More details in
|
||||||
|
[restoring bash history](#restoring-bash-history-experimental).
|
||||||
|
|
||||||
Requirements / dependencies: `tmux 1.9` or higher, `bash`.
|
Requirements / dependencies: `tmux 1.9` or higher, `bash`.
|
||||||
|
|
||||||
@ -56,10 +58,10 @@ already exist.
|
|||||||
|
|
||||||
Add plugin to the list of TPM plugins in `.tmux.conf`:
|
Add plugin to the list of TPM plugins in `.tmux.conf`:
|
||||||
|
|
||||||
set -g @tpm_plugins " \
|
set -g @tpm_plugins ' \
|
||||||
tmux-plugins/tpm \
|
tmux-plugins/tpm \
|
||||||
tmux-plugins/tmux-resurrect \
|
tmux-plugins/tmux-resurrect \
|
||||||
"
|
'
|
||||||
|
|
||||||
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
|
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
|
||||||
use the plugin.
|
use the plugin.
|
||||||
@ -123,6 +125,23 @@ Only a conservative list of programs is restored by default:<br/>
|
|||||||
`tmux-resurrect` will now restore vim sessions if `Sessions.vim` file is
|
`tmux-resurrect` will now restore vim sessions if `Sessions.vim` file is
|
||||||
present.
|
present.
|
||||||
|
|
||||||
|
#### Resurrect save dir
|
||||||
|
|
||||||
|
By default Tmux environment is saved to a file in `~/.tmux/resurrect` dir.
|
||||||
|
Change this with:
|
||||||
|
|
||||||
|
set -g @resurrect-dir '/some/path'
|
||||||
|
|
||||||
|
#### Restoring bash history (experimental)
|
||||||
|
|
||||||
|
In `.tmux.conf`:
|
||||||
|
|
||||||
|
set -g @resurrect-save-bash-history 'on'
|
||||||
|
|
||||||
|
Bash `history` for individual panes will now be saved and restored. Due to
|
||||||
|
technical limitations, this only works for panes which have Bash running in
|
||||||
|
foreground (as opposed to e.g. vi or top) when saving.
|
||||||
|
|
||||||
### Other goodies
|
### Other goodies
|
||||||
|
|
||||||
- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for
|
- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for
|
||||||
|
22
save_command_strategies/gdb.sh
Executable file
22
save_command_strategies/gdb.sh
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
PANE_PID="$1"
|
||||||
|
|
||||||
|
exit_safely_if_empty_ppid() {
|
||||||
|
if [ -z "$PANE_PID" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
full_command() {
|
||||||
|
gdb -batch --eval "attach $PANE_PID" --eval "call write_history(\"/tmp/bash_history-${PANE_PID}.txt\")" --eval 'detach' --eval 'q' >/dev/null 2>&1
|
||||||
|
\tail -1 "/tmp/bash_history-${PANE_PID}.txt"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
exit_safely_if_empty_ppid
|
||||||
|
full_command
|
||||||
|
}
|
||||||
|
main
|
22
save_command_strategies/pgrep.sh
Executable file
22
save_command_strategies/pgrep.sh
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
PANE_PID="$1"
|
||||||
|
|
||||||
|
exit_safely_if_empty_ppid() {
|
||||||
|
if [ -z "$PANE_PID" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
full_command() {
|
||||||
|
\pgrep -lf -P "$PANE_PID" |
|
||||||
|
cut -d' ' -f2-
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
exit_safely_if_empty_ppid
|
||||||
|
full_command
|
||||||
|
}
|
||||||
|
main
|
31
save_command_strategies/ps.sh
Executable file
31
save_command_strategies/ps.sh
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
PANE_PID="$1"
|
||||||
|
|
||||||
|
exit_safely_if_empty_ppid() {
|
||||||
|
if [ -z "$PANE_PID" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ps_command_flags() {
|
||||||
|
case $(uname -s) in
|
||||||
|
FreeBSD) echo "-ao" ;;
|
||||||
|
*) echo "-eo" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
full_command() {
|
||||||
|
ps "$(ps_command_flags)" "ppid command" |
|
||||||
|
sed "s/^ *//" |
|
||||||
|
grep "^${PANE_PID}" |
|
||||||
|
cut -d' ' -f2-
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
exit_safely_if_empty_ppid
|
||||||
|
full_command
|
||||||
|
}
|
||||||
|
main
|
@ -49,6 +49,11 @@ remove_first_char() {
|
|||||||
echo "$1" | cut -c2-
|
echo "$1" | cut -c2-
|
||||||
}
|
}
|
||||||
|
|
||||||
|
save_bash_history_option_on() {
|
||||||
|
local option="$(get_tmux_option "$bash_history_option" "off")"
|
||||||
|
[ "$option" == "on" ]
|
||||||
|
}
|
||||||
|
|
||||||
# path helpers
|
# path helpers
|
||||||
|
|
||||||
resurrect_dir() {
|
resurrect_dir() {
|
||||||
@ -63,3 +68,15 @@ resurrect_file_path() {
|
|||||||
last_resurrect_file() {
|
last_resurrect_file() {
|
||||||
echo "$(resurrect_dir)/last"
|
echo "$(resurrect_dir)/last"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resurrect_history_file() {
|
||||||
|
local pane_id="$1"
|
||||||
|
echo "$(resurrect_dir)/bash_history-${pane_id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_zoomed_windows() {
|
||||||
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $6 ~ /Z/ && $9 == 1 { print $2, $3; }' $(last_resurrect_file) |
|
||||||
|
while IFS=$'\t' read session_name window_number; do
|
||||||
|
tmux resize-pane -t "${session_name}:${window_number}" -Z
|
||||||
|
done
|
||||||
|
}
|
||||||
|
@ -57,7 +57,7 @@ _process_should_be_restored() {
|
|||||||
|
|
||||||
_restore_all_processes() {
|
_restore_all_processes() {
|
||||||
local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
||||||
if [ $restore_processes == ":all:" ]; then
|
if [ "$restore_processes" == ":all:" ]; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
@ -108,7 +108,7 @@ _get_proc_restore_element() {
|
|||||||
_restore_list() {
|
_restore_list() {
|
||||||
local user_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
local user_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
||||||
local default_processes="$(get_tmux_option "$default_proc_list_option" "$default_proc_list")"
|
local default_processes="$(get_tmux_option "$default_proc_list_option" "$default_proc_list")"
|
||||||
if [ -z $user_processes ]; then
|
if [ -z "$user_processes" ]; then
|
||||||
# user didn't define any processes
|
# user didn't define any processes
|
||||||
echo "$default_processes"
|
echo "$default_processes"
|
||||||
else
|
else
|
||||||
|
14
scripts/restore.exp
Executable file
14
scripts/restore.exp
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env expect
|
||||||
|
|
||||||
|
# start tmux
|
||||||
|
spawn tmux -S/tmp/foo
|
||||||
|
|
||||||
|
# delay with sleep to compensate for tmux starting time
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# run restore script directly
|
||||||
|
send "~/.tmux/plugins/tmux-resurrect/scripts/restore.sh\r"
|
||||||
|
|
||||||
|
# long wait until tmux restore is complete
|
||||||
|
# (things get messed up if expect client isn't attached)
|
||||||
|
sleep 100
|
@ -141,6 +141,21 @@ restore_all_panes() {
|
|||||||
done < $(last_resurrect_file)
|
done < $(last_resurrect_file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore_shell_history() {
|
||||||
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ { print $2, $3, $7, $10; }' $(last_resurrect_file) |
|
||||||
|
while IFS=$'\t' read session_name window_number pane_index pane_command; do
|
||||||
|
if ! is_pane_registered_as_existing "$session_name" "$window_number" "$pane_index"; then
|
||||||
|
if [ "$pane_command" = "bash" ]; then
|
||||||
|
local pane_id="$session_name:$window_number.$pane_index"
|
||||||
|
# tmux send-keys has -R option that should reset the terminal.
|
||||||
|
# However, appending 'clear' to the command seems to work more reliably.
|
||||||
|
local read_command="history -r '$(resurrect_history_file "$pane_id")'; clear"
|
||||||
|
tmux send-keys -t "$pane_id" "$read_command" C-m
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
restore_all_pane_processes() {
|
restore_all_pane_processes() {
|
||||||
if restore_pane_processes_enabled; then
|
if restore_pane_processes_enabled; then
|
||||||
local pane_full_command
|
local pane_full_command
|
||||||
@ -168,13 +183,6 @@ restore_active_pane_for_each_window() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_zoomed_windows() {
|
|
||||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /Z/ { print $2, $3; }' $(last_resurrect_file) |
|
|
||||||
while IFS=$'\t' read session_name window_number; do
|
|
||||||
tmux resize-pane -t "${session_name}:${window_number}" -Z
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
restore_active_and_alternate_windows() {
|
restore_active_and_alternate_windows() {
|
||||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) |
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) |
|
||||||
sort -u |
|
sort -u |
|
||||||
@ -196,6 +204,9 @@ main() {
|
|||||||
start_spinner "Restoring..." "Tmux restore complete!"
|
start_spinner "Restoring..." "Tmux restore complete!"
|
||||||
restore_all_panes
|
restore_all_panes
|
||||||
restore_pane_layout_for_each_window >/dev/null 2>&1
|
restore_pane_layout_for_each_window >/dev/null 2>&1
|
||||||
|
if save_bash_history_option_on; then
|
||||||
|
restore_shell_history
|
||||||
|
fi
|
||||||
restore_all_pane_processes
|
restore_all_pane_processes
|
||||||
# below functions restore exact cursor positions
|
# below functions restore exact cursor positions
|
||||||
restore_active_pane_for_each_window
|
restore_active_pane_for_each_window
|
||||||
|
@ -65,11 +65,35 @@ dump_panes_raw() {
|
|||||||
tmux list-panes -a -F "$(pane_format)"
|
tmux list-panes -a -F "$(pane_format)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_save_command_strategy_file() {
|
||||||
|
local save_command_strategy="$(get_tmux_option "$save_command_strategy_option" "$default_save_command_strategy")"
|
||||||
|
local strategy_file="$CURRENT_DIR/../save_command_strategies/${save_command_strategy}.sh"
|
||||||
|
local default_strategy_file="$CURRENT_DIR/../save_command_strategies/${default_save_command_strategy}.sh"
|
||||||
|
if [ -e "$strategy_file" ]; then # strategy file exists?
|
||||||
|
echo "$strategy_file"
|
||||||
|
else
|
||||||
|
echo "$default_strategy_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
pane_full_command() {
|
pane_full_command() {
|
||||||
local pane_pid="$1"
|
local pane_pid="$1"
|
||||||
ps -eo "ppid command" |
|
local strategy_file="$(_save_command_strategy_file)"
|
||||||
grep "^${pane_pid}" |
|
# execute strategy script to get pane full command
|
||||||
cut -d' ' -f2-
|
$strategy_file "$pane_pid"
|
||||||
|
}
|
||||||
|
|
||||||
|
save_shell_history() {
|
||||||
|
local pane_id="$1"
|
||||||
|
local pane_command="$2"
|
||||||
|
if [ "$pane_command" = "bash" ]; then
|
||||||
|
# leading space prevents the command from being saved to history
|
||||||
|
# (assuming default HISTCONTROL settings)
|
||||||
|
local write_command=" history -w '$(resurrect_history_file "$pane_id")'"
|
||||||
|
# C-e C-u is a Bash shortcut sequence to clear whole line. It is necessary to
|
||||||
|
# delete any pending input so it does not interfere with our history command.
|
||||||
|
tmux send-keys -t "$pane_id" C-e C-u "$write_command" C-m
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# translates pane pid to process command running inside a pane
|
# translates pane pid to process command running inside a pane
|
||||||
@ -78,6 +102,11 @@ dump_panes() {
|
|||||||
local d=$'\t' # delimiter
|
local d=$'\t' # delimiter
|
||||||
dump_panes_raw |
|
dump_panes_raw |
|
||||||
while IFS=$'\t' read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid; do
|
while IFS=$'\t' read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid; do
|
||||||
|
# check if current pane is part of a maximized window and if the pane is active
|
||||||
|
if [[ "${window_flags}" == *Z* ]] && [[ ${pane_active} == 1 ]]; then
|
||||||
|
# unmaximize the pane
|
||||||
|
tmux resize-pane -Z -t "${session_name}:${window_number}"
|
||||||
|
fi
|
||||||
full_command="$(pane_full_command $pane_pid)"
|
full_command="$(pane_full_command $pane_pid)"
|
||||||
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}"
|
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}"
|
||||||
done
|
done
|
||||||
@ -91,6 +120,13 @@ dump_state() {
|
|||||||
tmux display-message -p "$(state_format)"
|
tmux display-message -p "$(state_format)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump_bash_history() {
|
||||||
|
dump_panes_raw |
|
||||||
|
while IFS=$'\t' read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid; do
|
||||||
|
save_shell_history "$session_name:$window_number.$pane_index" "$pane_command"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
save_all() {
|
save_all() {
|
||||||
local resurrect_file_path="$(resurrect_file_path)"
|
local resurrect_file_path="$(resurrect_file_path)"
|
||||||
mkdir -p "$(resurrect_dir)"
|
mkdir -p "$(resurrect_dir)"
|
||||||
@ -98,6 +134,10 @@ save_all() {
|
|||||||
dump_windows >> $resurrect_file_path
|
dump_windows >> $resurrect_file_path
|
||||||
dump_state >> $resurrect_file_path
|
dump_state >> $resurrect_file_path
|
||||||
ln -fs "$resurrect_file_path" "$(last_resurrect_file)"
|
ln -fs "$resurrect_file_path" "$(last_resurrect_file)"
|
||||||
|
if save_bash_history_option_on; then
|
||||||
|
dump_bash_history
|
||||||
|
fi
|
||||||
|
restore_zoomed_windows
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
|
@ -16,7 +16,7 @@ MESSAGE="$1"
|
|||||||
END_MESSAGE="$2"
|
END_MESSAGE="$2"
|
||||||
SPIN='-\|/'
|
SPIN='-\|/'
|
||||||
|
|
||||||
trap "tmux display-message $END_MESSAGE; exit" SIGINT SIGTERM
|
trap "tmux display-message '$END_MESSAGE'; exit" SIGINT SIGTERM
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
local i=0
|
local i=0
|
||||||
|
@ -23,3 +23,8 @@ restore_processes=""
|
|||||||
restore_process_strategy_option="@resurrect-strategy-"
|
restore_process_strategy_option="@resurrect-strategy-"
|
||||||
|
|
||||||
inline_strategy_token="->"
|
inline_strategy_token="->"
|
||||||
|
|
||||||
|
save_command_strategy_option="@resurrect-save-command-strategy"
|
||||||
|
default_save_command_strategy="ps"
|
||||||
|
|
||||||
|
bash_history_option="@resurrect-save-bash-history"
|
||||||
|
BIN
video/issue_vid.png
Normal file
BIN
video/issue_vid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
Reference in New Issue
Block a user