Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
a649614a20 | |||
8166fa2602 | |||
ecc42c5a56 | |||
aa8f323b8b | |||
c78a38803a | |||
877780eb02 | |||
8ba7d6d873 | |||
c993e9ff00 | |||
81ed0811b4 | |||
732d53cede | |||
5c2853a55f | |||
70d78e8d73 | |||
1280e659d5 | |||
3dce66acaa |
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,4 +1,20 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
# master
|
### master
|
||||||
|
|
||||||
|
### v0.0.3, 2014-08-26
|
||||||
|
- save and restore current and alternate session
|
||||||
|
- fix a bug with non-existing window names
|
||||||
|
- restore active pane for each window that has multiple panes
|
||||||
|
- restore active and alternate window for each session
|
||||||
|
|
||||||
|
### v0.0.2, 2014-08-26
|
||||||
|
- saving a new session does not remove the previous one
|
||||||
|
- make the directory where sessions are stored configurable
|
||||||
|
- support only Tmux v1.9 or greater
|
||||||
|
- display a nice error message if saved session file does not exist
|
||||||
|
- added README
|
||||||
|
|
||||||
|
### v0.0.1, 2014-08-26
|
||||||
- started a project
|
- started a project
|
||||||
|
- basic saving and restoring works
|
||||||
|
36
README.md
36
README.md
@ -1,4 +1,40 @@
|
|||||||
# Tmux Session Saver
|
# Tmux Session Saver
|
||||||
|
|
||||||
|
Enables saving and restoring of tmux sessions.
|
||||||
|
|
||||||
|
### Key bindings
|
||||||
|
|
||||||
|
- `prefix + M-s` - save
|
||||||
|
- `prefix + M-r` - restore
|
||||||
|
|
||||||
|
### 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 " \
|
||||||
|
tmux-plugins/tpm \
|
||||||
|
tmux-plugins/tmux-session-saver \
|
||||||
|
"
|
||||||
|
|
||||||
|
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
|
||||||
|
use the plugin.
|
||||||
|
|
||||||
|
### Manual Installation
|
||||||
|
|
||||||
|
Clone the repo:
|
||||||
|
|
||||||
|
$ git clone https://github.com/tmux-plugins/tmux-session-saver ~/clone/path
|
||||||
|
|
||||||
|
Add this line to the bottom of `.tmux.conf`:
|
||||||
|
|
||||||
|
run-shell ~/clone/path/session_saver.tmux
|
||||||
|
|
||||||
|
Reload TMUX environment:
|
||||||
|
|
||||||
|
# type this in terminal
|
||||||
|
$ tmux source-file ~/.tmux.conf
|
||||||
|
|
||||||
|
You should now be able to use the plugin.
|
||||||
|
|
||||||
### License
|
### License
|
||||||
[MIT](LICENSE.md)
|
[MIT](LICENSE.md)
|
||||||
|
78
scripts/check_tmux_version.sh
Executable file
78
scripts/check_tmux_version.sh
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
VERSION="$1"
|
||||||
|
UNSUPPORTED_MSG="$2"
|
||||||
|
|
||||||
|
get_tmux_option() {
|
||||||
|
local option=$1
|
||||||
|
local default_value=$2
|
||||||
|
local option_value=$(tmux show-option -gqv "$option")
|
||||||
|
if [ -z "$option_value" ]; then
|
||||||
|
echo "$default_value"
|
||||||
|
else
|
||||||
|
echo "$option_value"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensures a message is displayed for 5 seconds in tmux prompt.
|
||||||
|
# Does not override the 'display-time' tmux option.
|
||||||
|
display_message() {
|
||||||
|
local message="$1"
|
||||||
|
|
||||||
|
# display_duration defaults to 5 seconds, if not passed as an argument
|
||||||
|
if [ "$#" -eq 2 ]; then
|
||||||
|
local display_duration="$2"
|
||||||
|
else
|
||||||
|
local display_duration="5000"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# saves user-set 'display-time' option
|
||||||
|
local saved_display_time=$(get_tmux_option "display-time" "750")
|
||||||
|
|
||||||
|
# sets message display time to 5 seconds
|
||||||
|
tmux set-option -gq display-time "$display_duration"
|
||||||
|
|
||||||
|
# displays message
|
||||||
|
tmux display-message "$message"
|
||||||
|
|
||||||
|
# restores original 'display-time' value
|
||||||
|
tmux set-option -gq display-time "$saved_display_time"
|
||||||
|
}
|
||||||
|
|
||||||
|
# this is used to get "clean" integer version number. Examples:
|
||||||
|
# `tmux 1.9` => `19`
|
||||||
|
# `1.9a` => `19`
|
||||||
|
get_digits_from_string() {
|
||||||
|
local string="$1"
|
||||||
|
local only_digits="$(echo "$string" | tr -dC '[:digit:]')"
|
||||||
|
echo "$only_digits"
|
||||||
|
}
|
||||||
|
|
||||||
|
tmux_version_int() {
|
||||||
|
local tmux_version_string=$(tmux -V)
|
||||||
|
echo "$(get_digits_from_string "$tmux_version_string")"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsupported_version_message() {
|
||||||
|
if [ -n "$UNSUPPORTED_MSG" ]; then
|
||||||
|
echo "$UNSUPPORTED_MSG"
|
||||||
|
else
|
||||||
|
echo "Error, Tmux version unsupported! Please install Tmux version $VERSION or greater!"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_if_unsupported_version() {
|
||||||
|
local current_version="$1"
|
||||||
|
local supported_version="$2"
|
||||||
|
if [ "$current_version" -lt "$supported_version" ]; then
|
||||||
|
display_message "$(unsupported_version_message)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local supported_version_int="$(get_digits_from_string "$VERSION")"
|
||||||
|
local current_version_int="$(tmux_version_int)"
|
||||||
|
exit_if_unsupported_version "$current_version_int" "$supported_version_int"
|
||||||
|
}
|
||||||
|
main
|
@ -1,3 +1,10 @@
|
|||||||
|
# configurable constants
|
||||||
|
default_sessions_dir="$HOME/.tmux/sessions"
|
||||||
|
sessions_dir_option="@sessions-dir"
|
||||||
|
|
||||||
|
SUPPORTED_VERSION="1.9"
|
||||||
|
|
||||||
|
# helper functions
|
||||||
get_tmux_option() {
|
get_tmux_option() {
|
||||||
local option="$1"
|
local option="$1"
|
||||||
local default_value="$2"
|
local default_value="$2"
|
||||||
@ -33,3 +40,23 @@ display_message() {
|
|||||||
# restores original 'display-time' value
|
# restores original 'display-time' value
|
||||||
tmux set-option -gq display-time "$saved_display_time"
|
tmux set-option -gq display-time "$saved_display_time"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
supported_tmux_version_ok() {
|
||||||
|
$CURRENT_DIR/check_tmux_version.sh "$SUPPORTED_VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
# path helpers
|
||||||
|
|
||||||
|
sessions_dir() {
|
||||||
|
echo $(get_tmux_option "$sessions_dir_option" "$default_sessions_dir")
|
||||||
|
}
|
||||||
|
|
||||||
|
session_path() {
|
||||||
|
local timestamp="$(date +"%Y-%m-%dT%H:%M:%S")"
|
||||||
|
echo "$(sessions_dir)/tmux_session_${timestamp}.txt"
|
||||||
|
}
|
||||||
|
|
||||||
|
last_session_path() {
|
||||||
|
echo "$(sessions_dir)/last"
|
||||||
|
}
|
||||||
|
@ -4,6 +4,21 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||||||
|
|
||||||
source "$CURRENT_DIR/helpers.sh"
|
source "$CURRENT_DIR/helpers.sh"
|
||||||
|
|
||||||
|
is_line_type() {
|
||||||
|
local line_type="$1"
|
||||||
|
local line="$2"
|
||||||
|
echo "$line" |
|
||||||
|
\grep -q "^$line_type"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_saved_session_exists() {
|
||||||
|
local saved_session="$(last_session_path)"
|
||||||
|
if [ ! -f $saved_session ]; then
|
||||||
|
display_message "Saved session not found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
window_exists() {
|
window_exists() {
|
||||||
local session_name="$1"
|
local session_name="$1"
|
||||||
local window_number="$2"
|
local window_number="$2"
|
||||||
@ -24,6 +39,10 @@ tmux_socket() {
|
|||||||
echo $TMUX | cut -d',' -f1
|
echo $TMUX | cut -d',' -f1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove_first_char() {
|
||||||
|
echo "$1" | cut -c2-
|
||||||
|
}
|
||||||
|
|
||||||
new_window() {
|
new_window() {
|
||||||
local session_name="$1"
|
local session_name="$1"
|
||||||
local window_number="$2"
|
local window_number="$2"
|
||||||
@ -56,29 +75,67 @@ new_pane() {
|
|||||||
restore_pane() {
|
restore_pane() {
|
||||||
local pane="$1"
|
local pane="$1"
|
||||||
echo "$pane" |
|
echo "$pane" |
|
||||||
while IFS=$'\t' read session_name window_number window_name dir; do
|
while IFS=$'\t' read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active; do
|
||||||
# echo "$session_name - $window_number - $window_name - $dir"
|
window_name="$(remove_first_char $window_name)"
|
||||||
if window_exists "$session_name" "$window_number"; then
|
if window_exists "$session_name" "$window_number"; then
|
||||||
echo "new pane $session_name $window_number"
|
|
||||||
new_pane "$session_name" "$window_number" "$window_name" "$dir"
|
new_pane "$session_name" "$window_number" "$window_name" "$dir"
|
||||||
elif session_exists "$session_name"; then
|
elif session_exists "$session_name"; then
|
||||||
echo "new window $session_name $window_number"
|
|
||||||
new_window "$session_name" "$window_number" "$window_name" "$dir"
|
new_window "$session_name" "$window_number" "$window_name" "$dir"
|
||||||
else
|
else
|
||||||
echo "new session $session_name"
|
|
||||||
new_session "$session_name" "$window_number" "$window_name" "$dir"
|
new_session "$session_name" "$window_number" "$window_name" "$dir"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore_state() {
|
||||||
|
local state="$1"
|
||||||
|
echo "$state" |
|
||||||
|
while IFS=$'\t' read line_type client_session client_last_session; do
|
||||||
|
tmux switch-client -t "$client_last_session"
|
||||||
|
tmux switch-client -t "$client_session"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
restore_all_sessions() {
|
restore_all_sessions() {
|
||||||
while read line; do
|
while read line; do
|
||||||
restore_pane "$line"
|
if is_line_type "pane" "$line"; then
|
||||||
done < $HOME/.tmux/session
|
restore_pane "$line"
|
||||||
display_message "Restored all Tmux sessions!"
|
fi
|
||||||
|
done < $(last_session_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_active_pane_for_each_window() {
|
||||||
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $7 != 0 && $9 == 1 { print $2, $3, $7; }' $(last_session_path) |
|
||||||
|
while IFS=$'\t' read session_name window_number active_pane; do
|
||||||
|
tmux switch-client -t "${session_name}:${window_number}"
|
||||||
|
tmux select-pane -t "$active_pane"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_active_and_alternate_windows() {
|
||||||
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $6 ~ /[*-]/ { print $2, $5, $3; }' $(last_session_path) |
|
||||||
|
sort -u |
|
||||||
|
while IFS=$'\t' read session_name active_window window_number; do
|
||||||
|
tmux switch-client -t "${session_name}:${window_number}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_active_and_alternate_sessions() {
|
||||||
|
while read line; do
|
||||||
|
if is_line_type "state" "$line"; then
|
||||||
|
restore_state "$line"
|
||||||
|
fi
|
||||||
|
done < $(last_session_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
restore_all_sessions
|
if supported_tmux_version_ok; then
|
||||||
|
check_saved_session_exists
|
||||||
|
restore_all_sessions
|
||||||
|
restore_active_pane_for_each_window
|
||||||
|
restore_active_and_alternate_windows
|
||||||
|
restore_active_and_alternate_sessions
|
||||||
|
display_message "Restored all Tmux sessions!"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
main
|
main
|
||||||
|
@ -4,30 +4,60 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||||||
|
|
||||||
source "$CURRENT_DIR/helpers.sh"
|
source "$CURRENT_DIR/helpers.sh"
|
||||||
|
|
||||||
dump_format() {
|
pane_format() {
|
||||||
local delimiter=$'\t'
|
local delimiter=$'\t'
|
||||||
local format
|
local format
|
||||||
|
format+="pane"
|
||||||
|
format+="${delimiter}"
|
||||||
format+="#{session_name}"
|
format+="#{session_name}"
|
||||||
format+="${delimiter}"
|
format+="${delimiter}"
|
||||||
format+="#{window_index}"
|
format+="#{window_index}"
|
||||||
format+="${delimiter}"
|
format+="${delimiter}"
|
||||||
format+="#{window_name}"
|
format+=":#{window_name}"
|
||||||
|
format+="${delimiter}"
|
||||||
|
format+="#{window_active}"
|
||||||
|
format+="${delimiter}"
|
||||||
|
format+=":#{window_flags}"
|
||||||
|
format+="${delimiter}"
|
||||||
|
format+="#{pane_index}"
|
||||||
format+="${delimiter}"
|
format+="${delimiter}"
|
||||||
format+="#{pane_current_path}"
|
format+="#{pane_current_path}"
|
||||||
|
format+="${delimiter}"
|
||||||
|
format+="#{pane_active}"
|
||||||
echo "$format"
|
echo "$format"
|
||||||
}
|
}
|
||||||
|
|
||||||
dump() {
|
state_format() {
|
||||||
tmux list-panes -a -F "$(dump_format)"
|
local delimiter=$'\t'
|
||||||
|
local format
|
||||||
|
format+="state"
|
||||||
|
format+="${delimiter}"
|
||||||
|
format+="#{client_session}"
|
||||||
|
format+="${delimiter}"
|
||||||
|
format+="#{client_last_session}"
|
||||||
|
echo "$format"
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_panes() {
|
||||||
|
tmux list-panes -a -F "$(pane_format)"
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_state() {
|
||||||
|
tmux display-message -p "$(state_format)"
|
||||||
}
|
}
|
||||||
|
|
||||||
save_all_sessions() {
|
save_all_sessions() {
|
||||||
mkdir -p $HOME/.tmux
|
local session_path="$(session_path)"
|
||||||
dump > $HOME/.tmux/session
|
mkdir -p "$(sessions_dir)"
|
||||||
|
dump_panes > $session_path
|
||||||
|
dump_state >> $session_path
|
||||||
|
ln -fs "$session_path" "$(last_session_path)"
|
||||||
display_message "Saved all Tmux sessions!"
|
display_message "Saved all Tmux sessions!"
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
save_all_sessions
|
if supported_tmux_version_ok; then
|
||||||
|
save_all_sessions
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
main
|
main
|
||||||
|
Reference in New Issue
Block a user