#
# .bashrc for use on my OS X systems at home
#
# forked and adapted from this version used on W3C systems:
# Id: .bashrc,v 1.49 2001/01/18 05:15:00 gerald Exp
#
# $Id: bashrc,v 1.52 2025/03/28 22:17:50 gerald Exp $
#

if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

if [ -f $HOME/.ssh/creds ]; then
	. $HOME/.ssh/creds
fi

export EDITOR=vi
export VISUAL=vi

# leave first element empty instead of "." to avoid printing path when cd'ing
CDPATH=:$HOME

# /opt/local/libexec/gnubin added to path to avoid having to create aliases
# for all the macports-installed gnu utils with g prefixes, e.g. gdate, gls

PATH=""
for dir in \
    /Users/gerald/bin \
    /home/gerald/bin \
    /opt/local/libexec/gnubin \
    /opt/local/sbin \
    /usr/local/sbin \
    /usr/local/bin \
    /opt/local/bin \
    /usr/sbin \
    /sbin \
    /usr/lib \
    /opt/bin \
    /bin \
    /usr/bin \
; \
do
    if [ -d $dir ]; then
	PATH="${PATH}:${dir}"
    fi
done
PATH=${PATH#:}	# make sure "" is not an element in the final path
export PATH

MANPATH=""
for dir in \
    /usr/local/man \
    /opt/local/share/man \
    /usr/man \
    /usr/share/man \
; \
do
    if [ -d $dir ]; then
	MANPATH="${MANPATH}:${dir}"
    fi
done
MANPATH=${MANPATH#:}	# make sure "" is not an element in the final path
export MANPATH

LANG=C
CC=gcc
INPUTRC=$HOME/.inputrc export INPUTRC
unset MAILCHECK
CVSROOT="/ds9/data/cvsroot"; export CVSROOT
CVS_RSH="ssh"; export CVS_RSH
PAGER="less"; export PAGER

if [ -z $HOST ]; then
    HOST=`scutil --get LocalHostName`
    HOST=${HOST%.w3.org}
fi
HOST=mini # temporary workaround for ugly prompt color for 'Mac-mini'
export HOST

ignoreeof=0				# makes ^D logout immediately
shopt -s histappend
shopt -s cmdhist
HISTSIZE=50000; export HISTSIZE
HISTFILESIZE=50000; export HISTFILESIZE
HISTTIMEFORMAT="%F %T "; export HISTTIMEFORMAT
HISTIGNORE="&:[ ]*:exit:ls:bg:fg:history"; export HISTIGNORE

case $TERM in
  linux)		colorPrompt=1;;
  color-xterm|xterm-color|xterm-256color|xterm|rxvt|screen)	colorPrompt=1; titleControl=1;;
esac

if [ $colorPrompt ]; then
    # vary hostname color in prompt based on hash of hostname
    HASH=`echo "$HOST" | md5sum`
    FG=$(($((0x${HASH:0:1}))%8+30))
    BG=$(($((0x${HASH:1:1}))%8+40))
    export PS1="\[\e[0;0m\]\u\[\e[0m\]@\[\e[1;${FG}m\e[0;${BG}m\]\h\[\e[0m\]:\w$ "
    unset HASH FG BG
fi

umask 022

set -o vi
bind "set completion-ignore-case on"
bind "set completion-map-case on"
bind "set show-all-if-ambiguous on"
bind "set mark-symlinked-directories on"
bind "set skip-completed-text on"
shopt -s autocd
shopt -s dirspell
shopt -s cdspell
shopt -s cdable_vars
shopt -s direxpand # try to avoid $VAR getting escaped during tab completion

alias ll="ls -laFN --color=auto"
alias l="ls -lFN --color=auto"
alias LL="ls -LlaFN --color=auto"
alias L="ls -LlFN --color=auto"

# remove annoying bold face from dir colors
eval `dircolors | sed 's/01;//g'`
# use red for executables; default green is unreadable on white bg
LS_COLORS=$LS_COLORS:"ex=31"; export LS_COLORS
# use blue for symlinks; default is bold red on black with bad wrapping
LS_COLORS=$LS_COLORS:"or=00;34"; export LS_COLORS

