From 8052911861883c9e3d1187529a72b72921f27746 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Mon, 27 Dec 2021 14:16:58 -0800 Subject: [PATCH 1/4] plugin/history: don't use `export` ...so the plugin is friendly to variables already marked read-only. --- plugins/available/history.plugin.bash | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/available/history.plugin.bash b/plugins/available/history.plugin.bash index be253e4a..4c8cdaba 100644 --- a/plugins/available/history.plugin.bash +++ b/plugins/available/history.plugin.bash @@ -5,11 +5,11 @@ about-plugin 'improve history handling with sane defaults' # variable when the shell exits, rather than overwriting the file. shopt -s histappend -# erase duplicates; alternative option: export HISTCONTROL=ignoredups -export HISTCONTROL=${HISTCONTROL:-ignorespace:erasedups} +# erase duplicates; alternative option: HISTCONTROL=ignoredups +: "${HISTCONTROL:=ignorespace:erasedups}" # resize history to 100x the default (500) -export HISTSIZE=${HISTSIZE:-50000} +: "${HISTSIZE:=50000}" # Flush history to disk after each command. export PROMPT_COMMAND="history -a;${PROMPT_COMMAND}" From 267a721ac607ea85fd262a0b4b490254854bab69 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Mon, 27 Dec 2021 14:21:44 -0800 Subject: [PATCH 2/4] plugin/history-eternal: Use `readonly` instead of `export` ...and hide errors relating to setting already-readonly variables. `plugin/history-eternal` does not need to force loading after `plugin/history` because both plugins will play nicely with read-only variables, and since we're overwritting and marking read-only then the intended result survives no matter which loads first. plugin/history-eternal: require Bash v4.3+ Unlimited history is only possible in _Bash_ version 4.3 and up --- plugins/available/history-eternal.plugin.bash | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/available/history-eternal.plugin.bash b/plugins/available/history-eternal.plugin.bash index a18283d3..829868df 100644 --- a/plugins/available/history-eternal.plugin.bash +++ b/plugins/available/history-eternal.plugin.bash @@ -1,20 +1,22 @@ # shellcheck shell=bash about-plugin 'eternal bash history' -# Load after the history plugin -# BASH_IT_LOAD_PRIORITY: 375 +if [[ ${BASH_VERSINFO[0]} -lt 4 ]] || [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 3 ]]; then + _log_warning "Bash version 4.3 introduced the 'unlimited' history size capability." + return 1 +fi # Modify history sizes before changing location to avoid unintentionally # truncating the history file early. # "Numeric values less than zero result in every command being saved on the history list (there is no limit)" -export HISTSIZE=-1 +readonly HISTSIZE=-1 2> /dev/null || true # "Non-numeric values and numeric values less than zero inhibit truncation" -export HISTFILESIZE='unlimited' +readonly HISTFILESIZE='unlimited' 2> /dev/null || true # Use a custom history file location so history is not truncated # if the environment ever loses this "eternal" configuration. HISTDIR="${XDG_STATE_HOME:-${HOME?}/.local/state}/bash" [[ -d ${HISTDIR?} ]] || mkdir -p "${HISTDIR?}" -export HISTFILE="${HISTDIR?}/history" +readonly HISTFILE="${HISTDIR?}/history" 2> /dev/null || true From f6119567e835b2048ca7ac015663381151e45b8e Mon Sep 17 00:00:00 2001 From: John D Pell Date: Mon, 27 Dec 2021 16:38:46 -0800 Subject: [PATCH 3/4] plugin/history*search: no need to load after `plugin/history` There's no need for these plugins to load after `plugin/history`. None of the history plugins depend upon each other loading before, after, or at all. --- plugins/available/history-search.plugin.bash | 3 --- plugins/available/history-substring-search.plugin.bash | 3 --- 2 files changed, 6 deletions(-) diff --git a/plugins/available/history-search.plugin.bash b/plugins/available/history-search.plugin.bash index 341ce2af..96941993 100644 --- a/plugins/available/history-search.plugin.bash +++ b/plugins/available/history-search.plugin.bash @@ -1,9 +1,6 @@ # shellcheck shell=bash about-plugin 'search history using the prefix already entered' -# Load after the history plugin -# BASH_IT_LOAD_PRIORITY: 375 - # enter a few characters and press UpArrow/DownArrow # to search backwards/forwards through the history if [[ ${SHELLOPTS} =~ (vi|emacs) ]]; then diff --git a/plugins/available/history-substring-search.plugin.bash b/plugins/available/history-substring-search.plugin.bash index 586ceb50..dde32720 100644 --- a/plugins/available/history-substring-search.plugin.bash +++ b/plugins/available/history-substring-search.plugin.bash @@ -1,9 +1,6 @@ # shellcheck shell=bash about-plugin 'search history using the substring already entered' -# Load after the history plugin -# BASH_IT_LOAD_PRIORITY: 375 - # enter a few characters and press UpArrow/DownArrow # to search backwards/forwards through the history if [[ ${SHELLOPTS} =~ (vi|emacs) ]]; then From 5d5858058ec61abefcfb122f90bd0eee3d8276f5 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Mon, 24 Jan 2022 21:37:04 -0800 Subject: [PATCH 4/4] lib/history: new functions `_bash-it-history-auto-*()` Two new functions `_bash-it-history-auto-save()` and `_bash-it-history-auto-load()`, which append new history to disk and load new history from disk, respectively. See bash-it/bash-it#1595 for discussion. --- clean_files.txt | 1 + lib/history.bash | 49 +++++++++++++++++++++++++++ plugins/available/history.plugin.bash | 9 +++-- themes/base.theme.bash | 5 +-- 4 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 lib/history.bash diff --git a/clean_files.txt b/clean_files.txt index 8f9c173a..70b1175c 100644 --- a/clean_files.txt +++ b/clean_files.txt @@ -83,6 +83,7 @@ completion/available/wpscan.completion.bash # libraries lib/colors.bash lib/helpers.bash +lib/history.bash lib/log.bash lib/preexec.bash lib/search.bash diff --git a/lib/history.bash b/lib/history.bash new file mode 100644 index 00000000..7bdbbd5e --- /dev/null +++ b/lib/history.bash @@ -0,0 +1,49 @@ +# shellcheck shell=bash +# +# Functions for working with Bash's command history. + +function _bash-it-history-init() { + safe_append_preexec '_bash-it-history-auto-save' + safe_append_prompt_command '_bash-it-history-auto-load' +} + +function _bash-it-history-auto-save() { + case $HISTCONTROL in + *'noauto'* | *'autoload'*) + : # Do nothing, as configured. + ;; + *'auto'*) + # Append new history from this session to the $HISTFILE + history -a + ;; + *) + # Append *only* if shell option `histappend` has been enabled. + shopt -q histappend && history -a && return + ;; + esac +} + +function _bash-it-history-auto-load() { + case $HISTCONTROL in + *'noauto'*) + : # Do nothing, as configured. + ;; + *'autosave'*) + # Append new history from this session to the $HISTFILE + history -a + ;; + *'autoloadnew'*) + # Read new entries from $HISTFILE + history -n + ;; + *'auto'*) + # Blank in-memory history, then read entire $HISTFILE fresh from disk. + history -a && history -c && history -r + ;; + *) + : # Do nothing, default. + ;; + esac +} + +_bash_it_library_finalize_hook+=('_bash-it-history-init') diff --git a/plugins/available/history.plugin.bash b/plugins/available/history.plugin.bash index 4c8cdaba..d9e930c3 100644 --- a/plugins/available/history.plugin.bash +++ b/plugins/available/history.plugin.bash @@ -5,15 +5,14 @@ about-plugin 'improve history handling with sane defaults' # variable when the shell exits, rather than overwriting the file. shopt -s histappend -# erase duplicates; alternative option: HISTCONTROL=ignoredups -: "${HISTCONTROL:=ignorespace:erasedups}" +# 'ignorespace': don't save command lines which begin with a space to history +# 'erasedups' (alternative 'ignoredups'): don't save duplicates to history +# 'autoshare': automatically share history between multiple running shells +: "${HISTCONTROL:=ignorespace:erasedups:autoshare}" # resize history to 100x the default (500) : "${HISTSIZE:=50000}" -# Flush history to disk after each command. -export PROMPT_COMMAND="history -a;${PROMPT_COMMAND}" - function top-history() { about 'print the name and count of the most commonly run tools' diff --git a/themes/base.theme.bash b/themes/base.theme.bash index a7e99961..d7479b3f 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -584,6 +584,7 @@ function aws_profile { } function _save-and-reload-history() { - local autosave=${1:-0} - [[ $autosave -eq 1 ]] && history -a && history -c && history -r + local autosave="${1:-${HISTORY_AUTOSAVE:-0}}" + [[ ${autosave} -eq 1 ]] && local HISTCONTROL="${HISTCONTROL:-}${HISTCONTROL:+:}autoshare" + _bash-it-history-auto-save && _bash-it-history-auto-load }