summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.bashrc23
-rwxr-xr-x.config/aerc/filters/pdf4
-rw-r--r--.config/alacritty/base.ovl.yml9
-rw-r--r--.config/git/config13
-rw-r--r--.config/kanshi/config8
-rw-r--r--.config/mpv/config47
-rw-r--r--.config/mpv/input.conf17
-rw-r--r--.config/mpv/scripts/mouse_coords.lua2
-rw-r--r--.config/mvi/mpv.conf5
l---------.config/mvi/scripts/gallery-thumbgen.lua1
l---------.config/mvi/scripts/lib.disable1
l---------.config/mvi/scripts/playlist-view.lua1
-rw-r--r--.config/oguri/config2
-rw-r--r--.config/sway/auto.conf2
-rw-r--r--.config/sway/binds.conf13
-rw-r--r--.config/sway/config20
-rw-r--r--.config/sway/input.conf4
-rw-r--r--.config/treestyletab.css22
-rw-r--r--.config/tridactyl/tridactylrc6
-rw-r--r--.config/vifm/vifmrc7
-rw-r--r--.config/waybar/config97
-rwxr-xr-x.config/waybar/modules/weather.sh4
-rw-r--r--.config/waybar/style.css15
-rw-r--r--.config/yamlfs/go.yml54
-rw-r--r--.profile15
-rw-r--r--.vim/UltiSnips/tex.snippets21
-rw-r--r--.vim/ftdetect/h.vim2
-rw-r--r--.vim/init.vim12
-rw-r--r--.vim/lua/conf/treesitter.lua5
-rw-r--r--.vim/lua/plugins.lua2
-rw-r--r--.vim/syntax/gotmpl.vim2
-rwxr-xr-xbin/enter24
-rwxr-xr-xbin/firefox1
-rwxr-xr-xbin/fzfez103
-rwxr-xr-xbin/grimshot2
-rwxr-xr-xbin/lock33
-rwxr-xr-xbin/menu6
-rwxr-xr-xbin/mpvdiff3
-rwxr-xr-xbin/oguri-cycle5
-rwxr-xr-xbin/open32
-rwxr-xr-xbin/semver29
-rwxr-xr-xbin/swx4
-rwxr-xr-xbin/trash29
-rwxr-xr-xbin/vncez13
-rwxr-xr-xbin/wfez75
-rwxr-xr-xbin/xdg-exec23
46 files changed, 547 insertions, 271 deletions
diff --git a/.bashrc b/.bashrc
index 4f0c876..525e5ed 100644
--- a/.bashrc
+++ b/.bashrc
@@ -44,13 +44,10 @@ if [ -d /usr/libexec/z_lua ]; then
 	safe_load /usr/libexec/z_lua/czmod/czmod.bash
 fi
 
-# Use keychain to reuse the ssh-agent between logins
-keychain --agents ssh -q "$HOME"/.ssh/id_rsa
+# Use keychain to reuse the ssh-agent and gpg-agent between logins
+keychain --agents ssh,gpg -q id_rsa # AF6AB8C8B10436B9F61293632143BD2AAB94BCC4
 safe_load "$HOME/.keychain/$(hostname)-sh"
-
-# use keychain to reuse gpg-agents between logins
-# keychain --agents ssh,gpg -q "$HOME"/.ssh/id_rsa B07A551E7F0D35A6A2CD9E5944DFC1CFDC3EA327
-# safe_load "$HOME/.keychain/$(hostname)-sh-gpg"
+safe_load "$HOME/.keychain/$(hostname)-sh-gpg"
 
 # Make sure to also load ~/.profile for non-login shells
 safe_load ~/.profile
@@ -67,3 +64,17 @@ _prompt_hook() {
 		PS1=$(prompt)
 	fi
 }
+
+# Alias shell commands
+# alias logout='dbus-send --session --type=method_call --print-reply --dest='
+alias rm='rm -I --one-file-system'
+alias vim=nvim
+alias v=nvim
+alias l='exa --long --classify --group --header --group-directories-first'
+alias lt='exa --classify --group-directories-first -T'
+alias ..='cd ..'
+alias cat=bat
+alias ssh='TERM=xterm-256color ssh'
+alias balssh='ssh -p 22222 -o User=root -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
+alias balscp='scp -P 22222 -o User=root -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
+alias k=kubectl
diff --git a/.config/aerc/filters/pdf b/.config/aerc/filters/pdf
index a0cd2e9..3fd709a 100755
--- a/.config/aerc/filters/pdf
+++ b/.config/aerc/filters/pdf
@@ -1,4 +1,2 @@
 #!/bin/sh
-
-exec pdftohtml -s -i -stdout /dev/stdin \
-	| /usr/share/aerc/filters/html
+exec pdftotext -q -layout /dev/stdin /dev/stdout
diff --git a/.config/alacritty/base.ovl.yml b/.config/alacritty/base.ovl.yml
index 7e07dce..3ccd271 100644
--- a/.config/alacritty/base.ovl.yml
+++ b/.config/alacritty/base.ovl.yml
@@ -1,6 +1,13 @@
 window:
   decorations: none
 
+cursor:
+  style:
+    shape: Block
+    blinking: Off
+
+  vi_mode_style: Underline
+
 font:
   size: 12.0
   normal:
@@ -36,3 +43,5 @@ key_bindings:
   - { key: 'Escape',                          action: 'ToggleViMode',   mode: 'Vi' }
   - { key: 'Slash',  mods: 'Alt',             action: 'SearchForward',  mode: 'Vi' }
   - { key: 'Slash',                           action: 'SearchBackward', mode: 'Vi' }
+  - { key: 'PageUp',                          action: 'ScrollPageUp',   mode: 'Vi' }
+  - { key: 'PageDown',                        action: 'ScrollPageDown', mode: 'Vi' }
diff --git a/.config/git/config b/.config/git/config
index b16e8c3..631a82a 100644
--- a/.config/git/config
+++ b/.config/git/config
@@ -16,6 +16,14 @@
     multiEdit = true
     confirm = always
 
+[credential "git.sr.ht"]
+    username = robertgzr
+    helper = !sh -c 'pass sr.ht/robertgzr | xargs printf "password=%s\n"'
+
+[credential "github.com"]
+    username = robertgzr
+    helper = !sh -c 'pass github.com/robertgzr | xargs printf "password=%s\n"'
+
 [credential "smtp://mail.gandi.net:465"]
     username = robert@gnzler.io
     helper = !sh -c 'pass email/gnzler.io | xargs printf "password=%s\n"'
@@ -83,8 +91,9 @@
     total-lines = "! git ls-tree -r master --name-only | xargs -I {} git blame --line-porcelain {} | sed -n 's/^author //p' | sort | uniq -c | sort -rn"
     fixup = "!f() { git commit --fixup=${1}; }; f"
     squash = "!f() { git commit --squash=${1}; }; f"
-    rbi = rebase --autosquash -i
-    rbi-pr = !bash -c 'git rebase --autosquash -i `git merge-base HEAD ${1:-origin/master}`'
+    r = rebase
+    ri = rebase --autosquash -i
+    ri-pr = !bash -c 'git rebase --autosquash -i `git merge-base HEAD ${1:-origin/master}`'
     pushf = push --force-with-lease
     root = "rev-parse --show-toplevel"
     trailer = "!f() { trailer=${1:-}; ref=${2:-HEAD}; mode='--amend'; [ $ref != 'HEAD' ] && mode='--fixup=$ref'; msg=$(git rev-parse --show-toplevel)/LAST_COMMIT_MSG; git log -1 --format=%B $ref > $msg; git interpret-trailers --in-place --trailer $trailer $msg; git commit --allow-empty --no-verify --only --edit --file $msg $mode; rm $msg; }; f"
diff --git a/.config/kanshi/config b/.config/kanshi/config
index 77930e8..fc9019d 100644
--- a/.config/kanshi/config
+++ b/.config/kanshi/config
@@ -26,8 +26,14 @@ profile laptop {
     exec oguri-cycle
 }
 
+profile sony {
+    output eDP-1 scale 1 position 0,0 enable
+    output "Sony SONY TV  *00 0x00000101" mode 3840x2160@23.976000Hz transform normal position 2560,0 enable
+    exec oguri-cycle
+}
+
 profile tv {
-    output eDP-1 scale 2 position 0,0 enable
+    output eDP-1 scale 1 position 0,0 enable
     output HDMI-A-1 transform normal position 2560,0 enable
     exec oguri-cycle
 }
diff --git a/.config/mpv/config b/.config/mpv/config
index 3491d76..8d6ac1a 100644
--- a/.config/mpv/config
+++ b/.config/mpv/config
@@ -4,12 +4,15 @@
 autoload-files=no
 input-ipc-server=/var/run/user/1000/mpv 
 profile=gpu-hq
+icc-profile=~~/B140QAN02_0.icm
+tone-mapping=clip
+target-peak=500
 
 #
 # Video
 #
-framedrop=vo
-video-sync=display-resample
+# framedrop=vo
+# video-sync=display-resample
 gpu-context=wayland
 window-maximized=yes # prevent wayland problems with buffer resize
 hwdec=yes
@@ -115,21 +118,39 @@ dscale=ewa_lanczossharp
 correct-downscaling=yes
 sigmoid-upscaling=yes
 
-[gpuscale8]
-profile-desc="Use GLSL shaders to scale via GPU"
+[gpuscale]
+profile-desc="Use GLSL shaders to scale via GPU (FSRCNNX)"
 profile=gpu-hq
-glsl-shaders=~~/shaders/FSRCNNX_x2_16-0-4-1.glsl
+hwdec=auto-copy
+gpu-api=opengl
+fbo-format=rgba16f
+cscale=mitchell
+dscale=mitchell
+linear-downscaling=no
+glsl-shaders-clr
+glsl-shaders=~~/shaders/default-shader-pack/shaders/FSRCNNX_x2_8-0-4-1.glsl
+glsl-shaders=~~/shaders/default-shader-pack/shaders/KrigBilateral.glsl
+glsl-shaders=~~/shaders/default-shader-pack/shaders/SSimDownscaler.glsl
 
-[gpuscale16]
-profile-desc="Use GLSL shaders to scale via GPU"
+[gpuscale-high]
+profile-desc="Use GLSL shaders to scale via GPU (FSRCNNX x16)"
 profile=gpu-hq