alias md="mkdir"
alias rd="rmdir"
alias c=clear
alias Grep=grep
alias Tar=tar
alias psg="ps aux | grep $*"
alias w3ccvs="CVS_RSH=ssh cvs -d cvs.w3.org:/w3ccvs"
alias mtr="mtr -t"
alias cu="cvs update"
alias count="sort | uniq -c | sort -n"
alias h="vi $HOME/misc/2025/hours"
alias v="mpv -fs --framedrop=decoder"
alias grep="grep --color"
alias hogs='du -cks * .??* | sort -n | while read size fname; do for unit in k M G T P E Z Y; do if [ $size -lt 1024 ]; then echo -e "${size}${unit}\t${fname}"; break; fi; size=$((size/1024)); done; done'
alias info="info --vi-keys"
alias top=htop
# http://www.commandlinefu.com/commands/view/5312/alias-head-for-automatic-smart-output
alias head='head -n $(($LINES-2))'
WWW=$HOME/WWW; export WWW
Y=$HOME/Dropbox/misc/archive/`date +%Y`; export Y
DA=$HOME/Dropbox/misc/archive; export DA
DM=/Volumes/media; export DM
DD=/Volumes/data; export DD
W=$DD/www/people/gerald; export W
SD=$HOME/SynoDrive; export SD
SG=$HOME/SynoGer; export SG
N=$SD/House/Notes; export N
L="??-??-??.jpg"; export L
P="$HOME/p/master"; export P
D="$P/modules/w3cnameserver/files/zones"; export D
E="$P/modules/w3cmailhub/files/etc"; export E

# need to do the following because stoopid dropbox doesn't preserve symlinks
alias addhrs="$HOME/impressive.net/people/gerald/2002/03/21/addhrs"
alias cal="$HOME/impressive.net/people/gerald/2003/01/cal"
alias dedundify="$HOME/impressive.net/people/gerald/2010/11/dedundify"
alias eta="$HOME/impressive.net/people/gerald/2009/07/eta"
alias magnet2seedbox="$HOME/impressive.net/people/gerald/2012/05/magnet2seedbox"
alias vix="$HOME/impressive.net/people/gerald/2013/04/vix"
alias m="$HOME/impressive.net/people/gerald/2001/04/fetch_mail"
alias w3c-browse-message="$HOME/impressive.net/people/gerald/2011/04/w3c-browse-message"
alias w3c-copy-archive-uri="$HOME/impressive.net/people/gerald/2011/04/w3c-copy-archive-uri"
alias addinv="$HOME/impressive.net/people/gerald/2002/07/19/addinv"
alias ymdify="$HOME/impressive.net/people/gerald/1999/10/ymdify"
alias H="lwp-request -m HEAD"
alias G="lwp-request -m GET"
alias n="ls -glartN | tail -n 40"
alias git="TZ=UTC git"
alias glog="git log --abbrev-commit --decorate --date=format-local:'%Y-%m-%d %H:%M:%S %Z'"
alias noop="cat>/dev/null"
alias globaltimes=dt
alias mmrefs='find mm/ -type f | sed "s,^mm/,~/$(readlink mm)/,"'

LESS="-aiMnR -b20"; export LESS

BAT_THEME="Monokai Extended Light"; export BAT_THEME

# keep track of various dirs that contain code, for easier grepping
# when I am trying to find similar code I wrote in the past
# (e.g. find $CODEDIRS -type f | xargs grep localtime)
for dir in \
    $HOME/bin \
    $HOME/p \
    $HOME/WWW/Systems/Mail/smartlist/etc \
    $HOME/WWW/Systems/Mail/smartlist/bin \
    $HOME/WWW/Systems/Mirroring/bin/cvs \
    $HOME/WWW/Web/stats-bin \
    $HOME/www/software/hurl/source \
; \
do
    if [ -d $dir ]; then
	CODEDIRS="${CODEDIRS} ${dir}"
    fi
done
export CODEDIRS

grepcode () {
    find $CODEDIRS -type f | xargs grep -l "$1" | sort -u | xargs grep "$1"
}

if [ "${-#hi}" != "${-}" ]		# this is for interactive shells only
then

  # this stuff stolen from Eric Prud'hommeaux
  if [ `echo "${TERM}"|grep xterm` ]; then
    title () { echo -n  ']0;'$1''; }
    icon_title () { echo -n  ']1;'$1''; }
    window_title () { echo -n  ']2;'$1''; }
    retitle () {
	window_title "$HOST"
	icon_title "$HOST"
    }

    ssh () {
      sshUser=$USER
      for arg in $*
      do
	if [ x$nextIsSshUser != x ]; then
	  sshUser=$arg
	  nextIsSshUser=
	elif [ x$nextIsSshParm != x ]; then
	  sshParm="$sshParam $arg"
	  nextIsSshParm=
	else
	  case $arg in
	  -l)
	    nextIsSshUser=1
	    continue;;
	  -f)
	    sshStatus='starting '
	    continue;;
	  -a|-f|-k|-n|-q|-P|-t|-v|-V|-g|-x|-C)
	    continue;;
	  -c|-e|-i|-o|-p|-L|-R)
	    nextIsSshParm=1
	    continue
	  esac
	  if [ x$sshHost != x ]; then
	    sshCmd="$sshCmd $arg"
	    continue
	  else
	    sshHost=$arg
	  fi
	fi
      done;
      # title "$sshStatus$sshUser@$sshHost $sshCmd";
      title "$sshHost"
      `\\which ssh` $*;
      retitle;
      sshUser=
      sshHost=
      sshCmd=
      sshStatus=
      nextIsSshUser= # in case of bad arguments to last ssh call
      nextIsSshParm=
    }
    retitle
  fi
