dotfiles/.bashrc

622 lines
21 KiB
Bash

#!/bin/bash - not strictly necessary, but helps nano with syntax highlighting.
__prompt_git_status() {
# Generate a git branch/status prompt.
# Based on git-prompt.sh by Shawn O. Pearce <spearce@spearce.org>.
# Arguments:
# $1 The printf format string for the prompt. Must include %s.
# Environment variables:
# GIT_PROMPT_SHOW_TYPE=1 Show type of repository (Bare, Shallow).
# GIT_PROMPT_SHOW_UPSTREAM=1 Show status of this repository compaired to upstream:
# ?? - No upstream set.
# == - Working tree is equal to upstream.
# <> - Divergent from upstream.
# >> or >x - Working tree is ahead of upstream (x = commits ahead when used with next option).
# << or <x - Working tree is behind upstream (x = commits behind when used with next option).
# GIT_PROMPT_SHOW_UPSTREAM_EXTENDED=1 In addition to upstream status, show the number of commits difference (inplies above).
# GIT_PROMPT_SHOW_IGNORED=1 Show a ! if the current directory is ignored, or _ if the git operation was timed out.
# GIT_PROMPT_SHOW_UNSTAGED=1 Show a * if there are unstaged changes (superceeded by above).
# GIT_PROMPT_SHOW_UNCOMMITTED=1 Show a & if there are staged but uncommitted changes (superceeded by above).
# GIT_PROMPT_SHOW_UNTRACKED=1 Show a + if there are untracked files in the working directory (superceeded by above).
# GIT_PROMPT_SHOW_STASH=1 Show a $ if there is a stash in this repository (superceeded by above).
# Displays: The printf formatted git prompt based upon $1 and the environment vaiables above, for example:
# S:branch_name >5 *
# Returns: 0 = Produced a prompt successfully.
# 1 = An error occured.
local BRANCH COUNT GIT_PROMPT GIT_PROMPT_MARKER_SET GIT_REPO_INFO IFS=$'\n'
# Bail out if there's no format argument given, or it doesn't contain %s
(( $# != 1 )) || [[ "$1" != *%s* ]] && return 1
# Get some repository information.
# shellcheck disable=SC2207
GIT_REPO_INFO=( $( git rev-parse --is-bare-repository --is-shallow-repository --is-inside-git-dir --is-inside-work-tree 2>/dev/null) ) || return 1
# Generate the prompt.
if [[ "${GIT_REPO_INFO[2]}" == "true" ]]; then
# In the git directory, use a special branch marker.
GIT_PROMPT+="!GIT_DIR!"
elif [[ "${GIT_REPO_INFO[3]}" == "true" ]]; then
# In the working directory, generate the prompt.
# Add type markers.
[[ -n "$GIT_PROMPT_SHOW_TYPE" ]] && {
if [[ "${GIT_REPO_INFO[0]}" == "true" ]]; then
GIT_PROMPT+="B:"
elif [[ "${GIT_REPO_INFO[1]}" == "true" ]]; then
GIT_PROMPT+="S:"
fi
}
# Add the branch or a no commits marker.
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
if [[ "$BRANCH" == "HEAD" ]]; then
GIT_PROMPT+="?NO COMMITS?"
# Output the prompt and escape early.
# shellcheck disable=SC2059
printf -- "$1" "$GIT_PROMPT"
return 0
else
GIT_PROMPT+="$BRANCH"
fi
# Add upstream status.
[[ -n "$GIT_PROMPT_SHOW_UPSTREAM" ]] || [[ -n "$GIT_PROMPT_SHOW_UPSTREAM_EXTENDED" ]] && {
COUNT="$(git rev-list --count --left-right "${BRANCH:+refs/prefetch/remotes/origin/}${BRANCH:-@{upstream\}}...HEAD" 2>/dev/null | tr '[:blank:]' ' ')"
case "$COUNT" in
"")
# No upstream.
GIT_PROMPT+=" ??"
;;
"0 0")
# Equal to upstream.
GIT_PROMPT+=" =="
;;
"0 "*)
# Ahead of upstream.
GIT_PROMPT+=" >"
if [[ -n "$GIT_PROMPT_SHOW_UPSTREAM_EXTENDED" ]]; then
# Show the number of the difference.
GIT_PROMPT+="${COUNT#0 }"
else
GIT_PROMPT+=">"
fi
;;
*" 0")
# Behind upstream.
GIT_PROMPT+=" <"
if [[ -n "$GIT_PROMPT_SHOW_UPSTREAM_EXTENDED" ]]; then
# Show the number of the difference.
GIT_PROMPT+="${COUNT% 0}"
else
GIT_PROMPT+="<"
fi
;;
*)
# Divergent from upstream.
GIT_PROMPT+=" <>"
;;
esac
}
# Add a marker if directory is ignored, there's unstaged files, uncommitted changes, untracked files or a stash.
[[ -n "$GIT_PROMPT_SHOW_IGNORED" ]] && git check-ignore . >/dev/null 2>&1 && {
GIT_PROMPT+=" !"
GIT_PROMPT_MARKER_SET=1
}
[[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_UNSTAGED" ]] && {
timeout --signal=KILL 2s git ls-files --modified --exclude-standard --directory --error-unmatch -- ':/*' >/dev/null 2>&1
ERR=$?
if (( ERR == 124 )) || (( ERR == 137 )); then
GIT_PROMPT+=" _"
GIT_PROMPT_MARKER_SET=1
elif (( ERR == 0 )); then
GIT_PROMPT+=" *"
GIT_PROMPT_MARKER_SET=1
fi
}
[[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_UNCOMMITTED" ]] && ! git diff --name-only --cached --exit-code >/dev/null 2>&1 && {
GIT_PROMPT+=" &"
GIT_PROMPT_MARKER_SET=1
}
[[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_UNTRACKED" ]] && {
timeout --signal=KILL 2s git ls-files git ls-files --others --exclude-standard --directory --error-unmatch -- ':/*' >/dev/null 2>&1
ERR=$?
if (( ERR == 124 )) || (( ERR == 137 )); then
GIT_PROMPT+=" _"
GIT_PROMPT_MARKER_SET=1
elif (( ERR == 0 )); then
GIT_PROMPT+=" +"
GIT_PROMPT_MARKER_SET=1
fi
}
[[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_STASH" ]] && git rev-parse --verify --quiet refs/stash >/dev/null && {
GIT_PROMPT+=" $"
GIT_PROMPT_MARKER_SET=1
}
fi
# Output the prompt.
# shellcheck disable=SC2059
printf -- "$1" "$GIT_PROMPT"
return 0
}
__prompt_user_colour() {
# Determine the colour of the username in the prompt.
if [[ "$LOGNAME" == "root" ]]; then
printf "%s" "1;31m" # Bright Red.
elif [[ "$LOGNAME" == "tadgy" ]]; then
printf "%s" "1;32m" # Bright Green.
else
printf "%s" "1;36m" # Bright Cyan.
fi
return 0
}
__git_prompt_command() {
# Perform git actions.
# Environment variables:
# GIT_DISABLE_PROMPT_PREFETCH=1 Disable automatic 'prefetch' of upstream refs.
# This can also be disabled on a per repository basis using:
# git config ---local -replace-all --type bool script.DisablePromptPrefetch true
# Returns: 0 = Tasks completed successfully.
# 1 = An error occured.
local GIT_REPO_INFO LC_ALL="C" NOW REPO_TIMESTAMP TIMESTAMP_VAR
# shellcheck disable=SC2207
GIT_REPO_INFO=( $( git rev-parse --is-inside-work-tree --show-toplevel 2>/dev/null) ) || return 1
# Only process if in a work directory.
[[ "${GIT_REPO_INFO[0]}" == "true" ]] && {
# Run prefetch tasks if not disabled.
[[ -z "$GIT_DISABLE_PROMPT_PREFETCH" ]] && [[ "$(git config --local --get --type bool script.DisablePromptPrefetch 2>/dev/null)" != "true" ]] && {
git maintenance run --task=prefetch 2>/dev/null || {
printf "\\033[1;31m%s\\033[0m\\n" "Git maintenance 'prefetch' task failed." >&2
return 1
}
}
# The time now.
if [[ "$PLATFORM" == "Linux" ]]; then
NOW="$(date +'%s%3N')"
elif [[ "$PLATFORM" == "Darwin" ]]; then
NOW="$(perl -e 'use Time::HiRes; printf "%.3f", Time::HiRes::time();')"
NOW="${NOW/.}"
fi
# Determine the timestamp variable name depending on bash version.
if (( BASH_VERSINFO[0] >= 4 )); then
TIMESTAMP_VAR="GIT_REPO_TIMESTAMP[${GIT_REPO_INFO[1]//[^[:alnum:]]/_}]"
else
# This is going to pollute the environment, but Darwin is a PITA.
TIMESTAMP_VAR="GIT_REPO_TIMESTAMP_${GIT_REPO_INFO[1]//[^[:alnum:]]/_}"
fi
if [[ -n "${!TIMESTAMP_VAR}" ]]; then
# Monitor the git repo.
REPO_TIMESTAMP="$(git config --local --get --type int script.AutoMergeLast)"
(( ${!TIMESTAMP_VAR:-0} < REPO_TIMESTAMP )) && {
# Display message depending on status.
if [[ "$(git config --local --get --type bool script.AutoMergeSuccess)" == "true" ]]; then
printf "\\033[1;32m%s" "Git auto-merge succeeded for this repo."
if [[ "${GIT_REPO_INFO[1]}" == "$HOME" ]]; then
printf " %s\\033[0m\\n" "Re-source .bash* files."
else
printf "\\033[0m\\n"
fi
# Update the timestamp in the environment.
declare -g "$TIMESTAMP_VAR"="$NOW"
else
printf "\\033[1;31m%s\\033[0m\\n" "Git auto-merge failed for this repo - correct manually." >&2
fi
}
else
# Just set the timestamp in the environment.
declare -g "$TIMESTAMP_VAR"="$NOW"
fi
}
return 0
}
__nanorc_prompt_command() {
# Dynamically handle .nanorc file versions.
hash nano >/dev/null 2>&1 && {
# shellcheck disable=SC2155
local NANO_VER="$(command nano --version | awk '/version/ { print $4 }' | cut -d. -f1)"
# Darwin specifc .nanorc version.
[[ "$PLATFORM" == "Darwin" ]] && NANO_VER="darwin"
if [[ -f "$HOME/.nanorc-$NANO_VER" ]]; then
if (( NANO_VER <= 4 )); then
( cd "$HOME" && ln -sf ".nanorc-$NANO_VER" ".nanorc" )
else
# shellcheck disable=SC2139
alias nano="nano -f \"$HOME/.nanorc-$NANO_VER\""
fi
else
if (( NANO_VER <= 4 )); then
[[ -L "$HOME/.nanorc" ]] && rm -f "$HOME/.nanorc"
else
unalias nano 2>/dev/null
fi
printf "\\033[1;31m%s\\033[0m\\n" "No .nanorc for version '$NANO_VER'." >&2
fi
}
return 0
}
__ssh_agent_prompt_command() {
# If necessary, find and activate a new ssh agent socket before each prompt is displayed.
# Returns: 0 = All is good.
# 1 = An error occured.
local ERR
if [[ -z "$SSH_AUTH_SOCK" ]]; then
ERR=2
else
ssh-add -l >/dev/null 2>&1
ERR=$?
fi
(( ERR == 2 )) && {
# Read alternative sockets from ~/.ssh/agents.
__read_ssh_agents || {
unset SSH_AUTH_SOCK
return 1
}
# Find a new socket to use.
if __find_ssh_agent_sock; then
printf "\\033[1;33m%s\\033[0m\\n" "Connected to existing ssh-agent socket."
sleep 0.5
else
# Start a new agent.
eval "$(ssh-agent -s 2>/dev/null | grep -v 'echo'; printf "%s" "ERR=${PIPESTATUS[0]}")"
(( ERR > 0 )) && {
printf "\\033[1;31m%s\\033[0m\\n" "Failed to start new ssh-agent - continuing with no agent."
sleep 0.5
return 1
}
printf "\\033[1;32m%s\\033[0m\\n" "Started new ssh-agent."
__write_ssh_agents
sleep 0.5
fi
}
return 0
}
__find_ssh_agent_sock() {
# Find an *active* ssh agent socket.
# Returns: 0 = Found an active socket.
# 1 = Did not find a viable socket.
local I
# Search the SSH_AUTH_SOCKS array for a viable socket.
for ((I = 0; I < ${#SSH_AUTH_SOCKS[@]}; I++)); do
[[ "${SSH_AUTH_SOCKS[$I]}" =~ ^[[:blank:]]*$ ]] && continue
SSH_AUTH_SOCK="${SSH_AUTH_SOCKS[$I]}" ssh-add -l >/dev/null 2>&1
(( $? <= 1 )) && {
export SSH_AUTH_SOCK="${SSH_AUTH_SOCKS[$I]}"
return 0
}
unset SSH_AUTH_SOCK
done
return 1
}
__read_ssh_agents() {
# Read all the known ssh agent sockets into an array.
# Returns: 0 = Processed and read the agents file without issue.
# 1 = Error processing/reading the agents file.
local ERR I SOCK
[[ ! -e "$HOME/.ssh/agents" ]] && touch "$HOME/.ssh/agents"
# Lock the ~/.ssh/agents file.
if [[ "$PLATFORM" == "Linux" ]]; then
# Linux has 'flock', thankfully.
exec 9<"$HOME/.ssh/agents" && flock -E 10 -e -w 0.5 9
ERR=$?
if (( ERR == 10 )); then
printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2
return 1
elif (( ERR > 0 )); then
printf "\\033[1;31m%s\\033[0m\\n" "Flock usage error." >&2
return 1
fi
# Make note of the mtime for use in write_ssh_agents.
SSH_AGENTS_MTIME="$(stat --format=%.9Y "$HOME/.ssh/agents")"
elif [[ "$PLATFORM" == "Darwin" ]]; then
# Do locking the sucky way on macOS.
for ((I = 0; I <= 5; I++)); do
if shlock -p "$$" -f "$HOME/.ssh/agents.lock"; then
exec 9<"$HOME/.ssh/agents"
# Make note of the mtime for use in write_ssh_agents.
SSH_AGENTS_MTIME="$(stat -f %Fm "$HOME/.ssh/agents")"
ERR=0
break
else
ERR=1
sleep 0.1
fi
done
(( ERR != 0 )) && {
printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2
return 1
}
else
printf "\\033[1;31m%s\\033[0m\\n" "File locking unsupported on '$PLATFORM'." >&2
return 1
fi
# Read the socket list (bash v2+ compliant)
while read -u 9 -r SOCK; do
[[ -n "$SOCK" ]] && SSH_AUTH_SOCKS+=("$SOCK")
done
ERR=$?
# Close the file descriptor (which on Linux releases the flock too).
exec 9<&-
# On Darwin, release the lock on the file.
rm -f "$HOME/.ssh/agents.lock"
# Remove the . in the mtime.
SSH_AGENTS_MTIME="${SSH_AGENTS_MTIME/\.}"
# Error out if the data couldn't be read.
(( ERR != 0 )) && {
printf "\\033[1;31m%s\\033[0m\\n" "Failed to read ssh-agent socket list." >&2
unset SSH_AUTH_SOCKS SSH_AGENTS_MTIME
return 1
}
return 0
}
__write_ssh_agents() {
# Write all unique ssh agent sockets into the ~/.ssh/agents file.
# Returns: 0 = Processed and wrote the agents file without issue.
# 1 = Error processing/writing the agents file.
# 2 = The SSH_AUTH_SOCKS array may be out of date as the agents file'a mtime has changed.
local ERR I J MTIME SOCKS
# Add the current agent socket to the sockets array.
SSH_AUTH_SOCKS=("$SSH_AUTH_SOCK" "${SSH_AUTH_SOCKS[@]}")
# Remove any duplicates from SSH_AUTH_SOCKS.
for ((I = 0; I < ${#SSH_AUTH_SOCKS[@]}; I++)); do
[[ -z "${SSH_AUTH_SOCKS[$I]}" ]] && continue
for ((J = 0; J < ${#SOCKS[@]}; J++)); do
[[ "${SSH_AUTH_SOCKS[$I]}" == "${SOCKS[$J]}" ]] && continue 2
done
# Only add the socket if it's still viable.
SSH_AUTH_SOCK="${SSH_AUTH_SOCKS[$I]}" ssh-add -l >/dev/null 2>&1
(( $? <= 1 )) && SOCKS+=("${SSH_AUTH_SOCKS[$I]}")
done
# Lock the ~/.ssh/agents file.
if [[ "$PLATFORM" == "Linux" ]]; then
# Make sure SSH_AUTH_SOCKS has the most up to date data.
MTIME="$(stat --format=%.9Y "$HOME/.ssh/agents")"
(( ${MTIME/\.} > SSH_AGENTS_MTIME )) && return 2
# Lock the agents file.
exec 9<"$HOME/.ssh/agents" && flock -E 10 -e -w 0.5 9
ERR=$?
if (( ERR == 10 )); then
printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2
return 1
elif (( ERR > 0 )); then
printf "\\033[1;31m%s\\033[0m\\n" "Flock usage error." >&2
return 1
fi
elif [[ "$(uname -s)" == "Darwin" ]]; then
# Make sure SSH_AUTH_SOCKS has the most up to date data.
MTIME="$(stat -f %Fm "$HOME/.ssh/agents")"
(( ${MTIME/\.} > SSH_AGENTS_MTIME )) && return 2
# Do locking the sucky way on OSX.
for ((I = 0; I <= 5; I++)); do
if shlock -p "$$" -f "$HOME/.ssh/agents.lock"; then
exec 9<"$HOME/.ssh/agents"
ERR=0
break
else
ERR=1
sleep 0.1
fi
done
(( ERR != 0 )) && {
printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2
return 1
}
else
printf "\\033[1;31m%s\\033[0m\\n" "File locking unsupported on '$PLATFORM'." >&2
return 1
fi
# Write the cleaned array to disk.
ERR=-1
[[ -n "${SOCKS[*]}" ]] && { printf "%s\\n" "${SOCKS[@]}" >"$HOME/.ssh/agents" 2>/dev/null; ERR=$?; }
# Release locks.
exec 9<&-
rm -f "$HOME/.ssh/agents.lock"
# Error out if the data couldn't be written.
if (( ERR == -1 )); then
rm -f "$HOME/.ssh/agents" 2>/dev/null
elif (( ERR >= 1 )); then
rm -f "$HOME/.ssh/agents" 2>/dev/null
printf "\\033[1;31m%s\\033[0m\\n" "Failed to write ssh-agent socket list." >&2
return 1
fi
return 0
}
imagebin() {
# Throw an image file into an imagebin.
[[ -z "$1" ]] || [[ ! -e "$1" ]] && {
printf "%s: %s\\n" "Usage" "${FUNCNAME[0]} <filename>" >&2
return 1
}
curl -F file="@$1" https://imagebin.ca/upload.php | grep '^url:' | cut -d: -f2-
}
# Determine the platform being logged into.
PLATFORM="$(uname -s)"
# Make bash a little more pleasent - these are valid for all versions.
shopt -s cdspell checkhash checkwinsize cmdhist histappend no_empty_cmd_completion
# Exit the shell on a Ctl+D.
IGNOREEOF=0
# History control.
HISTCONTROL="ignoredups"
HISTFILE="$HOME/.bash_history-${HOSTNAME%%.*}"
HISTFILESIZE=1000000
HISTIGNORE="bg:bg *:fg:fg *:jobs:exit:clear:history"
HISTSIZE=1000000
HISTTIMEFORMAT="%d/%m/%y %H:%M:%S "
history -a
history -r
# The commands to execute before the prompt is displayed.
PROMPT_COMMAND="__nanorc_prompt_command; __ssh_agent_prompt_command; __git_prompt_command"
# Git prompt options.
GIT_PROMPT_SHOW_TYPE=1
GIT_PROMPT_SHOW_UPSTREAM=1
GIT_PROMPT_SHOW_UPSTREAM_EXTENDED=1
GIT_PROMPT_SHOW_IGNORED=1
GIT_PROMPT_SHOW_UNSTAGED=1
GIT_PROMPT_SHOW_UNCOMMITTED=1
GIT_PROMPT_SHOW_UNTRACKED=1
GIT_PROMPT_SHOW_STASH=1
# Version specific set up.
if (( BASH_VERSINFO[0] >= 4 )); then
# Add to the shopts.
shopt -s checkjobs dirspell
# Trim the path in the prompt.
PROMPT_DIRTRIM=2
# Coloured username + host + directory:
PS1='[\[\033[$(__prompt_user_colour)\]\u\[\033[0m\]@\[\033[1;33m\]\h\[\033[0m\]] \[\033[1;34m\]\w\[\033[0m\]$(__prompt_git_status "\[\\033[1;35m\] (%s)\[\\033[0m\]") ->'
else
# Set the prompts.
# Coloured username + host + directory:
# shellcheck disable=SC2154
PS1='[\[\033[$(__prompt_user_colour)\]\u\[\033[0m\]@\[\033[1;33m\]\h\[\033[0m\]] \[\033[1;34m\]$(printf "%s" "${PWD/#$HOME/~}" | awk -F/ '\''{if (NF>3) {printf ".../" $(NF-1) "/" $NF} else {printf $0}}'\'')\[\033[0m\]$(__prompt_git_status "\[\\033[1;35m\] (%s)\[\\033[0m\]") ->'
fi
# Set the debugger prompt.
# shellcheck disable=SC2155
export PS4='+(\[\033[1;33m\]$?\[\033[0m\]) \[\033[1;34m\]${BASH_SOURCE##*/}\[\033[0m\]${FUNCNAME[0]:+(\[\033[1;32m\]${FUNCNAME[0]}\[\033[0m\])}:\[\033[1;31m\]$LINENO\[\033[0m\]: '
# Common aliases.
hash bc >/dev/null 2>&1 && alias bc='bc -lq'
hash grep >/dev/null 2>&1 && {
alias egrep='grep -E --color=auto'
alias fgrep='grep -F --color=auto'
alias grep='grep --color=auto'
}
# Auto start the ssh agent and add keys for scp/sftp/ssh.
__ssh_agent_prompt_command
hash scp ssh ssh-add >/dev/null 2>&1 && alias scp='_EXEC=scp ssh'
hash sftp ssh ssh-add >/dev/null 2>&1 && alias sftp='_EXEC=sftp ssh'
hash ssh ssh-add >/dev/null 2>&1 && ssh() {
local ERR
if [[ -z "$SSH_AUTH_SOCK" ]]; then
ERR=2
else
ssh-add -l >/dev/null 2>&1
ERR=$?
fi
if (( ERR == 1 )); then
ssh-add
elif (( ERR == 2 )); then
__ssh_agent_prompt_command
ssh-add
fi
command "${_EXEC:-${FUNCNAME[0]}}" "$@"
}
# Handle the ~/.gitconfig link.
if [[ -e "$HOME/.gitconfig-$USER@$HOSTNAME" ]]; then
FILENAME=".gitconfig-$USER@$HOSTNAME"
elif [[ -e "$HOME/.gitconfig-$USER@*.${HOSTNAME#*.}" ]]; then
FILENAME=".gitconfig-$USER@*.${HOSTNAME#*.}"
elif [[ -e "$HOME/.gitconfig-$USER@*" ]]; then
FILENAME=".gitconfig-$USER@*"
elif [[ -e "$HOME/.gitconfig-*@$HOSTNAME" ]]; then
FILENAME=".gitconfig-*@$HOSTNAME"
elif [[ -e "$HOME/.gitconfig-*.${HOSTNAME#*.}" ]]; then
FILENAME=".gitconfig-*.${HOSTNAME#*.}"
elif [[ -e "$HOME/.gitconfig-default" ]]; then
FILENAME=".gitconfig-default"
else
(cd "$HOME" && [[ -L ".gitconfig" ]] && rm -f ".gitconfig")
printf "%s: %s\\n" "${BASH_SOURCE##*/}" "failed to update .gitconfig symlink" >&2
fi
[[ -n "$FILENAME" ]] && (cd "$HOME" && ln -sf "$FILENAME" ".gitconfig")
unset FILENAME
# Platform specific set up.
if [[ "$PLATFORM" = "Linux" ]]; then
# Linux specific functions.
hash ps grep >/dev/null 2>&1 && psgrep() {
if [[ -n "$1" ]]; then
# shellcheck disable=SC2009
ps -auwwx | grep -E --color=always -- "(.*RSS.*|$1)" | grep -F -v '(.*RSS.*|'
else
printf "%s: %s\\n" "Usage" "${FUNCNAME[0]} <something>" >&2
return 1
fi
}
# Linux specific aliases.
hash diff >/dev/null 2>&1 && alias diff='diff --color=auto -u'
hash ftpwho >/dev/null 2>&1 && alias ftpwho='ftpwho -v'
hash gpg2 >/dev/null 2>&1 && alias gpg='command gpg2' && alias gpg2='gpg2 --pinentry-mode=loopback'
hash iftop >/dev/null 2>&1 && alias iftop='TERM=vt100 iftop'
hash iotop >/dev/null 2>&1 && alias iotop='TERM=linux iotop'
hash ip >/dev/null 2>&1 && alias ip='ip -color=auto'
hash last less >/dev/null 2>&1 && alias laston='last -a | less'
hash ls >/dev/null 2>&1 && alias ls='ls -bFv --color=auto'
hash minicom >/dev/null 2>&1 && alias minicom='minicom -m -c on'
hash mkpasswd >/dev/null 2>&1 && alias mkpasswd='mkpasswd -m sha512crypt'
hash mkpasswd >/dev/null 2>&1 && alias pwgen='mkpasswd -m sha512crypt'
hash nc >/dev/null 2>&1 && alias pastebin='nc termbin.com 9999'
hash pinfo >/dev/null 2>&1 && alias info='pinfo'
hash ping >/dev/null 2>&1 && alias ping='ping -b'
elif [[ "$PLATFORM" = "Darwin" ]]; then
# Darwin specific aliases (some dependant on macports)
[[ ! -e "/opt/local/libexec/gnubin/df" ]] && alias df='df -kP'
# shellcheck disable=SC2015
[[ ! -e "/opt/local/libexec/gnubin//diff" ]] && alias diff='diff -u' || alias diff='diff --color=auto -u'
hash last less >/dev/null 2>&1 && alias laston='last | less'
# shellcheck disable=SC2015
[[ ! -e "/opt/local/libexec/gnubin/ls" ]] && alias ls='ls -bFGO' || alias ls='ls -bFv --color=auto'
[[ -e "/opt/local/libexec/gnubin/nc" ]] && alias pastebin='nc termbin.com 9999'
[[ -e "/opt/local/bin/pinfo" ]] && alias info='pinfo'
hash top >/dev/null 2>&1 && alias top='top -o cpu -S'
else
printf "%s: %s\\n" "${BASH_SOURCE##*/}" "unsupported platform: $PLATFORM" >&2
fi