-glsl-shaders=~~/shaders/FSRCNNX_x2_8-0-4-1.glsl
+hwdec=auto-copy
+gpu-api=opengl
+fbo-format=rgba16f
+cscale=mitchell
+dscale=mitchell
+linear-downscaling=no
+glsl-shaders-clr
+glsl-shaders=~~/shaders/default-shader-pack/shaders/FSRCNNX_x2_16-0-4-1.glsl
+glsl-shaders=~~/shaders/default-shader-pack/shaders/KrigBilateral.glsl
+glsl-shaders=~~/shaders/default-shader-pack/shaders/SSimDownscaler.glsl
 
 [interpolate]
 profile-desc="Increase framecount by interpolating (with vapoursynth)"
 profile=gpu-hq
 vf=format=yuv420p,scale=w=-1:h=720,vapoursynth=~~/vapoursynth/interpolate.vpy:4:4
-video-sync=display-desync
+video-sync=display-resample
 
 [svp]
 profile-desc="[irrelevant] Integrate with SVP"
@@ -157,3 +178,11 @@ vf-add='stereo3d:ab2l:ml'
 [skip-silence]
 profile-desc="Skip over silent parts"
 af-add='silenceremove=0:0:0:-1:0.001:-45dB:0:rms'
+
+[anime4k]
+profile-desc="Anime4K x2 Perceptual"
+glsl-shaders-clr
+glsl-shaders=~~/shaders/default-shader-pack/shaders/Anime4K_3.0_Upscale_CNN_M_x2_Deblur.glsl
+glsl-shaders=~~/shaders/default-shader-pack/shaders/Anime4K_3.0_ThinLines_HQ.glsl
+glsl-shaders=~~/shaders/default-shader-pack/shaders/Anime4K_3.0_DarkLines_HQ.glsl
+glsl-shaders=~~/shaders/default-shader-pack/shaders/Anime4K_3.0_Denoise_Bilateral_Mode.glsl
diff --git a/.config/mpv/input.conf b/.config/mpv/input.conf
index 67ace36..259eafc 100644
--- a/.config/mpv/input.conf
+++ b/.config/mpv/input.conf
@@ -99,6 +99,7 @@ h cycle-values af lavfi=[bs2b=profile=default] lavfi=[bs2b=profile=jmeier] lavfi
 
 MBTN_RIGHT script_binding uosc/menu
 U script_binding uosc/menu
+Enter script_binding uosc/menu
 P script-binding uosc/playlist  #! select > playlist
 C script-binding uosc/chapters  #! select > chapters
 Ctrl+space script-binding uosc/peek-timeline
@@ -110,7 +111,7 @@ Alt+r script-binding slicing/slicing_mark      #! utils > slicing > mark
 Alt+t script-binding autodeint                 #! utils > autodeint
 Alt+y script-binding autocrop/toggle_crop      #! utils > autocrop
 c script-binding contact-sheet-toggle          #! utils > contact sheet
-g script-binding playlist-view-toggle          #! utils > playlist view
+# g script-binding playlist-view-toggle          #! utils > playlist view
 Alt+m script-binding mouse_coords              #! utils > mouse coords
 
 K ignore
@@ -126,8 +127,12 @@ J ignore
 8 ignore
 9 ignore
 
-Ctrl+Shift+1 apply-profile anime       # ! profile > anime
-Ctrl+Shift+2 apply-profile cache       # ! profile > cache
-Ctrl+Shift+3 apply-profile scale       # ! profile > scale
-Ctrl+Shift+4 apply-profile interpolate # ! profile > interpolate
-Ctrl+Shift+5 apply-profile 3d          # ! profile > 3d fix
+Ctrl+Shift+0 apply-profile reset         #! profiles > reset
+Ctrl+Shift+1 apply-profile anime         #! profiles > anime
+Ctrl+Shift+2 apply-profile cache         #! profiles > cache
+Ctrl+Shift+3 apply-profile scale         #! profiles > scale
+Ctrl+Shift+4 apply-profile interpolate   #! profiles > interpolate
+Ctrl+Shift+5 apply-profile 3d            #! profiles > 3d fix
+Ctrl+Shift+6 apply-profile anime4k       #! profiles > 3d fix
+Ctrl+Shift+7 apply-profile gpuscale      #! profiles > gpuscale x8
+Ctrl+Shift+8 apply-profile gpuscale-high #! profiles > gpuscale x16
diff --git a/.config/mpv/scripts/mouse_coords.lua b/.config/mpv/scripts/mouse_coords.lua
index dae6239..3bc59b9 100644
--- a/.config/mpv/scripts/mouse_coords.lua
+++ b/.config/mpv/scripts/mouse_coords.lua
@@ -21,7 +21,7 @@ local msg = require('mp.msg')
 
 function print_pos()
     x, y = mp.get_mouse_pos()
-    pos = "x: " .. x .. ", y: " .. y
+    pos = "xy: " .. x .. "," .. y
     mp.msg.warn(pos)
     mp.osd_message(pos)
 end
diff --git a/.config/mvi/mpv.conf b/.config/mvi/mpv.conf
index 1032b0e..2218a59 100644
--- a/.config/mvi/mpv.conf
+++ b/.config/mvi/mpv.conf
@@ -1,6 +1,11 @@
 gpu-context=wayland
 autofit-larger=x90%
 
+osd-font="Iosevka Aile"
+osd-font-size=15
+osd-scale-by-window=yes
+hidpi-window-scale
+
 ## IMAGE
 # classic opengl-hq parameter, change at will
 scale=spline36
diff --git a/.config/mvi/scripts/gallery-thumbgen.lua b/.config/mvi/scripts/gallery-thumbgen.lua
deleted file mode 120000
index 92816c8..0000000
--- a/.config/mvi/scripts/gallery-thumbgen.lua
+++ /dev/null
@@ -1 +0,0 @@
-../../mpv/scripts/mpv-gallery-view/scripts/gallery-thumbgen.lua
\ No newline at end of file
diff --git a/.config/mvi/scripts/lib.disable b/.config/mvi/scripts/lib.disable
deleted file mode 120000
index bc6efec..0000000
--- a/.config/mvi/scripts/lib.disable
+++ /dev/null
@@ -1 +0,0 @@
-../../mpv/scripts/mpv-gallery-view/scripts/lib.disable
\ No newline at end of file
diff --git a/.config/mvi/scripts/playlist-view.lua b/.config/mvi/scripts/playlist-view.lua
deleted file mode 120000
index ed4ac05..0000000
--- a/.config/mvi/scripts/playlist-view.lua
+++ /dev/null
@@ -1 +0,0 @@
-../../mpv/scripts/mpv-gallery-view/scripts/playlist-view.lua
\ No newline at end of file
diff --git a/.config/oguri/config b/.config/oguri/config
index 2288dae..cb2ea09 100644
--- a/.config/oguri/config
+++ b/.config/oguri/config
@@ -1,4 +1,4 @@
 [output *]
-image=$HOME/.config/oguri/leaves.jpg
+image=/home/robert/.config/oguri/leaves.jpg
 scaling-mode=tile
 filter=best
diff --git a/.config/sway/auto.conf b/.config/sway/auto.conf
index 6afe96b..fe004f9 100644
--- a/.config/sway/auto.conf
+++ b/.config/sway/auto.conf
@@ -18,6 +18,8 @@ for_window [app_id="firefox" title="^Developer Tools"] floating enable
 for_window [app_id="firefox" title="Sharing Indicator$"] floating enable, border none, move position 0 ppt 50 ppt, sticky enable
 for_window [app_id="firefox" title="^Close tabs?"] floating enable
 for_window [app_id="firefox" title="^File Upload$"] exec centercon -w .6
+for_window [app_id="firefox" title="^Save As$"] exec centercon -w .6
+for_window [app_id="Telegram" title="^Choose Files$"] floating enable; exec centercon -w .6
 
 # Tag windows
 for_window [app_id="firefox"] mark browser
diff --git a/.config/sway/binds.conf b/.config/sway/binds.conf
index f8591d6..838c78e 100644
--- a/.config/sway/binds.conf
+++ b/.config/sway/binds.conf
@@ -35,6 +35,7 @@ bindsym $mod+Shift+e exec swaynag \
 
 bindsym $mod+Shift+backspace exec lock
 
