if [[ ${__atuin_initialized-} == true ]]; then
false
elif [[ $- != *i* ]]; then
false
elif ((BASH_VERSINFO[0] < 3 || BASH_VERSINFO[0] == 3 && BASH_VERSINFO[1] < 1)); then
[[ -t 2 ]] && printf 'atuin: requires bash >= 3.1 for the integration.\n' >&2
false
else __atuin_initialized=true
if [[ -z "${ATUIN_SESSION:-}" || "${ATUIN_SHLVL:-}" != "$SHLVL" ]]; then
ATUIN_SESSION=$(atuin uuid)
export ATUIN_SESSION
export ATUIN_SHLVL=$SHLVL
fi
ATUIN_STTY=$(stty -g)
ATUIN_HISTORY_ID=""
export ATUIN_PREEXEC_BACKEND=$SHLVL:none
__atuin_update_preexec_backend() {
if [[ ${BLE_ATTACHED-} ]]; then
ATUIN_PREEXEC_BACKEND=$SHLVL:blesh-${BLE_VERSION-}
elif [[ ${bash_preexec_imported-} ]]; then
ATUIN_PREEXEC_BACKEND=$SHLVL:bash-preexec
elif [[ ${__bp_imported-} ]]; then
ATUIN_PREEXEC_BACKEND="$SHLVL:bash-preexec (old)"
else
ATUIN_PREEXEC_BACKEND=$SHLVL:unknown
fi
}
__atuin_preexec() {
if [[ ! ${BLE_ATTACHED-} ]]; then
if [[ $BASH_COMMAND != "$1" ]]; then
case $BASH_COMMAND in
'__atuin_history'* | '__atuin_widget_run'* | '__atuin_bash42_dispatch'*)
ATUIN_HISTORY_ID=__bash_preexec_failure__
return 0 ;;
esac
fi
fi
__atuin_update_preexec_backend
local id
id=$(atuin history start -- "$1" 2>/dev/null)
export ATUIN_HISTORY_ID=$id
__atuin_preexec_time=${EPOCHREALTIME-}
}
__atuin_precmd() {
local EXIT=$? __atuin_precmd_time=${EPOCHREALTIME-}
[[ ! $ATUIN_HISTORY_ID ]] && return
if [[ $ATUIN_HISTORY_ID == __bash_preexec_failure__ ]]; then
local previous_command
previous_command=$(
export LC_ALL=C HISTTIMEFORMAT=''
builtin history 1 | sed '1 s/^ *[0-9][0-9]*[* ] //'
)
__atuin_preexec "$previous_command"
fi
local duration=""
if [[ ${BLE_ATTACHED-} && ${_ble_exec_time_ata-} ]]; then
duration=${_ble_exec_time_ata}000
elif ((BASH_VERSINFO[0] >= 5)); then
duration=$((${__atuin_precmd_time//[!0-9]} - ${__atuin_preexec_time//[!0-9]}))
if ((duration >= 0)); then
duration=${duration}000
else
duration="" fi
fi
(ATUIN_LOG=error atuin history end --exit "$EXIT" ${duration:+"--duration=$duration"} -- "$ATUIN_HISTORY_ID" &) >/dev/null 2>&1
export ATUIN_HISTORY_ID=""
}
__atuin_set_ret_value() {
return ${1:+"$1"}
}
if ((BASH_VERSINFO[0] >= 5 || BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4)); then
__atuin_evaluate_prompt() {
__atuin_set_ret_value "${__bp_last_ret_value-}" "${__bp_last_argument_prev_command-}"
__atuin_prompt=${PS1@P}
__atuin_prompt=${__atuin_prompt//[$'\001\002']}
__atuin_prompt_offset=${__atuin_prompt//[!$'\n']}
__atuin_prompt_offset=${#__atuin_prompt_offset}
}
else
__atuin_evaluate_prompt() {
__atuin_prompt='$ '
__atuin_prompt_offset=0
}
fi
__atuin_clear_prompt_cache=()
__atuin_clear_prompt() {
local offset=$1
if [[ ! ${__atuin_clear_prompt_cache[offset]+set} ]]; then
if [[ ! ${__atuin_clear_prompt_cache[0]+set} ]]; then
__atuin_clear_prompt_cache[0]=$'\r'$(tput el 2>/dev/null || tput ce 2>/dev/null)
fi
if ((offset > 0)); then
__atuin_clear_prompt_cache[offset]=${__atuin_clear_prompt_cache[0]}$(
tput cuu "$offset" 2>/dev/null || tput UP "$offset" 2>/dev/null
tput dl "$offset" 2>/dev/null || tput DL "$offset" 2>/dev/null
tput il "$offset" 2>/dev/null || tput AL "$offset" 2>/dev/null
)
fi
fi
printf '%s' "${__atuin_clear_prompt_cache[offset]}"
}
__atuin_accept_line() {
local __atuin_command=$1
local __atuin_prompt __atuin_prompt_offset
__atuin_evaluate_prompt
__atuin_clear_prompt "$__atuin_prompt_offset"
printf '%s\n' "$__atuin_prompt$__atuin_command"
history -s "$__atuin_command"
local __atuin_preexec_function
local __atuin_preexec_function_ret_value
local __atuin_preexec_ret_value=0
for __atuin_preexec_function in "${preexec_functions[@]:-}"; do
if type -t "$__atuin_preexec_function" 1>/dev/null; then
__atuin_set_ret_value "${__bp_last_ret_value:-}"
"$__atuin_preexec_function" "$__atuin_command"
__atuin_preexec_function_ret_value=$?
if [[ $__atuin_preexec_function_ret_value != 0 ]]; then
__atuin_preexec_ret_value=$__atuin_preexec_function_ret_value
fi
fi
done
if ! { shopt -q extdebug && ((__atuin_preexec_ret_value)); }; then
export -n READLINE_LINE READLINE_POINT
local __atuin_stty_backup
__atuin_stty_backup=$(stty -g)
stty "$ATUIN_STTY"
__atuin_set_ret_value "${__bp_last_ret_value-}" "${__bp_last_argument_prev_command-}"
eval -- "$__atuin_command"$'\n__bp_last_ret_value=$? __bp_last_argument_prev_command=$_'
stty "$__atuin_stty_backup"
fi
local __atuin_prompt_command
for __atuin_prompt_command in "${PROMPT_COMMAND[@]}"; do
__atuin_set_ret_value "${__bp_last_ret_value-}" "${__bp_last_argument_prev_command-}"
eval -- "$__atuin_prompt_command"
done
__atuin_evaluate_prompt
printf '%s' "$__atuin_prompt"
__atuin_clear_prompt 0
}
__atuin_tmux_popup_check() {
[[ -n "${TMUX-}" ]] || return 1
[[ "${ATUIN_TMUX_POPUP:-true}" != "false" ]] || return 1
local tmux_version
tmux_version=$(tmux -V 2>/dev/null | sed -n 's/^[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p') [[ -z "$tmux_version" ]] && return 1
local m1 m2
m1=${tmux_version%%.*}
m2=${tmux_version#*.}
m2=${m2%%.*}
[[ "$m1" =~ ^[0-9]+$ ]] || return 1
[[ "$m2" =~ ^[0-9]+$ ]] || m2=0
(( m1 > 3 || (m1 == 3 && m2 >= 2) ))
}
__atuin_popup_tmpdir=""
__atuin_tmux_popup_cleanup() {
[[ -n "$__atuin_popup_tmpdir" && -d "$__atuin_popup_tmpdir" ]] && command rm -rf "$__atuin_popup_tmpdir"
__atuin_popup_tmpdir=""
}
__atuin_search_cmd() {
local -a search_args=("$@")
if __atuin_tmux_popup_check; then
__atuin_popup_tmpdir=$(mktemp -d) || return 1
local result_file="$__atuin_popup_tmpdir/result"
trap '__atuin_tmux_popup_cleanup' EXIT HUP INT TERM
local escaped_query escaped_args
escaped_query=$(printf '%s' "$READLINE_LINE" | sed "s/'/'\\\\''/g")
escaped_args=""
for arg in "${search_args[@]}"; do
escaped_args+=" '$(printf '%s' "$arg" | sed "s/'/'\\\\''/g")'"
done
local cdir popup_width popup_height
cdir=$(pwd)
popup_width="${ATUIN_TMUX_POPUP_WIDTH:-80%}" popup_height="${ATUIN_TMUX_POPUP_HEIGHT:-60%}"
tmux display-popup -d "$cdir" -w "$popup_width" -h "$popup_height" -E -E -- \
sh -c "PATH='$PATH' ATUIN_SESSION='$ATUIN_SESSION' ATUIN_SHELL=bash ATUIN_LOG=error ATUIN_QUERY='$escaped_query' atuin search $escaped_args -i 2>'$result_file'"
if [[ -f "$result_file" ]]; then
cat "$result_file"
fi
__atuin_tmux_popup_cleanup
trap - EXIT HUP INT TERM
else
ATUIN_SHELL=bash ATUIN_LOG=error ATUIN_QUERY=$READLINE_LINE atuin search "${search_args[@]}" -i 3>&1 1>&2 2>&3
fi
}
__atuin_history() {
if [[ ${BLE_ATTACHED-} && ${1-} == --shell-up-key-binding ]]; then
if [[ ${_ble_edit_str::_ble_edit_ind} == *$'\n'* || $_ble_edit_mark_active ]]; then
ble/widget/@nomarked backward-line
local status=$?
READLINE_LINE=$_ble_edit_str
READLINE_POINT=$_ble_edit_ind
READLINE_MARK=$_ble_edit_mark
return "$status"
fi
fi
[[ ${BLE_ATTACHED-} ]] || ((BASH_VERSINFO[0] >= 4)) ||
READLINE_LINE="" READLINE_POINT=0
local __atuin_output
__atuin_output=$(__atuin_search_cmd "$@")
[[ $__atuin_output ]] || return 0
if [[ $__atuin_output == __atuin_accept__:* ]]; then
__atuin_output=${__atuin_output#__atuin_accept__:}
if [[ ${BLE_ATTACHED-} ]]; then
ble-edit/content/reset-and-check-dirty "$__atuin_output"
ble/widget/accept-line
READLINE_LINE=""
elif [[ ${__atuin_macro_chain_keymap-} ]]; then
READLINE_LINE=$__atuin_output
bind -m "$__atuin_macro_chain_keymap" '"'"$__atuin_macro_chain"'": '"$__atuin_macro_accept_line"
else
__atuin_accept_line "$__atuin_output"
READLINE_LINE=""
fi
READLINE_POINT=${#READLINE_LINE}
else
READLINE_LINE=$__atuin_output
READLINE_POINT=${#READLINE_LINE}
if [[ ! ${BLE_ATTACHED-} ]] && ((BASH_VERSINFO[0] < 4)) && [[ ${__atuin_macro_chain_keymap-} ]]; then
bind -m "$__atuin_macro_chain_keymap" '"'"$__atuin_macro_chain"'": '"$__atuin_macro_insert_line"
fi
fi
}
__atuin_initialize_blesh() {
[[ ${BLE_VERSION-} ]] && ((_ble_version >= 400)) || return 0
ble-import contrib/integration/bash-preexec
function ble/complete/auto-complete/source:atuin-history {
local suggestion
suggestion=$(ATUIN_QUERY="$_ble_edit_str" atuin search --cmd-only --limit 1 --search-mode prefix 2>/dev/null)
[[ $suggestion == "$_ble_edit_str"?* ]] || return 1
ble/complete/auto-complete/enter h 0 "${suggestion:${#_ble_edit_str}}" '' "$suggestion"
}
ble/util/import/eval-after-load core-complete '
ble/array#unshift _ble_complete_auto_source atuin-history'
[[ ${BLE_SESSION_ID-} ]] && export BLE_SESSION_ID
}
__atuin_initialize_blesh
BLE_ONLOAD+=(__atuin_initialize_blesh)
precmd_functions+=(__atuin_precmd)
preexec_functions+=(__atuin_preexec)
__atuin_widget=()
__atuin_widget_save() {
local data=$1
for REPLY in "${!__atuin_widget[@]}"; do
if [[ ${__atuin_widget[REPLY]} == "$data" ]]; then
return 0
fi
done
REPLY=${#__atuin_widget[*]}
__atuin_widget[REPLY]=$data
}
__atuin_widget_run() {
local data=${__atuin_widget[$1]}
local keymap=${data%%:*} widget=${data#*:}
local __atuin_macro_chain_keymap=$keymap
bind -m "$keymap" '"'"$__atuin_macro_chain"'": ""'
builtin eval -- "$widget"
}
__atuin_macro_chain='\C-x\C-_A0\a'
for __atuin_keymap in emacs vi-insert vi-command; do
bind -m "$__atuin_keymap" "\"$__atuin_macro_chain\": \"\""
done
unset -v __atuin_keymap
if ((BASH_VERSINFO[0] >= 5 || BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 3)); then
__atuin_macro_accept_line=accept-line
__atuin_bind_impl() {
local keymap=$1 keyseq=$2 command=$3
local REPLY
__atuin_widget_save "$keymap:$command"
local widget=$REPLY
local ikeyseq1='\C-x\C-_A'$((1 + widget))'\a'
local ikeyseq2=$__atuin_macro_chain
if ((BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] == 1)); then
bind -m "$keymap" -r "$keyseq"
fi
bind -m "$keymap" "\"$keyseq\": \"$ikeyseq1$ikeyseq2\""
bind -m "$keymap" -x "\"$ikeyseq1\": __atuin_widget_run $widget"
}
__atuin_bind_blesh_onload() {
bleopt decode_error_cseq_discard=
}
if [[ ${BLE_VERSION-} ]]; then
__atuin_bind_blesh_onload
fi
BLE_ONLOAD+=(__atuin_bind_blesh_onload)
else
__atuin_bash42_code0='\C-xQ'
__atuin_bash42_code1='\C-xR'
__atuin_bash42_code2='\C-xS'
__atuin_bash42_encode() {
REPLY=
local n=$1 min_width=${2-}
while
if ((n % 2 == 0)); then
REPLY=$__atuin_bash42_code0$REPLY
else
REPLY=$__atuin_bash42_code1$REPLY
fi
(((n /= 2) || ${#REPLY} / ${#__atuin_bash42_code0} < min_width))
do :; done
}
__atuin_bash42_bind() {
local __atuin_keymap
for __atuin_keymap in emacs vi-insert vi-command; do
bind -m "$__atuin_keymap" -x '"'"$__atuin_bash42_code0"'": __atuin_bash42_dispatch_selector+=0'
bind -m "$__atuin_keymap" -x '"'"$__atuin_bash42_code1"'": __atuin_bash42_dispatch_selector+=1'
bind -m "$__atuin_keymap" -x '"'"$__atuin_bash42_code2"'": __atuin_bash42_dispatch'
done
}
__atuin_bash42_bind
BLE_ONLOAD+=(__atuin_bash42_bind)
if ((BASH_VERSINFO[0] >= 4)); then
__atuin_macro_accept_line=accept-line
else
for __atuin_keymap in emacs vi-insert vi-command; do
bind -m "$__atuin_keymap" '"\C-x\C-_A1\a": beginning-of-line'
bind -m "$__atuin_keymap" '"\C-x\C-_A2\a": kill-line'
bind -m "$__atuin_keymap" '"\C-x\C-_A3\a": "$READLINE_LINE"'
bind -m "$__atuin_keymap" '"\C-x\C-_A4\a": shell-expand-line'
bind -m "$__atuin_keymap" '"\C-x\C-_A5\a": accept-line'
bind -m "$__atuin_keymap" '"\C-x\C-_A6\a": end-of-line'
done
unset -v __atuin_keymap
bind -m vi-command '"\C-x\C-_A7\a": vi-insertion-mode'
bind -m vi-insert '"\C-x\C-_A7\a": vi-movement-mode'
bind -m emacs '"\C-x\C-_A10\a": "\C-x\C-_A1\a\C-x\C-_A2\a\C-x\C-_A3\a\C-x\C-_A4\a"'
bind -m vi-insert '"\C-x\C-_A10\a": "\C-x\C-_A1\a\C-x\C-_A2\a\C-x\C-_A3\a\C-x\C-_A4\a"'
bind -m vi-command '"\C-x\C-_A10\a": "\C-x\C-_A1\a\C-x\C-_A2\a\C-x\C-_A7\a\C-x\C-_A3\a\C-x\C-_A7\a\C-x\C-_A4\a"'
__atuin_macro_accept_line='"\C-x\C-_A10\a\C-x\C-_A5\a"'
__atuin_macro_insert_line='"\C-x\C-_A10\a\C-x\C-_A6\a"'
fi
__atuin_bash42_dispatch_selector=
__atuin_bash42_dispatch() {
local s=$__atuin_bash42_dispatch_selector
__atuin_bash42_dispatch_selector=
__atuin_widget_run "$((2#0$s))"
}
__atuin_bind_impl() {
local keymap=$1 keyseq=$2 command=$3
__atuin_widget_save "$keymap:$command"
__atuin_bash42_encode "$REPLY"
local macro=$REPLY$__atuin_bash42_code2$__atuin_macro_chain
bind -m "$keymap" "\"$keyseq\": \"$macro\""
}
fi
atuin-bind() {
local keymap=
local OPTIND=1 OPTARG="" OPTERR=0 flag
while getopts ':m:' flag "$@"; do
case $flag in
m) keymap=$OPTARG ;;
*)
printf '%s\n' "atuin-bind: unrecognized option '-$flag'" >&2
return 2
;;
esac
done
shift "$((OPTIND - 1))"
if (($# != 2)); then
printf '%s\n' 'usage: atuin-bind [-m keymap] keyseq widget' >&2
return 2
fi
local keyseq=$1
[[ $keymap ]] || keymap=$(bind -v | awk '$2 == "keymap" { print $3 }')
case $keymap in
emacs-meta) keymap=emacs keyseq='\e'$keyseq ;;
emacs-ctlx) keymap=emacs keyseq='\C-x'$keyseq ;;
emacs*) keymap=emacs ;;
vi-insert) ;;
vi*) keymap=vi-command ;;
*)
printf '%s\n' "atuin-bind: unknown keymap '$keymap'" >&2
return 2 ;;
esac
local command=$2 widget=${2%%[[:blank:]]*}
case $widget in
atuin-search) command=${2/#"$widget"/__atuin_history} ;;
atuin-search-emacs) command=${2/#"$widget"/__atuin_history --keymap-mode=emacs} ;;
atuin-search-viins) command=${2/#"$widget"/__atuin_history --keymap-mode=vim-insert} ;;
atuin-search-vicmd) command=${2/#"$widget"/__atuin_history --keymap-mode=vim-normal} ;;
atuin-up-search) command=${2/#"$widget"/__atuin_history --shell-up-key-binding} ;;
atuin-up-search-emacs) command=${2/#"$widget"/__atuin_history --shell-up-key-binding --keymap-mode=emacs} ;;
atuin-up-search-viins) command=${2/#"$widget"/__atuin_history --shell-up-key-binding --keymap-mode=vim-insert} ;;
atuin-up-search-vicmd) command=${2/#"$widget"/__atuin_history --shell-up-key-binding --keymap-mode=vim-normal} ;;
esac
__atuin_bind_impl "$keymap" "$keyseq" "$command"
}
if [[ $__atuin_bind_ctrl_r == true ]]; then
atuin-bind -m emacs '\C-r' atuin-search-emacs
atuin-bind -m vi-insert '\C-r' atuin-search-viins
atuin-bind -m vi-command '/' atuin-search-emacs
fi
if [[ $__atuin_bind_up_arrow == true ]]; then
atuin-bind -m emacs '\e[A' atuin-up-search-emacs
atuin-bind -m emacs '\eOA' atuin-up-search-emacs
atuin-bind -m vi-insert '\e[A' atuin-up-search-viins
atuin-bind -m vi-insert '\eOA' atuin-up-search-viins
atuin-bind -m vi-command '\e[A' atuin-up-search-vicmd
atuin-bind -m vi-command '\eOA' atuin-up-search-vicmd
atuin-bind -m vi-command 'k' atuin-up-search-vicmd
fi
fi