fi

LC_CTYPE=en_US.UTF-8; export LC_CTYPE
LC_ALL=en_US.UTF-8; export LC_ALL
PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH

# enable autocomplete for aws commands, per
# https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-completion.html
complete -C '/usr/local/bin/aws_completer' aws
AWS_PROFILE="gerald-w3c"; export AWS_PROFILE

scd() {
    cd `search-for $@`
}

# CVS fetch and edit the specified URL
edit() {
    url=${1%%#*}			# strip fragment if present
    url=${url/%\///Overview.html}	# add Overview.html if needed
    url=${url/#http:/https:}		# convert http to https for next rule
    path=WWW${url#https://www.w3.org}
    fed $path
    dir=${path%/*}
    cd $dir
}

muttenv="personal"; export muttenv
w3cmutt() {
    muttenv="w3c" mutt "$@"
}

# log in to root at the specified host via jump host
R() {
    h=${*}.w3.internal
    ssh -t root@$h 'bash --rcfile .bashrc.gerald'
}

if [ -e /etc/bash_completion ]; then
    . /etc/bash_completion
fi

# ruler: a shell function to print a ruler the width of the terminal window. 
# from http://www.commandlinefu.com/commands/view/4719/a-shell-function-to-print-a-ruler-the-width-of-the-terminal-window.
ruler() {
for s in '....^....|' '1234567890'; do
    w=${#s}
    str=$( for (( i=1; $i<=$(( ($COLUMNS + $w) / $w )) ; i=$i+1 )); do
	echo -n $s
    done )
    str=$(echo $str | cut -c -$COLUMNS)
    echo $str
done
}

f () {
    awk "{print \$$1}"
}

fq () {
    awk -F\" "{print \$$1}"
}

add() {
    awk '{ sum += $1; } END { print sum; }'
}

average() {
    awk '{ sum += $1; } END { print sum / NR; }'
}

# copied from https://stackoverflow.com/a/49263254
# see also: datamash (used in report-slowest-uris)
median() {
    sort -n | awk '{arr[NR]=$1} END {if (NR%2==1) print arr[(NR+1)/2]; else print (arr[NR/2]+arr[NR/2+1])/2}'
}

# smart cd: if file specified, cd to its parent dir 
# http://www.commandlinefu.com/commands/view/5452/smart-cd..-cd-to-the-file-directory-if-you-try-to-cd-to-a-file
cd() {
    [ -z "$1" ] && set -- ~
    [ -f "$1" ] && set -- "${1%/*}"
    builtin cd "$1"
}

# lf: less file foo (useful for peeking at a script with a distinct name)
lf() {
    DIRS="$P $HOME/WWW/Systems/Http/cgi-bin $HOME/WWW/Systems/Mail/smartlist"
    find $DIRS -type f -name "*$1*" -print0 | xargs -0 less
}

# calc: like expr, but handles floating point numbers
calc() {
    ( echo scale=4; echo $@ ) | bc
}

# print our current public IP address
# copied from https://github.com/jessfraz/dotfiles/blob/master/.aliases
myip() {
    dig +short myip.opendns.com @resolver1.opendns.com
}

# Get colors in manual pages
# copied from https://github.com/jessfraz/dotfiles/blob/master/.functions
man() {
    env \
	LESS_TERMCAP_mb="$(printf '\e[1;31m')" \
	LESS_TERMCAP_md="$(printf '\e[1;31m')" \
	LESS_TERMCAP_me="$(printf '\e[0m')" \
	LESS_TERMCAP_se="$(printf '\e[0m')" \
	LESS_TERMCAP_so="$(printf '\e[1;44;33m')" \
	LESS_TERMCAP_ue="$(printf '\e[0m')" \
	LESS_TERMCAP_us="$(printf '\e[1;32m')" \
	man "$@"
}

# rgi: interactive rg
# copied and adapted from https://news.ycombinator.com/item?id=31010090
rgi () {
    rg --line-number --no-heading --color=always --smart-case "$@" | fzf -d ':' -n 2.. --ansi --no-sort --preview-window 'down:20:+{2}-9' --preview 'bat --style=numbers --color=always --highlight-line {2} {1}'
}

