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