Last active
February 14, 2020 21:28
-
-
Save andrewelkins/e98fbaef9cf4ebf2392226682b42c611 to your computer and use it in GitHub Desktop.
a zshrc configuration file
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
# .zshrc interactive configuration file for zsh | |
# Thanks to klapmuetz, caphuso, Mikachu, +chris+, zshwiki.org. | |
# Originally from http://leahneukirchen.org/dotfiles/.zshrc | |
# first revision: 26/09/2019 andrew | |
# | |
# Path to your oh-my-zsh installation. | |
export ZSH="/Users/$USER/.oh-my-zsh" | |
## Addresses bash and pre installed item | |
export PATH=$HOME/bin:/usr/local/bin:$PATH | |
# Anaconda Python/R | |
export PATH="/usr/local/anaconda3/bin:$PATH" | |
# NVM Stuff | |
export NVM_DIR="$HOME/.nvm" | |
. "$(brew --prefix nvm)/nvm.sh" | |
# Set name of the theme to load --- if set to "random", it will | |
# load a random theme each time oh-my-zsh is loaded, in which case, | |
# to know which specific one was loaded, run: echo $RANDOM_THEME | |
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes | |
ZSH_THEME="robbyrussell" | |
#ZSH_THEME="spaceship" | |
#ZSH_THEME="powerlevel9k/powerlevel9k" | |
#ZSH_THEME="agnoster" | |
plugins=( | |
vscode | |
) | |
source $ZSH/oh-my-zsh.sh | |
## Addresses bash and pre installed item | |
#export PATH=$HOME/bin:/usr/local/bin:$PATH | |
# Anaconda Python/R | |
#export PATH="/usr/local/anaconda3/bin:$PATH" | |
# z fast complete | |
. `brew --prefix`/etc/profile.d/z.sh | |
# == OPTIONS | |
setopt NO_BEEP | |
setopt C_BASES | |
setopt OCTAL_ZEROES | |
setopt PRINT_EIGHT_BIT | |
setopt SH_NULLCMD | |
setopt AUTO_CONTINUE | |
setopt NO_BG_NICE | |
setopt PATH_DIRS | |
setopt NO_NOMATCH | |
setopt EXTENDED_GLOB | |
disable -p '^' | |
setopt LIST_PACKED | |
setopt BASH_AUTO_LIST | |
setopt NO_AUTO_MENU | |
setopt NO_CORRECT | |
setopt NO_ALWAYS_LAST_PROMPT | |
setopt NO_FLOW_CONTROL | |
setopt AUTO_PUSHD | |
setopt PUSHD_IGNORE_DUPS | |
setopt PUSHD_MINUS | |
setopt HIST_IGNORE_DUPS | |
setopt HIST_IGNORE_SPACE | |
setopt INC_APPEND_HISTORY | |
setopt EXTENDED_HISTORY | |
export HISTSIZE=1000000000 | |
export SAVEHIST=$HISTSIZE | |
setopt EXTENDED_HISTORY | |
# save every command before it is executed | |
setopt inc_append_history | |
# read history everytime before executing history | |
setopt share_history | |
HISTFILE=~/.zsh_history | |
LISTMAX=0 | |
REPORTTIME=60 | |
TIMEFMT="%J %U user %S system %P cpu %MM memory %*E total" | |
MAILCHECK=0 | |
# == PROMPT | |
# gitpwd - print %~, limited to $NDIR segments, with inline git branch | |
NDIRS=2 | |
gitpwd() { | |
local -a segs splitprefix; local gitprefix branch | |
segs=("${(Oas:/:)${(D)PWD}}") | |
segs=("${(@)segs/(#b)(?(#c10))??*(?(#c5))/${(j:\u2026:)match}}") | |
if gitprefix=$(git rev-parse --show-prefix 2>/dev/null); then | |
splitprefix=("${(s:/:)gitprefix}") | |
if ! branch=$(git symbolic-ref -q --short HEAD); then | |
branch=$(git name-rev --name-only HEAD 2>/dev/null) | |
[[ $branch = *\~* ]] || branch+="~0" # distinguish detached HEAD | |
fi | |
if (( $#splitprefix > NDIRS )); then | |
print -n "${segs[$#splitprefix]}@$branch " | |
else | |
segs[$#splitprefix]+=@$branch | |
fi | |
fi | |
(( $#segs == NDIRS+1 )) && [[ $segs[-1] == "" ]] && print -n / | |
print "${(j:/:)${(@Oa)segs[1,NDIRS]}}" | |
} | |
nbsp=$'\u00A0' | |
# == COMPLETION | |
zmodload zsh/complist | |
autoload -Uz compinit && compinit | |
zstyle ':completion:*' squeeze-slashes true | |
zstyle ':completion:*' special-dirs .. | |
zstyle ':completion:*' accept-exact-dirs true | |
zstyle ':completion:*' use-ip true | |
zstyle ':completion::*' insert-tab true | |
zstyle ':completion::complete:*' use-cache on | |
zstyle ':completion::complete:*' rehash true | |
zstyle ':completion:*:functions' ignored-patterns '_*' | |
zstyle ':completion:*:*:*:*:processes*' force-list always | |
zstyle ':completion:*:*:kill:*:processes' insert-ids single | |
zstyle ':completion:*:*:kill:*:processes' sort false | |
zstyle ':completion:*:*:kill:*:processes' command 'ps -u "$USER"' | |
zstyle ':completion:*:processes-names' command "ps -eo cmd= | sed 's:\([^ ]*\).*:\1:;s:\(/[^ ]*/\)::;/^\[/d'" | |
zstyle ':completion:*:evince::' \ | |
file-patterns '*.(#i)(dvi|djvu|tiff|pdf|ps|xps)(|.bz2|.gz|.xz|.z) *(-/)' '*' | |
compdef pkill=killall | |
compdef ping6=ping | |
compdef _gnu_generic curl emacs emacsclient file head mv paste | |
compdef _gnu_generic tail touch scrot shred watch wc zsh | |
# Don't complete the same twice for kill/diff. | |
# 25nov2010 +chris+ | |
zstyle ':completion:*:(kill|diff):*' ignore-line yes | |
# Don't complete from PATH for sh and rc. | |
# 27mar2018 +leah+ | |
zstyle ':completion:*:(sh|rc):*' tag-order '! commands builtins' - | |
# Don't complete backup files as commands. | |
# 29sep2012 +chris+ | |
zstyle ':completion:*:complete:-command-::*' ignored-patterns '*\~' | |
# Don't complete .pdf for less. | |
# 09apr2018 +leah+ | |
zstyle ':completion:*:less:*' file-patterns '*~*.pdf' | |
# Lax completion for cd | |
# 23feb2019 +leah+ | |
# 01mar2019 +leah+ fix uppercase completion | |
# 03mar2019 +leah+ use explicit tag-order | |
zstyle ':completion:*:cd:*' tag-order '*' '*:-case' | |
zstyle ':completion:*-case' matcher 'm:{a-zA-Z0-9}={A-Za-z0-9}' 'l:|=* r:|=*' | |
# Cycle through history completion (M-/, M-,). | |
# 12mar2013 +chris+ | |
zstyle ':completion:history-words:*:history-words' stop yes | |
zstyle ':completion:history-words:*:history-words' list no | |
zstyle ':completion:history-words:*' remove-all-dups yes | |
# == ZLE | |
# Emacs keybindings have been set above. | |
# Disable bracketed paste. | |
# 31aug2015 +chris+ | |
unset zle_bracketed_paste | |
# This is even better than copy-prev-shell-word, can be called repeatedly. | |
# 12mar2013 +chris+ | |
autoload -Uz copy-earlier-word | |
zle -N copy-earlier-word | |
bindkey "^[m" copy-earlier-word | |
# Remove prompt on line paste (cf. last printed char in cnprompt6). | |
# 09mar2013 +chris+ | |
bindkey -s $nbsp '^u' | |
# Shortcut for ' inside ' quoting | |
# 14mar2016 +chris+ | |
bindkey -s "\C-x'" \''\\'\'\' | |
# Expand to two last commands | |
# 09nov2017 +leah+ | |
bindkey -s "\C-x2" '!-2\t ; !-1\t' | |
# Move by physical lines, like gj/gk in vim | |
# 09apr2013 +chris+ | |
_physical_up_line() { zle backward-char -n $COLUMNS } | |
_physical_down_line() { zle forward-char -n $COLUMNS } | |
zle -N physical-up-line _physical_up_line | |
zle -N physical-down-line _physical_down_line | |
bindkey "\e\e[A" physical-up-line | |
bindkey "\e\e[B" physical-down-line | |
# M-DEL should stop at /. | |
# 25mar2007 +chris+ | |
# 28feb2011 +chris+ | |
WORDCHARS="*?_-.[]~&;$%^+" | |
# backward-kill-default-word (with $WORDCHARS from zsh -f and :) | |
# 26jun2012 +chris+ | |
_backward_kill_default_word() { | |
WORDCHARS='*?_-.[]~=/&:;!#$%^(){}<>' zle backward-kill-word | |
} | |
zle -N backward-kill-default-word _backward_kill_default_word | |
bindkey '\e=' backward-kill-default-word # = is next to backspace | |
# transpose-words acts on shell words | |
# 03mar2014 +chris+ | |
autoload -Uz transpose-words-match | |
zstyle ':zle:transpose-words' word-style shell | |
zle -N transpose-words transpose-words-match | |
# History search with globs. | |
# 21sep2011 +chris+ | |
# 05jun2012 +chris+ and keeping the rest of the line | |
# 22apr2016 +chris+ space for * | |
autoload -Uz narrow-to-region | |
_history-incremental-preserving-pattern-search-backward() { | |
local state | |
MARK=CURSOR # magick, else multiple ^R don't work | |
narrow-to-region -p "$LBUFFER${BUFFER:+>>}" -P "${BUFFER:+<<}$RBUFFER" -S state | |
zle end-of-history | |
zle history-incremental-pattern-search-backward | |
narrow-to-region -R state | |
} | |
zle -N _history-incremental-preserving-pattern-search-backward | |
bindkey "^R" _history-incremental-preserving-pattern-search-backward | |
bindkey -M isearch "^R" history-incremental-pattern-search-backward | |
bindkey -M isearch -s ' ' '*' | |
bindkey -M isearch -s ' ' '[[:blank:]]' | |
bindkey "^S" history-incremental-pattern-search-forward | |
# Quote stuff that looks like URLs automatically. | |
# 19jul2008 +chris+ | |
# 02dec2014 +chris+ | |
autoload -U url-quote-magic | |
zstyle ':urlglobber' url-other-schema ftp git gopher http https magnet | |
zstyle ':url-quote-magic:*' url-metas '*?[]^(|)~#=' # dropped { } | |
zle -N self-insert url-quote-magic | |
# Edit command line with $VISUAL. | |
# 26jul2010 +chris+ | |
autoload -z edit-command-line | |
zle -N edit-command-line | |
bindkey "^X^E" edit-command-line | |
# Force file name completion on C-x TAB, Shift-TAB. | |
# 23dec2010 +chris+ | |
# 28may2016 +chris+ also complete words already on the command line | |
autoload -Uz match-words-by-style | |
_args() { | |
local -a ign | |
match-words-by-style | |
[[ -z "$matched_words[3]" ]] && ign=("$matched_words[2]$matched_words[5]") | |
compadd -F ign -- ${(Q)${(z)BUFFER}} | |
} | |
zle -C complete-files complete-word _generic | |
zstyle ':completion:complete-files:*' completer _files _args | |
zstyle ':completion:complete-files:*' force-list always | |
bindkey "^X^I" complete-files | |
bindkey "^[[Z" complete-files | |
# Force menu on C-f. | |
# 29dec2010 +chris+ | |
# 21sep2011 +chris+ | |
# 04jan2013 +chris+ rewritten using menu-select | |
zle -C complete-menu menu-select _generic | |
_complete_menu() { | |
setopt localoptions alwayslastprompt | |
zle complete-menu | |
} | |
zle -N _complete_menu | |
bindkey '^F' _complete_menu | |
bindkey -M menuselect '^F' accept-and-infer-next-history | |
bindkey -M menuselect '/' accept-and-infer-next-history | |
bindkey -M menuselect '^?' undo | |
bindkey -M menuselect ' ' accept-and-hold | |
bindkey -M menuselect '*' history-incremental-search-forward | |
# Move to where the arguments belong. | |
# 24dec2010 +chris+ | |
after-first-word() { | |
zle beginning-of-line | |
zle forward-word | |
} | |
zle -N after-first-word | |
bindkey "^X1" after-first-word | |
# Scroll up in tmux on PageUp. | |
# 14jan2016 +chris+ | |
_tmux_copy_mode() { tmux copy-mode -eu } | |
zle -N _tmux_copy_mode | |
[[ $TMUX_PANE && -n $terminfo[kpp] ]] && bindkey $terminfo[kpp] _tmux_copy_mode | |
# fg editor on ^Z | |
# 27sep2011 +chris+ | |
# 17feb2012 +chris+ | |
foreground-vi() { fg %vi } | |
zle -N foreground-vi | |
bindkey '^Z' foreground-vi | |
# Allow to recover from C-c or failed history expansion (thx Mikachu). | |
# 26may2012 +chris+ | |
_recover_line_or_else() { | |
if [[ -z $BUFFER && $CONTEXT = start && $zsh_eval_context = shfunc | |
&& -n $ZLE_LINE_ABORTED | |
&& $ZLE_LINE_ABORTED != $history[$((HISTCMD-1))] ]]; then | |
LBUFFER+=$ZLE_LINE_ABORTED | |
unset ZLE_LINE_ABORTED | |
else | |
zle .$WIDGET | |
fi | |
} | |
zle -N up-line-or-history _recover_line_or_else | |
_zle_line_finish() { ZLE_LINE_ABORTED=$BUFFER } | |
zle -N zle-line-finish _zle_line_finish | |
# Inject mkdir call to create the dirname of the current argument. | |
# 10mar2015 +chris+ | |
autoload -Uz modify-current-argument | |
_mkdir_arg() { | |
local arg= | |
modify-current-argument '${arg:=$ARG}' | |
zle push-line | |
LBUFFER=" mkdir -p $arg:h" | |
RBUFFER= | |
} | |
zle -N mkdir-arg _mkdir_arg | |
bindkey '^[M' mkdir-arg | |
# Keep an archive of all commands typed. | |
# Initialize using: | |
# cat /data/dump/juno/2015<->/home/chris/.zsh_history | sort -u | grep '^:' | | |
# gawk -F: '{print $0 >> "chris@juno-" strftime("%Y-%m-%d", $2)}' | |
# 04sep2015 +chris+ | |
# 02sep2016 +chris+ store directory | |
# 01sep2019 +leah+ create dir if needed | |
[ -d ~/.zarchive ] || mkdir -p ~/.zarchive | |
zshaddhistory() { | |
local words=( ${(z)1} ) | |
local w1=$words[1] | |
(( $+aliases[$w1] )) && w1=$aliases[$w1] | |
if [[ -n $1 && $1 != $'\n' && $w1 != " "* ]]; then | |
printf ': %s:%s:0;%s' ${(%):-'%D{%s}'} ${(%):-%~} "$1" >> \ | |
~/.zarchive/${(%):-%n@%m-'%D{%Y-%m-%d}'} | |
fi | |
} | |
# za WORDS... - search .zarchive for WORDS | |
# 04sep2015 +chris+ | |
za() { | |
grep -a -r -e "${(j:.*:)@}" ~/.zarchive | | |
sed 's/[ \t]*$//' | | |
sort -r | sort -t';' -k2 -u | sort | | |
sed $'s,^[^:]*/,,; s,::[^;]*;,\u00A0\u00A0,' | |
} | |
alias za=' za' | |
# zd [WORDS...] - list last commands in PWD from .zarchive | |
# 02sep2016 +chris+ | |
zd() { | |
grep -a -r -e :${(%):-%~}: ~/.zarchive | | |
sed 's/[ \t]*$//' | | |
sort -r | sort -t';' -k2 -u | sort | | |
awk -F: -v dir=${(%):-%~} '$4 == dir && $5 ~ /^0;/' | | |
sed $'s,^[^:]*/,,; s,::[^;]*;,\u00A0\u00A0,' | |
} | |
alias zd=' zd' | |
# == ALIASES | |
alias hsitory='history' | |
alias hh='history' | |
alias mtr='mtr -t' | |
alias packer='COLOR=NO packer' | |
alias ping6='ping -6' | |
alias sort='LC_ALL=C sort' | |
(( $+commands[vim] )) && alias vi='vim' | |
alias texclean='rm -f *.toc *.aux *.log *.cp *.fn *.tp *.vr *.pg *.ky *.synctex.gz' | |
alias em='emacsclient -n' | |
alias dotf='ls .[a-zA-Z0-9_]*' | |
alias vil='vi *(.om[1]^D)' | |
alias cad='cat >/dev/null' | |
alias d.='df -h . |sed 1d' | |
alias s.='du -sh .' | |
alias pst='ps -o tname,user,bsdtime,pid,cmd -H' | |
alias exzsh='zsh -is eval \ zsh --version\; echo \$ZSH_PATCHLEVEL\; PS1="%#\ "' | |
alias zat='zathura --fork' | |
for cmd (coqtop ocaml MathKernel maxima k q ${(Mk)commands:#k[67-]*}) | |
(( $+commands[$cmd] )) && alias $cmd="rlwrap $cmd" | |
autoload zmv | |
alias zzmv='noglob zmv -W' | |
# 29feb2008 +chris+ | |
# 13apr2010 +chris+ allow completion | |
# 18dec2012 +chris+ set work tree too | |
alias homegit="GIT_DIR=~/prj/dotfiles/.git GIT_WORK_TREE=~ git" | |
hash -d mess=~/mess/current | |
hash -d uni=~/uni/current | |
hash -d phd=~/phd/current | |
hash -d [email protected]:/srv/http/chneukirchen.org/tmp | |
# == FUNCTIONS | |
# j -- search jobs | |
# 15oct2017 +leah+ convert from alias | |
j() { jobs -l | grep ${@:-.} || echo no jobs running } | |
# mess -- switch to current mess folder, creating it if needed | |
# 17may2008 +chris+ | |
mess phd () { | |
set +e | |
DIR=~/$0/$(date +%G/%V) | |
[[ -d $DIR ]] || { | |
mkdir -p $DIR | |
ln -sfn $DIR ~/$0/current | |
echo "Created $DIR." | |
} | |
cd ~/$0/current | |
} | |
# preserve cd - | |
# 21feb2011 +chris+ | |
# 12feb2012 +chris+ save full dirstack, adopted from grml | |
# 02feb2013 +chris+ only add $PWD to file, better for multiple shells | |
DIRSTACKSIZE=9 | |
DIRSTACKFILE=~/.zdirs | |
touch $DIRSTACKFILE | |
if [[ $#dirstack -eq 0 ]]; then | |
dirstack=( ${(f)"$(< $DIRSTACKFILE)"} ) | |
[[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD | |
fi | |
chpwd_dirstack() { | |
local -a dirs; dirs=( "$PWD" ${(f)"$(< $DIRSTACKFILE)"} ) | |
print -l ${${(u)dirs}[0,$DIRSTACKSIZE]} >$DIRSTACKFILE | |
} | |
# img -- display given or all images with the currently preferred viewer | |
# 01jun2010 +chris+ | |
# 01apr2013 +chris+ back to feh | |
# 15sep2013 +chris+ back to qiv | |
# 30aug2017 +chris+ try pqiv | |
# img() { qiv -ftuNRi ${*:-.} } | |
img() { pqiv -flni ${*:-.} } | |
# h -- grep history | |
# 08mar2011 +chris+ | |
# 14mar2011 +chris+ | |
# 08dec2011 +chris+ | |
# 19mar2014 +chris+ work without argument | |
h() { fc -l 0 -1 | sed -n "/${1:-.}/s/^ */!/p" | tail -n ${2:-10} } | |
alias h=' h' | |
# sucdo -- su -c like sudo without quotes | |
# 21mar2011 +chris+ | |
# 29mar2016 +chris+ proper quoting | |
sucdo() { su -c "${(j: :)${(q)@}}" } | |
compdef sucdo=sudo | |
# zman -- easier browsing of zsh manpage | |
# 20sep2011 +chris+ | |
# 16mar2015 +chris+ mdocml splits on any space in $PAGER | |
zman() { PAGER="less -g -s +/^\s{7}$1" man zshall } | |
# g -- call grep recursively with useful defaults | |
# 02oct2011 +chris+ | |
# 10jan2012 +chris+ take an directory as possible last argument | |
# 28nov2012 +chris+ use grep -r | |
# 15dec2013 +chris+ use LC_ALL=C for speed and UTF-8 segfaults with -P | |
# 13may2015 +chris+ use directory only when more than two arguments | |
# 22feb2016 +chris+ line-buffered to quicker pipes | |
# 14aug2016 +chris+ same for git-grep | |
# 27sep2016 +chris+ '+ext' to expand to --include=*.ext | |
g() { | |
LC_ALL=C grep \ | |
${${(M)@:#+*}:s/+/--include=*./} \ | |
--exclude "*~" --exclude "*.o" --exclude "tags" \ | |
--exclude-dir .bzr --exclude-dir .git --exclude-dir .hg --exclude-dir .svn \ | |
--exclude-dir _build \ | |
--line-buffered -r -P ${${@:#+*}:?regexp missing} | |
} | |
gg() { | |
local p=$argv[-1] | |
(( ARGC > 1 )) && { git rev-parse -q --verify $p >/dev/null || [ -d $p ] } && | |
argv[-1]=() || p='HEAD' | |
LC_ALL=C git grep -P ${@:?regexp missing} $p | |
} | |
# gl -- find file names in Git | |
# 23sep2016 +chris+ | |
#gl() { | |
# local p=$argv[-1] | |
# (( ARGC > 1 )) && { p=$p/; argv[-1]=(); } || p=':/' | |
# git ls-files --exclude-standard "$p" | egrep "${@:-.}" | |
#} | |
# d -- use g to find a definition (start of line, Go, Ocaml, Ruby, Rust) | |
# 07apr2014 +chris+ | |
# 13may2015 +chris+ | |
# 21jan2017 +leah+ ignore binary | |
# 10feb2018 +leah+ fix #define, better output | |
# 15aug2019 +leah+ revert output | |
d() { | |
g -IHn '(^|(#define|\b(func|let|let rec|class|module|def|fn))\s+)'"$@" | |
} | |
# l -- find file names, recursively | |
# 20jun2012 +chris+ take a directory as possible last argument | |
#l() { | |
# local p=$argv[-1] | |
# [[ -d $p ]] && { argv[-1]=(); } || p='.' | |
# find $p ! -type d | sed 's:^\./::' | egrep "${@:-.}" | |
#} | |
# 02feb2019 +leah+ | |
# L -- l, with fzf | |
L() { | |
local p=$argv[-1] | |
[[ -d $p ]] && { argv[-1]=(); } || p='.' | |
lr -0 -t 'type != d' $p | sed -z 's:^\./::' | | |
fzf --read0 -0 +s -e ${@:+-q "${@:-.} "} | |
} | |
# v - vim -q from stdin | |
# 14aug2019 +leah+ use quickfix | |
# 15aug2019 +leah+ | |
v qvim() { | |
vim --cmd "set efm=%f:%l:%c:%m,%f:%l:%m,%f:%s,%f" \ | |
-q <(if (( $# )); then printf '%s\n' "$@"; else cat; fi) </dev/tty | |
} | |
# oldv -- browse list of file names (stdin or arglist) with vim | |
# 14jul2015 +chris+ | |
oldv() {{ | |
tput smcup | |
{ [[ $# = 0 ]] && cat || print -l -- "$@" } | | |
vim - '+set nomod | map <buffer><C-M> <C-W>F<C-W>_' \ | |
'+silent g/\%^\%$/cq!' # quit on empty file | |
} always { | |
tput rmcup | |
}} | |
# this didnt understand file:line: | |
# vim - '+set nomod | map <buffer><C-M> :1000sp <cfile><C-M>' | |
# vl -- browse l with vim/v | |
# 25mar2015 +chris+ | |
# 14jul2015 +chris+ | |
# 14aug2019 +leah+ | |
vl() { l "$@" | sort | oldv } | |
# lr -- a saner ls -R (using find) | |
# 07jun2013 +chris+ | |
# 24oct2015 +chris+ prefer native implementation | |
(( $+commands[lr] )) || | |
lr() { | |
zparseopts -D -E S=S t=t r=r h=h U=U l=l F=F d=d | |
local sort="sort -t/ -k2" # by name (default) | |
local numfmt="cat" | |
local long='s:[^/]* /::; s:^\./\(.\):\1:;' # strip detail | |
local classify='' | |
[[ -n $F ]] && classify='/^d/s:$:/:; /^-[^ ]*x/s:$:*:;' # dir/ binary* | |
[[ -n $l ]] && long='s: /\(\./\)\?: :;' # show detail | |
[[ -n $S ]] && sort="sort -n -k5" # by size | |
[[ -n $r ]] && sort+=" -r" # reverse | |
[[ -n $t ]] && sort="sort -k6" && { [[ -n $r ]] || sort+=" -r" } # by date | |
[[ -n $U ]] && sort=cat # no sort, live output | |
[[ -n $h ]] && numfmt="numfmt --field=5 --to=iec --padding=6" # human fmt | |
[[ -n $d ]] && set -- "$@" -prune # don't enter dirs | |
find "$@" -printf "%M %2n %u %g %9s %TY-%Tm-%Td %TH:%TM /%p -> %l\n" | | |
$=sort | $=numfmt | | |
sed '/^[^l]/s/ -> $//; '$long' '$classify | |
} | |
alias lr='lr -FGHP' | |
# alias L='lr -FGHPl' | |
(( $+commands[lr] )) && alias l1='lr -FGHPl1' || | |
l1() { lr -Fl "$@" -maxdepth 1; } | |
(( $+commands[lr] )) && | |
lc() { | |
lr -AFGH1s -t '!type == d || depth > 0' "$@" |git column --mode=dense --pad=2 | |
} | |
# lwho - utmp-free replacement for who(1) | |
(( $+commands[lr] )) && lwho() { | |
lr -om -t 'name =~ "[0-9][0-9]*$" && uid != 0' \ | |
-f '%u\t%p\t%CF %CR\n' /dev/pts /dev/tty* | |
} | |
# imv -- interactive rename, using vared | |
# 03sep2012 +chris+ | |
# 21jul2014 +chris+ | |
# 09dec2014 +chris+ | |
# 24jul2019 +leah+ | |
imv() { | |
local src dst | |
for src; do | |
[[ -e $src ]] || { print -u2 "$src does not exist"; continue } | |
dst=$src | |
vared -f undefined-key dst | |
[[ $src != $dst ]] && mkdir -p $dst:h && mv -n $src $dst && | |
print -s mv -n $src:q:q $dst:q:q # save to history, thus M-. works | |
done | |
} | |
# ichmod -- interactive mode change, using vared | |
# 24jul2019 +leah+ | |
ichmod() { | |
local file perm oldperm map stat; integer special | |
typeset -A map=( --- 0 --x 1 -w- 2 -wx 3 r-- 4 r-x 5 rw- 6 rwx 7 ) | |
for file; do | |
zstat -H stat -s $file || continue | |
perm=$stat[mode] | |
oldperm=$perm | |
vared -i beginning-of-line -f undefined-key perm | |
[[ $perm = $oldperm ]] && continue | |
[[ $perm[1] = $oldperm[1] ]] || { print -u2 "can't change file type of $file"; continue } | |
special=0 | |
[[ $perm[4] = [sS] ]] && special+=4 | |
[[ $perm[7] = [sS] ]] && special+=2 | |
[[ $perm[10] = [tT] ]] && special+=1 | |
perm=${perm//[st]/x} | |
perm=${perm//[ST]/-} | |
chmod -v $special$map[$perm[2,4]]$map[$perm[5,7]]$map[$perm[8,10]] $file | |
done | |
} | |
# hl -- highlight regexps | |
# 06sep2012 +chris+ | |
#hl() { egrep --color=always -e '' -e${^*} } | |
# jpid -- map job ids to pids | |
# 23dec2012 +chris+ | |
jpid() { | |
local p | |
# $jobstates uses jobs.c:getjob() and can do %1 or %foo as well. | |
for id; p+=(${${${jobstates[$id]}#*:*:}%=*}) | |
print $p | |
} | |
# px -- verbose pgrep | |
# 17aug2016 +chris+ reformat VSZ,RSS, print elapsed | |
px() { | |
# ps uwwp ${$(pgrep -d, "${(j:|:)@}"):?no matches} | |
ps wwp ${$(pgrep -d, "${(j:|:)@}"):?no matches} \ | |
-o pid,user:6,%cpu,%mem,vsz:10,rss:10,bsdstart,etime:12,bsdtime,args | | |
sed '1s/ \(VSZ\|RSS\)/\1/g' | | |
numfmt --header --field 5,6 --from-unit=1024 --to=iec --format "%5f" | |
} | |
# crun -- compile and run .c program | |
# 24oct2017 +leah+ fix for different dirs than . | |
crun() { | |
local cprog=$1; shift | |
local n=$@[(i)--] | |
${CC:-cc} -o ${cprog%.*} $cprog $@[1,n-1] && ${${cprog%.*}:a} $@[n+1,-1] | |
} | |
# tracing -- run zsh function with tracing | |
# 16mar2016 +chris+ keep return code | |
tracing() { | |
local f=$1; shift | |
functions -t $f | |
$f "$@" | |
local r=$? | |
functions +t $f | |
return $r | |
} | |
# up [|N|pat] -- go up 1, N or until basename matches pat many directories | |
# just output directory when not used interactively, e.g. in backticks | |
# 06sep2013 +chris+ | |
# 11oct2017 +leah+ add completion | |
up() { | |
local op=print | |
[[ -t 1 ]] && op=cd | |
case "$1" in | |
'') up 1;; | |
-*|+*) $op ~$1;; | |
<->) $op $(printf '../%.0s' {1..$1});; | |
*) local -a seg; seg=(${(s:/:)PWD%/*}) | |
local n=${(j:/:)seg[1,(I)$1*]} | |
if [[ -n $n ]]; then | |
$op /$n | |
else | |
print -u2 up: could not find prefix $1 in $PWD | |
return 1 | |
fi | |
esac | |
} | |
_up() { compadd -V segments -- ${(Oas:/:)PWD} } | |
compdef _up up | |
# n -- quickest note taker | |
# 21nov2013 +chris+ | |
n() { [[ $# == 0 ]] && tail ~/.n || echo "$(date +'%F %R'): $*" >>~/.n } | |
alias n=' noglob n' | |
# count - count different lines | |
# 20jul2014 +chris+ zsh function | |
count() { sort "$@" | uniq -c | sort -n } | |
# imgur - post image to imgur.com | |
# 20jul2014 +chris+ zsh function | |
# 01apr2016 +chris+ use api v3 | |
imgur() { | |
curl -H "Authorization: Client-ID 3e7a4deb7ac67da" -F image=@$1 \ | |
https://api.imgur.com/3/upload | sed 's/.*http/http/; s/".*/\n/; s,\\/,/,g' | |
} | |
# keep - poor man's version control, make freshly numbered copies | |
# 20jul2014 +chris+ | |
# 08feb2019 +leah+ err when no arguments are given | |
keep() { | |
local f v | |
[[ $# = 0 ]] && return 255 | |
for f; do | |
f=$f:A | |
v=($f.<->(nOnN[1])) | |
if [[ -n "$v" ]] && cmp $v $f >/dev/null 2>&1; then | |
print -u2 $v not modified | |
else | |
cp -va $f $f.$((${${v:-.0}##*.} + 1)) | |
fi | |
done | |
} | |
# zombies - list all zombies and their parents to kill | |
# 23jul2014 +chris+ zsh function | |
zombies() { | |
ps f -eo state,pid,ppid,comm | awk ' | |
{ cmds[$2] = $NF } | |
/^Z/ { print $(NF-1) "/" $2 " zombie child of " cmds[$3] "/" $3 }' | |
} | |
# zpass - generate random password | |
# 01nov2014 +chris+ | |
# 10mar2017 +leah+ default to length 12 | |
zpass() { | |
LC_ALL=C tr -dc '0-9A-Za-z_@#%*,.:?!~' </dev/urandom | head -c${1:-12} | |
echo | |
} | |
# ltime - start and run time of last commands | |
# 05feb2018 +leah+ use tail -n | |
ltime() { fc -liDI | tail -n ${1:-10} } | |
# gman - format manpage using GNU troff | |
# 10apr2015 +chris+ | |
gman() { | |
( man -w "$@" 2>/dev/null || printf '%s\n' "$@" ) | | |
xargs cat | | |
groff -t -p -I/usr/share/man -Tutf8 -mandoc | less | |
} | |
# hman - format manpage as monospace HTML | |
# 10feb2018 +leah+ | |
hman() { man -T utf8 "$@" | ul | aha } | |
# sslcat HOST:PORT - print SSL certificate and details | |
sslcat() { | |
local cert="$(openssl s_client -connect $1 </dev/null | awk '/^--*BEGIN/,/^--*END/')" | |
printf '%s\n' "$cert" | openssl x509 -in /dev/stdin -text | |
printf '%s\n' "$cert" | openssl x509 -in /dev/stdin -noout -sha1 -fingerprint | |
printf '%s\n' "$cert" | openssl x509 -in /dev/stdin -noout -md5 -fingerprint | |
} | |
# clot - fill screen with garbage, as visual separator | |
# 17aug2015 +chris+ | |
# 11mar2016 +chris+ print seperate lines | |
clot() { | |
head -c $((LINES*COLUMNS)) </dev/urandom | | |
LC_ALL=C tr '\0-\377' ${(l:256::.*o@:)} | | |
fold -w $COLUMNS | |
} | |
# spot - show changes compared to previous line | |
# 03nov2017 +leah+ | |
spot() { | |
awk '{ for (i = 1; i <= length($0); i++) | |
printf("%c", ((l = substr($0, i, 1))!=" " && l!="\t" && | |
substr(p, i, 1)==l ? "." : l)) | |
printf("\n"); p = $0; }' | |
} | |
# suf FILENAME [SUFFIX] - replace or add suffix | |
# 02jan2018 +leah+ | |
suf() { print "${1%.*}${2:+.$2}" } | |
# mdless - read markdown with less | |
mdless() { pandoc -s -f gfm -t man "$@" | man -l } | |
# mcal [MONTH] - show calendar for this year's MONTH | |
# 12dec2017 +leah+ start with Monday | |
mcal() { cal -m "$@" $(date +%Y) } | |
# padd [CMD] - allow to run CMD without being in path | |
typeset -A padds | |
padd() { padds[$1:t]=$1:A; rehash } | |
rehash() { local c p; builtin rehash "$@" && for c p (${(kv)padds}) hash $c=$p } | |
# ghkeys - display github keys | |
# 23jun2017 +leah+ | |
ghkeys() { curl https://github.com/${^@}.keys } | |
# cdate - timestamp in my format | |
# 09jan2016 +chris+ | |
cdate() { print ${(L)${(%):-'%D{%d%b%Y}'}} " +$USER+" } | |
# dottime - a universal convention for conveying time | |
# https://dotti.me/ | |
# 31aug2019 +leah+ | |
dottime() { | |
( export TZ=GMT; print -Pn $'%D{%Y-%m-%dT%H\u00B7%M}' ) | |
print ${${(%):-%D{%z}}%00} | |
} | |
# notty - run command without controlling tty | |
# 29nov2017 +leah+ | |
notty() { s6-cat | setsid -w "$@" | s6-cat } | |
# wrap - wrap long lines using backslashes | |
wrap() { perl -pe 's/.{'$(( ${COLUMNS:-80} - 1))'}/$&\\\n/g' -- "$@" } | |
# meowth - a better cat -vET | |
# 30nov2016 +chris+ | |
meowth() { | |
perl -CO -MEncode -pe ' | |
$e=0; $w=4; eval { $_ = decode("UTF-8", $_, Encode::FB_CROAK) } or $w=2; | |
s/[\x01-\x08\x0E-\x1F\x{80}-\x{FFFFFF}\x80-\xFF]/ | |
sprintf "\x{29fc}%0${w}X\x{29fd}",ord $&/eg; | |
1 while s/\t/"\x{2014}" x ((length($&)*8 - length($`)%8)-1) . "\x{00BB}"/e; | |
s/\x0c$/("\x{22EF}"x78)/eg; | |
y/ \x00\x0b\x0c\r/\x{00B7}\x{2400}\x{240B}\x{240C}\x{240D}/; | |
s/\n$/\x{23CE}\n/ and $e=1; | |
END { $e or print "\x{2205}\n"} | |
' -- "$@" | |
} | |
# kcns NS - change k8s namespace for this shell session | |
# 06jun2019 +leah+ | |
kcns() { | |
: ${KUBECONFIG:=~/.kube/config} | |
KUBECONFIG=${KUBECONFIG#/tmp/.kcns.$$:} | |
kubectl config view --minify -o json | | |
jq '{kind,apiVersion,"contexts": | |
( .contexts[0].context |= . + {"namespace":"'$1'"} ).contexts}' \ | |
>/tmp/.kcns.$$ | |
export KUBECONFIG=/tmp/.kcns.$$:$KUBECONFIG | |
} | |
alias kn='kubectl get nodes' | |
alias kp='kubectl get pods' | |
alias ka='kubectl apply -f' | |
# collect all chpwd_* hooks | |
chpwd_functions=( ${(kM)functions:#chpwd?*} ) | |
# == SITE LOCAL CONFIG | |
[[ -e ~/.zshrc.local ]] && . ~/.zshrc.local || : | |
# Fix for direnv - https://github.com/direnv/direnv/wiki/Python | |
# 27/09/2019 | |
show_virtual_env() { | |
if [[ -n "$VIRTUAL_ENV" && -n "$DIRENV_DIR" ]]; then | |
echo "($(basename $VIRTUAL_ENV))" | |
fi | |
} | |
PS1='$(show_virtual_env)'$PS1 | |
# Hook up direnv | |
# 26/09/2019 andrew | |
eval "$(direnv hook zsh)" | |
#eval "$(direnv hook $0)" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment