about summary refs log tree commit diff stats
path: root/nix-conf
diff options
context:
space:
mode:
Diffstat (limited to 'nix-conf')
-rw-r--r--nix-conf/.sops.yaml7
-rw-r--r--nix-conf/home/includes/clojure.nix6
-rw-r--r--nix-conf/home/includes/common.nix39
-rw-r--r--nix-conf/home/includes/darwin.nix71
-rw-r--r--nix-conf/home/includes/dev-common.nix1
-rw-r--r--nix-conf/home/includes/linux-dev.nix1
-rw-r--r--nix-conf/home/includes/linux-server.nix3
-rw-r--r--nix-conf/home/includes/secrets.yaml (renamed from nix-conf/secrets/home.yaml)13
-rw-r--r--nix-conf/home/includes/zsh.nix454
-rw-r--r--nix-conf/home/otm.nix18
-rw-r--r--nix-conf/machines/djmuk1/configuration.nix17
-rw-r--r--nix-conf/machines/djmuk2/configuration.nix14
-rw-r--r--nix-conf/machines/djmuk2/secrets.yaml (renamed from nix-conf/secrets/djmuk2.yaml)0
-rw-r--r--nix-conf/machines/edrahil/configuration.nix117
-rw-r--r--nix-conf/machines/edrahil/network-configuration.nix2
-rw-r--r--nix-conf/machines/edrahil/secrets.yaml31
-rw-r--r--nix-conf/machines/egalmoth/configuration.nix22
-rw-r--r--nix-conf/secrets/edrahil.yaml21
18 files changed, 542 insertions, 295 deletions
diff --git a/nix-conf/.sops.yaml b/nix-conf/.sops.yaml
index 24125e8..2cb1a1e 100644
--- a/nix-conf/.sops.yaml
+++ b/nix-conf/.sops.yaml
@@ -3,15 +3,16 @@ keys:
   - &server_edrahil age1tjfctwnwldmyxnu6qmeufgr9l79vyzmrs7fy58v3d0qj4x4nhqhq2gjmlp
   - &server_djmuk2 age17j56andser5ddtlfunm35m25xueua4djh9glxlscfcet8865yv9s5aqvla
 creation_rules:
-  - path_regex: secrets/edrahil\.(json|yaml)$
+  - path_regex: edrahil/secrets\.(json|yaml)$
     key_groups:
     - age:
       - *server_edrahil
-  - path_regex: secrets/djmuk2\.(json|yaml)$
+      - *admin_djm
+  - path_regex: djmuk2/secrets\.(json|yaml)$
     key_groups:
     - age:
       - *server_djmuk2
-  - path_regex: secrets/[^/]+\.(json|yaml)$
+  - path_regex: secrets\.(json|yaml)$
     key_groups:
     - age:
       - *admin_djm
diff --git a/nix-conf/home/includes/clojure.nix b/nix-conf/home/includes/clojure.nix
index 85bd261..3915ab3 100644
--- a/nix-conf/home/includes/clojure.nix
+++ b/nix-conf/home/includes/clojure.nix
@@ -13,11 +13,13 @@ in
     [
       babashka
       clj-kondo
-      clojure
       clojure-lsp
+      emacs-lsp-booster
       jet
       maven
       neil
     ]
-    ++ optionals stdenv.isLinux [ leiningen ];
+    # TODO these are here because of the custom versions in otm.nix
+    # but there should be a better way
+    ++ optionals stdenv.isLinux [ leiningen clojure ];
 }
diff --git a/nix-conf/home/includes/common.nix b/nix-conf/home/includes/common.nix
index 6a0c721..e12558c 100644
--- a/nix-conf/home/includes/common.nix
+++ b/nix-conf/home/includes/common.nix
@@ -31,7 +31,7 @@ in
   sops = {
     age.keyFile = "${config.xdg.configHome}/sops/age/keys.txt";
     defaultSopsFile = builtins.path {
-      path = ./../../secrets/home.yaml;
+      path = ./secrets.yaml;
       name = "home-secrets.yaml";
     };
     secrets."ssh_config/oci" = { };
@@ -50,8 +50,10 @@ in
     aspellDicts.en
     aspellDicts.en-computers
     aspellDicts.en-science
+    bandwhich
     bottom
     broot
+    comma
     curl
     diff-so-fancy
     difftastic
@@ -70,6 +72,7 @@ in
     inetutils
     ispell
     isync
+    jd-diff-patch
     jq
     libqalculate
     lscolors
@@ -78,9 +81,12 @@ in
     nix-info
     nix-prefetch-git
     nix-prefetch-github
+    nix-search
     nixpkgs-review
     nvd
     pass
+    procs
+    pstree
     rage
     ripgrep
     rlwrap
@@ -95,11 +101,12 @@ in
     uni
     unzip
     w3m
+    xan
     yq
+    zip
     zstd
 
     unstable.nixfmt-rfc-style
-    unstable.wcurl
   ];
 
   programs.bat = {
@@ -124,7 +131,7 @@ in
   programs.eza = {
     enable = true;
     git = true;
-    icons = true;
+    icons = "auto";
     enableBashIntegration = false;
     enableZshIntegration = false;
     enableFishIntegration = false;
@@ -160,6 +167,14 @@ in
       set pastetoggle=<F2>
       nmap <silent> <F3> :silent nohlsearch<CR>
       imap <silent> <F3> <C-o>:silent nohlsearch<CR>
+      nmap <silent> <F4> :silent setlocal spell spelllang=en_gb<CR>
+      imap <silent> <F4> <C-o>:silent setlocal spell spelllang=en_gb<CR>
+      nmap <silent> <F5> :silent setlocal nospell<CR>
+      imap <silent> <F5> <C-o>:silent setlocal nospell<CR>
+      nmap <silent> <F6> :silent set diffopt+=iwhite<CR>
+      imap <silent> <F6> <C-o>:silent set diffopt+=iwhite<CR>
+      nmap <silent> <F7> :silent set diffopt-=iwhite<CR>
+      imap <silent> <F7> <C-o>:silent set diffopt-=iwhite<CR>
     '';
     plugins = [
       pkgs.vimPlugins.sensible
@@ -245,6 +260,22 @@ in
         identityFile = "~/.ssh/id_ed25519";
         identitiesOnly = true;
       };
+      "hb-backup" = {
+        hostname = "de1.hashbang.sh";
+        identityFile = "~/.ssh/hb_backup_key";
+        identitiesOnly = true;
+      };
+      "bs-backup" = {
+        hostname = "ssh.blinkenshell.org";
+        port = 2222;
+        identityFile = "~/.ssh/bs_backup_key";
+        identitiesOnly = true;
+      };
+      "tt-backup" = {
+        hostname = "tilde.team";
+        identityFile = "~/.ssh/tt_backup_key";
+        identitiesOnly = true;
+      };
     };
   };
 
@@ -296,6 +327,7 @@ in
           cmd = ''difft "$LOCAL" "$REMOTE"'';
         };
       };
