fish: add babelfish translation option

Configuration may be ran through fenv at shell start time
(as previously) or translated to fish at build time with
the babelfish package.
This commit is contained in:
Kevin Griffin 2021-01-11 16:11:29 +09:00 committed by Cole Helbling
parent 4aaa445477
commit 515d801aee

View File

@ -13,6 +13,27 @@ let
(filterAttrs (k: v: v != null) cfg.shellAliases) (filterAttrs (k: v: v != null) cfg.shellAliases)
); );
envShellInit = pkgs.writeText "shellInit" cfge.shellInit;
envLoginShellInit = pkgs.writeText "loginShellInit" cfge.loginShellInit;
envInteractiveShellInit = pkgs.writeText "interactiveShellInit" cfge.interactiveShellInit;
sourceEnv = file:
if cfg.useBabelfish then
"source /etc/fish/${file}.fish"
else
''
set fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish-foreign-env/functions $fish_function_path
fenv source /etc/fish/foreign-env/${file} > /dev/null
set -e fish_function_path[1]
'';
babelfishTranslate = path: name:
pkgs.runCommand "${name}.fish" {
nativeBuildInputs = [ pkgs.babelfish ];
} "${pkgs.babelfish}/bin/babelfish < ${path} > $out;";
in in
{ {
@ -29,6 +50,15 @@ in
type = types.bool; type = types.bool;
}; };
useBabelfish = mkOption {
type = types.bool;
default = false;
description = ''
If enabled, the configured environment will be translated to native fish using <link xlink:href="https://github.com/bouk/babelfish">babelfish</link>.
Otherwise, <link xlink:href="https://github.com/oh-my-fish/plugin-foreign-env">foreign-env</link> will be used.
'';
};
vendor.config.enable = mkOption { vendor.config.enable = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
@ -105,72 +135,152 @@ in
# Required for man completions # Required for man completions
documentation.man.generateCaches = lib.mkDefault true; documentation.man.generateCaches = lib.mkDefault true;
environment.etc."fish/foreign-env/shellInit".text = cfge.shellInit; environment = mkMerge [
environment.etc."fish/foreign-env/loginShellInit".text = cfge.loginShellInit; (mkIf cfg.useBabelfish
environment.etc."fish/foreign-env/interactiveShellInit".text = cfge.interactiveShellInit; {
etc."fish/setEnvironment.fish".source = babelfishTranslate config.system.build.setEnvironment "setEnvironment";
etc."fish/shellInit.fish".source = babelfishTranslate envShellInit "shellInit";
etc."fish/loginShellInit.fish".source = babelfishTranslate envLoginShellInit "loginShellInit";
etc."fish/interactiveShellInit.fish".source = babelfishTranslate envInteractiveShellInit "interactiveShellInit";
})
environment.etc."fish/nixos-env-preinit.fish".text = '' (mkIf (!cfg.useBabelfish)
# 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 etc."fish/foreign-env/shellInit".source = envShellInit;
set fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d $__fish_datadir/functions etc."fish/foreign-env/loginShellInit".source = envLoginShellInit;
etc."fish/foreign-env/interactiveShellInit".source = envInteractiveShellInit;
})
# source the NixOS environment config {
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ] etc."fish/nixos-env-preinit.fish".text =
fenv source ${config.system.build.setEnvironment} if cfg.useBabelfish
end then ''
# source the NixOS environment config
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]
source /etc/fish/setEnvironment.fish
end
''
else ''
# 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.fishPlugins.foreign-env}/share/fish/vendor_functions.d $__fish_datadir/functions
# clear fish_function_path so that it will be correctly set when we return to $__fish_datadir/config.fish # source the NixOS environment config
set -e fish_function_path if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]
''; fenv source ${config.system.build.setEnvironment}
end
environment.etc."fish/config.fish".text = '' # clear fish_function_path so that it will be correctly set when we return to $__fish_datadir/config.fish
# /etc/fish/config.fish: DO NOT EDIT -- this file has been generated automatically. set -e fish_function_path
'';
}
# if we haven't sourced the general config, do it {
if not set -q __fish_nixos_general_config_sourced etc."fish/config.fish".text = ''
set --prepend fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d # /etc/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.
fenv source /etc/fish/foreign-env/shellInit > /dev/null
set -e fish_function_path[1]
${cfg.shellInit} # if we haven't sourced the general config, do it
if not set -q __fish_nixos_general_config_sourced
${sourceEnv "shellInit"}
# and leave a note so we don't source this config section again from ${cfg.shellInit}
# this very shell (children will source the general config anew)
set -g __fish_nixos_general_config_sourced 1
end
# if we haven't sourced the login config, do it # and leave a note so we don't source this config section again from
status --is-login; and not set -q __fish_nixos_login_config_sourced # this very shell (children will source the general config anew)
and begin set -g __fish_nixos_general_config_sourced 1
set --prepend fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d end
fenv source /etc/fish/foreign-env/loginShellInit > /dev/null
set -e fish_function_path[1]
${cfg.loginShellInit} # if we haven't sourced the login config, do it
status --is-login; and not set -q __fish_nixos_login_config_sourced
and begin
${sourceEnv "loginShellInit"}
# and leave a note so we don't source this config section again from ${cfg.loginShellInit}
# this very shell (children will source the general config anew)
set -g __fish_nixos_login_config_sourced 1
end
# if we haven't sourced the interactive config, do it # and leave a note so we don't source this config section again from
status --is-interactive; and not set -q __fish_nixos_interactive_config_sourced # this very shell (children will source the general config anew)
and begin set -g __fish_nixos_login_config_sourced 1
${fishAliases} end
set --prepend fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d # if we haven't sourced the interactive config, do it
fenv source /etc/fish/foreign-env/interactiveShellInit > /dev/null status --is-interactive; and not set -q __fish_nixos_interactive_config_sourced
set -e fish_function_path[1] and begin
${fishAliases}
${cfg.promptInit} ${sourceEnv "interactiveShellInit"}
${cfg.interactiveShellInit}
# and leave a note so we don't source this config section again from ${cfg.promptInit}
# this very shell (children will source the general config anew, ${cfg.interactiveShellInit}
# allowing configuration changes in, e.g, aliases, to propagate)
set -g __fish_nixos_interactive_config_sourced 1 # and leave a note so we don't source this config section again from
end # this very shell (children will source the general config anew,
''; # allowing configuration changes in, e.g, aliases, to propagate)
set -g __fish_nixos_interactive_config_sourced 1
end
'';
}
{
etc."fish/generated_completions".source =
let
patchedGenerator = pkgs.stdenv.mkDerivation {
name = "fish_patched-completion-generator";
srcs = [
"${pkgs.fish}/share/fish/tools/create_manpage_completions.py"
"${pkgs.fish}/share/fish/tools/deroff.py"
];
unpackCmd = "cp $curSrc $(basename $curSrc)";
sourceRoot = ".";
patches = [ ./fish_completion-generator.patch ]; # to prevent collisions of identical completion files
dontBuild = true;
installPhase = ''
mkdir -p $out
cp * $out/
'';
preferLocalBuild = true;
allowSubstitutes = false;
};
generateCompletions = package: pkgs.runCommand
"${package.name}_fish-completions"
(
{
inherit package;
preferLocalBuild = true;
allowSubstitutes = false;
}
// optionalAttrs (package ? meta.priority) { meta.priority = package.meta.priority; }
)
''
mkdir -p $out
if [ -d $package/share/man ]; then
find $package/share/man -type f | xargs ${pkgs.python3.interpreter} ${patchedGenerator}/create_manpage_completions.py --directory $out >/dev/null
fi
'';
in
pkgs.buildEnv {
name = "system_fish-completions";
ignoreCollisions = true;
paths = map generateCompletions config.environment.systemPackages;
};
}
# include programs that bring their own completions
{
pathsToLink = []
++ optional cfg.vendor.config.enable "/share/fish/vendor_conf.d"
++ optional cfg.vendor.completions.enable "/share/fish/vendor_completions.d"
++ optional cfg.vendor.functions.enable "/share/fish/vendor_functions.d";
}
{ systemPackages = [ pkgs.fish ]; }
{
shells = [
"/run/current-system/sw/bin/fish"
"${pkgs.fish}/bin/fish"
];
}
];
programs.fish.interactiveShellInit = '' programs.fish.interactiveShellInit = ''
# add completions generated by NixOS to $fish_complete_path # add completions generated by NixOS to $fish_complete_path
@ -187,61 +297,6 @@ in
end end
''; '';
environment.etc."fish/generated_completions".source =
let
patchedGenerator = pkgs.stdenv.mkDerivation {
name = "fish_patched-completion-generator";
srcs = [
"${pkgs.fish}/share/fish/tools/create_manpage_completions.py"
"${pkgs.fish}/share/fish/tools/deroff.py"
];
unpackCmd = "cp $curSrc $(basename $curSrc)";
sourceRoot = ".";
patches = [ ./fish_completion-generator.patch ]; # to prevent collisions of identical completion files
dontBuild = true;
installPhase = ''
mkdir -p $out
cp * $out/
'';
preferLocalBuild = true;
allowSubstitutes = false;
};
generateCompletions = package: pkgs.runCommand
"${package.name}_fish-completions"
(
{
inherit package;
preferLocalBuild = true;
allowSubstitutes = false;
}
// optionalAttrs (package ? meta.priority) { meta.priority = package.meta.priority; }
)
''
mkdir -p $out
if [ -d $package/share/man ]; then
find $package/share/man -type f | xargs ${pkgs.python3.interpreter} ${patchedGenerator}/create_manpage_completions.py --directory $out >/dev/null
fi
'';
in
pkgs.buildEnv {
name = "system_fish-completions";
ignoreCollisions = true;
paths = map generateCompletions config.environment.systemPackages;
};
# include programs that bring their own completions
environment.pathsToLink = []
++ optional cfg.vendor.config.enable "/share/fish/vendor_conf.d"
++ optional cfg.vendor.completions.enable "/share/fish/vendor_completions.d"
++ optional cfg.vendor.functions.enable "/share/fish/vendor_functions.d";
environment.systemPackages = [ pkgs.fish ];
environment.shells = [
"/run/current-system/sw/bin/fish"
"${pkgs.fish}/bin/fish"
];
}; };
} }