NixDaemon

NixOS pentest workstation as one flake — IceBreaker's successor
git clone https://git.daemon-sec.xyz/NixDaemon.git
Log | Files | Refs | README

shell.nix (5492B)


      1 # modules/home/shell.nix — zsh as the shell, configured by the dotfiles.
      2 #
      3 # The dotfiles checkout (~/git/daemon-sec-dotfiles) carries a complete zsh
      4 # setup in home/.dotfiles: a ZDOTDIR tree with core.zsh (history, cached
      5 # compinit, the plugin loader, zoxide/atuin/fzf hooks), the leaf modules
      6 # (aliases, fzf verbs, ripgrep, cheats, music, jj, …), theme.zsh (starship
      7 # with a transient prompt) and animations.zsh (the login splash). The plugins
      8 # it loads — zsh-autosuggestions, zsh-syntax-highlighting, zsh-completions,
      9 # fzf-tab, history-substring-search, you-should-use — are vendored in
     10 # .dotfiles/config/plugins, so the config is used as-is rather than rewritten
     11 # as home-manager options. This module only supplies what the Omarchy install
     12 # had and NixOS does not:
     13 #
     14 #   ~/.zshenv            sets ZDOTDIR (home-manager owns this one file)
     15 #   ~/.dotfiles          → the checkout's .dotfiles (edits follow the repo)
     16 #   ~/.fzf.zsh           fzf's key bindings from the Nix store (core.zsh looks
     17 #                        in /usr/share/fzf, which does not exist here)
     18 #   ~/.zsh/completions   generated completions for tools without shipped ones
     19 #   tmux plugins from nixpkgs (~/.tmux.conf expects TPM; a shim loads them)
     20 #   ~/.config/secretspec  the keyring provider
     21 #
     22 # The dotfiles themselves (~/.dotfiles, ~/.tmux.conf, the tool configs under
     23 # ~/.config: starship, bat theme, atuin, fastfetch, cheats, …) are linked by
     24 # modules/home/dotfiles.nix. NixOS side (modules/hosts/laptop/configuration.nix): programs.zsh with the global compinit
     25 # and prompt off (core.zsh and theme.zsh do those), users.<user>.shell.
     26 { ... }:
     27 {
     28   flake.homeModules.shell =
     29   { config, pkgs, lib, ... }:
     30   let
     31     # Completions for tools that do not ship their own under share/zsh.
     32     # (uv, jj, gh, atuin, zoxide, eza, bat, fd, rg do; /etc/zshrc puts the
     33     # profiles' site-functions on fpath before core.zsh runs compinit.)
     34     generatedCompletions = pkgs.runCommand "nixdaemon-zsh-completions" { } ''
     35       mkdir -p $out
     36       export HOME=$TMPDIR
     37       ${pkgs.secretspec}/bin/secretspec completions zsh > $out/_secretspec
     38     '';
     39 
     40     # ~/.tmux.conf ends with `run '~/.tmux/plugins/tpm/tpm'` and lists plugins
     41     # for TPM to clone. nixpkgs has the plugins but not TPM, so each plugin is
     42     # linked where TPM would have put it and this stand-in sources them.
     43     tpmShim = ''
     44       #!${pkgs.bash}/bin/bash
     45       # Stand-in for tmux-plugin-manager (NixDaemon modules/home/shell.nix): the
     46       # plugins come from nixpkgs and are linked into ~/.tmux/plugins; this runs
     47       # each plugin's entry script the way TPM would. prefix+I/U do nothing here;
     48       # add plugins in shell.nix instead.
     49       for f in "$HOME"/.tmux/plugins/*/*.tmux; do
     50         case "$f" in */tpm/*) continue ;; esac
     51         [ -x "$f" ] && "$f"
     52       done
     53       exit 0
     54     '';
     55     tmuxPlugin = name: pkg: {
     56       name = ".tmux/plugins/${name}";
     57       value.source = "${pkg}/share/tmux-plugins/${pkg.pluginName}";
     58     };
     59   in
     60   {
     61     home.packages = with pkgs; [
     62       zsh
     63       tmux
     64       secretspec
     65     ];
     66 
     67     home.file = {
     68       # zsh: hand over to the dotfiles' ZDOTDIR tree.
     69       ".zshenv".text = ''
     70         # Managed by home-manager (NixDaemon modules/home/shell.nix). The shell
     71         # configuration lives in ~/.dotfiles (→ ~/git/daemon-sec-dotfiles).
     72         export ZDOTDIR="$HOME/.dotfiles"
     73         # home.sessionVariables (PASSAGE_*, XDG_*, …); programs.zsh is off, so
     74         # nothing else sources this.
     75         [[ -r "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" ]] \
     76           && . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
     77         [[ -r "$HOME/.cargo/env" ]] && . "$HOME/.cargo/env"
     78       '';
     79       ".fzf.zsh".text = ''
     80         # fzf key bindings (Ctrl-T, Alt-C, Ctrl-R) and completion from the Nix
     81         # store; sourced by ~/.dotfiles/config/core.zsh. Quiet when there is no
     82         # tty (the scripts restore `zle`, which fails outside a terminal).
     83         if [[ -t 0 ]]; then
     84           source ${pkgs.fzf}/share/fzf/key-bindings.zsh
     85           source ${pkgs.fzf}/share/fzf/completion.zsh
     86         else
     87           { source ${pkgs.fzf}/share/fzf/key-bindings.zsh; source ${pkgs.fzf}/share/fzf/completion.zsh; } 2>/dev/null
     88         fi
     89       '';
     90       ".zsh/completions".source = generatedCompletions;
     91 
     92       ".tmux/plugins/tpm/tpm" = {
     93         text = tpmShim;
     94         executable = true;
     95       };
     96     }
     97     // builtins.listToAttrs [
     98       (tmuxPlugin "tmux-resurrect" pkgs.tmuxPlugins.resurrect)
     99       (tmuxPlugin "tmux-continuum" pkgs.tmuxPlugins.continuum)
    100       (tmuxPlugin "tmux-yank" pkgs.tmuxPlugins.yank)
    101       (tmuxPlugin "tmux-open" pkgs.tmuxPlugins.open)
    102     ];
    103 
    104     xdg.configFile = {
    105       # secretspec (https://secretspec.dev): secrets in the system keyring, which
    106       # gnome-keyring provides and PAM unlocks at login. Per-project
    107       # secretspec.toml files declare what a project needs; `secretspec check`
    108       # prompts for anything missing, `secretspec run -- cmd` injects them.
    109       "secretspec/config.toml".text = ''
    110         [defaults]
    111         provider = "keyring"
    112         profile = "default"
    113       '';
    114     };
    115 
    116     # bat only sees a theme after its cache is rebuilt from ~/.config/bat/themes.
    117     home.activation.batCache = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
    118       if [ -d "$HOME/.config/bat/themes/" ]; then
    119         run ${pkgs.bat}/bin/bat cache --build >/dev/null 2>&1 || true
    120       fi
    121     '';
    122   }
    123   ;
    124 }