Files
dao_hades/cradle/usr/local/bin/prompt.sh
2025-11-08 06:38:37 +00:00

275 lines
6.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# ---
# @file_name: prompt.sh
# @version: 1.0.1
# @description: a prompt
# @author: Jamie Albert (empty_produce)
# @author_contact: <mailto:empty.produce@flatmail.me>
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
declare -g _cached_uh=""
declare -g _uh_cache_key=""
declare -g _cached_pyenv_version=""
declare -g _pyenv_cache_key=""
declare -g _cached_readonly=""
declare -g _readonly_cache_key=""
# ---
# Shell options configuration
# ---
shopt -s histappend
shopt -s cmdhist
shopt -s histreedit
shopt -s histverify
shopt -s interactive_comments
shopt -s checkwinsize
shopt -s globstar
shopt -s nocaseglob
shopt -s dirspell
shopt -s cdspell
shopt -u autocd
if [[ $- =~ "i" ]]; then
bind "set completion-ignore-case on"
bind "set show-all-if-ambiguous on"
bind "set mark-symlinked-directories on"
fi
# ---
# * Symbols
# ---
_prompt_symbol=""
_git_symbol="git:"
_pyenv_symbol="pyenv:"
_readonly_symbol="ro:"
_screen_symbol="scr:"
# ---
# * Colours
# ---
_prompt_success_colour="142"
_prompt_fail_colour="203"
_prompt_user_colour="109"
_prompt_sudo_colour="208"
_prompt_at_colour="249"
_prompt_hostname_colour="132"
_prompt_info_colour="172"
_prompt_input_colour="254"
_prompt_dir_colour="249"
_git_module_colour="66"
_pyenv_module_colour="66"
_readonly_module_colour="196"
_screen_module_colour="33"
# ---
# * Miscellaneous
# ---
_prompt_hostname="all"
_prompt_separator=" "
_prompt_wrapper="[]"
# ---
# // Nerd Symbols
# ---
# _git_symbol="󰘦"
# _pyenv_symbol="󰌠"
# _readonly_symbol="󰍁"
# _screen_symbol="󰐅"
# _prompt_symbol="󰥭"
# ---
# * Aliases
# ---
alias count='find . -type f | wc -l'
alias cdd='cd /home/jamie/dao'
alias dnf='sudo dnf'
alias hist='history|grep'
alias ll="ls -laFh"
alias la='ls -A'
alias li='la | grep -i'
alias lh='ll -d .*'
alias mkdir='mkdir -p'
alias nano='nano -W'
alias qq='exit'
alias sc='sudo systemctl'
alias xclipc='xclip -sel c'
# ---
# * Environment settings
# ---
declare -g HISTTIMEFORMAT='%F %T '
declare -g PROMPT_DIRTRIM="2"
[[ -z "$LC_CTYPE" && -z "$LC_ALL" ]] && declare -g LC_CTYPE="${LANG%%:*}"
[[ -z "$HISTFILE" ]] && declare -g HISTFILE="$HOME/.bash_history"
declare -x HISTCONTROL=ignorespace
declare -x HISTFILESIZE=10000
declare -x HISTSIZE=${HISTFILESIZE}
# ---
# * colour function
# ---
_prompt_colour() {
[[ ${1} != "-" ]] && echo -ne "\[\033[38;5;${1}m\]" || echo -ne "\[\033[0m\]"
}
# ---
# * Generate prompt segments
# ---
_prompt_generate() {
declare _separator="" _text="${1%%|*}" _colour="${1##*|}"
[[ ${_prompt_seg} -gt 1 ]] && _separator="${_prompt_separator}"
_prompt_information+="${_separator}$(_prompt_colour "${_colour}")${_text}\[\e[0m\]"
((_prompt_seg++))
}
# ---
# * Screen
# ---
_screen_pre() {
[[ ${TERM} == "screen"* ]] && _prompt_generate "${_screen_symbol}|${_screen_module_colour}"
}
# ---
# * Git
# ---
_git_post() {
[[ -z "$_git_dir" ]] && _git_dir="$(git rev-parse --git-dir 2>/dev/null)"
[[ -n "$_git_dir" ]] || return
local _unsafe_ref
_unsafe_ref=$(git symbolic-ref -q HEAD 2>/dev/null) || return
local _clean_ref="${_unsafe_ref##refs/heads/}"
_clean_ref="${_clean_ref//[^a-zA-Z0-9\/]/-}"
# Add status indicators
local _status=""
[[ -n "$(git status --porcelain 2>/dev/null)" ]] && _status="*"
[[ -n "$(git ls-files --others --exclude-standard 2>/dev/null)" ]] && _status="${_status}+"
[[ -n ${_clean_ref} ]] && _prompt_generate "${_git_symbol} ${_clean_ref}${_status}|${_git_module_colour}"
}
# ---
# * Pyenv
# ---
_pyenv_post() {
[[ -n ${VIRTUAL_ENV} ]] || return
[[ "$VIRTUAL_ENV" != "$_pyenv_cache_key" ]] && {
_cached_pyenv_version="${PYTHON_VERSION}"
[[ -z ${_cached_pyenv_version} ]] && _cached_pyenv_version="$(python3 --version 2>/dev/null)"
_cached_pyenv_version="${_cached_pyenv_version#Python }"
_pyenv_cache_key="$VIRTUAL_ENV"
}
[[ -n ${_cached_pyenv_version} ]] && _prompt_generate "${_prompt_wrapper:0:1}${_pyenv_symbol} ${_cached_pyenv_version}${_prompt_wrapper:1:1}|${_pyenv_module_colour}"
}
# ---
# * Readonly
# ---
_readonly_post() {
[[ "$PWD" != "$_readonly_cache_key" ]] && {
_cached_readonly=""
[[ ! -w "$(pwd)" ]] && _cached_readonly="readonly"
_readonly_cache_key="$PWD"
}
[[ -n "$_cached_readonly" ]] && _prompt_generate "${_prompt_wrapper:0:1}${_readonly_symbol}${_prompt_wrapper:1:1}|${_readonly_module_colour}"
}
# ---
# * Build the main prompt
# ---
_prompt_build() {
declare _last_status="$?" _gen_uh _cache_key="${PWD}"
declare -gi _prompt_seg=1
[[ "$_cache_key" != "$_last_cache_key" ]] && {
unset _git_dir _cached_pyenv_version
_last_cache_key="$_cache_key"
}
# ---
# ! Insert *pre* functions here
# ---
# START
_screen_pre
# END
# ---
# * User and hostname
# ---
declare _user_colour="${_prompt_user_colour}"
sudo -nv 2>/dev/null && _user_colour="${_prompt_sudo_colour}"
_gen_uh="${_cached_uh}"
# Change the cache key to include sudo status
_uh_cache_key="${_prompt_hostname}:${SSH_CLIENT:-}:$(sudo -n -v 2>/dev/null && echo 'sudo' || echo 'nosudo')"
[[ "$_uh_cache_key" != "$_last_uh_key" ]] && {
_gen_uh="$(_prompt_colour "${_user_colour}")${USER}"
# Add hostname if needed
if [[ ${_prompt_hostname} == "all" ]] || [[ ${_prompt_hostname} == "ssh" && -n ${SSH_CLIENT} ]]; then
_gen_uh+="$(_prompt_colour "${_prompt_at_colour}")@$(_prompt_colour "${_prompt_hostname_colour}")${HOSTNAME}"
fi
_gen_uh+="\[\033[0m\]" # Reset color
_cached_uh="$_gen_uh"
_last_uh_key="$_uh_cache_key"
}
_prompt_generate "${_gen_uh}|${_prompt_info_colour}"
# ---
# * Current directory
# ---
declare _current_dir="${PWD}"
_current_dir="${_current_dir/#$HOME/\~}"
# Build the segment with individual colours for each part
_prompt_generate "$(_prompt_colour "${_prompt_info_colour}")${_prompt_wrapper:0:1}$(_prompt_colour "${_prompt_dir_colour}")${_current_dir}$(_prompt_colour "${_prompt_info_colour}")${_prompt_wrapper:1:1}\[\033[0m\]|${_prompt_info_colour}"
# ---
# * Error status
# ---
[[ ${_last_status} -ne 0 ]] && _prompt_generate "${_prompt_wrapper:0:1}${_last_status}${_prompt_wrapper:1:1}|${_prompt_fail_colour}"
# ---
# ! Insert *post* functions here
# ---
# START
_git_post
_pyenv_post
_readonly_post
# END
# ---
# *Final prompt symbol
# ---
_prompt_status_colour=${_prompt_success_colour}
[[ ${_last_status} -ne 0 ]]&& _prompt_status_colour=${_prompt_fail_colour}
_prompt_information+="$(_prompt_colour "${_prompt_status_colour}")\n${_prompt_symbol}\[\e[0m\]"
PS1="${_prompt_information} "
unset _prompt_information _prompt_seg
}
# ---
# * Initialize prompt
# ---
_prompt_init() {
case "$PROMPT_COMMAND" in
*"_prompt_build"*) ;;
"") PROMPT_COMMAND="_prompt_build" ;;
*) PROMPT_COMMAND="_prompt_build;${PROMPT_COMMAND}" ;;
esac
}
# ---
# * Initialize when sourced
# ---
[[ ${BASH_SOURCE[0]} != "${0}" ]] && _prompt_init