+bindsym Print exec grimshot copy output
 bindsym $mod+Shift+s mode "screengrab"
 mode "screengrab" {
 bindsym a exec grimshot save screen; mode "default"
@@ -49,7 +50,7 @@ bindsym Escape mode "default"
 bindsym $mod+Shift+b border toggle
 bindsym $mod+Shift+r output - transform 90 clockwise
 
-bindsym $mod+a exec soundswitch
+bindsym $mod+Shift+a exec soundswitch
 # }}}
 
 # Moving around {{{
@@ -236,4 +237,14 @@ bindsym XF86MonBrightnessDown exec light -U 5
 bindsym XF86AudioPlay exec playerctl -p playerctld play-pause
 bindsym XF86AudioNext exec playerctl -p playerctld next
 bindsym XF86AudioPrev exec playerctl -p playerctld previous
+
+bindsym XF86WakeUp exec true
+# switch video mode
+bindsym XF86Display exec sh -c 'killall kanshi; exec kanshi'
+# config
+bindsym XF86Tools exec true
+# keyboard
+bindsym XF86Keyboard exec light -S 0
+# bookmarks
+bindsym XF86Favorites exec light -S 100
 # }}}
diff --git a/.config/sway/config b/.config/sway/config
index a2a64e4..c5b46dd 100644
--- a/.config/sway/config
+++ b/.config/sway/config
@@ -1,20 +1,22 @@
 # vim: ft=i3config fdm=marker
 
-exec doas rc gui
-
 output * scale 1
 output * max_render_time 1
 output * adaptive_sync on
 
-exec_always sh -c 'killall kanshi; exec kanshi'
-exec_always sh -c 'killall oguri; exec oguri; oguri-cycle'
-exec_always sh -c 'killall waybar; exec waybar'
-#exec_always kanshictl reload
+# exec_always sh -c 'killall oguri; exec oguri;'
+exec oguri
+# exec_always sh -c 'killall kanshi; exec kanshi;'
+exec kanshi
+# exec_always sh -c 'killall waybar; exec waybar;'
+exec waybar
+
+#exec doas rc sway
 
 exec light -S 80
 exec redshift
+exec pipewire
 exec mako
-# exec mpd-mpris -no-instance
 exec swayidle -w \
 	timeout 540 'lock' \
 	timeout 800 'swaymsg output \* dpms off' \
@@ -39,6 +41,8 @@ set $right l
 
 set $term alacritty
 set $floating_term $term --config-file $HOME/.config/alacritty/launcher.yml --class '__floating-Alacritty'
+# set $term foot
+# set $floating_term $term --app-id '__floating-term'
 set $menu menu -drun
 # set $menu wofi -k /dev/null --terminal $term --show drun
 set $run_menu menu -run
@@ -101,4 +105,4 @@ client.urgent $urgent2 $urgent $text $indicator $urgent
 # }}}
 
 # include config.d/*
-include "`uname -n`"
+# include "`uname -n`"
diff --git a/.config/sway/input.conf b/.config/sway/input.conf
index dc617a6..2635a50 100644
--- a/.config/sway/input.conf
+++ b/.config/sway/input.conf
@@ -14,7 +14,7 @@ input 65261:25700:Input_Club_Infinity_keyboard/QMK {
    repeat_rate 70
    repeat_delay 200
 }
-input 65261:24672:OLKB_Planck {
+input 12951:50895:ZSA_Technology_Labs_Planck_EZ_Glow {
    xkb_layout us
    xkb_variant mac
    xkb_options 'caps:hyper,lvl3:ralt_switch_multikey,eurosign:5'
@@ -22,7 +22,7 @@ input 65261:24672:OLKB_Planck {
    repeat_delay 200
 }
 
-input 2:7:SynPS/2_Synaptics_TouchPad {
+input 1739:0:Synaptics_TM3289-021 {
    tap enabled
    natural_scroll enabled
    accel_profile adaptive
diff --git a/.config/treestyletab.css b/.config/treestyletab.css
index 9339e73..8e62f48 100644
--- a/.config/treestyletab.css
+++ b/.config/treestyletab.css
@@ -1,17 +1,8 @@
 /* Show title of unread tabs with red and italic font */
-/*
 :root.sidebar tab-item.unread .label-content {
-  color: red !important;
   font-style: italic !important;
 }
-*/
 
-/* Add private browsing indicator per tab */
-/*
-:root.sidebar tab-item.private-browsing tab-label:before {
-  content: "🕶";
-}
-*/
 /* Less visible tab dividers. 
    A black border with a very low alpha slightly darkens any color. */
 tab-item {
@@ -20,11 +11,11 @@ tab-item {
 
 /* Change styling of pending (unloaded) tabs */
 tab-item.discarded {
-  opacity: 0.75;
+  opacity: 0.5;
 }
 
 tab-item.discarded .label-content {
-  opacity: 0.7;
+  opacity: 0.5;
 }
 
 :root.right tab-item tab-twisty {
@@ -42,7 +33,10 @@ tab-item.discarded .label-content {
 /* As little space before the tab name as possible.
    The fold/unfold icon is not affected. */
 tab-item:not(.pinned) {
-  padding-left: 6px !important; /* !important is required when there are enough tabs to cause a scrollbar */
+  padding-left: 6px !important;
+}
+tab-item:not(.pinned) .label-content {
+  padding-left: 2px;
 }
 
 tab-item tab-twisty {
@@ -50,4 +44,8 @@ tab-item tab-twisty {
   opacity: 0 !important;
   position: relative;
   z-index: 10000;
+}
+
+:root[theme="photon"], #background {
+  background-color: #2a2a2e;
 }
\ No newline at end of file
diff --git a/.config/tridactyl/tridactylrc b/.config/tridactyl/tridactylrc
index b196ae2..62a2753 100644
--- a/.config/tridactyl/tridactylrc
+++ b/.config/tridactyl/tridactylrc
@@ -2,8 +2,8 @@
 " sanitise tridactyllocal tridactylsync
 
 " rebind j/k for TST
-reset j
-reset k
+reset J
+reset K
 bind J tabnext
 bind K tabprev
 
@@ -31,6 +31,7 @@ bind <Space>ts fillcmdline tabopen -c shop
 
 bind <space>s fillcmdline tabopen search
 bind <space>n fillcmdline nativeopen
+bind <space>c fillcmdline recontain
 
 bind <C-o> back
 bind <C-i> forward
@@ -76,6 +77,7 @@ seturl overleaf.com mode ignore
 seturl jel.ly.fish mode ignore
 seturl gather.town mode ignore
 seturl typingclub.com mode ignore
+autocmd TabEnter typingclub.com mode ignore
 
 " fix youtube
 seturl youtube.com noiframe true
diff --git a/.config/vifm/vifmrc b/.config/vifm/vifmrc
index 26479b4..18da8dd 100644
--- a/.config/vifm/vifmrc
+++ b/.config/vifm/vifmrc
@@ -93,6 +93,8 @@ filextype *.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
         \ mpv --mute %f,
         \ {View using ffplay}
         \ ffplay -fs %f,
+       \ {Enqueue using xap}
+       \ xap add %c:p,
 
 fileviewer *.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
           \*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,
@@ -164,6 +166,11 @@ filetype *.7z
        \ 7z x %c,
 fileviewer *.7z 7z l %c
 
+filetype *.rar
+       \ {Extract RAR}
+       \ unrar x %c,
+fileviewer *.rar unrar v %c
+
 " ArchiveMount
 fileviewer *.tgz,*.tar.gz tar -tzf %c
 fileviewer *.tar.bz2,*.tbz2 tar -tjf %c
diff --git a/.config/waybar/config b/.config/waybar/config
index aed7d08..40e06a4 100644
--- a/.config/waybar/config
+++ b/.config/waybar/config
@@ -7,7 +7,7 @@
 
     "modules-left": ["sway/mode", "sway/workspaces", "sway/window", "custom/mpv", "custom/mpd", "custom/spotify", "custom/toggl"],
     "modules-center": ["custom/weather", "clock#local", "clock#utc"],
-    "modules-right": ["tray", "cpu", "memory", "disk#root", "disk#home", "temperature", "idle_inhibitor", "backlight", "custom/redshift", "pulseaudio", "network#wg", "network", "battery"],
+    "modules-right": ["tray", "cpu", "memory", "disk#root", "disk#home", "temperature", "idle_inhibitor", "backlight", "custom/redshift", "pulseaudio", "network#vpn", "network#tailscale", "network", "battery"],
 
     "sway/workspaces": {
         "disable-scroll": true,
@@ -30,30 +30,31 @@
     "idle_inhibitor": {
         "format": "{icon}",
         "format-icons": {
-            "activated": "󰛐",
-            "deactivated": "󰛑"
+            "activated": "󰅶",
+            "deactivated": "󰾪"
         }
     },
     "tray": {
         "spacing": 10
     },
     "clock#local": {
-        "timezone": "Europe/Berlin",
+        // "timezone": "Europe/Berlin",
+        // "timezone": "Europe/Istanbul",
         "format": "{:<i>%a</i> %d %b <b>%H:%M</b>}",
-	"tooltip-format": "TZ: {:%Z %z}\n\n{calendar}"
+        "tooltip-format": "TZ: {:%Z %z}\n\n{calendar}"
     },
     "clock#utc": {
         "timezone": "UTC",
         "format": "({:<small>%Z</small> %H:%M})",
-	"tooltip-format": "{:%Z %z}"
+        "tooltip-format": "{:%Z %z}"
     },
     "disk#root": {
-	"path": "/",
-	"format": "󰋊 <small>/ </small>{percentage_used}%"
+        "path": "/",
+        "format": "󰋊 <small>/ </small>{percentage_used}%"
     },
     "disk#home": {
-	"path": "/home",
-	"format": "<small>/home </small>{percentage_used}%"
+        "path": "/home",
+        "format": "<small>/home </small>{percentage_used}%"
     },
     "cpu": {
         "format": "󰊚 {}%",
@@ -69,13 +70,15 @@
         "format-icons": ["󱃃", "󰔏", "󱃂", "󰸁"]
     },
     "backlight": {
-        "states": {
-	    "off": "1"
-	},
         "format": "{icon} {percent}%",
         "format-icons": ["󰹐", "󰌶", "󰛩"],
-        "on-scroll-down": "light -D 5",
+        "on-scroll-down": "light -A 5",
         "on-scroll-up": "light -U 5",
+        // save current level
+        // then set to minimum brightness
+        "on-click-right": "light -O; light -S $(light -P)",
+        // revert to previously saved brightness
+        "on-click-middle": "light -I"
     },
     "battery": {
         "states": {
@@ -100,13 +103,21 @@
         "tooltip-format-disconnected": "disconnected",
         "on-click": "swx -t -f iwctl"
     },
-    "network#wg": {
+    "network#vpn": {
         "interface": "wg0",
-        "format": "󰯄",
-	"tooltip-format": "wg0: {ipaddr}/{cidr}",
+        "format": "󰌆",
+        "tooltip-format": "{ifname}: {ipaddr}/{cidr}",
+        "tooltip-format-disconnected": "disconnected",
+        "on-click": "doas wg-quick up wg0",
+        "on-click-right": "doas wg-quick down wg0"
+    },
+    "network#tailscale": {
+        "interface": "tailscale0",
+        "format": "󰹻", // "󰈓", // "󰠳",
+        "tooltip-format": "{ifname}: {ipaddr}/{cidr}",
         "tooltip-format-disconnected": "disconnected",
-	"on-click": "doas wg-quick up wg0",
-	"on-click-right": "doas wg-quick down wg0"
+        "on-click": "doas rc-service tailscale start",
+        "on-click-right": "doas rc-service tailscale stop"
     },
     "pulseaudio": {
         "format": "{icon} {volume}%",
@@ -131,46 +142,46 @@
         "return-type": "json",
         "max-length": 80,
         "escape": false,
-	"interval": 2,
+        "interval": 2,
         "exec": "$HOME/.config/waybar/modules/waybar-media spotify",
-	"exec-if": "pgrep spotify"
+        "exec-if": "pgrep spotify"
      },
     "custom/mpd": {
-        "format": "󰴙 {}",
+        "format": "󰐹 {}",
         "return-type": "json",
         "max-length": 80,
-	"interval": 2,
+        "interval": 2,
         "exec": "$HOME/.config/waybar/modules/waybar-media mpd",
-	"exec-if": "pgrep mpd"
+        "exec-if": "pgrep mpd"
     },
     "custom/mpv": {
         "format": "󰐍 {}",
         "return-type": "json",
         "max-length": 80,
-	"interval": 2,
+        "interval": 2,
         "exec": "$HOME/.config/waybar/modules/waybar-media mpv",
-	"exec-if": "pgrep mpv"
+        "exec-if": "pgrep mpv"
     },
     "custom/toggl": {
-	"format": "󰔟 {}",
+    "format": "󰔟 {}",
         "exec": "$HOME/.config/waybar/modules/toggl.lua 2>/dev/null",
         "interval": 30
     },
     "custom/redshift": {
-	"format": "{icon}",
-	"format-icons": {
+    "format": "{icon}",
+    "format-icons": {
             "day": "󰱌",
-	    "night": "󰱊"
+            "night": "󰱊"
         },
         "exec-if": "pgrep redshift",
         "exec": "$HOME/.config/waybar/modules/waybar-redshift",
-	"return-type": "json",
-	"on-click": "pkill -x -USR1 redshift",
-	"on-click-right": "pkill -x -HUP waybar-redshift"
+        "return-type": "json",
+        "on-click": "pkill -x -USR1 redshift",
+        "on-click-right": "pkill -x -HUP waybar-redshift"
     },
     "custom/weather": {
-	"format": "{icon} {percentage}℃",
-	"format-icons": {
+        "format": "{icon} {percentage}℃",
+        "format-icons": {
             "sunny": "󰖙",
             "partlycloudy": "󰖕",
             "cloudy": "󰖐",
@@ -182,15 +193,15 @@
             "thunder": "󰖓",
             "lightsnow": "󰖘",
             "heavysnow": "󰼶",
-            "snowrain": "󰙿",
+            "snowrain": "󰙿"
         },
-	"exec": "$HOME/.config/waybar/modules/weather.sh Berlin",
-	"interval": 600,
-	"return-type": "json",
-	"tooltip": true,
-	"signal": 4,
-	"on-click-right": "pkill -SIGRTMIN+5 waybar",
-	"on-click": "swx -t env REPORT=1 $HOME/.config/waybar/modules/weather.sh Berlin"
+        "exec": "$HOME/.config/waybar/modules/weather.sh",
+        "interval": 600,
+        "return-type": "json",
+        "tooltip": true,
+        "signal": 4,
+        "on-click-right": "pkill -SIGRTMIN+5 waybar",
+        "on-click": "swx -t env REPORT=1 $HOME/.config/waybar/modules/weather.sh Berlin"
     },
     "mpd": {
         "format": "{stateIcon} {artist} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S})",
diff --git a/.config/waybar/modules/weather.sh b/.config/waybar/modules/weather.sh
index 210c20a..0b83de1 100755
--- a/.config/waybar/modules/weather.sh
+++ b/.config/waybar/modules/weather.sh
@@ -3,6 +3,10 @@ set -e
 [ -n "$DEBUG" ] && set -x
 
 loc=$1
+if [ -z "${loc}" ]; then
+	# use /etc/localtime
+	loc=$(basename "$(readlink -f /etc/localtime)")
+fi
 
 if [ -n "$REPORT" ]; then
 	curl -s v2.wttr.in/"${loc}"?F | less
diff --git a/.config/waybar/style.css b/.config/waybar/style.css
index e3d6206..9e41694 100644
--- a/.config/waybar/style.css
+++ b/.config/waybar/style.css
@@ -143,14 +143,22 @@ label:focus {
   border-top: 2px solid @urgent;
   color: @dimmed;
 }
-#network.wg.disconnected {
+#network.vpn.disconnected {
   border-top: 2px solid @dimmeddarker;
 }
-#network.wg:not(.disconnected) {
+#network.vpn:not(.disconnected) {
   border-top: 2px solid #c476ff;
   /* background: #c476ff; */
   /* color: @dimmeddarker; */
 }
+#network.tailscale.disconnected {
+  border-top: 2px solid @dimmeddarker;
+}
+#network.tailscale:not(.disconnected) {
+  border-top: 2px solid #497e7a;
+  /* background: #497e7a; */
+  /* color: @dimmeddarker; */
+}
 #pulseaudio {}
 #pulseaudio.muted {
   border-top: 2px solid @urgent;
@@ -169,6 +177,7 @@ label:focus {
 }
 #idle_inhibitor.activated {
   color: unset;
+  border-top: 2px solid #7a8530;
 }
 
 #custom-mpd,
@@ -203,7 +212,7 @@ label:focus {
   }
 }
 #custom-redshift.night {
-  border-top: 2px solid #ffae42;
+  border-top: 2px solid #97822e;
   color: @foreground;
   animation-name: flash;
   animation-duration: 0.3s;
diff --git a/.config/yamlfs/go.yml b/.config/yamlfs/go.yml
index a634f92..21fb36d 100644
--- a/.config/yamlfs/go.yml
+++ b/.config/yamlfs/go.yml
@@ -1,6 +1,4 @@
-{% $goversion := 1.14 %}
-{% $gopkg := (printf "example.com/%s" .name) %}
-{% with .pkg %}{% $gopkg = . %}{% end %}
+{% $goversion := 1.15 %}
 cmd:
   {% .name %}:
     main.go: |
@@ -15,12 +13,13 @@ version:
     package version
 
     var (
-    	Version = "0.0.0+unknown"
+    	Package = "{% .gopkg %}"
     	Revision = ""
+    	Version = "0.0.0+unknown"
     )
 
 go.mod: |
-  module {% $gopkg %}
+  module {% .gopkg %}
 
   go {% $goversion %}
 
@@ -28,15 +27,30 @@ Dockerfile: |
   # syntax=docker/dockerfile:1.1-experimental
   # vim: ft=dockerfile
 
-  FROM --platform=$BUILDPLATFORM docker.io/library/alpine:3.11 AS base
-  RUN apk add -U --no-cache ca-certificates
+  ARG GO_VERSION={% $goversion %}
 
-  FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx:golang AS xx
-  FROM --platform=$BUILDPLATFORM docker.io/library/golang:{% $goversion %}-alpine AS build
+  FROM --platform=${BUILDPLATFORM:?err} docker.io/tonistiigi/xx:golang AS xx
+  FROM --platform=${BUILDPLATFORM:?err} docker.io/library/golang:${GO_VERSION:?err}-alpine AS buildenv
   COPY --from=xx / /
   ARG TARGETPLATFORM
   WORKDIR /src
-  RUN apk add -U --no-cache make
+  RUN apk --update-cache --no-cache add make
+
+  FROM buildenv AS gotestsum
+  RUN go get gotest.tools/gotestsum@0.6.0
+
+  FROM buildenv AS golangcilint
+  RUN go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0
+
+  FROM buildenv AS test
+  COPY --from=gotestsum /go/bin/gotestsum /usr/local/bin/
+  COPY --from=golangcilint /go/bin/golangci-lint /usr/local/bin/
+  RUN --mount=target=/src,rw \
+      --mount=type=cache,target=/go/pkg \
+      --mount=type=cache,target=/root/.cache \
+      make DESTDIR=/out clean validate test
+
+  FROM buildenv AS build
   RUN --mount=target=/src,rw \
       --mount=type=cache,target=/go/pkg \
       --mount=type=cache,target=/root/.cache \
@@ -45,7 +59,10 @@ Dockerfile: |
   FROM scratch AS final
   COPY --from=build /out/{% .name %} /
 
-  FROM base AS run
+  FROM --platform=${TARGETPLATFORM:?err} docker.io/library/alpine:3.11 AS runtime-base
+  RUN apk --update-cache --no-cache add ca-certificates
+
+  FROM runtime-base AS run
   COPY --from=build /out/{% .name %} /usr/local/bin/
   ENTRYPOINT [ "{% .name %}" ]
 
@@ -60,10 +77,10 @@ Makefile: |
   REVISION ?= $(shell git rev-parse HEAD)
 
   GO ?= go
-  GO_PKG ?= {% $gopkg %}
+  GO_PKG ?= {% .gopkg %}
   GO_BUILDTAGS ?= netgo osusergo static_build
   GO_LDFLAGS ?= -s -w -extldflags "-static"
-  GO_VERSIONFLAGS = -X {% $gopkg %}/version.Version=$(VERSION) -X {% $gopkg %}/version.Revision=$(REVISION)
+  GO_VERSIONFLAGS = -X $(GO_PKG)/version.Version=$(VERSION) -X $(GO_PKG)/version.Revision=$(REVISION)
 
   .PHONY: build
   build: {% .name %}
@@ -82,6 +99,11 @@ Makefile: |
   	DOCKER_BUILDKIT=1 \
   	docker build --platform $(PLATFORM) --target final -o . .
 
+  .PHONY: container-test
+  container-test:
+  	DOCKER_BUILDKIT=1 \
+  	docker build --platform $(PLATFORM) --target test -o type=tar,dest=/dev/null .
+
   .PHONY: container-image
   container-image:
   	DOCKER_BUILDKIT=1 \
@@ -138,9 +160,9 @@ Makefile: |
   	@printf "  container-image   image build\n"
   	@printf "  cross             build w/ buildkit (multi-platform support)\n"
   	@printf "\n"
-  	@printf "  DESTDIR, PREFIX   output location\n"
-  	@printf "  PLATFORM          output platform\n"
-  	@printf "  REPO, TAG         image repository:tag\n"
+  	@printf "  DESTDIR, PREFIX   output location (default: $(DESTDIR)/$(PREFIX))\n"
+  	@printf "  PLATFORM          output platform (default: $(PLATFORM))\n"
+  	@printf "  REPO, TAG         image repository:tag (default: $(REPO):$(TAG))\n"
   	@printf "\n"
 
 .editorconfig: |
diff --git a/.profile b/.profile
index 8ff4672..b2c5411 100644
--- a/.profile
+++ b/.profile
@@ -46,6 +46,7 @@ export NUMCPUSplusone=$((NUMCPUS + 1))
 export MAKEOPTS="-j${NUMCPUSplusone} -l${NUMCPUS}"
 export EMERGE_DEFAULT_OPTS="--jobs=${NUMCPUSplusone} --load-average=${NUMCPUS}"
 
+export GPG_TTY=$(tty)
 # Set prompt
 # export PS1="$(prompt)"
 
@@ -58,17 +59,3 @@ export LESS='--hilite-search --hilite-unread --long-prompt --raw-control-chars -
 
 # Set the rsync ssh command to use by default
 export RSYNC_RSH='ssh -T -x -o Compression=no'
-
-# Alias shell commands
-# alias logout='dbus-send --session --type=method_call --print-reply --dest='
-alias rm='rm -vI --one-file-system'
-alias vim=nvim
-alias v=nvim
-alias l='exa --long --classify --group --header --group-directories-first'
-alias lt='exa --classify --group-directories-first -T'
-alias ..='cd ..'
-alias cat=bat
-alias ssh='TERM=xterm-256color ssh'
-alias balssh='ssh -p 22222 -o User=root -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
-alias balscp='scp -P 22222 -o User=root -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
-alias k=kubectl
diff --git a/.vim/UltiSnips/tex.snippets b/.vim/UltiSnips/tex.snippets
index 2788273..38e9ef1 100644
--- a/.vim/UltiSnips/tex.snippets
+++ b/.vim/UltiSnips/tex.snippets
@@ -4,16 +4,16 @@ $0
 \end{$1}
 endsnippet
 
-snippet mk "Math" wA
+snippet $$ "Math" wA
 $${1}$ $0
 endsnippet
-snippet dm "Math" iA
+snippet \[ "Math" iA
 \[
 	${1:${VISUAL}}
 .\] $0
 endsnippet
 
-snippet // "Fraction" iA
+snippet frac "Fraction" iA
 \\frac{$1}{$2}$0
 endsnippet
 
@@ -64,20 +64,25 @@ snippet letter "letter"
 \nowindowtics
 \nowindowrules
 
+% unterschrift
 \newcommand{\setsign}{\includegraphics[height=30truemm]{/home/robert/Pictures/sign.png}}
 \signature{Robert Günzler}
 \address{
-	Robert Günzler \\\\
-	Street\\\\
-	PLZ Berlin}
+% absender
+  Robert Günzler \\\\
+  STREET \\\\
+  PLZ Berlin}
 
 \date{\today}
 \place{Berlin}
-%\subject{{\bf anliegen}}
+
+% betreff
+% \subject{{\bf anliegen}}
 
 \begin{document}
 \begin{letter}{
-	$1}
+% empfänger
+  $1}
 
 \opening{${2:Sehr geehrte Damen und Herren,}}
 
diff --git a/.vim/ftdetect/h.vim b/.vim/ftdetect/h.vim
index 665088d..fe92579 100644
--- a/.vim/ftdetect/h.vim
+++ b/.vim/ftdetect/h.vim
@@ -1 +1 @@
-au BufNewFile,BufEnter *.h :setlocal filetype=c
+au BufNewFile,BufEnter *.h setlocal filetype=c
diff --git a/.vim/init.vim b/.vim/init.vim
index 23c94c5..8ebf080 100644
--- a/.vim/init.vim
+++ b/.vim/init.vim
@@ -46,9 +46,10 @@ augroup Colors
 augroup END
 
 " Make comments italic, no matter what the colorscheme does
-hi Comment gui=italic
+hi Comment gui=italic cterm=italic
 " Fix ugly looking grey when transparent_background=1
 hi SignColumn guibg=none ctermbg=none
+hi MatchParen gui=underline cterm=underline
 " }}}
 
 " key bindings {{{
@@ -91,6 +92,7 @@ nmap <silent> <leader>v :Vista!!<CR>
 nmap <silent> <leader>nt :call numbertoggle#switch()<CR>
 nmap <silent> <leader>tn :rightbelow Tnew<CR>
 nmap <silent> gF :lua require'misc'.open_under_cursor()<CR>
+nmap <silent> gf :lua require'misc'.open_under_cursor('open')<CR>
 noremap <silent> gx :lua require'misc'.open_under_cursor('url-launcher')<CR>
 augroup netrw_maps
   au!
@@ -159,8 +161,12 @@ hi SignifySignChange guibg=NONE ctermbg=NONE
 hi SignifySignAdd guibg=NONE ctermbg=NONE
 hi SignifySignDelete guibg=NONE ctermbg=NONE
 
-nmap <silent> ]h <cmd>SignifyJumpToNextHunk<cr>
-nmap <silent> [h <cmd>SignifyJumpToPrevHunk<cr>
+" NOTE: it's not a good idea to start the bind with `h`
+" since that will interfere with cursor movement
+" nmap <silent> ]h <cmd>SignifyJumpToNextHunk<cr>
+" nmap <silent> [h <cmd>SignifyJumpToPrevHunk<cr>
+nmap <silent> ]h <plug>(signify-next-hunk)
+nmap <silent> [h <plug>(signify-prev-hunk)
 " }}}2
 
 let g:vue_disable_pre_processors = 1
diff --git a/.vim/lua/conf/treesitter.lua b/.vim/lua/conf/treesitter.lua
index 79763b8..fed55e1 100644
--- a/.vim/lua/conf/treesitter.lua
+++ b/.vim/lua/conf/treesitter.lua
@@ -1,9 +1,12 @@
 
 require 'nvim-treesitter.configs'.setup {
-	ensure_installed = { "c", "c_sharp", "lua", "bash" },
+	ensure_installed = { "c", "c_sharp", "javascript", "lua", "bash" },
 	highlight = {
 		enable = false,
 	},
+	indent = {
+		enable = true,
+	},
 	refactor = {
 		navigation = {
 			enable = true,
diff --git a/.vim/lua/plugins.lua b/.vim/lua/plugins.lua
index 1a66299..0ccfb05 100644
--- a/.vim/lua/plugins.lua
+++ b/.vim/lua/plugins.lua
@@ -11,7 +11,7 @@ function disable_distribution_plugins()
   vim.g.loaded_vimball           = 1
   vim.g.loaded_vimballPlugin     = 1
   vim.g.loaded_matchit           = 1
-  vim.g.loaded_matchparen        = 1
+  -- vim.g.loaded_matchparen        = 1
   vim.g.loaded_2html_plugin      = 1
   vim.g.loaded_logiPat           = 1
   vim.g.loaded_rrhelper          = 1
diff --git a/.vim/syntax/gotmpl.vim b/.vim/syntax/gotmpl.vim
index 9e6c1e1..b4bf6b9 100644
--- a/.vim/syntax/gotmpl.vim
+++ b/.vim/syntax/gotmpl.vim
@@ -15,7 +15,7 @@ endif
 
 runtime! syntax/html.vim
 
-syn case match
+" syn case match
 
 " Go escapes
 syn match       goEscapeOctal       display contained "\\[0-7]\{3}"
diff --git a/bin/enter b/bin/enter
index 61c1fb7..9c625a7 100755
--- a/bin/enter
+++ b/bin/enter
@@ -8,6 +8,7 @@ dockerfile="${PWD}/Dockerfile"
 priv=
 opts=
 become=
+verbose=
 
 usage() {
 	printf "usage: %s OPTIONS -- [ARGS]\n" "$(basename "$0")"
@@ -18,12 +19,13 @@ usage() {
 	printf "  -o EXTRA OPTIONS\n"
 	printf "  -D (run with elevated privileged, but not privileged)\n"
 	printf "  -B (don't reassign uid/gid)\n"
+	printf "  -v (be verbose)\n"
 	printf "\n"
 	printf "Enter the container defined in Dockerfile, with \$PWD mounted at /src\n"
 	exit 2
 }
 
-while getopts t:i:f:o:BDh o; do
+while getopts t:i:f:o:vBDh o; do
 	case $o in
 	t) 	target="$OPTARG" ;;
 	i) 	img="$OPTARG" ;;
@@ -31,12 +33,21 @@ while getopts t:i:f:o:BDh o; do
 	o)	opts="$OPTARG" ;;
 	D)	priv=1 ;;
 	B)	become=1 ;;
+	v)	verbose=1 ;;
 	h|?) 	usage ;;
 	esac
 done
 shift $((OPTIND - 1))
 
-[ -z "$img" ] && img="$(basename "$(dirname "$(readlink -f -- "$dockerfile")")")"
+if [ -z "$img" ]; then
+	img="$(basename "$(dirname "$(readlink -f -- "$dockerfile")")")"
+
+	# allow setting this to some non-file value to skip building
+	# > enter -i alpine -f none
+	# for a quick alpine based container with $PWD mounted in
+	[ -f "$dockerfile" ] && \
+		docker build --tag="$img" --target="$target" --file="$dockerfile" "$PWD"
+fi
 
 extra_args=
 [ -n "$become" ] && extra_args="${extra_args} "
@@ -58,17 +69,14 @@ extra_args=
 
 [ -n "$opts" ] && extra_args="${extra_args} ${opts}"
 
-# allow setting this to some non-file value to skip building
-# > enter -i alpine -f none
-# for a quick alpine based container with $PWD mounted in
-[ -f "$dockerfile" ] && \
-	docker build --tag="$img" --target="$target" --file="$dockerfile" "$PWD"
-
 [ -z "$become" ] && \
 	extra_args="${extra_args} --user="$(id -u):$(id -g)""
 
 ep="sh"
 [ -n "$1" ] && { ep="$1"; shift; }
+
+[ -n "$verbose" ] && { set -x; }
+
 exec docker run --rm -it \
 	--entrypoint="$ep" \
 	--mount=type=bind,src="$PWD",dst=/src -w /src $extra_args "$img" $@
diff --git a/bin/firefox b/bin/firefox
index 659b854..ed3ddb9 100755
--- a/bin/firefox
+++ b/bin/firefox
@@ -6,6 +6,7 @@ bin=${FIREFOX_BIN:-firefox-nightly-bin}
 
 # enable touch device support
 export MOZ_USE_XINPUT2=1
+export MOZ_WEBRENDER=1
 
 case "$(basename "$0")" in
     firefox|nightly)
diff --git a/bin/fzfez b/bin/fzfez
index dea63a1..dff86ba 100755
--- a/bin/fzfez
+++ b/bin/fzfez
@@ -6,40 +6,57 @@ if [ ! -f "$exec_hist" ]; then
 	touch "$exec_hist"
 fi
 
+_cat='cat'
+if bat --version >/dev/null; then
+	_cat='bat --color=always --style=numbers,changes'
+fi
+_ls='ls'
+if exa --version >/dev/null; then
+	_ls='exa --classify --group --header --group-directories-first --color=always'
+fi
+
 case "$1" in
+help|-h|--help)
+	printf "usage: fzfez [exec|git-log|git-tag|git-branches|rg|fd|vimwiki|*]\n"
+	exit 1 ;;
+
 exec)
 	uniq "$exec_hist" \
 		| grep -v '^$' \
 		| fzf \
-			--header 'Select or enter a command, {} is previous selection' \
+			--header "${FZFEZ_HEADER:-EXEC:} select or enter a command, {} is \"${FZFEZ_EXEC_SELECTION}\"" \
 			--bind 'tab:replace-query' \
-			--bind 'enter:print-query' \
-		| tee -a $exec_hist \
+			--bind 'esc:print-query' \
+			--bind 'enter:replace-query+accept' \
+		| tee -a $exec_hist >/dev/null \
 		| sed "s#{}#$2#g"  \
-		| sh -s
+		| sh -x -s
 	exit $?
 	;;
 
 _preview)
 	case "$(xdg-mime query filetype "$2")" in
-	inode/directory) 			exa -la "$2" ;;
-	text/*)					head "$2" ;;
-	application/javascript)			head "$2" ;;
-	application/x-shellscript)		head "$2" ;;
-	application/json)			jq "$2" ;;
-	application/x-compressed-tar)		tar -tvf "$2" ;;
-	application/pdf)			pdftotext "$2" - ;;
-	image/*)				mediainfo "$2" ;;
-	video/*|audio/*)			mediainfo "$2" ;;
-	*)					file "$2" ;;
+	inode/directory)                $_ls -la "$2" ;;
+	text/*)                         $_cat "$2" ;;
+	application/javascript)         $_cat "$2" ;;
+	application/x-yaml)             $_cat "$2" ;;
+	application/x-shellscript)      $_cat "$2" ;;
+	application/json)               jq "$2" || $_cat "$2" ;;
+	application/x-compressed-tar)   tar -tvf "$2" ;;
+	application/pdf)                pdftotext "$2" - ;;
+	image/*)                        mediainfo "$2" ;;
+	video/*|audio/*)                mediainfo "$2" ;;
+	*)                              file "$2" ;;
 	esac
 	;;
-_preview2) # invoke mpv/imv for media files
+_preview-detach) # invoke for media files
 	case "$(xdg-mime query filetype "$2")" in
-	image/*)				swx -f imv "$2" ;;
-	video/*|audio/*)			swx -f mpv "$2" ;;
-	application/pdf)			swx -f zathura "$2" ;;
-	*)					$0 exec "$2" ;;
+	inode/directory)   exa -la "$2" ;;
+	image/*)           swx -f mvi "$2" ;;
+	video/*|audio/*)   swx -f mpv "$2" ;;
+	application/pdf)   swx -f zathura "$2" ;;
+	test/*)            swx -t ${EDITOR} "$2" ;;
+	*)                 env FZFEZ_HEADER='PREVIEW-DETACH' $0 exec "$2" ;;
 	esac
 	;;
 
@@ -50,13 +67,12 @@ git-branches)
 		| sed 's#^refs/##' \
 		| sed 's#^remotes/##' \
 		| sed 's#^heads/##' \
-		| $0 \
+		| env FZFEZ_HEADER='BRANCHES:' \
+			$0 \
 			--ansi --no-sort --reverse --tac \
-			--header 'Press ctrl-s to toggle sort' \
-			--bind 'ctrl-s:toggle-sort' \
 			--preview 'git log --color=always --oneline --graph --date=short {} | head -${LINES}' \
 			--preview-window right:70% \
-			--bind "ctrl-o:execute(git checkout {})"
+			--bind "ctrl-o:execute(git checkout {})+abort"
 	;;
 
 git-tags)
@@ -66,7 +82,8 @@ git-tags)
 		| sed 's#^refs/##' \
 		| sed 's#^remotes/##' \
 		| sed 's#^heads/##' \
-		| $0 \
+		| env FZFEZ_HEADER='TAGS:' \
+			$0 \
 			--ansi --no-sort --reverse \
 			--preview 'git show --color=always {} | head -${LINES}' \
 			--preview-window right:70%
@@ -74,7 +91,8 @@ git-tags)
 
 git-log)
 	git log --color=always --oneline \
-		| $0 \
+		| env FZFEZ_HEADER='LOG:' \
+			$0 \
 			--ansi --no-sort --reverse \
 			--preview 'echo {} | cut -d\  -f1 | xargs git show --color=always --pretty=full --stat --patch' \
 			--preview-window right:50% \
@@ -84,11 +102,10 @@ git-log)
 
 rg)
 	shift
-	rg $@ --files-with-matches \
-		| $0 \
-			--header 'Press ctrl-s to toggle sort' \
-			--bind 'ctrl-s:toggle-sort' \
-			--preview "rg $* --color=always --no-filename --glob='{}' --context=5 --line-number"
+	rg --files-with-matches "$@" \
+		| env FZFEZ_HEADER='RG:' \
+			$0 \
+			--preview "rg \"$*\" --color=always --no-filename --glob='{}' --context=5 --line-number"
 	;;
 
 vimwiki)
@@ -96,26 +113,30 @@ vimwiki)
 	fd -t f -e md "${1:-.*}" "$HOME/wiki" \
 		| sed "s#^$HOME/wiki/##" \
 		| sed 's#.md$##' \
-		| $0 \
+		| env FZFEZ_HEADER='VIMWIKI:' \
+			$0 \
 			--print-query \
-			--preview="cat -n $HOME/wiki/{}.md" \
+			--preview="$_cat -n $HOME/wiki/{}.md" \
 		| xargs -r -i nvim +VimwikiIndex +VimwikiGoto\ {}
 	;;
 
 fd)
 	shift
-	fd $@ \
-		| $0 \
+	fd "$@" \
+		| env FZFEZ_HEADER='FD: c-o (xdg-open)' \
+			$0 \
 			--ansi --reverse \
-			--header 'Press ctrl-p to toggle preview, enter for xdg-open' \
-			--bind 'ctrl-p:toggle-preview' \
-			--bind "ctrl-space:execute($0 _preview2 {})" \
-			--preview "$0 _preview {}" \
-			--preview-window ':hidden' \
-		| xargs -r xdg-open
+			--bind "ctrl-o:execute(xdg-open {})+abort" \
+			--preview-window ':hidden'
 	;;
 
 *)
 	fzf \
-		--bind "ctrl-x:execute(${0} exec {})+accept" "$@" ;;
+		--header "${FZFEZ_HEADER:-FZF:} c-x (exec), ? (preview), c-space (preview-detach), c-s (sort)" \
+		--preview "${0} _preview {}" \
+		--preview-window ':hidden' \
+		--bind '?:toggle-preview' \
+		--bind 'ctrl-s:toggle-sort' \
+		--bind "ctrl-space:execute(${0} _preview-detach {})" \
+		--bind "ctrl-x:execute(env FZFEZ_HEADER=EXEC: FZFEZ_EXEC_SELECTION={} ${0} exec {})+accept" "$@" ;;
 esac
diff --git a/bin/grimshot b/bin/grimshot
index 434c97f..f661dad 100755
--- a/bin/grimshot
+++ b/bin/grimshot
@@ -134,11 +134,11 @@ elif [ "$ACTION" = "save" ] ; then
   if [ $? ]; then
     TITLE="Screenshot of $SUBJECT"
     MESSAGE=$(basename "$FILE")
+    wl-copy --type image/png < "$FILE"  || die "Clipboard error"
     notifyOk "$MESSAGE" "$TITLE"
   else
     notifyError "Error taking screenshot with grim"
   fi
-  wl-copy --type image/png < "$FILE"  || die "Clipboard error"
 elif [ "$ACTION" = "rec" ] ; then
   echo "$FILE" | awk '/png$/{exit 0}' && \
     FILE=$(xdg-user-dir VIDEOS)/grimshot/$(now).mp4
diff --git a/bin/lock b/bin/lock
index ecde789..41866a9 100755
--- a/bin/lock
+++ b/bin/lock
@@ -1,11 +1,28 @@
-#!/bin/sh
+#!/bin/bash
+
+set -e
+[ -n "$DEBUG" ] && set -x
 
 main_color="#4E4371"
 clear_color='#afd700'
 ver_color='#5f8787'
 wrong_color='#af005f'
 
-exec swaylock -f \
+# --effect-compose '7.5%,93%;10%x-1;center;/home/robert/Pictures/gentoo-logo/gentoo-horizontal.png'
+# --effect-compose '20%,50%;5%x-1;center;/home/robert/Pictures/hexagon.png'
+# --effect-compose '30%,50%;10%x-1;center;/home/robert/Pictures/gentoo-logo/gentoo-logo.png'
+if swaylock --help 2>&1 | grep effect >/dev/null; then
+    fx_args=(
+        --screenshots
+        --timestr '%H:%M' --datestr '%F'
+        --clock
+        --effect-scale 0.5 --effect-blur 10x5 --effect-scale 2
+        --effect-vignette 0.6:0.3
+        --effect-compose '49%,50%;20%x-1;center;/home/robert/.lock.png'
+    )
+fi
+
+exec swaylock -f ${fx_args[@]} \
     --color=#000000EE \
     --scaling=fill \
     --font=Iosevka\ Sparkle \
@@ -26,14 +43,4 @@ exec swaylock -f \
     --indicator-caps-lock \
     --show-failed-attempts \
     --hide-keyboard-layout \
-    --indicator-idle-visible \
-    --screenshots \
-    --effect-scale 0.5 --effect-blur 10x5 --effect-scale 2 \
-    --effect-vignette 0.6:0.3 \
-    --effect-compose '49%,50%;20%x-1;center;/home/robert/.lock.png' \
-    --clock \
-    --timestr "%H:%M" --datestr "%F"
-
-    # --effect-compose '7.5%,93%;10%x-1;center;/home/robert/Pictures/gentoo-logo/gentoo-horizontal.png' \
-    # --effect-compose '20%,50%;5%x-1;center;/home/robert/Pictures/hexagon.png' \
-    # --effect-compose '30%,50%;10%x-1;center;/home/robert/Pictures/gentoo-logo/gentoo-logo.png' \
+    --indicator-idle-visible
diff --git a/bin/menu b/bin/menu
index 94d886b..82979d5 100755
--- a/bin/menu
+++ b/bin/menu
@@ -38,8 +38,12 @@ done
 passwd_arg=
 [ -n "${MENU_PASSWORD}" ] && passwd_arg=--password
 
+
+# make sure there we are the only running menu
+pgrep "${arg0}" && pkill "${arg0}"
+
+   # --monitor=1 \
 exec "${arg0}" \
-   --monitor=1 \
    --no-overlap \
    --ignorecase \
    --list=10 \
diff --git a/bin/mpvdiff b/bin/mpvdiff
index a218709..9d5ce4a 100755
--- a/bin/mpvdiff
+++ b/bin/mpvdiff
@@ -2,7 +2,8 @@
 set -e
 [ -n "$DEBUG" ] && set -x
 
-args="--title=mpvdiff --hwdec=v4l2m2m-copy"
+# args="--title=mpvdiff --script=~~/scripts/diff"
+args="--title=mpvdiff"
 
 if [ "$1" = "-h" ]; then
 	printf "usage: %s [-2|-4] VIDEO..." "$(basename "$0")"
diff --git a/bin/oguri-cycle b/bin/oguri-cycle
index 495f983..30603a7 100755
--- a/bin/oguri-cycle
+++ b/bin/oguri-cycle
@@ -27,12 +27,14 @@ logger 'oguri-cycle: changing background(s)' || true
 OUTPUTS=( $(swq list output | jq -r '..|select(.transform?=="normal")|.name') )
 BGS=(
 "$HOME/Pictures/animepics/__original_drawn_by_abisswalker8__222dc00159b116c4e8bb6366ab4b677e.png"
-"$HOME/Pictures/animepics/__original_drawn_by_abisswalker8__c6069bdfad7b8f5d57dd1448ef2d85d9.png"
 "$HOME/Pictures/animepics/__original_drawn_by_n_bayashi__bf659af0c196a9fe8539be0f62205cca.jpg"
 "$HOME/Pictures/wallp/1514582672200.jpg"
 "$HOME/Pictures/wallp/1462298633114.jpg"
 "$HOME/Pictures/wallp/dahl_dresden_bei_mondlicht_1788.jpg"
 "$HOME/Pictures/wallp/1585191965174.jpg"
+"$HOME/Pictures/animepics/__original_drawn_by_mita_mitauzo__a225b710fe369391a7cddcf58a614f8f.jpg"
+"$HOME/Pictures/animepics/touhou drawn by cronstatd - 97bde9194d2a7b7cf1fbf9146a4f505f.jpg"
+"$HOME/Pictures/animepics/original drawn by zhuang_yao - ff96be280475dd5098a76fc76c847b27.jpg"
 )
 
 change_bg
@@ -42,6 +44,7 @@ BGS=(
 "$HOME/Pictures/animepics/__original_and_1_more_drawn_by_poppo_sutchy__333475fc9dd799c33f85ca6e73c4e277.png"
 "$HOME/Pictures/animepics/__original_drawn_by_pei_sumurai__a7e972c537eab0898dcbd409f9854b0b.jpg"
 "$HOME/Pictures/animepics/__original_drawn_by_raruru__96312c6d44f35c66ac456428f1ef1c63.jpg"
+"$HOME/Pictures/animepics/original drawn by karanagi - f016c50461614dfd2f3c19b3d7147051.jpg"
 )
 
 change_bg --anchor=left
diff --git a/bin/open b/bin/open
index 9a1eb3f..ba809bf 100755
--- a/bin/open
+++ b/bin/open
@@ -20,39 +20,33 @@ shift $((OPTIND-1))
 
 in="$1"
 
-mime=$(file --mime-type $in | awk -F': ' '{print $2}' )
-ext=$(basename $in | rev | cut -d'.' -f1 | rev)
+mime=$(file --mime-type "$in" | awk -F': ' '{print $2}' )
+ext=$(basename "$in" | rev | cut -d'.' -f1 | rev)
 opener=xdg-open
 
 fork() {
-    exec $@ 1>&2 2>/dev/null &
+    exec $@ >/dev/null 2>&1 &
 }
-
 term() {
     fork alacritty --title="$1" --command "$@"
 }
 
 case $mime in
-    inode/directory)    [ $termmode -eq 0 ] && vifm "$in" || fork nautilus -w "$in" ;;
-    # inode/file)         fork nautilus -w $in ;;
+    inode/directory)    [ $termmode -eq 0 ] && vifm "$in" ;;
+    inode/file)         [ $termmode -eq 0 ] && vifm "$in" ;;
 
-    image/*)            fork sxiv "$in" ;;
-    video/*)            fork mpv --force-widow=yes "$in" ;;
-    audio/*)            fork mpv --force-widow=yes "$in" ;;
+    image/*)            fork mvi "$in" ;;
+    video/*)            fork mpv --force-window=yes "$in" ;;
+    audio/*)            fork mpv --force-window=yes "$in" ;;
 
     application/pdf)    fork zathura "$in" ;;
-    application/vnd.ms-opentype|application/font-sfnt)
-                        fork gnome-font-viewer "$in" ;;
+    # application/vnd.ms-opentype|application/font-sfnt)
+                        # fork gnome-font-viewer "$in" ;;
 
     # now text...
-    text/*)
-        # echo $mime $ext
-        case $ext in
-            md|markdown) fork shiba "$(readlink -f "$in")" ;;
-            desktop) fork gtk-launch "$(basename "$in" | cut -d'.' -f1)" ;;
-            *)           fork term nvim "$in" ;;
-        esac
-        ;;
+    text/md|text/markdown)
+                        fork shiba "$(readlink -f "$in")" ;;
+    text/*)             fork term ${EDITOR} "$in" ;;
 
     # everything else...
     *) exec $opener "$in" ;;
diff --git a/bin/semver b/bin/semver
index cdc993a..19d2a58 100755
--- a/bin/semver
+++ b/bin/semver
@@ -16,6 +16,8 @@ import getopt
 
 simple_tag = False
 force = False
+changelog = True
+
 
 def usage():
     print(f"usage: {sys.argv[0]} OPTIONS COMMANDS")
@@ -24,6 +26,7 @@ OPTIONS:
 \t-h\tshow this help
 \t-t\tonly create a simple tag, otherwise annotate as well
 \t-f\toverwrite existing tag
+\t-c\tdon't write changelog
 
 COMMANDS:
 \tpatch
@@ -34,16 +37,18 @@ COMMANDS:
 
 
 try:
-    opts, argv = getopt.getopt(sys.argv[1:], 'tfh')
+    opts, argv = getopt.getopt(sys.argv[1:], 'tfch')
 except getopt.GetoptError as err:
     print(err)
     usage()
 
 for o, val in opts:
     if o == "-t":
-        simple_tag = True
+        simple_tag = not force
     elif o == "-f":
-        force = True
+        force = not force
+    elif o == "-c":
+        changelog = not changelog
     elif o == "-h":
         usage()
     else:
@@ -55,7 +60,8 @@ if subprocess.run(["git", "branch", "--show-current"],
 
 subprocess.run(["git", "pull", "--rebase"])
 
-p = subprocess.run(["git", "describe", "--abbrev=0", "--tags"], stdout=subprocess.PIPE)
+p = subprocess.run(["git", "describe", "--abbrev=0", "--tags"],
+                   stdout=subprocess.PIPE)
 describe = p.stdout.decode().strip()
 # TODO also ask to re-append the trailing portion.... e.g. -rev1
 old_version = describe.split("-")[0].split(".")
@@ -68,7 +74,9 @@ elif len(old_version) == 3:
     [major, minor, patch] = map(int, [major, minor, patch])
 
 else:
-    print(f"WARNING: git describe returned invalid semver version: \"{describe}\"")
+    print(
+        f"WARNING: git describe returned invalid semver version: \"{describe}\""
+    )
     # sys.exit(1)
     # old_version = [0, 0, 0]
 
@@ -125,5 +133,16 @@ else:
     args.extend([new_version])
     subprocess.run(args)
 
+if changelog:
+    import time
+    now = time.strftime("%Y-%m-%d", time.localtime())
+    with open("CHANGELOG", "r+") as f:
+        data = f.read()
+        f.seek(0)
+        f.write(f"\n{new_version} ({now})\n\n")
+        f.write(shortlog)
+        f.write(data)
+        f.flush()
+
 print(args)
 print(new_version)
diff --git a/bin/swx b/bin/swx
index dfe852f..284e5c7 100755
--- a/bin/swx
+++ b/bin/swx
@@ -123,7 +123,9 @@ if [ -n "${rotate}" ]; then
 fi
 
 if [ -n "${autotile}" ]; then
-	case "$(swq current workspace | jq -r '.layout')" in
+	layout=$(swq current con | jq -r '.layout')
+	# swq current workspace | jq -r '.. | select(.type?=="con" and .name?==null) | .layout'
+	case "${layout}" in
 	split*)
 		if [ "$(swq current con | jq '.rect | .width > .height')" = "true" ]; then
 			swaymsg splith
diff --git a/bin/trash b/bin/trash
index 5b810c1..4a1de6e 100755
--- a/bin/trash
+++ b/bin/trash
@@ -1,5 +1,4 @@
 #!/bin/sh
-
 set -e
 
 TRASH="$HOME/.trash"
@@ -34,20 +33,42 @@ yes | $0 --empty
 EOF
 }
 
+ask() {
+    r=$(printf 'yes\nno\n' | MENU_PROMPT="delete $1" menu)
+    [ "${r}" = "yes" ] && return 0
+    return 1
+}
+
+interactive=${TRASH_ASK:-}
+trashrm=${TRASH_RM:-}
+
 case "$1" in
     -e|--empty)
         empty_trash
         exit 0 ;;
-    -i|--install)
+    --install)
         install_auto_empty
         exit 0 ;;
+    -i)
+        interactive=1
+        shift ;;
     -h|--help)
         echo "usage: trash [-e|--empty] FILE..."
         exit 1 ;;
 esac
 
+set -x
+
 # main
-for f in "$@"; do
+while test $# -gt 0; do
+    f="$1" ; shift
+
+    [ -n "${interactive}" ] && { ask "$f" || continue; }
+
     echo "+ $(basename "$f")"
-    mv "$f" "$TRASH/"
+    if [ -z "${trashrm}" ]; then
+        rm "$f"
+    else
+        mv "$f" "$TRASH/"
+    fi
 done
diff --git a/bin/vncez b/bin/vncez
index 068a199..f82f524 100755
--- a/bin/vncez
+++ b/bin/vncez
@@ -1,10 +1,11 @@
 #!/bin/sh
 set -e
+[ -n "$DEBUG" ] && set -x
 
 if [ -n "$1" ]; then
 	printf "usage: %s\n" "$(basename "$0")"
 	printf "\n"
-	printf "launches wayvnc(1), wshowkeys(1) and remmina(1)\n"
+	printf "launches a vnc server and client, creating a loopback X window\n"
 	exit 2
 fi
 
@@ -13,16 +14,18 @@ if [ -n "$OUTPUT" ]; then
 	server_args="-o ${OUTPUT}"
 fi
 
-trap '{ printf "\n=> killing everything...\n"; pkill wayvnc; pkill gvncviewer; }' EXIT
+
+trap '{ printf "\n=> killing everything...\n"; }' INT
+trap '{ killall -9 wayvnc gvncviewer; notify-send "stopped output mirror" "cleaned up viewer window and workspace"; }' EXIT
 
 # echo "=> starting wshowkeys"
 # swaymsg exec "wshowkeys -a bottom -a left -F 'Iosevka Sparkle 25' -t 1" >/dev/null
 echo "=> starting wayvnc"
-swaymsg exec "wayvnc -c dmabuf -r ${server_args} 0.0.0.0" >/dev/null
+swaymsg exec "wayvnc -r ${server_args} 0.0.0.0"
 echo "=> starting viewer"
-swx -b none -S -F '1.0 tl' -- x11fy gvncviewer localhost
+swx -w __vnc -- x11fy gvncviewer "0.0.0.0"
 
-notify-send 'started screensharing' 'the vnc viewer window was moved to the scratchpad'
+notify-send 'started output mirror' 'the vnc viewer X window was moved to new workspace\nyou can screen cast the desktop using it'
 while true; do
 	sleep $((1024*1024))
 done
diff --git a/bin/wfez b/bin/wfez
index 50f485d..eac1b55 100755
--- a/bin/wfez
+++ b/bin/wfez
@@ -2,37 +2,68 @@
 set -e
 [ -n "$DEBUG" ] && set -x
 
-if [ "$1" = "-h" ]; then
-	printf "usage: %s [FILE]\n" "$(basename "$0")"
-	printf "\n"
-	printf "Launches wf-recorder(1) with optimized settings.\n"
-	printf "If FILE is omitted, \$HOME/Videos/rec_TIMESTAMP.mkv is used.\n"
-	printf "Optionally environment vars can be used to tune things:\n"
-	printf "  WF_AOUT - defaults to default pulseaudio sink\n"
-	printf "  WF_AIN - defaults to default pulseaudio source\n"
-	printf "  WF_AMUX - override creation of an pulseaudio sink for muxing\n"
-	printf "  WF_VOUT - limit to output, defaults to focused output (swq current output)\n"
-	printf "  WF_KEYS - launches wshowkeys(1)\n"
-	exit 2
-fi
+# check requirements
+for tool in wf-recorder wshowkeys pactl swq; do
+	if ! command -v "$tool" >/dev/null; then
+		printf "%s: %s not installed but required\n" "$(basename "$0")" "$tool" >&2
+		exit 1
+	fi
+done
+
+
 
-output_file=${1:-"${HOME}/Videos/rec_$(now).mkv"}
 audio_output=${WF_AOUT}
 audio_input=${WF_AIN}
 video_output=${WF_VOUT}
 showkeys=${WF_KEYS}
 mux_sink=${WF_AMUX}
+no_mux=
+
+while getopts i:o:m:v:kMh opt; do
+	case "$opt" in
+	i)	# audio in
+		audio_input="${OPTARG}" ;;
+	o)	# audio out
+		audio_output="${OPTARG}" ;;
+	m)	# mux
+		mux_sink="${OPTARG}" ;;
+	v)	# output to record
+		video_output="${OPTARG}" ;;
+	k)	# showkeys
+		showkeys=1 ;;
+	M)	# no mux
+		no_mux=1 ;;
+	h|?)
+		printf "usage: %s [-iomvkM] [FILE]\n" "$(basename "$0")"
+		printf "\n"
+		printf " Launches wf-recorder(1) with optimized settings.\n"
+		printf " When FILE is omitted, \$HOME/Videos/rec_TIMESTAMP.mkv is used.\n"
+		printf "\n"
+		printf " -o \t\taudio output; defaults to default pulseaudio sink\n"
+		printf " -i \t\taudio input; defaults to default pulseaudio source, can be 'none'\n"
+		printf " -m \t\taudio mux sink; override creation of an pulseaudio sink for muxing\n"
+		printf " -v \t\toutput to record; limit to output, defaults to focused output (swq current output)\n"
+		printf " -k \t\tlaunches wshowkeys(1)\n"
+		printf " -M \t\tdon't create a audio mux sink\n"
+		printf "\n"
+		exit 2 ;;
+	esac
+done
+shift $((OPTIND - 1))
 
-[ -z "${audio_output}" ] && audio_output=$(pacmd dump | grep "set-default-sink" | cut -d' ' -f2)
-[ -z "${audio_input}" ] && audio_input=$(pacmd dump | grep "set-default-source" | cut -d' ' -f2)
+output_file=${1:-"${HOME}/Videos/rec_$(now).mkv"}
+
+# setup defaults
+[ -z "${audio_output}" ] && audio_output=$(pactl info | grep "Default Sink" | cut -d':' -f2 | xargs -L1)
+[ -z "${audio_input}" ] && audio_input=$(pactl info | grep "Default Source" | cut -d':' -f2 | xargs -L1)
 [ -z "${video_output}" ] && video_output=$(swq current output)
 
-if [ "${WF_AIN}" = "none" ] && [ -z "${WF_AMUX}" ]; then
+if [ "${audio_input}" = "none" ] && [ -z "${mux_sink}" ]; then
 	echo "mux: ${audio_output}"
 	mux_sink="${audio_output}"
 fi
 
-if [ -z "${mux_sink}" ]; then
+if [ -z "${mux_sink}" ] && [ -z "${no_mux}" ]; then
 	mux_sink=wf-mux
 	mux_sink_id=
 	output_loopback_id=
@@ -40,7 +71,7 @@ if [ -z "${mux_sink}" ]; then
 	prepare_mux_sink() {
 		mux_sink_id=$(pactl load-module module-null-sink sink_name="${mux_sink}" channels=2)
 		output_loopback_id=$(pactl load-module module-loopback sink="${mux_sink}" source="${audio_output}.monitor" remix=true)
-		input_loopback_id=$(pactl load-module module-loopback sink="${mux_sink}" source="${audio_input}" remix=true)
+		input_loopback_id=$(pactl load-module module-loopback sink="${mux_sink}" source="${audio_input}" channels=1 remix=true)
 	}
 	teardown_mux_sink() {
 		pactl unload-module "${mux_sink_id}"
@@ -52,6 +83,10 @@ if [ -z "${mux_sink}" ]; then
 	echo "mux: ${mux_sink}"
 fi
 
+if [ -n "${no_mux}" ]; then
+	mux_sink="${audio_output}.monitor"
+fi
+
 if [ -n "${showkeys}" ]; then
 	echo "Starting wshowkeys on ${video_output}"
 	echo "WARNING: currently the -o flag to force display to a specific output is not implemented" >&2
@@ -61,4 +96,4 @@ if [ -n "${showkeys}" ]; then
 fi
 
 set -x
-wf-recorder -c h264_vaapi -d /dev/dri/renderD128 -o "${video_output}" -a "${mux_sink}.monitor" -f "${output_file}"
+wf-recorder -c h264_vaapi -d /dev/dri/renderD128 -x nv12 -o "${video_output}" -a "${mux_sink}.monitor" -f "${output_file}"
diff --git a/bin/xdg-exec b/bin/xdg-exec
index 787c502..e8f3ccb 100755
--- a/bin/xdg-exec
+++ b/bin/xdg-exec
@@ -1,7 +1,24 @@
 #!/bin/sh
+#
+# DESCRIPTION:
+#  parses a .desktop file, that matches in name to `$0`
+#  and executes the `Exec` value.
+#
+# INSTALL:
+#  ln -s <path/to/this/script> /usr/local/bin/app.desktop
+#
+
+XDG_DESKTOP_ENTRY_DIR=$HOME/.local/share/applications
 set -ex
 basepath=$(dirname "$0" | sed 's#/bin#/share/applications#')
 basename=$(basename "$0" | sed -e 's/^_//' -e 's/.desktop$//')
-desktop=${basepath}/${basename}.desktop
-bin=$(awk '/TryExec=/{split($0,l,"="); if (not system("command -v l[2]")){exit 1}} /Exec=/{print substr($0, index($0,"=")+1)}' "$desktop" | tr -d '\n' | sed "s/%.$//")
-exec $bin
+if [ -e "${XDG_DESKTOP_ENTRY_DIR}/${basename}.desktop" ]; then
+				desktop=${XDG_DESKTOP_ENTRY_DIR}/${basename}.desktop
+else
+				desktop=${basepath}/${basename}.desktop
+fi
+bin=$(awk '
+/^TryExec=/{split($0,l,"="); if(not system("command -v l[2]")){exit 1}}
+/^Exec=/{printf gensub(/Exec=([^%]+).*$/, "\\1", "")}
+' "$desktop" | sed 's/%.$//')
+exec ${bin} $@