A helper for the Bash shell that allows you to manage individual history files for specific directories.
Created
May 14, 2025 14:16
-
-
Save codemedic/b2cb583973f8dd3a291c56c1f5348efa to your computer and use it in GitHub Desktop.
A helper for the Bash shell that allows you to manage individual history files for specific directories.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The base path for the history files created by ch | |
ch_history_base_path="$HOME/.bash_history.d" | |
# ch_hist_file is a helper function to get the history file for a given directory. | |
# If no directory is given, it will use the current directory. | |
ch_hist_file() { | |
local dir | |
dir=$(realpath "${1:-.}") | |
# Check if the directory is under the home directory using a prefix match | |
if [[ "$dir" != "$HOME"* ]]; then | |
echo "ch: Directory is not under the home directory" 1>&2 | |
return 1 | |
fi | |
local history_file="${ch_history_base_path}/${dir#"$HOME"}.bash_history" | |
echo "$history_file" | |
} | |
# ch is a function to change the current directory and load the history file for that directory. | |
ch() { | |
# Check if we are already in a ch shell | |
if [[ "${__ch_load_history:-0}" == "1" ]]; then | |
echo "ch: Already in a ch shell" 1>&2 | |
return 0 | |
fi | |
local dir | |
dir=$(realpath "${1:-.}") | |
local history_file | |
if ! history_file="$(ch_hist_file "$dir")"; then | |
return 1 | |
fi | |
echo "ch: Loading history file $history_file" 1>&2 | |
# Make directory if it does not exist | |
mkdir -p "$(dirname "$history_file")" | |
# Create the history file if it does not exist | |
touch "$history_file" | |
# Set the history file for the new shell | |
export HISTFILE="$history_file" | |
# Set the history size for the new shell | |
export HISTSIZE=${HISTSIZE:-1000} | |
export HISTFILESIZE=${HISTFILESIZE:-2000} | |
# Open a new shell with the history file set to the current directory | |
# Use the --rcfile option to set the history file for the new shell. | |
exec bash --rcfile <( | |
echo ". ~/.bashrc" | |
echo "export HISTFILE='$history_file'" | |
echo "export HISTSIZE=$HISTSIZE" | |
echo "export HISTFILESIZE=$HISTFILESIZE" | |
echo "export __ch_load_history=1" | |
echo "builtin cd \"$dir\"" | |
) | |
} | |
# ch_autoload is a helper function to check if the history file exists and run `ch` if it does. | |
ch_autoload() { | |
local history_file | |
if history_file="$(ch_hist_file)" && [[ -f "$history_file" ]]; then | |
ch . | |
fi | |
} | |
# auto_ch is a wrapper function for the builtin cd command that autoloads the history file. Intended to be used as an alias for cd. | |
auto_ch() { | |
# Run the builtin cd command first | |
builtin cd "$@" || return $? | |
# Autoload the history file if it exists | |
ch_autoload | |
} | |
alias cd=auto_ch |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment