Commit Diff


commit - 1d434cf63b09f46667894a977873fca5122c465c
commit + 838681870e6b49fa8e7c76cd83928a00fd702b3d
blob - bb906d8c5ab9ec57d39fbbd42bd542b191dfb7e1
blob + bd6b991bd2d3ae07543e0122b49c35b1bd23d224
--- flake.lock
+++ flake.lock
@@ -250,11 +250,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1785301185,
-        "narHash": "sha256-eoS3KQTO0aPWXZvIaRbRAzSSHW3l5wdMFXtT1ISfoKA=",
+        "lastModified": 1785452004,
+        "narHash": "sha256-k94ksv7XmaLeK5sE1ST/TTdu2aDEO9sfbcgEaNJPTXA=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "9bc02893134c733dd85de46ee4fb2fac696b5529",
+        "rev": "a5e9f2fd9ef6011c6886d6935f3ef678c81385fa",
         "type": "github"
       },
       "original": {
blob - b18bbe3e9e719b5c5c7d424c78f08865c61e1e1b
blob + 9d0922aaac136a9cb988b9a43f5943812b27d150
--- hosts/void/default.nix
+++ hosts/void/default.nix
@@ -110,6 +110,7 @@
       winbox
       stunnel
       minica
+      botan3
     ];
 
     media = [
blob - 3ec368b17031d06c75994965fbece8e984aeec8f
blob + 6bc987bc573e7a9f5fe48df91e6032873eb4d20e
Binary files hosts/void/overlays/config/magdalena/config.json.nix and hosts/void/overlays/config/magdalena/config.json.nix differ
blob - e85f6fe1f31ba7acf03b328583f911e6b9548cac
blob + 855d562dbac4add11589c1dc335ccea4fe6c9404
Binary files hosts/void/overlays/config/plakar/sources.yml and hosts/void/overlays/config/plakar/sources.yml differ
blob - 0abd3e8d77a8d393b21b6a0744ed25ea81db05ae
blob + 1ecdba901addc7463c6d3c011861cffcedbcfa95
Binary files hosts/void/overlays/config/shell/rc/void and hosts/void/overlays/config/shell/rc/void differ
blob - 86fdf402016d85d244929d5f5f1356fb3f417c01
blob + 8bc232484fe7aa690addfcddd07f4d8a3f28304b
--- hosts/void/overlays/config/shepherd/init.d/cliphist.scm
+++ hosts/void/overlays/config/shepherd/init.d/cliphist.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; cliphist.scm --- Wayland clipboard history  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'cliphist '("wl-paste" "--watch" "cliphist" "store"))
+
+;;; cliphist.scm ends here
blob - /dev/null
blob + a4de61a2483d6b40e8425fb612d1704829d311d5 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/00-log-rotation.scm
@@ -0,0 +1,15 @@
+;;; 00-log-rotation.scm --- Rotate service log files  -*- mode: scheme; -*-
+
+(use-modules (helpers)
+             (shepherd service)
+             (shepherd service log-rotation)
+             (shepherd service timer))
+
+(start-service
+ (replace-service!
+  (log-rotation-service
+   (calendar-event #:hours '(4) #:minutes '(30))
+   #:expiry (* 28 24 3600)
+   #:rotation-size-threshold (* 1024 1024))))
+
+;;; 00-log-rotation.scm ends here
blob - d5a29f0e3b4db5bf7ed4e6b38bcd83b41d8bb73e
blob + 4fad8225da6412f8ba2c7a02b2afb0e96f32efa3
--- hosts/void/overlays/config/shepherd/init.d/fnott.scm
+++ hosts/void/overlays/config/shepherd/init.d/fnott.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; fnott.scm --- Wayland notification daemon  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'fnott '("fnott"))
+
+;;; fnott.scm ends here
blob - /dev/null
blob + b5202cebd45321d415a63d4904a2b9c280a29c93 (mode 644)
--- /dev/null
+++ hosts/void/overlays/config/shepherd/init.d/00-repl.scm
@@ -0,0 +1,9 @@
+;;; 00-repl.scm --- Read-eval-print loop over a socket  -*- mode: scheme; -*-
+
+(use-modules (helpers)
+             (shepherd service)
+             (shepherd service repl))
+
+(start-service (replace-service! (repl-service)))
+
+;;; 00-repl.scm ends here
blob - ecbf720129e459075185bf4f4f9e2f30390a3d2b
blob + 8387a9a8ae4c6aed323a46334118e9bb35573075
--- hosts/void/overlays/config/shepherd/init.d/foot-server.scm
+++ hosts/void/overlays/config/shepherd/init.d/foot-server.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; foot-server.scm --- Foot terminal server  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'foot-server '("/usr/bin/foot" "--server"))
+
+;;; foot-server.scm ends here
blob - e64eedb1ae666fb225a61f4e7ad564c7d3aa52ff
blob + 3a9ef0fc11808574f939e0bed5982f73b930b889
--- hosts/void/overlays/config/shepherd/init.d/hister.scm
+++ hosts/void/overlays/config/shepherd/init.d/hister.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; hister.scm --- Shell history daemon  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'hister '("hister" "listen"))
+
+;;; hister.scm ends here
blob - 0018b5ad243aaf53d1586cfa0473d8be71093506
blob + 81eddac8888a303c5c056754b22b623dc5d9c4d5
--- hosts/void/overlays/config/shepherd/init.d/kanshi.scm
+++ hosts/void/overlays/config/shepherd/init.d/kanshi.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; kanshi.scm --- Dynamic display configuration  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'kanshi '("kanshi"))
+
+;;; kanshi.scm ends here
blob - 6d6e91b297819b6083a172590173e83093482e55
blob + 4ec16267fa67e776e9161c0fa9ca6389b0c880d2
--- hosts/void/overlays/config/shepherd/init.d/memcached.scm
+++ hosts/void/overlays/config/shepherd/init.d/memcached.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; memcached.scm --- Memory object cache for magdalena  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'memcached '("memcached"))
+
+;;; memcached.scm ends here
blob - 2533b511934fdd81705bffc992d34c54d19b5af4
blob + 2cbf8228a9d38f572a8c60e6eb7a5d7de494b8e6
--- hosts/void/overlays/config/shepherd/init.d/nix-daemon.scm
+++ hosts/void/overlays/config/shepherd/init.d/nix-daemon.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; nix-daemon.scm --- Nix build daemon  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'nix-daemon '("nix-daemon"))
+
+;;; nix-daemon.scm ends here
blob - 7cb99343966d7a9244a6f576bf6abaff8947261a
blob + cdf2622bdcab0f98116259cb438a19d2616106cc
--- hosts/void/overlays/config/shepherd/init.d/pipewire.scm
+++ hosts/void/overlays/config/shepherd/init.d/pipewire.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; pipewire.scm --- Audio and video server  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'pipewire '("pipewire"))
+
+;;; pipewire.scm ends here
blob - 035a1d5ec8fa0aece366652dbf7dbc794b814c33
blob + 7e74d1d3d30fb362715ad6935c01711ee87494ee
--- hosts/void/overlays/config/shepherd/init.d/poweralertd.scm
+++ hosts/void/overlays/config/shepherd/init.d/poweralertd.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; poweralertd.scm --- Battery level alerts  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'poweralertd '("poweralertd" "-c" "15"))
+
+;;; poweralertd.scm ends here
blob - acfdde30f44ae83c016e156b9b5c5833f7281265
blob + 7e48f7fa69c3f61160747e8b6c30452cef8c8c63
--- hosts/void/overlays/config/shepherd/init.d/psi-notify.scm
+++ hosts/void/overlays/config/shepherd/init.d/psi-notify.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; psi-notify.scm --- Resource pressure alerts  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'psi-notify '("psi-notify"))
+
+;;; psi-notify.scm ends here
blob - 541596cd5aba01df0559215a264a9a709d369e46
blob + 1e9ecc4575dc6178de593f45617b3c950083cc13
--- hosts/void/overlays/config/shepherd/init.d/stunnel.scm
+++ hosts/void/overlays/config/shepherd/init.d/stunnel.scm
@@ -1,5 +1,7 @@
-;; -*- mode: scheme; -*-
+;;; stunnel.scm --- TLS wrapper for a local service  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'stunnel
-              (list "stunnel"
-                    (string-append %user-config-dir "/stunnel/stunnel.conf")))
+              (list "stunnel" (xdg-config-file "stunnel" "stunnel.conf")))
+
+;;; stunnel.scm ends here
blob - 7c055f781fd498041d4476d5af9fcac127c710c5
blob + 83fe933831f2c72d44baa94cd1d2bbbbbe748b65
--- hosts/void/overlays/config/shepherd/init.d/wbg.scm
+++ hosts/void/overlays/config/shepherd/init.d/wbg.scm
@@ -1,6 +1,9 @@
-;; -*- mode: scheme; -*-
+;;; wbg.scm --- Wayland wallpaper  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 (exec-service 'wbg
               (list "wbg"
                     "/home/miro/misc/random/wallpapers/bru.jpg"
                     "--stretch"))
