2025-06-18 19:17:20 +02:00

528 lines
18 KiB
Bash

#!/bin/sh
## SPDX-FileCopyrightText: 2004 - 2022 Tim Pope <https://tpo.pe>
## SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
##
## SPDX-License-Identifier: AGPL-3.0-or-later
## Credits: https://github.com/tpope/dotfiles/blob/master/.shrc
## {{{ Requirements
## If not running interactively, return.
case $- in
*i*) ;;
*) return;;
esac
## Source profile.
# shellcheck disable=SC1091
. "${HOME}/.profile"
## }}}
## {{{ Options
stty -ixon
set -o noclobber
set -o notify
#stty quit undef
stty werase undef
## }}}
## {{{ Alias
## Standard commands.
test -n "${VISUAL-}" && alias vi='${VISUAL}'
alias du="du -h"
alias df="df -h"
alias cp="cp -i"
alias mv="mv -i"
alias ls="ls -hF --group-directories-first --color=auto"
if has lsblk; then
_lsblk_options="NAME,FSTYPE,LABEL,SIZE,FSAVAIL,FSUSE%,MOUNTPOINT"
# shellcheck disable=SC2139
alias lsblk="lsblk -o ${_lsblk_options}"
# shellcheck disable=SC2139
alias lsblku="lsblk -o ${_lsblk_options},UUID,PARTUUID"
unset _lsblk_options
fi
if ! grep --color 2>&1 | grep -qE -e "(unrecognized|unknown) option" &&
! grep --exclude 2>&1 | grep -qE -e "(unrecognized|unknown) option"
then
alias grep="grep --exclude='.*.swp' --exclude='*~' --color=auto"
fi
alias fgrep="grep -F"
alias egrep="grep -E"
alias diff="diff --color=auto"
has dir && alias dir="dir --color=auto"
has vdir && alias vdir="vdir --color=auto"
alias ip="ip -color=auto"
has highlight && alias highlight="highlight --out-format=ansi"
has pygmentize && alias pygmentize="pygmentize -f terminal"
## Helpers.
alias reload='. ${ENV}' r="reload"
if test -f "${XDG_CONFIG_HOME:-${HOME}/.config}/x11/xprofile"; then
alias reload-xprofile='. ${XDG_CONFIG_HOME:-${HOME}/.config}/x11/xprofile'
alias rx="reload-xprofile"
fi
cd_up(){
# SPDX-FileCopyrightText: 2014 Grigory K <https://stackoverflow.com/users/2937875/grigory-k>
# SPDX-License-Identifier: CC-BY-SA-3.0
# Credits: https://stackoverflow.com/a/26134858
case "${1-}" in
[1-9])
has seq || return
# shellcheck disable=SC2312
cd "$(printf '%0.0s../' $(seq 1 "${1}"))" || return
;;
"")
cd .. || return;;
*)
# shellcheck disable=SC2312
cd "$(pwd | sed -r "s|(.*/${1}[^/]*/).*|\1|")" || return
;;
esac
}
alias up="cd_up"
## POSIX cd does not allow '--' and other shells breaks when not using it.
alias -- -="cd -" 2>/dev/null || true
test -n "${EDITOR-}" && alias e='${EDITOR}'
test -n "${VISUAL-}" && alias v='${VISUAL}'
alias j="jobs"
alias h="history"
alias l="ls -CF"
alias ll="ls -Fl"
alias la="ls -Fa"
alias lla="ls -Fla"
alias laa='ls -Fd .* 2>/dev/null'
alias llaa='ls -Fdl .* 2>/dev/null'
alias lr='ls -R'
alias lx='ll -BX'
alias lz='ll -rS'
alias lt='ll -rt'
alias lm='la | more'
alias now="date +%a\ %Y-%m-%d\ %T"
alias mkd="mkdir -pv"
mkcd(){ mkd "$1" && cd "$1" || return; }
## Non-standard programs.
has info && alias info="info --vi-keys"
has htop && alias top="htop"
has yt-dlp && alias yt="yt-dlp --add-metadata -ic"
has fdfind && alias fd="fdfind"
has lynx && alias lynx="lynx -vikeys"
has qubesctl && {
alias qctl="qubesctl"
alias qctls="qctl state.apply"
alias qctlu="qctl --skip-dom0 --targets"
qctlus(){
test -n "${2-}" || return 1
# shellcheck disable=SC3058
qubesctl --skip-dom0 --targets "${1}" state.apply "${@#"${1}"}"
}
}
has gpg && alias gpgs="gpg --show-keys"
## {{{ Tmux
has tmux && {
alias t="tmux"
alias td="t detach"
alias tls="t list-sessions" tl="tls"
alias tlw="t list-windows"
alias tlp="t list-panes"
alias tcl="clear && t clear-history" # clear buffer cus memory
tcla(){
## Clear all the panes of the current session.
for t_pane in $(tmux list-panes -s -F '#{pane_id}'); do
tmux clear-history -t "${t_pane}"
done
unset t_pane
}
}
## }}}
## {{{ Mutt
if has mutt; then
alias m="mutt"
alias mp="mutt -e 'set signature= pgp_autoinline=yes crypt_autosign=yes' -H"
fi
## }}}
## {{{ Git
if { ! test -f /usr/share/whonix/marker && has git; } ||
{ test -f /usr/share/whonix/marker && git -v >/dev/null 2>&1; }
then
## Whonix UWT wrapper circumvents the command existence check.
alias g="git"
alias gcd='cd "$(git rev-parse --show-toplevel)"'
## Use git aliases with 'g' prefix.
g_alias="$(git config --get-regexp 'alias.*' | sed 's/^alias\.//;s/ .*//')"
for key in $(printf '%s\n' "${g_alias}"); do
# shellcheck disable=SC2139,SC2140
alias "g${key}"="git ${key}"
done
unset key g_alias
fi
## }}}
## }}}
## {{{ Prompt
# shellcheck disable=SC2034
_get_term_cap(){
## SGR
_t_colors="$(tput colors)" 2>/dev/null || true
_t_sgr0="$(tput sgr0)" 2>/dev/null || true
_t_bold="$(tput bold)" 2>/dev/null || true
_t_dim="$(tput dim)" 2>/dev/null || true
_t_sitm="$(tput sitm)" 2>/dev/null || true
_t_smul="$(tput smul)" 2>/dev/null || true
_t_blink="$(tput blink)" 2>/dev/null || true
_t_rev="$(tput rev)" 2>/dev/null || true
_t_smso="$(tput rmso)" 2>/dev/null || true
_t_invis="$(tput invis)" 2>/dev/null || true
_t_ritm="$(tput ritm)" 2>/dev/null || true
_t_rmul="$(tput rmul)" 2>/dev/null || true
_t_rmso="$(tput rmso)" 2>/dev/null || true
_t_setaf_0="$(tput setaf 0)" 2>/dev/null || true
_t_setaf_1="$(tput setaf 1)" 2>/dev/null || true
_t_setaf_2="$(tput setaf 2)" 2>/dev/null || true
_t_setaf_3="$(tput setaf 3)" 2>/dev/null || true
_t_setaf_4="$(tput setaf 4)" 2>/dev/null || true
_t_setaf_5="$(tput setaf 5)" 2>/dev/null || true
_t_setaf_6="$(tput setaf 6)" 2>/dev/null || true
_t_setaf_7="$(tput setaf 7)" 2>/dev/null || true
_t_setab_0="$(tput setab 0)" 2>/dev/null || true
_t_setab_1="$(tput setab 1)" 2>/dev/null || true
_t_setab_2="$(tput setab 2)" 2>/dev/null || true
_t_setab_3="$(tput setab 3)" 2>/dev/null || true
_t_setab_4="$(tput setab 4)" 2>/dev/null || true
_t_setab_5="$(tput setab 5)" 2>/dev/null || true
_t_setab_6="$(tput setab 6)" 2>/dev/null || true
_t_setab_7="$(tput setab 7)" 2>/dev/null || true
## Movement
_t_ed="$(tput ed)" 2>/dev/null || true
_t_el="$(tput el)" 2>/dev/null || true
_t_home="$(tput home)" 2>/dev/null || true
_t_cnorm="$(tput cnorm)" 2>/dev/null || true
_t_civis="$(tput civis)" 2>/dev/null || true
_t_smcup="$(tput smcup)" 2>/dev/null || true
_t_rmcup="$(tput rmcup)" 2>/dev/null || true
_t_sc="$(tput sc)" 2>/dev/null || true
_t_clear="$(tput clear)" 2>/dev/null || true
## Extra
_t_cub1="$(tput cub1)" 2>/dev/null || true
_t_cud1="$(tput cud1)" 2>/dev/null || true
_t_ind="$(tput ind)" 2>/dev/null || true
_t_cr="$(tput cr)" 2>/dev/null || true
_t_u7="$(tput u7)" 2>/dev/null || true
_t_u8="$(tput u8)" 2>/dev/null || true
_t_u9="$(tput u9)" 2>/dev/null || true
}
_get_color_support(){
if test -n "${NO_COLOR-}"; then
color_support=-1
return 0
fi
case "${COLORTERM-}" in
truecolor|24bit)
color_support=$((1 << 24))
return 0
;;
*) ;;
esac
if has tput; then
if tput RGB >/dev/null 2>&1; then
color_support=$((1 << 24))
return 0
fi
color_support=${_t_colors}
if test -n "${color_support}"; then
return 0
fi
fi
## Color query from terminfo is relatively new, only available in ncurses
## since 2018. Below is a match based on terminfo revision 1.909 to query
## number of supported colors in case the terminfo database can't be
## queried.
case "${TERM-}" in
*?-truecolor*|*?-direct*)
## TODO: Some terminals such as iTerm should be in this list.
color_support=$((1 << 24))
;;
*?-256color*|absolute|alacritty|Apple_Terminal|domterm|iterm|iterm2|\
iTerm2.app|iTerm.app|kitty|mintty|ms-terminal|nsterm|nsterm-build309|\
nsterm-build326|nsterm-build343|nsterm-build361|nsterm-build400|\
nsterm-build440|scrt|securecrt|terminator|terminology|terminology-0.6.1|\
terminology-1.0.0|terminology-1.8.1|termite|vscode|xterm+256setaf|\
xterm.js)
color_support=256
;;
*?-88color*|rxvt-unicode)
color_support=88
;;
hpterm-color|wy370|wy370-101k|wy370-105k|wy370-EPC|wy370-nk|wy370-rv|\
wy370-vb|wy370-w|wy370-wvb|wyse370)
color_support=64
;;
d430c-dg-ccc|d430c-unix-25-ccc|d430c-unix-ccc|d430c-unix-s-ccc|\
d430c-unix-sr-ccc|d430c-unix-w-ccc|d430-dg-ccc|d430-unix-25-ccc|\
d430-unix-ccc|d430-unix-s-ccc|d430-unix-sr-ccc|d430-unix-w-ccc|dg+ccc|\
dgunix+ccc)
color_support=52
;;
*?-16color*|amiga-vnc|atari-color|atari_st-color|at-color|d430c-dg|\
d430c-unix|d430c-unix-25|d430c-unix-s|d430c-unix-sr|d430c-unix-w|d430-dg|\
d430-unix|d430-unix-25|d430-unix-s|d430-unix-sr|d430-unix-w|d470|d470-7b|\
d470c|d470c-7b|d470c-dg|d470-dg|dg+color|dg+fixed|dgmode+color|\
dgunix+fixed|hp2397|hp2397a|hp+color|ncr260wy325pp|ncr260wy325wpp|\
ncr260wy350pp|ncr260wy350wpp|nsterm-7-c|nsterm-7-c-s|nsterm-acs-c|\
nsterm-acs-c-s|nsterm-bce|nsterm+c|nsterm-c|nsterm-c-7|nsterm-c-acs|\
nsterm-c-s|nsterm-c-s-7|nsterm-c-s-acs|st52-color|tt52|tw52|\
tw52-color)
color_support=16
;;
*?-color*|color_xterm|386at|aixterm|alacritty+common|ansi|ansi80x25|\
ansi80x25-raw|ansi80x30|ansi80x43|ansi80x50|ansi80x60|ansi-emx|ansil|\
ansis|ansi.sys|ansi.sysk|ansisysk|ansi.sys-old|ansiw|arm100|arm100-am|\
arm100-w|arm100-wam|at386|aterm|att6386|beterm|bsdos-pc|bsdos-pc-nobold|\
bsdos-ppc|bterm|cons25|cons25-debian|cons25-iso8859|cons25-koi8-r|\
cons25l1|cons25r|cons25w|cons30|cons43|cons50|cons50-iso8859|\
cons50-koi8r|cons50l1|cons50r|cons60|cons60-iso|cons60-koi8r|cons60l1|\
cons60r|crt|crt-vt220|ctrm|cx|cx100|cygwin|cygwinB19|cygwinDBG|d220|\
d220-7b|d220-dg|d230|d230c|d230c-dg|d230-dg|darwin|darwin-100x37|\
darwin-112x37|darwin-128x40|darwin-128x48|darwin-144x48|darwin-160x64|\
darwin-200x64|darwin-200x75|darwin-256x96|darwin-80x25|darwin-80x30|\
darwin-90x30|darwin-b|darwin-f|darwin-f2|decansi|djgpp|djgpp204|dtterm|\
dumb-emacs-ansi|dvtm|emots|emx-base|Eterm|gnome|gnome-2007|gnome-2008|\
gnome-2012|gnome-fc5|gnome-rh62|gnome-rh72|gnome-rh80|gnome-rh90|gs6300|\
hft|hft-c|hft-c-old|hft-old|hterm|hurd|i3164|ibm3164|ibm5081|ibm5154|\
ibm6154|ibm8503|ibm8507|ibm8512|ibm8513|ibm8514|ibm8604|ibmpc3|ibmpc3r|\
interix|interix-nti|jaixterm|jfbterm|kon|kon2|konsole|konsole-base|\
konsole-linux|konsole-solaris|konsole-vt100|konsole-vt420pc|konsole-xf3x|\
konsole-xf4x|kterm|kterm-co|kvt|linux|linux2.2|linux2.6|linux2.6.26|\
linux3.0|linux-basic|linux-c|linux-c-nc|linux-koi8|linux-koi8r|linux-lat|\
linux-m1|linux-nic|linux-s|linux-vt|mgt|mgterm|minitel1|minitel1b|minix|\
minix-3.0|mintty+common|mlterm|mlterm2|mlterm3|mosh|mrxvt|ms-vt100+|\
ms-vt-utf8|mvterm|nansi.sys|nansisys|nansi.sysk|nansisysk|ncr260intan|\
ncr260intpp|ncr260intwan|ncr260intwpp|ncsa|ncsa-ns|ncsa-vt220|netbsd6|\
nsterm-7|nsterm-7-s|nsterm-acs|nsterm-acs-s|nsterm+c41|nsterm-old|\
nsterm-s|nsterm-s-7|nsterm-s-acs|ntconsole|ntconsole-100|\
ntconsole-100-nti|ntconsole-25|ntconsole-25-nti|ntconsole-25-w|\
ntconsole-25-w-vt|ntconsole-35|ntconsole-35-nti|ntconsole-35-w|\
ntconsole-50|ntconsole-50-nti|ntconsole-50-w|ntconsole-60|\
ntconsole-60-nti|ntconsole-60-w|ntconsole-w|ntconsole-w-vt|nxterm|old-st|\
opennt|opennt-100|opennt-100-nti|opennt-25|opennt-25-nti|opennt-25-w|\
opennt-25-w-vt|opennt-35|opennt-35-nti|opennt-35-w|opennt-50|\
opennt-50-nti|opennt-50-w|opennt-60|opennt-60-nti|opennt-60-w|opennt-nti|\
opennt-w|opennt-w-vt|pc3|pc3-bold|pc3r|pcansi|pcansi-25|pcansi25|\
pcansi-33|pcansi33|pcansi-43|pcansi43|pccon|pccon0|pc-minix|putty|\
putty-m1|putty-noapp|putty-sco|putty-screen|putty-vt100|qansi|qansi-g|\
qansi-m|qansi-t|qansi-w|qnx|qnx4|qnxm|qnxt|qnxt2|qnxt4|qnxw|rxvt|\
rxvt-cygwin|rxvt-cygwin-native|rxvt-xpm|scoansi|scoansi-new|scoansi-old|\
screen|screen4|screen5|screen-base|screen-bce|screen-bce.Eterm|\
screen-bce.gnome|screen-bce.konsole|screen-bce.linux|screen-bce.mrxvt|\
screen-bce.rxvt|screen-bce.xterm-new|screen.Eterm|screen.gnome|\
screen.konsole|screen.linux|screen.linux-m1|screen.linux-s|\
screen.minitel1|screen.minitel1b|screen.mlterm|screen.mrxvt|screen.putty|\
screen.putty-m1|screen.rxvt|screen-s|screen.teraterm|screen.vte|screen-w|\
screen.xterm-new|screen.xterm-xfree86|simpleterm|st|st-0.6|st-0.7|st-0.8|\
stterm|tek4205|teken|teken-2018|teken-2022|teken-sc|teken-vt|teraterm|\
teraterm2.3|teraterm4.59|teraterm4.97|ti928|ti928-8|ti_ansi|tmux|tw100|\
uwin|vt100+|vte|vte-2007|vte-2008|vte-2012|vte-2014|vte-2017|vte-2018|\
vtnt|vt-utf8|vv100|vwmterm|wsvt25|wsvt25m|wy350|wy350-vb|wy350-w|\
wy350-wvb|wyse350|wyse350-vb|wyse350-w|wyse350-wvb|xfce|xiterm|xnuppc|\
xnuppc-100x37|xnuppc-112x37|xnuppc-128x40|xnuppc-128x48|xnuppc-144x48|\
xnuppc-160x64|xnuppc-200x64|xnuppc-200x75|xnuppc-256x96|xnuppc-80x25|\
xnuppc-80x30|xnuppc-90x30|xnuppc-b|xnuppc+c|xnuppc-f|xnuppc-f2|xterm|\
xterm1|xterm-1002|xterm-1003|xterm-1005|xterm-1006|xterm-8bit|\
xterm-basic|xtermc|xterm-debian|xterm-hp|xterm-new|xterm-nic|xterm-noapp|\
xterm+nofkeys|xterm-p370|xterm-p371|xterm-sco|xterms-sun|xterm-sun|\
xterm-utf8|xterm-vt220|xterm-x10mouse|xterm-x11hilite|xterm-x11mouse|\
xterm-xf86-v32|xterm-xf86-v33|xterm-xf86-v333|xterm-xf86-v40|\
xterm-xf86-v43|xterm-xf86-v44|xterm-xfree86|xterm-xi|xwsh)
color_support=8
;;
*)
color_support=-1
;;
esac
}
_get_term_cap
_get_color_support
case "${color_support}" in
$((1 << 24))) export COLORTERM=truecolor; color_prompt=yes;;
[1-9]*) color_prompt=yes;;
*) color_prompt=no;;
esac
if test "${color_prompt-}" = "yes"; then
if has dircolors; then
## Use dircolors if available.
if test -r "${XDG_CONFIG_HOME}/dircolors/dircolors"; then
dircolors="$(dircolors -b -- "${XDG_CONFIG_HOME}/dircolors/dircolors")"
eval "${dircolors}"
else
dircolors="$(dircolors -b)"
eval "${dircolors}"
fi
unset dircolors
## Fix bold on some terminals.
case "${TERM-}" in
xterm*|screen*)
LS_COLORS="$(printf '%s' "${LS_COLORS}" |
sed -e 's/01;3\([0-9]\)/00;9\1/g')"
;;
*) ;;
esac
export LS_COLORS
else
## BSD
CLICOLOR=1 CLICOLOR_FORCE=1 LSCOLORS=ExGxFxdxCxfxDxxbadacad
export CLICOLOR CLICOLOR_FORCE LSCOLORS
fi
GCC_COLORS="error=00;31:warning=01;35:note=01;36:caret=01;32:locus=01"
GCC_COLORS="${GCC_COLORS}:quote=01"
export GCC_COLORS
## Colors for programs that uses 'less' such as 'man'.
GROFF_NO_SGR=1
LESS_TERMCAP_mb="${_t_bold}${_t_setaf_2}"
LESS_TERMCAP_md="${_t_bold}${_t_setaf_6}"
LESS_TERMCAP_me="${_t_sgr0}"
LESS_TERMCAP_so="${_t_bold}${_t_setaf_7}${_t_setab_4}"
LESS_TERMCAP_se="${_t_rmso}${_t_sgr0}"
LESS_TERMCAP_us="${_t_smul}${_t_bold}${_t_setaf_2}"
LESS_TERMCAP_ue="${_t_rmul}${_t_sgr0}"
LESS_TERMCAP_mr="${_t_rev}"
LESS_TERMCAP_mh="${_t_dim}"
export GROFF_NO_SGR
export LESS_TERMCAP_mb LESS_TERMCAP_md LESS_TERMCAP_me
export LESS_TERMCAP_so LESS_TERMCAP_se LESS_TERMCAP_us
export LESS_TERMCAP_ue LESS_TERMCAP_mr LESS_TERMCAP_mh
fi
# shellcheck disable=SC3028
_get_prompt_time(){
test -n "${SECONDS:-}" || return
# shellcheck disable=SC2154
ptime="$((SECONDS-_saved_prompt_time))"
printf '%02d:%02d:%02d' \
"$((ptime/3600))" "$(((ptime%3600)/60))" "$((ptime%60))"
unset ptime
}
_git_prompt_info(){
has git || return
## Whonix UWT wrapper circumvents the command existence check.
if test -f /usr/share/whonix/marker; then
git -v >/dev/null 2>&1 || return
fi
ref="$(git symbolic-ref HEAD 2>/dev/null | cut -d '/' -f3)"
test "${ref-}" ||
ref="$(git describe --tags --exact-match HEAD 2>/dev/null)"
test "${ref-}" || ref="$(git rev-parse HEAD 2>/dev/null | cut -c 1-7)"
test "${ref-}" || return
case "${color_support-}" in
256|$((1 << 24))) branchcolor="$(printf '%b' "\033[38;5;31m")";;
88) branchcolor="$(printf '%b' "\033[38;5;22m")";;
[1-9]*) branchcolor="${_t_bold}${_t_setaf_4}";;
*) branchcolor="";;
esac
if test -n "${ZSH_VERSION-}"; then
# shellcheck disable=2016
if test "${color_prompt-}" = "yes"; then
print -Pn '(%%{${branchcolor}%%}%20>...>${ref}%<<%%{${_t_sgr0}%%})'
else
print -Pn '(%20>...>${ref}%<<)'
fi
else
if test "${color_prompt-}" = "yes"; then
printf '%s' "(${branchcolor}${ref}${_t_sgr0})"
else
printf '%s' "(${ref})"
fi
fi
unset ref branchcolor
}
# shellcheck disable=SC2034
case "${color_support-}" in
256|$((1 << 24)))
usercolor="$(printf '%b' "\033[38;5;184m")"
dircolor="$(printf '%b' "\033[38;5;27m")"
;;
88)
usercolor="$(printf '%b' "\033[38;5;56m")"
dircolor="$(printf '%b' "\033[38;5;23m")"
;;
[1-9]*)
usercolor="${_t_bold}${_t_setaf_3}"
dircolor="${_t_bold}${_t_setaf_4}"
;;
*)
usercolor=""
dircolor=""
;;
esac
case "${ZSH_VERSION-}" in
"") ps1_symbol="$";;
*) ps1_symbol="%%";;
esac
# shellcheck disable=SC2034
uid="$(id -u)"
if test "${uid}" = "0"; then
usercolor="${_t_bold}${_t_setaf_7}"
ps1_symbol="#"
fi
unset uid
user="$(id -un)"
if test "${color_prompt-}" = "yes"; then
PS1="[${usercolor}${user} $(hostname -s)${_t_sgr0}]${ps1_symbol} "
else
PS1="${user}@$(hostname -s)${ps1_symbol} "
fi
unset user uid
## }}}
## {{{ External Functions
## Source file if it is readable.
## Usage: source_readable FILE
source_readable(){
for _file in "${@}"; do
# shellcheck disable=SC1090
! test -r "${_file}" || . "${_file}"
done
unset _file
}
_fzf_comprun() {
_fzf_command="$1"
shift
case "${_fzf_command}" in
cd) if has tree; then
fzf --preview 'tree -C -- {} | head -200' "${@}"
else
fzf "${@}"
fi
;;
export|unset)
fzf --preview "eval 'printf '%s\n' \$'{}" "${@}"
;;
ssh)
if has dig; then
fzf --preview 'dig {}' "${@}"
fi
;;
*)
fzf --preview 'test -d {} || cat -- {}' "${@}"
;;
esac
unset _fzf_command
}
## }}}
## {{{ End
## Source local shell configuration file.
source_readable "${HOME}/.shrc.local"
## }}}