+      merge.conflictstyle = "diff3";
       pull = {
         ff = "only";
         rebase = false;
@@ -333,6 +365,7 @@ in
 
   programs.lsd = {
     enable = true;
+    enableZshIntegration = false; # don't set aliases
     settings = {
       indicators = true;
       #layout = "oneline";
diff --git a/nix-conf/home/includes/darwin.nix b/nix-conf/home/includes/darwin.nix
index ebda874..e85f3f9 100644
--- a/nix-conf/home/includes/darwin.nix
+++ b/nix-conf/home/includes/darwin.nix
@@ -26,6 +26,63 @@ let
         --prefix PYTHONPATH : $out/${pkgs.mopidyPackages.python.sitePackages}
     '';
   };
+
+  # https://github.com/NixOS/nixpkgs/issues/395169
+  patched-pkgs = pkgs.extend (
+    _final: prev: {
+      ld64 = prev.ld64.overrideAttrs (old: {
+        patches = old.patches ++ [ ./Dedupe-RPATH-entries.patch  ];
+      });
+      libuv = prev.libuv.overrideAttrs (old: {
+        doCheck = false;
+      });
+      dbus = prev.dbus.overrideAttrs (old: {
+        doCheck = false;
+      });
+      python313 = prev.python313.override {
+        packageOverrides = self: super: {
+          execnet = super.execnet.overridePythonAttrs (old: {
+            doCheck = false;
+          });
+          pytest-xdist = super.pytest-xdist.overridePythonAttrs (old: {
+            doCheck = false;
+          });
+          requests = super.requests.overridePythonAttrs (old: {
+            doCheck = false;
+          });
+          sphinx = super.sphinx.overridePythonAttrs (old: {
+            doCheck = false;
+          });
+        };
+      };
+    }
+  );
+
+  # Use the patches from emacs-plus
+  emacs-plus = (patched-pkgs.emacs30-pgtk.overrideAttrs (old: {
+        patches =
+          (old.patches or [])
+          ++ [
+            (pkgs.fetchpatch {
+              url = "https://raw.githubusercontent.com/d12frosted/homebrew-emacs-plus/master/patches/emacs-30/fix-window-role.patch";
+              sha256 = "0c41rgpi19vr9ai740g09lka3nkjk48ppqyqdnncjrkfgvm2710z";
+            })
+            (pkgs.fetchpatch {
+              url = "https://raw.githubusercontent.com/d12frosted/homebrew-emacs-plus/master/patches/emacs-30/round-undecorated-frame.patch";
+              sha256 = "uYIxNTyfbprx5mCqMNFVrBcLeo+8e21qmBE3lpcnd+4=";
+            })
+            (pkgs.fetchpatch {
+              url = "https://raw.githubusercontent.com/d12frosted/homebrew-emacs-plus/master/patches/emacs-30/system-appearance.patch";
+              sha256 = "3QLq91AQ6E921/W9nfDjdOUWR8YVsqBAT/W9c1woqAw=";
+            })
+          ];
+      })).override{ withNativeCompilation = true; };
+
+  emacs-plus-with-packages = (pkgs.emacsPackagesFor emacs-plus).emacsWithPackages (ps: [
+    ps.vterm
+    ps.multi-vterm
+  ]);
+
 in
 {
   imports = [ ./dev-common.nix ];
@@ -37,10 +94,7 @@ in
     coreutils
     curl
     diffutils
-    ((emacsPackagesFor emacs29-macport).emacsWithPackages (ps: [
-      ps.vterm
-      ps.multi-vterm
-    ]))
+    emacs-plus-with-packages
     findutils
     gh
     gh-dash
@@ -57,14 +111,21 @@ in
     pgcli
     pgformatter
     #pms
+    poetry
     postgresql
     podman
     #python310Packages.sqlparse
+    redis
     sqls
     #vimpc
     wget
   ];
 
+  nixpkgs.config.permittedInsecurePackages = [
+    "emacs-mac-macport-29.1"
+    "emacs-mac-macport-with-packages-29.1"
+  ];
+
   nix.settings = {
     sandbox = true;
     keep-outputs = true;
@@ -78,4 +139,6 @@ in
     })
   ];
 
+  # TODO is this a good idea?
+  #programs.zsh.shellAliases = { emacs = "${emacs-plus-with-packages}/Applications/Emacs.app/Contents/MacOS/Emacs"; };
 }
diff --git a/nix-conf/home/includes/dev-common.nix b/nix-conf/home/includes/dev-common.nix
index 12f4893..92b286e 100644
--- a/nix-conf/home/includes/dev-common.nix
+++ b/nix-conf/home/includes/dev-common.nix
@@ -22,6 +22,7 @@ in
       gopass-jsonapi
       multimarkdown
       neovim
