filebin() { basePath=/srv/www/files ssh ymir find "${basePath}" -type f -print0 \ | while IFS= read -r -d $'\0' p; do printf "https://f.141.li/%s\n" "${p#${basePath}/}" done } genmail() { local baseName="" local target="" if [[ ${#@} -ge 1 ]]; then target=${1} shift fi if [[ ${#@} -ge 1 ]]; then baseName=$(pwgen ${@}) else baseName=$(pwgen -v -A -0 16 1) fi baseName=$(tr -cd $'[:alnum:]!#$%&*+-/=?^_{|}~.' <<<${baseName}) address=${baseName}@141.li insertAddr() { echo "${baseName} gkleen" | ssh ymir tee -a /srv/mail/spm 1>/dev/null \ } printf "%s\n" ${address} read -q 'cont?Continue [y/N]? ' || return insertAddr } s() { dir=$(pwd) [[ ${#@} -ge 1 ]] && dir=$1 shellFile=$(findNix ${@}) [[ ${#@} -ge 1 ]] && shift typeset -a cmd if [[ -d ${dir}/.nix-gc-roots ]]; then cmd=(persistent-nix-shell ${shellFile} ${S_EXTRA_ARGS} ${@}) else cmd=(nix-shell ${shellFile} ${S_EXTRA_ARGS} ${@}) fi if [[ -n "${S_SYSTEMD}" ]]; then systemd-run --user --slice=development.slice --collect -E PATH=${PATH} -p WorkingDirectory=${dir} -- ${cmd} else ( cd ${dir} exec ${cmd} ) fi } sz() { typeset -a S_EXTRA_ARGS S_EXTRA_ARGS=(--run "env __ETC_ZSHENV_SOURCED=1 zsh") s ${@} } st() { typeset -a S_EXTRA_ARGS S_EXTRA_ARGS=(--run "tmux new-session env __ETC_ZSHENV_SOURCED=1 zsh") s ${@} } stt() { typeset -a S_EXTRA_ARGS S_SYSTEMD=true S_EXTRA_ARGS=(--run "urxvt -e tmux -S .tmux.sock new-session env __ETC_ZSHENV_SOURCED=1 zsh") s ${@} } se() { typeset -a S_EXTRA_ARGS S_SYSTEMD=true S_EXTRA_ARGS=(--run "emacs") s ${@} } findNix() { if [[ $#@ -eq 0 ]]; then findNix $(pwd) elif [[ -f "$1" ]]; then print ${1:a} elif [[ -d "$1" && -f "$1"/shell.nix ]]; then print ${1:a}/shell.nix elif [[ -d "$1" && -f "$1"/default.nix ]]; then print ${1:a}/default.nix elif [[ -d "$1" && "$1" != "/" ]]; then findNix ${1:h} else printf "Traversed directories to ‘/’ and found no shell specification\n" >&2 return 1 fi } dir() { curlArchive=false templateArchive="" repoUrl="" nixShell="" findNix=false dir="" forceShell=false wormhole=false gitWorktree="" notmuchMsg="" quickserve=false while getopts ':t:a:s:Sd:ir:wqg:n:' arg; do case $arg in "t") ;; "a") if [[ ${OPTARG} =~ "://" ]]; then templateArchive=${OPTARG} curlArchive=true else templateArchive=${OPTARG:a} fi ;; "s") nixShell=${OPTARG:a} ;; "S") findNix=true ;; "d") dir=${OPTARG} ;; "i") forceShell=true ;; "r") repoUrl=${OPTARG} ;; "w") wormhole=true ;; "g") gitWorktree=${OPTARG} ;; "n") notmuchMsg=${OPTARG} ;; "q") quickserve=true ;; *) printf "Invalid option: %s\n" $arg >&2; exit 2 ;; esac done shift $((OPTIND - 1)) if [[ -z ${dir} && ${#@} -ge 1 ]]; then dir=${1} shift fi [[ -n ${dir} ]] || return 2; if [[ ! -e ${dir} ]]; then if [[ -z "${gitWorktree}" ]]; then mkdir -vp ${dir} else git -C ${gitWorktree} worktree add ${dir} fi else gitWorktree="" fi ( cd ${dir} export dir; ${findNix} && { nixShell=$(findNix) || return $? } [[ -n ${repoUrl} ]] && git clone -- ${repoUrl} . if [[ -n ${templateArchive} ]]; then ( archiveFile="" cleanup() { [[ -n "${archiveFile}" ]] && rm -fv ${archiveFile} } trap cleanup EXIT if ${curlArchive}; then archiveFile=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t}") curl -L -o ${archiveFile} ${templateArchive} templateArchive=${archiveFile} fi case $(file --brief --mime-type ${templateArchive}) in application/zip) unzip ${templateArchive} ;; *) tar -xvaf ${templateArchive} ;; esac ) fi if [[ -n ${notmuchMsg} ]]; then getMimeTypes() { nix-shell -p mailcap --run "find \${buildInputs} -path '*/etc/mime.types' | head -n 1 | xargs -- cat" } typeset -a messages messages=(${(z)$(notmuch search --output=messages ${notmuchMsg})}) for message (${messages}); do typeset -A notmuchAtts notmuchAtts=() while IFS= read -r -d $'\n' line; do [[ ${line} =~ '(attachment|part)\{ ID: ([0-9]+)' ]] || continue attId=${match[2]} [[ ${line} =~ 'Content-type: multipart/' ]] && continue fName="part_${attId}" [[ ${line} =~ 'Filename: (([^,]|,[^ ])+)' ]] && fName=${match[1]} if [[ ${#messages} -gt 1 ]]; then fName="${message}/${fName}" fi fExt="${fName:e}" [[ -n "${fExt}" ]] && fName="${fName:r}" if [[ -z "${fExt}" && ${line} =~ 'Content-type: (([^,]|,[^ ])+)$' ]]; then fExt=$(getMimeTypes | grep ${match[1]}$'\t' | head -n 1 | awk '{ print $2; }') fi mkdir -p ${fName:h} if [[ -n "${fExt}" ]]; then fName=$(mktemp -p . "${fName}.XXXXXX.${fExt}") else fName=$(mktemp -p . "${fName}.XXXXXX") fi notmuchAtts[${attId}]=${fName} done <<(notmuch show --decrypt=false -- ${message} | tr -d $'\f') for attId fName in ${(kv)notmuchAtts}; do [[ -d ${fName:h} ]] || mkdir -p ${fName:h} printf "#%d → ‘%s’\n" "${attId}" "${fName}" >&2 notmuch show --decrypt=false --part=${attId} -- ${message} | pv -W -D 2 -i 0.1 >${fName} done done fi ${wormhole} && wormhole receive if ${quickserve}; then quickserve --root . --upload . --show-hidden --tar gz fi if [[ ${#@} -eq 0 ]] || ${forceShell}; then if [[ ${#@} -gt 0 ]]; then if [[ -z ${nixShell} ]]; then ${@} else nix-shell ${nixShell} --run "${@}" fi fi cd $(pwd) # Needed for mounting to work isSingleDir() { typeset -a contents contents=(*(N) .*(N)) if [[ ${#contents} -eq 1 && -d ${contents[1]} ]]; then print ${contents[1]} return 0 else return 1 fi } while d=$(isSingleDir); do cd ${d}; done if [[ -z ${nixShell} ]]; then exec -- zsh else exec -- nix-shell ${nixShell} --run zsh fi else if [[ -z ${nixShell} ]]; then exec -- ${@} else exec -- nix-shell ${nixShell} --run "${@}" fi fi ) } tmpdir() { cleanup() { cd / unmount() { printf "Unmounting %s\n" ${1} >&2 fusermount -u ${1} || umount ${1} || sudo umount ${1} } if mountpoint -q -- ${dir}; then unmount ${dir} || return $? else while read -d $'\0' subDir; do mountpoint -q -- ${subDir} || continue unmount ${subDir} || return $? done <<<$(find ${dir} -xdev -type d -print0 | sort -zr) fi rm -rfv --one-file-system -- ${dir} } local tmpdir="" while getopts ':t:a:s:Sd:ir:wqg:n:' arg; do case $arg in "t") tmpdir="=${OPTARG}" ;; "?"|":") printf "Invalid option: %s\n" $arg >&2; exit 2 ;; esac done ( trap cleanup EXIT local dir=$(mktemp -ud --tmpdir${tmpdir} ${0}.XXXXXXXXXX || return $?) dir -d ${dir} ${@} ) } inhibit-sleep() { if systemctl --user is-active prevent-suspend.service 1>/dev/null; then echo "Allowing suspend" systemctl --user stop prevent-suspend.service else echo "Inhibiting suspend" systemctl --user start prevent-suspend.service fi } qr() { qrencode -l M -o - -t ANSIUTF8 $@ } clock() { tty-clock -sSbc -C 7 -d 0 -a 100000000 } public-ip() { curl -s -H 'Accept: application/json' $@ ifconfig.co | jq -r '.ip' } nix-ghci() { pkgExpr="" if [[ ${#@} -gt 0 ]]; then pkgExpr="${1}" shift fi nix-shell -p "with (import {}); pkgs.haskellPackages.ghcWithPackages (p: with p; [${pkgExpr}])" --run "ghci ${@}" } swap() { f1=${1} f2=${2} if [[ -z "${f1}" || ! -e "${f1}" ]]; then printf "‘%s’ does not exist\n" "${f1}" >&2 return 2 fi if [[ -z "${f2}" || ! -e "${f2}" ]]; then printf "‘%s’ does not exist\n" "${f2}" >&2 return 2 fi tmpfile=$(mktemp --dry-run --tmpdir=${f1:h} .swap.XXXXXXXXXX) mv -v ${f1} ${tmpfile} mv -v ${f2} ${f1} mv -v ${tmpfile} ${f2} } l() { exa --binary --git --time-style=iso --long --all --header --group-directories-first --colour=always $@ | less --mouse -FR } alias '..'='cd ..' alias -g L='| less' alias -g S='&> /dev/null' alias -g G='| grep' alias -g B='&> /dev/null &' alias -g BB='&> /dev/null &!' export DEFAULT_USER=gkleen export EDITOR=emacsclient bindkey -e bindkey ';5C' emacs-forward-word bindkey ';5D' emacs-backward-word