NixDaemon

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

prompt.nix (9411B)


      1 # modules/home/prompt.nix — the starship prompt and the fastfetch card, fresh
      2 # (2026-10-08), Rosé Pine, one colour per section, nothing Omarchy.
      3 #
      4 # Prompt (two lines, the dotfiles' "filigree" frame kept, the per-letter
      5 # gradients gone):
      6 #
      7 #   ╭╌ ☧  daemonsec@nixos ┄ 󰉋 ~/NixDaemon ┄  main [+2 !1] ⌁⡇⡆·    (right: 󰔚 3s · 󰥔 14:02)
      8 #   ╰╌ ❯
      9 #
     10 #   glyph iris · user rose · host foam · directory gold · git love (status subtle,
     11 #   week heartbeat iris) · languages text · duration/jobs gold · clock rose ·
     12 #   prompt char foam (love after an error). pine is never ink (3.3:1 on base).
     13 #   $CROSS_GLYPH comes from the dotfiles' animations.zsh (☧ + the NixOS glyph).
     14 #
     15 # theme.zsh in the dotfiles runs `starship init zsh` and adds the transient
     16 # prompt, so home-manager's own shell integration stays off here.
     17 #
     18 # fastfetch: the builtin NixOS logo in iris/foam, keys in rotating Rosé Pine
     19 # colours, the modules that matter on this laptop. The login splash
     20 # (animations.zsh) runs plain `fastfetch` when CROSS_FETCH=plain, which
     21 # .dotfiles/.zshrc now sets, so this config draws the whole card.
     22 { ... }:
     23 {
     24   flake.homeModules.prompt =
     25   { lib, ... }:
     26   let
     27     # Rosé Pine (main)
     28     rp = {
     29       love = "#eb6f92";
     30       gold = "#f6c177";
     31       rose = "#ebbcba";
     32       pine = "#31748f";
     33       foam = "#9ccfd8";
     34       iris = "#c4a7e7";
     35       text = "#e0def4";
     36       subtle = "#908caa";
     37       muted = "#6e6a86";
     38     };
     39     # the same colours as SGR parameters for fastfetch
     40     sgr = {
     41       love = "38;2;235;111;146";
     42       gold = "38;2;246;193;119";
     43       rose = "38;2;235;188;186";
     44       foam = "38;2;156;207;216";
     45       iris = "38;2;196;167;231";
     46       text = "38;2;224;222;244";
     47       subtle = "38;2;144;140;170";
     48       muted = "38;2;110;106;134";
     49     };
     50     lang = symbol: colour: {
     51       inherit symbol;
     52       format = " [$symbol($version)](fg:${colour})";
     53     };
     54   in
     55   {
     56     programs.starship = {
     57       enable = true;
     58       enableZshIntegration = false; # theme.zsh does it (with the transient prompt)
     59       enableBashIntegration = false;
     60       settings = {
     61         "$schema" = "https://starship.rs/config-schema.json";
     62         add_newline = true;
     63         palette = "rose_pine";
     64         palettes.rose_pine = rp;
     65 
     66         format = lib.concatStrings [
     67           "[╭╌](fg:muted) "
     68           "\${env_var.CROSS_GLYPH}"
     69           # The current pentest target, when one is set. starship renders
     70           # nothing that is not named here, so defining env_var.TARGET in
     71           # modules/home/htb-shell.nix is not enough on its own. It collapses
     72           # to nothing when $TARGET is unset.
     73           "\${env_var.TARGET}"
     74           "$username"
     75           "$hostname"
     76           "$shlvl"
     77           "$sudo"
     78           "\${custom.root}"
     79           "$directory"
     80           "$git_branch"
     81           "$git_status"
     82           "\${custom.gitweek}"
     83           "$git_state"
     84           "$python"
     85           "$nodejs"
     86           "$rust"
     87           "$golang"
     88           "$lua"
     89           "$docker_context"
     90           "$package"
     91           "$line_break"
     92           "[╰╌](fg:muted) "
     93           "$status"
     94           "$character"
     95         ];
     96         right_format = lib.concatStrings [ "$cmd_duration" "$jobs" "$battery" "$time" ];
     97 
     98         # identity
     99         env_var.CROSS_GLYPH = {
    100           variable = "CROSS_GLYPH";
    101           default = "☧";
    102           format = "[$env_value](bold fg:iris) ";
    103         };
    104         username = {
    105           show_always = true;
    106           format = "[$user](bold fg:rose)";
    107           style_user = "bold fg:rose";
    108           style_root = "bold fg:love";
    109         };
    110         hostname = {
    111           ssh_only = false;
    112           format = "[@](fg:muted)[$hostname](bold fg:foam)";
    113         };
    114         shlvl = {
    115           disabled = false;
    116           threshold = 2;
    117           format = " [↕$shlvl](bold fg:gold)";
    118         };
    119         sudo = {
    120           disabled = false;
    121           format = " [](bold fg:love)";
    122         };
    123         custom.root = {
    124           command = "echo ROOT";
    125           when = "[ \"$(id -u)\" -eq 0 ]";
    126           format = " [ $output](bold underline fg:love)";
    127         };
    128 
    129         # place
    130         directory = {
    131           format = " [┄](fg:muted) [󰉋 $path](bold fg:gold)[$read_only](fg:love)";
    132           truncation_length = 4;
    133           truncate_to_repo = true;
    134           truncation_symbol = "…/";
    135           read_only = " 󰌾";
    136         };
    137 
    138         # git
    139         git_branch = {
    140           symbol = " ";
    141           format = " [┄](fg:muted) [$symbol$branch(:$remote_branch)](bold fg:love)";
    142         };
    143         git_status = {
    144           format = "( [\\[$all_status$ahead_behind\\]](fg:subtle))";
    145           ahead = "⇡\${count}";
    146           behind = "⇣\${count}";
    147           diverged = "⇕⇡\${ahead_count}⇣\${behind_count}";
    148           conflicted = "=";
    149           untracked = "?";
    150           stashed = "≡";
    151           modified = "!";
    152           staged = "+";
    153           renamed = "»";
    154           deleted = "✘";
    155         };
    156         # the last 7 days of commits as a braille pulse (carried from the dotfiles)
    157         custom.gitweek = {
    158           command = ''git log --since=7.days --date=format:%Y%m%d --pretty=%cd 2>/dev/null | sort | uniq -c | awk 'BEGIN{split("· ⡀ ⡄ ⡆ ⡇",b," ")}{c[$2]=$1}END{for(i=6;i>=0;i--){d=strftime("%Y%m%d",systime()-i*86400);v=c[d]+0;idx=(v==0)?1:(v<3)?2:(v<6)?3:(v<10)?4:5;printf "%s",b[idx]}}' '';
    159           when = "git rev-parse --is-inside-work-tree 2>/dev/null | grep -q true";
    160           format = " [⌁$output](fg:iris)";
    161         };
    162         git_state = {
    163           format = " [\\($state $progress_current/$progress_total\\)](bold fg:love)";
    164         };
    165 
    166         # toolchains: only when the directory uses them
    167         python = (lang " " "text") // { format = " [$symbol$version( \\($virtualenv\\))](fg:text)"; };
    168         nodejs = lang " " "text";
    169         rust = lang " " "text";
    170         golang = lang " " "text";
    171         lua = lang " " "text";
    172         docker_context = { symbol = " "; format = " [$symbol$context](fg:subtle)"; };
    173         package = { symbol = "󰏗 "; format = " [$symbol$version](fg:subtle)"; };
    174 
    175         # right side
    176         cmd_duration = { min_time = 2000; format = "[󰔚 $duration](fg:gold) "; };
    177         jobs = { symbol = "󰜎 "; format = "[$symbol$number](bold fg:gold) "; };
    178         battery = {
    179           full_symbol = "󱈑 ";
    180           charging_symbol = "󰂄 ";
    181           discharging_symbol = "󱈏 ";
    182           unknown_symbol = "󰂑 ";
    183           empty_symbol = "󰁺 ";
    184           format = "[$symbol$percentage]($style) ";
    185           display = [
    186             { threshold = 20; style = "bold fg:love"; }
    187             { threshold = 50; style = "fg:gold"; }
    188           ];
    189         };
    190         time = {
    191           disabled = false;
    192           time_format = "%H:%M";
    193           format = "[󰥔 $time](fg:rose)";
    194         };
    195 
    196         # second line
    197         status = {
    198           disabled = false;
    199           symbol = "✗ ";
    200           format = "[$symbol$status](fg:love) ";
    201         };
    202         character = {
    203           success_symbol = "[❯](bold fg:foam)";
    204           error_symbol = "[❯](bold fg:love)";
    205           vimcmd_symbol = "[❮](bold fg:gold)";
    206           vimcmd_replace_one_symbol = "[❮](bold fg:rose)";
    207           vimcmd_replace_symbol = "[❮](bold fg:iris)";
    208           vimcmd_visual_symbol = "[❮](bold fg:gold)";
    209         };
    210         line_break.disabled = false;
    211       };
    212     };
    213 
    214     programs.fastfetch = {
    215       enable = true;
    216       settings = {
    217         "$schema" = "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json";
    218         logo = {
    219           type = "builtin";
    220           source = "nixos";
    221           color = { "1" = sgr.iris; "2" = sgr.foam; };
    222           padding = { top = 1; left = 2; right = 5; };
    223         };
    224         display = {
    225           separator = "  ";
    226           color = { keys = sgr.foam; title = sgr.rose; };
    227         };
    228         modules = [
    229           { type = "title"; color = { user = sgr.rose; at = sgr.muted; host = sgr.foam; }; }
    230           { type = "separator"; string = "┄"; length = 34; outputColor = sgr.muted; }
    231           { type = "os"; key = "  os"; keyColor = sgr.iris; }
    232           { type = "kernel"; key = "  kernel"; keyColor = sgr.foam; }
    233           { type = "uptime"; key = "  uptime"; keyColor = sgr.gold; }
    234           { type = "packages"; key = "󰏗  packages"; keyColor = sgr.rose; }
    235           { type = "shell"; key = "  shell"; keyColor = sgr.love; }
    236           "break"
    237           { type = "wm"; key = "  wm"; keyColor = sgr.iris; }
    238           { type = "display"; key = "󱄄  display"; keyColor = sgr.foam; compactType = "original-with-refresh-rate"; }
    239           { type = "terminal"; key = "  terminal"; keyColor = sgr.gold; }
    240           { type = "terminalfont"; key = "  font"; keyColor = sgr.rose; }
    241           "break"
    242           { type = "host"; key = "󰌢  host"; keyColor = sgr.love; }
    243           { type = "cpu"; key = "  cpu"; keyColor = sgr.iris; showPeCoreCount = true; }
    244           { type = "gpu"; key = "  gpu"; keyColor = sgr.foam; detectionMethod = "pci"; format = "{name}"; }
    245           { type = "memory"; key = "  memory"; keyColor = sgr.gold; }
    246           { type = "disk"; key = "󰋊  disk"; keyColor = sgr.rose; folders = "/"; }
    247           { type = "battery"; key = "󰁹  battery"; keyColor = sgr.love; }
    248           "break"
    249           { type = "colors"; symbol = "circle"; paddingLeft = 2; }
    250         ];
    251       };
    252     };
    253   }
    254   ;
    255 }