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