summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Vink <mike@pionative.com>2025-02-08 08:01:18 +0100
committerMike Vink <mike@pionative.com>2025-02-08 08:01:18 +0100
commitfd48011d2ef530b392df72e8685da4e8a2a54d1d (patch)
tree224f1ffa72e6d480871294a2e32015d7e72515ec
copy bin
-rwxr-xr-x.local/bin/checkout69
-rwxr-xr-x.local/bin/compile40
-rwxr-xr-x.local/bin/desktop-open-pipe7
-rwxr-xr-x.local/bin/filter-ansi2
-rwxr-xr-x.local/bin/get-sshables7
-rwxr-xr-x.local/bin/kubeconfig-merge3
-rwxr-xr-x.local/bin/lfub28
-rwxr-xr-x.local/bin/linkhandler37
-rwxr-xr-x.local/bin/macos6
-rwxr-xr-x.local/bin/macosfs2
-rwxr-xr-x.local/bin/mailsync112
-rwxr-xr-x.local/bin/maimpick22
-rwxr-xr-x.local/bin/news5
-rwxr-xr-x.local/bin/nixup94
-rwxr-xr-x.local/bin/notmuch-hook23
-rwxr-xr-x.local/bin/oath2
-rwxr-xr-x.local/bin/openfile10
-rwxr-xr-x.local/bin/pass-ansible-vault-client17
-rwxr-xr-x.local/bin/passmenu30
-rwxr-xr-x.local/bin/pnsh-nvim41
-rwxr-xr-x.local/bin/recordwin9
-rwxr-xr-x.local/bin/rotdir12
-rwxr-xr-x.local/bin/sb-battery37
-rwxr-xr-x.local/bin/sb-clock30
-rwxr-xr-x.local/bin/sb-internet26
-rwxr-xr-x.local/bin/sb-mailbox22
-rwxr-xr-x.local/bin/sb-music19
-rwxr-xr-x.local/bin/sb-nettraf29
-rwxr-xr-x.local/bin/sb-news17
-rwxr-xr-x.local/bin/sb-pomodoro38
-rwxr-xr-x.local/bin/sb-volume39
-rwxr-xr-x.local/bin/setbg19
-rwxr-xr-x.local/bin/showkeybin0 -> 51728 bytes
-rwxr-xr-x.local/bin/spectrwmbar59
-rwxr-xr-x.local/bin/surf-open.sh32
-rwxr-xr-x.local/bin/sysact21
-rwxr-xr-x.local/bin/terragrunt76
-rwxr-xr-x.local/bin/transadd9
-rwxr-xr-x.local/bin/vis-clipboard192
-rwxr-xr-x.local/bin/vremote41
-rwxr-xr-x.local/bin/window11
-rwxr-xr-x.local/bin/xdg-open5
-rwxr-xr-x.local/bin/zshcmd10
43 files changed, 1310 insertions, 0 deletions
diff --git a/.local/bin/checkout b/.local/bin/checkout
new file mode 100755
index 0000000..9619085
--- /dev/null
+++ b/.local/bin/checkout
@@ -0,0 +1,69 @@
+#!/bin/sh
+error () {
+ echo "$1"
+ exit 1
+}
+
+. <(pass show work/env)
+DEST_DIR=""
+case "${@}" in
+ az|"az "*)
+ shift
+ LIST_PROJECTS="/_apis/projects?api-version=7.1-preview.4"
+ AUTH_HEADER="Authorization: Basic $(echo -n ":$GIT_PASS" | base64)"
+ LIST_REPOSITORIES="/_apis/git/repositories?api-version=7.1-preview.1"
+ GIT_DIR="$HOME/projects/"
+ if [ ! -d $GIT_DIR ]; then
+ mkdir -p $GIT_DIR
+ fi
+ MAX_REPOS=20
+
+ echo "curl -s -H \"$AUTH_HEADER\" $WORK_AZDO_GIT_ORG_URL$LIST_PROJECTS"
+ PROJECT=$(curl -s -H "$AUTH_HEADER" $WORK_AZDO_GIT_ORG_URL$LIST_PROJECTS \
+ | jq '
+ .value[].name
+ ' \
+ | xargs -I{} bash -c "
+ curl -s -H '$AUTH_HEADER' $WORK_AZDO_GIT_ORG_URL/{}$LIST_REPOSITORIES \
+ | jq '
+ .value[].name
+ ' \
+ | awk '{ gsub(/\"/, \"\", \$1); printf \"{}/_git/%s\\n\", \$1 }'
+ " \
+ | fzf)
+
+ DEST_DIR="$GIT_DIR/$(echo $PROJECT | cut -d '/' -f3)"
+ if [ ! -d $DEST_DIR ]
+ then
+ git clone --bare $WORK_AZDO_GIT_ORG_URL/$PROJECT $DEST_DIR
+ fi
+ ;;
+ gh|"gh "*)
+ shift
+ repo=$(gh repo list --json owner,name -q '.[] | "\(.owner.login)/\(.name)"' | fzf --print-query -1)
+ GIT_DIR="$HOME/projects"
+ if [ ! -d $GIT_DIR ]; then
+ mkdir -p $GIT_DIR
+ fi
+
+ if [[ "$(echo "$repo" | wc -l)" -ne 1 ]]; then
+ echo "Fetching my repo"
+ repo="$(echo "$repo" | tail -n1)"
+ fi
+
+ DEST_DIR="$GIT_DIR/$(echo $repo | cut -d '/' -f2)"
+ if [ ! -d $DEST_DIR ]
+ then
+ gh repo clone $repo $DEST_DIR -- --bare
+ fi
+ ;;
+ *)
+ error "Don't know how to fetch this"
+ ;;
+esac
+
+if ! [[ -z "$DEST_DIR" ]]; then
+ cd $DEST_DIR
+ git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
+ $EDITOR "$DEST_DIR"
+fi
diff --git a/.local/bin/compile b/.local/bin/compile
new file mode 100755
index 0000000..7208b36
--- /dev/null
+++ b/.local/bin/compile
@@ -0,0 +1,40 @@
+#!/bin/sh
+echo " Compiliiing ${@}"
+
+error () {
+ echo "$1"
+ exit 1
+}
+
+case "${@}" in
+ racket*)
+ shift
+ echo " \-> racket -l errortrace -t ${@}"
+ racket -l errortrace -t ${@}
+ ;;
+ ansible-lint*)
+ shift
+ echo " \-> ansible-lint --profile production --write=all -qq --nocolor"
+ ansible-lint --profile production --write=all -qq --nocolor ${@}
+ ;;
+ ansible-playbook*)
+ shift
+ echo " \-> ansible-playbook -e@<(pass)"
+ ansible-playbook -b -e "{\"ansible_become_pass\":\"$PASSWORD\"}" ${@}
+ ;;
+ awx*)
+ echo " \-> awx"
+ shift
+ awx "$@" | filter-ansi
+ ;;
+ helm\ lint*)
+ shift
+ shift
+ echo " \-> helm lint --set cluster=debug-cluster --strict --quiet --with-subcharts ${@}"
+ helm lint --set cluster=debug-cluster --strict --quiet --with-subcharts ${@} | sed -u -E -e "s@$(basename ${PWD})/|error during tpl function execution for \".*\"@@g"
+ ;;
+ *)
+ echo " \-> ${@}"
+ ${@}
+ ;;
+esac
diff --git a/.local/bin/desktop-open-pipe b/.local/bin/desktop-open-pipe
new file mode 100755
index 0000000..338929d
--- /dev/null
+++ b/.local/bin/desktop-open-pipe
@@ -0,0 +1,7 @@
+#!/usr/bin/env nu
+echo listening for open commands
+loop {
+ let line = nc -l 127.0.0.1 1994
+ echo $line | save --append /tmp/debuglogs
+ try { ^open $line }
+}
diff --git a/.local/bin/filter-ansi b/.local/bin/filter-ansi
new file mode 100755
index 0000000..a45092e
--- /dev/null
+++ b/.local/bin/filter-ansi
@@ -0,0 +1,2 @@
+#!/bin/sh
+cat -u - | sed -u -E -e 's/\x1b\[[0-9;]*[mGKHF]|\r//g'
diff --git a/.local/bin/get-sshables b/.local/bin/get-sshables
new file mode 100755
index 0000000..fa88f7c
--- /dev/null
+++ b/.local/bin/get-sshables
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -euxo pipefail
+[[ -d ~/sshables ]] || mkdir -p ~/sshables
+
+for cluster in $(kubectl config get-clusters | tail -n +2); do
+ [[ -f ~/sshables/$cluster ]] || { echo $cluster; kubectl --context $cluster get nodes -oname > ~/sshables/$cluster; }
+done
diff --git a/.local/bin/kubeconfig-merge b/.local/bin/kubeconfig-merge
new file mode 100755
index 0000000..2567b60
--- /dev/null
+++ b/.local/bin/kubeconfig-merge
@@ -0,0 +1,3 @@
+#!/bin/sh
+cp $HOME/.kube/config /tmp/.kube_config
+KUBECONFIG=$1:/tmp/.kube_config kubectl config view --flatten > $HOME/.kube/config
diff --git a/.local/bin/lfub b/.local/bin/lfub
new file mode 100755
index 0000000..50bae0d
--- /dev/null
+++ b/.local/bin/lfub
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# This is a wrapper script for lb that allows it to create image previews with
+# ueberzug. This works in concert with the lf configuration file and the
+# lf-cleaner script.
+set -e
+
+cleanup() {
+ exec 3>&-
+ rm "$FIFO_UEBERZUG"
+}
+
+if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
+ lf "$@"
+else
+ [ ! -d "$HOME/.cache/lf" ] && mkdir -p "$HOME/.cache/lf"
+ export FIFO_UEBERZUG="$HOME/.cache/lf/ueberzug-$$"
+ mkfifo "$FIFO_UEBERZUG"
+ ueberzug layer -s <"$FIFO_UEBERZUG" -p json &
+ exec 3>"$FIFO_UEBERZUG"
+ sys="$(uname)"
+ if ! [ "$sys" = "Darwin" ]; then
+ trap cleanup HUP INT QUIT TERM PWR EXIT
+ else
+ trap cleanup HUP INT QUIT TERM EXIT
+ fi
+ lf "$@" 3>&-
+fi
diff --git a/.local/bin/linkhandler b/.local/bin/linkhandler
new file mode 100755
index 0000000..4dc1cf3
--- /dev/null
+++ b/.local/bin/linkhandler
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# Feed script a url or file location.
+# If an image, it will view in sxiv,
+# if a video or gif, it will view in mpv
+# if a music file or pdf, it will download,
+# otherwise it opens link in browser.
+
+if command -v pbpaste >/dev/null;
+then
+ paste=pbpaste
+else
+ paste="xclip -o"
+fi
+
+if [ -z $BROWSER ]; then
+ BROWSER=open
+fi
+
+if [ -z "$1" ]; then
+ url="$($paste)"
+else
+ url="$1"
+fi
+
+case "$url" in
+ *mkv|*webm|*mp4|*youtube.com/watch*|*youtube.com/playlist*|*youtube.com/shorts*|*youtu.be*|*hooktube.com*|*bitchute.com*|*videos.lukesmith.xyz*|*odysee.com*)
+ nohup mpv -quiet "$url" >/dev/null 2>&1 ;;
+ *png|*jpg|*jpe|*jpeg|*gif)
+ curl -sL "$url" > "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" && sxiv -a "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" ;;
+ *pdf|*cbz|*cbr)
+ curl -sL "$url" > "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" && zathura "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" ;;
+ *mp3|*flac|*opus|*mp3?source*)
+ qndl "$url" 'curl -LO' ;;
+ *)
+ [ -f "$url" ] && nohup "$TERMINAL" -e "$EDITOR" "$url" >/dev/null 2>&1 || nohup "$BROWSER" "$url"
+esac
diff --git a/.local/bin/macos b/.local/bin/macos
new file mode 100755
index 0000000..ba8e43c
--- /dev/null
+++ b/.local/bin/macos
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+args=""
+if [ -n "$1" ]; then
+ args="$(printf " %q" "${@}")"
+fi
+TERM=xterm-256color ssh -i ~/.ssh/macos mike@192.168.122.75 $args
diff --git a/.local/bin/macosfs b/.local/bin/macosfs
new file mode 100755
index 0000000..02820d2
--- /dev/null
+++ b/.local/bin/macosfs
@@ -0,0 +1,2 @@
+#!/bin/sh
+TERM=xterm-256color nix-shell -p sshfs --run "sshfs -o IdentityFile=$HOME/.ssh/macos $1 mike@192.168.122.75:$2"
diff --git a/.local/bin/mailsync b/.local/bin/mailsync
new file mode 100755
index 0000000..426e5b7
--- /dev/null
+++ b/.local/bin/mailsync
@@ -0,0 +1,112 @@
+#!/bin/sh
+
+# - Syncs mail for all accounts, or a single account given as an argument.
+# - Displays a notification showing the number of new mails.
+# - Displays a notification for each new mail with its subject displayed.
+# - Runs notmuch to index new mail.
+# - This script can be set up as a cron job for automated mail syncing.
+
+# There are many arbitrary and ugly features in this script because it is
+# inherently difficult to pass environmental variables to cronjobs and other
+# issues. It also should at least be compatible with Linux (and maybe BSD) with
+# Xorg and MacOS as well.
+
+# Run only if not already running in other instance
+pgrep mbsync >/dev/null && { echo "mbsync is already running."; exit ;}
+
+# First, we have to get the right variables for the mbsync file, the pass
+# archive, notmuch and the GPG home. This is done by searching common profile
+# files for variable assignments. This is ugly, but there are few options that
+# will work on the maximum number of machines.
+eval "$(grep -h -- \
+ "^\s*\(export \)\?\(MBSYNCRC\|MPOPRC\|PASSWORD_STORE_DIR\|PASSWORD_STORE_GPG_OPTS\|NOTMUCH_CONFIG\|GNUPGHOME\|MAILSYNC_MUTE\|XDG_CONFIG_HOME\|XDG_DATA_HOME\)=" \
+ "$HOME/.profile" "$HOME/.bash_profile" "$HOME/.zprofile" "$HOME/.config/zsh/.zprofile" "$HOME/.zshenv" \
+ "$HOME/.config/zsh/.zshenv" "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.config/zsh/.zshrc" \
+ "$HOME/.pam_environment" 2>/dev/null)"
+
+export GPG_TTY="$(tty)"
+
+[ -n "$MBSYNCRC" ] && alias mbsync="mbsync -c $MBSYNCRC" || MBSYNCRC="$HOME/.mbsyncrc"
+[ -n "$MPOPRC" ] || MPOPRC="$HOME/.config/mpop/config"
+
+lastrun="${XDG_CONFIG_HOME:-$HOME/.config}/neomutt/.mailsynclastrun"
+
+# Settings are different for MacOS (Darwin) systems.
+case "$(uname)" in
+ Darwin) notify() { osascript -e "display notification \"$2\" with title \"$1\"" ;} ;;
+ *)
+ case "$(readlink -f /sbin/init)" in
+ *systemd*|*openrc*) export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus ;;
+ esac
+ # remember if a display server is running since `ps` doesn't always contain a display
+ pgrepoutput="$(pgrep -ax X\(\|org\|wayland\))"
+ displays="$(echo "$pgrepoutput" | grep -wo "[0-9]*:[0-9]\+" | sort -u)"
+ [ -z "$displays" ] && [ -d /tmp/.X11-unix ] && displays=$(cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done)
+
+ notify() { [ -n "$pgrepoutput" ] && for x in ${displays:-:0}; do
+ export DISPLAY="$x"
+ notify-send --app-name="mutt-wizard" "$1" "$2"
+ done ;}
+ ;;
+esac
+
+# Check account for new mail. Notify if there is new content.
+syncandnotify() {
+ case "$1" in
+ imap) mbsync -q "$2" ;;
+ pop) mpop -q "$2" ;;
+ esac
+ new=$(find\
+ "$HOME/.local/share/mail/${2%%-*}/"[Ii][Nn][Bb][Oo][Xx]/new/ \
+ "$HOME/.local/share/mail/${2%%-*}/"[Ii][Nn][Bb][Oo][Xx]/cur/ \
+ -type f -newer "$lastrun" 2> /dev/null)
+ newcount=$(echo "$new" | sed '/^\s*$/d' | wc -l)
+ case 1 in
+ $((newcount > 5)) )
+ echo "$newcount new mail for $2."
+ [ -z "$MAILSYNC_MUTE" ] && notify "New Mail!" "πŸ“¬ $newcount new mail(s) in \`$2\` account."
+ ;;
+ $((newcount > 0)) )
+ echo "$newcount new mail for $2."
+ [ -z "$MAILSYNC_MUTE" ] &&
+ for file in $new; do
+ # Extract and decode subject and sender from mail.
+ subject="$(sed -n "/^Subject:/ s|Subject: *|| p" "$file" |
+ perl -CS -MEncode -ne 'print decode("MIME-Header", $_)')"
+ from="$(sed -n "/^From:/ s|From: *|| p" "$file" |
+ perl -CS -MEncode -ne 'print decode("MIME-Header", $_)')"
+ from="${from% *}" ; from="${from%\"}" ; from="${from#\"}"
+ notify "πŸ“§$from:" "$subject"
+ done
+ ;;
+ *) echo "No new mail for $2." ;;
+esac
+}
+
+allgroups="$(grep -hs "Group" "$MBSYNCRC" "$MPOPRC" | sort -u)"
+
+# Get accounts to sync. All if no argument. Prefix with `error` if non-existent.
+IFS='
+'
+if [ -z "$1" ]; then
+ tosync="$allgroups"
+else
+ tosync="$(for arg in "$@"; do for grp in $allgroups; do
+ [ "$arg" = "${grp##* }" ] && echo "$grp" && break
+ done || echo "error $arg"; done)"
+fi
+
+for grp in $tosync; do
+ case $grp in
+ Group*) syncandnotify imap "${grp##* }" & ;;
+ account*) syncandnotify pop "${grp##* }" & ;;
+ error*) echo "ERROR: Account ${channelt##* } not found." ;;
+ esac
+done
+
+wait
+
+notmuch-hook
+
+#Create a touch file that indicates the time of the last run of mailsync
+touch "$lastrun"
diff --git a/.local/bin/maimpick b/.local/bin/maimpick
new file mode 100755
index 0000000..f2a5f2b
--- /dev/null
+++ b/.local/bin/maimpick
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# This is bound to Shift+PrintScreen by default, requires maim. It lets you
+# choose the kind of screenshot to take, including copying the image or even
+# highlighting an area to copy. scrotcucks on suicidewatch right now.
+
+# variables
+output="$(date '+%y%m%d-%H%M-%S').png"
+clip() {
+ xclip -f -t image/png | xclip -sel c -t image/png
+}
+
+case "$(printf "a selected area\\ncurrent window\\nfull screen\\na selected area (save)\\ncurrent window (save)\\nfull screen (save)" | dmenu -l 6 -i -p "Screenshot which area?")" in
+ "a selected area") maim -u -s | clip ;;
+ "current window")
+ echo "$(xdotool getactivewindow)"
+ maim -q -d 0.2 -i "$(xdotool getactivewindow)" | clip ;;
+ "full screen") maim -q -d 0.2 | clip ;;
+ "a selected area (save)") maim -u -s pic-selected-"${output}" ;;
+ "current window (save)") maim -q -d 0.2 -i "$(xdotool getactivewindow)" pic-window-"${output}" ;;
+ "full screen (save)") maim -q -d 0.2 pic-full-"${output}" ;;
+esac
diff --git a/.local/bin/news b/.local/bin/news
new file mode 100755
index 0000000..7e302b9
--- /dev/null
+++ b/.local/bin/news
@@ -0,0 +1,5 @@
+#!/bin/sh
+cat <(cat ~/.config/newsboat/urls) <(for url in $(env | grep NEWSBOAT_URL_); do
+ printf '%s\n' ${url#NEWSBOAT_URL_*=}
+done) > ~/.newsboat-urls
+newsboat -u ~/.newsboat-urls
diff --git a/.local/bin/nixup b/.local/bin/nixup
new file mode 100755
index 0000000..537f3bb
--- /dev/null
+++ b/.local/bin/nixup
@@ -0,0 +1,94 @@
+#!/bin/sh
+case "${@}" in
+ bootstrap-store)
+ [[ -d ${HOME}/nix ]] || {
+ docker create --name nix-data-${USER} nixos/nix sh >/dev/null 2>&1
+ sudo docker cp nix-data-${USER}:/nix ~
+ docker rm nix-data-${USER}
+ }
+ docker create -v ${HOME}/nix:/nix --name nix-data-${USER} nixos/nix sh
+ ;;
+ nuke)
+ docker rm nix-data-${USER}
+ docker rm nixos-${USER}
+ ;;
+ "")
+ if ! docker image ls | grep nixos-${USER}; then
+ cat > /tmp/docker-build-${USER} <<EOF
+FROM alpine
+
+# Enable HTTPS support in wget and set nsswitch.conf to make resolution work within containers
+RUN apk add --no-cache --update openssl \
+ && echo hosts: files dns > /etc/nsswitch.conf
+
+# Download Nix and install it into the system.
+ARG NIX_VERSION=2.3.14
+RUN wget https://nixos.org/releases/nix/nix-\${NIX_VERSION}/nix-\${NIX_VERSION}-\$(uname -m)-linux.tar.xz \
+ && tar xf nix-\${NIX_VERSION}-\$(uname -m)-linux.tar.xz \
+ && addgroup -g 30000 -S nixbld \
+ && for i in \$(seq 1 30); do adduser -S -D -h /var/empty -g "Nix build user \$i" -u \$((30000 + i)) -G nixbld nixbld\$i ; done \
+ && mkdir -m 0755 /etc/nix \
+ && echo 'sandbox = false' > /etc/nix/nix.conf \
+ && mkdir -m 0755 /nix && USER=root sh nix-\${NIX_VERSION}-\$(uname -m)-linux/install \
+ && ln -s /nix/var/nix/profiles/default/etc/profile.d/nix.sh /etc/profile.d/ \
+ && rm -r /nix-\${NIX_VERSION}-\$(uname -m)-linux* \
+ && /nix/var/nix/profiles/default/bin/nix-collect-garbage --delete-old \
+ && /nix/var/nix/profiles/default/bin/nix-store --optimise \
+ && /nix/var/nix/profiles/default/bin/nix-store --verify --check-contents
+
+# Somehow this file is missing?
+RUN mkdir -p /etc/bash && touch /etc/bash/bashrc
+
+ONBUILD ENV \
+ ENV=/etc/profile \
+ USER=root \
+ PATH=/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
+ GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt \
+ NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
+
+ENV \
+ ENV=/etc/profile \
+ USER=root \
+ PATH=/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
+ GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt \
+ NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
+ NIX_PATH=/nix/var/nix/profiles/per-user/root/channels
+
+# Add your user the alpine way
+RUN apk add --no-cache --update shadow \
+ && groupadd -g $(getent group docker | cut -d: -f3) docker \
+ && groupadd -g $(id -g) ${USER} \
+ && useradd -g $(id -g) --groups wheel,docker -u $(id -u) ${USER} \
+ && rm -rf /var/cache/apk/*
+EOF
+ docker build . -t nixos-${USER} -f /tmp/docker-build-${USER}
+ fi
+ docker run --volumes-from=nix-data-${USER} --rm -it \
+ -v /var/run/docker.sock:/var/run/docker.sock \
+ -v /etc/kube:/etc/kube \
+ -v /etc/ssl/certs/ca-bundle.crt:/etc/ssl/certs/ca-bundle.crt \
+ -v /etc/ssl/certs/ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt \
+ -e GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt \
+ -e NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt \
+ -e SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt \
+ -e no_proxy=$no_proxy \
+ -e http_proxy=$http_proxy \
+ -e https_proxy=$http_proxy \
+ -e SHELL=bash \
+ -e USER=${USER} \
+ -u $(id -u):$(id -g) \
+ --group-add wheel \
+ --group-add docker \
+ -v ${HOME}:${HOME} \
+ -w ${HOME} \
+ --name nixos-${USER} \
+ --network host \
+ nixos-${USER} bash --login
+ ;;
+ clear)
+ docker run --rm --volumes-from=nix-data-${USER} nixos/nix nix-collect-garbage -d
+ ;;
+ list)
+ docker run --rm --volumes-from nix-data-${USER} nixos/nix ls -la /nix
+ ;;
+esac
diff --git a/.local/bin/notmuch-hook b/.local/bin/notmuch-hook
new file mode 100755
index 0000000..8203558
--- /dev/null
+++ b/.local/bin/notmuch-hook
@@ -0,0 +1,23 @@
+notmuch new --quiet
+notmuch tag -new +unread +jobs -- 'tag:new and (from:jobs-listings* or from:jobs-noreply*)'
+notmuch tag -new +unread +dev -- 'tag:new and (from:/.*github.com/ or thread:{from:/.*github.com/})'
+
+# New needs to be removed, otherwise it will re add inbox unread
+notmuch tag -new +inbox +unread -- tag:new
+
+# Gmail + mbsync = a lot of duplicates due to the archive
+notmuch tag -new -inbox +archive -- 'folder:/Archive/ -folder:/Inbox/ -folder:/\[Gmail\]/ -folder:/FarDrafts/ -folder:/Important/ -folder:/Sent/'
+notmuch tag --remove-all +sent -- folder:/Sent/
+notmuch tag --remove-all +drafts -- folder:/Drafts/
+
+# Tag messages with files that were moved to trash in neomutt
+notmuch tag --remove-all +trash -- folder:/Trash/
+
+# Same but with messages with files that were moved to spam
+notmuch tag --remove-all +spam -- folder:/Spam/ or folder:/Junk/
+# Remove files of messages that were tagged but still have files left behind in the mailbox, should be fine since gmail already keeps a duplicate in the Archive so the message will not be deleted only one file of the message
+# TODO(): make this work with non gmail emails too
+# notmuch search --output=files -- 'folder:/Inbox/ -tag:inbox' | grep Inbox | xargs >/dev/null 2>&1 rm
+
+# update dwmblocks mail module
+pkill -RTMIN+12 dwmblocks
diff --git a/.local/bin/oath b/.local/bin/oath
new file mode 100755
index 0000000..0173a2d
--- /dev/null
+++ b/.local/bin/oath
@@ -0,0 +1,2 @@
+#!/bin/sh
+nix-shell -p yubikey-manager --run 'ykman oath accounts code --single Pionative:mike@pionative.com' | xclip -f | xclip -sel c -f
diff --git a/.local/bin/openfile b/.local/bin/openfile
new file mode 100755
index 0000000..0f60b10
--- /dev/null
+++ b/.local/bin/openfile
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# Helps open a file with xdg-open from mutt in a external program without weird side effects.
+tempdir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard/files"
+file="$tempdir/${1##*/}"
+[ "$(uname)" = "Darwin" ] && opener="open" || opener="setsid -f xdg-open"
+mkdir -p "$tempdir"
+cp -f "$1" "$file"
+$opener "$file" >/dev/null 2>&1
+find "${tempdir:?}" -mtime +1 -type f -delete
diff --git a/.local/bin/pass-ansible-vault-client b/.local/bin/pass-ansible-vault-client
new file mode 100755
index 0000000..8d1f9a2
--- /dev/null
+++ b/.local/bin/pass-ansible-vault-client
@@ -0,0 +1,17 @@
+#!/bin/sh
+VAULT_ID=""
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --vault-id)
+ VAULT_ID=$2
+ shift
+ shift
+ ;;
+ --vault-id=*)
+ VAULT_ID="${1#*=}"
+ shift
+ ;;
+ esac
+done
+
+pass show work/ansible-vault/$VAULT_ID
diff --git a/.local/bin/passmenu b/.local/bin/passmenu
new file mode 100755
index 0000000..d323930
--- /dev/null
+++ b/.local/bin/passmenu
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+shopt -s nullglob globstar
+
+dmenu=dmenu
+copy() {
+ xclip -f | xclip -f -sel c
+}
+if [ "$(uname)" = "Darwin" ]; then
+ copy() {
+ pbcopy
+ }
+fi
+
+(
+ export PASSWORD_STORE_DIR="$HOME/sync/password-store"
+ prefix="$PASSWORD_STORE_DIR"
+ echo "prefix: $prefix"
+ password_files=( "$prefix"/**/*.gpg )
+ password_files=( "${password_files[@]#"$prefix"/}" )
+ password_files=( "${password_files[@]%.gpg}" )
+ echo "password_files: ${password_files[*]}"
+
+ password="$(printf '%s\n' "${password_files[@]}" | "$dmenu" "$@")"
+ echo "password: $password"
+
+ [[ -n $password ]] || exit
+
+ pass show "$password" | head -n1 | copy
+) >/tmp/debug 2>&1
+
diff --git a/.local/bin/pnsh-nvim b/.local/bin/pnsh-nvim
new file mode 100755
index 0000000..61bc47c
--- /dev/null
+++ b/.local/bin/pnsh-nvim
@@ -0,0 +1,41 @@
+#!/usr/bin/env nu
+let desktop_open_pipe = $"($env.HOME)/.cache/desktop-open.pipe"
+if not ($desktop_open_pipe | path exists) {
+ mkfifo $desktop_open_pipe
+ bash -c 'nohup desktop-open-pipe &'
+}
+
+let args = (
+"--init" +
+" --entrypoint=/usr/bin/nu" +
+" --env=TERM=xterm-ghostty" +
+$" --env=EDITOR=vis" +
+$" --volume=($env.TERMINFO)/78/xterm-ghostty:/usr/share/terminfo/x/xterm-ghostty" +
+" --env=_ZO_DATA_DIR=/hostfs/.local/share/zoxide" +
+" --volume=/etc/profiles/per-user/ivi/etc/profile.d:/etc/profiles/per-user/ivi/etc/profile.d" +
+" --env=SHELL=/usr/bin/nu" +
+" --env=DISPLAY" +
+" --env=XDG_RUNTIME_DIR" +
+" --volume=/tmp/.X11-unix:/tmp/.X11-unix" +
+$" --volume=($env.HOME)/.ssh/known_hosts:($env.HOME)/.ssh/known_hosts" +
+" --volume=/run/pcscd/pcscd.comm:/run/pcscd/pcscd.comm" +
+$" --hostname=(hostname)" +
+" --env=STARSHIP_CONFIG=/hostfs/.config/starship.toml" +
+" --env=HOME" +
+$" --volume=($env.HOME):($env.HOME)" +
+$" --workdir=($env | default $env.HOME PWD | get PWD)" +
+# " --volume=/nix/store:/nix/store" +
+$" --volume=/nix-config:/nix-config" +
+$" --volume=($env.HOME)/.ssh:/root/.ssh" +
+$" --volume=($env | default "/var/run" XDG_RUNTIME_DIR | get XDG_RUNTIME_DIR)/docker.sock:/var/run/docker.sock" +
+" --net=host"
+)
+
+(
+^pnsh
+ --pnsh-host-bindfs-disabled
+ --pnsh-docker-extra-args=$"($args)"
+ --with-docker
+ --docker-image=pionativedev.azurecr.io/pionative/pnsh-vis
+ --docker-tag=latest
+)
diff --git a/.local/bin/recordwin b/.local/bin/recordwin
new file mode 100755
index 0000000..bb48104
--- /dev/null
+++ b/.local/bin/recordwin
@@ -0,0 +1,9 @@
+#!/bin/sh
+if pidof ffmpeg; then
+ notify-send ffmpeg "killing current recording"
+ pkill --signal=TERM ffmpeg
+else
+ notify-send ffmpeg "Start recording"
+ ffmpeg -f x11grab $(xdotool getwindowfocus getwindowgeometry | tr '\n' ' ' | gawk '{print "-video_size " $8 " -i +"$4 }') -y ~/recording.webm
+ notify-send ffmpeg "saved recording to ~/recording.webm"
+fi
diff --git a/.local/bin/rotdir b/.local/bin/rotdir
new file mode 100755
index 0000000..d171f29
--- /dev/null
+++ b/.local/bin/rotdir
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# When I open an image from the file manager in nsxiv (the image viewer), I want
+# to be able to press the next/previous keys to key through the rest of the
+# images in the same directory. This script "rotates" the content of a
+# directory based on the first chosen file, so that if I open the 15th image,
+# if I press next, it will go to the 16th etc. Autistic, I know, but this is
+# one of the reasons that nsxiv is great for being able to read standard input.
+
+[ -z "$1" ] && echo "usage: rotdir regex 2>&1" && exit 1
+base="$(basename "$1")"
+ls "$PWD" | awk -v BASE="$base" 'BEGIN { lines = ""; m = 0; } { if ($0 == BASE) { m = 1; } } { if (!m) { if (lines) { lines = lines"\n"; } lines = lines""$0; } else { print $0; } } END { print lines; }'
diff --git a/.local/bin/sb-battery b/.local/bin/sb-battery
new file mode 100755
index 0000000..93cbe08
--- /dev/null
+++ b/.local/bin/sb-battery
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# Prints all batteries, their percentage remaining and an emoji corresponding
+# to charge status (πŸ”Œ for plugged up, πŸ”‹ for discharging on battery, etc.).
+
+case $BLOCK_BUTTON in
+ 3) notify-send "πŸ”‹ Battery module" "πŸ”‹: discharging
+πŸ›‘: not charging
+β™»: stagnant charge
+πŸ”Œ: charging
+⚑: charged
+❗: battery very low!
+- Scroll to change adjust xbacklight." ;;
+ 4) xbacklight -inc 10 ;;
+ 5) xbacklight -dec 10 ;;
+ 6) "$TERMINAL" -e "$EDITOR" "$0" ;;
+esac
+
+# Loop through all attached batteries and format the info
+for battery in /sys/class/power_supply/BAT?*; do
+ # If non-first battery, print a space separator.
+ [ -n "${capacity+x}" ] && printf " "
+ # Sets up the status and capacity
+ case "$(cat "$battery/status" 2>&1)" in
+ "Full") status="⚑" ;;
+ "Discharging") status="πŸ”‹" ;;
+ "Charging") status="πŸ”Œ" ;;
+ "Not charging") status="πŸ›‘" ;;
+ "Unknown") status="♻️" ;;
+ *) exit 1 ;;
+ esac
+ capacity="$(cat "$battery/capacity" 2>&1)"
+ # Will make a warn variable if discharging and low
+ [ "$status" = "πŸ”‹" ] && [ "$capacity" -le 25 ] && warn="❗"
+ # Prints the info
+ printf "%s%s%d%%" "$status" "$warn" "$capacity"; unset warn
+done && printf "\\n"
diff --git a/.local/bin/sb-clock b/.local/bin/sb-clock
new file mode 100755
index 0000000..c079a58
--- /dev/null
+++ b/.local/bin/sb-clock
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+clock=$(date '+%I')
+
+case "$clock" in
+ "00") icon="πŸ•›" ;;
+ "01") icon="πŸ•" ;;
+ "02") icon="πŸ•‘" ;;
+ "03") icon="πŸ•’" ;;
+ "04") icon="πŸ•“" ;;
+ "05") icon="πŸ•”" ;;
+ "06") icon="πŸ••" ;;
+ "07") icon="πŸ•–" ;;
+ "08") icon="πŸ•—" ;;
+ "09") icon="πŸ•˜" ;;
+ "10") icon="πŸ•™" ;;
+ "11") icon="πŸ•š" ;;
+ "12") icon="πŸ•›" ;;
+esac
+
+case $BLOCK_BUTTON in
+ 1) notify-send "This Month" "$(cal --color=always | sed "s/..7m/<b><span color=\"cyan\">/;s|..0m|</span></b>|")" && notify-send -t 100000 "$(khal list now 14d -f "{calendar-color} {start-time} {title} {status} {description}
+" | sed "s/..7m/<b><span color=\"cyan\">/;s|..0m|</span></b>|")" ;;
+ 2) setsid -f "$TERMINAL" -e khal interactive ;;
+ 3) notify-send "πŸ“… Time/date module" "\- Left click to show upcoming appointments for the next three days via \`calcurse -d3\` and show the month via \`cal\`
+- Middle click opens calcurse if installed" ;;
+ 6) "$TERMINAL" -e "$EDITOR" "$0" ;;
+esac
+
+date "+%Y %b %d (%a) $icon%I:%M%p"
diff --git a/.local/bin/sb-internet b/.local/bin/sb-internet
new file mode 100755
index 0000000..94b7da2
--- /dev/null
+++ b/.local/bin/sb-internet
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# Show wifi πŸ“Ά and percent strength or πŸ“‘ if none.
+# Show 🌐 if connected to ethernet or ❎ if none.
+# Show πŸ”’ if a vpn connection is active
+
+case $BLOCK_BUTTON in
+ 1) "$TERMINAL" -e nmtui; pkill -RTMIN+4 dwmblocks ;;
+ 3) notify-send "🌐 Internet module" "\- Click to connect
+❌: wifi disabled
+πŸ“‘: no wifi connection
+πŸ“Ά: wifi connection with quality
+❎: no ethernet
+🌐: ethernet working
+πŸ”’: vpn is active
+" ;;
+ 6) "$TERMINAL" -e "$EDITOR" "$0" ;;
+esac
+
+if grep -xq 'up' /sys/class/net/w*/operstate 2>/dev/null ; then
+ wifiicon="$(awk '/^\s*w/ { print "πŸ“Ά", int($3 * 100 / 70) "% " }' /proc/net/wireless)"
+elif grep -xq 'down' /sys/class/net/w*/operstate 2>/dev/null ; then
+ grep -xq '0x1003' /sys/class/net/w*/flags && wifiicon="πŸ“‘ " || wifiicon="❌ "
+fi
+
+printf "%s%s%s\n" "$wifiicon" "$(sed "s/down/❎/;s/up/🌐/" /sys/class/net/e*/operstate 2>/dev/null)" "$(sed "s/.*/πŸ”’/" /sys/class/net/tun*/operstate 2>/dev/null)"
diff --git a/.local/bin/sb-mailbox b/.local/bin/sb-mailbox
new file mode 100755
index 0000000..8fd2d5b
--- /dev/null
+++ b/.local/bin/sb-mailbox
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Displays number of unread mail and an loading icon if updating.
+# When clicked, brings up `neomutt`.
+
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e neomutt ;;
+ 2) setsid -f mailsync >/dev/null ;;
+ 3) notify-send "πŸ“¬ Mail module" "\- Shows unread mail
+- Shows πŸ”ƒ if syncing mail
+- Left click opens neomutt
+- Middle click syncs mail" ;;
+ 6) "$TERMINAL" -e "$EDITOR" "$0" ;;
+esac
+
+# NOTE(): can't figure out why this one doesn't work, emails don't end up in new folder always
+# unread="$(find "${XDG_DATA_HOME:-$HOME/.local/share}"/mail/*/[Ii][Nn][Bb][Oo][Xx]/new/* -type f | wc -l 2>/dev/null)"
+unread="$(notmuch search tag:inbox and tag:unread | wc -l 2>/dev/null)"
+
+pidof mbsync >/dev/null 2>&1 && icon="πŸ”ƒ"
+
+[ "$unread" = "0" ] && [ "$icon" = "" ] || echo "πŸ“¬$unread$icon"
diff --git a/.local/bin/sb-music b/.local/bin/sb-music
new file mode 100755
index 0000000..d164b4b
--- /dev/null
+++ b/.local/bin/sb-music
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+filter() { sed "/^volume:/d;s/\\&/&amp;/g;s/\\[paused\\].*/⏸/g;/\\[playing\\].*/d;/^ERROR/Q" | paste -sd ' ' -;}
+
+pidof -x sb-mpdup >/dev/null 2>&1 || sb-mpdup >/dev/null 2>&1 &
+
+case $BLOCK_BUTTON in
+ 1) mpc status | filter ; setsid -f "$TERMINAL" -e ncmpcpp ;; # right click, pause/unpause
+ 2) mpc toggle | filter ;; # right click, pause/unpause
+ 3) mpc status | filter ; notify-send "🎡 Music module" "\- Shows mpd song playing.
+- ⏸ when paused.
+- Left click opens ncmpcpp.
+- Middle click pauses.
+- Scroll changes track.";; # right click, pause/unpause
+ 4) mpc prev | filter ;; # scroll up, previous
+ 5) mpc next | filter ;; # scroll down, next
+ 6) mpc status | filter ; "$TERMINAL" -e "$EDITOR" "$0" ;;
+ *) mpc status | filter ;;
+esac
diff --git a/.local/bin/sb-nettraf b/.local/bin/sb-nettraf
new file mode 100755
index 0000000..178f677
--- /dev/null
+++ b/.local/bin/sb-nettraf
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# Module showing network traffic. Shows how much data has been received (RX) or
+# transmitted (TX) since the previous time this script ran. So if run every
+# second, gives network traffic per second.
+
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e bmon ;;
+ 3) notify-send "🌐 Network traffic module" "πŸ”»: Traffic received
+πŸ”Ί: Traffic transmitted" ;;
+ 6) "$TERMINAL" -e "$EDITOR" "$0" ;;
+esac
+
+update() {
+ sum=0
+ for arg; do
+ read -r i < "$arg"
+ sum=$(( sum + i ))
+ done
+ cache=/tmp/${1##*/}
+ [ -f "$cache" ] && read -r old < "$cache" || old=0
+ printf %d\\n "$sum" > "$cache"
+ printf %d\\n $(( sum - old ))
+}
+
+rx=$(update /sys/class/net/[ew]*/statistics/rx_bytes)
+tx=$(update /sys/class/net/[ew]*/statistics/tx_bytes)
+
+printf "πŸ”»%4sB πŸ”Ί%4sB\\n" $(numfmt --to=iec $rx $tx)
diff --git a/.local/bin/sb-news b/.local/bin/sb-news
new file mode 100755
index 0000000..fe701db
--- /dev/null
+++ b/.local/bin/sb-news
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# Displays number of unread news items and an loading icon if updating.
+# When clicked, brings up `newsboat`.
+
+case $BLOCK_BUTTON in
+ 1) setsid "$TERMINAL" -e newsboat ;;
+ 2) setsid -f newsup >/dev/null exit ;;
+ 3) notify-send "πŸ“° News module" "\- Shows unread news items
+- Shows πŸ”ƒ if updating with \`newsup\`
+- Left click opens newsboat
+- Middle click syncs RSS feeds
+<b>Note:</b> Only one instance of newsboat (including updates) may be running at a time." ;;
+ 6) "$TERMINAL" -e "$EDITOR" "$0" ;;
+esac
+
+ cat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ if($1>0) print "πŸ“°" $1}')$(cat "${XDG_CONFIG_HOME:-$HOME/.config}"/newsboat/.update 2>/dev/null)"
diff --git a/.local/bin/sb-pomodoro b/.local/bin/sb-pomodoro
new file mode 100755
index 0000000..1eb222a
--- /dev/null
+++ b/.local/bin/sb-pomodoro
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+# Displays current pomodoro status
+# When clicked, brings up `newsboat`.
+
+case $BLOCK_BUTTON in
+ 1) setsid -f pomodoro start >/dev/null ;;
+ 2) setsid -f pomodoro finish >/dev/null ;;
+ 3) notify-send "πŸ… Pomodoro module" "\- Shows current pomodoro status
+- Shows ⏱ if a Pomodoro is running
+- Left click starts a new Pomodoro
+- Middle click finishes a Pomodoro early
+- Shift click opens ~/.pomodoro in editor" ;;
+ 6) "$TERMINAL" -e "$EDITOR" "$HOME/.pomodoro" ;;
+esac
+
+if ! status=$(pomodoro status); then
+ exit 0
+fi
+
+if [ -z "$status" ]; then
+ daily_completed=$(grep -c "^$(date --iso-8601)" ~/.pomodoro/history)
+ daily_total="$(grep daily_goal ~/.pomodoro/settings | cut -f2 -d'=')"
+
+ msg="$daily_completed/$daily_totalπŸ…"
+ if [ "$daily_completed" -ne "0" ]; then
+ seconds_since_last_started="$(( $(date +%s -u) - $(tail -n1 ~/.pomodoro/history | cut -f1 -d' ' | xargs -I{} date -d"{}" +%s -u) ))"
+ seconds_since_last="$(( "$seconds_since_last_started" - 60*$(tail -n1 ~/.pomodoro/history | cut -f2 -d' ' | cut -f2 -d'=')))"
+ if [ "$seconds_since_last" -lt 0 ]; then
+ seconds_since_last=0
+ fi
+ msg="$(date -d@"$seconds_since_last" +"%H:%M" -u)min ago $msg"
+ fi
+ echo "$msg"
+ exit 0
+fi
+
+echo "$status"
diff --git a/.local/bin/sb-volume b/.local/bin/sb-volume
new file mode 100755
index 0000000..e66dea7
--- /dev/null
+++ b/.local/bin/sb-volume
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Prints the current volume or πŸ”‡ if muted.
+
+case $BLOCK_BUTTON in
+ 1) setsid -w -f "$TERMINAL" -e pulsemixer; pkill -RTMIN+10 "${STATUSBAR:-dwmblocks}" ;;
+ 2) wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle ;;
+ 4) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%+ ;;
+ 5) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%- ;;
+ 3) notify-send "πŸ“’ Volume module" "\- Shows volume πŸ”Š, πŸ”‡ if muted.
+- Middle click to mute.
+- Scroll to change." ;;
+ 6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
+esac
+
+vol="$(wpctl get-volume @DEFAULT_AUDIO_SINK@)"
+
+# If muted, print πŸ”‡ and exit.
+[ "$vol" != "${vol%\[MUTED\]}" ] && echo πŸ”‡ && exit
+
+vol="${vol#Volume: }"
+
+split() {
+ # For ommiting the . without calling and external program.
+ IFS=$2
+ set -- $1
+ printf '%s' "$@"
+}
+
+vol="$(printf "%.0f" "$(split "$vol" ".")")"
+
+case 1 in
+ $((vol >= 70)) ) icon="πŸ”Š" ;;
+ $((vol >= 30)) ) icon="πŸ”‰" ;;
+ $((vol >= 1)) ) icon="πŸ”ˆ" ;;
+ * ) echo πŸ”‡ && exit ;;
+esac
+
+echo "$icon$vol%"
diff --git a/.local/bin/setbg b/.local/bin/setbg
new file mode 100755
index 0000000..7f5977d
--- /dev/null
+++ b/.local/bin/setbg
@@ -0,0 +1,19 @@
+#!/bin/sh
+reload=0
+while getopts "r" opt; do
+ case "$opt" in
+ h|\?) exit 0 ;;
+ r) reload=1 ;;
+ esac
+done
+if [ $reload -eq 1 ]; then
+ # (cat ~/.cache/wal/sequences &)
+ wal -R
+else
+ if [ -z "$1" ]; then
+ sxiv -tob ~/Wallpapers | xargs wal -i
+ else
+ wal -i "$1"
+ fi
+ kill -HUP "$(pidof dwm)"
+fi
diff --git a/.local/bin/showkey b/.local/bin/showkey
new file mode 100755
index 0000000..9bb9a3b
--- /dev/null
+++ b/.local/bin/showkey
Binary files differ
diff --git a/.local/bin/spectrwmbar b/.local/bin/spectrwmbar
new file mode 100755
index 0000000..a106b01
--- /dev/null
+++ b/.local/bin/spectrwmbar
@@ -0,0 +1,59 @@
+#!/usr/bin/env sh
+# script for spectrwm status bar
+
+trap 'update' 5
+
+fgcolors=("+@fg=1;" "+@fg=2;" "+@fg=3;" "+@fg=4;" "+@fg=5;" "+@fg=6;" "+@fg=7;" "+@fg=8;")
+nfgcolors=${#fgcolors[@]}
+
+SLEEP_SEC=5m
+
+repeat() {
+ i=0; while [ $i -lt $1 ]
+ do
+ echo -ne "$TOKEN"
+ i=$(( i + 1 ))
+ done
+}
+
+cpu() {
+ read cpu a b c previdle rest < /proc/stat
+ prevtotal=$((a+b+c+previdle))
+ sleep 0.5
+ read cpu a b c idle rest < /proc/stat
+ total=$((a+b+c+idle))
+ cpu=$((100*( (total-prevtotal) - (idle-previdle) ) / (total-prevtotal) ))
+ echo -e "CPU: $cpu%"
+}
+
+battery() {
+ BATTERY="$(cat /sys/class/power_supply/BAT0/capacity)"
+
+ BAR_LEFT=$BATTERY
+ BATTERY_BAR=""
+ BLOCK=$(( 100 / nfgcolors ))
+ TOKEN=$(printf '\u2588')
+
+ BAT_COL=$(( $nfgcolors -1 ))
+ #loops forever outputting a line every SLEEP_SEC secs
+ while [ $(( BAR_LEFT - BLOCK )) -gt 0 ]
+ do
+ BATTERY_BAR="${fgcolors[$BAT_COL]}$(repeat $BLOCK)${BATTERY_BAR}"
+ BAR_LEFT=$(( BAR_LEFT - BLOCK ))
+ BAT_COL=$(( BAT_COL - 1))
+ done
+
+ BATTERY_BAR="BATTERY: ${fgcolors[$BAT_COL]}$(repeat $BAR_LEFT)${BATTERY_BAR}"
+ echo $BATTERY_BAR
+}
+
+update() {
+ echo "$(cpu) $(battery)"
+ wait
+}
+
+while :; do
+ update
+ sleep $SLEEP_SEC &
+ wait
+done
diff --git a/.local/bin/surf-open.sh b/.local/bin/surf-open.sh
new file mode 100755
index 0000000..c22edc2
--- /dev/null
+++ b/.local/bin/surf-open.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# See the LICENSE file for copyright and license details.
+#
+
+xidfile="$HOME/tmp/tabbed-surf.xid"
+uri=""
+
+if [ "$#" -gt 0 ];
+then
+ uri="$1"
+fi
+
+runtabbed() {
+ tabbed -dn tabbed-surf -r 2 surf -e '' "$uri" >"$xidfile" \
+ 2>/dev/null &
+}
+
+if [ ! -r "$xidfile" ];
+then
+ runtabbed
+else
+ xid=$(cat "$xidfile")
+ xprop -id "$xid" >/dev/null 2>&1
+ if [ $? -gt 0 ];
+ then
+ runtabbed
+ else
+ surf -e "$xid" "$uri" >/dev/null 2>&1 &
+ fi
+fi
+
diff --git a/.local/bin/sysact b/.local/bin/sysact
new file mode 100755
index 0000000..4bb92dc
--- /dev/null
+++ b/.local/bin/sysact
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# A dmenu wrapper script for system functions.
+export WM="dwm"
+ctl='systemctl'
+
+wmpid(){ # This function is needed if there are multiple instances of the window manager.
+ echo "$(pidof dwm)"
+}
+
+case "$(printf "πŸ”’ lock\nπŸšͺ leave $WM\n♻️ renew $WM\n🐻 hibernate\nπŸ”ƒ reboot\nπŸ–₯️shutdown\nπŸ’€ sleep\nπŸ“Ί display off" | dmenu -i -p 'Action: ')" in
+ 'πŸ”’ lock') slock ;;
+ "πŸšͺ leave $WM") kill -TERM "$(wmpid)" ;;
+ "♻️ renew $WM") kill -HUP "$(wmpid)" ;;
+ '🐻 hibernate') slock $ctl hibernate -i ;;
+ 'πŸ’€ sleep') slock $ctl suspend -i ;;
+ 'πŸ”ƒ reboot') $ctl reboot -i ;;
+ 'πŸ–₯️shutdown') $ctl poweroff -i ;;
+ 'πŸ“Ί display off') xset dpms force off ;;
+ *) exit 1 ;;
+esac
diff --git a/.local/bin/terragrunt b/.local/bin/terragrunt
new file mode 100755
index 0000000..d0b47f7
--- /dev/null
+++ b/.local/bin/terragrunt
@@ -0,0 +1,76 @@
+#!/bin/sh
+TERRAGRUNT_ARGS=()
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -full)
+ FULL=1
+ shift
+ ;;
+ -p|--path)
+ path="$2"
+ shift
+ shift
+ ;;
+ -p=*|--path=*)
+ path="${1#*=}"
+ shift
+ ;;
+ *|-*)
+ TERRAGRUNT_ARGS+=("$1")
+ shift
+ esac
+done
+
+TTY=""
+case ${TERRAGRUNT_ARGS[0]} in
+ plan)
+ TERRAGRUNT_ARGS+=(-no-color -compact-warnings)
+ ;;
+ apply|destroy)
+ TTY="-t"
+ for arg in $TERRAGRUNT_ARGS; do
+ if [[ $arg -eq "gruntplan" ]]; then
+ TTY=""
+ fi
+ done
+ TERRAGRUNT_ARGS+=(-no-color -compact-warnings)
+ ;;
+ init)
+ TERRAGRUNT_ARGS+=(-no-color -compact-warnings)
+ ;;
+esac
+
+VARIABLES=""
+REPO="${PWD}"
+for var in $(pass show work/env)
+do
+ case $var in
+ TERRAGRUNT_EXTRA_MOUNTS*)
+ TERRAGRUNT_EXTRA_MOUNTS="$TERRAGRUNT_EXTRA_MOUNTS ${var#*=}"
+ ;;
+ *)
+ VARIABLES="$VARIABLES$(printf ' -e %s' "$var")"
+ ;;
+ esac
+done
+
+for var in $(printenv)
+do
+ case $var in
+ TF_*)
+ VARIABLES="$VARIABLES$(printf ' -e %s' $var)"
+ ;;
+ esac
+done
+
+WORKDIR="$REPO/$path"
+
+docker run --rm -i $TTY \
+ $VARIABLES \
+ -v $HOME/.terragrunt-cache:/tmp \
+ -v $HOME/.azure:/root/.azure \
+ -v $HOME/.netrc:/root/.netrc \
+ $TERRAGRUNT_EXTRA_MOUNTS \
+ -v ${REPO}:${REPO} \
+ -w ${WORKDIR} \
+ $TERRAGRUNT_CONTAINER terragrunt ${TERRAGRUNT_ARGS[@]} | filter-ansi
diff --git a/.local/bin/transadd b/.local/bin/transadd
new file mode 100755
index 0000000..a598fad
--- /dev/null
+++ b/.local/bin/transadd
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Mimeapp script for adding torrent to transmission-daemon, but will also start the daemon first if not running.
+
+# transmission-daemon sometimes fails to take remote requests in its first moments, hence the sleep.
+
+pidof transmission-daemon >/dev/null || (transmission-daemon && notify-send "Starting transmission daemon..." && sleep 3 && pkill -RTMIN+7 "${STATUSBAR:-dwmblocks}")
+
+transmission-remote -a "$@" && notify-send "πŸ”½ Torrent added."
diff --git a/.local/bin/vis-clipboard b/.local/bin/vis-clipboard
new file mode 100755
index 0000000..ccb9237
--- /dev/null
+++ b/.local/bin/vis-clipboard
@@ -0,0 +1,192 @@
+#!/bin/sh
+# Copyright (C) 2016 Richard Burke, ISC licensed
+# shellcheck disable=SC2317
+set -e
+
+vc_fatal() {
+ echo "$@" >&2
+ exit 1
+}
+
+vc_usage() {
+ vc_fatal "Usage: $(basename "$0") [--selection sel] [--usable|--copy|--paste]
+
+Copy/paste clipboard interface with support on all provided platforms.
+
+Options:
+ --copy copy text from standard input
+ --paste paste text to standard output
+ --usable silently exit with a status code indicating if a supported
+ clipboard implementation was found
+ --selection take input from sel. valid options: clipboard, primary"
+}
+
+vc_determine_command() {
+ if [ -n "$WAYLAND_DISPLAY" ]; then
+ for c in wl-copy wl-paste; do
+ if command -v "$c" >/dev/null 2>&1; then
+ echo "wlclipboard"
+ return 0
+ fi
+ done
+
+ for c in waycopy waypaste; do
+ if command -v "$c" >/dev/null 2>&1; then
+ echo "wayclip"
+ return 0
+ fi
+ done
+ fi
+
+ if [ -n "$DISPLAY" ]; then
+ for c in xclip xsel; do
+ if command -v "$c" >/dev/null 2>&1; then
+ echo "$c"
+ return 0
+ fi
+ done
+ fi
+
+ if command -v osc >/dev/null 2>&1; then
+ echo 'osc'
+ return 0
+ fi
+
+ if command -v pbcopy >/dev/null 2>&1; then
+ echo 'mac'
+ return 0
+ fi
+
+ if [ -c /dev/clipboard ]; then
+ echo 'cygwin'
+ return 0
+ fi
+
+ return 1
+}
+
+vc_usable() {
+ if vc_determine_command >/dev/null 2>&1; then
+ exit 0
+ fi
+
+ exit 1
+}
+
+vc_copy() {
+ COPY_CMD="$(vc_determine_command 2>/dev/null)"
+
+ # shellcheck disable=SC2181
+ if [ $? -ne 0 ] || [ -z "$COPY_CMD" ]; then
+ vc_fatal 'System clipboard not supported'
+ fi
+
+ "vc_${COPY_CMD}_copy"
+
+ exit $?
+}
+
+vc_paste() {
+ PASTE_CMD="$(vc_determine_command 2>/dev/null)"
+
+ # shellcheck disable=SC2181
+ if [ $? -ne 0 ] || [ -z "$PASTE_CMD" ]; then
+ vc_fatal 'System clipboard not supported'
+ fi
+
+ "vc_${PASTE_CMD}_paste"
+
+ exit $?
+}
+
+vc_wlclipboard_copy() {
+ if [ "$sel" = "primary" ]; then
+ wl-copy --primary -t TEXT 2>/dev/null
+ else
+ wl-copy -t TEXT 2>/dev/null
+ fi
+}
+
+vc_wlclipboard_paste() {
+ if [ "$sel" = "primary" ]; then
+ wl-paste --no-newline --primary -t text
+ else
+ wl-paste --no-newline -t text
+ fi
+}
+
+vc_wayclip_copy() {
+ if [ "$sel" = "primary" ]; then
+ waycopy -p
+ else
+ waycopy
+ fi
+}
+
+vc_wayclip_paste() {
+ if [ "$sel" = "primary" ]; then
+ waypaste -p
+ else
+ waypaste
+ fi
+}
+
+vc_xsel_copy() {
+ xsel --"$sel" -i
+}
+
+vc_xsel_paste() {
+ xsel --"$sel" -o
+}
+
+vc_xclip_copy() {
+ xclip -selection "$sel" -i >/dev/null 2>&1
+}
+
+vc_xclip_paste() {
+ xclip -selection "$sel" -o
+}
+
+vc_osc_copy() {
+ osc copy
+}
+
+vc_osc_paste() {
+ osc paste
+}
+
+vc_mac_copy() {
+ pbcopy
+}
+
+vc_mac_paste() {
+ pbpaste
+}
+
+vc_cygwin_copy() {
+ cat >/dev/clipboard
+}
+
+vc_cygwin_paste() {
+ cat /dev/clipboard
+}
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --usable) fn=vc_usable;;
+ --copy) fn=vc_copy;;
+ --paste) fn=vc_paste;;
+ --selection)
+ shift
+ if [ "$1" != "clipboard" ] && [ "$1" != "primary" ]; then
+ vc_fatal "Invalid selection: $1\nValid options are 'clipboard' or 'primary'"
+ fi
+ sel="$1";;
+ *) vc_usage;;
+ esac
+ shift
+done
+
+sel=${sel:-"clipboard"} $fn
+
+vc_usage
diff --git a/.local/bin/vremote b/.local/bin/vremote
new file mode 100755
index 0000000..4d0d417
--- /dev/null
+++ b/.local/bin/vremote
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+if [ -z "$PATH" ]; then
+ PATH="/etc/profiles/per-user/$USER/bin:/run/current-system/sw/bin:/usr/bin:/bin"
+fi
+server_pipe="$XDG_CACHE_HOME/nvim/server.pipe"
+if ! [ -e "$server_pipe" ]; then
+ nohup nvim --listen "$server_pipe" --headless >/dev/null 2>&1 &
+fi
+
+(
+ file_names=()
+ if [ -n "$1" ]; then
+ for file_name in "${@}"; do
+ if [[ "${file_name:0:1}" == / || "${file_name:0:2}" == ~[/a-zA-Z0-9] ]]
+ then
+ file_names+=("$file_name")
+ else
+ file_names+=("${PWD}/$file_name")
+ fi
+ done
+ echo "got file_names: ${file_names[*]}"
+ fi
+
+ if ! nvim \
+ --headless \
+ --server ~/.cache/nvim/server.pipe \
+ --remote-expr 'luaeval("vim.json.encode(vim.iter(vim.api.nvim_list_uis()):map(function(v) return v.chan end):totable())")' \
+ | jq -er '.[]'
+ then
+ nvim --server "$server_pipe" --remote "${file_names[@]}" >/dev/tty
+ exec nvim --server "$server_pipe" --remote-ui >/dev/tty
+ else
+ if ! command -v osascript >/dev/null 2>&1; then
+ notify-send "already existing ui
+starting new nvim instance"
+ else
+ osascript -e 'display notification "already existing ui..." with title "vremote"'
+ fi
+ exec nvim "${file_names[@]}" >/dev/tty </dev/tty
+ fi
+) > ~/vremote_logs 2>&1
diff --git a/.local/bin/window b/.local/bin/window
new file mode 100755
index 0000000..bd40a4c
--- /dev/null
+++ b/.local/bin/window
@@ -0,0 +1,11 @@
+#!/bin/sh
+PIPE=/tmp/window-fifo
+STDIN="$(cat -)"
+rm $PIPE
+mkfifo $PIPE
+echo "$STDIN" | tee $PIPE >/dev/null &
+if command -v st >/dev/null; then
+ st -e sh -c "<$PIPE ${*}" &
+else
+ tmux splitw sh -c "<$PIPE ${*}" &
+fi
diff --git a/.local/bin/xdg-open b/.local/bin/xdg-open
new file mode 100755
index 0000000..f401d16
--- /dev/null
+++ b/.local/bin/xdg-open
@@ -0,0 +1,5 @@
+#!/bin/bash
+case "$(file --mime-type $1 | awk '{print $2}')" in
+ text/*|application/json) exec "$EDITOR" $1 ;;
+ *) nu --commands "^echo $1 | nc 127.0.0.1 1994 | echo" ;;
+esac
diff --git a/.local/bin/zshcmd b/.local/bin/zshcmd
new file mode 100755
index 0000000..1a2fc88
--- /dev/null
+++ b/.local/bin/zshcmd
@@ -0,0 +1,10 @@
+#!/usr/bin/env zsh
+if [ -f ~/.zshrc ]; then
+ source ~/.zshrc &>/dev/null
+fi
+
+# Enable alias expansion
+setopt aliases
+
+# Run your commands that use aliases
+eval ${@}