#!/usr/bin/env bash # # ~/.bashrc.br - user specific initialization # # (C) Bruno Raoult ("br"), 2001-2024 # Licensed under the GNU General Public License v3.0 or later. # Some rights reserved. See COPYING. # # You should have received a copy of the GNU General Public License along with this # program. If not, see . # # SPDX-License-Identifier: GPL-3.0-or-later # # Usage: to be invoked from .bashrc. # i.e., add at the end of .bashrc: # [ -f "$HOME/.bashrc.$USER" ] && . "$HOME/.bashrc.$USER" # # Debian default ~/.profile usually does: # 1) source .bashrc if it exists # 2) add "$HOME"/bin in PATH # This imply a duplicate "$HOME/bin" in PATH, as we do everything here. # Better to have a ~/.bash_profile with the lines above. # _var_del() - remove an element from a colon-separated list. # $1: name (reference) of a colon separated list # $2: element to remove (string) # # _var_del() removes every occurrence of $2, if there are more than 1, # and leaves $1 unchanged if $2 is not present. # # Example: # With VAR's value being "foo:bar:quax:bar". Using "_var_del VAR bar" will # leave VAR with the value "foo:quax". _var_del() { local -n _p_del=$1 local _l=":$_p_del:" while [[ $_l =~ :$2: ]]; do _l=${_l//:$2:/:} done _l=${_l%:} _l=${_l#:} _p_del="$_l" } # _var_prepend() - prepend element to colon-separated variable. # $1: variable name (reference) # $2: element to add (string) # # Any occurrence of $2 in $1 is first removed, then $2 is added at $1 beginning. # # Example: # With VAR's value being "foo:bar:quax:bar". Using "_var_prepend VAR bar" # will leave VAR with the value "bar:foo:quax". _var_prepend() { local -n _p_prepend=$1 _var_del _p_prepend "$2" [[ -z $_p_prepend ]] && _p_prepend="$2" && return _p_prepend="$2:$_p_prepend" } # _var_append() - append element to colon-separated variable. # $1: variable name (reference) # $2: element to add (string) # # Any occurrence of $2 in $1 is first removed, then $2 is added at $1 end. # # Example: # With VAR's value being "foo:bar:quax:bar". Using "_var_append VAR bar" # will leave VAR with the value "foo:quax:bar". _var_append() { local -n _p_append=$1 _var_del _p_append "$2" [[ -z $_p_append ]] && _p_append="$2" && return _p_append="$_p_append:$2" } # adjust PATH. Below paths will be added at beginning. _lpath=("$HOME/bin/$(uname -s)-$(uname -m)" # architecture specific "$HOME/bin" # user scripts "$HOME/.local/bin" # pip venv #"$HOME/.cargo/bin" "/usr/local/bin" ) # loop array in reverse order. Note: We do not test for path existence and add it # unconditionally, to avoid automounter interference. for (( _i = ${#_lpath[@]} - 1; _i >= 0; --_i )); do _var_prepend PATH "${_lpath[_i]}" done unset _lpath # why is it in default Ubuntu path ? _var_del PATH /snap/bin # enable core file ulimit -Sc 102400 # in 1024 bytes, 100Mb # Set pager: "less" is prefered over "more". if hash less 2>/dev/null; then export PAGER=less # do not clear screen after "less", exit immediately if one page only export LESS="--quit-if-one-screen --quit-at-eof --no-init" alias more=less else export MORE="--exit-on-eof --silent" export PAGER=more alias less=more fi # no output split for dc and bc / make bc silent export DC_LINE_LENGTH=0 export BC_LINE_LENGTH=0 export BC_ENV_ARGS=--quiet # both ubuntu and debian assume we want colors if TERM contains "color" # this is surely not true, as TERM is often forced by terminal emulator # shellcheck disable=SC2154 PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" ;; *) ;; esac # trim prompt path export PROMPT_DIRTRIM=3 # find a suitable editor e() { $VISUAL "$@" } export -f e if hash emacs 2>/dev/null; then # look for Emacs... # uncomment below to use full emacs #export EDITOR=emacs # ... OR: uncomment below to use emacsclient #export ALTERNATE_EDITOR="/usr/bin/emacs" #export EDITOR="emacs.sh" #alias emacs="emacs.sh" export ALTERNATE_EDITOR="" export VISUAL="emacsclient -c" alias emacs="emacsclient -c" #alias crontab="VISUAL=emacsclient crontab -e" #alias crontab="emacs-crontab.sh" else # ... or clones, vim/vi, etc... _VISUALS=(zile jed mg e3em vim vi nano ed) for e in "${_VISUALS[@]}"; do if hash "$e" 2>/dev/null; then export VISUAL="$e" break fi done unset _VISUALS fi export EDITOR=$VISUAL for _pdfviewer in atril qpdfview; do # look for a pdf viewer if hash "$_pdfviewer" 2>/dev/null; then # shellcheck disable=SC2139 alias acroread="$_pdfviewer" break fi done unset _pdfviewer # append to the history file, don't overwrite it shopt -s histappend # write history after each command export PROMPT_COMMAND="history -a" # Add timestamp in history export HISTTIMEFORMAT="%d/%m %H:%M " # ignore history dups, delete all previous dups export HISTCONTROL="ignorespace:ignoredups:erasedups" # ignore these in history export HISTIGNORE="history *:h:hl:hll:hlll" # history size HISTSIZE=5000 HISTFILESIZE=5000 # remove new stupid Debian "ls" quoting, and colors... # Many complains, one of them: # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226 export QUOTING_STYLE=literal [[ -v BASH_ALIASES[ls] ]] && unalias ls # avoid these stupid systemd defaults (horizontal scroll and pager) alias systemctl="systemctl --no-pager --full" # aliases/functions for usual commands (ls, history, grep...) alias l='ls -F' alias ls='ls -F' alias l1='ls -1F' alias la='ls -AF' alias ll='ls -lF' alias lla='ls -lAF' alias ldl='ls -l | grep ^d' [[ -v BASH_ALIASES[lrt] ]] && unalias lrt lrt() { local -i _l=20 if (( $# > 0 )) && [[ $1 =~ [[:digit:]]+ ]]; then _l="$1" shift fi # shellcheck disable=2012 ls -lrt "${1:-.}" | tail -"$_l" } [[ -v BASH_ALIASES[lart] ]] && unalias lart lart() { local -i _l=20 if (( $# > 0 )) && [[ $1 =~ [[:digit:]]+ ]]; then _l="$1" shift fi # shellcheck disable=2012 ls -laFrt "${1:-.}" | tail -"$_l" } alias h="history 10" # short alias hl="history 25" # long alias hll="history 100" # very long alias hlll="history" # all history alias grep='grep --color=auto' # add colors to grep alias fgrep='fgrep --color=auto' alias egrep='egrep --color=auto' # user temp directory export USERTMP=~/tmp # misc aliases alias fuck='sudo $(history -p \!\!)' alias diff='diff -u' # fdiff() - compare two files with same name # parameters: # $1: first file # $2: second file directory # # fdiff will compare (diff) $1 with a file of basename $1 in $2 directory. # Examples: # % fdiff .bashrc ~ # compare .bashrc with ~/.bashrc # % fdiff /tmp/.bashrc /home/br/ # compare /tmp/.bashrc with /home/br/.bashrc fdiff () { local file1="$1" # file to compare local file2="$2/${file1##*/}" # file2 with path diff "$file1" "$file2" } # I am used to rehash... # rehash - manage bash's remembered commands paths # $1...: Only forget those commands rehash() { if (($#)); then hash -d "$@" else hash -r fi } # french-> english and english->french translation alias trans="trans.sh" alias rtrans="trans.sh -fen -tfr" # easy directory sync (remove source trailing slash) syncdir() { local -a opts=(--archive --hard-links --one-file-system --itemize-changes --delete) local src="$1" dst="$2" case "$src" in *[!/]*/) src=${src%"${src##*[!/]}"};; *[/]) src="/";; esac rsync "${opts[@]}" "$src" "$dst" } # host specific initialization # shellcheck disable=SC1090 [ -f "$HOME/.bashrc.$USER.$(hostname)" ] && . "$HOME/.bashrc.$USER.$(hostname)" # Indent style for emacs # Local Variables: # mode: shell-script # sh-basic-offset: 4 # sh-indentation: 4 # indent-tabs-mode: nil # End: