summaryrefslogtreecommitdiff
path: root/home-config/fish/conf.d
diff options
context:
space:
mode:
Diffstat (limited to 'home-config/fish/conf.d')
-rw-r--r--home-config/fish/conf.d/nix-env.fish138
1 files changed, 138 insertions, 0 deletions
diff --git a/home-config/fish/conf.d/nix-env.fish b/home-config/fish/conf.d/nix-env.fish
new file mode 100644
index 0000000..22d7b31
--- /dev/null
+++ b/home-config/fish/conf.d/nix-env.fish
@@ -0,0 +1,138 @@
1# Setup Nix
2
3# We need to distinguish between single-user and multi-user installs.
4# This is difficult because there's no official way to do this.
5# We could look for the presence of /nix/var/nix/daemon-socket/socket but this will fail if the
6# daemon hasn't started yet. /nix/var/nix/daemon-socket will exist if the daemon has ever run, but
7# I don't think there's any protection against accidentally running `nix-daemon` as a user.
8# We also can't just look for /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh because
9# older single-user installs used the default profile instead of a per-user profile.
10# We can still check for it first, because all multi-user installs should have it, and so if it's
11# not present that's a pretty big indicator that this is a single-user install. If it does exist,
12# we still need to verify the install type. To that end we'll look for a root owner and sticky bit
13# on /nix/store. Multi-user installs set both, single-user installs don't. It's certainly possible
14# someone could do a single-user install as root and then manually set the sticky bit but that
15# would be extremely unusual.
16
17set -l nix_profile_path /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
18set -l single_user_profile_path ~/.nix-profile/etc/profile.d/nix.sh
19if test -e $nix_profile_path
20 # The path exists. Double-check that this is a multi-user install.
21 # We can't just check for ~/.nix-profile/… because this may be a single-user install running as
22 # the wrong user.
23
24 # stat is not portable. Splitting the output of ls -nd is reliable on most platforms.
25 set -l owner (string split -n ' ' (command ls -nd /nix/store 2>/dev/null))[3]
26 if not test -k /nix/store -a $owner -eq 0
27 # /nix/store is either not owned by root or not sticky. Assume single-user.
28 set nix_profile_path $single_user_profile_path
29 end
30else
31 # The path doesn't exist. Assume single-user
32 set nix_profile_path $single_user_profile_path
33end
34
35if test -e $nix_profile_path
36 # Source the nix setup script
37 # We're going to run the regular Nix profile under bash and then print out a few variables
38 for line in (command env -u BASH_ENV bash -c '. "$0"; for name in PATH "${!NIX_@}"; do printf "%s=%s\0" "$name" "${!name}"; done' $nix_profile_path | string split0)
39 set -xg (string split -m 1 = $line)
40 end
41
42 # Insert Nix's fish share directories into fish's special variables.
43 # nixpkgs-installed fish tries to set these up already if NIX_PROFILES is defined, which won't
44 # be the case when sourcing $__fish_data_dir/share/config.fish normally, but might be for a
45 # recursive invocation. To guard against that, we'll only insert paths that don't already exit.
46 # Furthermore, for the vendor_conf.d sourcing, we'll use the pre-existing presence of a path in
47 # $fish_function_path to determine whether we want to source the relevant vendor_conf.d folder.
48
49 # To start, let's locally define NIX_PROFILES if it doesn't already exist.
50 set -al NIX_PROFILES
51 if test (count $NIX_PROFILES) -eq 0
52 set -a NIX_PROFILES $HOME/.nix-profile
53 end
54 # Replicate the logic from nixpkgs version of $__fish_data_dir/__fish_build_paths.fish.
55 set -l __nix_profile_paths (string split ' ' -- $NIX_PROFILES)[-1..1]
56 set -l __extra_completionsdir \
57 $__nix_profile_paths/etc/fish/completions \
58 $__nix_profile_paths/share/fish/vendor_completions.d
59 set -l __extra_functionsdir \
60 $__nix_profile_paths/etc/fish/functions \
61 $__nix_profile_paths/share/fish/vendor_functions.d
62 set -l __extra_confdir \
63 $__nix_profile_paths/etc/fish/conf.d \
64 $__nix_profile_paths/share/fish/vendor_conf.d \
65
66 ### Configure fish_function_path ###
67 # Remove any of our extra paths that may already exist.
68 # Record the equivalent __extra_confdir path for any function path that exists.
69 set -l existing_conf_paths
70 for path in $__extra_functionsdir
71 if set -l idx (contains --index -- $path $fish_function_path)
72 set -e fish_function_path[$idx]
73 set -a existing_conf_paths $__extra_confdir[(contains --index -- $path $__extra_functionsdir)]
74 end
75 end
76 # Insert the paths before $__fish_data_dir.
77 if set -l idx (contains --index -- $__fish_data_dir/functions $fish_function_path)
78 # Fish has no way to simply insert into the middle of an array.
79 set -l new_path $fish_function_path[1..$idx]
80 set -e new_path[$idx]
81 set -a new_path $__extra_functionsdir
82 set fish_function_path $new_path $fish_function_path[$idx..-1]
83 else
84 set -a fish_function_path $__extra_functionsdir
85 end
86
87 ### Configure fish_complete_path ###
88 # Remove any of our extra paths that may already exist.
89 for path in $__extra_completionsdir
90 if set -l idx (contains --index -- $path $fish_complete_path)
91 set -e fish_complete_path[$idx]
92 end
93 end
94 # Insert the paths before $__fish_data_dir.
95 if set -l idx (contains --index -- $__fish_data_dir/completions $fish_complete_path)
96 set -l new_path $fish_complete_path[1..$idx]
97 set -e new_path[$idx]
98 set -a new_path $__extra_completionsdir
99 set fish_complete_path $new_path $fish_complete_path[$idx..-1]
100 else
101 set -a fish_complete_path $__extra_completionsdir
102 end
103
104 ### Source conf directories ###
105 # The built-in directories were already sourced during shell initialization.
106 # Any __extra_confdir that came from $__fish_data_dir/__fish_build_paths.fish was also sourced.
107 # As explained above, we're using the presence of pre-existing paths in $fish_function_path as a
108 # signal that the corresponding conf dir has also already been sourced.
109 # In order to simulate this, we'll run through the same algorithm as found in
110 # $__fish_data_dir/config.fish except we'll avoid sourcing the file if it comes from an
111 # already-sourced location.
112 # Caveats:
113 # * Files will be sourced in a different order than we'd ideally do (because we're coming in
114 # after the fact to source them).
115 # * If there are existing extra conf paths, files in them may have been sourced that should have
116 # been suppressed by paths we're inserting in front.
117 # * Similarly any files in $__fish_data_dir/vendor_conf.d that should have been suppressed won't
118 # have been.
119 set -l sourcelist
120 for file in $__fish_config_dir/conf.d/*.fish $__fish_sysconf_dir/conf.d/*.fish
121 # We know these paths were sourced already. Just record them.
122 set -l basename (string replace -r '^.*/' '' -- $file)
123 contains -- $basename $sourcelist
124 or set -a sourcelist $basename
125 end
126 for root in $__extra_confdir
127 for file in $root/*.fish
128 set -l basename (string replace -r '^.*/' '' -- $file)
129 contains -- $basename $sourcelist
130 and continue
131 set -a sourcelist $basename
132 contains -- $root $existing_conf_paths
133 and continue # this is a pre-existing path, it will have been sourced already
134 [ -f $file -a -r $file ]
135 and source $file
136 end
137 end
138end