# .bashrc -- Bash loads this file at startup, after ".bash_profile". # Yes, Bash syntax allows "export FOO=BAR", but sh syntax requires # "FOO=BAR; export FOO", so that's what we do to remain /bin/sh # compatible. # My .xinitrc (and, indirectly, my .twmrc) use this: HOST=`hostname`; export HOST # Hosts we care about prefer SSH: CVS_RSH=ssh export CVS_RSH if [ "${TERM}X" = "dumbX" -o "${TERM}X" = "emacsX" ]; then PAGER=/bin/cat export PAGER MANPAGER=/bin/cat export MANPAGER fi # Many programs use an $EDITOR variable; "emacsclient" says to connect # with a running emacs if one exists, else just use emacs: # EDITOR=emacsclient; # export EDITOR EDITOR=emacsclient export EDITOR # Some variables I don't use right now, but might want to later (see # https://zwischenzugs.com/2019/05/11/seven-surprising-bash-variables # for longer explanations). # # * PROMPT_COMMAND # E.g., PROMPT_COMMAND='echo -n "printing this prompt at " && date' # # * HISTTIMEFORMAT # E.g., HISTTIMEFORMAT='I ran this command at: %d/%m/%y %T ' # # * CDPATH # E.g., .:/private/work:/www # # * TMOUT # E.g., TMOUT=300 means log me out after 5 minutes of inactivity # # * SHLVL, LINENO, REPLY # You use these, rather than set them (well, 'read' sets REPLY). PATH=\ ${HOME}/.jenv/bin:\ ${HOME}/private/bin:\ ${HOME}/.local/bin:\ ${HOME}/bin:\ /usr/local/bin:\ /bin:\ /usr/bin:\ /sbin:\ /usr/sbin:\ /usr/games:\ ${PATH} export PATH # http://www.jenv.be/: Support multiple simultaneous versions of Java. # Recommended by Dan Schultz (slifty). TL;DR: # - git clone https://github.com/gcuisinier/jenv.git ~/.jenv # - Add ${HOME}/.jenv/bin to $PATH # - Put 'eval "$(jenv init -)"' in .bashrc # i.e., as done below # - jenv add /usr/lib/jvm/java-8-openjdk-amd64 # - Use 'jenv versions' to see available Java versions # (Examples below assume the output lists "1.8" among other things.) # - Use 'jenv global 1.8' to get Java 1.8 # 'local' and 'shell' work tooa # - Use 'java -version' to see active version if [ -x ${HOME}/.jenv/bin/jenv ]; then eval "$(jenv init -)" fi INFOPATH=${HOME}/src/org-mode/info:${INFOPATH} export INFOPATH LD_LIBRARY_PATH=.:${LD_LIBRARY_PATH}:/usr/local/lib export LD_LIBRARY_PATH # Don't clutter command history with duplicates history_control=ignoredups export history_control # Oh, apparently it's "HISTCONTROL" nowadays. Fine, whatever. HISTCONTROL=ignoredups export HISTCONTROL # I like to be able to use C-d to log out. unset ignoreeof # Make second-level prompt show the hostname: PS2="\h... " export PS2 # https://spin.atomicobject.com/2016/05/28/log-bash-history/ points # out that one could log every Bash command, like so: # export PROMPT_COMMAND='if [ "$(id -u)" -ne 0 ]; then echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(history 1)" >> ~/.logs/bash-history-$(date "+%Y-%m-%d").log; fi' # My standard aliases alias m="${HOME}/bin/maltron.sh" alias ls="ls -CF" alias os="ls -CF" alias ll="ls -l" alias lh="ls -lh" alias ol="ls -l" alias la="ls -a" alias rr="rm -r" alias gb="git branch" alias gd="git diff" alias gdc="git diff --cached" alias stq="svn st -q" alias pu=pushd alias po=popd alias ro=cleanemacs alias whom="who" alias slog="svn log > log.out" alias svlog="svn log -v > logv.out.tmp && mv logv.out.tmp logv.out" alias gvlog="git log --name-status" alias bvlog="bzr log -v -n0 --show-ids > log-vn0.out &" alias blog="bzr log -n0 --show-ids > log-n0.out" # Quick Fix for terminal terminals function termfix { TERM=vt100 export TERM stty rows 24 cols 80 } ## I like my prompt to show me who I am if [ ${UID} = 0 ] then PROMPTEND='# ' else PROMPTEND='>' fi export PROMPTEND ## And I like my prompt to show me where I am: # for when prompt gets overly long: function shortprompt { PS1="@\W\$PROMPTEND" export PS1 } alias shortp=shortprompt # for when prompt gets underly short: function longprompt { PS1="@\$PWD\$PROMPTEND" export PS1 } alias longp=longprompt # prompt used in book examples (so I can paste directly from my shell buffer) function bookprompt { PS1="\h$ " export PS1 } # The short form is usually what I want: shortprompt function cleanemacs { # Remove all emacs junk files in specified directory (default: current # directory) and subtrees. Any files that are removed are printed to # the screen. Does not ask. DIR=${1-`pwd`} find ${DIR} \ \( -name '.[BC]*' \ -o -name '.emacs_[0-9]*' \ -o -name '.*~' \ -o -name '*~' \ -o -name '#*#' \) \ -print -exec rm -f {} \; } function svncount { # Show commit activity. I don't anticipate running this, I just # wanted to save that awesome command line so I don't have to make # it up again next time. svn log https://svn.apache.org/repos/asf/subversion/ \ | grep -E "^r[0-9]+ \|" | cut -d "|" -f 2 | cut -d " " -f 2 \ | sort | uniq -c | sort -rn } ############################################################################## # # PGL == Pretty Git Log # # Adapted from Thorsten Ball's post # https://registerspill.thorstenball.com/p/how-i-use-git. # Thorsten Ball apparently got it from Gary Bernhardt: # https://www.destroyallsoftware.com/screencasts/catalog/pretty-git-logs # # There's probably lots of other stuff in Thorsten Ball's .githelpers: # https://github.com/mrnugget/dotfiles/blob/c4624ed521d539856bcf764f04a295bb19093566/gitconfig#L13-L17 PGL_HASH="%C(always,yellow)%h%C(always,reset)" PGL_RELATIVE_TIME="%C(always,green)%ar%C(always,reset)" PGL_AUTHOR="%C(always,bold blue)%an%C(always,reset)" PGL_REFS="%C(always,red)%d%C(always,reset)" PGL_SUBJECT="%s" PGL_FORMAT="$PGL_HASH $PGL_RELATIVE_TIME{$PGL_AUTHOR{$PGL_REFS $PGL_SUBJECT" function pretty_git_log() { # If you want to page it through 'less', just plain 'less' won't cut # it (er, if you'll pardon the expression). You need something like # # blah blah blah | less -XRS --quit-if-one-screen # # in order to handle the color codes correctly. And you might # consider this just to make life even prettier: # # blah blah blah | less -XRS --quit-if-one-screen git --no-pager log --graph --pretty="tformat:$PGL_FORMAT" $* | column -t -s '{' } alias pgl=pretty_git_log ############################################################################## # I believe this has something to do with mail... if [ -z "${USER}" ]; then USER=${LOGNAME} fi if [ -x ${HOME}/bin/gnotifications -a -d ${HOME}/.cache ]; then ${HOME}/bin/gnotifications > ${HOME}/.cache/gnotifications.out & fi ### OTS stuff. ### export OTS_DIR=${HOME}/private/work/ots export OTS_TOOLS_DIR=${HOME}/private/work/ots/r/ots-tools export PATH=${OTS_TOOLS_DIR}:${PATH} export OTS_DOCTOOLS_DIR=${HOME}/private/work/ots/r/ots-doctools export OTS_USERNAME=kfogel export OTS_BOOKKEEPING_DIR=${HOME}/private/work/ots/r/ots-bookkeeping export TEXMFHOME=${HOME}/private/.texmf # Needed for https://code.librehq.com/ots/pass-git-svn export PASSWORD_STORE_ENABLE_EXTENSIONS=true # We no longer set PASSWORD_STORE_EXTENSIONS_DIR because by default # 'pass' will look in ~/.password-store/.extensions/ and that's where # we're putting the 'git-svn.bash' extension. If this environment # variable were set, then pass would use only it and never look in # ~/.password-store/.extensions/. I've submitted a proposal # (ref:1a5e5498) to upstream to fix this, but who knows when or if # they'll agree. So for now, I just don't set this variable. # # export PASSWORD_STORE_EXTENSIONS_DIR=/usr/local/lib/password-store/extensions # Recommended by https://code.librehq.com/ots/ots-tools/-/blob/main/opass if [ -d ${OTS_TOOLS_DIR} -a -f ${OTS_TOOLS_DIR}/opass-bash-completion ]; then source ${OTS_TOOLS_DIR}/opass-bash-completion fi # Set up pyenv, as per https://gioele.io/pyenv-pipenv. # See https://github.com/pyenv/pyenv/ for more about pyenv. if [ ! -d ${HOME}/.pyenv ]; then mkdir -p ${HOME}/.pyenv fi PYENV_ROOT=${HOME}/.pyenv export PYENV_ROOT # git clone https://github.com/pyenv/pyenv.git $PYENV_ROOT/ PATH=${PYENV_ROOT}/bin:${PATH} export PATH # This page suggests Debian packages to install: # # https://github.com/pyenv/pyenv/wiki # # As of this writing they are: # # $ apt-get install --no-install-recommends \ # make build-essential libssl-dev zlib1g-dev libbz2-dev \ # libreadline-dev libsqlite3-dev wget curl llvm \ # libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \ # libffi-dev liblzma-dev # # Once all the above is done, run ~/private/bin/pyenv-enable and # follow the instructions it gives. Then you can do things like: # # $ pyenv install 3.6.3 # # https://github.com/OpenTechStrategies/flask-restplus-csrf was one # motivation for this. ### End OTS stuff. ### if [ -f ${HOME}/private/.bashrc ]; then source ${HOME}/private/.bashrc fi #### If there is an ssh agent running on this machine, set up the #### environment accordingly. This writes the agent info to a file #### named $HOME/.ssh-HOSTNAME, checks if the agent is still alive, #### and restarts a new one otherwise. # function ssh-find-agent { # local agentfile="$HOME/.ssh-`hostname`" # [ -f $agentfile ] && . $agentfile > /dev/null # ## Is the agent process still alive? # ( ssh-add -l > /dev/null 2>&1 ) || { # ## No, start a new one. # ssh-agent > $agentfile # . $agentfile > /dev/null # } # }