+      ripgrep-all
     ]
     ++ optionals (!stdenv.isDarwin) [
       ffmpeg
diff --git a/nix-conf/home/includes/linux-dev.nix b/nix-conf/home/includes/linux-dev.nix
index d680760..473118e 100644
--- a/nix-conf/home/includes/linux-dev.nix
+++ b/nix-conf/home/includes/linux-dev.nix
@@ -4,7 +4,6 @@
 
   programs.emacs = {
     enable = true;
-    package = pkgs.emacs29;
     extraPackages = (
       epkgs: [
         epkgs.vterm
diff --git a/nix-conf/home/includes/linux-server.nix b/nix-conf/home/includes/linux-server.nix
index 427b167..62233f0 100644
--- a/nix-conf/home/includes/linux-server.nix
+++ b/nix-conf/home/includes/linux-server.nix
@@ -7,7 +7,6 @@
     irssi
     libtree
     msmtp
-    neomutt
     pinentry
     restic
     sword
@@ -16,7 +15,7 @@
 
   services.gpg-agent = {
     enable = true;
-    pinentryPackage = pkgs.pinentry-curses;
+    pinentry.package = pkgs.pinentry-curses;
     defaultCacheTtl = 34560000;
     maxCacheTtl = 34560000;
   };
diff --git a/nix-conf/secrets/home.yaml b/nix-conf/home/includes/secrets.yaml
index 8222439..2fc9d8c 100644
--- a/nix-conf/secrets/home.yaml
+++ b/nix-conf/home/includes/secrets.yaml
@@ -1,14 +1,10 @@
 ssh_config:
     oci: ENC[AES256_GCM,data:l1GZ6mszgDhGztWmMdkNY2wRGfLIOGfHou7m0p8NkvaZZ3oKhblyu9C2Y2uEZArC8aCysxmU0QDfeIxDAzBdszUY,iv:HD8xdaiF9s0XZAuHNjAQfEtMgKaM0R12FCv5rTq19+Y=,tag:bfa48iOXhASXc+JhmYy/EQ==,type:str]
-    otm: ENC[AES256_GCM,data:fGChw7JlnWtnP4lVX1XXAH97gR0iWgBPuR2o7IgQ5wI8QlQCsrkY/GGa6pFanFsblYWGnwpiv8Cu7Bj7A+ShR1bjTeMdVRjLTe6fkAAj7jL5Np+C/xK12zUK,iv:X486VWdXg9KtuK4yDsq3+P+lY45+nxAwmEkI59olwwI=,tag:PVif5yh0M9dBLmsnGqYJYw==,type:str]
+    otm: ""
 git_email_config:
     default: ENC[AES256_GCM,data:ADmbGuV+E5wvGdbdC12BDi2TvHeoIRWjerKxnvDV7dENCxFyy+3P01IyCA==,iv:Nik4YiC8WhWmAnM7g1ER5HU0pg88l9uFiHQNtou5jas=,tag:RtK0XKKcHHR39p3mSl5YRw==,type:str]
     otm: ENC[AES256_GCM,data:dFrxmxFRU5MThUSdqWuL3ZmBCJfMUVYWQTnWQF25Cnn6lMflau5vHNEFZZDZxyFBk7A=,iv:EOv1xgxXuN3LuiO1eorazgQHBkWY9GKUjFBaYnfkLRI=,tag:Mg6SwdQSGjtlR5iiOU/q7g==,type:str]
 sops:
-    kms: []
-    gcp_kms: []
-    azure_kv: []
-    hc_vault: []
     age:
         - recipient: age1w7kjp0qdgfyg9cyj5w4qc4fc9qz3w65xw2veazesfgdenqrd3ucqsc5ejv
           enc: |
@@ -19,8 +15,7 @@ sops:
             cjlWWTNQR3lLLzBqTHhld05VblFJdHcKihceil9ge+IKG2GZcLpGWUncvRvmyJ7w
             YiWtb/ApF4T27wsmmFyLSnG8OWkLCKzaeU4QOVIGYQcfzzcQD5nUGg==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2024-08-29T14:36:21Z"
-    mac: ENC[AES256_GCM,data:AVaoEELI5iftC2eNI9pRoL/LWhwGVgCm/VfiVi67yYdG7HwyJwK60L1gAoLxvsvhIeZPXGq+CIt0iN2jjOSnNymh8b9zbpIs8h3PHelZs+yaKgpxRCKnIy6OKvUoRft16P1/VVq6ZMqA1qmOvXxtUOp/F5yZx7x7ix1aPoO2rpw=,iv:DTwuUqYCI98vNF5viz7r3DzZhjj9Xu5rFbabkmY5gK4=,tag:MQTIONNC29xeCOg0/C0jfw==,type:str]
-    pgp: []
+    lastmodified: "2025-04-29T13:45:42Z"
+    mac: ENC[AES256_GCM,data:Z4jJujUvl8jmJQbquV9NeczVZF17HI01sDpUoSSS7cM89WUOZzAOcT3zxR4hzyCfq4je++YkBPPFl4hcqbuVyBu8zCxY4z9673sFSLYrUA8THVeLYjMOTo0Hu0tIy8vy+uZZcAuRFaXyS+GrQHAdSSm4zVkwLG9R1nod+ys6LvQ=,iv:WfubcgFSY94cyfrlAlND6CQudoISuGL5fBhm9E3O4Q4=,tag:IeKYzou3EDwGyA23FGHtdA==,type:str]
     unencrypted_suffix: _unencrypted
-    version: 3.9.0
+    version: 3.10.2
diff --git a/nix-conf/home/includes/zsh.nix b/nix-conf/home/includes/zsh.nix
index a76fea4..650f559 100644
--- a/nix-conf/home/includes/zsh.nix
+++ b/nix-conf/home/includes/zsh.nix
@@ -17,10 +17,17 @@ in
     changeDirWidgetCommand = "fd --type=d --hidden --strip-cwd-prefix --exclude .git --exclude node_modules"; # FZF_ALT_C_COMMAND
     changeDirWidgetOptions = [ "--preview 'eza --tree --color=always {} | head -200'" ]; # FZF_ALT_C_OPTS
     defaultCommand = "fd --hidden --strip-cwd-prefix --exclude .git --exclude node_modules"; # FZF_DEFAULT_COMMAND
-    defaultOptions = [ "--bind=ctrl-t:toggle-all" "--bind=ctrl-j:jump" ]; # FZF_DEFAULT_OPTS
-    fileWidgetCommand = config.programs.fzf.defaultCommand;  # FZF_CTRL_T_COMMAND
+    defaultOptions = [
+      "--bind=ctrl-t:toggle-all"
+      "--bind=ctrl-j:jump"
+    ]; # FZF_DEFAULT_OPTS
+    fileWidgetCommand = config.programs.fzf.defaultCommand; # FZF_CTRL_T_COMMAND
     fileWidgetOptions = [ "--preview '${show_file_or_dir_preview}'" ]; # FZF_CTRL_T_OPTS
-    historyWidgetOptions = [ "--preview 'echo {}'" "--preview-window down:3:hidden:wrap" "--bind 'ctrl-t:toggle-preview'" ]; # FZF_CTRL_R_OPTS
+    historyWidgetOptions = [
+      "--preview 'echo {}'"
+      "--preview-window down:3:hidden:wrap"
+      "--bind 'ctrl-t:toggle-preview'"
+    ]; # FZF_CTRL_R_OPTS
   };
   programs.zoxide = {
     enable = true;
@@ -47,10 +54,13 @@ in
   programs.zsh = {
     enable = true;
     enableCompletion = true;
-    # TODO: put strategy here after 24.11 is released
     autosuggestion = {
       enable = true;
       highlight = "fg=#808080";
+      strategy = [
+        "history"
+        "completion"
+      ];
     };
     defaultKeymap = "emacs";
     history = {
@@ -63,6 +73,7 @@ in
     historySubstringSearch = {
       enable = true;
       searchUpKey = "$terminfo[kcuu1]";
+      searchDownKey = "$terminfo[kcud1]";
     };
 
     profileExtra = ''
@@ -77,12 +88,18 @@ in
       mv = "mv -iv";
       mkdir = "mkdir -v";
       cat = "bat -p";
+      c = "bat -p";
       l = "eza";
       la = "eza -a";
       lg = "eza -G";
+      lga = "eza -aG";
       ll = "\\eza --icons --git --colour --long --group-directories-first --classify";
       lla = "ll -a";
       t = "eza --tree";
+      p = "lsd";
+      pa = "lsd -a";
+      pll = "lsd -l";
+      pla = "lsd -la";
 
       pp = ''pushbullet push "Pixel" link "''${1}" "''${1}"'';
 
@@ -126,244 +143,249 @@ in
     localVariables = {
       PER_DIRECTORY_HISTORY_TOGGLE = "^\\\\"; # ^\\ is ^#
       HISTORY_START_WITH_GLOBAL = true;
-
-      # TODO move to programs.zsh.autosuggestion.strategy when 24.11 is released
-      ZSH_AUTOSUGGEST_STRATEGY = [
-        "history"
-        "completion"
-      ];
-
       LESS = "-iRXF";
     };
-    initExtraFirst = ''
-      [[ $TERM == "tramp" ]] && unsetopt zle && PS1='$ ' && return
-    '';
-    initExtra = ''
-      # Based on prezto tmux plugin
-      if [[ -z "$TMUX" && -z "$EMACS" && -z "$VIM" && -z "$INSIDE_EMACS" && (-z "$SSH_TTY" || -n "$TMUX_AUTO_ATTACH") ]]; then
-        tmux start-server
-
-        if ! tmux has-session 2> /dev/null; then
-          tmux new-session -d -s "0" \; set-option -t "0" destroy-unattached off &> /dev/null
-        fi
+    initContent = lib.mkMerge [
+      (lib.mkBefore ''
+        [[ $TERM == "tramp" ]] && unsetopt zle && PS1='$ ' && return
+      '')
+      ''
+        # Based on prezto tmux plugin
+        if [[ -z "$TMUX" && -z "$EMACS" && -z "$VIM" && -z "$INSIDE_EMACS" && (-z "$SSH_TTY" || -n "$TMUX_AUTO_ATTACH") ]]; then
+          tmux start-server
+
+          if ! tmux has-session 2> /dev/null; then
+            tmux new-session -d -s "0" \; set-option -t "0" destroy-unattached off &> /dev/null
+          fi
 
-        if [[ -n "$SSH_TTY" ]]; then
-          exec tmux -u attach-session
-        else
-          exec tmux -u attach-session -d
+          if [[ -n "$SSH_TTY" ]]; then
+            exec tmux -u attach-session
+          else
+            exec tmux -u attach-session -d
+          fi
         fi
-      fi
-
-      autopair-init
-      enable-fzf-tab
-
-      # make home and end work
-      [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
-      [[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line
-
-      # disable sort when completing `git checkout`
-      zstyle ':completion:*:git-checkout:*' sort false
-      # set descriptions format to enable group support
-      zstyle ':completion:*:descriptions' format '[%d]'
-      # Allow tab to expand aliases
-      zstyle ':completion:*' completer _expand_alias _complete _ignored
-      # set list-colors to enable filename colorizing
-      #zstyle ':completion:*' list-colors ''${(s.:.)LS_COLORS}
-      # preview directory's content with eza when completing cd
-      zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
-      # switch group using `,` and `.`
-      zstyle ':fzf-tab:*' switch-group ',' '.'
-
-      # functions modified from https://www.josean.com/posts/7-amazing-cli-tools
-      _fzf_compgen_path() {
-        fd --hidden --exclude .git --exclude node_modules . "$1"
-      }
-      _fzf_compgen_dir() {
-        fd --type=d --hidden --exclude .git --exclude node_modules . "$1"
-      }
-      _fzf_comprun() {
-        local command=$1
-        shift
-
-        case "$command" in
-          cd)           fzf --preview 'eza --tree --color=always {} | head -200' "$@" ;;
-          export|unset) fzf --preview "eval 'echo $'{}"         "$@" ;;
-          ssh)          fzf --preview 'dig {}'                   "$@" ;;
-          *)            fzf --preview "${show_file_or_dir_preview}" "$@" ;;
-        esac
-      }
 
-      set -o noclobber
+        autopair-init
+        enable-fzf-tab
+
+        # make home and end work
+        [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
+        [[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line
+
+        # disable sort when completing `git checkout`
+        zstyle ':completion:*:git-checkout:*' sort false
+        # set descriptions format to enable group support
+        zstyle ':completion:*:descriptions' format '[%d]'
+        # Allow tab to expand aliases
+        zstyle ':completion:*' completer _expand_alias _complete _ignored
+        # set list-colors to enable filename colorizing
+        #zstyle ':completion:*' list-colors ''${(s.:.)LS_COLORS}
+        # preview directory's content with eza when completing cd
+        zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
+        # switch group using `,` and `.`
+        zstyle ':fzf-tab:*' switch-group ',' '.'
+
+        # functions modified from https://www.josean.com/posts/7-amazing-cli-tools
+        _fzf_compgen_path() {
+          fd --hidden --exclude .git --exclude node_modules . "$1"
+        }
+        _fzf_compgen_dir() {
+          fd --type=d --hidden --exclude .git --exclude node_modules . "$1"
+        }
+        _fzf_comprun() {
+          local command=$1
+          shift
+
+          case "$command" in
+            cd)           fzf --preview 'eza --tree --color=always {} | head -200' "$@" ;;
+            export|unset) fzf --preview "eval 'echo $'{}"         "$@" ;;
+            ssh)          fzf --preview 'dig {}'                   "$@" ;;
+            *)            fzf --preview "${show_file_or_dir_preview}" "$@" ;;
+          esac
+        }
 
-      # disable flow control (so that fzf-git.sh's ^g^s can work)
-      stty -ixon
+        set -o noclobber
+
+        # disable flow control (so that fzf-git.sh's ^g^s can work)
+        stty -ixon
+
+        # These functions are called as follows, after using ea (using vip as an example):
+        # vip  # edits the first result from ea (roughly equivalent to vi `ea p 1`)
+        # vip <n> # edits the nth result from ea (vi `ea p <n>`)
+        # vip <n> foo # if the nth result from ea is a directory, edit foo in that directory (vi `ea p <n>`/foo)
+        # Will add +<line-number>, where the line number is available
+        function _vip () {
+          local cmd=(''${=1}) # zsh only, not portable; something like CMD=($(echo $1)) is more portable but is ugly
+          local idx=''${2:-1}
+          local base_path=$(ea p $idx)
+          local line=$(ea p $idx "{line}")
+          local ea_format="'{path}'"
+
+          if [ -z "$base_path" ]; then
+            echo "No file path found for index $2"
+            return 1
+          fi
 
-      # These functions are called as follows, after using ea (using vip as an example):
-      # vip  # edits the first result from ea (roughly equivalent to vi `ea p 1`)
-      # vip <n> # edits the nth result from ea (vi `ea p <n>`)
-      # vip <n> foo # if the nth result from ea is a directory, edit foo in that directory (vi `ea p <n>`/foo)
-      function _vip () {
-        CMD=(''${=1}) # zsh only, not portable; something like CMD=($(echo $1)) is more portable but is ugly
-        BASE_PATH=$(ea p ''${2:-1})
+          if [ $# -gt 2 -a ! -d "$base_path" ]; then
+            echo "$base_path is not a directory"
+            return 2
+          fi
 
-        if [ -z "$BASE_PATH" ]; then
-          echo "No file path found for index $2"
-          return 1
-        fi
+          if [ $# -lt 3 -a $line -ne 1 ]; then
+            ea_format+=" +{line}"
+          fi
 
-        if [ $# -gt 2 -a ! -d "$BASE_PATH" ]; then
-          echo "$BASE_PATH is not a directory"
-          return 2
-        fi
+          eval $(ea p $idx "$cmd ''${ea_format}$3")
+        }
 
-        $CMD "''${BASE_PATH}''${3}"
-      }
+        function vip () {
+          _vip $EDITOR ''${@}
+        }
+        function bp () {
+          _vip bat ''${@}
+        }
+        function bpp () {
+          # this will be split into an array in _vip
+          CMD="bat -p"
+          _vip $CMD ''${@}
+        }
 
-      function vip () {
-        _vip $EDITOR ''${@}
-      }
-      function bp () {
-        _vip bat ''${@}
-      }
-      function bpp () {
-        # this will be split into an array in _vip
-        CMD="bat -p"
-        _vip $CMD ''${@}
-      }
+        function ecd () {
+          cd $(ea p ''${1:-1})
+        }
 
-      function generate () { gopass generate -s -p $1 $((RANDOM % 14 + 45)) }
-      function fcd { cd $(fd -L --max-depth=''${1:-4} --type=d 2>/dev/null | fzf-tmux) }
+        function generate () { gopass generate -s -p $1 $((RANDOM % 14 + 45)) }
+        function fcd { cd $(fd -L --max-depth=''${1:-4} --type=d 2>/dev/null | fzf-tmux) }
 
-      fif() {
-        if [ ! "$#" -gt 0  ]; then
-          echo "usage: fif <SEARCH_TERM>"
-          return 1;
-        fi
-        rg --files-with-matches --no-messages "$1" | fzf $FZF_PREVIEW_WINDOW --preview "rg --ignore-case --pretty --context 10 '$1' {}"
-      }
+        fif() {
+          if [ ! "$#" -gt 0  ]; then
+            echo "usage: fif <SEARCH_TERM>"
+            return 1;
+          fi
+          rg --files-with-matches --no-messages "$1" | fzf $FZF_PREVIEW_WINDOW --preview "rg --ignore-case --pretty --context 10 '$1' {}"
+        }
 
-      fe() {
-        IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
-        [[ -n "$files" ]] && ''${EDITOR:-vim} "''${files[@]}"
-      }
+        fe() {
+          IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
+          [[ -n "$files" ]] && ''${EDITOR:-vim} "''${files[@]}"
+        }
 
-      # TODO is there a way to do this in shellAliases
-      alias ..="cd .."
-      alias ...="cd ../.."
-      alias -- -="cd -"
-
-      .,() {
-        local declare dirs=()
-        get_parent_dirs() {
-          if [[ -d "''${1}" ]]; then dirs+=("$1"); else return; fi
-          if [[ "''${1}" == '/' ]]; then
-            for _dir in "''${dirs[@]}"; do echo $_dir; done
-          else
-            get_parent_dirs $(dirname "$1")
-          fi
+        # TODO is there a way to do this in shellAliases
+        alias ..="cd .."
+        alias ...="cd ../.."
+        alias -- -="cd -"
+
+        .,() {
+          local declare dirs=()
+          get_parent_dirs() {
+            if [[ -d "''${1}" ]]; then dirs+=("$1"); else return; fi
+            if [[ "''${1}" == '/' ]]; then
+              for _dir in "''${dirs[@]}"; do echo $_dir; done
+            else
+              get_parent_dirs $(dirname "$1")
+            fi
+          }
+          local DIR=$(get_parent_dirs $(realpath "$PWD/..") | fzf-tmux)
+          cd "$DIR"
         }
-        local DIR=$(get_parent_dirs $(realpath "$PWD/..") | fzf-tmux)
-        cd "$DIR"
-      }
 
-      # From omz
-      function mkcd () {
-        mkdir -p $@ && cd ''${@:$#}
-      }
+        # From omz
+        function mkcd () {
+          mkdir -p $@ && cd ''${@:$#}
+        }
 
-      tre () { command tre "$@" -e && source "/tmp/tre_aliases_$USER" 2>/dev/null; }
+        tre () { command tre "$@" -e && source "/tmp/tre_aliases_$USER" 2>/dev/null; }
 
-      function gcd () {
-        if [ $# -eq 0 ] ; then
-          echo "Number of days must be specified" >&2
-          return 1
-        fi
-        if ! [[ $1 =~ '^[0-9]+$' ]] ; then
-          echo "Number of days must be a number" >&2
-          return 2
-        fi
+        function gcd () {
+          if [ $# -eq 0 ] ; then
+            echo "Number of days must be specified" >&2
+            return 1
+          fi
+          if ! [[ $1 =~ '^[0-9]+$' ]] ; then
+            echo "Number of days must be a number" >&2
+            return 2
+          fi
 
-        if [ $1 -eq 0 ] ; then
-         GC_ARGS=(-d)
-        else
-          GC_ARGS=(--delete-older-than ''${1}d)
-        fi
+          if [ $1 -eq 0 ] ; then
+           GC_ARGS=(-d)
+          else
+            GC_ARGS=(--delete-older-than ''${1}d)
+          fi
 
-        DOAS=$(command -v doas)
+          DOAS=$(command -v doas)
 
-        # Run as the current user (as well as root) to clean up hm generations
-        nix-collect-garbage ''${GC_ARGS[@]}
-        if [ -n $DOAS ] ; then
-          $DOAS nix-collect-garbage ''${GC_ARGS[@]}
-        fi
+          # Run as the current user (as well as root) to clean up hm generations
+          nix-collect-garbage ''${GC_ARGS[@]}
+          if [ -n $DOAS ] ; then
+            $DOAS nix-collect-garbage ''${GC_ARGS[@]}
+          fi
 
-        df -h
-        date
-      }
+          df -h
+          date
+        }
 
-      function checkout-pr () {
-        git fetch ''${2:-upstream} pull/''${1}/head:pr-''${1}
-        git switch pr-''${1}
-      }
+        function checkout-pr () {
+          git fetch ''${2:-upstream} pull/''${1}/head:pr-''${1}
+          git switch pr-''${1}
+        }
 
-      [[ ! -f ~/.zsh.local ]] || source ~/.zsh.local
+        [[ ! -f ~/.zsh.local ]] || source ~/.zsh.local
 
-      [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
-    '';
+        [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
+      ''
+    ];
 
-    plugins =
-      with pkgs;
-      [
-        {
-          name = "zsh-autopair";
-          src = zsh-autopair;
-          file = "share/zsh/zsh-autopair/autopair.zsh";
-        }
-        {
-          name = "zsh-bd";
-          src = zsh-bd;
-          file = "share/zsh-bd/bd.zsh";
-        }
-        {
-          name = "zsh-fzf-tab";
-          src = zsh-fzf-tab;
-          file = "share/fzf-tab/fzf-tab.zsh";
-        }
-        {
-          name = "zsh-fast-syntax-highlighting";
-          src = zsh-fast-syntax-highlighting;
-          file = "share/zsh/site-functions/fast-syntax-highlighting.plugin.zsh";
-        }
-        {
-          name = "zsh-powerlevel10k";
-          src = zsh-powerlevel10k;
-          file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
-        }
-        {
-          name = "zsh-forgit";
-          src = zsh-forgit;
-          file = "share/zsh/zsh-forgit/forgit.plugin.zsh";
-        }
-        {
-          name = "zsh-edit";
-          src = zsh-edit;
-          file = "share/zsh/zsh-edit/zsh-edit.plugin.zsh";
-        }
-        {
-          name = "fzf-git.sh";
-          src = fzf-git-sh;
-          file = "share/fzf-git-sh/fzf-git.sh";
-        }
-        {
-          name = "per-directory-history";
-          src = fetchFromGitHub {
-            owner = "jimhester";
-            repo = "per-directory-history";
-            rev = "0687bbfd736da566472a6d67c2b45c501b73d405";
-            sha256 = "7Z0qaDhgopKt9BDKSqdziw9jsVgiLLafs30wPPbz+oo=";
-          };
-          file = "per-directory-history.zsh";
-        }
-      ];
+    plugins = with pkgs; [
+      {
+        name = "zsh-autopair";
+        src = zsh-autopair;
+        file = "share/zsh/zsh-autopair/autopair.zsh";
+      }
+      {
+        name = "zsh-bd";
+        src = zsh-bd;
+        file = "share/zsh-bd/bd.zsh";
+      }
+      {
+        name = "zsh-fzf-tab";
+        src = zsh-fzf-tab;
+        file = "share/fzf-tab/fzf-tab.zsh";
+      }
+      {
+        name = "zsh-fast-syntax-highlighting";
+        src = zsh-fast-syntax-highlighting;
+        file = "share/zsh/site-functions/fast-syntax-highlighting.plugin.zsh";
+      }
+      {
+        name = "zsh-powerlevel10k";
+        src = zsh-powerlevel10k;
+        file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
+      }
+      {
+        name = "zsh-forgit";
+        src = zsh-forgit;
+        file = "share/zsh/zsh-forgit/forgit.plugin.zsh";
+      }
+      {
+        name = "zsh-edit";
+        src = zsh-edit;
+        file = "share/zsh/zsh-edit/zsh-edit.plugin.zsh";
+      }
+      {
+        name = "fzf-git.sh";
+        src = fzf-git-sh;
+        file = "share/fzf-git-sh/fzf-git.sh";
+      }
+      {
+        name = "per-directory-history";
+        src = fetchFromGitHub {
+          owner = "jimhester";
+          repo = "per-directory-history";
+          rev = "0687bbfd736da566472a6d67c2b45c501b73d405";
+          sha256 = "7Z0qaDhgopKt9BDKSqdziw9jsVgiLLafs30wPPbz+oo=";
+        };
+        file = "per-directory-history.zsh";
+      }
+    ];
   };
 }
diff --git a/nix-conf/home/otm.nix b/nix-conf/home/otm.nix
index 7d7c667..2055780 100644
--- a/nix-conf/home/otm.nix
+++ b/nix-conf/home/otm.nix
@@ -103,13 +103,18 @@ let
     # and https://github.com/NixOS/nixpkgs/blob/4877ea239f4d02410c3516101faf35a81af0c30e/pkgs/development/compilers/openjdk/jre.nix#L32
     passthru.home = "${zscaler-jdk}"; # make sure JAVA_HOME is set
     installPhase =
+      # This is probably equivalent to
+      # $out/bin/keytool -import -noprompt -trustcacerts -alias zscalerrootca -keystore $out/lib/security/cacerts <<< "${zscaler-cert}"
+      # but follow the zscaler instructions just in case
       old.installPhase
       + ''
-        $out/bin/keytool -import -noprompt -trustcacerts -alias zscalerrootca -keystore $out/lib/security/cacerts <<< "${zscaler-cert}"
+        ${pkgs.openssl}/bin/openssl x509 -inform pem -outform der <<< "${zscaler-cert}" | $out/bin/keytool -import -noprompt -trustcacerts -alias zscalerrootca -keystore $out/lib/security/cacerts
       '';
   });
 
   zscaler-lein = pkgs.leiningen.override { jdk = zscaler-jdk; };
+  zscaler-clojure = pkgs.clojure.override { jdk = zscaler-jdk; };
+
 in
 {
   imports = [ ./includes/darwin.nix ];
@@ -133,17 +138,22 @@ in
     NIX_SSL_CERT_FILE = "${full-cert-file}";
     NODE_EXTRA_CA_CERTS = "${zscaler-cert-file}";
     JVM_OPTS = "-Dcom.amazonaws.sdk.disableCertChecking";
+    LEIN_JVM_OPTS = "-Dcom.amazonaws.sdk.disableCertChecking";
   };
 
   home.shellAliases = {
     notify_success = ''( osascript -e 'display notification "The command finished" with title "Success"' && afplay /System/Library/Sounds/Ping.aiff && say done  )'';
     notify_failure = ''( osascript -e 'display notification "The command failed" with title "Failure"' && afplay /System/Library/Sounds/Sosumi.aiff && say failed  )'';
     notify = "notify_success || notify_failure";
+    ltn = "lein test && notify";
+    yb = "aws codeartifact login --tool npm --repository otm-js --domain otm --domain-owner 103567893073 --region eu-west-1 --profile aws_otm_dev_developers && yarn && yarn build && notify";
     auth = "auth2aws login -r aws_otm_dev_developers,aws_otm_prd_developers && osascript -e 'tell app \"iTerm\" to activate'";
-    yarn_build = "aws codeartifact login --tool npm --repository otm-js --domain otm --domain-owner 103567893073 --region eu-west-1 --profile aws_otm_dev_developers && yarn && yarn build && notify";
   };
 
-  home.packages = with pkgs; [ zscaler-lein ];
+  home.packages = with pkgs; [
+    zscaler-clojure
+    zscaler-lein
+  ];
 
   home.file = {
     "certs/zscaler-cert.pem".source = zscaler-cert-file;
@@ -151,6 +161,8 @@ in
     "certs/full-cert.pem".source = full-cert-file;
     "certs/internal-ca.pem".text = internal-cert;
     "certs/staging-internal-ca.pem".text = internal-staging-cert;
+    ".docker/certs.d/zcaler-cert.pem".source = zscaler-cert-file;
+    ".wgetrc".text = "ca_certificate=${full-cert-file}";
   };
 
   sops.secrets = {
diff --git a/nix-conf/machines/djmuk1/configuration.nix b/nix-conf/machines/djmuk1/configuration.nix
index 3ae99c5..7405e9a 100644
--- a/nix-conf/machines/djmuk1/configuration.nix
+++ b/nix-conf/machines/djmuk1/configuration.nix
@@ -29,11 +29,7 @@
   services.sshguard.enable = true;
   services.oidentd.enable = true;
 
-  services.locate = {
-    enable = true;
-    package = pkgs.plocate;
-    localuser = null;
-  };
+  services.locate.enable = true;
 
   users.users.djm = {
     isNormalUser = true;
@@ -66,11 +62,13 @@
 
   programs.zsh.enable = true;
 
-  programs.vim.defaultEditor = true;
+  programs.vim = {
+    enable = true;
+    defaultEditor = true;
+  };
 
   environment.systemPackages = with pkgs; [
     #procmail
-    vim
     wget
   ];
 
@@ -81,5 +79,10 @@
 
   i18n.defaultLocale = "en_GB.UTF-8";
 
+  swapDevices = [ {
+    device = "/var/lib/swapfile";
+    size = 2*1024;
+  } ];
+
   system.stateVersion = "23.11";
 }
diff --git a/nix-conf/machines/djmuk2/configuration.nix b/nix-conf/machines/djmuk2/configuration.nix
index 9cc0a85..0b31a01 100644
--- a/nix-conf/machines/djmuk2/configuration.nix
+++ b/nix-conf/machines/djmuk2/configuration.nix
@@ -30,15 +30,11 @@
   services.sshguard.enable = true;
   services.oidentd.enable = true;
 
-  services.locate = {
-    enable = true;
-    package = pkgs.plocate;
-    localuser = null;
-  };
+  services.locate.enable = true;
 
   # Emulate nix-sops. Technically an anti-pattern, but this isn't a real secret, and this has to be embedded here, as we cannot set a file path to read it from.
   # Populate/update with:
-  # SOPS_AGE_KEY=$(doas ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key) sops -d --extract '["openiscsi_name"]' secrets/djmuk2.yaml | doas tee /root/.config/secrets/openiscsi_name
+  # SOPS_AGE_KEY=$(doas ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key) sops -d --extract '["openiscsi_name"]' machines/djmuk2/secrets.yaml | doas tee /root/.config/secrets/openiscsi_name
   services.openiscsi.enable = true;
   services.openiscsi.name = builtins.readFile "/root/.config/secrets/openiscsi_name";
   #services.openiscsi.enableAutoLoginOut = true;
@@ -74,12 +70,14 @@
 
   programs.zsh.enable = true;
 
-  programs.vim.defaultEditor = true;
+  programs.vim = {
+    enable = true;
+    defaultEditor = true;
+  };
 
   environment.systemPackages = with pkgs; [
     #procmail
     git
-    vim
     wget
   ];
 
diff --git a/nix-conf/secrets/djmuk2.yaml b/nix-conf/machines/djmuk2/secrets.yaml
index 3216fd3..3216fd3 100644
--- a/nix-conf/secrets/djmuk2.yaml
+++ b/nix-conf/machines/djmuk2/secrets.yaml
diff --git a/nix-conf/machines/edrahil/configuration.nix b/nix-conf/machines/edrahil/configuration.nix
index d78c2a8..a1bc8e3 100644
--- a/nix-conf/machines/edrahil/configuration.nix
+++ b/nix-conf/machines/edrahil/configuration.nix
@@ -3,6 +3,7 @@
   imports = [
     ./hardware-configuration.nix
     ./network-configuration.nix
+    <sops-nix/modules/sops>
   ];
 
   boot.tmp.cleanOnBoot = true;
@@ -17,6 +18,16 @@
     ];
   };
 
+  sops = {
+    defaultSopsFile = builtins.path {
+      path = /etc/nixos/secrets.yaml;
+      name = "edrahil-secrets.yaml";
+    };
+    secrets.restic_password = {
+      owner = config.users.users.djm.name;
+    };
+  };
+
   services.openssh = {
     enable = true;
     ports = [ 2222 ];
@@ -38,10 +49,95 @@
   services.sshguard.enable = true;
   services.oidentd.enable = true;
 
-  services.locate = {
-    enable = true;
-    package = pkgs.plocate;
-    localuser = null;
+  services.locate.enable = true;
+
+  services.restic = {
+    backups = {
+      hb = {
+        paths = [ "${config.users.users.djm.home}" ];
+        repository = "sftp:djm@hb-backup:/home/djm/backup/edrahil";
+        initialize = true;
+        user = "djm";
+        environmentFile = "/etc/restic-environment";
+        passwordFile = config.sops.secrets.restic_password.path;
+        timerConfig = {
+          OnCalendar = "02:25";
+          RandomizedDelaySec = "20min";
+        };
+        exclude = [
+          "irclogs"
+          ".cache"
+          ".config"
+          ".directory_history"
+          ".local"
+          "nixpkgs"
+        ];
+        extraBackupArgs = [
+          "--compression=max"
+        ];
+        pruneOpts = [
+          "--keep-daily 5"
+          "--keep-weekly 2"
+          "--keep-monthly 3"
+        ];
+      };
+      bs = {
+        paths = [ "${config.users.users.djm.home}" ];
+        repository = "sftp:djm@bs-backup:/home/djm/backup/edrahil";
+        initialize = true;
+        user = "djm";
+        environmentFile = "/etc/restic-environment";
+        passwordFile = config.sops.secrets.restic_password.path;
+        timerConfig = {
+          OnCalendar = "03:15";
+          RandomizedDelaySec = "20min";
+        };
+        exclude = [
+          "irclogs"
+          ".cache"
+          ".config"
+          ".directory_history"
+          ".local"
+          "nixpkgs"
+        ];
+        extraBackupArgs = [
+          "--compression=max"
+        ];
+        pruneOpts = [
+          "--keep-daily 5"
+          "--keep-weekly 2"
+          "--keep-monthly 3"
+        ];
+      };
+      tt = {
+        paths = [ "${config.users.users.djm.home}" ];
+        repository = "sftp:djm@tt-backup:/home/djm/backup/edrahil";
+        initialize = true;
+        user = "djm";
+        environmentFile = "/etc/restic-environment";
+        passwordFile = config.sops.secrets.restic_password.path;
+        timerConfig = {
+          OnCalendar = "04:05";
+          RandomizedDelaySec = "20min";
+        };
+        exclude = [
+          "irclogs"
+          ".cache"
+          ".config"
+          ".directory_history"
+          ".local"
+          "nixpkgs"
+        ];
+        extraBackupArgs = [
+          "--compression=max"
+        ];
+        pruneOpts = [
+          "--keep-daily 5"
+          "--keep-weekly 2"
+          "--keep-monthly 3"
+        ];
+      };
+    };
   };
 
   time.timeZone = "Europe/London";
@@ -77,7 +173,18 @@
 
   programs.zsh.enable = true;
 
-  programs.vim.defaultEditor = true;
+  programs.vim = {
+    enable = true;
+    defaultEditor = true;
+  };
+
+  environment.etc = {
+    "restic-environment" = {
+      text = ''
+        RESTIC_COMPRESSION=max
+      '';
+    };
+  };
 
   environment.systemPackages = with pkgs; [
     #procmail
diff --git a/nix-conf/machines/edrahil/network-configuration.nix b/nix-conf/machines/edrahil/network-configuration.nix
index b8ce55f..4b85912 100644
--- a/nix-conf/machines/edrahil/network-configuration.nix
+++ b/nix-conf/machines/edrahil/network-configuration.nix
@@ -6,7 +6,7 @@
         # Emulate nix-sops. Technically an anti-pattern, but IP addresses aren't real secrets, and this has to be embedded here,
         # as we cannot set a file path to read it from.
         # Populate/update with:
-        # SOPS_AGE_KEY=$(doas ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key) sops -d --extract '["ipv6_address"]' secrets/edrahil.yaml | doas tee /root/.config/secrets/ipv6_address
+        # SOPS_AGE_KEY=$(doas ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key) sops -d --extract '["ipv6_address"]' machines/edrahil/secrets.yaml | doas tee /root/.config/secrets/ipv6_address
         address = builtins.readFile "/root/.config/secrets/ipv6_address";
         prefixLength = 64;
       }
diff --git a/nix-conf/machines/edrahil/secrets.yaml b/nix-conf/machines/edrahil/secrets.yaml
new file mode 100644
index 0000000..1f4c31e
--- /dev/null
+++ b/nix-conf/machines/edrahil/secrets.yaml
@@ -0,0 +1,31 @@
+ipv6_address: ENC[AES256_GCM,data:CGQWUSuwmucIEwtlLK0FodXOWjM=,iv:ZLPiACwjOmes+FbezZKjjwUETujhTbT++4zCuoptpkY=,tag:VjMtetJhRDlJXdKAmJlOxQ==,type:str]
+restic_password: ENC[AES256_GCM,data:2sxeUDRdh9cPv0ACY9EIP7JcmPFo/w==,iv:bkA/FW82l5gSEOZPtVhSNoATmoJf07kC0FJLAcXFkZU=,tag:PbDY039oBas7CvK8RaFRkA==,type:str]
+sops:
+    kms: []
+    gcp_kms: []
+    azure_kv: []
+    hc_vault: []
+    age:
+        - recipient: age1tjfctwnwldmyxnu6qmeufgr9l79vyzmrs7fy58v3d0qj4x4nhqhq2gjmlp
+          enc: |
+            -----BEGIN AGE ENCRYPTED FILE-----
+            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvUGNnbm1Jemc5dVZYM01h
+            R0h4RlRpVnU1ZGxyL3V2TXdYS2JUSHFNTm1BCjJxdlFFbURjdXBaNjNUdldXNkJy
+            blZYRkhkZUgxR0lST2MxM3hENUhiQkEKLS0tIDhvYjhpRnpIVnVmV0VoTDFNOXIx
+            RlB1dXVsdEhETTNUdTRIbGxIMGNFSEkKqeafOyRg3F9dtENNnH5DhJzJU+AEEqrV
+            nfndOlVQe0G/e8SUzUYjVtD6V6Hj/x8OxN6FSOfZnNFNFHQgJ42jFg==
+            -----END AGE ENCRYPTED FILE-----
+        - recipient: age1w7kjp0qdgfyg9cyj5w4qc4fc9qz3w65xw2veazesfgdenqrd3ucqsc5ejv
+          enc: |
+            -----BEGIN AGE ENCRYPTED FILE-----
+            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwSGIvTjdEZGdGWm9ldnow
+            RGxnZ3RhMmthQXFhOCtaNUk1UGhYSytQdkFnCmY3UUxWVFJKeDE5eG9GNktobndz
+            UjBLOFBNWmFXSmJ2akRDYitsZm9TcmMKLS0tIDZoTGFxSWpwWmFTNjN6b2Q2T2Y3
+            Qm1PWnAvZGcxWGZjcnE4QWJZaDE2cGMKOAfTIipI68eJnOnvpQyLCOyH1KAWd/d/
+            SLnJQ+rmh9onA/znahB7Pn3LQtfKLNBADVtwLIuPID0FcgUW7nlOiw==
+            -----END AGE ENCRYPTED FILE-----
+    lastmodified: "2024-09-17T13:43:53Z"
+    mac: ENC[AES256_GCM,data:lVMbjnDvwlw72CiixJkEXCO7a20DYi4zKA8JTf0kSVQR/xjr9WbLpyllNq9Ex+eca/X0yaHBYjyOnBBpgz1h5o4i5iq738VXOEqD9v5BMdOrVmmDNnVcTAXqmWZGE7/pGmkiKef/iXOyJT2vsrrYR0vhgrvo/0WXce1YLUA4NTs=,iv:Y1w/llSNDry+PWz4oA/0MBJ+Ra6ceC1ZHMKb+CPCvE0=,tag:r2RR6ZfGL9TYwHtV9auL3A==,type:str]
+    pgp: []
+    unencrypted_suffix: _unencrypted
+    version: 3.8.1
diff --git a/nix-conf/machines/egalmoth/configuration.nix b/nix-conf/machines/egalmoth/configuration.nix
index 21b7d23..e47cd45 100644
--- a/nix-conf/machines/egalmoth/configuration.nix
+++ b/nix-conf/machines/egalmoth/configuration.nix
@@ -4,7 +4,9 @@
   lib,
   ...
 }:
-
+let
+  unstable = import <unstable> { };
+in
 {
   imports = [ ./hardware-configuration.nix ];
 
@@ -52,8 +54,7 @@
     };
   };
 
-  hardware.opengl.enable = true;
-  hardware.opengl.driSupport = true;
+  hardware.graphics.enable = true;
 
   networking.hostName = "egalmoth"; # Define your hostname.
   networking.networkmanager.enable = true;
@@ -158,11 +159,7 @@
     ];
   };
 
-  services.locate = {
-    enable = true;
-    package = pkgs.plocate;
-    localuser = null;
-  };
+  services.locate.enable = true;
 
   environment.systemPackages = with pkgs; [
     acpi
@@ -181,7 +178,8 @@
     rofi
     st
     sway
-    vim
+    vdhcoapp
+    ungoogled-chromium
     wayland
     wayst
     wezterm
@@ -206,6 +204,7 @@
     iosevka-bin
     jetbrains-mono
     meslo-lgs-nf
+    unstable.aporetic
   ];
 
   programs.zsh.enable = true;
@@ -220,7 +219,10 @@
     enableSSHSupport = true;
   };
 
-  programs.vim.defaultEditor = true;
+  programs.vim = {
+    enable = true;
+    defaultEditor = true;
+  };
 
   services.openssh.enable = true;
 
diff --git a/nix-conf/secrets/edrahil.yaml b/nix-conf/secrets/edrahil.yaml
deleted file mode 100644
index 1b15022..0000000
--- a/nix-conf/secrets/edrahil.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-ipv6_address: ENC[AES256_GCM,data:4oIZakw5l3axCBc4aMTj1kxpUNg=,iv:/wocTWNcxkgOQQF31XJ3/tMuUm9u+oDSwa2IqWkTMnI=,tag:vx8gYah7r3qSt/dbd4U/cA==,type:str]
-sops:
-    kms: []
-    gcp_kms: []
-    azure_kv: []
-    hc_vault: []
-    age:
-        - recipient: age1tjfctwnwldmyxnu6qmeufgr9l79vyzmrs7fy58v3d0qj4x4nhqhq2gjmlp
-          enc: |
-            -----BEGIN AGE ENCRYPTED FILE-----
-            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpOExVL2dvUGloajRUM042
-            a2xQMTcrRDdmUWJmdkxMdnZleHYyZGordW5rCjBTQmRWdndYbjNsQnd2QXo5VVRs
-            aytvOVEvZUtBMm9lYlVNTjlaN3JvS00KLS0tIFBJVWlNQzB2ZXA4ZWRKdmRaSjYy
-            L2owQXVwRXRnWmhuVGk5QjVwQjdweEEKxksatVlA9RP4CqRCRAiXjLE4W3iZa1P6
-            pOtqoPB+QtcnJtEo5rOU+Bw7nlHVocy9oshwrgN+vNWoiCoQwAGUSw==
-            -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2024-08-30T08:39:18Z"
-    mac: ENC[AES256_GCM,data:jRAyoYXXG6AKugVUyqv6tDp3orSZn66zn7ypVh5wsmbQictV8jeY6lrN/0AZsKZyTDuOlguG1NYRm8WHdSndZtPyv18LAme4nnAcMkqBGFQ4Uo5kx1zNv/+fi6CzLNYwiok1UbJGtMdASqpSXKgMiuGaBct5OohXzzgvHE7npFY=,iv:PCYwNQpBnhvZNhnwUO4iMuO6/A09XvPrRucQX4Hzx+4=,tag:d8MhigIjNM49fnas7JeaTg==,type:str]
-    pgp: []
-    unencrypted_suffix: _unencrypted
-    version: 3.8.1