]> gitweb.ps.run Git - flake_thinkpad/blob - home-ps.nix
changes
[flake_thinkpad] / home-ps.nix
1 { config, pkgs, lib, wallpaper, ... }:
2
3 let
4   theme = pkgs.qogir-theme.override { tweaks = [ "square" ]; };
5   markdownStyleHeader = pkgs.writeText "style.html" ''
6     <style type="text/css">
7     html{
8       margin:40px auto;
9       max-width:650px;
10       line-height:1.6;
11       font-size:18px;
12       color:#444;
13       background-color:#EEE;
14       padding:0 10px
15     }
16     @media (prefers-color-scheme: dark) {
17     html{
18       color:#CCC;
19       background-color:#333;
20     }
21     }
22     h1,h2,h3{line-height:1.2}
23     </style>
24   '';
25   markdownCaddyfile = pkgs.writeText "Caddyfile" ''
26     :8123
27
28     encode zstd gzip
29     templates
30     file_server browse {
31             root "/"
32             hide ".*"
33     }
34
35     @md <<CEL
36       {file}.endsWith(".md")
37       || {file}.endsWith(".MD")
38       CEL
39
40     header @md Content-Type "text/html; charset=UTF-8"
41     respond @md <<HTML
42             <!DOCTYPE html>
43             <html>
44                     <head>
45                             <title>{{ "{file.base}" }}</title>
46                             <link rel="stylesheet" href="https://sindresorhus.com/github-markdown-css/github-markdown.css">
47                             <style>
48                             .markdown-body {
49                                         box-sizing: border-box;
50                                         min-width: 200px;
51                                         max-width: 980px;
52                                         margin: 0 auto;
53                                         padding: 45px;
54                                 }
55                             </style>
56                     </head>
57                     <body class="markdown-body">
58                     {{
59                     markdown (include "{path}")
60                     }}
61                     </body>
62             </html>
63             HTML 200
64   '';
65 in
66 {
67   # Home Manager needs a bit of information about you and the paths it should
68   # manage.
69   home.username = "ps";
70   home.homeDirectory = "/home/ps";
71
72   services.xcape = {
73     enable = true;
74     mapExpression = {
75       Caps_Lock = "Escape";
76     };
77   };
78
79   xfconf.settings = {
80     xfce4-desktop = {
81       "backdrop/screen0/monitor0/image-path" = "${wallpaper}";
82       "backdrop/screen0/monitor0/image-show" = true;
83       "backdrop/screen0/monitor0/image-style" = 5;
84     };
85   };
86
87   systemd.user.services.markdownCaddy = {
88     Unit = {
89       Description = "Run a web server serving Markdown files.";
90       Wants = [ "network-online.target" ];
91       After = [ "network-online.target" ];
92     };
93     Install = {
94       WantedBy = [ "default.target" ];
95     };
96     Service = {
97       WorkingDirectory = "/";
98       ExecStart = "${pkgs.writeShellScript "markdown-caddy" ''
99         ${pkgs.caddy}/bin/caddy run --config ${markdownCaddyfile} --adapter caddyfile
100       ''}";
101     };
102   };
103   
104   xsession.windowManager.i3 = {
105     enable = true;
106     config = {
107       bars = [];
108       modifier = "Mod4";
109       terminal = "${pkgs.kitty}/bin/kitty";
110       gaps = { inner = 0; outer = 0; };
111       keybindings =
112         let
113           mod = config.xsession.windowManager.i3.config.modifier;
114           i3-next = pkgs.writers.writePython3 "i3-next" {} ''
115             import json
116             from subprocess import check_output
117
118             workspaces = json.loads(check_output(
119               ["${pkgs.i3}/bin/i3-msg",
120                "-t", "get_workspaces"]))
121
122             outputs = {}
123             activeOutput = ""
124             activeWorkspace = -1
125
126             for w in workspaces:
127                 output = w["output"]
128                 workspace = int(w["num"])
129                 if output not in outputs:
130                     outputs[output] = set()
131                 outputs[output].add(workspace)
132                 if w["focused"]:
133                     activeOutput = output
134                     activeWorkspace = workspace
135
136             workspacesSorted = sorted(outputs[activeOutput])
137             activeWorkspaceIndex = workspacesSorted.index(activeWorkspace)
138
139             if activeWorkspaceIndex < len(workspacesSorted) - 1:
140                 print(workspacesSorted[activeWorkspaceIndex + 1])
141             else:
142                 allWorkspaces = set()
143                 for o in outputs.values():
144                     allWorkspaces = allWorkspaces.union(o)
145                 allWorkspacesSorted = sorted(allWorkspaces)
146                 print(allWorkspacesSorted[-1]+1)
147           '';
148   
149           i3-empty = pkgs.writers.writePython3 "i3-empty" {} ''
150             import json
151             from subprocess import check_output
152
153             workspaces = json.loads(check_output(
154               ["${pkgs.i3}/bin/i3-msg",
155                "-t", "get_workspaces"]))
156
157             nextWorkspace = 1
158       
159             for w in workspaces:
160                 wNum = int(w["num"])
161                 if wNum >= nextWorkspace:
162                     nextWorkspace = wNum + 1
163
164             print(nextWorkspace)
165           '';
166           
167           i3-max = pkgs.writers.writePython3 "i3-max" {} ''
168             import json
169             from subprocess import check_output
170
171             workspaces = json.loads(check_output(
172               ["${pkgs.i3}/bin/i3-msg",
173                "-t", "get_workspaces"]))
174
175             result = "MAX"
176       
177             for w in workspaces:
178                 wName = w["name"]
179                 wFocused = w["focused"]
180                 if wName == "MAX" and wFocused:
181                     result = "back_and_forth"
182                     break
183
184             print(f"move window to workspace {result}; workspace {result}")
185           '';
186           i3-move-max = pkgs.writers.writePython3 "i3-move-max" {} ''
187             import json
188             from subprocess import check_output
189
190             workspaces = json.loads(check_output(
191               ["${pkgs.i3}/bin/i3-msg",
192                "-t", "get_workspaces"]))
193
194             result = "MAX"
195       
196             for w in workspaces:
197                 wName = w["name"]
198                 wFocused = w["focused"]
199                 if wName == "MAX" and wFocused:
200                     result = "back_and_forth"
201                     break
202
203             print(f"workspace {result}")
204           '';
205         in lib.mkOptionDefault
206           {
207             # "${mod}+d" = "exec --no-startup-id krunner";
208             # "${mod}+Shift+p" = "exec --no-startup-id set-wallpaper";
209             "${mod}+Shift+Return" = "exec --no-startup-id ${pkgs.kitty}/bin/kitty -d $(${pkgs.xcwd}/bin/xcwd)";
210             "${mod}+BackSpace" = "kill";
211             "${mod}+Prior" = "workspace prev_on_output";
212             "${mod}+Next" = "exec --no-startup-id i3-msg workspace number $(${i3-next})";
213             "${mod}+End" = "exec --no-startup-id i3-msg workspace $(${i3-empty})";
214             "${mod}+Shift+Prior" = "move container to workspace prev_on_output";
215             "${mod}+Shift+Next" = "exec --no-startup-id i3-msg move container to workspace number $(${i3-next})";
216             "${mod}+Shift+End" = "exec --no-startup-id i3-msg move container to workspace $(${i3-empty})";
217             "${mod}+Ctrl+Left" = "move workspace to output left";
218             "${mod}+Ctrl+Right" = "move workspace to output right";
219             "${mod}+y" = "exec --no-startup-id mirror-phone";
220             "${mod}+n" = "exec ${pkgs.kitty}/bin/kitty -d ~/sync/txt nvim -c 'autocmd VimEnter * ++once Telescope find_files'";
221             "${mod}+m" = "exec --no-startup-id i3-msg $(${i3-max})";
222             "${mod}+b" = "split toggle; layout tabbed";
223             "${mod}+Shift+m" = "exec --no-startup-id i3-msg $(${i3-move-max})";
224             "${mod}+Shift+p" = "exec --no-startup-id ${pkgs.autorandr}/bin/autorandr --match-edid -c -f";
225           };
226     };
227     extraConfig = ''
228       exec ${pkgs.xfce.xfce4-panel}/bin/xfce4-panel
229       for_window [window_role="pop-up"] floating enable
230       for_window [window_role="task_dialog"] floating enable
231       for_window [workspace="9"] floating enable
232
233       for_window [class="kitty-popup"] floating enable
234       for_window [class="Xfce4-appfinder"] floating enable
235       for_window [class="yakuake"] floating enable
236       for_window [class="systemsettings"] floating enable
237       for_window [title="win7"] floating enable; border none
238       for_window [title="Arbeitsfläche.*"] kill, floating enable, border none
239
240       # class                 border  backgr. text    indicator child_border
241       client.focused          #000000bf #000000bf #e6ebef #000000bf   #000000bf
242       client.focused_inactive #00000080 #00000080 #e6ebef #00000080   #00000080
243       client.unfocused        #00000040 #00000040 #e6ebef #00000040   #00000040
244       client.urgent           #2f343a #900000 #e6ebef #900000   #2f343a
245       client.placeholder      #000000 #0c0c0c #e6ebef #000000   #0c0c0c
246
247       focus_follows_mouse no
248       mouse_warping none
249       popup_during_fullscreen all
250     '';
251   };
252
253   services.picom = {
254     enable = true;
255     vSync = true;
256     opacityRules = [
257       "0:_NET_WM_STATE@[*]:a = '_NET_WM_STATE_HIDDEN'"
258     ];
259   };
260
261   programs.git = {
262     userName = "patrick-scho";
263     userEmail = "patrick.schoenberger@posteo.de";
264     includes = [{ contents = {
265         user = {
266           email = "patrick.schoenberger@posteo.de";
267           name = "psch";
268         };
269     };}];
270   };
271
272   programs.bash = {
273     enable = true;
274     historySize = -1;
275     historyFileSize = -1;
276     shellAliases = {  
277       snrs = "sudo nixos-rebuild switch --flake /etc/nixos#default";
278       snrt = "sudo nixos-rebuild test --flake /etc/nixos#default";
279       snrb = "sudo nixos-rebuild boot --flake /etc/nixos#default";
280       senc = "sudo $EDITOR /etc/nixos/configuration.nix";
281       senh = "sudo $EDITOR /etc/nixos/home-ps.nix";
282       senhc = "sudo $EDITOR /etc/nixos/home-common.nix";
283       senf = "sudo $EDITOR /etc/nixos/flake.nix";
284       flakerun = "nix run --override-input nixpkgs nixpkgs";
285       n = "nvim";
286     };
287   };
288
289   programs.fzf = {
290     enable = true;
291     enableBashIntegration = true;
292   };
293
294   programs.readline = {
295     enable = true;
296     bindings = {
297       "\\e[A" = "history-search-backward";
298       "\\e[B" = "history-search-forward";
299     };
300   };
301
302   programs.kitty = {
303     enable = true;
304     themeFile = "Adapta_Nokto_Maia";
305     settings = {
306       # hide_window_decorations = "yes";
307       background_opacity = "0.98";
308       background_blur = "1";
309       confirm_os_window_close = "0";
310       enable_audio_bell = "no";
311       scrollback_pager_history_size = "1024";
312     };
313   };
314
315   programs.helix = {
316     enable = true;
317     settings = {
318       theme = "base16_terminal";
319       editor.cursor-shape = {
320         insert = "bar";
321         normal = "block";
322         select = "underline";
323       };
324       editor.soft-wrap = {
325         enable = true;
326       };
327       editor.file-picker = {
328         hidden = false;
329       };
330       keys.normal."space" = {
331         "space" = "goto_word";
332       };
333     };
334     languages = {
335       language = [{
336         name = "c";
337         auto-format = true;
338         formatter = { command = "clang-format"; args = ["--style=microsoft"]; };
339       }];
340     };
341   };
342
343   home.file.".config/zls.json".text = ''
344     {
345       "enable_build_on_save": true,
346       "build_on_save_step": "check"
347     }
348   '';
349   
350   home.file.".config/vis/plugins/vis-lspc" = {
351     source = builtins.fetchGit {
352       url = "https://gitlab.com/muhq/vis-lspc.git";
353       rev = "e184eb6c971abfcd0dc7f836f402aae6c33a8d13";
354     };
355     recursive = true;
356   };
357   home.file.".config/vis/plugins/vis-commentary" = {
358     source = builtins.fetchGit {
359       url = "https://github.com/lutobler/vis-commentary.git";
360       rev = "0e06ed8212c12c6651cb078b822390094b396f08";
361     };
362     recursive = true;
363   };
364   home.file.".config/vis/visrc.lua".text = ''
365       require('vis')
366       require('plugins/vis-commentary')
367       lspc = require('plugins/vis-lspc')
368
369       lspc.menu_cmd = 'vis-menu'
370       lspc.fallback_dirname_as_root = true
371       lspc.ls_map.zig = {name='zls',cmd='zls',roots={'build.zig'}}
372     
373       vis.events.subscribe(vis.events.INIT, function()
374         -- Your global configuration options
375       end)
376
377       vis.events.subscribe(vis.events.WIN_OPEN, function(win) -- luacheck: no unused args
378         -- Your per window configuration options e.g.
379         vis:command('set number on')
380         vis:command('set autoindent')
381         vis:command('set tabwidth 4')
382         vis:command('set expandtab on')
383       end)
384     '';
385
386   programs.emacs = {
387     enable = true;
388     extraConfig = ''
389       (menu-bar-mode 1)
390       (tool-bar-mode 0)
391       (scroll-bar-mode 0)
392       (global-display-line-numbers-mode)
393       (setq-default
394         display-line-numbers-type 'relative
395         make-backup-files nil
396         inhibit-startup-screen t)
397       (load-theme 'tango-dark t)
398     '';
399     extraPackages = epkgs: [
400       epkgs.zig-mode
401       epkgs.lsp-mode
402     ];
403   };
404
405   programs.tmux = {
406     enable = true;
407     escapeTime = 0;
408     extraConfig = ''
409       set-option -g default-terminal screen-256color
410       set -g history-limit 10000
411       set -g base-index 1
412       set-option -g renumber-windows on
413       bind-key -n M-n new-window -c "#{pane_current_path}"
414       bind-key -n M-1 select-window -t :1
415       bind-key -n M-2 select-window -t :2
416       bind-key -n M-3 select-window -t :3
417       bind-key -n M-4 select-window -t :4
418       bind-key -n M-5 select-window -t :5
419       bind-key -n M-6 select-window -t :6
420       bind-key -n M-7 select-window -t :7
421       bind-key -n M-8 select-window -t :8
422       bind-key -n M-9 select-window -t :9
423       bind-key -n M-0 select-window -t :0
424       bind-key -n M-. select-window -n
425       bind-key -n M-, select-window -p
426       bind-key -n M-S-. swap-window -t +1
427       bind-key -n M-S-, swap-window -t -1
428       bind-key -n M-X confirm-before "kill-window"
429       bind-key -n M-v split-window -h -c "#{pane_current_path}"
430       bind-key -n M-b split-window -v -c "#{pane_current_path}"
431       bind-key -n M-R command-prompt -I "" "rename-window '%%'"
432       bind-key -n M-f resize-pane -Z
433       bind-key -n M-h select-pane -L
434       bind-key -n M-l select-pane -R
435       bind-key -n M-k select-pane -U
436       bind-key -n M-j select-pane -D
437       bind-key -n M-Left select-pane -L
438       bind-key -n M-Right select-pane -R
439       bind-key -n M-Up select-pane -U
440       bind-key -n M-Down select-pane -D
441       bind-key -n "M-H" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -L; tmux swap-pane -t $old'
442       bind-key -n "M-J" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -D; tmux swap-pane -t $old'
443       bind-key -n "M-K" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -U; tmux swap-pane -t $old'
444       bind-key -n "M-L" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -R; tmux swap-pane -t $old'
445       bind-key -n "M-S-Left" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -L; tmux swap-pane -t $old'
446       bind-key -n "M-S-Down" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -D; tmux swap-pane -t $old'
447       bind-key -n "M-S-Up" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -U; tmux swap-pane -t $old'
448       bind-key -n "M-S-Right" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -R; tmux swap-pane -t $old'
449       bind-key -n M-x confirm-before "kill-pane"
450       bind-key -n M-/ copy-mode
451
452       # Linux system clipboard
453       bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"
454       bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "xclip -in -selection clipboard"
455
456       set -g mouse on
457       # set-option -g status-keys vi
458       # set-option -g set-titles on
459       # set-option -g set-titles-string 'tmux - #W'
460       # set -g bell-action any
461       # set-option -g visual-bell off
462       # set-option -g set-clipboard off
463       # setw -g mode-keys vi
464       # setw -g monitor-activity on
465       # set -g visual-activity on
466       # set -g status-style fg=colour15
467       # set -g status-justify centre
468       # set -g status-left ""
469       # set -g status-right ""
470       # set -g status-interval 1
471       # set -g message-style fg=colour0,bg=colour3
472       # setw -g window-status-bell-style fg=colour1
473       # setw -g window-status-current-style fg=yellow,bold
474       # setw -g window-status-style fg=colour250
475       # setw -g window-status-current-format ' #{?#{==:#W,#{b:SHELL}},#{b:pane_current_path},#W} '
476       # setw -g window-status-format ' #{?#{==:#W,#{b:SHELL}},#{b:pane_current_path},#W} '
477       # # For older tmux:
478       # #setw -g window-status-format ' #W '
479       # #setw -g window-status-current-format ' #W '
480     '';
481   };
482
483   programs.nushell = {
484     enable = true;
485     # for editing directly to config.nu 
486     extraConfig = ''
487       $env.config = {
488         show_banner: false,
489         completions: {
490           case_sensitive: false # case-sensitive completions
491           quick: true           # set to false to prevent auto-selecting completions
492           partial: true         # set to false to prevent partial filling of the prompt
493           algorithm: "fuzzy"    # prefix or fuzzy
494         }
495         hooks: {
496           command_not_found: { |cmd| (command-not-found $cmd | str trim)  }
497         }
498       } 
499     '';
500     #  shellAliases = {
501     #  vi = "hx";
502     #  vim = "hx";
503     #  nano = "hx";
504     # };
505   };  
506   # programs.carapace = {
507   #   enable = true;
508   #   enableNushellIntegration = true;
509   # };
510
511   # programs.starship = {
512   #   enable = true;
513   #   settings = {
514   #     add_newline = false;
515   #     character = { 
516   #       success_symbol = "[➜](bold green)";
517   #       error_symbol = "[➜](bold red)";
518   #     };
519   #   };
520   # };
521
522   programs.firefox = {
523     enable = true;
524     profiles = {
525       default = {
526         settings = {
527           "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
528           "browser.fullscreen.autohide" = false;
529           "browser.toolbars.bookmarks.visibility" = "never";
530           "browser.tabs.inTitlebar" = 0;
531           "browser.compactmode.show" = true;
532           "browser.uidensity" = 1;
533         };
534         userChrome = ''
535         #TabsToolbar {
536           visibility: collapse !important;
537         }
538         '';
539       };
540       appmode = {
541         id = 1;
542         settings = {
543           "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
544           "browser.fullscreen.autohide" = false;
545           "browser.toolbars.bookmarks.visibility" = "never";
546           "browser.tabs.inTitlebar" = 0;
547           "browser.compactmode.show" = true;
548           "browser.uidensity" = 1;
549         };
550         userChrome = ''
551         #TabsToolbar {
552           visibility: collapse !important;
553         }
554         #nav-bar {
555           visibility: collapse !important;
556         }
557         #navigator-toolbox {
558           border-bottom: none !important;
559         }
560         '';        
561       };
562     };
563   };
564
565   xdg.desktopEntries = {
566     whatsapp = {
567       name = "WhatsApp";
568       genericName = "Messenger";
569       exec = "app web.whatsapp.com";
570       terminal = false;
571       categories = [ "Application" ];
572       icon = pkgs.fetchurl {
573         url = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/2062095_application_chat_communication_logo_whatsapp_icon.svg/1024px-2062095_application_chat_communication_logo_whatsapp_icon.svg.png";
574         sha256 = "sha256-0eE3EEGnWFlpObfraTXMIqJz0Uya/h0hDsUA528qKCY=";
575       };
576     };
577     md = {
578       name = "Markdown";
579       genericName = "Documents";
580       exec = "md-app";
581       terminal = false;
582       categories = [ "Application" ];
583       icon = pkgs.fetchurl {
584         url = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Markdown-mark.svg/1024px-Markdown-mark.svg.png";
585         sha256 = "0v161jvmcfxp9lwd86y789430w1vpvxnnm5n2hzgr1kfh03psvb2";
586       };
587     };
588   };
589
590   gtk.enable = true;
591   gtk.theme = {
592     package = theme;
593     name = "Qogir-Dark";
594   };
595   # programs.gnome-shell.theme = {
596   #   package = theme;
597   #   name = "Qogir-Dark";
598   # };
599   # gtk.iconTheme = {
600   #   package = pkgs.vimix-icon-theme;
601   #   name = "vimix-doder-dark";
602   # };
603   home.pointerCursor = {
604     gtk.enable = true;
605     x11.enable = true;
606
607     name = "volantes_light_cursors";
608     size = 24;
609     package = pkgs.volantes-cursors;
610   };
611
612   # This value determines the Home Manager release that your configuration is
613   # compatible with. This helps avoid breakage when a new Home Manager release
614   # introduces backwards incompatible changes.
615   #
616   # You should not change this value, even if you update Home Manager. If you do
617   # want to update the value, then make sure to first check the Home Manager
618   # release notes.
619   home.stateVersion = "24.05"; # Please read the comment before changing.
620
621   # The home.packages option allows you to install Nix packages into your
622   # environment.
623   home.packages = with pkgs; [
624     nixos-icons
625     spotify-player
626     prismlauncher
627     pandoc
628     ghidra
629     gnome-firmware
630     fzf bat delta silver-searcher ripgrep perl universal-ctags
631     rofi
632     # bintools
633     htop
634     unzip
635     rr wrk
636     clang-tools bear
637     linuxPackages_latest.perf
638     texliveFull
639     asciidoctor-with-extensions
640     emscripten
641     caddy
642     python3
643     qogir-icon-theme
644     volantes-cursors
645     xorg.xkill
646     lf nnn yazi
647     feh
648     xarchiver
649     tig lazygit gitui
650     thunderbird
651     aerc
652     libreoffice
653     gimp
654     guvcview
655     arandr
656     vial
657     ncdu
658     gnumake gcc
659     linux-wifi-hotspot
660     esptool picocom
661     wireshark
662     nil
663     bc
664     ffmpeg-full
665     sc-im visidata
666     localsend
667     vis
668     wineWowPackages.unstableFull winetricks
669     signal-desktop
670
671     # # It is sometimes useful to fine-tune packages, for example, by applying
672     # # overrides. You can do that directly here, just don't forget the
673     # # parentheses. Maybe you want to install Nerd Fonts with a limited number of
674     # # fonts?
675     # (pkgs.nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })
676
677     # # You can also create simple shell scripts directly inside your
678     # # configuration. For example, this adds a command 'my-hello' to your
679     # # environment:
680     # (pkgs.writeShellScriptBin "my-hello" ''
681     #   echo "Hello, ${config.home.username}!"
682     # '')
683     # $@ - Liste aller Parameter
684     # $* - String aller Parameter
685     # $# - Anzahl aller Parameter
686     # &> - stdout und stderr pipen
687     # '' - Literal
688     # "" - Expanded
689     # 
690     (pkgs.writeShellScriptBin "app" ''
691       ${pkgs.firefox}/bin/firefox -p appmode --new-window "$@"
692     '')
693     (pkgs.writeShellScriptBin "md" ''
694       file=$(mktemp --suffix=.html) && \
695       echo $file && \
696       ${pkgs.pandoc}/bin/pandoc -o $file $1 -s -H ${markdownStyleHeader} && \
697       app $file && \
698       rm $file
699     '')
700     (pkgs.writeShellScriptBin "run" ''
701       (nohup "$@" &>/dev/null &); sleep 0
702     '')
703     (pkgs.writeShellScriptBin "popup" ''
704       ${pkgs.kitty}/bin/kitty -o hide_window_decorations=yes -o background_opacity=0.5 \
705         --class kitty-popup -o remember_window_size=no \
706         -o initial_window_width=120c -o initial_window_height=40c \
707         "$@"
708     '')
709     (pkgs.writeShellScriptBin "fzfdir" ''
710       find "$1" -name "$2" | ${pkgs.fzf}/bin/fzf --layout=reverse
711     '')
712     (pkgs.writeShellScriptBin "file-app" ''
713       app localhost:8123
714     '')
715     (pkgs.writeShellScriptBin "run-popup" ''
716       popup bash -c 'file=$(compgen -c | grep -v fzf | sort -u | fzf --layout=reverse --print-query | tail -n 1) && run $file'
717     '')
718     (pkgs.writeShellScriptBin "set-wallpaper" ''
719       ${pkgs.feh}/bin/feh --bg-fill --no-fehbg ${wallpaper}
720     '')
721     (pkgs.writeShellScriptBin "mirror-phone" "IP=$(select-ip) && sudo scrcpy --tcpip=$IP --no-audio -K --kill-adb-on-close")
722     (pkgs.writeShellScriptBin "select-ip" ''
723       FILE=$HOME/.cache/select-ip.txt
724       IP=$( ${pkgs.rofi}/bin/rofi -dmenu -input $FILE -p IP ) || exit 1
725       echo $IP >> $FILE
726       gawk -i inplace 'FNR==1{delete a} !a[$0]++' $FILE
727       echo $IP
728     '')
729     (pkgs.writeShellScriptBin "create-repo" ''
730       ssh psch.dev sudo -u git git init --bare /srv/git/$1
731     '')
732   ];
733
734   # Home Manager is pretty good at managing dotfiles. The primary way to manage
735   # plain files is through 'home.file'.
736   home.file = {
737     # # Building this configuration will create a copy of 'dotfiles/screenrc' in
738     # # the Nix store. Activating the configuration will then make '~/.screenrc' a
739     # # symlink to the Nix store copy.
740     # ".screenrc".source = dotfiles/screenrc;
741
742     # # You can also set the file content immediately.
743     # ".gradle/gradle.properties".text = ''
744     #   org.gradle.console=verbose
745     #   org.gradle.daemon.idletimeout=3600000
746     # '';
747   };
748
749   # Home Manager can also manage your environment variables through
750   # 'home.sessionVariables'. These will be explicitly sourced when using a
751   # shell provided by Home Manager. If you don't want to manage your shell
752   # through Home Manager then you have to manually source 'hm-session-vars.sh'
753   # located at either
754   #
755   #  ~/.nix-profile/etc/profile.d/hm-session-vars.sh
756   #
757   # or
758   #
759   #  ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
760   #
761   # or
762   #
763   #  /etc/profiles/per-user/ps/etc/profile.d/hm-session-vars.sh
764   #
765   home.sessionVariables = {
766     # EDITOR = "emacs";
767   };
768
769   # Let Home Manager install and manage itself.
770   programs.home-manager.enable = true;
771 }