me like nix
0

Configure Feed

Select the types of activity you want to include in your feed.

1{ 2 pkgs, 3 inputs, 4 config, 5 ... 6}: 7 8{ 9 # Import the home-manager modules you want to use 10 imports = [ 11 inputs.catppuccin.homeModules.catppuccin 12 inputs.niri.homeModules.niri 13 inputs.zen-browser.homeModules.beta 14 inputs.agenix.homeManagerModules.default 15 ]; 16 17 # All your user-specific packages 18 home.packages = with pkgs; [ 19 helix 20 git 21 jujutsu # jj-cli 22 atop 23 zellij # terminal multiplexer 24 alacritty 25 fuzzel # Application launcher 26 bemoji # emoji picker 27 networkmanager_dmenu # network picker for fuzzel 28 quickshell # Status bar (QML-based) 29 swww # For setting wallpapers 30 cliphist # Clipboard history manager 31 pavucontrol # GUI for PulseAudio/PipeWire volume control 32 playerctl # MPRIS media player control 33 (element-desktop.override { 34 commandLineArgs = "--password-store=gnome-libsecret"; 35 }) 36 fd 37 ripgrep 38 yazi # tui file browser 39 gh # github cli 40 signal-desktop 41 xwayland-satellite # for running x11 apps 42 nixfmt # nix formatter 43 nil # nix language server 44 atac # postman-like TUI 45 trippy # network analyzer 46 rsync # file sync utility 47 udiskie # for mounting external drives 48 darktable # photo editing 49 zoxide 50 chromium 51 claude-code 52 nautilus # file browser 53 sqlitebrowser 54 gnome-characters # symbol picker 55 sendme # file transfer 56 desktop-file-utils # for managing .desktop files 57 flyctl # fly.io cli 58 vscode-json-languageserver 59 gnome-network-displays 60 doppler # secret management 61 rainfrog # db tui 62 loupe # image viewer 63 glycin-loaders # various format loaders for loupe 64 docker-compose 65 discord 66 mangohud 67 prismlauncher # minecraft launcher 68 fastfetch 69 inputs.agenix.packages.${pkgs.system}.default # agenix CLI 70 age-plugin-yubikey # Yubikey support for agenix 71 72 # --- FONTS ARE IMPORTANT --- 73 # Berkeley Mono is the main system font, keeping JetBrains and Font Awesome for icons 74 font-awesome 75 noto-fonts 76 noto-fonts-cjk-sans 77 noto-fonts-color-emoji 78 nerd-fonts.jetbrains-mono 79 nerd-fonts.symbols-only 80 # --- POLKIT AGENT (for 1Password GUI, etc.) --- 81 lxqt.lxqt-policykit # Lightweight polkit agent 82 ]; 83 84 programs.niri = { 85 enable = true; 86 settings = { 87 window-rules = [ 88 { 89 geometry-corner-radius = { 90 top-left = 5.0; 91 top-right = 5.0; 92 bottom-left = 5.0; 93 bottom-right = 5.0; 94 }; 95 clip-to-geometry = true; 96 draw-border-with-background = false; 97 } 98 ]; 99 debug = { 100 honor-xdg-activation-with-invalid-serial = { }; 101 }; 102 layout = { 103 focus-ring = { 104 width = 2; 105 active.color = "#8caaee"; 106 inactive.color = "#414559"; 107 }; 108 struts = { 109 top = -6; 110 bottom = -6; 111 left = 0; 112 right = 0; 113 }; 114 gaps = 8; 115 }; 116 gestures = { 117 hot-corners = { 118 enable = false; 119 }; 120 }; 121 binds = { 122 "Mod+d".action.spawn = "fuzzel"; 123 "Mod+e".action.spawn = "bemoji"; 124 "Mod+n".action.spawn = "networkmanager_dmenu"; 125 "Mod+a".action.spawn = "alacritty"; 126 "Mod+h".action = { 127 focus-column-left = { }; 128 }; 129 "Mod+j".action = { 130 focus-workspace-down = { }; 131 }; 132 "Mod+k".action = { 133 focus-workspace-up = { }; 134 }; 135 "Mod+l".action = { 136 focus-column-right = { }; 137 }; 138 "Mod+Shift+h".action = { 139 move-column-left = { }; 140 }; 141 "Mod+Shift+j".action = { 142 move-window-down-or-to-workspace-down = { }; 143 }; 144 "Mod+Shift+k".action = { 145 move-window-up-or-to-workspace-up = { }; 146 }; 147 "Mod+Shift+l".action = { 148 move-column-right = { }; 149 }; 150 "Mod+Down".action = { 151 move-workspace-down = { }; 152 }; 153 "Mod+Up".action = { 154 move-workspace-up = { }; 155 }; 156 "Mod+p".action = { 157 show-hotkey-overlay = { }; 158 }; 159 "Mod+o".action = { 160 toggle-overview = { }; 161 }; 162 "Mod+q".action = { 163 close-window = { }; 164 }; 165 "Mod+f".action = { 166 toggle-window-floating = { }; 167 }; 168 "Mod+Shift+f".action = { 169 switch-focus-between-floating-and-tiling = { }; 170 }; 171 "Mod+m".action = { 172 fullscreen-window = { }; 173 }; 174 "Mod+s".action = { 175 screenshot = { 176 show-pointer = true; 177 }; 178 }; 179 "Mod+1".action = { 180 set-column-width = "100%"; 181 }; 182 "Mod+2".action = { 183 set-column-width = "50%"; 184 }; 185 "Mod+Minus".action = { 186 set-column-width = "-10%"; 187 }; 188 "Mod+Equal".action = { 189 set-column-width = "+10%"; 190 }; 191 "Mod+Shift+q".action = { 192 quit = { }; 193 }; 194 "Mod+Shift+r".action.spawn = [ 195 "systemctl" 196 "--user" 197 "restart" 198 "quickshell.service" 199 ]; 200 "XF86AudioPlay".action.spawn = [ 201 "playerctl" 202 "play-pause" 203 ]; 204 "XF86AudioStop".action.spawn = [ 205 "playerctl" 206 "stop" 207 ]; 208 "XF86AudioNext".action.spawn = [ 209 "playerctl" 210 "next" 211 ]; 212 "XF86AudioPrev".action.spawn = [ 213 "playerctl" 214 "previous" 215 ]; 216 "XF86MonBrightnessDown".action.spawn = [ 217 "brightnessctl" 218 "set" 219 "5%-" 220 ]; 221 "XF86MonBrightnessUp".action.spawn = [ 222 "brightnessctl" 223 "set" 224 "+5%" 225 ]; 226 }; 227 outputs = { 228 # External monitor - primary display at position (0, 0) 229 "DP-5" = { 230 scale = 2.0; 231 mode = { 232 width = 5120; 233 height = 2160; 234 refresh = 120.0; 235 }; 236 position = { 237 x = 0; 238 y = 0; 239 }; 240 }; 241 "DP-1" = { 242 scale = 2.0; 243 mode = { 244 width = 5120; 245 height = 2160; 246 refresh = 120.0; 247 }; 248 position = { 249 x = 0; 250 y = 0; 251 }; 252 }; 253 "DP-2" = { 254 scale = 1.0; 255 mode = { 256 width = 5120; 257 height = 2160; 258 refresh = 120.0; 259 }; 260 position = { 261 x = 0; 262 y = 0; 263 }; 264 }; 265 "DP-6" = { 266 scale = 2.0; 267 mode = { 268 width = 5120; 269 height = 2160; 270 refresh = 120.0; 271 }; 272 position = { 273 x = 0; 274 y = 0; 275 }; 276 }; 277 "DP-7" = { 278 scale = 2.0; 279 mode = { 280 width = 5120; 281 height = 2160; 282 refresh = 120.0; 283 }; 284 position = { 285 x = 0; 286 y = 0; 287 }; 288 }; 289 # Laptop display - secondary display positioned underneath 290 "eDP-1" = { 291 scale = 1.5; 292 mode = { 293 width = 2560; 294 height = 1600; 295 refresh = 165.0; 296 }; 297 position = { 298 x = 0; 299 y = 1080; # Position underneath the external monitor (2160 / 2 scale = 1080 logical height) 300 }; 301 }; 302 }; 303 spawn-at-startup = [ 304 { command = [ "xwayland-satellite" ]; } 305 { command = [ "swww-daemon" ]; } 306 { command = [ "wl-paste --watch cliphist store" ]; } 307 ]; 308 environment = { 309 DISPLAY = ":0"; 310 }; 311 }; 312 }; 313 314 # Allow unfree packages 315 nixpkgs.config.allowUnfree = true; 316 317 nixpkgs.config.permittedInsecurePackages = [ 318 "libsoup-2.74.3" 319 ]; 320 321 # Quickshell status bar 322 xdg.configFile."quickshell/shell.qml".source = ./quickshell/shell.qml; 323 324 systemd.user.services.quickshell = { 325 Unit = { 326 Description = "QuickShell status bar"; 327 After = [ "graphical-session.target" ]; 328 PartOf = [ "graphical-session.target" ]; 329 }; 330 Service = { 331 ExecStart = "${pkgs.quickshell}/bin/quickshell"; 332 Restart = "on-failure"; 333 RestartSec = 2; 334 }; 335 Install = { 336 WantedBy = [ "graphical-session.target" ]; 337 }; 338 }; 339 340 systemd.user.services.quickshell-reload = { 341 Unit = { 342 Description = "Reload QuickShell on wake or display change"; 343 After = [ 344 "quickshell.service" 345 "graphical-session.target" 346 ]; 347 PartOf = [ "graphical-session.target" ]; 348 }; 349 Service = { 350 Type = "simple"; 351 ExecStart = "${pkgs.writeShellScript "quickshell-reload" '' 352 LOCKFILE="/tmp/quickshell-reload.lock" 353 354 do_restart() { 355 ( 356 ${pkgs.util-linux}/bin/flock -xn 200 || exit 0 357 sleep 2 358 ${pkgs.systemd}/bin/systemctl --user restart quickshell.service 359 sleep 3 360 ) 200>"$LOCKFILE" 361 } 362 363 # Sleep/wake monitor 364 ${pkgs.dbus}/bin/dbus-monitor --system \ 365 "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForSleep'" 2>/dev/null | \ 366 while IFS= read -r line; do 367 if [[ "$line" == *"boolean false"* ]]; then 368 do_restart 369 fi 370 done & 371 372 # Display hotplug monitor 373 ${pkgs.systemd}/bin/udevadm monitor --property --subsystem-match=drm 2>/dev/null | \ 374 while IFS= read -r line; do 375 if [[ "$line" == *"HOTPLUG=1"* ]]; then 376 do_restart 377 fi 378 done & 379 380 wait 381 ''}"; 382 Restart = "on-failure"; 383 RestartSec = 5; 384 }; 385 Install = { 386 WantedBy = [ "graphical-session.target" ]; 387 }; 388 }; 389 390 programs.ssh = { 391 enable = true; 392 enableDefaultConfig = false; 393 matchBlocks = { 394 "*" = { 395 identityFile = [ 396 "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk" 397 "${config.home.homeDirectory}/.ssh/id_rsa.pub" 398 ]; 399 }; 400 }; 401 }; 402 403 programs.awscli = { 404 enable = true; 405 settings = { 406 "default" = { 407 region = "us-east-1"; 408 }; 409 }; 410 }; 411 412 services.udiskie = { 413 enable = true; 414 tray = "auto"; 415 automount = true; 416 }; 417 418 services.mako = { 419 enable = true; 420 settings = { 421 border-radius = 8; 422 border-size = 2; 423 padding = "12"; 424 margin = "12"; 425 font = "BerkeleyMono Nerd Font 11"; 426 on-button-left = "invoke-default-action"; 427 on-button-right = "dismiss"; 428 }; 429 }; 430 431 catppuccin = { 432 enable = true; 433 flavor = "frappe"; 434 }; 435 436 programs.fuzzel.enable = true; 437 438 programs.direnv.enable = true; 439 440 programs.atuin = { 441 enable = true; 442 enableFishIntegration = true; 443 daemon.enable = true; 444 settings = { 445 filter_mode_shell_up_key_binding = "session"; 446 }; 447 }; 448 449 programs.zellij = { 450 enable = true; 451 settings = { 452 keybinds = { 453 unbind = [ 454 "Ctrl q" 455 "Ctrl o" 456 ]; 457 normal = { 458 "bind \"Ctrl m\"" = { 459 SwitchToMode = "Session"; 460 }; 461 }; 462 }; 463 pane_frames = false; 464 show_startup_tips = false; 465 ui = { 466 pane_frames.hide_session_name = true; 467 }; 468 }; 469 }; 470 471 programs.zen-browser.enable = true; 472 # programs.swww.enable = true; 473 programs.zoxide = { 474 enable = true; 475 enableFishIntegration = true; 476 }; 477 478 programs.obs-studio = { 479 enable = true; 480 plugins = with pkgs.obs-studio-plugins; [ 481 obs-backgroundremoval 482 ]; 483 }; 484 485 # Program configurations 486 programs.git = { 487 enable = true; 488 settings = { 489 user = { 490 name = "seanaye"; 491 email = "hello@seanaye.ca"; 492 }; 493 init.defaultBranch = "main"; 494 commit.gpgSign = true; 495 gpg.format = "ssh"; 496 user.signingKey = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIOIgEteUEW06dnBHe2z8vNLwz2iMKe8bba6JgMmOUpcBAAAABHNzaDo= sean@framework16"; 497 gpg.ssh.allowedSignersFile = "${config.home.homeDirectory}/.ssh/allowed_signers"; 498 }; 499 }; 500 programs.jujutsu = { 501 enable = true; 502 settings = { 503 user = { 504 email = "hello@seanaye.ca"; 505 name = "Sean Aye"; 506 }; 507 signing = { 508 sign-all = true; 509 behavior = "own"; 510 backend = "ssh"; 511 key = "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk"; 512 backends.ssh.allowed-signers = "${config.home.homeDirectory}/.ssh/allowed_signers"; 513 }; 514 }; 515 }; 516 517 programs.home-manager.enable = true; 518 519 programs.fish = { 520 enable = true; 521 shellAliases = { 522 agenix = "agenix -i ~/.config/agenix/yubikey-identity.txt"; 523 }; 524 interactiveShellInit = '' 525 set fish_greeting 526 # Set 1Password SSH agent socket 527 set -gx SSH_AUTH_SOCK ${config.home.homeDirectory}/.1password/agent.sock 528 # Load 1Password CLI plugins 529 if test -f ~/.config/op/plugins.sh 530 source ~/.config/op/plugins.sh 531 end 532 # Show fastfetch when inside zellij 533 if set -q ZELLIJ 534 fastfetch --logo small 535 end 536 537 function y 538 set tmp (mktemp -t "yazi-cwd.XXXXXX") 539 yazi $argv --cwd-file="$tmp" 540 if read -z cwd < "$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ] 541 builtin cd -- "$cwd" 542 end 543 rm -f -- "$tmp" 544 end 545 ''; 546 functions = { 547 s3edit = '' 548 set file (basename $argv[1]) 549 set tmpfile /tmp/$file 550 aws s3 cp $argv[1] $tmpfile 551 and $EDITOR $tmpfile 552 and aws s3 cp $tmpfile $argv[1] 553 ''; 554 }; 555 }; 556 557 programs.starship = { 558 enable = true; 559 enableFishIntegration = true; 560 }; 561 562 programs.alacritty = { 563 enable = true; 564 settings = { 565 terminal.shell = { 566 program = "zellij"; 567 args = [ 568 "options" 569 "--on-force-close" 570 "detach" 571 ]; 572 }; 573 window = { 574 decorations = "none"; 575 opacity = 0.9; 576 }; 577 font = { 578 normal = { 579 family = "BerkeleyMono Nerd Font"; 580 style = "Regular"; 581 }; 582 size = 12.0; 583 }; 584 }; 585 586 }; 587 588 programs.helix = { 589 enable = true; 590 settings = { 591 editor = { 592 bufferline = "multiple"; 593 file-picker = { 594 hidden = false; 595 git-ignore = true; 596 }; 597 cursor-shape = { 598 insert = "bar"; 599 normal = "block"; 600 select = "underline"; 601 }; 602 line-number = "relative"; 603 cursorline = true; 604 auto-format = true; 605 end-of-line-diagnostics = "hint"; 606 soft-wrap = { 607 enable = true; 608 }; 609 lsp = { 610 display-inlay-hints = true; 611 display-messages = true; 612 display-progress-messages = true; 613 }; 614 inline-diagnostics = { 615 cursor-line = "hint"; 616 }; 617 }; 618 keys = { 619 normal = { 620 esc = [ 621 "keep_primary_selection" 622 "collapse_selection" 623 ]; 624 }; 625 626 }; 627 }; 628 languages = { 629 630 language-server.rust-analyzer = { 631 config = { 632 check = { 633 command = "clippy"; 634 }; 635 checkOnSave = true; 636 cargo = { 637 allFeatures = true; 638 }; 639 }; 640 }; 641 language-server.deno-lsp = { 642 command = "deno"; 643 args = [ "lsp" ]; 644 config.deno.enable = true; 645 }; 646 647 language = [ 648 { 649 name = "html"; 650 formatter = { 651 command = "prettier"; 652 args = [ 653 "--parser" 654 "html" 655 ]; 656 }; 657 } 658 { 659 name = "nix"; 660 auto-format = true; 661 formatter = { 662 command = "${pkgs.nixfmt}/bin/nixfmt"; 663 }; 664 } 665 { 666 name = "kotlin"; 667 auto-format = true; 668 } 669 { 670 name = "rust"; 671 auto-format = true; 672 formatter = { 673 command = "rustfmt"; 674 args = [ 675 "--edition" 676 "2024" 677 ]; 678 }; 679 indent = { 680 tab-width = 4; 681 unit = "t"; 682 }; 683 } 684 { 685 name = "astro"; 686 auto-format = true; 687 formatter = { 688 command = "npx"; 689 args = [ 690 "prettier" 691 "--plugin" 692 "prettier-plugin-astro" 693 "--parser" 694 "astro" 695 ]; 696 }; 697 } 698 { 699 name = "json"; 700 auto-format = true; 701 } 702 { 703 name = "just"; 704 auto-format = true; 705 formatter = { 706 command = "just"; 707 args = [ 708 "--justfile" 709 "/dev/stdin" 710 "--dump" 711 ]; 712 }; 713 } 714 { 715 name = "toml"; 716 auto-format = true; 717 formatter = { 718 command = "taplo"; 719 args = [ 720 "format" 721 "-" 722 ]; 723 }; 724 } 725 # { 726 # name = "typescript"; 727 # roots = [ 728 # "deno.json" 729 # "deno.jsonc" 730 # ]; 731 # file-types = [ 732 # "ts" 733 # "tsx" 734 # ]; 735 # auto-format = true; 736 # language-servers = [ "deno-lsp" ]; 737 # } 738 ]; 739 }; 740 }; 741 742 dconf.settings = { 743 "org/gnome/desktop/interface" = { 744 color-scheme = "prefer-dark"; 745 enable-hot-corners = false; 746 }; 747 }; 748 749 # Font rendering configuration 750 fonts.fontconfig = { 751 enable = true; 752 defaultFonts = { 753 monospace = [ "BerkeleyMono Nerd Font" ]; 754 sansSerif = [ "Noto Sans" ]; 755 serif = [ "Noto Serif" ]; 756 }; 757 }; 758 759 # Cursor configuration 760 home.pointerCursor = { 761 name = "Adwaita"; 762 package = pkgs.adwaita-icon-theme; 763 size = 16; 764 x11.enable = true; 765 gtk.enable = true; 766 }; 767 768 # Session variables 769 home.sessionVariables = { 770 EDITOR = "hx"; 771 VISUAL = "hx"; 772 SUDO_EDITOR = "hx"; 773 SSH_AUTH_SOCK = "${config.home.homeDirectory}/.1password/agent.sock"; 774 SSH_ASKPASS = "${pkgs.openssh-askpass}/bin/gnome-ssh-askpass3"; 775 SSH_ASKPASS_REQUIRE = "prefer"; 776 }; 777 778 # SSH allowed signers for commit signature verification 779 home.file.".ssh/allowed_signers".text = '' 780 hello@seanaye.ca ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCIqgZ7kedxo+mOW7YG73Vp3zel3h180y3GKvHtRsXfGlpIIvRDy7pgCBQ4AGXYD4y78URQmFohYSAPqCPOPaWcU2un3XG9KvCzEsHmsbskPonitUmCiKvrKkb6oW4jCBtd7AEtBn+AiajAQFtPZ7NN2Df3AmTypvR6Irg7R+nxnfc9NTIHmGvxSDyWcbb4pguL20sctUSqGL6xGh8q/bqhdOThSimM+z9bEUNxK/5rPhwkNniMrp4pJcUrUiAh5/4DiRFG6KT+oeg+/myoz/Z1sPvAs7u/8JDQI4RshRD8Hu0oTkRBN6Hxj478q2SXbeBUZlD6IdjP3RhGpmSecoDdtWqKbpuV3eVRtQtba3KL86GBeV/bugaOdJ1Aud+1SOFJreAAuvxzMMKT+cdQZk6oOPP148DA/No+mDm/2S43lcdCXh79wA6YRAmKQ8jmZxTCtPutrvuZK1rguvvUlEoG/vhdNHh7eDa4Td07V6bjCRPUl8qk/e4M0E3pwsTlZc= 781 hello@seanaye.ca sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAILdilHXHdAP/V8Zq28EzHKtLAMMaFPu4+1det2N50QfhAAAABHNzaDo= sean@framework16 782 ''; 783 784 # Yubikey identity for agenix (not secret - just a reference to the hardware key) 785 home.file.".config/agenix/yubikey-identity.txt".text = '' 786 # Serial: 26930059, Slot: 1 787 # Name: agenix 788 # Recipient: age1yubikey1qw64ag5lzvn9ekrflu5ruj4a6ucycscl6ctk39fjzf76jptsay39z442pxv 789 AGE-PLUGIN-YUBIKEY-1304E5QVZZD74FKSP8FMCT 790 ''; 791 792 # Same identity for sops (expects keys at this path by default) 793 home.file.".config/sops/age/keys.txt".text = '' 794 # Serial: 26930059, Slot: 1 795 # Name: agenix 796 # Recipient: age1yubikey1qw64ag5lzvn9ekrflu5ruj4a6ucycscl6ctk39fjzf76jptsay39z442pxv 797 AGE-PLUGIN-YUBIKEY-1304E5QVZZD74FKSP8FMCT 798 ''; 799 800 home.file.".config/Yubico/u2f_keys".text = '' 801 sean:6sa1fnimjshdqKgadDlgQXqSXD6qQ7eSOZneMQZNAzO2OVCViQlxAZXHVf8kDOLKQ4uzcrHMj/t3889Sqi3Dyw==,1jm0HwRmNFFRMGu/DsVrwIBZc6HyNDSlvDhwQd73f0f3KWVxHo6PdSu4OUr+7GwOAfASKGakwyyetv73463CQw==,es256,+presence 802 ''; 803 804 # Set the state version for Home Manager 805 home.stateVersion = "25.05"; 806}