397 lines
10 KiB
Bash
397 lines
10 KiB
Bash
#!/usr/bin/env bash
|
||
|
||
blesh=true
|
||
|
||
# ─< Helper functions >─────────────────────────────────────────────────────────────────
|
||
# ───────────────────────────────────< Message storage >─────────────────────────────────
|
||
declare -A _MESSAGES
|
||
_MESSAGES=(
|
||
[missing]=""
|
||
[error]=""
|
||
[warn]=""
|
||
[info]=""
|
||
)
|
||
|
||
# Define color variables
|
||
RED='\033[0;31m'
|
||
YELLOW='\033[0;33m'
|
||
CYAN='\033[0;36m'
|
||
GREEN='\033[1;32m'
|
||
NC='\033[0m' # No Color
|
||
BOLD='\033[1m'
|
||
|
||
# Functions to store messages
|
||
echo_error() {
|
||
_MESSAGES[error]+="${RED}❌ $@${NC}\n"
|
||
}
|
||
|
||
echo_missing() {
|
||
_MESSAGES[missing]+="${YELLOW} $@${NC}\n"
|
||
}
|
||
|
||
echo_warning() {
|
||
_MESSAGES[warn]+="${YELLOW}⚠️ $@${NC}\n"
|
||
}
|
||
|
||
echo_info() {
|
||
_MESSAGES[info]+="${CYAN}ℹ️ $@${NC}\n"
|
||
}
|
||
|
||
if $blesh; then
|
||
if [ ! -e /usr/share/blesh/ble.sh ] && [ ! -e "$HOME/.local/share/blesh/ble.sh" ]; then
|
||
blesh=false
|
||
echo_missing blesh
|
||
fi
|
||
fi
|
||
|
||
if $blesh; then
|
||
[[ $- == *i* ]] && { source /usr/share/blesh/ble.sh --noattach || source "$HOME/.local/share/blesh/ble.sh" --noattach; }
|
||
# Enable history expansion (!!, !$, etc.) in ble.sh
|
||
bleopt history_expand_on_space=1
|
||
fi
|
||
|
||
# Display stored messages
|
||
error_log() {
|
||
[[ -z "${_MESSAGES[error]}${_MESSAGES[warn]}${_MESSAGES[info]}${_MESSAGES[missing]}" ]] && return 0
|
||
|
||
typeset -A headers colors
|
||
headers=(
|
||
missing "⚠️ MISSING ESSENTIALS ⚠️"
|
||
error "❌ Errors"
|
||
warn "⚠️ Warnings"
|
||
info "ℹ️ Info"
|
||
)
|
||
colors=(
|
||
missing "$YELLOW"
|
||
error "$RED"
|
||
warn "$YELLOW"
|
||
info "$CYAN"
|
||
)
|
||
|
||
for type in error warn info missing; do
|
||
[[ -n "${_MESSAGES[$type]}" ]] && {
|
||
printf "\n${BOLD}${colors[$type]}=== ${headers[$type]} ===${NC}\n"
|
||
printf "${_MESSAGES[$type]}"
|
||
}
|
||
done
|
||
}
|
||
|
||
# ─< Silent execution >─────────────────────────────────────────────────────────────────
|
||
silentexec() {
|
||
"$@" >/dev/null 2>&1
|
||
}
|
||
|
||
# ─< Check if the given command exists silently >─────────────────────────────────────────
|
||
command_exists() {
|
||
command -v "$@" >/dev/null 2>&1
|
||
}
|
||
|
||
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
|
||
check_root() {
|
||
if [ "$(id -u)" -ne 0 ]; then
|
||
if command_exists sudo; then
|
||
# echo_warning "User is not root. Using sudo for privileged operations."
|
||
_sudo="sudo -E"
|
||
else
|
||
# echo_error "No sudo found and you're not root! Can't install packages."
|
||
return 1
|
||
fi
|
||
else
|
||
echo_info "Root access confirmed."
|
||
_sudo=""
|
||
fi
|
||
}
|
||
|
||
_source() {
|
||
[[ -e "$1" ]] &&
|
||
. "$1" &&
|
||
echo "Sourced $1"
|
||
}
|
||
|
||
_sources() {
|
||
_source "$HOME/.bash_aliases"
|
||
}
|
||
|
||
setup-pkg() {
|
||
case "$1" in
|
||
apt)
|
||
install() {
|
||
if command-exists nala; then
|
||
$_sudo nala install --assume-yes "$@"
|
||
else
|
||
$_sudo apt install --color=always --assume-yes "$@"
|
||
fi
|
||
}
|
||
|
||
if command_exists nala; then
|
||
alias search="nala search"
|
||
alias update="$_sudo nala update && $_sudo nala upgrade --full"
|
||
alias remove="$_sudo nala purge"
|
||
else
|
||
alias search="apt-cache search"
|
||
alias update="$_sudo apt update && $_sudo apt upgrade"
|
||
alias remove="$_sudo apt purge"
|
||
fi
|
||
return 0
|
||
;;
|
||
pacman)
|
||
install() {
|
||
if command_exists paru; then
|
||
paru -S --no-confirm --color=always "$@"
|
||
elif command_exists yay; then
|
||
yay -S --no-confirm --color=always "$@"
|
||
else
|
||
$_sudo pacman -S --no-confirm --color=always "$@"
|
||
fi
|
||
}
|
||
|
||
if command_exists paru; then
|
||
alias search="paru -Ss"
|
||
alias update="paru -Syu"
|
||
alias remove="paru -R"
|
||
elif command_exists yay; then
|
||
alias search="yay -Ss"
|
||
alias update="yay -Syu"
|
||
alias remove="yay -R"
|
||
else
|
||
alias search="pacman -Ss"
|
||
alias update="$_sudo pacman -Syu"
|
||
alias remove="$_sudo pacman -R"
|
||
fi
|
||
return 0
|
||
;;
|
||
dnf)
|
||
alias install="$_sudo dnf install"
|
||
alias search="pacman -Ss"
|
||
alias update="$_sudo pacman -Syu"
|
||
alias remove="$_sudo pacman -R"
|
||
return 0
|
||
;;
|
||
zypper)
|
||
alias install="$_sudo zypper install"
|
||
alias search="zypper search"
|
||
alias update="$_sudo zypper dup"
|
||
alias remove="$_sudo zypper remove"
|
||
return 0
|
||
;;
|
||
apk)
|
||
alias install="$_sudo apk add"
|
||
alias search="apk search"
|
||
alias update="$_sudo apk update && $_sudo apk upgrade"
|
||
alias remove="$_sudo apk del"
|
||
return 0
|
||
;;
|
||
esac
|
||
|
||
local pkg=() p
|
||
|
||
pkg=(
|
||
apt
|
||
dnf
|
||
pacman
|
||
zypper
|
||
apk
|
||
)
|
||
|
||
for p in "${pkg[@]}"; do
|
||
if command_exists $p; then
|
||
setup-pkg $p
|
||
break
|
||
fi
|
||
done
|
||
}
|
||
|
||
setup-keychain() {
|
||
setupKeys() {
|
||
local keys=(
|
||
"homelab-id_rsa"
|
||
"hetzner_id_rsa"
|
||
)
|
||
|
||
for i in "${keys[@]}"; do
|
||
if [ -n $i ]; then
|
||
if [ -e "$i" ]; then
|
||
eval "$(keychain --eval --noask --agents ssh ~/.ssh/$i)"
|
||
fi
|
||
else
|
||
return 69
|
||
fi
|
||
done
|
||
}
|
||
|
||
if ! setupKeys; then
|
||
eval "$(keychain --eval --noask --agents ssh ~/.ssh/{homelab-id_rsa,hetzner_id_rsa})"
|
||
fi
|
||
}
|
||
|
||
_init() {
|
||
# ─< fzf >────────────────────────────────────────────────────────────────────────────────
|
||
if command_exists fzf; then
|
||
eval "$(fzf --bash)"
|
||
else
|
||
echo_missing fzf
|
||
fi
|
||
|
||
# ─< oh-my-posh initialization >────────────────────────────────────────────────────────────
|
||
if command_exists oh-my-posh; then
|
||
eval "$(oh-my-posh init bash --config "$HOME/.omp.toml")"
|
||
# eval "$(curl -fsSL https://git.k4li.de/dotfiles/oh-my-posh/raw/branch/main/zen.toml)"
|
||
else
|
||
if command_exists curl; then
|
||
curl -s https://ohmyposh.dev/install.sh | $_sudo bash -s -- -d /usr/bin/
|
||
binDirs=(
|
||
"$HOME/.local/bin"
|
||
"/usr/local/bin"
|
||
"/usr/bin"
|
||
)
|
||
|
||
while ! command_exists oh-my-posh; do
|
||
for binDir in "${binDirs[@]}"; do
|
||
if [ -d "$binDir" ]; then
|
||
case "$binDir" in
|
||
"$HOME/.local/bin")
|
||
echo_info "Installing oh-my-posh into $binDir"
|
||
curl -s https://ohmyposh.dev/install.sh | bash -s -- -d "$binDir"
|
||
;;
|
||
*)
|
||
echo_info "Installing oh-my-posh into $binDir"
|
||
curl -s https://ohmyposh.dev/install.sh | $_sudo bash -s -- -d "$binDir"
|
||
;;
|
||
esac
|
||
fi
|
||
done
|
||
done
|
||
fi
|
||
fi
|
||
}
|
||
|
||
_env() {
|
||
local essentials=(
|
||
neovim
|
||
git
|
||
docker
|
||
zoxide
|
||
yazi
|
||
curl
|
||
tmux
|
||
fzf
|
||
cowsay
|
||
btop
|
||
)
|
||
|
||
for pkg in "${essentials[@]}"; do
|
||
case $pkg in
|
||
neovim)
|
||
if ! command_exists nvim; then
|
||
echo_missing "$pkg"
|
||
if command_exists vim; then
|
||
EDITOR=vim
|
||
elif command_exists vi; then
|
||
EDITOR=vi
|
||
else
|
||
echo_missing "vim & vi"
|
||
fi
|
||
else
|
||
EDITOR=nvim
|
||
fi
|
||
|
||
;;
|
||
*)
|
||
if ! command_exists $pkg; then
|
||
echo_missing "$pkg"
|
||
fi
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
_color_prompt_() {
|
||
# set a fancy prompt (non-color, unless we know we "want" color)
|
||
case "$TERM" in
|
||
xterm-color | *-256color) color_prompt=yes ;;
|
||
esac
|
||
|
||
# uncomment for a colored prompt, if the terminal has the capability; turned
|
||
# off by default to not distract the user: the focus in a terminal window
|
||
# should be on the output of commands, not on the prompt
|
||
force_color_prompt=yes
|
||
|
||
if [ -n "$force_color_prompt" ]; then
|
||
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
|
||
# We have color support; assume it's compliant with Ecma-48
|
||
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
|
||
# a case would tend to support setf rather than setaf.)
|
||
color_prompt=yes
|
||
else
|
||
color_prompt=
|
||
fi
|
||
|
||
if [ "$color_prompt" = yes ]; then
|
||
# PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
|
||
PS1="\[$(tput setaf 196)\]\u\[$(tput setaf 247)\]@\[$(tput setaf 203)\]\h \[$(tput setaf 49)\]\w \[$(tput sgr0)\]$ "
|
||
else
|
||
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
|
||
fi
|
||
unset color_prompt force_color_prompt
|
||
fi
|
||
}
|
||
|
||
_end() {
|
||
# ─< fastfetch >────────────────────────────────────────────────────────────────────────────
|
||
if command_exists fastfetch; then
|
||
alias ff="fastfetch"
|
||
alias clearff="command clear & fastfetch"
|
||
alias clearf="command clear & fastfetch"
|
||
if fastfetch --config os >/dev/null 2>&1; then
|
||
alias f="fastfetch --config os"
|
||
else
|
||
git clone https://git.k4li.de/mirrors/fastfetch.git "$HOME/.local/share/fastfetch" >/dev/null 2>&1
|
||
exec $SHELL
|
||
fi
|
||
command clear &
|
||
fastfetch
|
||
fi
|
||
|
||
if command_exists cowsay; then
|
||
alias clear='clear && cowsay -f tux "$(uptime --pretty)"'
|
||
cowsay -f tux "$(uptime --pretty)"
|
||
fi
|
||
|
||
# ─< zoxide >─────────────────────────────────────────────────────────────────────────────
|
||
if command_exists zoxide; then
|
||
eval "$(zoxide init bash)"
|
||
fi
|
||
|
||
error_log
|
||
}
|
||
|
||
main() {
|
||
# _sources
|
||
# _blesh
|
||
_init
|
||
|
||
_color_prompt_
|
||
_env
|
||
check_root
|
||
setup-pkg
|
||
_end
|
||
|
||
_source "$HOME/.bash_aliases"
|
||
_source "$HOME/.bash/plugins/autopairs.sh"
|
||
_source "$HOME/.fzf/shell/completion.bash"
|
||
_source "$HOME/.fzf/shell/key-bindings.bash"
|
||
|
||
if command_exists keychain; then
|
||
eval "$(keychain --eval --noask --agents ssh ~/.ssh/{homelab-id_rsa,hetzner_id_rsa})"
|
||
# setup-keychain
|
||
else
|
||
echo_missing "keychain"
|
||
fi
|
||
}
|
||
|
||
main
|
||
if $blesh; then
|
||
set -o vi
|
||
|
||
[[ ! ${BLE_VERSION-} ]] || ble-attach
|
||
fi
|