me like nix
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 ];
15
16 programs.niri = {
17 enable = true;
18 settings = {
19 window-rules = [
20 {
21 geometry-corner-radius = {
22 top-left = 5.0;
23 top-right = 5.0;
24 bottom-left = 5.0;
25 bottom-right = 5.0;
26 };
27 clip-to-geometry = true;
28 draw-border-with-background = false;
29 }
30 ];
31 layout = {
32 struts = {
33 top = 0;
34 bottom = 0;
35 left = 8;
36 right = 8;
37 };
38 gaps = 8;
39 };
40 gestures = {
41 hot-corners = {
42 enable = false;
43 };
44 };
45 binds = {
46 "Mod+d".action.spawn = "fuzzel";
47 "Mod+e".action.spawn = "bemoji";
48 "Mod+n".action.spawn = "networkmanager_dmenu";
49 "Mod+a".action.spawn = "alacritty";
50 "Mod+h".action = {
51 focus-column-left = { };
52 };
53 "Mod+j".action = {
54 focus-workspace-down = { };
55 };
56 "Mod+k".action = {
57 focus-workspace-up = { };
58 };
59 "Mod+l".action = {
60 focus-column-right = { };
61 };
62 "Mod+Shift+h".action = {
63 move-column-left = { };
64 };
65 "Mod+Shift+j".action = {
66 move-window-down-or-to-workspace-down = { };
67 };
68 "Mod+Shift+k".action = {
69 move-window-up-or-to-workspace-up = { };
70 };
71 "Mod+Shift+l".action = {
72 move-column-right = { };
73 };
74 "Mod+Down".action = {
75 move-workspace-down = { };
76 };
77 "Mod+Up".action = {
78 move-workspace-up = { };
79 };
80 "Mod+p".action = {
81 show-hotkey-overlay = { };
82 };
83 "Mod+o".action = {
84 toggle-overview = { };
85 };
86 "Mod+q".action = {
87 close-window = { };
88 };
89 "Mod+s".action = {
90 screenshot = {
91 show-pointer = true;
92 };
93 };
94 "Mod+1".action = {
95 set-column-width = "100%";
96 };
97 "Mod+2".action = {
98 set-column-width = "50%";
99 };
100 "XF86MonBrightnessDown".action.spawn = [
101 "brightnessctl"
102 "set"
103 "5%-"
104 ];
105 "XF86MonBrightnessUp".action.spawn = [
106 "brightnessctl"
107 "set"
108 "+5%"
109 ];
110 };
111 outputs = {
112 # External monitor - primary display at position (0, 0)
113 "DP-5" = {
114 scale = 2.0;
115 mode = {
116 width = 5120;
117 height = 2160;
118 refresh = 120.0;
119 };
120 position = {
121 x = 0;
122 y = 0;
123 };
124 };
125 "DP-1" = {
126 scale = 2.0;
127 mode = {
128 width = 5120;
129 height = 2160;
130 refresh = 120.0;
131 };
132 position = {
133 x = 0;
134 y = 0;
135 };
136 };
137 "DP-2" = {
138 scale = 2.0;
139 mode = {
140 width = 5120;
141 height = 2160;
142 refresh = 120.0;
143 };
144 position = {
145 x = 0;
146 y = 0;
147 };
148 };
149 "DP-7" = {
150 scale = 2.0;
151 mode = {
152 width = 5120;
153 height = 2160;
154 refresh = 120.0;
155 };
156 position = {
157 x = 0;
158 y = 0;
159 };
160 };
161 # Laptop display - secondary display positioned underneath
162 "eDP-1" = {
163 scale = 1.5;
164 mode = {
165 width = 2560;
166 height = 1600;
167 refresh = 165.0;
168 };
169 position = {
170 x = 0;
171 y = 1080; # Position underneath the external monitor (2160 / 2 scale = 1080 logical height)
172 };
173 };
174 };
175 spawn-at-startup = [
176 { command = [ "xwayland-satellite" ]; }
177 { command = [ "swww-daemon" ]; }
178 { command = [ "mako" ]; }
179 { command = [ "waybar" ]; }
180 { command = [ "wl-paste --watch cliphist store" ]; }
181 ];
182 environment = {
183 DISPLAY = ":0";
184 };
185 };
186 };
187
188 # Allow unfree packages
189 nixpkgs.config.allowUnfree = true;
190
191 nixpkgs.config.permittedInsecurePackages = [
192 "libsoup-2.74.3"
193 ];
194
195 programs.waybar = {
196 enable = true;
197 settings = {
198 mainBar = {
199 height = 8;
200 spacing = 0;
201
202 modules-left = [
203 "custom/media"
204 ];
205
206 modules-center = [
207 "clock"
208 ];
209
210 modules-right = [
211 "mpd"
212 "pulseaudio"
213 "network"
214 "power-profiles-daemon"
215 "cpu"
216 "memory"
217 "temperature"
218 "backlight"
219 "sway/language"
220 "battery"
221 "battery#bat2"
222 "custom/power"
223 ];
224
225 "keyboard-state" = {
226 numlock = true;
227 capslock = true;
228 format = "{name} {icon}";
229 format-icons = {
230 locked = " ";
231 unlocked = " ";
232 };
233 };
234
235 mpd = {
236 format = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ";
237 format-disconnected = "Disconnected ";
238 format-stopped = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ";
239 unknown-tag = "N/A";
240 interval = 5;
241 consume-icons = {
242 on = " ";
243 };
244 random-icons = {
245 off = "<span color=\"#f53c3c\"></span> ";
246 on = " ";
247 };
248 repeat-icons = {
249 on = " ";
250 };
251 single-icons = {
252 on = "1 ";
253 };
254 state-icons = {
255 paused = "";
256 playing = "";
257 };
258 tooltip-format = "MPD (connected)";
259 tooltip-format-disconnected = "MPD (disconnected)";
260 };
261
262 idle_inhibitor = {
263 format = "{icon}";
264 format-icons = {
265 activated = " ";
266 deactivated = " ";
267 };
268 };
269
270 tray = {
271 spacing = 10;
272 };
273
274 clock = {
275 format = "{:%d-%m-%Y %H:%M}";
276 tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
277 format-alt = "{:%Y-%m-%d %H:%M:%S}";
278 };
279
280 cpu = {
281 format = "{usage}% ";
282 tooltip = false;
283 };
284
285 memory = {
286 format = "{}% ";
287 };
288
289 temperature = {
290 critical-threshold = 80;
291 format = "{temperatureC}°C {icon}";
292 format-icons = [
293 ""
294 ""
295 ""
296 ];
297 };
298
299 backlight = {
300 format = "{percent}% {icon}";
301 format-icons = [
302 ""
303 ""
304 ""
305 ""
306 ""
307 ""
308 ""
309 ""
310 ""
311 ];
312 };
313
314 battery = {
315 states = {
316 warning = 30;
317 critical = 15;
318 };
319 format = "{capacity}% {icon}";
320 format-full = "{capacity}% {icon}";
321 format-charging = "{capacity}% ";
322 format-plugged = "{capacity}% ";
323 format-alt = "{time} {icon}";
324 format-icons = [
325 ""
326 ""
327 ""
328 ""
329 ""
330 ];
331 };
332
333 "battery#bat2" = {
334 bat = "BAT2";
335 };
336
337 "power-profiles-daemon" = {
338 format = "{icon}";
339 tooltip-format = "Power profile: {profile}\nDriver: {driver}";
340 tooltip = true;
341 format-icons = {
342 default = "";
343 performance = "";
344 balanced = " ";
345 power-saver = " ";
346 };
347 };
348
349 network = {
350 format-wifi = "{essid} ({signalStrength}%) ";
351 format-ethernet = "{ipaddr}/{cidr} ";
352 tooltip-format = "{ifname} via {gwaddr} ";
353 format-linked = "{ifname} (No IP) ";
354 format-disconnected = "Disconnected ⚠";
355 format-alt = "{ifname}: {ipaddr}/{cidr}";
356 };
357
358 pulseaudio = {
359 format = "{volume}% {icon} {format_source}";
360 format-bluetooth = "{volume}% {icon} {format_source}";
361 format-bluetooth-muted = " {icon} {format_source}";
362 format-muted = " {format_source}";
363 format-source = "{volume}% ";
364 format-source-muted = " ";
365 format-icons = {
366 headphone = "";
367 hands-free = "";
368 headset = "";
369 phone = "";
370 portable = "";
371 car = "";
372 default = [
373 ""
374 " "
375 " "
376 ];
377 };
378 on-click = "pavucontrol";
379 };
380
381 "custom/media" = {
382 format = "{icon} {text}";
383 return-type = "json";
384 max-length = 40;
385 format-icons = {
386 spotify = " ";
387 default = "🎜 ";
388 };
389 escape = true;
390 exec = "$HOME/.config/waybar/mediaplayer.py 2> /dev/null";
391 };
392
393 "custom/power" = {
394 format = "⏻ ";
395 tooltip = false;
396 menu = "on-click";
397 menu-file = "${./waybar/power_menu.xml}";
398 menu-actions = {
399 shutdown = "shutdown";
400 reboot = "reboot";
401 suspend = "systemctl suspend";
402 hibernate = "systemctl hibernate";
403 };
404 };
405 };
406 };
407 style = builtins.readFile ./waybar/style.css;
408 };
409
410 programs.ssh = {
411 enable = true;
412 extraConfig = ''
413 Host *
414 IdentityAgent ${config.home.homeDirectory}/.1password/agent.sock
415 '';
416 };
417
418 programs.awscli = {
419 enable = true;
420 settings = {
421 "default" = {
422 region = "us-east-1";
423 };
424 };
425 };
426
427 # All your user-specific packages
428 home.packages = with pkgs; [
429 helix
430 git
431 jujutsu # jj-cli
432 htop
433 zellij # terminal multiplexer
434 alacritty
435 fuzzel # Application launcher
436 bemoji # emoji picker
437 networkmanager_dmenu # network picker for fuzzel
438 waybar # Status bar (highly recommended)
439 mako # Notification daemon
440 swww # For setting wallpapers
441 cliphist # Clipboard history manager
442 pavucontrol # GUI for PulseAudio/PipeWire volume control
443 fd
444 ripgrep
445 yazi # tui file browser
446 gh # github cli
447 signal-desktop
448 xwayland-satellite # for running x11 apps
449 nixfmt-rfc-style # nix formatter
450 nil # nix language server
451 atac # postman-like TUI
452 trippy # network analyzer
453 rsync # file sync utility
454 udiskie # for mounting external drives
455 darktable # photo editing
456 zoxide
457 chromium
458 claude-code
459 nautilus # file browser
460 sqlitebrowser
461 gnome-characters # symbol picker
462 sendme # file transfer
463 desktop-file-utils # for managing .desktop files
464 flyctl # fly.io cli
465 vscode-json-languageserver
466 gnome-network-displays
467 doppler # secret management
468 rainfrog # db tui
469 loupe # image viewer
470 glycin-loaders # various format loaders for loupe
471 docker-compose
472 discord
473 prismlauncher # minecraft launcher
474 atuin
475
476 # --- FONTS ARE IMPORTANT ---
477 # Berkeley Mono is the main system font, keeping JetBrains and Font Awesome for waybar
478 font-awesome # For icons in waybar
479 noto-fonts
480 noto-fonts-cjk-sans
481 noto-fonts-color-emoji
482 nerd-fonts.jetbrains-mono
483 nerd-fonts.symbols-only # Additional Nerd Font symbols for waybar
484 # --- POLKIT AGENT (for 1Password GUI, etc.) ---
485 lxqt.lxqt-policykit # Lightweight polkit agent
486 ];
487
488 services.udiskie = {
489 enable = true;
490 tray = "auto";
491 automount = true;
492 };
493
494 catppuccin = {
495 enable = true;
496 flavor = "frappe";
497 };
498
499 programs.fuzzel.enable = true;
500
501 programs.direnv.enable = true;
502
503 programs.zellij = {
504 enable = true;
505 settings = {
506 keybinds = {
507 unbind = [
508 "Ctrl q"
509 "Ctrl o"
510 ];
511 normal = {
512 "bind \"Ctrl m\"" = {
513 SwitchToMode = "Session";
514 };
515 };
516 };
517 pane_frames = false;
518 ui = {
519 pane_frames.hide_session_name = true;
520 };
521 };
522 };
523
524 programs.zen-browser.enable = true;
525 # programs.swww.enable = true;
526 programs.zoxide = {
527 enable = true;
528 enableFishIntegration = true;
529 };
530
531 programs.obs-studio = {
532 enable = true;
533 plugins = with pkgs.obs-studio-plugins; [
534 obs-backgroundremoval
535 ];
536 };
537
538 # Program configurations
539 programs.git = {
540 enable = true;
541 userName = "seanaye";
542 userEmail = "hello@seanaye.ca";
543 extraConfig = {
544 init.defaultBranch = "main";
545 };
546 };
547 programs.jujutsu = {
548 enable = true;
549 settings = {
550 user = {
551 email = "hello@seanaye.ca";
552 name = "Sean Aye";
553 };
554 signing = {
555 sign-all = true;
556 behavior = "own";
557 backend = "ssh";
558 key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCIqgZ7kedxo+mOW7YG73Vp3zel3h180y3GKvHtRsXfGlpIIvRDy7pgCBQ4AGXYD4y78URQmFohYSAPqCPOPaWcU2un3XG9KvCzEsHmsbskPonitUmCiKvrKkb6oW4jCBtd7AEtBn+AiajAQFtPZ7NN2Df3AmTypvR6Irg7R+nxnfc9NTIHmGvxSDyWcbb4pguL20sctUSqGL6xGh8q/bqhdOThSimM+z9bEUNxK/5rPhwkNniMrp4pJcUrUiAh5/4DiRFG6KT+oeg+/myoz/Z1sPvAs7u/8JDQI4RshRD8Hu0oTkRBN6Hxj478q2SXbeBUZlD6IdjP3RhGpmSecoDdtWqKbpuV3eVRtQtba3KL86GBeV/bugaOdJ1Aud+1SOFJreAAuvxzMMKT+cdQZk6oOPP148DA/No+mDm/2S43lcdCXh79wA6YRAmKQ8jmZxTCtPutrvuZK1rguvvUlEoG/vhdNHh7eDa4Td07V6bjCRPUl8qk/e4M0E3pwsTlZc=";
559 };
560 };
561 };
562
563 programs.home-manager.enable = true;
564
565 programs.fish = {
566 enable = true;
567 interactiveShellInit = ''
568 set fish_greeting
569 # Set 1Password SSH agent socket
570 set -gx SSH_AUTH_SOCK ${config.home.homeDirectory}/.1password/agent.sock
571 # Load 1Password CLI plugins
572 if test -f ~/.config/op/plugins.sh
573 source ~/.config/op/plugins.sh
574 end
575 # Initialize atuin shell history
576 atuin init fish | source
577
578 function y
579 set tmp (mktemp -t "yazi-cwd.XXXXXX")
580 yazi $argv --cwd-file="$tmp"
581 if read -z cwd < "$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
582 builtin cd -- "$cwd"
583 end
584 rm -f -- "$tmp"
585 end
586 '';
587 functions = {
588 s3edit = ''
589 set file (basename $argv[1])
590 set tmpfile /tmp/$file
591 aws s3 cp $argv[1] $tmpfile
592 and $EDITOR $tmpfile
593 and aws s3 cp $tmpfile $argv[1]
594 '';
595 };
596 };
597
598 programs.starship = {
599 enable = true;
600 enableFishIntegration = true;
601 };
602
603 programs.alacritty = {
604 enable = true;
605 settings = {
606 window = {
607 decorations = "none";
608 opacity = 0.9;
609 };
610 font = {
611 normal = {
612 family = "BerkeleyMono Nerd Font";
613 style = "Regular";
614 };
615 size = 12.0;
616 };
617 };
618
619 };
620
621 programs.helix = {
622 enable = true;
623 settings = {
624 editor = {
625 bufferline = "multiple";
626 file-picker = {
627 hidden = false;
628 git-ignore = true;
629 };
630 cursor-shape = {
631 insert = "bar";
632 normal = "block";
633 select = "underline";
634 };
635 line-number = "relative";
636 cursorline = true;
637 auto-format = true;
638 end-of-line-diagnostics = "hint";
639 soft-wrap = {
640 enable = true;
641 };
642 lsp = {
643 display-inlay-hints = true;
644 display-messages = true;
645 display-progress-messages = true;
646 };
647 inline-diagnostics = {
648 cursor-line = "hint";
649 };
650 };
651 keys = {
652 normal = {
653 esc = [
654 "keep_primary_selection"
655 "collapse_selection"
656 ];
657 };
658
659 };
660 };
661 languages = {
662
663 language-server.rust-analyzer = {
664 config = {
665 check = {
666 command = "clippy";
667 };
668 checkOnSave = true;
669 cargo = {
670 allFeatures = true;
671 };
672 };
673 };
674 language-server.deno-lsp = {
675 command = "deno";
676 args = [ "lsp" ];
677 config.deno.enable = true;
678 };
679
680 language = [
681 {
682 name = "html";
683 formatter = {
684 command = "prettier";
685 args = [
686 "--parser"
687 "html"
688 ];
689 };
690 }
691 {
692 name = "nix";
693 auto-format = true;
694 formatter = {
695 command = "${pkgs.nixfmt-rfc-style}/bin/nixfmt";
696 };
697 }
698 {
699 name = "kotlin";
700 auto-format = true;
701 }
702 {
703 name = "rust";
704 auto-format = true;
705 formatter = {
706 command = "rustfmt";
707 args = [
708 "--edition"
709 "2024"
710 ];
711 };
712 indent = {
713 tab-width = 4;
714 unit = "t";
715 };
716 }
717 {
718 name = "astro";
719 auto-format = true;
720 formatter = {
721 command = "npx";
722 args = [
723 "prettier"
724 "--plugin"
725 "prettier-plugin-astro"
726 "--parser"
727 "astro"
728 ];
729 };
730 }
731 {
732 name = "json";
733 auto-format = true;
734 }
735 {
736 name = "just";
737 auto-format = true;
738 formatter = {
739 command = "just";
740 args = [
741 "--justfile"
742 "/dev/stdin"
743 "--dump"
744 ];
745 };
746 }
747 {
748 name = "toml";
749 auto-format = true;
750 formatter = {
751 command = "taplo";
752 args = [
753 "format"
754 "-"
755 ];
756 };
757 }
758 # {
759 # name = "typescript";
760 # roots = [
761 # "deno.json"
762 # "deno.jsonc"
763 # ];
764 # file-types = [
765 # "ts"
766 # "tsx"
767 # ];
768 # auto-format = true;
769 # language-servers = [ "deno-lsp" ];
770 # }
771 ];
772 };
773 };
774
775 dconf.settings = {
776 "org/gnome/desktop/interface" = {
777 color-scheme = "prefer-dark";
778 enable-hot-corners = false;
779 };
780 };
781
782 # Font rendering configuration
783 fonts.fontconfig = {
784 enable = true;
785 defaultFonts = {
786 monospace = [ "BerkeleyMono Nerd Font" ];
787 sansSerif = [ "Noto Sans" ];
788 serif = [ "Noto Serif" ];
789 };
790 };
791
792 # Cursor configuration
793 home.pointerCursor = {
794 name = "Adwaita";
795 package = pkgs.adwaita-icon-theme;
796 size = 16;
797 x11.enable = true;
798 gtk.enable = true;
799 };
800
801 # Session variables
802 home.sessionVariables = {
803 EDITOR = "hx";
804 VISUAL = "hx";
805 SUDO_EDITOR = "hx";
806 SSH_AUTH_SOCK = "${config.home.homeDirectory}/.1password/agent.sock";
807 };
808
809 # Set the state version for Home Manager
810 home.stateVersion = "25.05";
811}