+
+;;; wbg.scm ends here
blob - 87daa1d536bb0b0db32a557b34380f9c739a71fe
blob + 174c06e01a513a3e8aabb2471656a4c2078dcdb5
--- hosts/void/overlays/config/shepherd/init.d/wl-gammarelay.scm
+++ hosts/void/overlays/config/shepherd/init.d/wl-gammarelay.scm
@@ -1,3 +1,6 @@
-;; -*- mode: scheme; -*-
+;;; wl-gammarelay.scm --- Screen colour temperature  -*- mode: scheme; -*-
+
 (use-modules (helpers))
-(exec-service 'hister '("wl-gammarelay"))
+(exec-service 'wl-gammarelay '("wl-gammarelay"))
+
+;;; wl-gammarelay.scm ends here
blob - 9f701595db7ae8f8b79edf85d53a603b673a309b
blob + e9cf9363819f7c91d079c3498e43b948343e1c57
--- hosts/void/overlays/config/shepherd/init.d/wob.scm
+++ hosts/void/overlays/config/shepherd/init.d/wob.scm
@@ -1,4 +1,5 @@
-;; -*- mode: scheme; -*-
+;;; wob.scm --- Overlay bar for volume and brightness  -*- mode: scheme; -*-
+
 (use-modules (helpers))
 ;; wob reads volume/brightness levels from a FIFO at $XDG_RUNTIME_DIR/wob.sock
 (exec-service
@@ -8,3 +9,5 @@
         "sock=\"$XDG_RUNTIME_DIR/wob.sock\"; "
         "[ -p \"$sock\" ] || mkfifo \"$sock\"; "
         "exec sh -c 'tail -f \"$1\" | wob' _ \"$sock\"")))
