Ben Grande 45a0acb222
feat: support truecolor
- Standardize capability usage with the terminfo database for
  portability. POSIX tput does declare only the basic options such as
  'init', 'reset' and 'clear', leaving the rest unspecified, that is not
  ideal but hard coding escape sequences is way worse.
- Set colorization options based on number of colors the terminal
  supports and not the TERM variable when possible. This is incomplete,
  terminal emulators may support or adapt more than it is advertised,
  but involves using DECRQSS queries and delays, as an example, 'resize'
  utility from XTerm uses 3 seconds as delay, this is worrisome.
- Term with only '-direct' variants without ending with 256 means it
  only supports direct-color indexing, therefore 'tmux-direct' cannot be
  used, but the non-multiplexer terminal 'xterm-direct256' can.
2025-03-27 11:42:50 +01:00

152 lines
3.9 KiB
Bash

#!/usr/bin/env bash
## SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
##
## SPDX-License-Identifier: AGPL-3.0-or-later
## {{{ Requirements
## If not running interactively, return.
case $- in
*i*) ;;
*) return;;
esac
## Source default files.
# shellcheck disable=SC1090,SC1091
source "${HOME}/.profile"
# shellcheck disable=SC1090
source "${ENV}"
## }}}
## {{{ Options
HISTCONTROL=ignoredups
shopt -s autocd
shopt -s direxpand
shopt -s cdspell
shopt -s dirspell
shopt -s histappend
shopt -s checkwinsize
shopt -s extglob
shopt -s globstar
## }}}
## {{{ Alias
alias reload="exec bash"
## }}}
## {{{ Prompt
if test -z "${debian_chroot:-}" && test -r /etc/debian_chroot; then
debian_chroot="$(cat -- /etc/debian_chroot)"
fi
_reset_line() {
case "${TERM-}" in
""|dumb|linux*|vt100*|vt220*) return;;
*) ;;
esac
## Credit: Can't find the source, posted on StackExchange or alike.
## Does not work well on Bash 5.0 and older.
bash_version_clean="${BASH_VERSION%.*}"
bash_version_clean="${bash_version_clean//\./}"
if [[ ! ${bash_version_clean} =~ ^[0-9]+$ ]]; then
return
fi
if test "${bash_version_clean}" -lt 51; then
unset bash_version_clean
return
fi
unset bash_version_clean
## Ask the terminal for any pending (line buffered) input.
termios="$(stty -g)" && stty -icanon && stty "${termios}"
unset termios
## On pending input, assume it's been echoed and we're not in first column.
## Otherwise ask the terminal for current column and read it from input.
if read -t 0 || {
# shellcheck disable=SC2154
IFS='[;' read -s -r -d'R' -p "${_t_u7}" _ _ cur_y && [[ ${cur_y} != 1 ]]
}
then
unset cur_y
## Print line ending char with reversed video and end with newline.
if test "${color_prompt-}" = "yes"; then
# shellcheck disable=SC2154
printf '%s\n\r' "${_t_sgr0}${_t_rev}%${_t_sgr0}"
else
printf '%s\n\r' "%"
fi
fi
}
_print_ec(){
test "${_ec_ps1}" = "0" && return
if test "${color_prompt:-}" = "yes"; then
# shellcheck disable=SC2154
printf '(\001%s\002%s\001%s\002)' "${_t_setaf_1}" "${_ec_ps1}" \
"${_t_sgr0}"
else
printf '(%s)' "${_ec_ps1}"
fi
unset _ec_ps1
}
_save_ec() { _ec_ps1=$?; }
PROMPT_COMMAND=(_save_ec)
newline=$'\n'
# shellcheck disable=SC2154
if test "${color_prompt:-}" = "yes"; then
# shellcheck disable=SC2154
PS1="\$(_reset_line)\$(resize-terminal)\[${_t_setaf_5}\][\[${_t_sgr0}\]"
PS1="${PS1}${debian_chroot:+(${debian_chroot})}\[${usercolor}\]\u@\h "
PS1="${PS1}\[${dircolor}\]\w\[${_t_sgr0}\]\$(_git_prompt_info)"
PS1="${PS1}\[${_t_setaf_5}\]]\[${_t_sgr0}\]${newline-}\$(_print_ec)"
PS1="${PS1}${ps1_symbol} "
else
PS1="\$(_reset_line)\$(resize-terminal)"
PS1="${PS1}[${debian_chroot:+(${debian_chroot})}"
PS1="${PS1}\u@\h:\w\$(_git_prompt_info)]${newline-}\$(_print_ec)"
PS1="${PS1}${ps1_symbol} "
fi
case "${TERM-}" in
screen*|xterm*|rxvt*)
## Set window title
PS1="\[\033]0;${debian_chroot:+(${debian_chroot})}\u@\h: \w\a\]${PS1}"
;;
*) ;;
esac
case "${TERM-}" in
""|dumb|linux*|vt100*|vt220*)
PS0=""
;;
*)
## Reset cursor to steady block after command input and before execution.
# shellcheck disable=SC2034
PS0="\033[2 q\2"
;;
esac
if ! shopt -oq posix; then
source_readable /usr/share/bash-completion/bash_completion
fi
unset newline ps1_symbol dircolor usercolor
## }}}
## {{{ Plugins
if has zoxide; then
zoxide_bash_completion="$(zoxide init bash)"
eval "${zoxide_bash_completion}"
unset zoxide_bash_completion
fi
if has gitlint; then
gitlint_bash_completion="$(_GITLINT_COMPLETE=bash_source gitlint)"
eval "${gitlint_bash_completion}"
unset gitlint_bash_completion
fi
source_readable /usr/share/doc/fzf/examples/key-bindings.bash
source_readable /usr/share/doc/fzf/examples/completion.bash
## }}}
## {{{ End
## Source local bash configuration.
source_readable "${HOME}/.bashrc.local"
## }}}