NixOS system configurations + dotfiles via home-manager
1{ inputs, lib, ... }:
2let
3 fishPrompt =
4 pkgs:
5 pkgs.fishPlugins.buildFishPlugin {
6 pname = "fish-prompt-pvsr";
7 src = inputs.fish-prompt-pvsr;
8 version = inputs.fish-prompt-pvsr.shortRev;
9 };
10in
11{
12 flake.modules.nixos.base =
13 { pkgs, ... }:
14 {
15 programs.fish.enable = true;
16 programs.fish.useBabelfish = true;
17 users.defaultUserShell = pkgs.fishMinimal;
18 environment.systemPackages = [ (fishPrompt pkgs) ];
19 };
20
21 flake.modules.darwin.default =
22 { pkgs, ... }:
23 {
24 programs.fish.enable = true;
25 programs.fish.useBabelfish = true;
26 environment.systemPackages = [ (fishPrompt pkgs) ];
27 };
28
29 flake.modules.nixos.core =
30 { pkgs, ... }:
31 {
32 users.defaultUserShell = lib.mkForce pkgs.fish;
33 };
34
35 flake.modules.hjem.core =
36 { config, pkgs, ... }:
37 let
38 cfg = config.fish;
39 writeFish =
40 name: content:
41 pkgs.runCommandLocal name
42 {
43 inherit content;
44 passAsFile = [ "content" ];
45 }
46 ''
47 ${pkgs.fish}/bin/fish --no-config --no-execute "$contentPath"
48 ${pkgs.fish}/bin/fish_indent < "$contentPath" > $out 2> /dev/null
49 '';
50 mkFunction = name: text: {
51 name = "fish/functions/${name}.fish";
52 value.source = writeFish "${name}.fish" ''
53 function ${name}
54 ${text}
55 end
56 '';
57 };
58 mkWrapper = wraps: name: text: {
59 name = "fish/functions/${name}.fish";
60 value.source = writeFish "${name}.fish" ''
61 function ${name} --wraps='${wraps}'
62 ${text}
63 end
64 '';
65 };
66 in
67 {
68 options.fish = with lib.types; {
69 interactiveShellInit = lib.mkOption {
70 type = lines;
71 default = "";
72 };
73 functions = lib.mkOption {
74 type = attrsOf str;
75 default = { };
76 };
77 wrappers = lib.mkOption {
78 type = attrsOf (attrsOf str);
79 default = { };
80 };
81 };
82
83 config.packages = [ pkgs.fish ];
84
85 config.xdg.config.files = {
86 "fish/conf.d/env.fish".text = lib.concatMapAttrsStringSep "\n" (
87 name: value: "set -gx ${lib.escapeShellArg name} ${toString value}"
88 ) config.environment.sessionVariables;
89 "fish/conf.d/zoxide.fish".source = pkgs.runCommandLocal "zoxide.fish" { } ''
90 echo 'status is-interactive; or exit' > $out
91 ${pkgs.zoxide}/bin/zoxide init fish >> $out
92 '';
93 "fish/themes/magenta.theme".source = ./magenta.theme;
94 "fish/config.fish".source = writeFish "config.fish" ''
95 status is-interactive; or exit
96 set -g fish_greeting
97 set -g fish_key_bindings fish_hybrid_key_bindings
98 bind -M insert ctrl-n down-or-search
99 bind -M insert ctrl-q push-line
100 bind -M default -m insert ctrl-q push-line
101 set -g fish_cursor_default block
102 set -g fish_cursor_insert line
103 set -g fish_cursor_replace_one underscore
104
105 abbr -a --position anywhere -- \
106 nn '--log-format internal-json -v 2&| nom --json'
107 abbr -a --position anywhere --set-cursor -- \
108 .c/ '$XDG_CONFIG_HOME/%'
109
110 abbr -a sc 'systemctl'
111 abbr -a ssc 'sudo systemctl'
112 abbr -a scu 'systemctl --user'
113 abbr -a jce 'journalctl -e'
114 abbr -a jcf 'journalctl -f'
115 abbr -a jcu 'journalctl -u'
116 abbr -a jcm 'sudo journalctl -M'
117
118 ${cfg.interactiveShellInit}
119 '';
120 }
121 // lib.mapAttrs' mkFunction {
122 push-line = # fish
123 ''
124 set -g __fish_pushed_line (commandline)
125 commandline ""
126 function after-next-prompt --on-event fish_postexec
127 commandline $__fish_pushed_line
128 functions --erase after-next-prompt
129 end
130 '';
131 session = # fish
132 ''
133 if set -q argv[1]
134 set -gx fish_history $argv[1]
135 set data_dir "$HOME/.local/share/zoxide/sessions/$argv[1]"
136 mkdir -p $data_dir
137 and set -gx _ZO_DATA_DIR "$data_dir"
138 pushd (zoxide query 2> /dev/null; or echo .)
139 else
140 set -ge fish_history
141 set -ge _ZO_DATA
142 popd 2> /dev/null
143 end
144 '';
145 fish_mode_prompt = "";
146 }
147 // lib.mapAttrs' mkFunction cfg.functions
148 // lib.concatMapAttrs (wrapped: lib.mapAttrs' (mkWrapper wrapped)) cfg.wrappers;
149 };
150}