-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathflake.nix
144 lines (125 loc) · 4.3 KB
/
flake.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
{
description = "xdg-override";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
};
outputs = inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [
"aarch64-linux"
"armv6l-linux"
"armv7l-linux"
"i686-linux"
"riscv64-linux"
"x86_64-linux"
];
perSystem = { config, self', inputs', pkgs, system, ... }: {
packages = rec {
xdg-override = let
text = builtins.readFile ./xdg-override;
in pkgs.writeShellApplication {
name = "xdg-override";
text = text;
};
default = xdg-override;
};
};
flake.lib = let
proxyText = { nameMatch, delegate }: let
_ = assert (builtins.typeOf nameMatch == "list" && builtins.length nameMatch > 0); null;
conditions = map ({ case, command }: ''if [[ "$1" =~ ${case} ]]; then ${command} "$1" & exit 0'') nameMatch;
conditionsStr = builtins.concatStringsSep "\nel" conditions;
in ''
${conditionsStr}
else ${delegate} "$1"
fi
'';
in rec {
/* Generate an overlay with patched xdg-utils package.
# Inputs
`nameMatch` a list of pairs
{ case = "<regex>"; command = "<command>" }
Example:
(overlay {
nameMatch = [
{ case = "^https?://"; command = "firefox" }
]
})
WARNING: on a typical desktop many derivations depend on xdg-utils. Adding this overlay will cause massive
rebuilds
*/
overlay = { nameMatch } : final : prev : {
xdg-utils =
prev.symlinkJoin {
name = "xdg-utils";
paths = [ prev.xdg-utils ];
buildInputs = [ prev.makeWrapper ];
postBuild = ''
mv $out/bin/xdg-open $out/bin/.xdg-open
cat <<EOF > $out/bin/xdg-open
${proxyText { inherit nameMatch; delegate = "$out/bin/.xdg-open"; }}
EOF
chmod +x $out/bin/xdg-open
'';
};
};
/* Generate a proxy xdg-open package.
The intended use-case is to install this package and to shadow xdg-open from xdg-utils to globally dispatch
certain URLs to an alternative browser.
# Inputs
`pkgs` system's nixpkgs
`nameMatch` a list of pairs
{ case = "<regex>"; command = "<command>" }
Example:
home.packages = [
(xdg-override.lib.proxyPkg { inherit pkgs; nameMatch = [
{ case = "^https?://.*\.youtube.com/"; command = "mpv"; }
];})
]
The example will open all *.youtube.com URLs in `mpv` instead of the default browser.
*/
proxyPkg = { pkgs, nameMatch } : let
text = proxyText { inherit nameMatch; delegate = "${pkgs.xdg-utils}/bin/xdg-open"; };
in pkgs.writeShellApplication {
name = "xdg-open";
checkPhase = "true";
text = ''
${text}
'';
};
/* Wrap a single package and inject custom xdg-open proxy into its `PATH``
# Inputs
`nameMatch` a list of pairs
{ case = "<regex>"; command = "<command>" }
`pkg` a package to wrap
Example:
home.packages = [
(xdg-override.lib.wrapPacakge {
nameMatch = [
{ case = "^https?://"; command = "firefox"; }
];
} pkgs.slack)
]
This will install a wrapped slack package, which will open all links in Firefox instead of the default browser.
*/
wrapPackage = { nameMatch }: pkg: let
system = pkg.system;
pkgs = inputs.nixpkgs.legacyPackages."${system}";
proxy = proxyPkg { inherit pkgs nameMatch; };
pname = pkg.out.pname;
in pkgs.symlinkJoin {
name = pkg.name;
paths = [ pkg ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram "$out/bin/${pname}" --prefix PATH : "${proxy}/bin"
for desktopFile in $out/share/applications/*; do
cp --remove-destination $(readlink -e "$desktopFile") "$desktopFile"
sed -i -e 's:${pkg}/bin/${pname}:${pname}:' "$desktopFile"
done
'';
};
};
};
}