diff --git a/nixos/doc/manual/release-notes/rl-2103.xml b/nixos/doc/manual/release-notes/rl-2103.xml
index 432de831cb6..dbc4ecd6930 100644
--- a/nixos/doc/manual/release-notes/rl-2103.xml
+++ b/nixos/doc/manual/release-notes/rl-2103.xml
@@ -309,6 +309,14 @@
Based on , existing installations will continue to work.
+
+
+ fish-foreign-env is now an alias for the
+ fishPlugins.foreign-env package, in which the fish
+ functions have been relocated to the
+ vendor_functions.d directory to be loaded automatically.
+
+
The prometheus json exporter is now managed by the prometheus community. Together with additional features
diff --git a/nixos/modules/programs/fish.nix b/nixos/modules/programs/fish.nix
index 50d1077dd41..34a0dc6a2df 100644
--- a/nixos/modules/programs/fish.nix
+++ b/nixos/modules/programs/fish.nix
@@ -112,7 +112,7 @@ in
environment.etc."fish/nixos-env-preinit.fish".text = ''
# This happens before $__fish_datadir/config.fish sets fish_function_path, so it is currently
# unset. We set it and then completely erase it, leaving its configuration to $__fish_datadir/config.fish
- set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $__fish_datadir/functions
+ set fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d $__fish_datadir/functions
# source the NixOS environment config
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]
@@ -128,7 +128,7 @@ in
# if we haven't sourced the general config, do it
if not set -q __fish_nixos_general_config_sourced
- set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path
+ set --prepend fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d
fenv source /etc/fish/foreign-env/shellInit > /dev/null
set -e fish_function_path[1]
@@ -142,7 +142,7 @@ in
# if we haven't sourced the login config, do it
status --is-login; and not set -q __fish_nixos_login_config_sourced
and begin
- set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path
+ set --prepend fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d
fenv source /etc/fish/foreign-env/loginShellInit > /dev/null
set -e fish_function_path[1]
@@ -158,7 +158,7 @@ in
and begin
${fishAliases}
- set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path
+ set --prepend fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d
fenv source /etc/fish/foreign-env/interactiveShellInit > /dev/null
set -e fish_function_path[1]
diff --git a/pkgs/shells/fish/plugins/build-fish-plugin.nix b/pkgs/shells/fish/plugins/build-fish-plugin.nix
new file mode 100644
index 00000000000..e2ec342e544
--- /dev/null
+++ b/pkgs/shells/fish/plugins/build-fish-plugin.nix
@@ -0,0 +1,77 @@
+{ stdenv, lib, writeShellScriptBin, writeScript, fish }:
+
+let
+ rtpPath = "share/fish";
+
+ mapToFuncPath = v:
+ if lib.isString v
+ then v
+ else "${v}/${rtpPath}/vendor_functions.d";
+
+ fishWithFunctionPath = plugins: let
+ funcPaths = map mapToFuncPath plugins;
+ in writeShellScriptBin "fish" ''
+ ${fish}/bin/fish \
+ --init-command \
+ "set --prepend fish_function_path ${lib.escapeShellArgs funcPaths}" \
+ "$@"
+ '';
+
+in attrs@{
+ pname,
+ version,
+ src,
+
+ name ? "fishplugin-${pname}-${version}",
+ unpackPhase ? "",
+ configurePhase ? ":",
+ buildPhase ? ":",
+ preInstall ? "",
+ postInstall ? "",
+ # name of the subdirectory in which to store the plugin
+ installPath ? lib.getName pname,
+
+ checkInputs ? [],
+ # plugins or paths to add to the function path of the test fish shell
+ checkFunctionPath ? [],
+ # test script to be executed in a fish shell
+ checkPhase ? "",
+ doCheck ? checkPhase != "",
+
+ ...
+}:
+
+stdenv.mkDerivation (attrs // {
+ inherit name;
+ inherit unpackPhase configurePhase buildPhase;
+
+ inherit preInstall postInstall;
+ installPhase = ''
+ runHook preInstall
+
+ (
+ install_vendor_files() {
+ source="$1"
+ target="$out/${rtpPath}/vendor_$2.d"
+
+ [ -d $source ] || return 0
+ mkdir -p $target
+ cp -r $source/*.fish "$target/"
+ }
+
+ install_vendor_files completions completions
+ install_vendor_files functions functions
+ install_vendor_files conf conf
+ install_vendor_files conf.d conf
+ )
+
+ runHook postInstall
+ '';
+
+ inherit doCheck;
+ checkInputs = [ (fishWithFunctionPath checkFunctionPath) ] ++ checkInputs;
+ checkPhase = ''
+ export HOME=$(mktemp -d) # fish wants a writable home
+ fish "${writeScript "${name}-test" checkPhase}"
+ '';
+})
diff --git a/pkgs/shells/fish/plugins/default.nix b/pkgs/shells/fish/plugins/default.nix
new file mode 100644
index 00000000000..e543d49516a
--- /dev/null
+++ b/pkgs/shells/fish/plugins/default.nix
@@ -0,0 +1,13 @@
+{ lib, newScope }:
+
+lib.makeScope newScope (self: with self; {
+
+ buildFishPlugin = callPackage ./build-fish-plugin.nix { };
+
+ fishtape = callPackage ./fishtape.nix { };
+
+ foreign-env = callPackage ./foreign-env { };
+
+ pure = callPackage ./pure.nix { };
+
+})
diff --git a/pkgs/shells/fish/plugins/fishtape.nix b/pkgs/shells/fish/plugins/fishtape.nix
new file mode 100644
index 00000000000..326ff61c417
--- /dev/null
+++ b/pkgs/shells/fish/plugins/fishtape.nix
@@ -0,0 +1,32 @@
+{ lib, buildFishPlugin, fetchFromGitHub }:
+
+buildFishPlugin rec {
+ pname = "fishtape";
+ version = "2.1.3";
+
+ src = fetchFromGitHub {
+ owner = "jorgebucaran";
+ repo = "fishtape";
+ rev = version;
+ sha256 = "0dxcyhs2shhgy5xnwcimqja8vqsyk841x486lgq13i3y1h0kp2kd";
+ };
+
+ checkFunctionPath = [ "./" ]; # fishtape is introspective
+ checkPhase = ''
+ rm test/tty.fish # test expects a tty
+ fishtape test/*.fish
+ '';
+
+ preInstall = ''
+ # move the function script in the proper sub-directory
+ mkdir functions
+ mv fishtape.fish functions/
+ '';
+
+ meta = {
+ description = "TAP-based test runner for Fish";
+ homepage = "https://github.com/jorgebucaran/fishtape";
+ license = lib.licenses.mit;
+ maintainers = with lib.maintainers; [ pacien ];
+ };
+}
diff --git a/pkgs/shells/fish/fish-foreign-env/default.nix b/pkgs/shells/fish/plugins/foreign-env/default.nix
similarity index 66%
rename from pkgs/shells/fish/fish-foreign-env/default.nix
rename to pkgs/shells/fish/plugins/foreign-env/default.nix
index ef157f32392..03435340d17 100644
--- a/pkgs/shells/fish/fish-foreign-env/default.nix
+++ b/pkgs/shells/fish/plugins/foreign-env/default.nix
@@ -1,7 +1,7 @@
-{ stdenv, fetchFromGitHub, gnused, bash, coreutils }:
+{ lib, buildFishPlugin, fetchFromGitHub, gnused, bash, coreutils }:
-stdenv.mkDerivation {
- pname = "fish-foreign-env";
+buildFishPlugin {
+ pname = "foreign-env";
version = "git-20200209";
src = fetchFromGitHub {
@@ -11,18 +11,16 @@ stdenv.mkDerivation {
sha256 = "00xqlyl3lffc5l0viin1nyp819wf81fncqyz87jx8ljjdhilmgbs";
};
- installPhase = ''
- mkdir -p $out/share/fish-foreign-env/functions/
- cp functions/* $out/share/fish-foreign-env/functions/
+ patches = [ ./suppress-harmless-warnings.patch ];
+
+ preInstall = ''
sed -e "s|sed|${gnused}/bin/sed|" \
-e "s|bash|${bash}/bin/bash|" \
-e "s|\| tr|\| ${coreutils}/bin/tr|" \
- -i $out/share/fish-foreign-env/functions/*
+ -i functions/*
'';
- patches = [ ./suppress-harmless-warnings.patch ];
-
- meta = with stdenv.lib; {
+ meta = with lib; {
description = "A foreign environment interface for Fish shell";
license = licenses.mit;
maintainers = with maintainers; [ jgillich ];
diff --git a/pkgs/shells/fish/fish-foreign-env/suppress-harmless-warnings.patch b/pkgs/shells/fish/plugins/foreign-env/suppress-harmless-warnings.patch
similarity index 100%
rename from pkgs/shells/fish/fish-foreign-env/suppress-harmless-warnings.patch
rename to pkgs/shells/fish/plugins/foreign-env/suppress-harmless-warnings.patch
diff --git a/pkgs/shells/fish/plugins/pure.nix b/pkgs/shells/fish/plugins/pure.nix
new file mode 100644
index 00000000000..54af2e0663e
--- /dev/null
+++ b/pkgs/shells/fish/plugins/pure.nix
@@ -0,0 +1,29 @@
+{ lib, buildFishPlugin, fetchFromGitHub, git, fishtape }:
+
+buildFishPlugin rec {
+ pname = "pure";
+ version = "3.4.2";
+
+ src = fetchFromGitHub {
+ owner = "rafaelrinaldi";
+ repo = "pure";
+ rev = "v${version}";
+ sha256 = "134sz3f98gb6z2vgd5kkm6dd8pka5gijk843c32s616w35y07sga";
+ };
+
+ checkInputs = [ git ];
+ checkFunctionPath = [ fishtape ];
+ checkPhase = ''
+ # https://github.com/rafaelrinaldi/pure/issues/264
+ rm tests/_pure_string_width.test.fish
+
+ fishtape tests/*.test.fish
+ '';
+
+ meta = {
+ description = "Pretty, minimal and fast Fish prompt, ported from zsh";
+ homepage = "https://github.com/rafaelrinaldi/pure";
+ license = lib.licenses.mit;
+ maintainers = with lib.maintainers; [ pacien ];
+ };
+}
diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix
index 4a4277c2072..01c80ea3d80 100644
--- a/pkgs/top-level/aliases.nix
+++ b/pkgs/top-level/aliases.nix
@@ -158,6 +158,7 @@ mapAliases ({
firefoxWrapper = firefox; # 2015-09
firestr = throw "firestr has been removed."; # added 2019-12-08
+ fish-foreign-env = fishPlugins.foreign-env; # added 2020-12-29
flameGraph = flamegraph; # added 2018-04-25
flvtool2 = throw "flvtool2 has been removed."; # added 2020-11-03
foldingathome = fahclient; # added 2020-09-03
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index c11c82800f7..d4ca2d6f741 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -8843,7 +8843,7 @@ in
fish = callPackage ../shells/fish { };
- fish-foreign-env = callPackage ../shells/fish/fish-foreign-env { };
+ fishPlugins = recurseIntoAttrs (callPackage ../shells/fish/plugins { });
ion = callPackage ../shells/ion {
inherit (darwin) Security;