Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native fish environment with babelfish #270

Merged
merged 1 commit into from
Jan 28, 2021

Conversation

kevingriffin
Copy link
Contributor

This is an alternative approach to #266

Adds the babelfish package for translating the environment to fish at build time, eliminating the need for and performance cost of fenv.

I'm not sure if we want to vendor the package, get it added upsteam in nixpkgs, or some other approach. Ideally nixOS users would receive a similar change to their module as well.

Fixes #269

@toonn
Copy link
Contributor

toonn commented Jan 9, 2021

This does seem to work fine for me. Doesn't really affect loading time of a shell started from a shell but spawning a new terminal has gone for ~8s to under 4s.

Note that I don't use POSIX variable substitutions in my environment so I can't vouch for that working.

@kevingriffin
Copy link
Contributor Author

Thanks for having a look! I prefer this approach and opened PRs on nixpkgs to add the package and use it in the nixOS module.

Copy link

@bouk bouk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for getting started on this, I already have something like this in my own nix config:

https://github.com/bouk/b/blob/5cfc6ec6a46d15fffef9c92788b719d07a1a950e/darwin.nix#L80-L117

For me it was a huge speed boost, shaving 3-4 seconds (!) off every new shell invocation

set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path
fenv source /etc/fish/foreign-env/interactiveShellInit > /dev/null
set -e fish_function_path[1]

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're removing a bunch of the shell inits here, which will break gpg-agent for example.

I think we should translate all of the init files and save them as environment.etc."fish/interactiveShellInit.fish" etc. Then we also don't need system.build.setEnvironmentFish

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bouk I've tried implementing this approach. If you could have a look and give feedback, I'll port the same change to the nixOS module.

@kevingriffin
Copy link
Contributor Author

I've made changes here and on the nixOS module to make this change optional, configured on the fish module. I also committed a change to the namespace of the foreign-env package to resolve the original issue for users who don't use the new babelfish-based generation option.

${babelfish}/bin/babelfish < ${config.system.build.setEnvironment} > $out;
'';

etc."fish/shellInit".source = pkgs.runCommand "shellInit" {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fish files always have .fish at the end, so I think you should add that here too.

else
''
set fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish-foreign-env/functions $fish_function_path
fenv source ${path} > /dev/null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need fenv there as we are using babelfish?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't. In the version I've done for nixOS, this requirement is removed. I'll go ahead and port it back to nix-darwin in this branch.

Copy link
Owner

@LnL7 LnL7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few extra things to consider here compared to the NixOS module since this needs to be compatible with both 20.09 and unstable.

@@ -12,6 +12,23 @@ let
mapAttrsFlatten (k: v: "alias ${k} '${v}'") cfg.shellAliases
);

babelfish = pkgs.callPackage ../../pkgs/shells/fish/plugins/babelfish.nix { };
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really want to keep package definitions in this repo.

Since this isn't guaranteed to be available in nixpkgs (eg. 20.09) the best solution is to add a package option without a default, that way it's up to the user to either introduce the version they want into their configuration or if nixpkgs is recent enough just use pkgs.babelfish. The later can then also the default once the oldest supported release has babelfish available.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. It was convenient to spike it, but I wouldn't want to vendor an old package in nix-darwin. I'll add a package option.

"source ${path}"
else
''
set fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish-foreign-env/functions $fish_function_path
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the babelfish package, this should still handle the case where fishPlugins isn't available in nixpkgs yet. That's what is causing the tests to fail. eg.

let
  fenv = pkgs.fish-foreign-env or pkgs.fishPlugins.foreign-env;
in
  # ...

Ideally an alias would be added in nixpkgs however, just renaming stuff isn't really something projects outside of the repo should have deal with without some compatibility window.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very clean way to do it. I'll incorporate that into this branch, along with the other changes (like selecting which method to use—fenv or babelfish—) from the nixOS module and push up a new version.

Configuration may be ran through fenv at shell start time
(as previously) or translated to fish at build time with
a specified babelfish package.
@kevingriffin
Copy link
Contributor Author

@LnL7 Thanks for the review! I believe what I just pushed up addresses your comments. Let me know if there's anything else to improve.

@kevingriffin
Copy link
Contributor Author

@LnL7 The nixOS module was merged with no further changes. Is there anything else to do to make this suitable for nix-darwin?

Copy link
Owner

@LnL7 LnL7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the extra compatibility changes this looks good to me. I'm not a fish user but people with more relevant knowledge should have already reviewed this on the NixOS side.

@LnL7 LnL7 merged commit 32d49bc into LnL7:master Jan 28, 2021
@teehemkay
Copy link

teehemkay commented Jan 29, 2021

There's an issue where fish-foreign-env has now been aliased to throw "fish-foreign-env has been replaced with fishPlugins.foreign-env in Nixpkgs.

If works fine if the user chooses to enable babelfish.
But it results in an error if fish is enabled but babelfish is not used and Nixpkgs has already been upgraded to fishPlugins.foreign-env which unfortunately is the default configuration...

The test to bind fenv in the let expression should probably be inverted.
Maybe something like:

 fenv = if builtins.hasAttr "fishPlugins" pkgs then pkgs.fishPlugins.foreign-env else pkgs.fish-foreign-env;


envInteractiveShellInit = pkgs.writeText "interactiveShellInit" cfge.interactiveShellInit;

fenv = pkgs.fish-foreign-env or pkgs.fishPlugins.foreign-env;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran into the same problem because of the redirect at pkgs.fish-foreign-env, looks like flipping around the packages would indeed fix it.

Suggested change
fenv = pkgs.fish-foreign-env or pkgs.fishPlugins.foreign-env;
fenv = pkgs.fishPlugins.foreign-env or pkgs.fish-foreign-env;

@teehemkay
Copy link

teehemkay commented Jan 29, 2021

Yep. I was beeing extra cautious (check before jumping) hence the if expression.

I've updated my previous comment to clarify when the error occurs.

@kevingriffin
Copy link
Contributor Author

Thank you @teehemkay and @toonn for the testing. I opened a quick PR to integrate this change:

#283

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Recent changes in fish-foreign-env (Nixpkgs) break /etc/fish/nixos-env-preinit.fish
6 participants