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 8let 9 zjctl = import ../../packages/zjctl.nix { inherit pkgs; }; 10 zrpc-wasm = import ../../packages/zrpc-wasm.nix { inherit pkgs; }; 11in 12{ 13 # Import the home-manager modules you want to use 14 imports = [ 15 inputs.catppuccin.homeModules.catppuccin 16 inputs.niri.homeModules.niri 17 inputs.zen-browser.homeModules.beta 18 inputs.agenix.homeManagerModules.default 19 ]; 20 21 # All your user-specific packages 22 home.packages = with pkgs; [ 23 helix 24 git 25 jujutsu # jj-cli 26 htop 27 iotop 28 ncdu 29 youtube-tui 30 yt-dlp # youtube-tui and mpv need this to resolve YouTube URLs 31 zellij # terminal multiplexer 32 alacritty 33 inputs.fsel.packages.${pkgs.system}.default # App launcher / fuzzy finder 34 inputs.mako-tui.packages.${pkgs.system}.default # Notification TUI 35 bemoji # emoji picker 36 networkmanager_dmenu # network picker for fuzzel 37 quickshell # Status bar (QML-based) 38 inputs.kaleidux.packages.${pkgs.system}.default # Dynamic wallpaper daemon 39 (import ../../packages/cclip.nix { inherit pkgs; }) # Clipboard history manager 40 pavucontrol # GUI for PulseAudio/PipeWire volume control 41 playerctl # MPRIS media player control 42 (element-desktop.override { 43 commandLineArgs = "--password-store=gnome-libsecret"; 44 }) 45 fd 46 ripgrep 47 opencode 48 yazi # tui file browser 49 gh # github cli 50 forgejo-cli 51 gh-dash # github dashboard TUI 52 diffnav # git diff viewer 53 signal-desktop 54 xwayland-satellite # for running x11 apps 55 nixfmt # nix formatter 56 nil # nix language server 57 atac # postman-like TUI 58 trippy # network analyzer 59 rsync # file sync utility 60 udiskie # for mounting external drives 61 darktable # photo editing 62 zoxide 63 chromium 64 claude-code 65 libnotify # for notify-send (claude-notify) 66 zjctl # Programmatic Zellij control 67 (pkgs.writeShellScriptBin "claude-notify" '' 68 PANE_ID="$ZELLIJ_PANE_ID" 69 SESSION="$ZELLIJ_SESSION_NAME" 70 ID_FILE="/tmp/claude-notify-''${PANE_ID}" 71 ( 72 { 73 read -r NOTIFY_ID 74 echo "$NOTIFY_ID" > "$ID_FILE" 75 while read -r line; do 76 if [ "$line" = "default" ]; then 77 WIN_ID=$(niri msg windows | ${pkgs.gnugrep}/bin/grep -B1 "$SESSION" | ${pkgs.gnugrep}/bin/grep -oP '(?<=Window ID )\d+') 78 if [ -n "$WIN_ID" ]; then 79 niri msg action focus-window --id "$WIN_ID" 80 fi 81 zjctl pane focus --pane "id:terminal:$PANE_ID" 82 fi 83 done 84 } < <(${pkgs.libnotify}/bin/notify-send "Claude Code" "Waiting for your approval" \ 85 --app-name=claude-code \ 86 --action=default=Open \ 87 --print-id \ 88 --wait) 89 rm -f "$ID_FILE" 90 ) & 91 '') 92 (pkgs.writeShellScriptBin "claude-notify-clear" '' 93 PANE_ID="$ZELLIJ_PANE_ID" 94 ID_FILE="/tmp/claude-notify-''${PANE_ID}" 95 if [ -f "$ID_FILE" ]; then 96 NOTIFY_ID=$(cat "$ID_FILE") 97 ${pkgs.dbus}/bin/dbus-send --session \ 98 --print-reply \ 99 --dest=org.freedesktop.Notifications \ 100 --type=method_call \ 101 /org/freedesktop/Notifications \ 102 org.freedesktop.Notifications.CloseNotification \ 103 "uint32:$NOTIFY_ID" >/dev/null 2>&1 104 rm -f "$ID_FILE" 105 fi 106 '') 107 nautilus # file browser 108 sqlitebrowser 109 gnome-characters # symbol picker 110 sendme # file transfer 111 desktop-file-utils # for managing .desktop files 112 flyctl # fly.io cli 113 vscode-json-languageserver 114 gnome-network-displays 115 rainfrog # db tui 116 loupe # image viewer 117 glycin-loaders # various format loaders for loupe 118 docker-compose 119 discord 120 mangohud 121 prismlauncher # minecraft launcher 122 fastfetch 123 inputs.agenix.packages.${pkgs.system}.default # agenix CLI 124 age-plugin-yubikey # Yubikey support for agenix 125 # --- FONTS ARE IMPORTANT --- 126 # Berkeley Mono is the main system font, keeping JetBrains and Font Awesome for icons 127 font-awesome 128 noto-fonts 129 noto-fonts-cjk-sans 130 noto-fonts-color-emoji 131 nerd-fonts.jetbrains-mono 132 nerd-fonts.symbols-only 133 # --- POLKIT AGENT (for 1Password GUI, etc.) --- 134 lxqt.lxqt-policykit # Lightweight polkit agent 135 ]; 136 137 programs.niri = { 138 enable = true; 139 settings = { 140 window-rules = [ 141 { 142 geometry-corner-radius = { 143 top-left = 5.0; 144 top-right = 5.0; 145 bottom-left = 5.0; 146 bottom-right = 5.0; 147 }; 148 clip-to-geometry = true; 149 draw-border-with-background = false; 150 } 151 { 152 matches = [ { app-id = "^fsel$"; } ]; 153 open-floating = true; 154 default-column-width.fixed = 800; 155 default-window-height.fixed = 500; 156 } 157 { 158 matches = [ { app-id = "^mako-tui$"; } ]; 159 open-floating = true; 160 default-column-width.fixed = 800; 161 default-window-height.fixed = 500; 162 } 163 ]; 164 debug = { 165 honor-xdg-activation-with-invalid-serial = { }; 166 }; 167 layout = { 168 focus-ring = { 169 width = 2; 170 active.color = "#8caaee"; 171 inactive.color = "#414559"; 172 }; 173 struts = { 174 top = -6; 175 bottom = -6; 176 left = 0; 177 right = 0; 178 }; 179 gaps = 8; 180 }; 181 gestures = { 182 hot-corners = { 183 enable = false; 184 }; 185 }; 186 binds = { 187 "Mod+d".action.spawn = [ 188 "alacritty" 189 "--class" 190 "fsel" 191 "-e" 192 "fsel" 193 "--detach" 194 ]; 195 "Mod+c".action.spawn = [ 196 "alacritty" 197 "--class" 198 "fsel" 199 "-e" 200 "fsel" 201 "--cclip" 202 ]; 203 "Mod+e".action.spawn = "bemoji"; 204 "Mod+n".action.spawn = [ 205 "alacritty" 206 "--class" 207 "mako-tui" 208 "-e" 209 "mako-tui" 210 ]; 211 "Mod+a".action.spawn = "alacritty"; 212 "Mod+h".action = { 213 focus-column-left = { }; 214 }; 215 "Mod+j".action = { 216 focus-workspace-down = { }; 217 }; 218 "Mod+k".action = { 219 focus-workspace-up = { }; 220 }; 221 "Mod+l".action = { 222 focus-column-right = { }; 223 }; 224 "Mod+Shift+h".action = { 225 move-column-left = { }; 226 }; 227 "Mod+Shift+j".action = { 228 move-window-down-or-to-workspace-down = { }; 229 }; 230 "Mod+Shift+k".action = { 231 move-window-up-or-to-workspace-up = { }; 232 }; 233 "Mod+Shift+l".action = { 234 move-column-right = { }; 235 }; 236 "Mod+Down".action = { 237 move-workspace-down = { }; 238 }; 239 "Mod+Up".action = { 240 move-workspace-up = { }; 241 }; 242 "Mod+p".action = { 243 show-hotkey-overlay = { }; 244 }; 245 "Mod+o".action = { 246 toggle-overview = { }; 247 }; 248 "Mod+q".action = { 249 close-window = { }; 250 }; 251 "Mod+f".action = { 252 toggle-window-floating = { }; 253 }; 254 "Mod+Shift+f".action = { 255 switch-focus-between-floating-and-tiling = { }; 256 }; 257 "Mod+m".action = { 258 fullscreen-window = { }; 259 }; 260 "Mod+s".action = { 261 screenshot = { 262 show-pointer = true; 263 }; 264 }; 265 "Mod+1".action = { 266 set-column-width = "100%"; 267 }; 268 "Mod+2".action = { 269 set-column-width = "50%"; 270 }; 271 "Mod+Minus".action = { 272 set-column-width = "-10%"; 273 }; 274 "Mod+Equal".action = { 275 set-column-width = "+10%"; 276 }; 277 "Mod+Shift+q".action = { 278 quit = { }; 279 }; 280 "Mod+Shift+r".action.spawn = [ 281 "systemctl" 282 "--user" 283 "restart" 284 "quickshell.service" 285 ]; 286 "XF86AudioPlay".action.spawn = [ 287 "playerctl" 288 "play-pause" 289 ]; 290 "XF86AudioStop".action.spawn = [ 291 "playerctl" 292 "stop" 293 ]; 294 "XF86AudioNext".action.spawn = [ 295 "playerctl" 296 "next" 297 ]; 298 "XF86AudioPrev".action.spawn = [ 299 "playerctl" 300 "previous" 301 ]; 302 "XF86MonBrightnessDown".action.spawn = [ 303 "brightnessctl" 304 "set" 305 "5%-" 306 ]; 307 "XF86MonBrightnessUp".action.spawn = [ 308 "brightnessctl" 309 "set" 310 "+5%" 311 ]; 312 }; 313 outputs = { 314 # External monitor - primary display at position (0, 0) 315 "DP-5" = { 316 scale = 2.0; 317 mode = { 318 width = 5120; 319 height = 2160; 320 refresh = 120.0; 321 }; 322 position = { 323 x = 0; 324 y = 0; 325 }; 326 }; 327 "DP-1" = { 328 scale = 2.0; 329 mode = { 330 width = 5120; 331 height = 2160; 332 refresh = 120.0; 333 }; 334 position = { 335 x = 0; 336 y = 0; 337 }; 338 }; 339 "DP-2" = { 340 scale = 1.0; 341 mode = { 342 width = 5120; 343 height = 2160; 344 refresh = 120.0; 345 }; 346 position = { 347 x = 0; 348 y = 0; 349 }; 350 }; 351 "DP-6" = { 352 scale = 2.0; 353 mode = { 354 width = 5120; 355 height = 2160; 356 refresh = 120.0; 357 }; 358 position = { 359 x = 0; 360 y = 0; 361 }; 362 }; 363 "DP-7" = { 364 scale = 2.0; 365 mode = { 366 width = 5120; 367 height = 2160; 368 refresh = 120.0; 369 }; 370 position = { 371 x = 0; 372 y = 0; 373 }; 374 }; 375 # Laptop display - secondary display positioned underneath 376 "eDP-1" = { 377 scale = 1.5; 378 mode = { 379 width = 2560; 380 height = 1600; 381 refresh = 165.0; 382 }; 383 position = { 384 x = 0; 385 y = 1080; # Position underneath the external monitor (2160 / 2 scale = 1080 logical height) 386 }; 387 }; 388 }; 389 spawn-at-startup = [ 390 { command = [ "xwayland-satellite" ]; } 391 { command = [ "cclipd" ]; } 392 ]; 393 environment = { 394 DISPLAY = ":0"; 395 }; 396 }; 397 }; 398 399 # Allow unfree packages 400 nixpkgs.config.allowUnfree = true; 401 402 nixpkgs.config.permittedInsecurePackages = [ 403 "libsoup-2.74.3" 404 ]; 405 406 # Download wallpapers at activation time (skips dead URLs gracefully) 407 home.activation.downloadWallpapers = 408 let 409 wallpapers = import ./wallpapers.nix; 410 downloads = builtins.concatStringsSep "\n" ( 411 map (wp: '' 412 if [ ! -f "$DIR/${wp.filename}" ]; then 413 echo "Downloading ${wp.filename}..." 414 ${pkgs.curl}/bin/curl -fsSL -o "$DIR/${wp.filename}" ${ 415 builtins.replaceStrings [ "\"" ] [ "\\\"" ] wp.url 416 } || echo "WARNING: Failed to download ${wp.filename}, skipping" 417 fi 418 '') wallpapers 419 ); 420 in 421 config.lib.dag.entryAfter [ "writeBoundary" ] '' 422 DIR="${config.home.homeDirectory}/Pictures/Wallpapers" 423 mkdir -p "$DIR" 424 ${downloads} 425 ''; 426 427 # Kaleidux wallpaper daemon config 428 xdg.configFile."kaleidux/config.toml".text = '' 429 [global] 430 monitor-behavior = "independent" 431 video-ratio = 50 432 sorting = "loveit" 433 transition-time = 1000 434 435 [any] 436 path = "${config.home.homeDirectory}/Pictures/Wallpapers" 437 duration = "15m" 438 transition = { type = "fade" } 439 ''; 440 441 # Quickshell status bar 442 xdg.configFile."quickshell" = { 443 source = ./quickshell; 444 recursive = true; 445 }; 446 447 systemd.user.services.kaleidux = { 448 Unit = { 449 Description = "Kaleidux dynamic wallpaper daemon"; 450 After = [ "graphical-session.target" ]; 451 PartOf = [ "graphical-session.target" ]; 452 }; 453 Service = { 454 ExecStart = "${inputs.kaleidux.packages.${pkgs.system}.default}/bin/kaleidux-daemon"; 455 Restart = "on-failure"; 456 RestartSec = 2; 457 }; 458 Install = { 459 WantedBy = [ "graphical-session.target" ]; 460 }; 461 }; 462 463 systemd.user.services.quickshell = { 464 Unit = { 465 Description = "QuickShell status bar"; 466 After = [ "graphical-session.target" ]; 467 PartOf = [ "graphical-session.target" ]; 468 }; 469 Service = { 470 ExecStart = "${pkgs.quickshell}/bin/quickshell"; 471 Restart = "on-failure"; 472 RestartSec = 2; 473 }; 474 Install = { 475 WantedBy = [ "graphical-session.target" ]; 476 }; 477 }; 478 479 systemd.user.services.quickshell-reload = { 480 Unit = { 481 Description = "Reload QuickShell on wake or display change"; 482 After = [ 483 "quickshell.service" 484 "graphical-session.target" 485 ]; 486 PartOf = [ "graphical-session.target" ]; 487 }; 488 Service = { 489 Type = "simple"; 490 ExecStart = "${pkgs.writeShellScript "quickshell-reload" '' 491 LOCKFILE="/tmp/quickshell-reload.lock" 492 493 do_restart() { 494 ( 495 ${pkgs.util-linux}/bin/flock -xn 200 || exit 0 496 sleep 2 497 ${pkgs.systemd}/bin/systemctl --user restart quickshell.service 498 sleep 3 499 ) 200>"$LOCKFILE" 500 } 501 502 # Sleep/wake monitor 503 ${pkgs.dbus}/bin/dbus-monitor --system \ 504 "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForSleep'" 2>/dev/null | \ 505 while IFS= read -r line; do 506 if [[ "$line" == *"boolean false"* ]]; then 507 do_restart 508 fi 509 done & 510 511 # Display hotplug monitor 512 ${pkgs.systemd}/bin/udevadm monitor --property --subsystem-match=drm 2>/dev/null | \ 513 while IFS= read -r line; do 514 if [[ "$line" == *"HOTPLUG=1"* ]]; then 515 do_restart 516 fi 517 done & 518 519 wait 520 ''}"; 521 Restart = "on-failure"; 522 RestartSec = 5; 523 }; 524 Install = { 525 WantedBy = [ "graphical-session.target" ]; 526 }; 527 }; 528 529 programs.ssh = { 530 enable = true; 531 enableDefaultConfig = false; 532 matchBlocks = { 533 "*" = { 534 identityFile = [ 535 "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk" 536 "${config.home.homeDirectory}/.ssh/id_rsa.pub" 537 ]; 538 }; 539 }; 540 }; 541 542 programs.awscli = { 543 enable = true; 544 settings = { 545 "default" = { 546 region = "us-east-1"; 547 }; 548 }; 549 }; 550 551 services.udiskie = { 552 enable = true; 553 tray = "never"; 554 automount = true; 555 }; 556 557 services.mako = { 558 enable = true; 559 settings = { 560 border-radius = 8; 561 border-size = 2; 562 padding = "12"; 563 margin = "12"; 564 font = "BerkeleyMono Nerd Font 11"; 565 on-button-left = "invoke-default-action"; 566 on-button-right = "dismiss"; 567 }; 568 }; 569 570 catppuccin = { 571 enable = true; 572 flavor = "frappe"; 573 }; 574 575 programs.direnv.enable = true; 576 577 programs.atuin = { 578 enable = true; 579 enableFishIntegration = true; 580 daemon.enable = true; 581 settings = { 582 filter_mode_shell_up_key_binding = "session"; 583 }; 584 }; 585 586 programs.zellij = { 587 enable = true; 588 settings = { 589 keybinds = { 590 unbind = [ 591 "Ctrl q" 592 "Ctrl o" 593 ]; 594 normal = { 595 "bind \"Ctrl m\"" = { 596 SwitchToMode = "Session"; 597 }; 598 }; 599 }; 600 load_plugins = { 601 "\"file:~/.config/zellij/plugins/zrpc.wasm\"" = { }; 602 }; 603 pane_frames = false; 604 show_startup_tips = false; 605 ui = { 606 pane_frames.hide_session_name = true; 607 }; 608 }; 609 }; 610 611 xdg.configFile."zellij/plugins/zrpc.wasm".source = "${zrpc-wasm}/zrpc.wasm"; 612 613 home.file.".claude/settings.json".text = builtins.toJSON { 614 enabledPlugins = { 615 "rust-analyzer-lsp@claude-plugins-official" = true; 616 "typescript-lsp@claude-plugins-official" = true; 617 }; 618 hooks = { 619 Notification = [ 620 { 621 matcher = "permission_prompt"; 622 hooks = [ 623 { 624 type = "command"; 625 command = "claude-notify"; 626 } 627 ]; 628 } 629 ]; 630 Stop = [ 631 { 632 hooks = [ 633 { 634 type = "command"; 635 command = "claude-notify-clear"; 636 } 637 ]; 638 } 639 ]; 640 }; 641 }; 642 643 xdg.configFile."zellij/layouts/split.kdl".text = '' 644 layout { 645 tab { 646 pane size="50%" 647 pane split_direction="vertical" size="50%" { 648 pane 649 pane 650 } 651 } 652 } 653 ''; 654 655 xdg.configFile."gh-dash/config.yml".text = '' 656 prSections: 657 - title: My Pull Requests 658 filters: is:open author:@me 659 - title: Review Requested 660 filters: is:open review-requested:@me 661 issuesSections: 662 - title: My Issues 663 filters: is:open author:@me 664 pager: 665 diff: diffnav 666 keybindings: 667 prs: 668 - key: T 669 name: enhance 670 command: >- 671 zellij run -- gh enhance -R {{.RepoName}} {{.PrNumber}} 672 ''; 673 674 programs.zen-browser.enable = true; 675 # programs.swww.enable = true; 676 programs.zoxide = { 677 enable = true; 678 enableFishIntegration = true; 679 }; 680 681 programs.obs-studio = { 682 enable = true; 683 plugins = with pkgs.obs-studio-plugins; [ 684 obs-backgroundremoval 685 ]; 686 }; 687 688 # Program configurations 689 programs.mpv = { 690 enable = true; 691 scripts = [ pkgs.mpvScripts.mpris ]; 692 config.af = "loudnorm=I=-16:TP=-1.5:LRA=11"; 693 }; 694 xdg.configFile."youtube-tui/commands.yml".source = ./youtube-tui/commands.yml; 695 programs.git = { 696 enable = true; 697 settings = { 698 user = { 699 name = "seanaye"; 700 email = "hello@seanaye.ca"; 701 }; 702 init.defaultBranch = "main"; 703 commit.gpgSign = true; 704 gpg.format = "ssh"; 705 user.signingKey = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIOIgEteUEW06dnBHe2z8vNLwz2iMKe8bba6JgMmOUpcBAAAABHNzaDo= sean@framework16"; 706 gpg.ssh.allowedSignersFile = "${config.home.homeDirectory}/.ssh/allowed_signers"; 707 diff.tool = "diffnav"; 708 difftool.prompt = false; 709 "difftool \"diffnav\"".cmd = "diffnav \"$LOCAL\" \"$REMOTE\""; 710 }; 711 }; 712 programs.jujutsu = { 713 enable = true; 714 settings = { 715 user = { 716 email = "hello@seanaye.ca"; 717 name = "Sean Aye"; 718 }; 719 ui."diff-formatter" = ":git"; 720 signing = { 721 sign-all = true; 722 behavior = "own"; 723 backend = "ssh"; 724 key = "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk"; 725 backends.ssh.allowed-signers = "${config.home.homeDirectory}/.ssh/allowed_signers"; 726 }; 727 }; 728 }; 729 xdg.configFile."jj/conf.d/diffnav.toml".text = '' 730 [[--scope]] 731 --when.commands = ["diff", "show"] 732 [--scope.ui] 733 pager = "diffnav" 734 ''; 735 736 programs.home-manager.enable = true; 737 738 programs.fish = { 739 enable = true; 740 shellAliases = { 741 agenix = "agenix -i ~/.config/agenix/yubikey-identity.txt"; 742 }; 743 interactiveShellInit = '' 744 set fish_greeting 745 # Set 1Password SSH agent socket 746 set -gx SSH_AUTH_SOCK ${config.home.homeDirectory}/.1password/agent.sock 747 # Load 1Password CLI plugins 748 if test -f ~/.config/op/plugins.sh 749 source ~/.config/op/plugins.sh 750 end 751 # Auto-launch zellij if not already inside a session 752 if not set -q ZELLIJ 753 zellij 754 else 755 fastfetch --logo small 756 end 757 758 function y 759 set tmp (mktemp -t "yazi-cwd.XXXXXX") 760 yazi $argv --cwd-file="$tmp" 761 if read -z cwd < "$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ] 762 builtin cd -- "$cwd" 763 end 764 rm -f -- "$tmp" 765 end 766 ''; 767 functions = { 768 s3edit = '' 769 set file (basename $argv[1]) 770 set tmpfile /tmp/$file 771 aws s3 cp $argv[1] $tmpfile 772 and $EDITOR $tmpfile 773 and aws s3 cp $tmpfile $argv[1] 774 ''; 775 }; 776 }; 777 778 programs.starship = { 779 enable = true; 780 enableFishIntegration = true; 781 }; 782 783 programs.alacritty = { 784 enable = true; 785 settings = { 786 terminal.shell.program = "fish"; 787 window = { 788 decorations = "none"; 789 opacity = 0.9; 790 }; 791 font = { 792 normal = { 793 family = "BerkeleyMono Nerd Font"; 794 style = "Regular"; 795 }; 796 size = 12.0; 797 }; 798 }; 799 800 }; 801 802 programs.helix = { 803 enable = true; 804 settings = { 805 editor = { 806 bufferline = "multiple"; 807 file-picker = { 808 hidden = false; 809 git-ignore = true; 810 }; 811 cursor-shape = { 812 insert = "bar"; 813 normal = "block"; 814 select = "underline"; 815 }; 816 line-number = "relative"; 817 cursorline = true; 818 auto-format = true; 819 end-of-line-diagnostics = "hint"; 820 soft-wrap = { 821 enable = true; 822 }; 823 lsp = { 824 display-inlay-hints = true; 825 display-messages = true; 826 display-progress-messages = true; 827 }; 828 inline-diagnostics = { 829 cursor-line = "hint"; 830 }; 831 }; 832 keys = { 833 normal = { 834 esc = [ 835 "keep_primary_selection" 836 "collapse_selection" 837 ]; 838 }; 839 840 }; 841 }; 842 languages = { 843 844 language-server.rust-analyzer = { 845 config = { 846 check = { 847 command = "clippy"; 848 }; 849 checkOnSave = true; 850 cargo = { 851 allFeatures = true; 852 }; 853 }; 854 }; 855 language-server.deno-lsp = { 856 command = "deno"; 857 args = [ "lsp" ]; 858 config.deno.enable = true; 859 }; 860 861 language = [ 862 { 863 name = "html"; 864 formatter = { 865 command = "prettier"; 866 args = [ 867 "--parser" 868 "html" 869 ]; 870 }; 871 } 872 { 873 name = "nix"; 874 auto-format = true; 875 formatter = { 876 command = "${pkgs.nixfmt}/bin/nixfmt"; 877 }; 878 } 879 { 880 name = "kotlin"; 881 auto-format = true; 882 } 883 { 884 name = "rust"; 885 auto-format = true; 886 formatter = { 887 command = "rustfmt"; 888 args = [ 889 "--edition" 890 "2024" 891 ]; 892 }; 893 indent = { 894 tab-width = 4; 895 unit = "t"; 896 }; 897 } 898 { 899 name = "astro"; 900 auto-format = true; 901 formatter = { 902 command = "npx"; 903 args = [ 904 "prettier" 905 "--plugin" 906 "prettier-plugin-astro" 907 "--parser" 908 "astro" 909 ]; 910 }; 911 } 912 { 913 name = "json"; 914 auto-format = true; 915 } 916 { 917 name = "just"; 918 auto-format = true; 919 formatter = { 920 command = "just"; 921 args = [ 922 "--justfile" 923 "/dev/stdin" 924 "--dump" 925 ]; 926 }; 927 } 928 { 929 name = "toml"; 930 auto-format = true; 931 formatter = { 932 command = "taplo"; 933 args = [ 934 "format" 935 "-" 936 ]; 937 }; 938 } 939 # { 940 # name = "typescript"; 941 # roots = [ 942 # "deno.json" 943 # "deno.jsonc" 944 # ]; 945 # file-types = [ 946 # "ts" 947 # "tsx" 948 # ]; 949 # auto-format = true; 950 # language-servers = [ "deno-lsp" ]; 951 # } 952 ]; 953 }; 954 }; 955 956 dconf.settings = { 957 "org/gnome/desktop/interface" = { 958 color-scheme = "prefer-dark"; 959 enable-hot-corners = false; 960 }; 961 }; 962 963 # Font rendering configuration 964 fonts.fontconfig = { 965 enable = true; 966 defaultFonts = { 967 monospace = [ "BerkeleyMono Nerd Font" ]; 968 sansSerif = [ "Noto Sans" ]; 969 serif = [ "Noto Serif" ]; 970 }; 971 }; 972 973 # Cursor configuration 974 home.pointerCursor = { 975 name = "Adwaita"; 976 package = pkgs.adwaita-icon-theme; 977 size = 16; 978 x11.enable = true; 979 gtk.enable = true; 980 }; 981 982 # Session variables 983 home.sessionVariables = { 984 EDITOR = "hx"; 985 VISUAL = "hx"; 986 SUDO_EDITOR = "hx"; 987 SSH_AUTH_SOCK = "${config.home.homeDirectory}/.1password/agent.sock"; 988 SSH_ASKPASS = "${pkgs.openssh-askpass}/bin/gnome-ssh-askpass3"; 989 SSH_ASKPASS_REQUIRE = "prefer"; 990 }; 991 992 # SSH allowed signers for commit signature verification 993 home.file.".ssh/allowed_signers".text = '' 994 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= 995 hello@seanaye.ca sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAILdilHXHdAP/V8Zq28EzHKtLAMMaFPu4+1det2N50QfhAAAABHNzaDo= sean@framework16 996 ''; 997 998 # Yubikey identity for agenix (not secret - just a reference to the hardware key) 999 home.file.".config/agenix/yubikey-identity.txt".text = '' 1000 # Serial: 26930059, Slot: 1 1001 # Name: agenix 1002 # Recipient: age1yubikey1qw64ag5lzvn9ekrflu5ruj4a6ucycscl6ctk39fjzf76jptsay39z442pxv 1003 AGE-PLUGIN-YUBIKEY-1304E5QVZZD74FKSP8FMCT 1004 ''; 1005 1006 # Same identity for sops (expects keys at this path by default) 1007 home.file.".config/sops/age/keys.txt".text = '' 1008 # Serial: 26930059, Slot: 1 1009 # Name: agenix 1010 # Recipient: age1yubikey1qw64ag5lzvn9ekrflu5ruj4a6ucycscl6ctk39fjzf76jptsay39z442pxv 1011 AGE-PLUGIN-YUBIKEY-1304E5QVZZD74FKSP8FMCT 1012 ''; 1013 1014 # yubikey sudo access 1015 home.file.".config/Yubico/u2f_keys".text = '' 1016 sean:2HY//CedY0ZSrKf57lT7abxG8+8bkPyxCfp/0HMlk/il/5W8pn4R5xLiZDcJtvL85U24h9IEIxa4CS22mpaDSA==,gcD/dpLdwvUFcGGPHS4qNsarH4lOEy1AJAT7zoC6BPlFRUYEa8DpVVKFTcvT6PotjnSHSrWWGb/f3U2k2jIOIw==,es256,+presence 1017 ''; 1018 1019 # Set the state version for Home Manager 1020 home.stateVersion = "25.05"; 1021}