Merge pull request #108491 from pacien/fishPlugins-wrapFish
wrapFish: add fish shell wrapper package
This commit is contained in:
commit
a306b088f6
|
@ -0,0 +1,50 @@
|
||||||
|
# Fish {#sec-fish}
|
||||||
|
|
||||||
|
Fish is a "smart and user-friendly command line shell" with support for plugins.
|
||||||
|
|
||||||
|
|
||||||
|
## Vendor Fish scripts {#sec-fish-vendor}
|
||||||
|
|
||||||
|
Any package may ship its own Fish completions, configuration snippets, and
|
||||||
|
functions. Those should be installed to
|
||||||
|
`$out/share/fish/vendor_{completions,conf,functions}.d` respectively.
|
||||||
|
|
||||||
|
When the `programs.fish.enable` and
|
||||||
|
`programs.fish.vendor.{completions,config,functions}.enable` options from the
|
||||||
|
NixOS Fish module are set to true, those paths are symlinked in the current
|
||||||
|
system environment and automatically loaded by Fish.
|
||||||
|
|
||||||
|
|
||||||
|
## Packaging Fish plugins {#sec-fish-plugins-pkg}
|
||||||
|
|
||||||
|
While packages providing standalone executables belong to the top level,
|
||||||
|
packages which have the sole purpose of extending Fish belong to the
|
||||||
|
`fishPlugins` scope and should be registered in
|
||||||
|
`pkgs/shells/fish/plugins/default.nix`.
|
||||||
|
|
||||||
|
The `buildFishPlugin` utility function can be used to automatically copy Fish
|
||||||
|
scripts from `$src/{completions,conf,conf.d,functions}` to the standard vendor
|
||||||
|
installation paths. It also sets up the test environment so that the optional
|
||||||
|
`checkPhase` is executed in a Fish shell with other already packaged plugins
|
||||||
|
and package-local Fish functions specified in `checkPlugins` and
|
||||||
|
`checkFunctionDirs` respectively.
|
||||||
|
|
||||||
|
See `pkgs/shells/fish/plugins/pure.nix` for an example of Fish plugin package
|
||||||
|
using `buildFishPlugin` and running unit tests with the `fishtape` test runner.
|
||||||
|
|
||||||
|
|
||||||
|
## Fish wrapper {#sec-fish-wrapper}
|
||||||
|
|
||||||
|
The `wrapFish` package is a wrapper around Fish which can be used to create
|
||||||
|
Fish shells initialised with some plugins as well as completions, configuration
|
||||||
|
snippets and functions sourced from the given paths. This provides a convenient
|
||||||
|
way to test Fish plugins and scripts without having to alter the environment.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
wrapFish {
|
||||||
|
pluginPkgs = with fishPlugins; [ pure foreign-env ];
|
||||||
|
completionDirs = [];
|
||||||
|
functionDirs = [];
|
||||||
|
confDirs = [ "/path/to/some/fish/init/dir/" ];
|
||||||
|
}
|
||||||
|
```
|
|
@ -11,6 +11,7 @@
|
||||||
<xi:include href="elm.xml" />
|
<xi:include href="elm.xml" />
|
||||||
<xi:include href="emacs.section.xml" />
|
<xi:include href="emacs.section.xml" />
|
||||||
<xi:include href="firefox.section.xml" />
|
<xi:include href="firefox.section.xml" />
|
||||||
|
<xi:include href="fish.section.xml" />
|
||||||
<xi:include href="ibus.xml" />
|
<xi:include href="ibus.xml" />
|
||||||
<xi:include href="kakoune.section.xml" />
|
<xi:include href="kakoune.section.xml" />
|
||||||
<xi:include href="linux.section.xml" />
|
<xi:include href="linux.section.xml" />
|
||||||
|
|
|
@ -1,23 +1,6 @@
|
||||||
{ stdenv, lib, writeShellScriptBin, writeScript, fish }:
|
{ stdenv, lib, writeScript, wrapFish }:
|
||||||
|
|
||||||
let
|
attrs@{
|
||||||
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,
|
pname,
|
||||||
version,
|
version,
|
||||||
src,
|
src,
|
||||||
|
@ -32,8 +15,10 @@ in attrs@{
|
||||||
installPath ? lib.getName pname,
|
installPath ? lib.getName pname,
|
||||||
|
|
||||||
checkInputs ? [],
|
checkInputs ? [],
|
||||||
# plugins or paths to add to the function path of the test fish shell
|
# plugin packages to add to the vendor paths of the test fish shell
|
||||||
checkFunctionPath ? [],
|
checkPlugins ? [],
|
||||||
|
# vendor directories to add to the function path of the test fish shell
|
||||||
|
checkFunctionDirs ? [],
|
||||||
# test script to be executed in a fish shell
|
# test script to be executed in a fish shell
|
||||||
checkPhase ? "",
|
checkPhase ? "",
|
||||||
doCheck ? checkPhase != "",
|
doCheck ? checkPhase != "",
|
||||||
|
@ -52,7 +37,7 @@ stdenv.mkDerivation (attrs // {
|
||||||
(
|
(
|
||||||
install_vendor_files() {
|
install_vendor_files() {
|
||||||
source="$1"
|
source="$1"
|
||||||
target="$out/${rtpPath}/vendor_$2.d"
|
target="$out/share/fish/vendor_$2.d"
|
||||||
|
|
||||||
[ -d $source ] || return 0
|
[ -d $source ] || return 0
|
||||||
mkdir -p $target
|
mkdir -p $target
|
||||||
|
@ -69,7 +54,12 @@ stdenv.mkDerivation (attrs // {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
inherit doCheck;
|
inherit doCheck;
|
||||||
checkInputs = [ (fishWithFunctionPath checkFunctionPath) ] ++ checkInputs;
|
|
||||||
|
checkInputs = [ (wrapFish {
|
||||||
|
pluginPkgs = checkPlugins;
|
||||||
|
functionDirs = checkFunctionDirs;
|
||||||
|
}) ] ++ checkInputs;
|
||||||
|
|
||||||
checkPhase = ''
|
checkPhase = ''
|
||||||
export HOME=$(mktemp -d) # fish wants a writable home
|
export HOME=$(mktemp -d) # fish wants a writable home
|
||||||
fish "${writeScript "${name}-test" checkPhase}"
|
fish "${writeScript "${name}-test" checkPhase}"
|
||||||
|
|
|
@ -11,7 +11,7 @@ buildFishPlugin rec {
|
||||||
sha256 = "0dxcyhs2shhgy5xnwcimqja8vqsyk841x486lgq13i3y1h0kp2kd";
|
sha256 = "0dxcyhs2shhgy5xnwcimqja8vqsyk841x486lgq13i3y1h0kp2kd";
|
||||||
};
|
};
|
||||||
|
|
||||||
checkFunctionPath = [ "./" ]; # fishtape is introspective
|
checkFunctionDirs = [ "./" ]; # fishtape is introspective
|
||||||
checkPhase = ''
|
checkPhase = ''
|
||||||
rm test/tty.fish # test expects a tty
|
rm test/tty.fish # test expects a tty
|
||||||
fishtape test/*.fish
|
fishtape test/*.fish
|
||||||
|
|
|
@ -12,7 +12,7 @@ buildFishPlugin rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
checkInputs = [ git ];
|
checkInputs = [ git ];
|
||||||
checkFunctionPath = [ fishtape ];
|
checkPlugins = [ fishtape ];
|
||||||
checkPhase = ''
|
checkPhase = ''
|
||||||
# https://github.com/rafaelrinaldi/pure/issues/264
|
# https://github.com/rafaelrinaldi/pure/issues/264
|
||||||
rm tests/_pure_string_width.test.fish
|
rm tests/_pure_string_width.test.fish
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
{ lib, writeShellScriptBin, fish }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
makeOverridable ({
|
||||||
|
completionDirs ? [],
|
||||||
|
functionDirs ? [],
|
||||||
|
confDirs ? [],
|
||||||
|
pluginPkgs ? []
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
vendorDir = kind: plugin: "${plugin}/share/fish/vendor_${kind}.d";
|
||||||
|
complPath = completionDirs ++ map (vendorDir "completions") pluginPkgs;
|
||||||
|
funcPath = functionDirs ++ map (vendorDir "functions") pluginPkgs;
|
||||||
|
confPath = confDirs ++ map (vendorDir "conf") pluginPkgs;
|
||||||
|
safeConfPath = map escapeShellArg confPath;
|
||||||
|
|
||||||
|
in writeShellScriptBin "fish" ''
|
||||||
|
${fish}/bin/fish --init-command "
|
||||||
|
set --prepend fish_complete_path ${escapeShellArgs complPath}
|
||||||
|
set --prepend fish_function_path ${escapeShellArgs funcPath}
|
||||||
|
for c in {${concatStringsSep "," safeConfPath}}/*; source $c; end
|
||||||
|
" "$@"
|
||||||
|
'')
|
|
@ -8933,6 +8933,8 @@ in
|
||||||
|
|
||||||
fish = callPackage ../shells/fish { };
|
fish = callPackage ../shells/fish { };
|
||||||
|
|
||||||
|
wrapFish = callPackage ../shells/fish/wrapper.nix { };
|
||||||
|
|
||||||
fishPlugins = recurseIntoAttrs (callPackage ../shells/fish/plugins { });
|
fishPlugins = recurseIntoAttrs (callPackage ../shells/fish/plugins { });
|
||||||
|
|
||||||
ion = callPackage ../shells/ion {
|
ion = callPackage ../shells/ion {
|
||||||
|
|
Loading…
Reference in New Issue