Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 77 additions & 27 deletions docs/restoring_bash_history.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,89 @@
tmux-ressurect no longer restores shell history for each pane, as of [this PR](https://github.com/tmux-plugins/tmux-resurrect/pull/308).
tmux-resurrect no longer restores shell history for each pane, as of [this PR](https://github.com/tmux-plugins/tmux-resurrect/pull/308).

As a workaround, you can use the `HISTFILE` environment variable to preserve history for each pane separately, and modify
`PROMPT_COMMAND` to make sure history gets saved with each new command.
As a workaround, you can use the `HISTFILE` environment variable to preserve history for each pane separately (and modifing
`PROMPT_COMMAND` to make sure history gets saved with each new command), then use tmux-resurrect hooks to save/restore the histfile

Unfortunately, we haven't found a perfect way of getting a unique identifier for each pane, as the `TMUX_PANE` variable
seems to occasionally change when resurrecting. As a workaround, the example below sets a unique ID in each pane's `title`.
The downside of this implementation is that pane titles must all be unique across sessions/windows, and also must use the `pane_id_prefix`.
Add this to your .bashrc
```bash
# If in a TMUX pane, setup special history handling
if [ -n "$TMUX_PANE" ]; then
# Pick a history directory and make sure it exists
HISTDIR=$HOME/.bash_history.d
mkdir -p "$HISTDIR"

# Set history file to a file using the TMUX pane id
export HISTFILE="${HISTDIR}/tmux_pane_${TMUX_PANE}"

# Setup so that after each command we:
# 1. Append current history to histfile
# 2. Clear current cached history info from memory
# 3. Read history from the histfile
export PROMPT_COMMAND="history -a;history -c;history -r;${PROMPT_COMMAND}"
fi
```

Any improvements/suggestions for getting a unique, persistent ID for each pane are welcome!
Then make some scripts (or merge into one, dealer's choice) to handle saving/restoring the histories.
For this example, I'll assume you have these scripts placed in the root directory. Don't do that.

post-save-all.sh
```bash
pane_id_prefix="resurrect_"
#!/usr/bin/env bash

# Create history directory if it doesn't exist
HISTS_DIR=$HOME/.bash_history.d
mkdir -p "${HISTS_DIR}"
RESURRECT_DIR="$HOME/.local/share/tmux/resurrect"

if [ -n "${TMUX_PANE}" ]; then
save_files() {
SAVE_DIR=$RESURRECT_DIR/$1
FILE_PREFIX=$2

# Check if we've already set this pane title
pane_id=$(tmux display -pt "${TMUX_PANE:?}" "#{pane_title}")
if [[ $pane_id != "$pane_id_prefix"* ]]; then
rm -r "$SAVE_DIR" 2>/dev/null

# if not, set it to a random ID
random_id=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
printf "\033]2;$pane_id_prefix$random_id\033\\"
pane_id=$(tmux display -pt "${TMUX_PANE:?}" "#{pane_title}")
fi
for PANE_INFO in $(tmux list-panes -aF "#{pane_id}=#{session_id}:#{window_index}.#{pane_index}"); do
PANE_ID=$(echo $PANE_INFO | cut -f 1 -d'=' | cut -d% -f 2)
IN=${FILE_PREFIX}${PANE_ID}
if ! [[ -e "$IN" ]]; then continue; fi

# use the pane's random ID for the HISTFILE
export HISTFILE="${HISTS_DIR}/bash_history_tmux_${pane_id}"
else
export HISTFILE="${HISTS_DIR}/bash_history_no_tmux"
fi
PANE_INDEX=$(echo $PANE_INFO | cut -f 2 -d'=')
OUT=$SAVE_DIR/$PANE_INDEX
if [[ -e "$OUT" ]]; then rm -r "$OUT"; fi

mkdir -p $(dirname "$OUT")
cp -p -r "$IN" "$OUT"
done
}

# Stash the new history each time a command runs.
export PROMPT_COMMAND="$PROMPT_COMMAND;history -a"
save_files "history" "$HOME/.bash_history.d/tmux_pane_"
```

pre-restore-pane-processes.sh
```bash
#!/usr/bin/env bash

RESURRECT_DIR="$HOME/.local/share/tmux/resurrect"

restore_files() {
SAVE_DIR=$RESURRECT_DIR/$1
FILE_PREFIX=$2

for PANE_INFO in $(tmux list-panes -aF "#{pane_id}=#{session_id}:#{window_index}.#{pane_index}"); do
PANE_ID=$(echo $PANE_INFO | cut -f 1 -d'=' | cut -d% -f 2)
OUT=${FILE_PREFIX}${PANE_ID}
if [[ -e "$OUT" ]]; then rm -r "$OUT"; fi

PANE_INDEX=$(echo $PANE_INFO | cut -f 2 -d'=')
IN=$SAVE_DIR/$PANE_INDEX
if ! [[ -e "$IN" ]]; then continue; fi

mkdir -p $(dirname "$OUT")
cp --preserve -r "$IN" "$OUT"
done
}

restore_files "history" "$HOME/.bash_history.d/tmux_pane_"
```

Finally, add the following to your .tmux.conf
```bash
# Don't actually put these in the root folder!
set -g @resurrect-hook-post-save-all "/post-save-all.sh"
set -g @resurrect-hook-pre-restore-pane-processes "/pre-restore-pane-processes.sh"
```