Skip to content
Open
Show file tree
Hide file tree
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
56 changes: 26 additions & 30 deletions src/atuin/scripts/bash-preexec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Author: Ryan Caloras (ryan@bashhub.com)
# Forked from Original Author: Glyph Lefkowitz
#
# V0.5.0
# V0.6.0
#

# General Usage:
Expand Down Expand Up @@ -38,7 +38,7 @@
# Make sure this is bash that's running and return otherwise.
# Use POSIX syntax for this line:
if [ -z "${BASH_VERSION-}" ]; then
return 1;
return 1
fi

# We only support Bash 3.1+.
Expand All @@ -48,7 +48,7 @@ if [[ -z "${BASH_VERSINFO-}" ]] || (( BASH_VERSINFO[0] < 3 || (BASH_VERSINFO[0]
fi

# Avoid duplicate inclusion
if [[ -n "${bash_preexec_imported:-}" ]]; then
if [[ -n "${bash_preexec_imported:-}" || -n "${__bp_imported:-}" ]]; then
return 0
fi
bash_preexec_imported="defined"
Expand Down Expand Up @@ -76,13 +76,13 @@ __bp_install_string=$'__bp_trap_string="$(trap -p DEBUG)"\ntrap - DEBUG\n__bp_in
# Fails if any of the given variables are readonly
# Reference https://stackoverflow.com/a/4441178
__bp_require_not_readonly() {
local var
for var; do
if ! ( unset "$var" 2> /dev/null ); then
echo "bash-preexec requires write access to ${var}" >&2
return 1
fi
done
local var
for var; do
if ! ( unset "$var" 2> /dev/null ); then
echo "bash-preexec requires write access to ${var}" >&2
return 1
fi
done
}

# Remove ignorespace and or replace ignoreboth from HISTCONTROL
Expand All @@ -95,7 +95,7 @@ __bp_adjust_histcontrol() {
# Replace ignoreboth with ignoredups
if [[ "$histcontrol" == *"ignoreboth"* ]]; then
histcontrol="ignoredups:${histcontrol//ignoreboth}"
fi;
fi
export HISTCONTROL="$histcontrol"
}

Expand Down Expand Up @@ -136,7 +136,7 @@ __bp_sanitize_string() {
# It sets a variable to indicate that the prompt was just displayed,
# to allow the DEBUG trap to know that the next command is likely interactive.
__bp_interactive_mode() {
__bp_preexec_interactive_mode="on";
__bp_preexec_interactive_mode="on"
}


Expand All @@ -154,7 +154,7 @@ __bp_precmd_invoke_cmd() {
# prompt command" by another precmd execution loop. This avoids infinite
# recursion.
if (( __bp_inside_precmd > 0 )); then
return
return
fi
local __bp_inside_precmd=1

Expand Down Expand Up @@ -211,7 +211,7 @@ __bp_preexec_invoke_exec() {
__bp_last_argument_prev_command="${1:-}"
# Don't invoke preexecs if we are inside of another preexec.
if (( __bp_inside_preexec > 0 )); then
return
return
fi
local __bp_inside_preexec=1

Expand All @@ -222,9 +222,9 @@ __bp_preexec_invoke_exec() {
return
fi

if [[ -n "${COMP_LINE:-}" ]]; then
# We're in the middle of a completer. This obviously can't be
# an interactively issued command.
if [[ -n "${COMP_POINT:-}" || -n "${READLINE_POINT:-}" ]]; then
# We're in the middle of a completer or a keybinding set up by "bind
# -x". This obviously can't be an interactively issued command.
return
fi
if [[ -z "${__bp_preexec_interactive_mode:-}" ]]; then
Expand All @@ -250,10 +250,8 @@ __bp_preexec_invoke_exec() {
fi

local this_command
this_command=$(
export LC_ALL=C
HISTTIMEFORMAT='' builtin history 1 | sed '1 s/^ *[0-9][0-9]*[* ] //'
)
this_command=$(LC_ALL=C HISTTIMEFORMAT='' builtin history 1)
this_command="${this_command#*[[:digit:]][* ] }"

# Sanity check to make sure we have something to invoke our function with.
if [[ -z "$this_command" ]]; then
Expand Down Expand Up @@ -291,20 +289,18 @@ __bp_preexec_invoke_exec() {
__bp_install() {
# Exit if we already have this installed.
if [[ "${PROMPT_COMMAND[*]:-}" == *"__bp_precmd_invoke_cmd"* ]]; then
return 1;
return 1
fi

trap '__bp_preexec_invoke_exec "$_"' DEBUG

# Preserve any prior DEBUG trap as a preexec function
local prior_trap
# we can't easily do this with variable expansion. Leaving as sed command.
# shellcheck disable=SC2001
prior_trap=$(sed "s/[^']*'\(.*\)'[^']*/\1/" <<<"${__bp_trap_string:-}")
eval "local trap_argv=(${__bp_trap_string:-})"
local prior_trap=${trap_argv[2]:-}
unset __bp_trap_string
if [[ -n "$prior_trap" ]]; then
eval '__bp_original_debug_trap() {
'"$prior_trap"'
'"$prior_trap"'
}'
preexec_functions+=(__bp_original_debug_trap)
fi
Expand All @@ -321,7 +317,7 @@ __bp_install() {
# Set so debug trap will work be invoked in subshells.
set -o functrace > /dev/null 2>&1
shopt -s extdebug > /dev/null 2>&1
fi;
fi

local existing_prompt_command
# Remove setting our trap install string and sanitize the existing prompt command string
Expand Down Expand Up @@ -369,12 +365,12 @@ __bp_install_after_session_init() {
if [[ -n "$sanitized_prompt_command" ]]; then
# shellcheck disable=SC2178 # PROMPT_COMMAND is not an array in bash <= 5.0
PROMPT_COMMAND=${sanitized_prompt_command}$'\n'
fi;
fi
# shellcheck disable=SC2179 # PROMPT_COMMAND is not an array in bash <= 5.0
PROMPT_COMMAND+=${__bp_install_string}
}

# Run our install so long as we're not delaying it.
if [[ -z "${__bp_delay_install:-}" ]]; then
__bp_install_after_session_init
fi;
fi
186 changes: 31 additions & 155 deletions src/atuin/scripts/install-atuin.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#! /usr/bin/env bash

set -euo pipefail
#! /bin/sh
set -eu

cat << EOF
_______ _______ __ __ ___ __ _
Expand All @@ -15,173 +14,34 @@ Magical shell history

Atuin setup
https://github.com/atuinsh/atuin
https://forum.atuin.sh

Please file an issue if you encounter any problems!
Please file an issue or reach out on the forum if you encounter any problems!

===============================================================================

EOF

if ! command -v curl &> /dev/null; then
__atuin_install_binary(){
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/atuinsh/atuin/releases/latest/download/atuin-installer.sh | sh
}

if ! command -v curl > /dev/null; then
echo "curl not installed. Please install curl."
exit
elif ! command -v sed &> /dev/null; then
elif ! command -v sed > /dev/null; then
echo "sed not installed. Please install sed."
exit
fi

LATEST_RELEASE=$(curl -L -s -H 'Accept: application/json' https://github.com/atuinsh/atuin/releases/latest)
# Allow sed; sometimes it's more readable than ${variable//search/replace}
# shellcheck disable=SC2001
LATEST_VERSION=$(echo "$LATEST_RELEASE" | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')

__atuin_install_arch(){
echo "Arch Linux detected!"

if command -v pacman &> /dev/null
then
echo "Installing with pacman"
sudo pacman -S atuin
else
echo "Attempting AUR install"
if command -v yaourt &> /dev/null; then
echo "Found yaourt"
yaourt -S atuin
elif command -v yay &> /dev/null; then
echo "Found yay"
yay -S atuin
elif command -v pakku &> /dev/null; then
echo "Found pakku"
pakku -S atuin
elif command -v pamac &> /dev/null; then
echo "Found pamac"
pamac install atuin
else
echo "Failed to install atuin! Please try manually: https://aur.archlinux.org/packages/atuin-git/"
fi
fi

}

__atuin_install_ubuntu(){
if [ "$(dpkg --print-architecture)" = "amd64" ]; then
echo "Ubuntu detected"
ARTIFACT_URL="https://github.com/atuinsh/atuin/releases/download/$LATEST_VERSION/atuin_${LATEST_VERSION//v/}_amd64.deb"
TEMP_DEB="$(mktemp)".deb &&
curl -Lo "$TEMP_DEB" "$ARTIFACT_URL"
if command -v sudo &> /dev/null; then
sudo apt install "$TEMP_DEB"
else
su -l -c "apt install '$TEMP_DEB'"
fi
rm -f "$TEMP_DEB"
else
echo "Ubuntu detected, but not amd64"
__atuin_install_unsupported
fi
}

__atuin_install_linux(){
echo "Detected Linux!"
echo "Checking distro..."
if (uname -a | grep -qi "Microsoft"); then
OS="ubuntuwsl"
elif ! command -v lsb_release &> /dev/null; then
echo "lsb_release could not be found. Falling back to /etc/os-release"
OS="$(grep -Po '(?<=^ID=).*$' /etc/os-release | tr '[:upper:]' '[:lower:]')" 2>/dev/null
else
OS=$(lsb_release -i | awk '{ print $3 }' | tr '[:upper:]' '[:lower:]')
fi
case "$OS" in
"arch" | "manjarolinux" | "endeavouros")
__atuin_install_arch;;
"ubuntu" | "ubuntuwsl" | "debian" | "linuxmint" | "parrot" | "kali" | "elementary" | "pop")
__atuin_install_ubuntu;;
*)
# TODO: download a binary or smth
__atuin_install_unsupported;;
esac
}

__atuin_install_mac(){
echo "Detected Mac!"

if command -v brew &> /dev/null
then
echo "Installing with brew"
brew install atuin
else
echo "Could not find brew, installing with Cargo"
__atuin_install_unsupported
fi

}

__atuin_install_termux(){
echo "Termux detected!"

if command -v pkg &> /dev/null; then
echo "Installing with pkg"
pkg install atuin
else
echo "Could not find pkg"
__atuin_install_unsupported
fi
}

__atuin_install_cargo(){
echo "Attempting install with cargo"

if ! command -v cargo &> /dev/null
then
echo "cargo not found! Attempting to install rustup"

if command -v rustup &> /dev/null
then
echo "rustup was found, but cargo wasn't. Something is up with your install"
exit 1
fi

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -q

echo "rustup installed! Attempting cargo install"

fi

cargo install atuin
}

__atuin_install_unsupported(){
echo "Unknown or unsupported OS or architecture"
echo "Please check the README at https://github.com/atuinsh/atuin for manual install instructions"
echo "If you have any problems, please open an issue!"

while true; do
read -r -p "Do you wish to attempt an install with 'cargo'? [Y/N] " yn
case $yn in
[Yy]* ) __atuin_install_cargo; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
}

# TODO: would be great to support others!
case "$OSTYPE" in
linux-android*) __atuin_install_termux ;;
linux*) __atuin_install_linux ;;
darwin*) __atuin_install_mac ;;
msys*) __atuin_install_unsupported ;;
solaris*) __atuin_install_unsupported ;;
bsd*) __atuin_install_unsupported ;;
*) __atuin_install_unsupported ;;
esac
__atuin_install_binary

# TODO: Check which shell is in use
# Use of single quotes around $() is intentional here
# shellcheck disable=SC2016
if ! grep -q "atuin init zsh" ~/.zshrc; then
printf '\neval "$(atuin init zsh)"\n' >> ~/.zshrc
if ! grep -q "atuin init zsh" "${ZDOTDIR:-$HOME}/.zshrc"; then
printf '\neval "$(atuin init zsh)"\n' >> "${ZDOTDIR:-$HOME}/.zshrc"
fi

# Use of single quotes around $() is intentional here
Expand All @@ -193,6 +53,22 @@ if ! grep -q "atuin init bash" ~/.bashrc; then
echo 'eval "$(atuin init bash)"' >> ~/.bashrc
fi

if [ -f "$HOME/.config/fish/config.fish" ]; then
# Check if the line already exists to prevent duplicates
if ! grep -q "atuin init fish" "$HOME/.config/fish/config.fish"; then
# Detect BSD or GNU sed
if sed --version >/dev/null 2>&1; then
# GNU
sed -i '/if status is-interactive/,/end/ s/end$/ atuin init fish | source\
end/' "$HOME/.config/fish/config.fish"
else
# BSD (macOS)
sed -i '' '/if status is-interactive/,/end/ s/end$/ atuin init fish | source\
end/' "$HOME/.config/fish/config.fish"
fi
fi
fi

cat << EOF


Expand All @@ -209,10 +85,10 @@ cat << EOF

Thanks for installing Atuin! I really hope you like it.

If you have any issues, please open an issue on GitHub or visit our Discord (https://discord.gg/dPhv2B3x)!
If you have any issues, please open an issue on GitHub or visit our forum (https://forum.atuin.sh)!

If you love Atuin, please give us a star on GitHub! It really helps ⭐️ https://github.com/atuinsh/atuin

Please run "atuin register" to get setup with sync, or "atuin login" if you already have an account

EOF
EOF
Loading
Loading