Last active
June 28, 2021 18:10
-
-
Save rbf/1844923 to your computer and use it in GitHub Desktop.
Enhanced Terminal Prompt for Mac OS X (keywords: bash, shell)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Repeat a command N times | |
# From: http://www.stefanoforenza.com/how-to-repeat-a-shell-command-n-times/ | |
repeat() { | |
n=$1 | |
shift | |
while [ $(( n -= 1 )) -ge 0 ] | |
do | |
"$@" | |
done | |
} | |
# Goes to N directories upwards. | |
# ${1-1} means the first argument or the default value "1" if it is not set. | |
# ${parameter-default} as from: http://tldp.org/LDP/abs/html/parameter-substitution.html | |
up() { | |
repeat ${1-1} cd .. | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# System-wide .profile for sh(1) | |
# To be placed in /etc/profile or ~/.bash_profile | |
if [ -x /usr/libexec/path_helper ]; then | |
eval `/usr/libexec/path_helper -s` | |
fi | |
# include .bashrc if it exists | |
if [ -f ~/.bashrc ]; then | |
source ~/.bashrc | |
fi | |
# include .bash_aliases if it exists | |
if [ -f ~/.bash_aliases ]; then | |
source ~/.bash_aliases | |
fi | |
alias reload='source ~/.bash_profile' | |
alias reload_prompt='source ~/.bashrc' | |
alias dev="cd ~/Dropbox/dev" | |
alias la='ls -la' | |
alias tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'" | |
alias showall='defaults write com.apple.Finder AppleShowAllFiles true' | |
alias showallnot='defaults write com.apple.Finder AppleShowAllFiles false' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# System-wide .bashrc file for interactive bash(1) shells. | |
############################################################################### | |
# Custom commands and aliases | |
############################################################################### | |
# Repeat a command N times | |
# From: http://www.stefanoforenza.com/how-to-repeat-a-shell-command-n-times/ | |
repeat() { | |
n=$1 | |
shift | |
while [ $(( n -= 1 )) -ge 0 ] | |
do | |
"$@" | |
done | |
} | |
# Create N number of files with given ext in the current dir | |
# Used without params, it creates 1 file of the form tmp-XXXX.txt | |
tmpfiles() { | |
n="${1:-1}" | |
extention="${2:-txt}" | |
extention="${extention#.}" | |
while [ $(( n -= 1 )) -ge 0 ] | |
do | |
f=$(mktemp "tmp-XXXX") | |
mv "${f}" "${f}.${extention}" | |
done | |
} | |
# Goes to N directories upwards. | |
# ${1-1} means the first argument or the default value "1" if it is not set. | |
# ${parameter-default} as from: http://tldp.org/LDP/abs/html/parameter-substitution.html | |
up() { | |
repeat ${1-1} cd .. | |
} | |
# Goes to the previous directory | |
back() { | |
cd "${OLDPWD}" | |
} | |
# Goes to the home directory | |
home() { | |
cd ~ | |
} | |
# Change directory creating it if it doesn't exists. | |
cdf() { | |
if [ ! -d $1 ]; then | |
mkdir -p $1; | |
fi | |
cd $1; | |
} | |
datestamp() { | |
echo $(date +"%Y%m%d") | |
} | |
timestamp() { | |
echo $(date +"%Y%m%d%H%M%S") | |
} | |
# cdf into a folder with current date | |
today() { | |
if [[ "$(basename $(pwd))" =~ 20[1-9][0-9][0-1][0-9][0-3][0-9] ]]; then | |
echo "Already in a datestamped folder: $(pwd)" | |
echo "Nothing to do." | |
else | |
cdf "$(datestamp)" | |
fi | |
} | |
# Generate uuid using Python | |
uuid() { | |
repeat ${1-1} python -c "import uuid; print uuid.uuid4();" | |
} | |
# Duplicate a file adding the extention .bak_[timestamp] | |
backup() { | |
if [ -z "${1}" ] | |
then | |
echo "Missing file to backup. Nothing to do." | |
return 1 | |
fi | |
BACKUP_FILENAME="${1}.bak_$(date +"%Y%m%d%H%M%S")"; | |
cp "${1}" "${BACKUP_FILENAME}" && echo "Backup created: ${BACKUP_FILENAME}"; | |
} | |
create_subl_project_file() { | |
filename="$(basename $(pwd)).sublime-project" | |
[ -f "${filename}" ] && backup "${filename}" | |
cat << EOF > "${filename}" | |
{ | |
"folders": | |
[ | |
{ | |
"path": ".", | |
"folder_exclude_patterns": ["tmp", "bin", "log"], | |
} | |
] | |
} | |
EOF | |
echo "${filename}" | |
} | |
stt() { | |
filename="$(ls -1 *.sublime-project 2>/dev/null | head -1)" | |
if [ -z "${filename}" ];then | |
echo "Creating a default '.sublime-project' file for this folder..." | |
filename="$(create_subl_project_file)" | |
fi | |
echo "Opening project ${filename} with SublimeText 3..." | |
subl --project "${filename}" | |
} | |
# List files (containing $2 in the name) containing a string ($1) begining from the current dir | |
# "${@:3}" Stands for all parameters from the third (included) on. (From: http://wiki.bash-hackers.org/scripting/posparams#mass_usage) | |
hgrep() { | |
if [ $# -gt 0 ]; then | |
egrep "$1" -i -n -r . --colour --include "*$2*" "${@:3}" | |
fi | |
} | |
# lsnc List Network Connections | |
lsnc(){ | |
lsof -i -n -c 16| awk '{print $1 "\t\t" $9 " " $10}' | uniq | grep -v COMMAND | egrep -v "\->127.0.0.1:.*" | |
} | |
# Primarily used for the prompt function. | |
truncate_string() { | |
local string="${1}" | |
local maxlen=${2:-25} | |
local trunc_symbol=${3:-"…"} | |
if [ "${#string}" -gt "${maxlen}" ]; then | |
string="${string:0:$maxlen}${trunc_symbol}" | |
fi | |
echo "${string}" | |
} | |
alias la='ls -laGFTB' | |
# To make it equivalent to CentOS machines and others deployed with SlipStream | |
alias ll='ls -lG' | |
alias tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'" | |
alias showall='defaults write com.apple.Finder AppleShowAllFiles true' | |
alias showallnot='defaults write com.apple.Finder AppleShowAllFiles false' | |
# Include user custom aliases if defined | |
if [ -f ~/.bash_aliases ]; then | |
source ~/.bash_aliases | |
fi | |
alias reload_aliases='source ~/.bash_aliases' | |
alias reload_bashrc='source /etc/bashrc' | |
############################################################################### | |
# Enhanced Terminal Prompt | |
# Mac OS X 10.6 Version (Snow Leopard) | |
# Original from: http://phil.cryer.us/code/dotfiles/bashrc | |
############################################################################### | |
# Example: | |
# 14:42:52 username@hostname ~/somedirectory$ | |
# In directories with a git repository, it will display the current branch in: | |
# - green: for a clean branch (HEAD and index clean) | |
# - orange: if the HEAD is clean but there are files to commit in the index | |
# - red: if there are modified files in the HEAD | |
# Original from: http://vvv.tobiassjosten.net/bash/dynamic-prompt-with-git-and-ansi-colors | |
# Example: | |
# 14:42:52 username@hostname ~/somedirectory [master]$ | |
# To be placed in /etc/bashrc or ~/.bashrc | |
################################################## | |
# Fancy PWD display function | |
################################################## | |
# The home directory (HOME) is replaced with a ~ | |
# The last pwdmaxlen characters of the PWD are displayed | |
# Leading partial directory names are striped off | |
# /home/me/stuff -> ~/stuff if USER=me | |
# /usr/share/big_dir_name -> ../share/big_dir_name if pwdmaxlen=20 | |
################################################## | |
bash_prompt_command() { | |
local OLD_PWD="${NEW_PWD}" | |
# How many characters of the $PWD should be kept | |
local pwdmaxlen=24 | |
# Indicate that there has been dir truncation | |
local trunc_symbol=".." | |
local dir=${PWD##*/} | |
pwdmaxlen=$(( ( pwdmaxlen < ${#dir} ) ? ${#dir} : pwdmaxlen )) | |
NEW_PWD=${PWD/$HOME/\~} | |
local pwdoffset=$(( ${#NEW_PWD} - pwdmaxlen )) | |
if [ ${pwdoffset} -gt "0" ] | |
then | |
NEW_PWD=${NEW_PWD:$pwdoffset:$pwdmaxlen} | |
NEW_PWD=${trunc_symbol}/${NEW_PWD#*/} | |
fi | |
# Check if we changed dir since last time | |
local IS_NEW_PWD=false | |
if [ "${NEW_PWD}" != "${OLD_PWD}" ]; then | |
local IS_NEW_PWD=true | |
fi | |
# Setup variable for current git branch, if available | |
if ! git rev-parse --git-dir > /dev/null 2>&1; then | |
GIT_CURRENT_BRANCH="" | |
GIT_CURRENT_BRANCH_STATE_COLOR="" | |
GIT_CURRENT_BRANCH_UNTRACKED_FILES="" | |
else | |
if ! git diff --quiet 2>/dev/null >&2; then | |
GIT_CURRENT_BRANCH_STATE_COLOR='\[\033[0;31m\]' #git dirty HEAD | |
else | |
if ! git diff --cached --quiet 2>/dev/null >&2; then | |
GIT_CURRENT_BRANCH_STATE_COLOR='\[\033[0;33m\]' #git dirty index | |
else | |
GIT_CURRENT_BRANCH_STATE_COLOR='\[\033[0;32m\]' #git clean branch | |
fi | |
fi | |
if git ls-files --others --exclude-standard --error-unmatch "./$(git rev-parse --show-cdup 2>/dev/null)" 2>/dev/null >&2; then | |
GIT_CURRENT_BRANCH_UNTRACKED_FILES='+??' #git untracked files | |
else | |
GIT_CURRENT_BRANCH_UNTRACKED_FILES='' #git no untracked files | |
fi | |
GIT_CURRENT_BRANCH="$(git branch 2>/dev/null| sed -n '/^\*/s/^\* //p')${GIT_CURRENT_BRANCH_UNTRACKED_FILES}" | |
GIT_CURRENT_BRANCH=" [$(truncate_string "${GIT_CURRENT_BRANCH}" 15)]" | |
fi | |
bash_prompt # call again this function to update PS1 to use corresponding GIT_CURRENT_BRANCH_STATE_COLOR | |
if $IS_NEW_PWD && [ -n "${GIT_CURRENT_BRANCH}" ]; then | |
( [ -n "$(git remote)" ] && ping -t 1 -c 1 github.com 1>/dev/null && git fetch & ) # Silent and async | |
# [ -n "$(git remote)" ] && ping -t 1 -c 1 github.com 1>/dev/null && git fetch # Silent and sync | |
git status -sb | |
fi | |
} | |
bash_prompt() { | |
local NONE='\[\033[0m\]' # unsets color to term's fg color | |
# NB: Unused Colors disabled | |
# regular colors | |
# local K='\[\033[0;30m\]' # black | |
local R='\[\033[0;31m\]' # red | |
# local G='\[\033[0;32m\]' # green | |
# local Y='\[\033[0;33m\]' # yellow | |
local B='\[\033[0;34m\]' # blue | |
# local M='\[\033[0;35m\]' # magenta | |
# local C='\[\033[0;36m\]' # cyan | |
# local W='\[\033[0;37m\]' # white | |
# empahsized (bolded) colors | |
# local EMK='\[\033[1;30m\]' | |
# local EMR='\[\033[1;31m\]' | |
# local EMG='\[\033[1;32m\]' | |
# local EMY='\[\033[1;33m\]' | |
# local EMB='\[\033[1;34m\]' | |
# local EMM='\[\033[1;35m\]' | |
# local EMC='\[\033[1;36m\]' | |
# local EMW='\[\033[1;37m\]' | |
# background colors | |
# local BGK='\[\033[40m\]' | |
# local BGR='\[\033[41m\]' | |
# local BGG='\[\033[42m\]' | |
# local BGY='\[\033[43m\]' | |
# local BGB='\[\033[44m\]' | |
# local BGM='\[\033[45m\]' | |
# local BGC='\[\033[46m\]' | |
# local BGW='\[\033[47m\]' | |
local UC=$C # user's color | |
[ $UID -eq "0" ] && UC=$R # root's color | |
#PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"' | |
#PS1="${EMK}[${UC}\u${EMR}@${UC}\h ${EMB}\${NEW_PWD}${EMK}]${UC}\\$ ${NONE}" | |
if [ -z ${TMUX+x} ]; then | |
# TMUX is not set, so we are not in a TMUX session | |
# We include the username and hostname into the prompt | |
PS1="${NONE}\t ${R}\u@\h ${B}\${NEW_PWD}${NONE}${G}${GIT_CURRENT_BRANCH_STATE_COLOR}\${GIT_CURRENT_BRANCH}${NONE}\$ ${NONE}" | |
# PS1="${NONE}[\t${NONE}] ${NONE}[${R}\u${R}@${R}\h ${B}\${NEW_PWD}${NONE}]${G}${GIT_CURRENT_BRANCH_STATE_COLOR}\${GIT_CURRENT_BRANCH}${NONE}\\$ ${NONE}" | |
else | |
# TMUX is set, so we are in a TMUX session | |
# We don't need to include the username and hostname into the prompt since it's in TMUX's status bar. | |
PS1="${NONE}\t ${B}\${NEW_PWD}${NONE}${G}${GIT_CURRENT_BRANCH_STATE_COLOR}\${GIT_CURRENT_BRANCH}${NONE}\$ ${NONE}" | |
fi | |
SUDO_PS1="${NONE}[\t${NONE}] ${NONE}[${R}\u${R}@${R}\h ${B}\${NEW_PWD}${NONE}]${G}\${GIT_CURRENT_BRANCH}${NONE}\\$ ${NONE}" | |
} | |
PROMPT_COMMAND=bash_prompt_command | |
bash_prompt | |
#unset bash_prompt # Don't unset this function if updating the PS1 variable every time | |
# autocompletes | |
# NOTE: To install the git autocomplete script execute: | |
# sudo curl -sSL https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -o /etc/bash_completion.d/git-completion.bash --create-dirs | |
if [ ! -f /etc/bash_completion ]; then | |
# In case the /etc/bash_completion file exists, is surely already called by the former bashrc. | |
for f in /etc/bash_completion.d/*; do | |
[ -f $f ] && source $f | |
done | |
# brew is probably installing completion scripts here | |
if [ -d /usr/local/etc/bash_completion.d/ ]; then | |
for f in /usr/local/etc/bash_completion.d/*; do | |
[ -f $f ] && source $f | |
done | |
fi | |
fi | |
#ORIGINAL BASHRC PS1 DEFINITION: | |
#if [ -z "$PS1" ]; then | |
# return | |
#fi | |
# | |
#PS1='\h:\W \u\$ ' | |
# Make bash check its window size after a process completes | |
shopt -s checkwinsize | |
# SOURCE: https://discourse.brew.sh/t/failed-to-set-locale-category-lc-numeric-to-en-ru/5092/12 | |
export LC_ALL=en_US.UTF-8 | |
# Change behavior of fzf dialogue | |
# SOURCE: https://medium.com/free-code-camp/fzf-a-command-line-fuzzy-finder-missing-demo-a7de312403ff | |
# SOURCE: https://gist.github.com/samoshkin/efc6672b13b4244f000cfc4b0c4d6125 | |
export FZF_DEFAULT_OPTS="--no-mouse --height 50% --select-1 --reverse --multi --inline-info --preview='if [[ -d {} ]]; then ls -lahGFTB {}; elif [[ \$(file --mime {}) =~ binary ]]; then echo {} is a binary file; else (BAT_LINE=\$(echo {} | grep \":\\d\\d*\\b\" | sed \"s/[^:]*:\([0-9][0-9]*\).*/\\1/g\"); bat \$(echo {} | sed \"s/:.*//g\") \$( [ -n \"\${BAT_LINE}\" ] && echo \"--highlight-line \${BAT_LINE} --line-range \$(( \${BAT_LINE} - 10 < 1 ? 1 : \${BAT_LINE} - 10 )):\") --style=numbers --color=always || cat {}) 3> /dev/null | head -300; fi;' --preview-window='right:wrap' --bind='space:execute(bat --style=numbers {} || less -f {}),ctrl-p:toggle-preview,ctrl-d:half-page-down,ctrl-u:half-page-up,ctrl-a:select-all+accept,ctrl-y:execute-silent(echo {+} | pbcopy),ctrl-o:execute(vim {+})+accept,esc:cancel'" | |
[ -f ~/.fzf.bash ] && source ~/.fzf.bash | |
# SOURCE: https://github.com/junegunn/fzf#settings | |
# Use fd (https://github.com/sharkdp/fd) instead of the default find | |
# command for listing path candidates. | |
# - The first argument to the function ($1) is the base path to start traversal | |
# - See the source code (completion.{bash,zsh}) for the details. | |
_fzf_compgen_path() { | |
fd --hidden --follow --exclude ".git" . "$1" | |
} | |
# Use fd to generate the list for directory completion | |
_fzf_compgen_dir() { | |
fd --type d --follow --exclude ".git" . "$1" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment