mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
fish: keep all fish-completions packages around
...even empty ones. For packages in `home.packages` with no Fish completions, we build an empty directory that is not included in our runtime closure (because we build a collection of symlinks to their contents: if there are no contents, there is nothing to symlink). This means these empty completion packages get garbage-collected by Nix. They are not that expensive to rebuild but there can be enough of them it adds up, and any change to any package in `home.packages` is enough to trigger a rebuild. Fix this by forcing a dependency on all of them. Since we already depended on them anyway if they were non-empty, this only adds dependencies on empty directories (so should not significantly affect storage space). Fixes #6157.
This commit is contained in:
parent
361ab4484e
commit
f045bd46b7
1 changed files with 87 additions and 76 deletions
|
|
@ -434,92 +434,103 @@ in
|
||||||
lib.mkMerge [
|
lib.mkMerge [
|
||||||
{ home.packages = [ cfg.package ]; }
|
{ home.packages = [ cfg.package ]; }
|
||||||
|
|
||||||
(mkIf cfg.generateCompletions {
|
(mkIf cfg.generateCompletions (
|
||||||
# Support completion for `man` by building a cache for `apropos`.
|
let
|
||||||
programs.man.generateCaches = lib.mkDefault true;
|
generateCompletions =
|
||||||
|
let
|
||||||
xdg.dataFile."fish/home-manager_generated_completions".source =
|
getName =
|
||||||
let
|
attrs: attrs.name or "${attrs.pname or "«pname-missing»"}-${attrs.version or "«version-missing»"}";
|
||||||
# Paths later in the list will overwrite those already linked
|
in
|
||||||
destructiveSymlinkJoin =
|
package:
|
||||||
args_@{
|
pkgs.runCommand "${getName package}-fish-completions"
|
||||||
name,
|
{
|
||||||
paths,
|
srcs =
|
||||||
preferLocalBuild ? true,
|
[ package ]
|
||||||
allowSubstitutes ? false,
|
++ lib.filter (p: p != null) (
|
||||||
postBuild ? "",
|
builtins.map (outName: package.${outName} or null) config.home.extraOutputsToInstall
|
||||||
...
|
);
|
||||||
}:
|
nativeBuildInputs = [ pkgs.python3 ];
|
||||||
let
|
buildInputs = [ cfg.package ];
|
||||||
args =
|
preferLocalBuild = true;
|
||||||
removeAttrs args_ [
|
}
|
||||||
"name"
|
''
|
||||||
"postBuild"
|
|
||||||
]
|
|
||||||
// {
|
|
||||||
# pass the defaults
|
|
||||||
inherit preferLocalBuild allowSubstitutes;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
pkgs.runCommand name args ''
|
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
for i in $paths; do
|
for src in $srcs; do
|
||||||
if [ -z "$(find $i -prune -empty)" ]; then
|
if [ -d $src/share/man ]; then
|
||||||
cp -srf $i/* $out
|
find -L $src/share/man -type f \
|
||||||
|
-exec python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out {} + \
|
||||||
|
> /dev/null
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
${postBuild}
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
generateCompletions =
|
allCompletions =
|
||||||
let
|
let
|
||||||
getName =
|
cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
|
||||||
attrs: attrs.name or "${attrs.pname or "«pname-missing»"}-${attrs.version or "«version-missing»"}";
|
in
|
||||||
in
|
map generateCompletions (lib.sort cmp config.home.packages);
|
||||||
package:
|
in
|
||||||
pkgs.runCommand "${getName package}-fish-completions"
|
{
|
||||||
{
|
# Support completion for `man` by building a cache for `apropos`.
|
||||||
srcs =
|
programs.man.generateCaches = lib.mkDefault true;
|
||||||
[ package ]
|
|
||||||
++ lib.filter (p: p != null) (
|
xdg.dataFile."fish/home-manager_generated_completions".source =
|
||||||
builtins.map (outName: package.${outName} or null) config.home.extraOutputsToInstall
|
let
|
||||||
);
|
# Paths later in the list will overwrite those already linked
|
||||||
nativeBuildInputs = [ pkgs.python3 ];
|
destructiveSymlinkJoin =
|
||||||
buildInputs = [ cfg.package ];
|
args_@{
|
||||||
preferLocalBuild = true;
|
name,
|
||||||
}
|
paths,
|
||||||
''
|
preferLocalBuild ? true,
|
||||||
|
allowSubstitutes ? false,
|
||||||
|
postBuild ? "",
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
args =
|
||||||
|
removeAttrs args_ [
|
||||||
|
"name"
|
||||||
|
"postBuild"
|
||||||
|
]
|
||||||
|
// {
|
||||||
|
# pass the defaults
|
||||||
|
inherit preferLocalBuild allowSubstitutes;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.runCommand name args ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
for src in $srcs; do
|
for i in $paths; do
|
||||||
if [ -d $src/share/man ]; then
|
if [ -z "$(find $i -prune -empty)" ]; then
|
||||||
find -L $src/share/man -type f \
|
cp -srf $i/* $out
|
||||||
-exec python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out {} + \
|
|
||||||
> /dev/null
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
${postBuild}
|
||||||
'';
|
'';
|
||||||
in
|
|
||||||
destructiveSymlinkJoin {
|
|
||||||
name = "${config.home.username}-fish-completions";
|
|
||||||
paths =
|
|
||||||
let
|
|
||||||
cmp = (a: b: (a.meta.priority or 0) > (b.meta.priority or 0));
|
|
||||||
in
|
|
||||||
map generateCompletions (lib.sort cmp config.home.packages);
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.fish.interactiveShellInit = ''
|
in
|
||||||
# add completions generated by Home Manager to $fish_complete_path
|
destructiveSymlinkJoin {
|
||||||
begin
|
name = "${config.home.username}-fish-completions";
|
||||||
set -l joined (string join " " $fish_complete_path)
|
paths = allCompletions;
|
||||||
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
|
};
|
||||||
set -l post_joined (string replace $prev_joined "" $joined)
|
|
||||||
set -l prev (string split " " (string trim $prev_joined))
|
# For packages with no Fish completions, generateCompletions will build an empty directory,
|
||||||
set -l post (string split " " (string trim $post_joined))
|
# which means they will not be in our runtime closure. Force a dependency so these do not get
|
||||||
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
|
# constantly rebuilt.
|
||||||
end
|
home.extraDependencies = allCompletions;
|
||||||
'';
|
|
||||||
})
|
programs.fish.interactiveShellInit = ''
|
||||||
|
# add completions generated by Home Manager to $fish_complete_path
|
||||||
|
begin
|
||||||
|
set -l joined (string join " " $fish_complete_path)
|
||||||
|
set -l prev_joined (string replace --regex "[^\s]*generated_completions.*" "" $joined)
|
||||||
|
set -l post_joined (string replace $prev_joined "" $joined)
|
||||||
|
set -l prev (string split " " (string trim $prev_joined))
|
||||||
|
set -l post (string split " " (string trim $post_joined))
|
||||||
|
set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
{
|
{
|
||||||
xdg.configFile."fish/config.fish".source = fishIndent "config.fish" ''
|
xdg.configFile."fish/config.fish".source = fishIndent "config.fish" ''
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue