My .zshrc file

This is my .zshrc file.

# My .zshrc file
#
# Written by Matthew Blissett.
#
# Latest version available from https://matt.blissett.me.uk/linux/zsh/zshrc
#
# Some of this is my own creation, other functions are taken from various
# web sites or mailing lists, including:
# - http://leahneukirchen.org/dotfiles/.zshrc
#
# Last updated 2019-05-12
#
# Released into the public domain.
#

# Skip all this for non-interactive shells
[[ -z "$PS1" ]] && return

# Set prompt
# Exit status indicator in red (if not 0)
# Background job count in yellow (if not 0)
# Date in white, host in magenta, directory in default, prompt character
# Example:
#     1J 23:06:26 ig:~ >
PS1=$'%(?..%B%K{red}[%?]%K{def}%b )%(1j.%b%K{yel}%F{bla}%jJ%F{def}%K{def} .)%F{def}%B%*%b %F{mag}%m:%F{def}%~ %(!.#.>) %F{def}'
#     <------- exit status -------><------- background job count ----------><--- time -->-< host ->-<- dir ->-<------> <----->
# (See 'EXPANSION OF PROMPT SEQUENCES' in zshmisc.)

# Completion system
autoload -Uz compinit
compinit

# Set less options
if [[ -x $(which less 2> /dev/null) ]]; then
    export PAGER="less"
    export LESS="--ignore-case --LONG-PROMPT --QUIET --chop-long-lines -Sm --RAW-CONTROL-CHARS --quit-if-one-screen --no-init"
    export LESSHISTFILE='-'
    if [[ -x $(which lesspipe 2> /dev/null) ]]; then
        LESSOPEN="| lesspipe %s"
        export LESSOPEN
    fi
fi

# Set default editor
if [[ -x $(which emacs 2> /dev/null) ]]; then
    export EDITOR="emacs"
    export USE_EDITOR=$EDITOR
    export VISUAL=$EDITOR
fi

# FAQ 3.10: Why does zsh not work in an Emacs shell mode any more?
# http://zsh.sourceforge.net/FAQ/zshfaq03.html#l26
[[ $EMACS = t ]] && unsetopt zle

# Zsh settings for history
HISTORY_IGNORE="(ls|[bf]g|exit|reset|clear|cd|cd ..|cd..)"
HISTSIZE=25000
HISTFILE=~/.zsh_history
SAVEHIST=100000
setopt INC_APPEND_HISTORY
setopt HIST_IGNORE_ALL_DUPS
setopt HIST_IGNORE_SPACE
setopt HIST_REDUCE_BLANKS
setopt HIST_VERIFY

# nf [-NUM] [COMMENTARY...] -- never forget last N commands
nf() {
  local n=-1
  [[ "$1" = -<-> ]] && n=$1 && shift
  fc -lnt ": %Y-%m-%d %H:%M ${*/\%/%%} ;" $n | tee -a .neverforget
}

# 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'
}

# sprunge FILES... - paste to sprunge.us
# 20jul2014  +chris+  zsh function
sprunge() {
  local f
  if [ $# -lt 2 ]; then
    cat "$@"
  else
    for f; do
      echo "## $f"
      cat "$f"
      echo
    done
  fi | curl -sF 'sprunge=<-' http://sprunge.us | tr -d ' '
}

#http://chneukirchen.org/dotfiles/.zshrc

# Say how long a command took, if it took more than 30 seconds
export REPORTTIME=120

# Update the prompt (i.e. the clock) before executing a command
TRAPDEBUG() {
  case "$WIDGET" in
    zle-line-finish)
      zle reset-prompt
      ;;
    *)
      ;;
  esac
}

# Colour output on Mac OS
export CLICOLOR=1

# Zsh spelling correction options
#setopt CORRECT
#setopt DVORAK

# Prompts for confirmation after 'rm *' etc
# Helps avoid mistakes like 'rm * o' when 'rm *.o' was intended
setopt RM_STAR_WAIT