+
+;;; wob.scm ends here
blob - 2231adce0b02f22cfec0beb8e63ec022453b81fc
blob + 136ff2ae5b2d4c0fa32668681be827b78e81ad90
--- hosts/void/overlays/config/shepherd/init.scm
+++ hosts/void/overlays/config/shepherd/init.scm
@@ -1,5 +1,4 @@
-;; -*- mode: scheme; -*-
-;;; ~/.config/shepherd/init.scm
+;;; init.scm --- Shepherd user configuration entry point  -*- mode: scheme; -*-
 
 (use-modules (shepherd service)
              (shepherd support)
@@ -22,3 +21,5 @@
               (load (string-append init.d "/" file)))
             (scandir init.d
                      (lambda (file) (string-suffix? ".scm" file)))))
+
+;;; init.scm ends here
blob - d8d117f928533d98257c8620dc1d8a2ee55811c5
blob + 52caf5cd1a6a31b95b946f3eead40bbe4ce489e4
--- hosts/void/overlays/config/shepherd/modules/helpers.scm
+++ hosts/void/overlays/config/shepherd/modules/helpers.scm
@@ -1,12 +1,26 @@
-;; -*- mode: scheme; -*-
-;;; ~/.config/shepherd/modules/helpers.scm
+;;; helpers.scm --- Service definition helpers  -*- mode: scheme; -*-
 
 (define-module (helpers)
   #:use-module (shepherd service)
   #:use-module (shepherd support)
   #:use-module (srfi srfi-13)
-  #:export (exec-service))
+  #:export (exec-service
+            replace-service!
+            xdg-config-file
+            xdg-data-file))
 
+(define (xdg-dir variable fallback)
+  (let ((value (getenv variable)))
+    (if (and value (not (string-null? value)))
+        value
+        (string-append user-homedir fallback))))
+
+(define (xdg-config-file . parts)
+  (string-join (cons (xdg-dir "XDG_CONFIG_HOME" "/.config") parts) "/"))
+
+(define (xdg-data-file . parts)
+  (string-join (cons (xdg-dir "XDG_DATA_HOME" "/.local/share") parts) "/"))
+
 (define (environment-with-overrides base overrides)
   "Return BASE (a list of \"KEY=VALUE\" strings) with OVERRIDES applied.
 Each override must be a \"KEY=VALUE\" string; if the key already exists in
@@ -25,25 +39,43 @@ BASE, the old entry is replaced."
                                 (not (string-prefix? prefix entry)))
                               result)))))))
 
