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 debug = {
32 honor-xdg-activation-with-invalid-serial = { };
33 };
34 layout = {
35 focus-ring = {
36 width = 2;
37 active.color = "#8caaee";
38 inactive.color = "#414559";
39 };
40 struts = {
41 top = -6;
42 bottom = -6;
43 left = 0;
44 right = 0;
45 };
46 gaps = 8;
47 };
48 gestures = {
49 hot-corners = {
50 enable = false;
51 };
52 };
53 binds = {
54 "Mod+d".action.spawn = "fuzzel";
55 "Mod+e".action.spawn = "bemoji";
56 "Mod+n".action.spawn = "networkmanager_dmenu";
57 "Mod+a".action.spawn = "alacritty";
58 "Mod+h".action = {
59 focus-column-left = { };
60 };
61 "Mod+j".action = {
62 focus-workspace-down = { };
63 };
64 "Mod+k".action = {
65 focus-workspace-up = { };
66 };
67 "Mod+l".action = {
68 focus-column-right = { };
69 };
70 "Mod+Shift+h".action = {
71 move-column-left = { };
72 };
73 "Mod+Shift+j".action = {
74 move-window-down-or-to-workspace-down = { };
75 };
76 "Mod+Shift+k".action = {
77 move-window-up-or-to-workspace-up = { };
78 };
79 "Mod+Shift+l".action = {
80 move-column-right = { };
81 };
82 "Mod+Down".action = {
83 move-workspace-down = { };
84 };
85 "Mod+Up".action = {
86 move-workspace-up = { };
87 };
88 "Mod+p".action = {
89 show-hotkey-overlay = { };
90 };
91 "Mod+o".action = {
92 toggle-overview = { };
93 };
94 "Mod+q".action = {
95 close-window = { };
96 };
97 "Mod+f".action = {
98 toggle-window-floating = { };
99 };
100 "Mod+Shift+f".action = {
101 switch-focus-between-floating-and-tiling = { };
102 };
103 "Mod+s".action = {
104 screenshot = {
105 show-pointer = true;
106 };
107 };
108 "Mod+1".action = {
109 set-column-width = "100%";
110 };
111 "Mod+2".action = {
112 set-column-width = "50%";
113 };
114 "Mod+Minus".action = {
115 set-column-width = "-10%";
116 };
117 "Mod+Equal".action = {
118 set-column-width = "+10%";
119 };
120 "Mod+Shift+r".action.spawn = [
121 "sh"
122 "-c"
123 "pkill quickshell; quickshell &"
124 ];
125 "XF86MonBrightnessDown".action.spawn = [
126 "brightnessctl"
127 "set"
128 "5%-"
129 ];
130 "XF86MonBrightnessUp".action.spawn = [
131 "brightnessctl"
132 "set"
133 "+5%"
134 ];
135 };
136 outputs = {
137 # External monitor - primary display at position (0, 0)
138 "DP-5" = {
139 scale = 2.0;
140 mode = {
141 width = 5120;
142 height = 2160;
143 refresh = 120.0;
144 };
145 position = {
146 x = 0;
147 y = 0;
148 };
149 };
150 "DP-1" = {
151 scale = 2.0;
152 mode = {
153 width = 5120;
154 height = 2160;
155 refresh = 120.0;
156 };
157 position = {
158 x = 0;
159 y = 0;
160 };
161 };
162 "DP-2" = {
163 scale = 2.0;
164 mode = {
165 width = 5120;
166 height = 2160;
167 refresh = 120.0;
168 };
169 position = {
170 x = 0;
171 y = 0;
172 };
173 };
174 "DP-7" = {
175 scale = 2.0;
176 mode = {
177 width = 5120;
178 height = 2160;
179 refresh = 120.0;
180 };
181 position = {
182 x = 0;
183 y = 0;
184 };
185 };
186 # Laptop display - secondary display positioned underneath
187 "eDP-1" = {
188 scale = 1.5;
189 mode = {
190 width = 2560;
191 height = 1600;
192 refresh = 165.0;
193 };
194 position = {
195 x = 0;
196 y = 1080; # Position underneath the external monitor (2160 / 2 scale = 1080 logical height)
197 };
198 };
199 };
200 spawn-at-startup = [
201 { command = [ "xwayland-satellite" ]; }
202 { command = [ "swww-daemon" ]; }
203 { command = [ "quickshell" ]; }
204 { command = [ "wl-paste --watch cliphist store" ]; }
205 ];
206 environment = {
207 DISPLAY = ":0";
208 };
209 };
210 };
211
212 # Allow unfree packages
213 nixpkgs.config.allowUnfree = true;
214
215 nixpkgs.config.permittedInsecurePackages = [
216 "libsoup-2.74.3"
217 ];
218
219 # Quickshell status bar
220 xdg.configFile."quickshell/shell.qml".source = ./quickshell/shell.qml;
221
222 programs.ssh = {
223 enable = true;
224 enableDefaultConfig = false;
225 matchBlocks = {
226 "*" = {
227 extraOptions = {
228 IdentityAgent = "${config.home.homeDirectory}/.1password/agent.sock";
229 };
230 };
231 };
232 };
233
234 programs.awscli = {
235 enable = true;
236 settings = {
237 "default" = {
238 region = "us-east-1";
239 };
240 };
241 };
242
243 # All your user-specific packages
244 home.packages = with pkgs; [
245 helix
246 git
247 jujutsu # jj-cli
248 htop
249 zellij # terminal multiplexer
250 alacritty
251 fuzzel # Application launcher
252 bemoji # emoji picker
253 networkmanager_dmenu # network picker for fuzzel
254 quickshell # Status bar (QML-based)
255 swww # For setting wallpapers
256 cliphist # Clipboard history manager
257 pavucontrol # GUI for PulseAudio/PipeWire volume control
258 fd
259 ripgrep
260 yazi # tui file browser
261 gh # github cli
262 signal-desktop
263 xwayland-satellite # for running x11 apps
264 nixfmt # nix formatter
265 nil # nix language server
266 atac # postman-like TUI
267 trippy # network analyzer
268 rsync # file sync utility
269 udiskie # for mounting external drives
270 darktable # photo editing
271 zoxide
272 chromium
273 claude-code
274 nautilus # file browser
275 sqlitebrowser
276 gnome-characters # symbol picker
277 sendme # file transfer
278 desktop-file-utils # for managing .desktop files
279 flyctl # fly.io cli
280 vscode-json-languageserver
281 gnome-network-displays
282 doppler # secret management
283 rainfrog # db tui
284 loupe # image viewer
285 glycin-loaders # various format loaders for loupe
286 docker-compose
287 discord
288 prismlauncher # minecraft launcher
289 fastfetch
290
291 # --- FONTS ARE IMPORTANT ---
292 # Berkeley Mono is the main system font, keeping JetBrains and Font Awesome for icons
293 font-awesome
294 noto-fonts
295 noto-fonts-cjk-sans
296 noto-fonts-color-emoji
297 nerd-fonts.jetbrains-mono
298 nerd-fonts.symbols-only
299 # --- POLKIT AGENT (for 1Password GUI, etc.) ---
300 lxqt.lxqt-policykit # Lightweight polkit agent
301 ];
302
303 services.udiskie = {
304 enable = true;
305 tray = "auto";
306 automount = true;
307 };
308
309 services.mako = {
310 enable = true;
311 settings = {
312 border-radius = 8;
313 border-size = 2;
314 padding = "12";
315 margin = "12";
316 font = "BerkeleyMono Nerd Font 11";
317 on-button-left = "invoke-default-action";
318 on-button-right = "dismiss";
319 };
320 };
321
322 catppuccin = {
323 enable = true;
324 flavor = "frappe";
325 };
326
327 programs.fuzzel.enable = true;
328
329 programs.direnv.enable = true;
330
331 programs.atuin = {
332 enable = true;
333 enableFishIntegration = true;
334 settings = {
335 filter_mode_shell_up_key_binding = "session";
336 };
337 };
338
339 programs.zellij = {
340 enable = true;
341 settings = {
342 keybinds = {
343 unbind = [
344 "Ctrl q"
345 "Ctrl o"
346 ];
347 normal = {
348 "bind \"Ctrl m\"" = {
349 SwitchToMode = "Session";
350 };
351 };
352 };
353 pane_frames = false;
354 show_startup_tips = false;
355 ui = {
356 pane_frames.hide_session_name = true;
357 };
358 };
359 };
360
361 programs.zen-browser.enable = true;
362 # programs.swww.enable = true;
363 programs.zoxide = {
364 enable = true;
365 enableFishIntegration = true;
366 };
367
368 programs.obs-studio = {
369 enable = true;
370 plugins = with pkgs.obs-studio-plugins; [
371 obs-backgroundremoval
372 ];
373 };
374
375 # Program configurations
376 programs.git = {
377 enable = true;
378 settings = {
379 user = {
380 name = "seanaye";
381 email = "hello@seanaye.ca";
382 };
383 init.defaultBranch = "main";
384 };
385 };
386 programs.jujutsu = {
387 enable = true;
388 settings = {
389 user = {
390 email = "hello@seanaye.ca";
391 name = "Sean Aye";
392 };
393 signing = {
394 sign-all = true;
395 behavior = "own";
396 backend = "ssh";
397 key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCIqgZ7kedxo+mOW7YG73Vp3zel3h180y3GKvHtRsXfGlpIIvRDy7pgCBQ4AGXYD4y78URQmFohYSAPqCPOPaWcU2un3XG9KvCzEsHmsbskPonitUmCiKvrKkb6oW4jCBtd7AEtBn+AiajAQFtPZ7NN2Df3AmTypvR6Irg7R+nxnfc9NTIHmGvxSDyWcbb4pguL20sctUSqGL6xGh8q/bqhdOThSimM+z9bEUNxK/5rPhwkNniMrp4pJcUrUiAh5/4DiRFG6KT+oeg+/myoz/Z1sPvAs7u/8JDQI4RshRD8Hu0oTkRBN6Hxj478q2SXbeBUZlD6IdjP3RhGpmSecoDdtWqKbpuV3eVRtQtba3KL86GBeV/bugaOdJ1Aud+1SOFJreAAuvxzMMKT+cdQZk6oOPP148DA/No+mDm/2S43lcdCXh79wA6YRAmKQ8jmZxTCtPutrvuZK1rguvvUlEoG/vhdNHh7eDa4Td07V6bjCRPUl8qk/e4M0E3pwsTlZc=";
398 };
399 };
400 };
401
402 programs.home-manager.enable = true;
403
404 programs.fish = {
405 enable = true;
406 interactiveShellInit = ''
407 set fish_greeting
408 # Set 1Password SSH agent socket
409 set -gx SSH_AUTH_SOCK ${config.home.homeDirectory}/.1password/agent.sock
410 # Load 1Password CLI plugins
411 if test -f ~/.config/op/plugins.sh
412 source ~/.config/op/plugins.sh
413 end
414 # Show fastfetch when inside zellij
415 if set -q ZELLIJ
416 fastfetch --logo small
417 end
418
419 function y
420 set tmp (mktemp -t "yazi-cwd.XXXXXX")
421 yazi $argv --cwd-file="$tmp"
422 if read -z cwd < "$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
423 builtin cd -- "$cwd"
424 end
425 rm -f -- "$tmp"
426 end
427 '';
428 functions = {
429 s3edit = ''
430 set file (basename $argv[1])
431 set tmpfile /tmp/$file
432 aws s3 cp $argv[1] $tmpfile
433 and $EDITOR $tmpfile
434 and aws s3 cp $tmpfile $argv[1]
435 '';
436 };
437 };
438
439 programs.starship = {
440 enable = true;
441 enableFishIntegration = true;
442 };
443
444 programs.alacritty = {
445 enable = true;
446 settings = {
447 terminal.shell = {
448 program = "zellij";
449 args = [ "options" "--on-force-close" "detach" ];
450 };
451 window = {
452 decorations = "none";
453 opacity = 0.9;
454 };
455 font = {
456 normal = {
457 family = "BerkeleyMono Nerd Font";
458 style = "Regular";
459 };
460 size = 12.0;
461 };
462 };
463
464 };
465
466 programs.helix = {
467 enable = true;
468 settings = {
469 editor = {
470 bufferline = "multiple";
471 file-picker = {
472 hidden = false;
473 git-ignore = true;
474 };
475 cursor-shape = {
476 insert = "bar";
477 normal = "block";
478 select = "underline";
479 };
480 line-number = "relative";
481 cursorline = true;
482 auto-format = true;
483 end-of-line-diagnostics = "hint";
484 soft-wrap = {
485 enable = true;
486 };
487 lsp = {
488 display-inlay-hints = true;
489 display-messages = true;
490 display-progress-messages = true;
491 };
492 inline-diagnostics = {
493 cursor-line = "hint";
494 };
495 };
496 keys = {
497 normal = {
498 esc = [
499 "keep_primary_selection"
500 "collapse_selection"
501 ];
502 };
503
504 };
505 };
506 languages = {
507
508 language-server.rust-analyzer = {
509 config = {
510 check = {
511 command = "clippy";
512 };
513 checkOnSave = true;
514 cargo = {
515 allFeatures = true;
516 };
517 };
518 };
519 language-server.deno-lsp = {
520 command = "deno";
521 args = [ "lsp" ];
522 config.deno.enable = true;
523 };
524
525 language = [
526 {
527 name = "html";
528 formatter = {
529 command = "prettier";
530 args = [
531 "--parser"
532 "html"
533 ];
534 };
535 }
536 {
537 name = "nix";
538 auto-format = true;
539 formatter = {
540 command = "${pkgs.nixfmt}/bin/nixfmt";
541 };
542 }
543 {
544 name = "kotlin";
545 auto-format = true;
546 }
547 {
548 name = "rust";
549 auto-format = true;
550 formatter = {
551 command = "rustfmt";
552 args = [
553 "--edition"
554 "2024"
555 ];
556 };
557 indent = {
558 tab-width = 4;
559 unit = "t";
560 };
561 }
562 {
563 name = "astro";
564 auto-format = true;
565 formatter = {
566 command = "npx";
567 args = [
568 "prettier"
569 "--plugin"
570 "prettier-plugin-astro"
571 "--parser"
572 "astro"
573 ];
574 };
575 }
576 {
577 name = "json";
578 auto-format = true;
579 }
580 {
581 name = "just";
582 auto-format = true;
583 formatter = {
584 command = "just";
585 args = [
586 "--justfile"
587 "/dev/stdin"
588 "--dump"
589 ];
590 };
591 }
592 {
593 name = "toml";
594 auto-format = true;
595 formatter = {
596 command = "taplo";
597 args = [
598 "format"
599 "-"
600 ];
601 };
602 }
603 # {
604 # name = "typescript";
605 # roots = [
606 # "deno.json"
607 # "deno.jsonc"
608 # ];
609 # file-types = [
610 # "ts"
611 # "tsx"
612 # ];
613 # auto-format = true;
614 # language-servers = [ "deno-lsp" ];
615 # }
616 ];
617 };
618 };
619
620 dconf.settings = {
621 "org/gnome/desktop/interface" = {
622 color-scheme = "prefer-dark";
623 enable-hot-corners = false;
624 };
625 };
626
627 # Font rendering configuration
628 fonts.fontconfig = {
629 enable = true;
630 defaultFonts = {
631 monospace = [ "BerkeleyMono Nerd Font" ];
632 sansSerif = [ "Noto Sans" ];
633 serif = [ "Noto Serif" ];
634 };
635 };
636
637 # Cursor configuration
638 home.pointerCursor = {
639 name = "Adwaita";
640 package = pkgs.adwaita-icon-theme;
641 size = 16;
642 x11.enable = true;
643 gtk.enable = true;
644 };
645
646 # Session variables
647 home.sessionVariables = {
648 EDITOR = "hx";
649 VISUAL = "hx";
650 SUDO_EDITOR = "hx";
651 SSH_AUTH_SOCK = "${config.home.homeDirectory}/.1password/agent.sock";
652 };
653
654 # Set the state version for Home Manager
655 home.stateVersion = "25.05";
656}