# Background processes aren't killed on exit of shell
setopt AUTO_CONTINUE

# Don’t write over existing files with >, use >! instead
setopt NOCLOBBER

# Don’t nice background processes
setopt NO_BG_NICE

# Watch other user login/out
watch=notme
export LOGCHECK=60

# Stop at / when deleting
export WORDCHARS='*?_-.[]~=&;!#$%^(){}<>'

# Enable color support of ls
if [[ "$TERM" != "dumb" ]]; then
    if [[ -x `which dircolors 2> /dev/null` ]]; then
        eval `dircolors -b`
        if ls --color &> /dev/null; then
            alias 'ls=ls --color=auto'
        fi
    fi
fi

# Why is the date American even when the locale is en_GB?  Choose ISO form anyway.
export TIME_STYLE="long-iso"

# Commas in ls, du, df output
export BLOCK_SIZE="'1"

# No quoting spaces in newer coreutils
export QUOTING_STYLE=literal

# Short command aliases
alias 'l=ls'
alias 'la=ls -A'
alias 'll=ls -l'
alias 'llh=ls -l --si'
alias 'lq=ls -Q'
alias 'lr=ls -R'
alias 'lrs=ls -lrS'
alias 'lrt=ls -lrt'
alias 'lrta=ls -lrtA'
alias 'lrth=ls -lrth --si'
alias 'lrtha=ls -lrthA --si'
alias 'j=jobs -l'
alias 'kw=kwrite'
alias 'tf=tail -F'
alias 'grep=grep --colour --devices=skip --exclude-dir=.git'
alias 'vnice=nice -n 20 ionice -c 3'
alias 'get_iplayer=get_iplayer --nopurge'
alias 'get-iplayer=get-iplayer --nopurge'
alias "tree=tree -I 'CVS|.git|*~'"
alias 'lo=z loffice'
alias 'idea=z intellij-idea-community'
alias 'synchist=fc -RI'

# Useful KDE integration
alias 'k=kate -u' # -u is reuse existing session if possible
alias 'white=konsoleprofile colors=SolarizedLight'
alias 'black=konsoleprofile colors=Linux'

# These are useful with the Dvorak keyboard layout
alias 'h=ls'
alias 'ha=la'
alias 'hh=ll'
alias 'hhh=llh'
alias 'hq=lq'
alias 'hr=lr'
alias 'hrt=lrt'
alias 'hrs=lrs'

# Play safe!
alias 'rm=rm -i'
alias 'mv=mv -i'
alias 'cp=cp -i'

# For Git
alias 'gk=z gitk --all'
alias 'gs=git status' # (NB overriding GhostScript)
alias 'gd=git diff'
alias 'gg=z git gui'
alias 'git-stashpullpop=git stash && git pull --rebase && git stash pop'
alias 'gl=git log --graph --abbrev-commit --pretty=oneline --decorate'

# For convenience
alias 'aspell=aspell --dont-backup'
alias 'mkdir=mkdir -p'
alias 'cal=ncal -b' # Weeks start on Monday
alias 'dmesg=dmesg --ctime'
alias 'df=df --exclude-type=tmpfs --exclude-type=devtmpfs --exclude-type=squashfs'
alias 'd.=df -h . |sed 1d'
alias 'dus=du -msc * .*(N) | sort -n'
alias 'dus.=du -msc .* | sort -n'
alias 'fcs=(for i in * .*(N); do echo $(find $i -type f | wc -l) "\t$i"; done) | sort -n'
alias 'fcs.=(for i in .*; do echo $(find $i -type f | wc -l) "\t$i"; done) | sort -n'
alias 'last=last -a'
alias 'zap=clear; echo -en "\e[3J"'
alias 'rmedir=rmdir -v **/*(/^F)'
alias 'xmlindent=xmlindent -t -f -nbe'
alias 'psqltsv=psql -X -t -A -F"	"'
alias 'qr=qrencode -t UTF8'

