commit - 8727e48c019cbf81e7b9290bb08459ac5b512d65
commit + af8af444582ea33ed63a21a78329af59e191db4f
blob - e39dca1bf2bde6b5093f9678e00a62433ca1f20a
blob + dc2adffeb301cdd13645a7daf8bd99bf7ecce2a1
--- flake.lock
+++ flake.lock
]
},
"locked": {
- "lastModified": 1784030718,
- "narHash": "sha256-6EvmUvmyG6ciz71anFi+KbH3JZf8Z0SeI1jVb2u8Rgo=",
+ "lastModified": 1784049068,
+ "narHash": "sha256-nvO5rN+SWdpVGY1OIFziAz8JaTl265lgSRlPnQCciIc=",
"owner": "~mtmn",
"repo": "corpus",
- "rev": "2f4f1bb6530a517dd155e2fcf7d2aa93f8343e15",
+ "rev": "4a464dc7ea2c23ef107e4b2d9f5cc6c840c52e26",
"type": "sourcehut"
},
"original": {
blob - 92754fba4f0c97d4edd1bf914c5bf0492cf02c3c
blob + 4b23cbe5c0b76e3801826dbe54d702f724404753
--- hosts/void/overlays/bin/mics
+++ hosts/void/overlays/bin/mics
-#!/bin/sh
-sw=numid=7
+#!/bin/bash -e
-cur=$(amixer -c 1 cget "$sw" | sed -n 's/.*: values=\(on\|off\).*/\1/p' | head -1)
+usage() {
+ echo "Usage: mics mute|unmute [seconds]"
+ exit 1
+}
-if [ "$cur" = off ]; then
- amixer -c 1 cset "$sw" on >/dev/null
- printf '%s\n' "mic unmuted"
+cmd=${1:-mute}
+
+if [ "$cmd" != "mute" ] && [ "$cmd" != "unmute" ]; then
+ usage
+fi
+
+indices=$(pactl list short sources | awk '{print $1}')
+
+if [ "$cmd" = "mute" ]; then
+ echo "$indices" | xargs -I{} pactl set-source-volume {} 0%
else
- amixer -c 1 cset "$sw" off >/dev/null
- printf '%s\n' "mic muted"
+ time=$2
+ echo "$indices" | xargs -I{} pactl set-source-volume {} 100%
+ if [ "$time" ]; then
+ sleep "$time"
+ echo "$indices" | xargs -I{} pactl set-source-volume {} 0%
+ fi
fi
+
+echo "Current microphone status:"
+echo "$indices" | while read -r idx; do
+ echo "Source $idx:"
+ echo " $(pactl get-source-mute "$idx")"
+ echo " $(pactl get-source-volume "$idx")"
+done
blob - c75f4db815840fec3f55eaf3a98a25db91c671f9 (mode 644)
blob + /dev/null
--- hosts/void/overlays/bin/otterb
+++ /dev/null
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-require "fileutils"
-require "open3"
-require "etc"
-
-class Builder
- REPO = "https://repo-default.voidlinux.org/current"
- DEPS = %w[
- cmake
- make
- gcc
- qt5-devel
- qt5-svg-devel
- qt5-multimedia-devel
- qt5-declarative-devel
- qt5-webengine
- qt5-webengine-devel
- qt5-webkit-devel
- qt5-webchannel-devel
- qt5-location-devel
- hunspell-devel
- gstreamer1-devel
- libxml2-devel
- qt5-tools
- ]
- .freeze
-
- def initialize(argv)
- @outdir = nil
- @chroot = "/var/chroot/otter-build"
- @keep = false
- @quiet = false
- parse(argv)
- validate
- end
-
- def run
- bootstrap
- mount_vfs
- prep_chroot
- install_deps
- build
- extract
- ensure
- unmount_vfs
- remove_chroot unless @keep
- msg("done.")
- end
-
- private
-
- def parse(argv)
- i = 0
- while i < argv.length
- case argv[i]
- when "-o"
- @outdir = argv[i += 1]
- when "-c"
- @chroot = argv[i += 1]
- when "-k"
- @keep = true
- when "-q"
- @quiet = true
- when "-h", "--help"
- usage(code: 0)
- else
- usage
- end
-
- i += 1
- end
- end
-
- def usage_lines
- [
- "Usage: #{File.basename($0)} [-o DIR] [-c DIR] [-k] [-q]",
- " -o DIR output directory (default: invoking user home)",
- " -c DIR chroot directory (default: /var/chroot/otter-build)",
- " -k keep chroot after build",
- " -q quiet"
- ]
- end
-
- def usage(code: 1)
- usage_lines.each { |l| puts(l) }
- exit(code)
- end
-
- def validate
- unless Process.uid.zero?
- usage_lines.each { |l| puts(l) }
- die("must run as root")
- end
-
- @src = Dir.pwd
- die("no CMakeLists.txt in #{@src}") unless File.file?(File.join(@src, "CMakeLists.txt"))
-
- inv = ENV["SUDO_USER"] || ENV["DOAS_USER"]
- if inv
- @pw = Etc.getpwnam(inv) rescue nil
- die("cannot resolve user #{inv}") unless @pw
- @outdir ||= @pw.dir
- else
- @outdir ||= File.expand_path("~")
- end
- end
-
- def msg(s) = puts(s) unless @quiet
-
- def die(s)
- $stderr.puts("#{File.basename($0)}: #{s}")
- exit(1)
- end
-
- def run_cmd(cmd, fatal: true)
- msg(cmd)
- _o, e, st = Open3.capture3(cmd)
- die("#{cmd}: #{e.strip}") if !st.success? && fatal
- st.success?
- end
-
- def chroot_cmd(script)
- msg("chroot #{@chroot} /bin/bash -c '#{script}'")
- die("chroot command failed") unless system("chroot #{@chroot} /bin/bash -c '#{script}'")
- end
-
- def bootstrap
- FileUtils.mkdir_p(@chroot)
- return if File.executable?(File.join(@chroot, "bin/bash"))
-
- msg("bootstrapping chroot...")
- kdir = File.join(@chroot, "var/db/xbps/keys")
- FileUtils.mkdir_p(kdir)
- Dir.glob("/var/db/xbps/keys/*").each { |f| FileUtils.cp(f, kdir) }
-
- run_cmd("xbps-install -Syu -R #{REPO} -r #{@chroot} base-voidstrap", fatal: false)
- die("bootstrap failed") unless File.executable?(File.join(@chroot, "bin/bash"))
- msg("bootstrap ok")
- end
-
- def mount_vfs
- mounts = {
- File.join(@chroot, "proc") => ["-t", "proc", "proc"],
- File.join(@chroot, "sys") => ["-t", "sysfs", "sys"],
- File.join(@chroot, "dev") => ["--bind", "/dev"]
- }
- mounts.each do |dst, opts|
- FileUtils.mkdir_p(dst)
- next if system("mountpoint -q #{dst} 2>/dev/null")
- system("mount #{opts.join(" ")} #{dst}")
- end
- end
-
- def unmount_vfs
- %w[dev sys proc].each { |n| system("umount #{File.join(@chroot, n)} 2>/dev/null") }
- end
-
- def prep_chroot
- FileUtils.cp("/etc/resolv.conf", File.join(@chroot, "etc/resolv.conf"))
- kdir = File.join(@chroot, "var/db/xbps/keys")
- FileUtils.mkdir_p(kdir)
- Dir.glob("/var/db/xbps/keys/*").each { |f| FileUtils.cp(f, kdir) }
- end
-
- def install_deps
- chroot_cmd("xbps-install -Syu")
- chroot_cmd("xbps-install -S #{DEPS.join(" ")}")
- end
-
- def build
- dst = File.join(@chroot, "src/otter-browser")
- FileUtils.rm_rf(dst)
- FileUtils.mkdir_p(File.dirname(dst))
- system("cp -a #{@src} #{dst}") || die("copy failed")
-
- cm = File.join(dst, "CMakeLists.txt")
- txt = File.read(cm)
- unless txt.include?("FATAL_ON_MISSING_REQUIRED_PACKAGES")
- die("CMakeLists.txt: FATAL_ON_MISSING_REQUIRED_PACKAGES not found")
- end
-
- txt.gsub!("FATAL_ON_MISSING_REQUIRED_PACKAGES", "")
- File.write(cm, txt)
-
- script = "set -e; cd /src/otter-browser; rm -rf build; mkdir build; cd build; cmake -DENABLE_QT5=ON ../; make -j$(nproc)"
- chroot_cmd(script)
- end
-
- def extract
- bin = File.join(@chroot, "src/otter-browser/build/otter-browser")
- die("binary not found") unless File.file?(bin)
-
- out = File.join(@outdir, "otter-browser")
- system("cp #{bin} #{out}") || die("copy binary failed")
- FileUtils.chmod("+x", out)
-
- if @pw
- begin
- File.chown(@pw.uid, @pw.gid, out)
- rescue => e
- msg("chown failed: #{e}")
- end
- end
-
- msg("binary: #{out}")
- end
-
- def remove_chroot
- msg("removing #{@chroot}...")
- FileUtils.rm_rf(@chroot)
- end
-end
-
-Builder.new(ARGV).run
blob - ee6c7a7b0ffbad97cfc990add38df7b78472982b
blob + 48b410ec42d1892bf13c48b3cdb3537815a2fc7b
--- hosts/void/overlays/config/river/init
+++ hosts/void/overlays/config/river/init
riverctl map normal $mod Tab focus-previous-tags
riverctl map normal $mod+Shift Tab send-to-previous-tags
-swaybg -m fill -c "#0d1612" -i "$HOME/misc/random/wallpapers/curtains.jpg" &
-mkfifo "$wobsock" && tail -f "$wobsock" | wob &
-wl-paste --watch cliphist store &
-
-services_to_start=(
- battery-notify
- fnott
- pipewire
- kanshi
- psi-notify
- memcached
- nix-daemon
-)
-
-for s in "${services_to_start[@]}"; do
- "$s" 2>&1 | vlogger -t "$s" &
-done
+runsvdir "$HOME/.config/sv" &
blob - /dev/null
blob + d7890f835d0920aa84eff1ca11382994d8849dfc (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/battery-notify.scm
+;; -*- mode: scheme; -*-
+(exec-service 'battery-notify '("battery-notify"))
blob - /dev/null
blob + 3dd1f9669954f510716dde7a90b1be4a49957454 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/cliphist.scm
+;; -*- mode: scheme; -*-
+(exec-service 'cliphist '("wl-paste" "--watch" "cliphist" "store"))
blob - /dev/null
blob + 0ee7387bd902c2edca98407c2596ae79f521ae0f (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/fnott.scm
+;; -*- mode: scheme; -*-
+(exec-service 'fnott '("fnott"))
blob - /dev/null
blob + 990f67e1094a6021172cd1b0b715b029df87ab59 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/hister.scm
+;; -*- mode: scheme; -*-
+(exec-service 'hister '("hister" "listen"))
blob - /dev/null
blob + a33c316e34352b8463d3eb91564168370a34cac9 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/kanshi.scm
+;; -*- mode: scheme; -*-
+(exec-service 'kanshi '("kanshi"))
blob - /dev/null
blob + 09304c6911eff2c72925319adcd8eefc2716e8db (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/memcached.scm
+;; -*- mode: scheme; -*-
+(exec-service 'memcached '("memcached"))
blob - /dev/null
blob + e339da50cbe82c2f9ce4ef4d7fe2072de8b9c814 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/nix-daemon.scm
+;; -*- mode: scheme; -*-
+(exec-service 'nix-daemon '("nix-daemon"))
blob - /dev/null
blob + dc458a7d0d58fdb438904bd22447d4e55c4717a5 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/pipewire.scm
+;; -*- mode: scheme; -*-
+(exec-service 'pipewire '("pipewire"))
blob - /dev/null
blob + 7fa8d625de9bdf259ba9d88c1201f98d748e18bd (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/psi-notify.scm
+;; -*- mode: scheme; -*-
+(exec-service 'psi-notify '("psi-notify"))
blob - /dev/null
blob + 05e9f3832b683dfdfe602e91415e0269e1c42328 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/swaybg.scm
+;; -*- mode: scheme; -*-
+(exec-service 'swaybg
+ (list "swaybg" "-m" "fill" "-c" "#0d1612"
+ "-i" (string-append (getenv "HOME")
+ "/misc/random/wallpapers/curtains.jpg")))
blob - /dev/null
blob + 9bd2f907e28d3de02df2aacf7f787039b2c0c043 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/wob.scm
+;; -*- mode: scheme; -*-
+;; wob reads volume/brightness levels from a FIFO at $XDG_RUNTIME_DIR/wob.sock
+(exec-service
+ 'wob
+ (list "sh" "-c"
+ (string-append
+ "sock=\"$XDG_RUNTIME_DIR/wob.sock\"; "
+ "[ -p \"$sock\" ] || mkfifo \"$sock\"; "
+ "exec sh -c 'tail -f \"$1\" | wob' _ \"$sock\"")))
blob - /dev/null
blob + 740c3450d99aac3e5b09f96119cfd9ff9f9283e0 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.scm
+;; -*- mode: scheme; -*-
+;;; ~/.config/shepherd/init.scm
+
+(use-modules (shepherd service)
+ (shepherd support)
+ ((ice-9 ftw) #:select (scandir)))
+
+(default-environment-variables (environ))
+
+;; Per-service log files live here as <name>.log
+(mkdir-p %user-log-dir)
+
+(define* (exec-service name command #:key (respawn? #t))
+ (let ((svc (service (list name)
+ #:documentation (string-append "Run " (symbol->string name) ".")
+ #:start (make-forkexec-constructor
+ command
+ #:log-file (string-append %user-log-dir "/"
+ (symbol->string name) ".log"))
+ #:stop (make-kill-destructor)
+ #:respawn? respawn?)))
+ (register-services (list svc))
+ (start-service svc)))
+
+;; Send Shepherd to the background
+(perform-service-action root-service 'daemonize)
+
+;; Load every ~/.config/shepherd/init.d/*.scm file
+(let ((init.d (string-append %user-config-dir "/init.d")))
+ (for-each (lambda (file)
+ (load (string-append init.d "/" file)))
+ (scandir init.d
+ (lambda (file) (string-suffix? ".scm" file)))))
blob - 861b5e9fe5887e520fef1c1ba48ae802cab5470a
blob + e4c6eea62d3d66878d16ca5f507223971ef5f0e9
--- hosts/void/overlays/config/volare/config
+++ hosts/void/overlays/config/volare/config
bindsym --locked XF86MonBrightnessUp exec sh -c 'brightnessctl set +5% | sed -En "s/.*\(([0-9]+)%\).*/\1/p" > $wobsock'
bindsym --locked XF86MonBrightnessDown exec sh -c 'brightnessctl set 5%- | sed -En "s/.*\(([0-9]+)%\).*/\1/p" > $wobsock'
-exec swaybg -m fill -c "#0d1612" -i "$HOME/misc/random/wallpapers/curtains.jpg"
-exec sh -c 'mkfifo $wobsock 2>/dev/null; tail -f $wobsock | wob'
-exec wl-paste --watch cliphist store
+exec shepherd
-exec battery-notify
-exec fnott
-exec pipewire
-exec kanshi
-exec psi-notify
-exec memcached
-exec nix-daemon
-exec hister listen
-
font Fragment Mono 10
bar {
blob - /dev/null
blob + dd170015435b965bf885c4000ff40c694807ed5c (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/bin/ffmpeg-cut
+#!/bin/bash -e
+
+# Takes a file with lines like:
+#
+# VID_20240630_143147_036.mp4
+# VID_20240630_144842_041.mp4 01:45
+# VID_20240630_145538_042.mp4 01:00 01:50
+#
+# ...and extracts them into another folder.
+#
+# The keyframe seeking is imprecise, but with the Ace Pro it's close enough
+# that it doesn't matter.
+
+while getopts ":i:o:" opt; do
+ case $opt in
+ i) input_dir="$OPTARG"
+ ;;
+ o) output_dir="$OPTARG"
+ ;;
+ \?) echo "Invalid option -$OPTARG" >&2
+ exit 1
+ ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+file_list="$1"
+
+if [[ -z "$input_dir" || -z "$output_dir" || -z "$file_list" ]]; then
+ echo "Usage: $0 -i input_dir -o output_dir file_list"
+ exit 1
+fi
+
+time_to_seconds() {
+ IFS=: read -r m s <<< "$1"
+ echo $((10#${m:-0} * 60 + 10#${s:-0}))
+}
+
+while IFS=' ' read -r file start end; do
+ if [[ -z "$file" ]]; then
+ echo "File name is empty" >&2
+ exit 1
+ fi
+
+
+ input_file="$input_dir/$file"
+
+ if ! [[ -f "$input_file" ]]; then
+ echo "$input_file does not exist" >&2
+ exit 1
+ fi
+
+ base_name=$(basename "$file" .mp4)
+ if [[ -n "$start" && -n "$end" ]]; then
+ start_formatted=$(echo "$start" | tr -d ':')
+ end_formatted=$(echo "$end" | tr -d ':')
+ output_file="$output_dir/${base_name}_${start_formatted}_${end_formatted}.mp4"
+ elif [[ -n "$start" ]]; then
+ start_formatted=$(echo "$start" | tr -d ':')
+ output_file="$output_dir/${base_name}_${start_formatted}.mp4"
+ else
+ output_file="$output_dir/$file"
+ fi
+
+ cmd=("ffmpeg" "-nostdin")
+
+ if [[ -n "$start" ]]; then
+ cmd+=("-ss" "$start")
+ fi
+
+ cmd+=("-i" "$input_file" "-muxpreload" "0" "-muxdelay" "0")
+
+ if [[ -n "$end" ]]; then
+ start_seconds=$(time_to_seconds "$start")
+ end_seconds=$(time_to_seconds "$end")
+ relative_end_seconds=$((end_seconds - start_seconds))
+ cmd+=("-to" "$relative_end_seconds")
+ fi
+
+ cmd+=("-c" "copy" "$output_file")
+
+ echo "${cmd[@]}"
+ "${cmd[@]}"
+done < "$file_list"
blob - /dev/null
blob + 2fccc51f0d56aa55ae2fb7c7afbaffbed6c5cec1 (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/bin/ffmpeg-merge
+#!/bin/bash -ex
+
+out=${1?}
+shift
+
+# Need to put working directory in or ffmpeg will think it's relative to the
+# named pipe in /proc...?
+ffmpeg -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" "$@") -c copy "$out"
blob - 03e286932f1adbc0b9c082eb822d4d739ced7652
blob + 000de57cf5ecb30b22f75e21bdf4f2257189cf58
--- modules/mixins/dotfiles/bin/isolate
+++ modules/mixins/dotfiles/bin/isolate
"$HOME/.config" \
"$HOME/.gitconfig" \
"$HOME/.local/bin" \
- "$HOME/.local/share/tools" \
"$HOME/.cache/zig" \
"$HOME/.rustup" \
"$HOME/.nix-profile"; do
blob - /dev/null
blob + c97eeae4858b91d27cc85a31042595eb9ac9a183 (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/bin/plane
+#!/usr/bin/env bash
+
+# Base mp3 is from donation export from https://mynoise.net/NoiseMachines/rainNoiseGenerator.php?c=2&l=2420212127302925252300&m=&d=0
+# This is then cut +10 from beginning/-10 from end to get rid of fades, so it can be looped:
+#
+# ffmpeg -i myNoise_RAIN_24202121273029252523_0_5.mp3 -vn -acodec copy -ss 00:10 -to 04:10 rain.mp3
+#
+# We play with --no-config to avoid normalisation settings that are mostly for video
+# You'll also want to go into Audacity or similar and cut off the silence
+
+exec mpv --quiet --no-config --loop-file --no-audio-display --no-resume-playback ~/plane.mp3
blob - /dev/null
blob + 16e6e9e014cee32c35086abe5445f46d054d597b (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/bin/sprunge
+#!/bin/bash -e
+
+curl --data-binary @- https://paste.rs/
+printf "\n"
blob - /dev/null
blob + 35152ea411a04c5298245af0ed2fccbb0b12e04e (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/bin/thunder
+#!/usr/bin/env bash
+
+# Base mp3 is from donation export from https://mynoise.net/NoiseMachines/rainNoiseGenerator.php?c=2&l=2420212127302925252300&m=&d=0
+# This is then cut +10 from beginning/-10 from end to get rid of fades, so it can be looped:
+#
+# ffmpeg -i myNoise_RAIN_24202121273029252523_0_5.mp3 -vn -acodec copy -ss 00:10 -to 04:10 rain.mp3
+#
+# We play with --no-config to avoid normalisation settings that are mostly for video
+# You'll also want to go into Audacity or similar and cut off the silence
+
+exec mpv --quiet --no-config --loop-file --no-audio-display --no-resume-playback ~/misc/thunder.mp3