28 Commits

Author SHA1 Message Date
e38eed7dae v1.4.0 2014-10-25 18:46:15 +02:00
a35d5f9b90 Update changelog & readme for the zoomed windows feature
Closes #47, #54
2014-10-25 18:43:56 +02:00
0b496dd228 Removing the last_resized variable
Instead resizing only if pane_active is set so we are sure the resizep
is called only once
2014-10-25 18:29:52 +02:00
ad52ade4bf Preserving layout of zoomed windows across restores
The problem is that tmux list-window shows only the current pane layout
if a pane is maximized. This is a bug in tmux. In order to avoid this
bug we unzoom the window when saving and zoom in again after saving.
This implies that the Z flag is no longer set in list-windows, and so it
can't be used when restoring. Instead we use the Z flag of the panes
(which still have it) to restore the zoom.
2014-10-25 18:29:52 +02:00
3ba092459a Merge pull request #49 from tmux-plugins/bash_history
Bash save and restore history feature
2014-10-20 23:17:46 +02:00
6a6d65b98a Update the readme 2014-10-20 23:16:56 +02:00
f3fe4acc39 Document bash restore history feature 2014-10-17 22:40:15 +02:00
8684d4592b Flag gate the bash history restore feature 2014-10-17 22:33:29 +02:00
8328de41d8 Update changelog 2014-10-17 17:47:10 +02:00
94985fc500 Extract save_shell_history to a separate function 2014-10-17 17:45:49 +02:00
81982b5114 Add bash history saving and restoring (first version).
This does not yet have flag to turn the feature off.
2014-10-17 17:14:33 +02:00
a73c465e47 Add issue video screenshot 2014-10-07 13:55:23 +02:00
4ba0e398b9 Document tmux env save dir 2014-10-06 12:59:14 +02:00
8fd38588c0 Fix ps command flags for FreeBSD
This was reported by @duck in #45
2014-09-29 13:39:41 +02:00
a7fe9dcac3 Command line script that fully restores tmux environment 2014-09-24 14:33:46 +02:00
ec9f68cad5 Quote arguments in tmux display-message 2014-09-24 14:30:05 +02:00
94594efdb0 Small bugfix: text command arguments 2014-09-24 14:25:30 +02:00
1b79eb2f63 Rename default strategy to ps 2014-09-21 15:12:35 +02:00
8ebda79f68 Implement save command strategy gdb
@danschumann originally came up with this strategy in #44
2014-09-21 00:08:41 +02:00
ae9083e695 Implement save command strategy: pgrep 2014-09-20 23:55:19 +02:00
9f7050aaae Use a strategy when fetching pane full command 2014-09-20 23:47:15 +02:00
99abfa5f13 Small readme update 2014-09-20 22:45:37 +02:00
95303946b2 v1.3.0 2014-09-20 22:36:42 +02:00
1d09f07d2b Remove dependency on pgrep; use ps to get process names
Fixes #43
2014-09-20 22:33:14 +02:00
618769b62f Update readme 2014-09-20 13:23:42 +02:00
fac377bf8c Add bash to the dependency list 2014-09-10 21:53:38 +02:00
dc7561df74 Small readme tweak 2014-09-10 13:26:14 +02:00
eb2cd31d4b Update readme
Do not invite people to negotiate default program restore list.
2014-09-07 10:19:03 +02:00
13 changed files with 223 additions and 24 deletions

View File

@ -2,6 +2,21 @@
### 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
- remove dependency on `pgrep` command. Use `ps` for fetching process names.
### v1.2.1, 2014-09-02
- tweak 'new_pane' creation strategy to fix #36
- when running multiple tmux server and for a large number of panes (120 +) when

View File

