zshrc

This is my .zshrc; it will be used in many environments:

Each environment has slightly different setups, which will be tangled to different files according to the function `org-tags-to-filenames’, defined in the previous section.

TODO replace em-world alias with a function accepting arguments

now, the em-world is an alias that only exists in the version of zshrc that I use for root. How do I want to proceed?

TODO have a look at this idea:

Instead of defining a lot of functions in your `.zshrc’, all of which you may not use, it is often better to use the autoload builtin. The idea is, you create a directory where function definitions are stored, declare the names in your `.zshrc’, and tell the shell where to look for them. Whenever you reference a function, the shell will automatically load it into memory.

% mkdir /tmp/funs
% cat >/tmp/funs/yp
ypmatch $1 passwd.byname
^D
% cat >/tmp/funs/cx
chmod +x $*
^D
% FPATH=/tmp/funs
% autoload cx yp
% functions cx yp
undefined cx ()
undefined yp ()
% chmod 755 /tmp/funs/{cx,yp}
% yp egsirer
egsirer:*:3214:35:Emin Gun Sirer:/u/egsirer:/bin/sh
% functions yp
yp () {
        ypmatch $1 passwd.byname
}

Include

First, include a script that sets a number of confidential data (e.g. API keys and such)

source ~/.config/confidential.sh
# This defines a number of env variables:
# ANDROID_A3=xxxx
# ANDROID_BLU=xxx
# ANDROID_IP=xxx.xxx.xxx.xxx

Then, add helper directory to fpath

fpath=(~/clones/zshrc/ $fpath)

KDE helpers

Define a number of KDE helpers.

#!/bin/zsh

function kde-current-activity () {
    qdbus6 org.kde.ActivityManager /ActivityManager/Activities org.kde.ActivityManager.Activities.CurrentActivity
}

function kde-current-activity-name () {
    qdbus6 org.kde.ActivityManager /ActivityManager/Activities org.kde.ActivityManager.Activities.ActivityName `kde-current-activity`
}
local kde_src_basedir="kde/src"
local kde_build_basedir="kde/build"

function kde-cd-build () {
    cd ${PWD/$kde_src_basedir/$kde_build_basedir/}
}

function kde-cd-src () {
    cd ${PWD/$kde_build_basedir/$kde_src_basedir/}
}
function kde-osd-message() {
    qdbus6 org.freedesktop.Notifications /org/kde/osdService org.kde.osdService.showText alert $1
}
source ~/scripts/kde-utils.sh

Do not litter

if [ "$TERM_PROGRAM" = tmux ]; then
    # suppress tmout in tmux
else
    TMOUT=300
fi

Android helpers

These are various helpers to drive my current Android phone when connected to the box.

function run-task () {
    adb -s $ANDROID_CUR shell am broadcast --user 0 -a net.dinglish.tasker.run_task -e task "$1"
}

function android-remote-keyboard()
{
    # should set this up in a tmux session
    adb -s $ANDROID_CUR shell ime set de.onyxbits.remotekeyboard/.RemoteKeyboardService;
    adb -s $ANDROID_CUR forward tcp:6023 tcp:2323;
    sleep 1;
    telnet 127.0.0.1 6023
}
function android-remote-keyboard-wifi()
{
    # should set this up in a tmux session
    adb -s $ANDROID_IP:5555 shell ime set de.onyxbits.remotekeyboard/.RemoteKeyboardService;
    adb -s $ANDROID_IP:5555 forward tcp:6023 tcp:2323;
    sleep 1;
    telnet 127.0.0.1 6023
}

function android-remote-keyboard-blu()
{
    # should set this up in a tmux session
    adb -s $ANDROID_BLU shell ime set de.onyxbits.remotekeyboard/.RemoteKeyboardService;
    adb -s $ANDROID_BLU forward tcp:6028 tcp:2323;
    sleep 1;
    telnet 127.0.0.1 6028
}

function setup-ipwebcam()
{
    adb -s $ANDROID_BLU forward tcp:8097 tcp:8080
    ffmpeg  -i http://localhost:8097/video -map 0:v -pix_fmt yuv420p -f v4l2 /dev/video2
    adb -s $ANDROID_BLU forward --remove tcp:8097
}

function setup-pi-webcam()
{
    ffmpeg  -i http://192.168.0.41:8080/stream/video.mjpeg -map 0:v -pix_fmt yuv420p -f v4l2 /dev/video2
}

This is an autoremote helper

function autoremote () {
    curl "https://autoremotejoaomgcd.appspot.com/sendmessage?key=f8eK0OaZQVk:APA91bEZaciLdVb_c4yv2fNQW-2iSEjJ-2MYZMBokyGhrdLe1AKwt-zxm1C_WKdZ1prBYho8BKqKj4YTR4jzt6LQv9oRjrYrvKiRgs8ghFmnqmOT98qJCFFAsLaxpKyAgZx_M6UuH-Rk&message=$(echo $1 | sed -e 's/ /\%20/g')&password=$(pass autoremote)"
    }

TODO The last bit is really pi material

Misc helpers

function tmux-guard()
{
    if [[ -v TMUX ]]; then
        $@
    else
        echo tmux-guard: ensure you are in a tmux session to run $@
    fi
}
function wttr()
{
    local location=Toronto
    [[ $(tput cols) -le 124 ]] && local narrow=n;
    curl -H "Accept-Language: ${LANG%_*}" wttr.in/"${1:-$location}?T$narrow"
}

BIG FAT WARNING: this needs to specify an actual file as a destination (similar to ln) adding a directory would not work.

function bl()
 {
 mv $1 $2
 ln $2 $1
}

xournal helper

function xou-mk ()
 {
     /home/jacopods/clones/xournalpp/build/xournalpp $1 -p ${1:r}.pdf
 }

konsole helpers

function set-terminal-title() {
    echo -en "\e]2;$@\a"
}

function get-konsole-title() {
    qdbus  "${KONSOLE_DBUS_SERVICE}" "${KONSOLE_DBUS_SESSION}" tabTitleFormat 0
}

function set-konsole-title() {
    qdbus  "${KONSOLE_DBUS_SERVICE}" "${KONSOLE_DBUS_SESSION}" setTabTitleFormat 0 $1
}

function set-konsole-pomo-title() {
    previous_title=$(get-konsole-title)
    set-konsole-title "pomodoro";
}

function restore-konsole-title() {
    set-konsole-title ${previous_title}
}

color helpers

function lunarized-pick()
{
(cd ~/scripts/.lunarized; cat $(find | grep -v "^.$" | sed -e "s+^./++" | fzf))
}

paper-books helpers

function o--generic ()
{
(cd $1; eca "$(find | sed -e "s+^./++" | fzf)")
}

Should we rather use aliases? yes please

function o-books () {
    (o--generic ~/work/books)
}

function o-papers () {
    (o--generic ~/work/papers)
}

function o-offprints () {
    (o--generic ~/work/offprints)
}

shell helpers

This function is a poor-man eselect for configuration files it mv’s filename to filename_ or viceversa

  function uv()
{
    if [[ -f $1 ]]; then
      if [[ ${1:(-1)} == '_' ]]; then
        mv -i $1 ${1%_}
      else
        mv -i $1 $1_
      fi
    else
      echo $0: \'$1\': no such file or directory
      return 1
    fi
}

emacs helpers

Here we take care of setting up the emacs workflow

Emacs aliases for the pi

export EMACS="emacsclient"
export EMACS_DEF_ARGUMENTS="--alternate-editor=emacs"

specialized helper for the daily box

export EMACS="/home/jacopods/.emacs.d/emacsclient-activities"
export EMACS_DEF_ARGUMENTS=""

Define the eca function

# Emacs stuff
 SOLARIZED="true"
 eca()
 {
     if [[ "$SSH_CONNECTION" != '' ]]; then
         EMACS_ARGUMENTS="-t"
     else
         EMACS_ARGUMENTS="-n"
     fi
     $EMACS $EMACS_DEF_ARGUMENTS $EMACS_ARGUMENTS $@
 }

magit

magit() {
    # TODO: add parameter just in case
    eca -e "(magit-status \"$(pwd)\")"
    eca -e "(x-focus-frame nil)"
}
bindkey -s '^X^G' 'magit\n'

mu4e + agenda

function μ() {
    eca -e "(mu4e)"
    eca -e "(x-focus-frame nil)"
}

function agenda() {
    # TODO: add parameter just in case
    eca -e "(org-agenda-list)"
    eca -e "(x-focus-frame nil)"
}

function kill-emacs() {
    eca -e "(kill-emacs)"
}

media helpers

brownian noise

function brown () {
    if [ $# -eq 1 ]; then
        mpv ~/sound/brown.flac -loop=$(($1-1))
    else
        mpv ~/sound/brown.flac
    fi
}

Fuzzy search unreal mods and play for 25 minutes

alias xmp-unreal='(cd ~/tmp/unreal-mods; xmp "$(find . | fzf)" -U 1500)'

oh-my-zsh setup

# Path to your oh-my-zsh configuration.
ZSH=$HOME/.oh-my-zsh

# Set name of the theme to load.
# Look in ~/.oh-my-zsh/themes/
ZSH_THEME="gentoo-wilder"

# Set to this to use case-sensitive completion
CASE_SENSITIVE="true"

# Uncomment this to disable bi-weekly auto-update checks
# DISABLE_AUTO_UPDATE="true"

# Uncomment to change how often before auto-updates occur? (in days)
# export UPDATE_ZSH_DAYS=13

# Uncomment following line if you want to disable colors in ls
# DISABLE_LS_COLORS="true"

# Uncomment following line if you want to disable autosetting terminal title.
DISABLE_AUTO_TITLE="true"

# Uncomment following line if you want to disable command autocorrection
# DISABLE_CORRECTION="true"

# Uncomment following line if you want red dots to be displayed while waiting for completion
# COMPLETION_WAITING_DOTS="true"

# Uncomment following line if you want to disable marking untracked files under
# VCS as dirty. This makes repository status check for large repositories much,
# much faster.

DISABLE_UNTRACKED_FILES_DIRTY="true"

eval `dircolors ~/.dir_colors`

setopt AUTO_PUSHD
setopt PUSHD_MINUS
setopt BASH_AUTO_LIST
setopt RM_STAR_WAIT
setopt HIST_FIND_NO_DUPS
setopt AUTO_NAME_DIRS
setopt CDABLE_VARS
# Uncomment following line if you want to  shown in the command execution time stamp
# in the history command output. The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|
# yyyy-mm-dd
# HIST_STAMPS="mm/dd/yyyy"

# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
plugins=(git colorize wd history-substring-search)

export FZF_WD_BINDKEY="^X^B"

source $ZSH/oh-my-zsh.sh
#source $ZSH/z.sh

if [[ "$TERM" == "dumb" ]]
then
  unsetopt zle
  unsetopt prompt_cr
  unsetopt prompt_subst
  unfunction precmd
  unfunction preexec
  PS1='$ '
fi

# try to use system colors for completion
zstyle ':completion:*' list-colors "${(@s.:.)LS_COLORS}"

# reset default oh-my-zsh matcher-list
zstyle ':completion:*' matcher-list ''

# smart: ignore parent directory when completing ../<TAB>

zstyle ':completion:*:(cd|mv|cp):*' ignore-parents parent pwd
zstyle ':completion:*:(rm|kill|diff):*' ignore-line yes

autoload -U compinit && compinit

# User configuration

export PATH="/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/games/bin:$PATH"

bindkey -s '^[(' '()^B'
bindkey -s '^[{' '{}^B'
# Make ctrl-Backspace work
bindkey "\e[9;5~" backward-delete-word

autoload zmv

This expands … to ../.. and so on. See this post for source and further reference

if is-at-least 5.0.0 && [[ ! $UID -eq 0 ]]; then
    ## http://www.zsh.org/mla/users/2010/msg00769.html
    function rationalize-dot()
    {
        local MATCH # keep the regex match from leaking to the environment
        if [[ $LBUFFER =~ '(^|/| |      |'$'\n''|\||;|&)\.\.$' && ! $LBUFFER = p4* ]]; then
            #if [[ ! $LBUFFER = p4* && $LBUFFER = *.. ]]; then
            LBUFFER+=/..
        else
            zle self-insert
        fi
    }

    zle -N rationalize-dot
    bindkey . rationalize-dot
    bindkey -M isearch . self-insert
fi

TODO editor env variables

This needs to be diff’d among the versions

export EDITOR="$EMACS -n"
export VISUAL=$EDITOR
export GIT_EDITOR=$EMACS
export SUDO_EDITOR=$EMACS

fzf colour options

export FZF_DEFAULT_OPTS="
--color='dark,fg+:red,pointer:red,info:blue,hl:yellow,hl+:yellow'"

git helpers

function git-create-pi-remote () {
    REPO_NAME=$(basename "`pwd`")
    source ~/scripts/git-init-pi4.sh "$REPO_NAME.git"
    git remote add π "[email protected]:repos/$REPO_NAME.git"
}

function git-create-thinkspoon-remote () {
    REPO_NAME=$(basename "`pwd`")
    source ~/scripts/git-init-thinkspoon.sh "$REPO_NAME.git"
    git remote add thinkspoon "[email protected]:repos/$REPO_NAME.git"
}

function git-current-branch () {
    # do I want to give up on revision numbers in detached-head state?
    git rev-parse --abbrev-ref HEAD | grep -v HEAD || \
    git describe --exact-match HEAD 2> /dev/null || \
    git rev-parse HEAD
}

TODO Create a script to add an arbitrary remote

Aliases

## Aliases
alias e="eca"
alias E=sudoedit
alias mpv-pomodoro="mpv --script=~/scripts/mpv/auto-pomodoro.lua"
alias alexa="/home/jacopods/clones/alexa-remote-control/alexa_remote_control.sh"
alias ta="tmux attach"

Aliases specific for daily

alias urxvt="urxvtc"
alias mpv="mpv --no-audio-display"
alias top="urxvt -e htop &"
alias mk="~/scripts/latex-mk $@"
alias neofetch="~/clones/neofetch/neofetch --source ~/clones/neofetch/ascii/gentoo-one --separator ' ▏' --bold off --colors 13 12 5 1 12 12 |  sed -e 's/bree/Bree/g' | sed -e 's/2560x/2560×/'"
alias xou="source /home/jacopods/scripts/setwacom.sh;/home/jacopods/clones/xournalpp/build/xournalpp"
alias xmp="/home/jacopods/clones/xmp-cli/src/xmp"

Aliases for the pi

alias hugo="/snap/bin/hugo"

dnd management

alias with-dnd="~/scripts/dnd-wrapper.py "

This silences the fan:

alias with-power-save="powerprofilesctl launch -p power-saver -r 'quiet operations' "

with-mpc

function with-mpc-fade () {
    ~/scripts/mpc-fade
    $@
    ~/scripts/mpc-fade
}
# Define an alias with a space at the end so that we can chain with
# other non-global aliases ()
alias with-mpc-fade='with-mpc-fade '

Pomodoro aliases

These aliases help setting up termdown to countdown for the pomodoro technique

termdown_bin=/usr/bin/termdown

alias pomo="$termdown_bin 25m -aW -f 3x5 -c 180 -b -q 10 -s $@"
alias heirloom="$termdown_bin -s 37m -aW -f 3x5 -c 300 -b -q 10 $@"
alias pomodorino="$termdown_bin 14m -aW -f 3x5 -c 120 -b -q 10 -s $@"
alias pomodoro=pomo
alias pomo-break="$termdown_bin 5m -aW -f 3x5 -c 60 -b -q 10 $@"
alias pomodorino-break="$termdown_bin 2m30s -aW -f 3x5 -c 45 -b -q 10 $@"

Wrapped pomodoro aliases

Here we wrap the commands in a python script that takes care of setting do not disturb on the KDE notification system

termdown_bin=/usr/bin/termdown
termdown_opts="-aWb -f 3x5 "

pomo_cmd="$termdown_bin $termdown_opts 25m -c 180 -q 10 -s $@"
heirloom_cmd="$termdown_bin $termdown_opts 37m -c 300 -q 10 -s $@"
pomodorino_cmd="$termdown_bin $termdown_opts 14m -c 120 -q 10 -s $@"

pomo_break_cmd="$termdown_bin $termdown_opts 5m -c 60 -q 10 $@"
pomodorino_break_cmd="$termdown_bin 2m30s $termdown_opts -c 45  -q 10 $@"

alias pomo="with-dnd '$pomo_cmd' Pomodoro"
alias pomodoro=pomo
alias heirloom="with-dnd '$heirloom_cmd' Pomodoro"
alias pomodorino="with-dnd '$pomodorino_cmd' Pomodoro"
alias pomo-break="with-dnd '$pomo_break_cmd' Pomodoro"
alias pomodorino-break="with-dnd '$pomodorino_break_cmd' Pomodoro"

Android aliases

alias android-unlock='~/scripts/unlock-android.sh' #$(cat ~/scripts/unlock-android.gpg | gpg 2>/dev/null)'
alias android-kbd="android-remote-keyboard"
alias dock="~/scripts/dock-a3.sh"

Misc helpers

alias K=/home/jacopods/tmp/keymaps/remap-keyboard

EZA_COLORS="xx=0"

alias ls=' eza --no-quotes'
alias sl=' eza --no-quotes' # a frequent typo
alias c=' cd'
alias cd=' cd'

alias o="xdg-open"

alias acroread="env WINEPREFIX=$HOME/.wine32 WINEARCH='win32' wine ~/.wine32/drive_c/Program\ Files/Adobe/Reader\ 11.0/Reader/AcroRd32.exe >/dev/null 2>/dev/null"

function run-silent() {
  "$@" 2>/dev/null
}

alias git-init-coxeter="source ~/scripts/git-init-coxeter.sh"

alias -s pdf='run-silent okular'
alias -s djvu='run-silent okular'
alias -s tex=emacs

alias d.u='ssh dropbox.utoronto "~/dropbox.py"'

alias -g C='| xclip'

Named directories

Add frequently accessed directories to the hash for quicker reference

hash -d papers="/home/jacopods/work/papers"
hash -d books="/home/jacopods/work/books"
hash -d kde="/scratch/src/kde"
hash -d kwin="/scratch/src/kde/kde/workspace/kwin"

Un-colemak bindings

Mitigate muscle memory typos by changing the bindings for the keys t and f in colemak

bindkey  "^t" forward-char
bindkey  "^[t" forward-word

bindkey  "^g" transpose-chars
bindkey  "^[g" transpose-words

Connection warning

ip a | grep nordlynx >>/dev/null && echo → Connected to $fg_bold[magenta]NordVPN$reset_color
true

TODO Rearrange this bit