Skip to content

Instantly share code, notes, and snippets.

@NickCrew
Created January 16, 2025 18:50
Show Gist options
  • Save NickCrew/2aab62f046bc27721ada9a9b1f3724aa to your computer and use it in GitHub Desktop.
Save NickCrew/2aab62f046bc27721ada9a9b1f3724aa to your computer and use it in GitHub Desktop.
Minimal Bashrc - Sane defaults to carry from host to host
#
# A minimal bash configuration to carry around with you
#
# !! Plus some bonus extras like fancy git prompt and bookmarks
#
#
set -o vi # unless you're one of *those*
# Globlin
shopt -s globstar # use **/foo to match any depth
shopt -s extglob # Enables *.@(TMP|tmp|~) and similar constructs
shopt -s failglob # don't substitute if there are no matches
# Exports
export PAGER='less'
export TERM=xterm-colors # Fix backspace and other weird behaviors
export LESS_TERMCAP_mb=$'\e[1;32m' # Make less use colors
export LESS_TERMCAP_md=$'\e[1;32m'
export LESS_TERMCAP_me=$'\e[0m'
export LESS_TERMCAP_se=$'\e[0m'
export LESS_TERMCAP_so=$'\e[01;33m'
export LESS_TERMCAP_ue=$'\e[0m'
export LESS_TERMCAP_us=$'\e[1;4;31m'
# History
HISTCONTROL=ignoreboth # ignore space and duplicates
HISTIGNORE='ls:bg:fg:history'
HISTTIMEFORMAT='%F %T ' # record timestamps
shopt -s histappend
shopt -s cmdhist
shopt -s histverify # Using ! history will substitute first, then execute if you hit enter a second time
# Completion
bind 'TAB:menu-complete';
bind '"\e[Z" : menu-complete-backward';
bind "set show-all-if-ambiguous on";
bind "set menu-complete-display-prefix on";
bind "set completion-ignore-case on";
bind '"\e[A":history-search-backward';
bind '"\e[B":history-search-forward';
# Aliases
if [ -x /usr/bin/dircolors ]; # Enable color support of ls and also add handy aliase0s
then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto --classify --human-readable'
alias dir='dir --color=auto'
alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
alias la='ls -a'
alias ll='ls -l'
alias la='ls -alh'
alias less="less -r"
#########
# EXTRAS
#########
#
# Git prompt
#
USE_GIT_PROMPT=1
export USE_GIT_PROMPT
git_prompt_toggle() {
if [[ $USE_GIT_PROMPT == 1 ]]; then
USE_GIT_PROMPT=0
else
USE_GIT_PROMPT=1
fi
export USE_GIT_PROMPT
}
_show_git_status() {
# Get the current git branch and colorize to indicate branch state
# branch_name+ indicates there are stash(es)
# branch_name? indicates there are untracked files
# branch_name! indicates your branches have diverged
local unknown untracked stash clean ahead behind staged dirty diverged
unknown='0;34' # blue
untracked='0;32' # green
stash='0;32' # green
clean='0;32' # green
ahead='0;33' # yellow
behind='0;33' # yellow
staged='0;96' # cyan
dirty='0;31' # red
diverged='0;31' # red
if [[ $TERM = *256color ]]; then
unknown='38;5;20' # dark blue
untracked='38;5;76' # mid lime-green
stash='38;5;76' # mid lime-green
clean='38;5;82' # brighter green
ahead='38;5;226' # bright yellow
behind='38;5;142' # darker yellow-orange
staged='38;5;214' # orangey yellow
dirty='38;5;202' # orange
diverged='38;5;196' # red
fi
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ -n "$branch" ]]; then
if [[ "$branch" == 'HEAD' ]]; then
branch=$(git rev-parse --short HEAD 2>/dev/null)
fi
git_status=$(git status 2> /dev/null)
# If nothing changes the color, we can spot unhandled cases.
color=$unknown
if [[ $git_status =~ 'Untracked files' ]]; then
color=$untracked
branch="${branch}?"
fi
if git stash show &>/dev/null; then
color=$stash
branch="${branch}+"
fi
if [[ $git_status =~ working.*clean ]]; then
color=$clean
fi
if [[ $git_status =~ 'Your branch is ahead' ]]; then
color=$ahead
branch="${branch}>"
fi
if [[ $git_status =~ 'Your branch is behind' ]]; then
color=$behind
branch="${branch}<"
fi
if [[ $git_status =~ 'Changes to be committed' ]]; then
color=$staged
fi
if [[ $git_status =~ 'Changed but not updated' ||
$git_status =~ 'Changes not staged' ||
$git_status =~ 'Unmerged paths' ]]; then
color=$dirty
fi
if [[ $git_status =~ 'Your branch'.+diverged ]]; then
color=$diverged
branch="${branch}!"
fi
# Print the colored branch name + indicators
printf "\[\033[%sm\]%s" "$color" "$branch"
# Reset the color
printf "\[\033[0m\]"
fi
return 0
}
_show_last_exit_status() {
# Display the exit status of the last run command
exit_status=$?
if [[ "$exit_status" -ne 0 ]]; then
echo "Exit $exit_status"
fi
}
_build_prompt() {
local git_status prompt_dir
if [[ $USE_GIT_PROMPT != 0 ]]; then
git_status=$(_show_git_status)
if [[ -n "$git_status" ]]; then
git_status=":${git_status}"
fi
fi
prompt_dir=$(basename "${PWD}")
color=32
if [[ $EUID -eq 0 ]]; then
color=31
fi
PS1="\[\e[1;${color}m\]\h\[\e[0m\] [${prompt_dir}${git_status}]\\\$ "
return 0
}
PROMPT_COMMAND="_show_last_exit_status; _build_prompt; history -a;"
#
# Bookmarks
#
export MARKS=$HOME/files/marks
jump() {
if [[ -n "$1" ]]; then
cd -P "$MARKS/$1" 2>/dev/null
if [[ $? -ne 0 ]]; then
printf "Mark not found: %s\n" "$1" 1>&2
return 2
fi
else
printf "Usage: jump MARK\n" 1>&2
return 1
fi
}
mark() {
mark="$1"
if [[ -z "$mark" ]]; then
mark="${PWD##*/}"
read -r -p "Create mark for $mark? (Y/n) " ans
if [[ "$ans" == [Nn] ]]; then
printf "Mark creation aborted: %s\n" "$mark" 1>&2
return 3
fi
fi
if [[ -z "$MARKS" ]]; then
printf "\$MARKS environment variable not set\n" 1>&2
return 1
fi
if [[ ! -d "$MARKS" ]]; then
mkdir -p "$MARKS"
fi
if [[ ! -e "$MARKS/$mark" ]]; then
ln -s "$PWD" "$MARKS/$mark"
else
printf "Mark already exists: %s\n" "$mark" 1>&2
return 2
fi
}
unmark() {
if [[ -z "$1" || -z "$MARKS" ]]; then
printf "Usage: unmark MARK\n" 1>&2
return 1
fi
if [[ -e "$MARKS/$1" ]]; then
rm -f "$MARKS/$1"
else
printf "Mark does not exist: %s\n" "$1" 1>&2
return 2
fi
}
marks() {
find "$MARKS" -maxdepth 1 -type l -printf "%f -> %l\n" | column -t
}
_marks_complete() {
local word=${COMP_WORDS[COMP_CWORD]}
local list=$(find "$MARKS" -maxdepth 1 -type l -printf "%f\n")
COMPREPLY=($(compgen -W '${list[@]}' -- "$word"))
return 0
}
complete -F _marks_complete jump
complete -F _marks_complete unmark
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment