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