-;; Register and start NAME running COMMAND (program + args).  Idempotent:
-;; an existing service by that name is replaced, so re-running the file via
-;; `herd load' reloads it in place.
-(define* (exec-service name command #:key (respawn? #t) (environment '()))
-  (let ((old (lookup-service name)))
+(define (replace-service! svc)
+  (let ((old (lookup-service (service-canonical-name svc))))
     (when old
-      (stop-service old)
       (unregister-services (list old))))
+  (register-services (list svc))
+  svc)
+
+(define* (exec-service name command
+                       #:key
+                       (requirement '())
+                       (respawn? #t)
+                       (respawn-limit (default-respawn-limit))
+                       (one-shot? #f)
+                       (start? #t)
+                       (directory (default-service-directory))
+                       (environment '())
+                       (documentation
+                        (string-append "Run " (symbol->string name) ".")))
   (let ((svc (service (list name)
-                      #:documentation (string-append "Run " (symbol->string name) ".")
+                      #:documentation documentation
+                      #:requirement requirement
+                      #:one-shot? one-shot?
+                      #:respawn? (and respawn? (not one-shot?))
+                      #:respawn-limit respawn-limit
                       #:start (make-forkexec-constructor
                                command
+                               #:directory directory
                                #:log-file (string-append %user-log-dir "/"
                                                          (symbol->string name) ".log")
                                #:environment-variables
                                (environment-with-overrides
                                 (default-environment-variables)
                                 environment))
-                      #:stop (make-kill-destructor)
-                      #:respawn? respawn?)))
-    (register-services (list svc))
-    (start-service svc)))
+                      #:stop (make-kill-destructor))))
+    (replace-service! svc)
+    (when start?
+      (start-service svc))
+    svc))
+
+;;; helpers.scm ends here
blob - /dev/null
blob + f7edb52cc818af9c66e2658e6511cff63fed1ed3 (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/bin/histdb-fts-all
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+sqlite3 -batch -noheader -separator "$(printf '\037')" \
+  "${HISTDB_FILE:-$HOME/.histdb/zsh-history.db}" <<'SQL'
+SELECT
+  history.id,
+  replace(commands.argv, char(10), ' ↵ ')
+FROM history
+JOIN commands ON history.command_id = commands.id
+ORDER BY history.start_time DESC;
+SQL
blob - 5f7d3d57de7935f41c7d9835d2a3cb5647c6836e
blob + 118b829cbd334007225540229b540716aa26c470
--- modules/mixins/dotfiles/config/zsh/rc/plugins
+++ modules/mixins/dotfiles/config/zsh/rc/plugins
@@ -14,7 +14,6 @@ fi
 source $HOME/.config/zsh/plugins/zsh-histdb/sqlite-history.zsh
 source $HOME/.config/zsh/plugins/zsh-histdb/histdb-interactive.zsh
 autoload -Uz add-zsh-hook
-bindkey '^r' _histdb-isearch
 
 # https://github.com/ajeetdsouza/zoxide
 eval "$(zoxide init zsh)"
blob - /dev/null
blob + 3658087f8f574f50a501ea64477a2b595fa13f27 (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/config/zsh/rc/zzz-histdb-fts
@@ -0,0 +1,96 @@
+#!/bin/zsh
+# Loaded after plugins by the rc-file ordering in ~/.zshrc.
+
+# Build the index explicitly: rebuilding a trigram index can take a while on a
+# large history database, so shell startup must never perform the migration.
+histdb-fts-index() {
+  [[ $(_histdb_query "SELECT sqlite_compileoption_used('ENABLE_FTS5')") == 1 ]] || {
+    print -u2 'histdb-fts-index: sqlite3 was built without FTS5'
+    return 1
+  }
+
+  _histdb_query <<'SQL'
+BEGIN;
+DROP TRIGGER IF EXISTS commands_fts_insert;
+DROP TRIGGER IF EXISTS commands_fts_delete;
+DROP TABLE IF EXISTS commands_fts;
+CREATE VIRTUAL TABLE commands_fts USING fts5(
+  argv,
+  content='commands',
+  content_rowid='id',
+  tokenize='trigram',
+  detail='none'
+);
+CREATE TABLE IF NOT EXISTS histdb_fts_meta (
+  name TEXT PRIMARY KEY
+);
+CREATE TRIGGER IF NOT EXISTS commands_fts_insert
+AFTER INSERT ON commands BEGIN
+  INSERT INTO commands_fts(rowid, argv) VALUES (new.id, new.argv);
+END;
+CREATE TRIGGER IF NOT EXISTS commands_fts_delete
+AFTER DELETE ON commands BEGIN
+  INSERT INTO commands_fts(commands_fts, rowid, argv)
+  VALUES ('delete', old.id, old.argv);
+END;
+DELETE FROM histdb_fts_meta WHERE name = 'commands_fts_v1';
+INSERT INTO histdb_fts_meta(name) VALUES ('commands_fts_v1');
+INSERT INTO commands_fts(commands_fts) VALUES ('rebuild');
+COMMIT;
+SQL
+
+  if (( ${+widgets[_histdb-fts-fzf-history]} )); then
+    bindkey '^r' _histdb-fts-fzf-history
+  fi
+  print 'histdb-fts-index: trigram index built'
+}
+
+_histdb_fts_candidates() {
+  local where=
+  if (( ${#1} >= 3 )); then
+    where="JOIN commands_fts AS fts ON fts.rowid = commands.id
+      WHERE fts.argv LIKE '%$(sql_escape "$1")%'"
+  fi
+
+  _histdb_query -separator $'\x1f' "
+    SELECT
+      history.id,
+      replace(commands.argv, char(10), ' ↵ ')
+    FROM history
+    JOIN commands ON history.command_id = commands.id
+    JOIN places ON history.place_id = places.id
+    ${where}
+    ORDER BY history.start_time DESC
+    LIMIT 5000
+  "
+}
+
+_histdb-fts-fzf-history() {
+  local id
+
+  id=$(
+    _histdb_fts_candidates "$LBUFFER" |
+      fzf --exact \
+          --no-sort \
+          --query="$LBUFFER" \
+          --delimiter=$'\x1f' \
+          --with-nth=2.. \
+          --accept-nth=1 \
+          --bind "ctrl-a:clear-query+reload($HOME/bin/histdb-fts-all)" \
+          --height=40% \
+          --reverse
+  ) || return
+
+  [[ $id == <-> ]] || return
+  BUFFER=$(_histdb_query "
+    SELECT commands.argv
+    FROM history
+    JOIN commands ON history.command_id = commands.id
+    WHERE history.id = $id
+  ")
+  CURSOR=${#BUFFER}
+  zle reset-prompt
+}
+
+zle -N _histdb-fts-fzf-history
+bindkey '^r' _histdb-fts-fzf-history
blob - f04c2e4c7b1e06be261825c4c039acc9b2bcb038
blob + 27040afdb575a70e0b8c4910db3dc986d7215d75
--- modules/mixins/dotfiles/default.nix
+++ modules/mixins/dotfiles/default.nix
@@ -2,11 +2,17 @@
   config,
   lib,
   inputs,
+  pkgs,
   ...
 }: let
   sources = import ./npins;
   overlay = import ../../../lib/mk-overlay.nix {inherit config lib inputs;};
   inherit (overlay) mkMapping;
+  histdb = pkgs.applyPatches {
+    name = "zsh-histdb-with-fts";
+    src = sources.zsh-histdb;
+    patches = [./patches/zsh-histdb-fts.patch];
+  };
 in {
   imports = [./plass.nix];
 
@@ -25,7 +31,7 @@ in {
       (mkMapping ./config "")
       // {
         "zsh/plugins/zsh-autopair".source = sources.zsh-autopair;
-        "zsh/plugins/zsh-histdb".source = sources.zsh-histdb;
+        "zsh/plugins/zsh-histdb".source = histdb;
         "zsh/plugins/zsh-autosuggestions".source = sources.zsh-autosuggestions;
         "zsh/plugins/zsh-completions".source = sources.zsh-completions;
       };
blob - /dev/null
blob + 75eee0755518b2c2d7d5c15b03e9cede2c8187e1 (mode 644)
--- /dev/null
+++ modules/mixins/dotfiles/patches/zsh-histdb-fts.patch
@@ -0,0 +1,25 @@
+diff --git a/sqlite-history.zsh b/sqlite-history.zsh
+index 1075073..baf4baa 100644
+--- a/sqlite-history.zsh
++++ b/sqlite-history.zsh
+@@ -87,6 +87,20 @@ _histdb_init () {
+                        place_id int references places (id),
+                        exit_status int,
+                        start_time int,
+                        duration int);
++create virtual table commands_fts using fts5(
++  argv,
++  content='commands',
++  content_rowid='id',
++  tokenize='trigram',
++  detail='none'
++);
++create trigger commands_fts_insert after insert on commands begin
++  insert into commands_fts(rowid, argv) values (new.id, new.argv);
++end;
++create trigger commands_fts_delete after delete on commands begin
++  insert into commands_fts(commands_fts, rowid, argv)
++  values ('delete', old.id, old.argv);
++end;
+ PRAGMA user_version = 2;
+ EOF