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 iotop 24 zellij # terminal multiplexer 25 alacritty 26 fuzzel # Application launcher 27 bemoji # emoji picker 28 networkmanager_dmenu # network picker for fuzzel 29 quickshell # Status bar (QML-based) 30 swww # For setting wallpapers 31 (import ../../packages/cclip.nix { inherit pkgs; }) # Clipboard history manager 32 pavucontrol # GUI for PulseAudio/PipeWire volume control 33 playerctl # MPRIS media player control 34 (element-desktop.override { 35 commandLineArgs = "--password-store=gnome-libsecret"; 36 }) 37 fd 38 ripgrep 39 yazi # tui file browser 40 gh # github cli 41 signal-desktop 42 xwayland-satellite # for running x11 apps 43 nixfmt # nix formatter 44 nil # nix language server 45 atac # postman-like TUI 46 trippy # network analyzer 47 rsync # file sync utility 48 udiskie # for mounting external drives 49 darktable # photo editing 50 zoxide 51 chromium 52 claude-code 53 nautilus # file browser 54 sqlitebrowser 55 gnome-characters # symbol picker 56 sendme # file transfer 57 desktop-file-utils # for managing .desktop files 58 flyctl # fly.io cli 59 vscode-json-languageserver 60 gnome-network-displays 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 # --- FONTS ARE IMPORTANT --- 72 # Berkeley Mono is the main system font, keeping JetBrains and Font Awesome for icons 73 font-awesome 74 noto-fonts 75 noto-fonts-cjk-sans 76 noto-fonts-color-emoji 77 nerd-fonts.jetbrains-mono 78 nerd-fonts.symbols-only 79 # --- POLKIT AGENT (for 1Password GUI, etc.) --- 80 lxqt.lxqt-policykit # Lightweight polkit agent 81 ]; 82 83 programs.niri = { 84 enable = true; 85 settings = { 86 window-rules = [ 87 { 88 geometry-corner-radius = { 89 top-left = 5.0; 90 top-right = 5.0; 91 bottom-left = 5.0; 92 bottom-right = 5.0; 93 }; 94 clip-to-geometry = true; 95 draw-border-with-background = false; 96 } 97 ]; 98 debug = { 99 honor-xdg-activation-with-invalid-serial = { }; 100 }; 101 layout = { 102 focus-ring = { 103 width = 2; 104 active.color = "#8caaee"; 105 inactive.color = "#414559"; 106 }; 107 struts = { 108 top = -6; 109 bottom = -6; 110 left = 0; 111 right = 0; 112 }; 113 gaps = 8; 114 }; 115 gestures = { 116 hot-corners = { 117 enable = false; 118 }; 119 }; 120 binds = { 121 "Mod+d".action.spawn = "fuzzel"; 122 "Mod+e".action.spawn = "bemoji"; 123 "Mod+n".action.spawn = "networkmanager_dmenu"; 124 "Mod+a".action.spawn = "alacritty"; 125 "Mod+h".action = { 126 focus-column-left = { }; 127 }; 128 "Mod+j".action = { 129 focus-workspace-down = { }; 130 }; 131 "Mod+k".action = { 132 focus-workspace-up = { }; 133 }; 134 "Mod+l".action = { 135 focus-column-right = { }; 136 }; 137 "Mod+Shift+h".action = { 138 move-column-left = { }; 139 }; 140 "Mod+Shift+j".action = { 141 move-window-down-or-to-workspace-down = { }; 142 }; 143 "Mod+Shift+k".action = { 144 move-window-up-or-to-workspace-up = { }; 145 }; 146 "Mod+Shift+l".action = { 147 move-column-right = { }; 148 }; 149 "Mod+Down".action = { 150 move-workspace-down = { }; 151 }; 152 "Mod+Up".action = { 153 move-workspace-up = { }; 154 }; 155 "Mod+p".action = { 156 show-hotkey-overlay = { }; 157 }; 158 "Mod+o".action = { 159 toggle-overview = { }; 160 }; 161 "Mod+q".action = { 162 close-window = { }; 163 }; 164 "Mod+f".action = { 165 toggle-window-floating = { }; 166 }; 167 "Mod+Shift+f".action = { 168 switch-focus-between-floating-and-tiling = { }; 169 }; 170 "Mod+m".action = { 171 fullscreen-window = { }; 172 }; 173 "Mod+s".action = { 174 screenshot = { 175 show-pointer = true; 176 }; 177 }; 178 "Mod+1".action = { 179 set-column-width = "100%"; 180 }; 181 "Mod+2".action = { 182 set-column-width = "50%"; 183 }; 184 "Mod+Minus".action = { 185 set-column-width = "-10%"; 186 }; 187 "Mod+Equal".action = { 188 set-column-width = "+10%"; 189 }; 190 "Mod+Shift+q".action = { 191 quit = { }; 192 }; 193 "Mod+Shift+r".action.spawn = [ 194 "systemctl" 195 "--user" 196 "restart" 197 "quickshell.service" 198 ]; 199 "XF86AudioPlay".action.spawn = [ 200 "playerctl" 201 "play-pause" 202 ]; 203 "XF86AudioStop".action.spawn = [ 204 "playerctl" 205 "stop" 206 ]; 207 "XF86AudioNext".action.spawn = [ 208 "playerctl" 209 "next" 210 ]; 211 "XF86AudioPrev".action.spawn = [ 212 "playerctl" 213 "previous" 214 ]; 215 "XF86MonBrightnessDown".action.spawn = [ 216 "brightnessctl" 217 "set" 218 "5%-" 219 ]; 220 "XF86MonBrightnessUp".action.spawn = [ 221 "brightnessctl" 222 "set" 223 "+5%" 224 ]; 225 }; 226 outputs = { 227 # External monitor - primary display at position (0, 0) 228 "DP-5" = { 229 scale = 2.0; 230 mode = { 231 width = 5120; 232 height = 2160; 233 refresh = 120.0; 234 }; 235 position = { 236 x = 0; 237 y = 0; 238 }; 239 }; 240 "DP-1" = { 241 scale = 2.0; 242 mode = { 243 width = 5120; 244 height = 2160; 245 refresh = 120.0; 246 }; 247 position = { 248 x = 0; 249 y = 0; 250 }; 251 }; 252 "DP-2" = { 253 scale = 1.0; 254 mode = { 255 width = 5120; 256 height = 2160; 257 refresh = 120.0; 258 }; 259 position = { 260 x = 0; 261 y = 0; 262 }; 263 }; 264 "DP-6" = { 265 scale = 2.0; 266 mode = { 267 width = 5120; 268 height = 2160; 269 refresh = 120.0; 270 }; 271 position = { 272 x = 0; 273 y = 0; 274 }; 275 }; 276 "DP-7" = { 277 scale = 2.0; 278 mode = { 279 width = 5120; 280 height = 2160; 281 refresh = 120.0; 282 }; 283 position = { 284 x = 0; 285 y = 0; 286 }; 287 }; 288 # Laptop display - secondary display positioned underneath 289 "eDP-1" = { 290 scale = 1.5; 291 mode = { 292 width = 2560; 293 height = 1600; 294 refresh = 165.0; 295 }; 296 position = { 297 x = 0; 298 y = 1080; # Position underneath the external monitor (2160 / 2 scale = 1080 logical height) 299 }; 300 }; 301 }; 302 spawn-at-startup = [ 303 { command = [ "xwayland-satellite" ]; } 304 { command = [ "swww-daemon" ]; } 305 { command = [ "cclipd" ]; } 306 ]; 307 environment = { 308 DISPLAY = ":0"; 309 }; 310 }; 311 }; 312 313 # Allow unfree packages 314 nixpkgs.config.allowUnfree = true; 315 316 nixpkgs.config.permittedInsecurePackages = [ 317 "libsoup-2.74.3" 318 ]; 319 320 # Quickshell status bar 321 xdg.configFile."quickshell/shell.qml".source = ./quickshell/shell.qml; 322 323 systemd.user.services.quickshell = { 324 Unit = { 325 Description = "QuickShell status bar"; 326 After = [ "graphical-session.target" ]; 327 PartOf = [ "graphical-session.target" ]; 328 }; 329 Service = { 330 ExecStart = "${pkgs.quickshell}/bin/quickshell"; 331 Restart = "on-failure"; 332 RestartSec = 2; 333 }; 334 Install = { 335 WantedBy = [ "graphical-session.target" ]; 336 }; 337 }; 338 339 systemd.user.services.quickshell-reload = { 340 Unit = { 341 Description = "Reload QuickShell on wake or display change"; 342 After = [ 343 "quickshell.service" 344 "graphical-session.target" 345 ]; 346 PartOf = [ "graphical-session.target" ]; 347 }; 348 Service = { 349 Type = "simple"; 350 ExecStart = "${pkgs.writeShellScript "quickshell-reload" '' 351 LOCKFILE="/tmp/quickshell-reload.lock" 352 353 do_restart() { 354 ( 355 ${pkgs.util-linux}/bin/flock -xn 200 || exit 0 356 sleep 2 357 ${pkgs.systemd}/bin/systemctl --user restart quickshell.service 358 sleep 3 359 ) 200>"$LOCKFILE" 360 } 361 362 # Sleep/wake monitor 363 ${pkgs.dbus}/bin/dbus-monitor --system \ 364 "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForSleep'" 2>/dev/null | \ 365 while IFS= read -r line; do 366 if [[ "$line" == *"boolean false"* ]]; then 367 do_restart 368 fi 369 done & 370 371 # Display hotplug monitor 372 ${pkgs.systemd}/bin/udevadm monitor --property --subsystem-match=drm 2>/dev/null | \ 373 while IFS= read -r line; do 374 if [[ "$line" == *"HOTPLUG=1"* ]]; then 375 do_restart 376 fi 377 done & 378 379 wait 380 ''}"; 381 Restart = "on-failure"; 382 RestartSec = 5; 383 }; 384 Install = { 385 WantedBy = [ "graphical-session.target" ]; 386 }; 387 }; 388 389 programs.ssh = { 390 enable = true; 391 enableDefaultConfig = false; 392 matchBlocks = { 393 "*" = { 394 identityFile = [ 395 "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk" 396 "${config.home.homeDirectory}/.ssh/id_rsa.pub" 397 ]; 398 }; 399 }; 400 }; 401 402 programs.awscli = { 403 enable = true; 404 settings = { 405 "default" = { 406 region = "us-east-1"; 407 }; 408 }; 409 }; 410 411 services.udiskie = { 412 enable = true; 413 tray = "auto"; 414 automount = true; 415 }; 416 417 services.mako = { 418 enable = true; 419 settings = { 420 border-radius = 8; 421 border-size = 2; 422 padding = "12"; 423 margin = "12"; 424 font = "BerkeleyMono Nerd Font 11"; 425 on-button-left = "invoke-default-action"; 426 on-button-right = "dismiss"; 427 }; 428 }; 429 430 catppuccin = { 431 enable = true; 432 flavor = "frappe"; 433 }; 434 435 programs.fuzzel.enable = true; 436 437 programs.direnv.enable = true; 438 439 programs.atuin = { 440 enable = true; 441 enableFishIntegration = true; 442 daemon.enable = true; 443 settings = { 444 filter_mode_shell_up_key_binding = "session"; 445 }; 446 }; 447 448 programs.zellij = { 449 enable = true; 450 settings = { 451 keybinds = { 452 unbind = [ 453 "Ctrl q" 454 "Ctrl o" 455 ]; 456 normal = { 457 "bind \"Ctrl m\"" = { 458 SwitchToMode = "Session"; 459 }; 460 }; 461 }; 462 pane_frames = false; 463 show_startup_tips = false; 464 ui = { 465 pane_frames.hide_session_name = true; 466 }; 467 }; 468 }; 469 470 programs.zen-browser.enable = true; 471 # programs.swww.enable = true; 472 programs.zoxide = { 473 enable = true; 474 enableFishIntegration = true; 475 }; 476 477 programs.obs-studio = { 478 enable = true; 479 plugins = with pkgs.obs-studio-plugins; [ 480 obs-backgroundremoval 481 ]; 482 }; 483 484 # Program configurations 485 programs.git = { 486 enable = true; 487 settings = { 488 user = { 489 name = "seanaye"; 490 email = "hello@seanaye.ca"; 491 }; 492 init.defaultBranch = "main"; 493 commit.gpgSign = true; 494 gpg.format = "ssh"; 495 user.signingKey = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIOIgEteUEW06dnBHe2z8vNLwz2iMKe8bba6JgMmOUpcBAAAABHNzaDo= sean@framework16"; 496 gpg.ssh.allowedSignersFile = "${config.home.homeDirectory}/.ssh/allowed_signers"; 497 }; 498 }; 499 programs.jujutsu = { 500 enable = true; 501 settings = { 502 user = { 503 email = "hello@seanaye.ca"; 504 name = "Sean Aye"; 505 }; 506 signing = { 507 sign-all = true; 508 behavior = "own"; 509 backend = "ssh"; 510 key = "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk"; 511 backends.ssh.allowed-signers = "${config.home.homeDirectory}/.ssh/allowed_signers"; 512 }; 513 }; 514 }; 515 516 programs.home-manager.enable = true; 517 518 programs.fish = { 519 enable = true; 520 shellAliases = { 521 agenix = "agenix -i ~/.config/agenix/yubikey-identity.txt"; 522 }; 523 interactiveShellInit = '' 524 set fish_greeting 525 # Set 1Password SSH agent socket 526 set -gx SSH_AUTH_SOCK ${config.home.homeDirectory}/.1password/agent.sock 527 # Load 1Password CLI plugins 528 if test -f ~/.config/op/plugins.sh 529 source ~/.config/op/plugins.sh 530 end 531 # Auto-launch zellij if not already inside a session 532 if not set -q ZELLIJ 533 zellij 534 else 535 fastfetch --logo small 536 end 537 538 function y 539 set tmp (mktemp -t "yazi-cwd.XXXXXX") 540 yazi $argv --cwd-file="$tmp" 541 if read -z cwd < "$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ] 542 builtin cd -- "$cwd" 543 end 544 rm -f -- "$tmp" 545 end 546 ''; 547 functions = { 548 s3edit = '' 549 set file (basename $argv[1]) 550 set tmpfile /tmp/$file 551 aws s3 cp $argv[1] $tmpfile 552 and $EDITOR $tmpfile 553 and aws s3 cp $tmpfile $argv[1] 554 ''; 555 }; 556 }; 557 558 programs.starship = { 559 enable = true; 560 enableFishIntegration = true; 561 }; 562 563 programs.alacritty = { 564 enable = true; 565 settings = { 566 terminal.shell.program = "fish"; 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}