# Typing errors...
alias 'cd..= cd ..'

# Global aliases (expand whatever their position)
#  e.g. find . E L
alias -g :E='2> /dev/null'
alias -g :C='| wc -l'
alias -g :H='| head'
alias -g :L='|& less'
alias -g :S='| sort'
alias -g :SN='| sort -n'
alias -g :T='| tail'
unglobalalias() {
    for i in ':E' ':C' ':H' ':L' ':S' ':SN' ':T'; unalias $i
}

# Log file viewing
lastlogdir=logs
alias taillast='tail -f $lastlogdir/*(om[1])'
alias catlast='< $lastlogdir/*(om[1])'
alias lesslast='less $lastlogdir/*(om[1])'

# Build commands, etc
alias gdoc='docker run --rm -it --user $(id -u):$(id -g) -v $PWD:/documents/ docker.gbif.org/asciidoctor-toolkit build'
alias 'gdoc-continuous'='docker run --rm -it --user $(id -u):$(id -g) -v $PWD:/documents/ docker.gbif.org/asciidoctor-toolkit continuous'
alias hp='docker run -e JEKYLL_ENV=development -e JEKYLL_UID=$(id -u) -e JEKYLL_GID=$(id -g) --rm --volume="$PWD:/srv/jekyll" jekyll/jekyll:4.1.0 bash -c "gem sources --add https://repository.gbif.org/repository/rubygems.org/ && gem sources --remove https://rubygems.org/ && bundle config mirror.https://rubygems.org https://repository.gbif.org/repository/rubygems.org && echo && echo && echo && echo BUILD STARTING: && jekyll build --unpublished --strict-front-matter"'

# Quick TSV/CSV file formatting
tsv() {
    if [[ -t 1 ]]; then
        column --separator $'\t' --table $* | less
    else
        column --separator $'\t' --table $*
    fi
}
tsvn() {
    dir=$(mktemp -d)
    mkfifo $dir/firstline
    cat $* | tee $dir/firstline | \
        (seq -f '%g	' $(head -n 1 $dir/firstline | tr -dc '\t' | awk '{print length+1}') | tr -d '\n' | sed 's/	$/\n/'; \
         cat) \
        | tsv
    rm -Rf $dir
}
csv() {
    # csvtool
    if [[ -t 1 ]]; then
        csvtool readable $* | less
    else
        csvtool readable
    fi
}

# chop - limit lines to terminal size
# 14jun2016  +chris+
chop() { cut -c-${COLUMNS:-80} }

# SSH aliases
alias 'sshb=ssh matt@uc.blissett.me.uk'
alias 'sshstop=ssh -O stop'
alias 'c5g=ssh mblissett@c5gateway-vh.gbif.org'

# SSH to shell[1234].doc.ic.ac.uk at random
sshdoc() {
    ssh mrb04@shell$(($RANDOM % 4 + 1)).doc.ic.ac.uk $*
}

# Remove a known host and its IP from the cache
ssh-knownhosts-remove() {
    ssh-keygen -R $1
    ssh-keygen -R $(dig $1 +short)
    ssh -O stop $1 &> /dev/null
}

ssh-knownhosts-remove-by-line() {
    echo "Not implemented"
    # sed -e '800d' | sponge...?
}

