Add the session restoration support for macOS

Also known as Resume, this feature allows one to store
current environment and later restore it thanks to the fact
that Terminal.app (as well as iTerm) provdes the TERM_SESSION_ID
environment variable which is preserved between restarts.
This commit is contained in:
Ilya Kulakov 2017-02-14 13:17:01 -08:00
parent d2725d44fc
commit 276a58e0c3
2 changed files with 93 additions and 0 deletions

29
plugins/session/README.md Normal file
View File

@ -0,0 +1,29 @@
Terminal.app on macOS provides the `TERM_SESSION_ID` environment variable into every shell process.
Out of the box, for bash, it allows one to define the `shell_session_save_user_state` function which
can write any shell command to the `SHELL_SESSION_FILE` file.
If user then exit Terminal.app with open sessions, this function will be called for each of them.
On the next launch, Terminal.app will source session files into corresponding sessions.
This plugin implements that logic for Zsh.
E.g. to automatically restore Python's virtual environment, just add the following to you `.zshrc`:
```zsh
function shell_session_save_user_state() {
# Resulting files is sourced at the very beginning,
# which maybe to early.
# It's better to have control over when session should be restored.
echo "function restore_session() {" >> $SHELL_SESSION_FILE
if [[ -n ${VIRTUAL_ENV} ]]; then
echo source \"${VIRTUAL_ENV}\"/bin/activate >> $SHELL_SESSION_FILE
fi
echo "}" >> $SHELL_SESSION_FILE
}
if typeset -f restore_session >/dev/null; then
restore_session
fi
```

View File

@ -0,0 +1,64 @@
# Terminal.app session restoration from /etc/bashrc_Apple_Terminal for ZSH
if [[ ${SHELL_SESSION_DID_INIT:-0} -eq 0 ]] && [[ -n "${TERM_SESSION_ID}" ]] then
SHELL_SESSION_DID_INIT=1
#
# Set up the session directory/file.
#
SHELL_SESSION_DIR="${HOME}/.zsh_sessions"
SHELL_SESSION_FILE="${SHELL_SESSION_DIR}/${TERM_SESSION_ID}.session"
mkdir -p "${SHELL_SESSION_DIR}"
#
# Restore previous session state.
#
if [[ -r "${SHELL_SESSION_FILE}" ]]; then
. "${SHELL_SESSION_FILE}"
rm "${SHELL_SESSION_FILE}"
fi
#
# Arrange to save session state when exiting the shell.
#
function shell_session_save() {
if [[ -n "${SHELL_SESSION_FILE}" ]]; then
echo -n 'Saving session...'
typeset -f shell_session_save_user_state >/dev/null && shell_session_save_user_state
echo 'completed.'
fi
}
#
# Delete old session files. (Not more than once a day.)
#
SHELL_SESSION_TIMESTAMP_FILE="${SHELL_SESSION_DIR}/_expiration_check_timestamp"
function shell_session_delete_expired() {
if [[ ! -e "${SHELL_SESSION_TIMESTAMP_FILE}" || -z $(find "${SHELL_SESSION_TIMESTAMP_FILE}" -mtime -1d) ]]; then
local expiration_lock_file="${SHELL_SESSION_DIR}/_expiration_lockfile"
if shlock -f "${expiration_lock_file}" -p $$; then
echo -n 'Deleting expired sessions...'
local delete_count=$(find "${SHELL_SESSION_DIR}" -type f -mtime +2w -print -delete | wc -l)
[ "${delete_count}" -gt 0 ] && echo ${delete_count}' completed.' || echo 'none found.'
touch "${SHELL_SESSION_TIMESTAMP_FILE}"
rm "${expiration_lock_file}"
fi
fi
}
#
# Update saved session state when exiting.
#
function shell_session_update() {
shell_session_save && shell_session_delete_expired
}
trap shell_session_update EXIT
fi