@ -20,15 +20,15 @@ It even (optionally) [restores vim sessions](#restoring-vim-sessions)!
### Key bindings
- `prefix + Ctrl-s` or `prefix + Alt-s` - save
- `prefix + Ctrl-r` or `prefix + Alt-r` - restore
- `prefix + Ctrl-s` - save
- `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`:
set -g @resurrect-save "S"
set -g @resurrect-restore "R"
set -g @resurrect-save 'S'
set -g @resurrect-restore 'R'
### About
@ -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
- 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 window for each session
- windows with focus
@ -46,17 +46,22 @@ This plugin goes to great lengths to save and restore all the details from your
[configuration section](#configuration).
- restoring vim sessions (optional). More details in
[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, `pgrep`
Requirements / dependencies: `tmux 1.9` or higher, `bash`.
`tmux-resurrect` is idempotent! It will not try to restore panes or windows that
already exist.
### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended)
Add plugin to the list of TPM plugins in `.tmux.conf`:
set -g @tpm_plugins " \
set -g @tpm_plugins ' \
tmux-plugins/tpm \
tmux-plugins/tmux-resurrect \
"
'
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
use the plugin.
@ -84,7 +89,6 @@ Configuration is not required, but it enables extra features.
Only a conservative list of programs is restored by default:<br/>
`vi vim emacs man less more tail top htop irssi`.
Open a GitHub issue if you think some other program should be on the default list.
- Restore additional programs with the setting in `.tmux.conf`:
@ -116,11 +120,28 @@ Open a GitHub issue if you think some other program should be on the default lis
- save vim sessions. I recommend [tpope/vim-obsession](https://github.com/tpope/vim-obsession).
- in `.tmux.conf`:
set -g @resurrect-strategy-vim "session"
set -g @resurrect-strategy-vim 'session'
`tmux-resurrect` will now restore vim sessions if `Sessions.vim` file is
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
- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for

22
save_command_strategies/gdb.sh Executable file
View 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

View 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
View 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

View File

@ -49,6 +49,11 @@ remove_first_char() {
echo "$1" | cut -c2-
}
save_bash_history_option_on() {
local option="$(get_tmux_option "$bash_history_option" "off")"
[ "$option" == "on" ]
}
# path helpers
resurrect_dir() {
@ -63,3 +68,15 @@ resurrect_file_path() {
last_resurrect_file() {
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
}

View File

@ -57,7 +57,7 @@ _process_should_be_restored() {
_restore_all_processes() {
local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
if [ $restore_processes == ":all:" ]; then
if [ "$restore_processes" == ":all:" ]; then
return 0
else
return 1
@ -108,7 +108,7 @@ _get_proc_restore_element() {
_restore_list() {
local user_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
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
echo "$default_processes"
else

14
scripts/restore.exp Executable file
View 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

View File

@ -141,6 +141,21 @@ restore_all_panes() {
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() {
if restore_pane_processes_enabled; then
local pane_full_command
@ -168,13 +183,6 @@ restore_active_pane_for_each_window() {
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() {
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) |
sort -u |
@ -196,6 +204,9 @@ main() {
start_spinner "Restoring..." "Tmux restore complete!"
restore_all_panes
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
# below functions restore exact cursor positions
restore_active_pane_for_each_window

View File

@ -65,10 +65,35 @@ dump_panes_raw() {
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_pid="$1"
\pgrep -lf -P "$pane_pid" |
cut -d' ' -f2-
local pane_pid="$1"
local strategy_file="$(_save_command_strategy_file)"
# execute strategy script to get pane full command
$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
@ -77,6 +102,11 @@ dump_panes() {
local d=$'\t' # delimiter
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
# 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)"
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
@ -90,6 +120,13 @@ dump_state() {
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() {
local resurrect_file_path="$(resurrect_file_path)"
mkdir -p "$(resurrect_dir)"
@ -97,6 +134,10 @@ save_all() {
dump_windows >> $resurrect_file_path
dump_state >> $resurrect_file_path
ln -fs "$resurrect_file_path" "$(last_resurrect_file)"
if save_bash_history_option_on; then
dump_bash_history
fi
restore_zoomed_windows
}
main() {

View File

@ -16,7 +16,7 @@ MESSAGE="$1"
END_MESSAGE="$2"
SPIN='-\|/'
trap "tmux display-message $END_MESSAGE; exit" SIGINT SIGTERM
trap "tmux display-message '$END_MESSAGE'; exit" SIGINT SIGTERM
main() {
local i=0

View File

@ -23,3 +23,8 @@ restore_processes=""
restore_process_strategy_option="@resurrect-strategy-"
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB