diff options
author | Kevin Griffin <me@kevin.jp> | 2021-01-11 16:11:29 +0900 |
---|---|---|
committer | Cole Helbling <cole.e.helbling@outlook.com> | 2021-01-22 09:24:40 -0800 |
commit | 515d801aee4a660803dce3edb1d1f74c6f3a3b2e (patch) | |
tree | 87be707d661d59a048a4b741cb4f3f5dd2c4f025 /nixos | |
parent | 4aaa445477b9bf59db2f163c714f3654c2ace0ba (diff) |
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.
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/programs/fish.nix | 297 |
1 files changed, 176 insertions, 121 deletions
diff --git a/nixos/modules/programs/fish.nix b/nixos/modules/programs/fish.nix index 34a0dc6a2df3d..d3f7d3eb1af54 100644 --- a/nixos/modules/programs/fish.nix +++ b/nixos/modules/programs/fish.nix @@ -13,6 +13,27 @@ let (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 { @@ -29,6 +50,15 @@ in 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 { type = types.bool; default = true; @@ -105,72 +135,152 @@ in # Required for man completions documentation.man.generateCaches = lib.mkDefault true; - environment.etc."fish/foreign-env/shellInit".text = cfge.shellInit; - environment.etc."fish/foreign-env/loginShellInit".text = cfge.loginShellInit; - environment.etc."fish/foreign-env/interactiveShellInit".text = cfge.interactiveShellInit; - - 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.fishPlugins.foreign-env}/share/fish/vendor_functions.d $__fish_datadir/functions - - # source the NixOS environment config - if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ] - fenv source ${config.system.build.setEnvironment} - end - - # clear fish_function_path so that it will be correctly set when we return to $__fish_datadir/config.fish - set -e fish_function_path - ''; - - environment.etc."fish/config.fish".text = '' - # /etc/fish/config.fish: DO NOT EDIT -- this file has been generated automatically. - - # if we haven't sourced the general config, do it - if not set -q __fish_nixos_general_config_sourced - 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] - - ${cfg.shellInit} - - # and leave a note so we don't source this config section again from - # 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 - status --is-login; and not set -q __fish_nixos_login_config_sourced - and begin - 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] - - ${cfg.loginShellInit} - - # and leave a note so we don't source this config section again from - # 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 - status --is-interactive; and not set -q __fish_nixos_interactive_config_sourced - and begin - ${fishAliases} - - 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] - - ${cfg.promptInit} - ${cfg.interactiveShellInit} - - # and leave a note so we don't source this config section again from - # 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 - ''; + environment = mkMerge [ + (mkIf cfg.useBabelfish + { + 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"; + }) + + (mkIf (!cfg.useBabelfish) + { + etc."fish/foreign-env/shellInit".source = envShellInit; + etc."fish/foreign-env/loginShellInit".source = envLoginShellInit; + etc."fish/foreign-env/interactiveShellInit".source = envInteractiveShellInit; + }) + + { + etc."fish/nixos-env-preinit.fish".text = + if cfg.useBabelfish + 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 + + # source the NixOS environment config + if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ] + fenv source ${config.system.build.setEnvironment} + end + + # clear fish_function_path so that it will be correctly set when we return to $__fish_datadir/config.fish + set -e fish_function_path + ''; + } + + { + etc."fish/config.fish".text = '' + # /etc/fish/config.fish: DO NOT EDIT -- this file has been generated automatically. + + # if we haven't sourced the general config, do it + if not set -q __fish_nixos_general_config_sourced + ${sourceEnv "shellInit"} + + ${cfg.shellInit} + + # and leave a note so we don't source this config section again from + # 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 + status --is-login; and not set -q __fish_nixos_login_config_sourced + and begin + ${sourceEnv "loginShellInit"} + + ${cfg.loginShellInit} + + # and leave a note so we don't source this config section again from + # 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 + status --is-interactive; and not set -q __fish_nixos_interactive_config_sourced + and begin + ${fishAliases} + + ${sourceEnv "interactiveShellInit"} + + ${cfg.promptInit} + ${cfg.interactiveShellInit} + + # and leave a note so we don't source this config section again from + # 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 = '' # add completions generated by NixOS to $fish_complete_path @@ -187,61 +297,6 @@ in 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" - ]; - }; } |