- Note taken on [2012-01-30 Mo 11:53]
tangle to the correct locations; use logbook drawer - Note taken on [2012-01-29 So 01:15]
Git functions added; prompt added; html export style
This is a literate programming zsh configuration written in org-mode/org-babel.
Up until January 2012 I used oh-my-zsh to configure my shell environment. It contains a lot of good ideas and a plethora of tools but, it also contains many errors and small mistakes; the code-quality overall is lousy.
After discovering the emacs starter kit I thought a lot about a good project to start to learn about and use org-babel for a literate programming adventure.
I’m usualy slow to take action, considering a lot, thinking ahead as many paths as I can – think of. Since, as of january 3d, oh-my-zsh get’s on my nerves for a couple of weeks now instead of making my day, taking on my first LP project wasn’t such a long process after all.
The first version considered complete enough to replace oh-my-zsh, finaly ridden of the command substitution bug, was finished <2012-01-10 Tue 13:21>.
<<variables>>
<<modules>>
<<aliases>>
<<functions>>
<<options>>
<<gnuglobal>>
<<keybindings>>
<<command_completion>>
<<commandline_editing>>
<<history>>
<<dired>>
<<hooks>>
<<terminal>>
<<prompt>>
<<groovy>>
<<git>>
<<packages>>
On different systems emacs 24 will be installed in different
locations; I set EMACS_BASE
here; aliases etc. later will use it.
if [ -z "${EMACS_BASE}" ]; then
EMACS_BASE="/usr/local"
export EMACS_BASE
fi
# emacs cask package/dev managment
export PATH="$HOME/.cask/bin:$PATH"
Use green
for matches, not red
.
export GREP_COLORS="mt=01;32:ms=01;32:mc=01;32:sl=:cx=:fn=35:ln=32:bn=32:se=36"
export PAGER='less'
export LC_CTYPE=$LANG
Newest GNU R in ~/opt
path=( ~/opt/bin $path )
Haskell development.
path=( ~/.cabal/bin $path )
This should always be the last part of path
tinkering, as I’m used
to be able to override any executable by putting a replacement or
wrapper in my ~/bin
.
path=( ~/bin $path )
Finaly adjust the fpath
; a lot of the stuff following is tangled
into files autoloadable, and I use wd
for easier filesystem navigation
fpath=( ~/bin/wd.zsh $fpath)
fpath=( ~/.zsh.d/functions $fpath )
wd() {
. ~/bin/wd.zsh/wd.sh
}
#
# Add RVM to PATH for scripting
PATH=$PATH:$HOME/.rvm/bin
export BASH_LIBS_DIR=~/lib/bash
export EDITOR="${EMACS_BASE}/bin/emacsclient -nw -c"
export _JAVA_AWT_WM_NONREPARENTING=1
export WEBDEV_ROOT="~/Projekte/devserver/"
export ARDUINO_PATH=/usr/share/arduino
export SKETCHBOOK_DIR=${HOME}/Arduino
export $( dex /etc/xdg/autostart/gnome-keyring-ssh.desktop )
autoload colors; colors
A few standard aliases to deal with colored output in terminals.
[ ! -L ~/bin/ls ] && alias ls='/opt/coreutils/bin/ls --color=auto'
alias grep='grep --color=auto'
alias less='less -R'
My emacs installation is sometimes in special locations; the aliases defined here reflect that.
alias emacs="${EMACS_BASE}/bin/emacs"
alias emc="${EMACS_BASE}/bin/emacsclient -c -nw"
I use awesome and don’t want nautilus
to take over my desktop.
Defining this alias prevents the nautilus
started by
gnome-session
to automaticaly take over.
alias nautilus='nautilus --no-desktop'
alias vssh="pushd ${WEBDEV_ROOT} && docker exec -it devserver /bin/bash; popd"
alias tue="tmux update-environment"
alias syslog="journalctl -f -o json | lnav"
function extract() {
unset REMOVE_ARCHIVE
if test "$1" = "-r"; then
REMOVE_ARCHIVE=1
shift
fi
if [[ -f $1 ]]; then
case $1 in
*.tar.bz2) tar xvjf $1;;
*.tar.gz) tar xvzf $1;;
*.tar.xz) tar xvJf $1;;
*.tar.lzma) tar --lzma -xvf $1;;
*.bz2) bunzip $1;;
*.rar) unrar x $1;;
*.gz) gunzip $1;;
*.tar) tar xvf $1;;
*.tbz2) tar xvjf $1;;
*.tgz) tar xvzf $1;;
*.zip) unzip $1;;
*.Z) uncompress $1;;
*.7z) 7z x $1;;
*) echo "'$1' cannot be extracted via >extract<";;
esac
if [[ $REMOVE_ARCHIVE -eq 1 ]]; then
echo removing "$1";
/bin/rm "$1";
fi
else
echo "'$1' is not a valid file"
fi
}
bash_source() {
alias shopt=':'
alias _expand=_bash_expand
alias _complete=_bash_comp
emulate -L sh
setopt kshglob noshglob braceexpand
source "$@"
}
function fromut() {
echo `perl -e "print scalar(localtime(${1})),\"\n\";"`
}
function remove_host_keys() {
host="${1}"
if [ -n "${host}" ]; then
ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${host}"
else
echo "remove_host_keys {IP|HOST}" > /dev/stderr
fi
}
function phpunit() {
command phpunit ${@}
printf '\xb1�0m'
}
function compress_jpeg() {
for pic in "${@}"; do
convert -strip -interlace Plane -gaussian-blur 0.05 -quality 85% "${pic}" "${pic}"
done
}
function check_zero_bytes() {
status=0
for arg in "${@}"; do
perl -ne '/\000/ and print' "${arg}"
status=1
done
return $status
}
setopt extended_glob \
glob_complete \
function_arg_zero \
hash_cmds \
hash_dirs \
multios \
re_match_pcre
bindkey -e
autoload -Uz compinit; compinit
unsetopt menu_complete \
flowcontrol
setopt auto_menu \
complete_in_word \
always_to_end
zmodload -i zsh/complist
zstyle :compinstall filename "$HOME/.zshrc"
autoload -Uz bashcompinit; bashcompinit
zstyle ':completion:*' matcher-list 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
zstyle ':completion:*' list-colors ''
zstyle ':completion:*:*:*:*:*' menu select
bindkey -M menuselect '^o' accept-and-infer-next-history
Menu of own processes for kill.
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01'
zstyle ':completion:*:*:*:*:processes' command "ps -u $(whoami) -o pid,user,comm -w -w"
[ -r /etc/ssh/ssh_known_hosts ] && _global_ssh_hosts=(${${${${(f)"$(</etc/ssh/ssh_known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
[ -r ~/.ssh/known_hosts ] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=()
[ -r /etc/hosts ] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}} || _etc_hosts=()
hosts=(
"$_global_ssh_hosts[@]"
"$_ssh_hosts[@]"
"$_etc_hosts[@]"
`hostname`
localhost
)
zstyle ':completion:*:hosts' hosts $hosts
Ignore most system users
zstyle ':completion:*:*:*:users' ignored-patterns \
adm amanda apache avahi beaglidx bin cacti canna clamav daemon \
dbus distcache dovecot fax ftp games gdm gkrellmd gopher \
hacluster haldaemon halt hsqldb ident junkbust ldap lp mail \
mailman mailnull mldonkey mysql nagios \
named netdump news nfsnobody nobody nscd ntp nut nx openvpn \
operator pcap postfix postgres privoxy pulse pvm quagga radvd \
rpc rpcuser rpm shutdown squid sshd sync uucp vcsa xfs
# ... unless we really want to.
zstyle '*' single-ignored show
Some completions need caching (dpkg, …)
zstyle ':completion::complete:*' use-cache 1
zstyle ':completion::complete:*' cache-path ~/.zsh.d/cache/
if [[ -r "/usr/share/bash-completion/devserver" ]]; then
bash_source /usr/share/bash-completion/devserver
fi
bindkey "^[[H" beginning-of-line
bindkey "^[[1~" beginning-of-line
bindkey "^[OH" beginning-of-line
bindkey "^[[F" end-of-line
bindkey "^[[4~" end-of-line
bindkey "^[OF" end-of-line
bindkey "^[[1;5C" forward-word
bindkey "^[[1;5D" backward-word
bindkey '^?' backward-delete-char
bindkey "^[[3~" delete-char
bindkey "^[3;5~" delete-char
bindkey "\e[3~" delete-char
bindkey \^U backward-kill-line
bindkey "^[m" copy-prev-shell-word
autoload -U url-quote-magic
zle -N self-insert url-quote-magic
setopt no_beep \
rm_star_wait
run-with-sudo () { LBUFFER="sudo $LBUFFER" }
zle -N run-with-sudo
bindkey '^Xs' run-with-sudo
complete-or-list() {
[[ $#BUFFER != 0 ]] && { zle complete-word ; return 0 }
echo
ls
zle reset-prompt
}
zle -N complete-or-list
bindkey '^I' complete-or-list
typeset -Ag abbreviations
abbreviations=(
"Il" "| less"
"Ia" "| awk"
"Ig" "| grep"
"Ieg" "| egrep"
"Iag" "| agrep"
"Ih" "| head"
"Ik" "| keep"
"It" "| tail"
"Is" "| sort"
"Iv" "| ${VISUAL:-${EDITOR}}"
"Iw" "| wc"
"Ix" "| xargs"
)
magic-abbrev-expand() {
local MATCH
LBUFFER=${LBUFFER%%(#m)[_a-zA-Z0-9]#}
LBUFFER+=${abbreviations[$MATCH]:-$MATCH}
zle self-insert
}
no-magic-abbrev-expand() {
LBUFFER+=' '
}
zle -N magic-abbrev-expand
zle -N no-magic-abbrev-expand
bindkey " " magic-abbrev-expand
bindkey "^x " no-magic-abbrev-expand
bindkey -M isearch " " self-insert
HISTFILE=~/.histfile
HISTSIZE=10000
SAVEHIST=10000
setopt append_history
setopt extended_history
setopt hist_expire_dups_first
setopt hist_ignore_dups
setopt hist_ignore_space
setopt hist_verify
setopt inc_append_history
setopt share_history
setopt hist_fcntl_lock
setopt hist_ignore_all_dups
lh
is short for load history
, fc
is a zsh
-builtin to access
the history. -R
rereads the history - in this case from the
standard history file. -I
only appends new entries from this file
to the current active history of the shell process.
alias lh='fc -RI'
function zsh_stats() {
history | awk '{print $2}' | sort | uniq -c | sort -rn | head
}
bindkey '^r' history-incremental-search-backward
bindkey "^[[5~" up-line-or-history
bindkey "^[[6~" down-line-or-history
bindkey '�OA' up-line-or-search
bindkey '�OB' down-line-or-search
bindkey '^P' up-line-or-search
bindkey '^N' down-line-or-search
setopt long_list_jobs
I use autocorrection, but define a couple of aliases for commands for which I don’t want correction.
setopt correct \
correct_all
alias man='nocorrect man'
alias mv='nocorrect mv'
alias mkdir='nocorrect mkdir'
alias gist='nocorrect gist'
alias ebuild='nocorrect ebuild'
setopt auto_name_dirs
setopt auto_pushd
setopt auto_cd
setopt pushd_ignore_dups
setopt pushd_silent
alias ..='cd ..'
alias cd..='cd ..'
alias cd...='cd ../..'
alias cd....='cd ../../..'
alias cd.....='cd ../../../..'
alias cd/='cd /'
alias md='mkdir -p'
alias rd=rmdir
alias d='dirs -v'
cd () {
if [[ "x$*" == "x..." ]]; then
cd ../..
elif [[ "x$*" == "x...." ]]; then
cd ../../..
elif [[ "x$*" == "x....." ]]; then
cd ../../..
elif [[ "x$*" == "x......" ]]; then
cd ../../../..
else
builtin cd "$@"
fi
}
function mcd() {
mkdir -p "$1" && cd "$1";
}
autoload -U add-zsh-hook
eval $(dircolors)
In omz_termsupport_preexec
$(
and %
are escaped in the second argument to
function title()
; this is to prevent multiple execution of the $()
command – prompt substitution as used in title
(option -P
to
print
) would execute the command at least once, and confusion of %
tags to commands like date
with prompt %
tags.
function title {
[ "$DISABLE_AUTO_TITLE" != "true" ] || return
if [[ "$TERM" == screen* ]]; then
print -Pn "\ek$1:q\e\\" #set screen hardstatus, usually truncated at 20 chars
elif [[ "$TERM" == xterm* ]] || [[ $TERM == rxvt* ]] || [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then
print -Pn "\e]2;$2:q\a" #set window name
print -Pn "\e]1;$1:q\a" #set icon (=tab) name (will override window name on broken terminal)
fi
}
ZSH_THEME_TERM_TAB_TITLE_IDLE="%15<..<%~%<<" #15 char left truncated PWD
ZSH_THEME_TERM_TITLE_IDLE="%n@%m: %~"
#Appears when you have the prompt
function omz_termsupport_precmd {
title $ZSH_THEME_TERM_TAB_TITLE_IDLE $ZSH_THEME_TERM_TITLE_IDLE
}
#Appears at the beginning of (and during) of command execution
function omz_termsupport_preexec {
emulate -L zsh
setopt no_extended_glob
local CMD_1=${1[(wr)^(*=*|sudo|ssh|-*)]} #cmd name only, or if this is sudo or ssh, the next cmd
local CMD_2=${2//\$\(/\\\$(} # ')}
CMD_1=${CMD_1//\%/%%}
CMD_2=${CMD_2//\%/%%}
#
title "${CMD_1}" "%100>...>${CMD_2}%<<"
}
add-zsh-hook precmd omz_termsupport_precmd
add-zsh-hook preexec omz_termsupport_preexec
tmux wrapper that adds new commands to update environment variables in running panes/windows
function tmux() {
case "$1" in
update-environment|update-env|env-update)
local v
command tmux show-environment | while read v; do
if [[ "$v" == -* ]]; then
unset ${v/#-/}
else
# Add quotes around the argument
v=${v/=/\=\"}
v=${v/%/\"}
eval export $v
fi
done
;;
*)
command tmux "$@"
;;
esac
}
autoload -U promptinit; promptinit
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git svn
precmd() {
vcs_info
}
setopt prompt_subst
if [ -f ~/.local/share/icons-in-terminal/icons_bash.sh ]; then
. ~/.local/share/icons-in-terminal/icons_bash.sh
elif [ -f /usr/share/icons-in-terminal/icons_bash.sh ]; then
. /usr/share/icons-in-terminal/icons_bash.sh
fi
Do not show the nodejs
block, show our new shiny php block instead.
BLOX_BLOCK__PHP_SYMBOL="${BLOX_BLOCK__PHP_SYMBOL:-${file_php:-php} }"
BLOX_BLOCK__PHP_COLOR="${BLOX_BLOCK__PHP_COLOR:-green}"
function blox_block__php() {
if [ -n "$(find_root "$PWD" RoboFile.php)" ]; then
PHPV=$(php --version | head -n 1 | cut -d- -f1 | sed 's/PHP //' | cut -d\ -f1)
blox_helper__build_block \
"${BLOX_BLOCK__PHP_COLOR}" \
"${BLOX_BLOCK__PHP_SYMBOL}${PHPV}"
fi
}
export BLOX_SEG__UPPER_RIGHT=( bgjobs php pyenv virtualenv time )
export GTAGSCONF=/usr/local/share/gtags/gtags.conf
export GTAGSLABEL=pygments
source ~/.gvm/bin/gvm-init.sh
If there is on thing I had to name, that made me crave for oh-my-zsh it was the right site prompt stating repository state; here are the functions I ripped from it…
function git_prompt_info() {
ref=$(git symbolic-ref HEAD 2> /dev/null) || return
echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX"
}
function parse_git_dirty() {
if [[ -n $(git status -s --ignore-submodules=dirty 2> /dev/null) ]]; then
echo "$ZSH_THEME_GIT_PROMPT_DIRTY"
else
echo "$ZSH_THEME_GIT_PROMPT_CLEAN"
fi
}
function git_prompt_ahead() {
if $(echo "$(git log origin/$(current_branch)..HEAD 2> /dev/null)" | grep '^commit' &> /dev/null); then
echo "$ZSH_THEME_GIT_PROMPT_AHEAD"
fi
}
function git_prompt_short_sha() {
SHA=$(git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
}
function git_prompt_long_sha() {
SH A=$(git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
}
function git_prompt_status() {
INDEX=$(git status --porcelain 2> /dev/null)
STATUS=""
if $(echo "$INDEX" | grep '^?? ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS"
fi
if $(echo "$INDEX" | grep '^A ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
elif $(echo "$INDEX" | grep '^M ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
fi
if $(echo "$INDEX" | grep '^ M ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
elif $(echo "$INDEX" | grep '^AM ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
elif $(echo "$INDEX" | grep '^ T ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
fi
if $(echo "$INDEX" | grep '^R ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_RENAMED$STATUS"
fi
if $(echo "$INDEX" | grep '^ D ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
elif $(echo "$INDEX" | grep '^AD ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
fi
if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then
STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS"
fi
echo $STATUS
}
autoload -Uz gitaliasinit; gitaliasinit
autoload -Uz find_root
autoload -Uz stumpdeb
# Load RVM into a shell session *as a function
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
if [ "$0" = "/usr/sbin/lightdm-session" -a "$DESKTOP_SESSION" = "i3" ]; then
export $(gnome-keyring-daemon -s)
fi
yardnsm/blox-zsh-theme
hlissner/zsh-autopair
zsh-users/zsh-completions
zsh-users/zsh-autosuggestions
zsh-users/zsh-history-substring-search
zsh-users/zsh-syntax-highlighting
[ -f ~/.zsh.d/plugins.sh ] && source ~/.zsh.d/plugins.sh
_GITALIAS_DIR=${:-~/.zsh.d/functions/git}
gitaliasinit() {
fpath=($_GITALIAS_DIR $fpath)
for gitalias in $_GITALIAS_DIR/*; do
if [[ -r $gitalias ]]; then
name=$gitalias:t
autoload -Uz $name
fi
done
}
[[ -o kshautoload ]] || gitaliasinit "$@"
git add "${argv[@]}"
git commit "${argv[@]}"
git diff "${argv[@]}"
git log "${argv[@]}"
git status "${argv[@]}"
The normal git pull
git pull "${argv[@]}"
Update a local branch from updated master
checkout master && pull && checkout local && git merge master
Update org-mode from maint, not master
checkout maint && pull && checkout local && git merge maint
git push "${argv[@]}"
git checkout "${argv[@]}"
git clone "${argv[@]}"
pushd ~/Projekte/stumpwm-contrib/
git pull
popd
pushd ~/Projekte/stumpwm
mkdir -p usr/local/bin
mkdir -p usr/local/share/stumpwm/lisp
mkdir -p usr/local/share/info
cp stumpwm usr/local/bin
find ~/Projekte/stumpwm-contrib -maxdepth 1 -mindepth 1 -name '[a-z]*' -type d -print0 | xargs -0 -ILISP cp -a LISP usr/local/share/stumpwm/lisp/
cp stumpwm.info usr/local/share/info/
gzip usr/local/share/info/stumpwm.info
fpm -t deb -s dir -n stumpwm -v $(date +"%Y%m%d") -d sbcl usr/
popd
local look_from=${1:-$PWD}
local look_for=${2:-}
local look_until=${${3:-/}:A}
# Manually look in parent dirs. An extended Zsh glob should use Y1 for
# # performance reasons, which is only available in zsh-5.0.5-146-g9381bb6.
local last
local parent_dir="$look_from"
local abs_parent_dir
while true; do
abs_parent_dir=${parent_dir:A}
if [[ $abs_parent_dir == $last ]]; then
break
fi
local parent_file="${parent_dir}/${look_for}"
if [[ -f $parent_file ]]; then
if [[ ${parent_file[1,2]} == './' ]]; then
echo ${parent_file#./}
else
echo ${parent_file:a}
fi
break
fi
if [[ $abs_parent_dir == $look_until ]]; then
break
fi
last=$abs_parent_dir
parent_dir="${parent_dir}/.."
done