# Automatically background processes (no output to terminal etc)
z () {
    grey='\e[1;30m'
    norm='\e[m'
    outfile=$(mktemp --tmpdir ${1//\//}.XXX)
    echo "$grey$* &> $outfile$norm"
    $* &>! $outfile &!
}
compdef z=sudo

# Aliases to use this
# Use e.g. 'command gv' to avoid
for i in acroread akregator amarok ario audacity chromium darktable dolphin easytag eclipse \
    firefox gimp gpdf gpsprune gv gwenview hugin inkscape kate kmag konqueror ktorrent kwrite \
    libreoffice lobase localc lodraw loffice lomath loffice lowriter \
    okular openscad prusa-gcodeviewer prusa-gcodeviewer-alpha prusa-gcodeviewer-xz prusa-slicer prusa-slicer-alpha \
    qgis see skype skypeforlinux super-slicer thunderbird vlc; do
    alias "$i=z $i"
done

# Quick find
f() {
    echo "find . -iname \"*$1*\""
    find . -iname "*$1*"
}

# Quick regex history search
zh() {
    pattern=^$(echo '(?=.*'${^@}')' | tr -d ' ')
    grep --text ~/.zsh_history --perl-regexp --regexp $pattern
}

# Remap Dvorak-Qwerty quickly
alias 'aoeu=setxkbmap us -option' # (British keyboard layout, no special options)
alias 'asdf=setxkbmap us dvorak -option compose:menu,terminate:ctrl_alt_bksp'

# Change between English and Danish
english() {
    export LANG=en_GB.UTF-8
    export LANGUAGE=en_GB:en
}
danish() {
    export LANG=da_DK.UTF-8
    export LANGUAGE=da_DK:da
}

# Bring emacs to foreground, or else edit last-modified file
e() {
    if [[ -n "$1" ]]; then
        files=( **/*$1*(.) )

        if [[ $#files = 1 ]]; then
            echo Selected $files[1]
            emacs $files[1]
        else
            echo Matched multiple files:
            echo $files
        fi
    else
        jobs emacs && fg emacs || emacs *(.om[1]^D)
    fi
}

# Change terminal title
title() {
    echo -ne "\033]30;$*\007"
}

# Update config files (master copies stored on server)
alias pull-config='(cd ~/.matt-config; git --git-dir=$HOME/.matt-config/.git pull --rebase && . ~/.zshrc)'

pull-config-regularly() {
    if [[ -z "$SSH_CONNECTION" ]]; then
        if after 1 day $HOME/.pull-config-regularly; then
            echo "Pulling config"
            pushd ~/.matt-config
            git pull --rebase
            popd
            touch $HOME/.pull-config-regularly
        fi
    fi
}
pull-config-regularly

# Check dot-files are up-to-date
~/.matt-config/make-links

# Named directories
hash -d config=$HOME/.matt-config
hash -d bin=$HOME/.matt-config/bin
hash -d log=/var/log

# notes — switch to current notes folder, creating it if needed
notes xxx () {
  set +e
  DIR=~/$0/$(date +%G/%V)
  [[ -d $DIR ]] || {
    mkdir -p $DIR
    ln -sfn $DIR ~/$0/current
    echo "Created $DIR."
  }
  cd ~/$0/current
}

# mkcd -- mkdir and cd at once
mkcd() { mkdir -p -- "$1" && cd -- "$1" }
compdef mkcd=mkdir

# When directory is changed set xterm title to host:dir
chpwd() {
    [[ -t 1 ]] || return
    case $TERM in
        sun-cmd) print -Pn "\e]l%~\e\\";;
        *xterm*|rxvt|(dt|k|E)term) print -Pn "\e]2;%m:%~\a";;
    esac
}

# For changing the umask automatically
chpwd () {
    case $PWD in
        $HOME/[Dd]ocuments*)
            if [[ $(umask) -ne 077 ]]; then
                umask 0077
                echo >&2 -e "\033[01;32mumask: private \033[m"
            fi;;
        /nothing)
            if [[ $(umask) -ne 072 ]]; then
                umask 0072
                echo >&2 -e "\033[01;33mumask: other readable \033[m"
            fi;;
        /nothing)
            if [[ $(umask) -ne 002 ]]; then
                umask 0002
                echo >&2 -e "\033[01;35mumask: group writable \033[m"
            fi;;
        *)
            if [[ $(umask) -ne 022 ]]; then
                umask 0022
                echo >&2 -e "\033[01;31mumask: world readable \033[m"
            fi;;
    esac
}
cd . &> /dev/null

for d in ~/GBIF/Workspace ~/Workspace; do
    if [[ -d $d ]]; then
        cdpath=( $d $d/gbif-documents )
        export cdpath
        hash -d Workspace=$d
        # Used below for hostname completion
        workspace=$d
    fi
done

# For quickly plotting data with gnuplot.  Arguments are files for 'plot "" with lines'.
plot () {
    echo -n '(echo set term png; '
    echo -n 'echo -n plot \"'$1'\" with lines; '
    for i in $*[2,$#@]; echo -n 'echo -n , \"'$i'\" with lines; '
    echo 'echo ) | gnuplot | display png:-'

    (
        echo "set term png"
        echo -n plot \"$1\" with lines
        for i in $*[2,$#@]; echo -n "," \"$i\" "with lines"
        ) | gnuplot | display png:-
}
# Persistant gnuplot (can be resized etc)
plotp () {
    echo -n '(echo -n plot \"'$1'\" with lines; '
    for i in $*[2,$#@]; echo -n 'echo -n , \"'$i'\" with lines; '
    echo 'echo ) | gnuplot -persist'

    (
        echo -n plot \"$1\" with lines
        for i in $*[2,$#@]; echo -n "," \"$i\" "with lines"
        echo
        ) | gnuplot -persist
}
#
scatterplot () {
    echo -n '(echo set term png; '
    echo -n 'echo -n plot \"'$1'\" with points; '
    for i in $*[2,$#@]; echo -n 'echo -n , \"'$i'\" with points; '
    echo 'echo ) | gnuplot | display png:-'

    (
        echo "set term png"
        echo -n plot \"$1\" with points
        for i in $*[2,$#@]; echo -n "," \"$i\" "with points"
        ) | gnuplot | display png:-
}

# CD into random directory in PWD
cdrand () {
    all=( *(/) )
    rand=$(( 1 + $RANDOM % $#all ))
    cd $all[$rand]
}

# 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
alias up=' up'

# Rotate a jpeg, losslessly
#jrotate-r () {
#    for i in $*; do
#        exiftran -9 -b -i $i
#    done
#}

# Calculate the difference in whole days between two dates, ignoring timezone changes
datediff () {
    echo $(( ($(date -u -d $1 +%s) - $(date -u -d $2 +%s)) / 86400))
}

# Close Amarok and shut down
bedtime-awake () {
    sleep ${1}m
    qdbus org.kde.amarok /Player StopAfterCurrent > /dev/null
    t=-10
    while [[ $t -lt 600 ]] && \
        qdbus --literal org.kde.amarok /Player GetStatus > /dev/null && \
        qdbus --literal org.kde.amarok /Player GetStatus | grep -vq 2
    do
        ((t = t+10))
        echo -n "\rWaited" $t "seconds"
        sleep 10;
    done
    echo "\rQuitting"
    qdbus org.kde.amarok / Quit
    qdbus org.ktorrent.ktorrent /MainApplication quit &> /dev/null
}

bedtime () {
    bedtime-awake ${1}
    sudo shutdown -h 1
}

untilquit () {
    while c=$(pgrep -c -x ${1}); do echo -n "\r${c} ${1} processes remaining." && sleep 2; done; echo;
}

untilquitsudo () {
    while c=$(pgrep -c -x ${1}); do echo -n "\r${c} ${1} processes remaining." && sleep 2; sudo -v; done; echo;
}

untilquitpid () {
    while kill -0 ${1} &> /dev/null; do echo -n "\rProcess with PID ${1} is still running." && sleep 2; done; echo;
}

untilquitmatch () {
    while c=$(pgrep -c -f ${*}); do echo -n "\r${c} ${1} matching processes remaining." && sleep 2; done; echo;
}

# Quote and separate by commas a list of strings.
# Accepts shell arguments then newline-separated arguments on standard input.
quote () {
    echo -n "("
    had_args=
    for arg in $*; do
        if [[ -n $had_args ]]; then
            echo -n ", "
        fi
        echo -n "'$arg'"
        had_args=1
    done

    if [[ -z $had_args ]]; then
        while IFS='\n' read arg; do
            if [[ -n $had_args ]]; then
                echo -n ", "
            fi
            echo -n "'"${${arg## }%% }"'"
            had_args=1
        done
    fi

    echo ")"

    #echo ${(qq)*}
}

function best() {
    local i
    for i in $*; do
        if [[ -f $i ]]; then
            ls $i
            touch $i.best
        fi
        if [[ -f $i.jpeg ]]; then
            touch $i.jpeg.best
        elif [[ -f $i.jpg ]]; then
            touch $i.jpg.best
        fi
    done
    ls ${^*:r}.*
}

function ignore() {
    local i
    for i in $*; do
        if [[ -f $i ]]; then
            touch $i.ignore
        fi
        if [[ -f $i.jpeg ]]; then
            touch $i.jpeg.ignore
        fi
        if [[ -f $i.jpg ]]; then
            touch $i.jpg.ignore
        fi
        if [[ -f $i.JPG ]]; then
            touch $i.JPG.ignore
        fi
    done
    ls ${^*:r}.*
}

function pano() {
    local i
    for i in $*; do
        if [[ ! $i =~ ".*-.*\.jp?g" ]]; then
            echo "Not a panorama $i (use image)" >&2
            return 1
        fi

        ignore ${(s/-/)i:r}

        if [[ $i =~ ".jpg" ]]; then
            mv $i $i:r.jpeg
        fi
    done
    ls ${^*:r}.*
}

function sound() {
    f=$1:r
    space=' '
    cat >! $f.jpg.comment <
  
  

EOF

    $EDITOR +1:8 $f.jpg.comment
    [[ -e $f.jpg.comment~ ]] && rm -f $f.jpg.comment~
    touch $f.ogg.ignore $f.mp3.ignore $f.flac.ignore
    ls $f.*
}

function comment() {
    f=$1:r
    space=' '
    cat >! $f.jpg.comment <

EOF $EDITOR +1:8 $f.jpg.comment [[ -e $f.jpg.comment~ ]] && rm -f $f.jpg.comment~ ls $f.* } # MySQL prompt export MYSQL_PS1="\R:\m:\s \h.\d> " # export MAVEN_OPTS="-DdownloadSources=true -DdownloadJavadocs=true $MAVEN_OPTS" # Build a GBIF AsciiDoctor document builddoc () { doclang=${1:-en} docker run --rm -it -e PRIMARY_LANGUAGE=$doclang --user $(id -u):$(id -g) -v $PWD:/documents/ gbif/asciidoctor-toolkit } # Print some stuff date +%c #if [[ -x `which fortune 2> /dev/null` ]]; then # echo # fortune -a 2> /dev/null #fi # The following lines were added by compinstall #zstyle ':completion:*' completer _complete _match zstyle ':completion:*' format 'Completing %d' zstyle ':completion:*' glob 0 zstyle ':completion:*' group-name '' zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} zstyle ':completion:*' matcher-list '+m:{a-z}={A-Z} r:|[._-]=** r:|=**' '' '' '+m:{a-z}={A-Z} r:|[._-]=** r:|=**' zstyle ':completion:*' max-errors 1 numeric zstyle ':completion:*' substitute 0 zstyle :compinstall filename "$HOME/.zshrc" # End of lines added by compinstall # Completers for my own scripts zstyle ':completion:*:*:(album-cover|copy-geotag):*' file-patterns '*.(#i)(jp*g|png|tif*)' zstyle ':completion:*:*:photo-sort:*' file-patterns '*(/)' zstyle ':completion:*:*:photo-sort:*' file-sort time compdef untilquit=pkill # Don't complete backup files as commands. zstyle ':completion:*:complete:-command-::*' ignored-patterns '*\~' # Username completion. # Delete old definitions zstyle -d users # For SSH and Rsync, use remote users set in SSH configuration, plus root zstyle ':completion:*:*:(scp|ssh|rsync):*' users root $(awk '$1 == "User" { print $2 }' ~/.ssh/config | sort -u) # For everything else, use non-system users from /etc/passwd, plus root zstyle ':completion:*:*:*:*' users root $(awk -F: '$3 > 1000 && $3 < 65000 { print $1 }' /etc/passwd) # Hostname completion for i in $workspace/Ansible/inventories/*/hosts; do if [[ ! -e $HOME/.hosts-ansible-$i:h:t ]] || [[ $i -nt $HOME/.hosts-ansible-$i:h:t ]]; then eval echo $(cut -d ' ' -f 1 $i | grep -v '=' | grep -h '\.' | sort -u | sed 's/:/../; s/\[/{/; s/\]/}/') \ | tr ' ' '\n' | sort -u >! $HOME/.hosts-ansible-$i:h:t fi done zstyle ':completion:*' hosts $( grep -h '\.' $HOME/.hosts* ) # URL completion. Use URLs from history. zstyle -e ':completion:*:*:urls' urls 'reply=( ${${(f)"$(egrep --only-matching \(ftp\|https\?\)://\[A-Za-z0-9\].\* $HISTFILE)"}%%[# ]*} )' # Quote stuff that looks like URLs automatically. #autoload -U url-quote-magic #zstyle ':urlglobber' url-other-schema ftp git gopher http https magnet #zstyle ':url-quote-magic:*' url-metas '*?[]^(|)~#=' #zle -N self-insert url-quote-magic # File/directory completion, for cd command #zstyle ':completion:*:cd:*' ignored-patterns '(*/)#lost+found' '(*/)#CVS' # and for all commands taking file arguments #zstyle ':completion:*:(all-|)files' ignored-patterns '(|*/)CVS' # Prevent offering a file (process, etc) that's already in the command line. zstyle ':completion:*:(diff|cmp|cp|emacs|kill|rm|scp):*' ignore-line yes # (Use Alt-Comma to do something like "mv abcd.efg abcd.efg.old") # Completion selection by menu for kill zstyle ':completion:*:*:kill:*' menu yes select zstyle ':completion:*:kill:*' force-list always zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd' zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31' # Filename suffixes to ignore during completion (except after rm command) # https://unix.stackexchange.com/questions/693084/how-can-i-make-zsh-globbing-ignore-files-like-ds-store zstyle ':completion::complete:*:*:files' ignored-patterns '*.o' '*.old' '*.bak' '*.retry' '*~' zstyle ':completion::complete:*:*:globbed-files' ignored-patterns '*.o' '*.old' '*.bak' '*.retry' '*~' zstyle ':completion::complete:rm:*:globbed-files' ignored-patterns zstyle ':completion::complete:emacs:*:globbed-files' ignored-patterns '*.o' '*.old' '*.bak' '*.retry' '*~' '*.asis' zstyle '*' single-ignored show # Finenames to prefer/limit during completion zstyle ':completion:*:*:loffice:*' file-patterns '*.(doc|docx|dot|dotx|xls|xlsx|xlt|xltx|odt|ods|csv|tsv|txt):documents *(-/):directories' '%p:all-files' zstyle ':completion:*:*:rmdir:*' file-sort time #[[ -d /web/matt.blissett.me.uk]] && zstyle ':completion:*' local matt.blissett.me.uk /web/matt.blissett.me.uk # CD to never select parent directory zstyle ':completion:*:cd:*' ignore-parents parent pwd ## Use cache # Some functions, like _apt and _dpkg, are very slow. You can use a cache in # order to proxy the list of results (like the list of available debian # packages) zstyle ':completion:*' use-cache on zstyle ':completion:*' cache-path ~/.zsh/cache # Quick ../../.. from https://github.com/blueyed/oh-my-zsh resolve-alias() { # Recursively resolve aliases and echo the command. typeset -a cmd cmd=(${(z)1}) while (( ${+aliases[$cmd[1]]} )) \ && [[ ${aliases[$cmd[1]]} != $cmd ]]; do cmd=(${(z)aliases[${cmd[1]}]}) done echo $cmd } rationalise-dot() { # Auto-expand "..." to "../..", "...." to "../../.." etc. # It skips certain commands (git, tig, p4). # # resolve-alias is defined in a separate function. local MATCH # keep the regex match from leaking to the environment. # Skip pasted text. if (( PENDING > 0 )); then zle self-insert return fi if [[ $LBUFFER =~ '(^|/| | |'$'\n''|\||;|&)\.\.$' ]] \ && ! [[ $(resolve-alias $LBUFFER) =~ '(git|tig|p4)' ]]; then LBUFFER+=/ zle self-insert zle self-insert else zle self-insert fi } zle -N rationalise-dot bindkey . rationalise-dot bindkey -M isearch . self-insert 2>/dev/null autoload zsh/sched # Copys word from earlier in the current command line # or previous line if it was chosen with ^[. etc autoload copy-earlier-word zle -N copy-earlier-word bindkey '^[,' copy-earlier-word # Cycle between positions for ambigous completions autoload cycle-completion-positions zle -N cycle-completion-positions bindkey '^[z' cycle-completion-positions # Increment integer argument autoload incarg zle -N incarg bindkey '^X+' incarg # Write globbed files into command line autoload insert-files zle -N insert-files bindkey '^Xf' insert-files # Play tetris #autoload -U tetris #zle -N tetris #bindkey '^X^T' tetris # xargs but zargs autoload -U zargs # Calculator autoload zcalc # Line editor autoload zed # Renaming with globbing autoload zmv # Add Git functions if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then true # SSH connection else if [[ -d ~/.matt-config/zsh-git/functions ]]; then fpath=($fpath ~/.matt-config/zsh-git/functions) typeset -U fpath setopt promptsubst autoload -U promptinit promptinit prompt wunjo fi fi #if [[ -e ~/.matt-config/zsh-git-prompt/zshrc.sh ]]; then # source ~/.matt-config/zsh-git-prompt/zshrc.sh # RPROMPT='$(git_super_status)' #fi # Git completion, retrieved from https://git.kernel.org/cgit/git/git.git/tree/contrib/completion/git-completion.zsh if [[ -f ~/.matt-config/git-completion.zsh ]]; then fpath=(~/.matt-config/git-completion.zsh $fpath) fi # PRLL, for parallel shell processing if [[ -e ~/.matt-config/prll/prll.sh ]]; then source ~/.matt-config/prll/prll.sh fi # Various reminders of things I forget... # (Mostly useful features that I forget to use) # vared # =ls turns to /bin/ls # =(ls) turns to filename (which contains output of ls) # <(ls) turns to named pipe # ^X* expand word # ^[^_ copy prev word # ^[A accept and hold # echo $name:r not-extension # echo $name:e extension # echo $xx:l lowercase # echo $name:s/foo/bar/ # Quote current line: M-' # Quote region: M-" # Up-case-word: M-u # Down-case-word: M-l # Capitilise word: M-c # kill-region # expand word: ^X* # accept-and-hold: M-a # accept-line-and-down-history: ^O # execute-named-cmd: M-x # push-line: ^Q # run-help: M-h # spelling correction: M-s # echo ${^~path}/*mous* # Add host/domain specific zshrc domainname() { setopt extended_glob local_options hostname -d 2> /dev/null || echo ${$(hostname -f)#[a-z0-9-]##\.} } if [ -f $HOME/.zshrc-$(domainname) ] then . $HOME/.zshrc-$(domainname) fi if [ -f $HOME/.zshrc-$HOST ] then . $HOME/.zshrc-$HOST fi if [ -f $HOME/.zshrc-$(hostname -f) ] then . $HOME/.zshrc-$(hostname -f) fi

Also see these other dotfiles: