nix-community / home-manager

Manage a user environment using Nix [maintainer=@rycee]
https://nix-community.github.io/home-manager/
MIT License
6.8k stars 1.78k forks source link

Changing .zshrc should delete .zshrc.zwc file on home-manager switch #1088

Open lukasstevens opened 4 years ago

lukasstevens commented 4 years ago

Since zsh compiles .zshrc to .zshrc.zwc, changes of .zshrc are sometimes not picked up.

rycee commented 4 years ago

Ah, I've never heard of that before. Perhaps the module needs an activation script to delete the zwc file or something? @uvNikita Anything you know about? 🙂

uvNikita commented 4 years ago

I have never used zsh zcompile function before, which seems to be used to create those precompiled .zwc files. Looking at how someone is doing it here https://medium.com/@voyeg3r/holy-grail-of-zsh-performance-a56b3d72265d it seems to me that it does make sense to remove/recompile those files during home-manager activation on .zshrc file change. Since home-manager know when the file is changed, we wouldn't need a zcompare script like in the linked blog post.

That said, since I don't have any experience with this functionality, I'm not confident enough to implement it myself :)

rycee commented 4 years ago

Would it be possible to compile the file at generation build time and link the compiled version into place?

uvNikita commented 4 years ago

@rycee I think this would be a very good solution. Since we know that we control config files completely, we can probably do such compilation when changes are detected.

lukasstevens commented 4 years ago

@rycee @uvNikita Sounds good to me.

colinxs commented 3 years ago

@rycee @uvNikita

Hey all, I came across this issue as well. I'm fairly familiar with ZSH and zcompile, so maybe I can lend a hand here? I'm using a custom zsh module that I made, which is more-or-less a stripped down version of modules/programs/zsh.nix that adds the following features:

All these additions are effectively what the zimfw plugin manager does, adapted to Nix. zimfw, unlike oh-my-zsh or prezto, is "universal" in that it can be used for any kind of "plugin", whether that be a oh-my-zsh/prezto module or something else. It's also significantly faster.

The only thing I'm stuck on is how in the hell do I compile all the ZSH dotfiles (e.g. .zshrc) and link them to $HOME? What I'm currently doing in zsh.nix, which is wrong is:

home.activation.compile = lib.hm.dag.entryAfter [ "installPackages" ] ''
  rm -f ${relToDotDir ".zshrc.zwc"}
  ${pkgs.zsh}/bin/zsh -c 'zcompile ${relToDotDir ".zshrc"}'
''

which means .zshrc.zwc isn't tracked by home-manager. I made a few ugly attempts at doing this but couldn't figure out how.

tl;dr if you can help me figure out this last point, then I'd love to upstream the improvements I made to the ZSH module!

colinxs commented 3 years ago

Another constraint that I recently learned: any compilation would have to occur after linkGeneration if the files being zcompile'ed source any other files.

stale[bot] commented 3 years ago

Thank you for your contribution! I marked this issue as stale due to inactivity. If this remains inactive for another 7 days, I will close this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

If you are not the original author of the issue

* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

Memorandum on closing issues

If you have nothing of substance to add, please refrain from commenting and allow the bot close the issue. Also, don't be afraid to manually close an issue, even if it holds valuable information.

Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

lukasstevens commented 3 years ago

I think the issue is still relevant.

anund commented 3 years ago

@colinxs roughly. Note: the filename of the eventual link target and the file past to zcompile need to match. I had to explicitly add the dot to the file in runcommand for zsh to use the .zwc result.

    (let
    zshrc = pkgs.writeText "zshrc" ''... snip ...'';
    zshrcCompiled = pkgs.runCommand "zshrc.zwc" {} ''
        cp ${zshrc} .zshrc
        ${pkgs.zsh}/bin/zsh -c "zcompile .zshrc"
        cp .zshrc.zwc $out
    '';
    in
    {
      home.packages = with pkgs; [ zsh ]
        ++ optional cfg.enableCompletion nix-zsh-completions
        ++ optional cfg.oh-my-zsh.enable oh-my-zsh;

      home.file."${relToDotDir ".zshrc"}".source = zshrc;
      home.file."${relToDotDir ".zshrc.zwc"}".source = zshrcCompiled;
    })
anund commented 3 years ago

@lukasstevens can you tell me what your zsh configuration is? The default zsh configuration doesn't run zcompile (or zrecompile). Testing with your configuration would help guarantee the fix I sketch just above would actually work

stale[bot] commented 2 years ago

Thank you for your contribution! I marked this issue as stale due to inactivity. If this remains inactive for another 7 days, I will close this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

If you are not the original author of the issue

* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

Memorandum on closing issues

If you have nothing of substance to add, please refrain from commenting and allow the bot close the issue. Also, don't be afraid to manually close an issue, even if it holds valuable information.

Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

lukasstevens commented 2 years ago

Sorry I somehow missed your message @anund. My configuration is available here https://github.com/lukasstevens/dotfiles/blob/master/zsh-settings.nix. The base16-theme should hopefully not be relevant to this issue. Currently, the .zshrc is not compiled on my system. Was this changed in the meantime? Or was the issue originally due to a mistake/change in configuration on my side?

anund commented 2 years ago

When I last looked home-manager doesn't do anything to invoke zcomplie. That shouldn't be an issue unless there is some plugin that attempts to zcompile everything zsh related including .zshrc. Since those plugins have no idea when home-manager changes .zshrc they don't know to call compile when things change. Zsh will happily open .zshrc.zwc if it exists regardless of whether or not it's older than the current .zshrc.

I can take your config and validate that's what's happening, which plugin might be calling zcompile, and check if home-manager generating the the compiled version the way I sketch out above is compatible with what that plugin is doing. (there are some possible complications with calling zcompile to combine multiple files into one target)

anund commented 2 years ago

@lukasstevens, ah I misread your last response. Yes a .zshrc.zwc would have come from your existing/some other zsh configuration and not home-manager. I've looked through your config and a basic version of prezto; neither compile .zshrc. zimfw does compile and will have issues if .zshrc is managed by home-manager.

For this issue we could consider to changes to home-manager.

  1. flag configured compilation based on a sketch above
  2. a warning that detects the presence of compile versions of any of the zsh files generated

The first option needs to be behind a flag to avoid accidental foot guns that come with compilations. There are some edge cases that crop up with compilation of .rc files containing certain zsh features. zimfw demonstrates it's mostly fine in practice just by existing though.

I'm personally more interested in figuring out how to do 2 in the short term. 1 needs more thought. https://github.com/romkatv/zsh-bench is a decent start. Also @colinxs might have some ideas.

lukasstevens commented 2 years ago

I think a warning would be great and cover most use cases.

jonas-w commented 5 months ago

Would be great to have a compile option where home-manager only outputs the .zshrc.zwc (.zprofile.zwc/...) file. As current performance hacks like https://github.com/romkatv/zsh-bench/tree/master?tab=readme-ov-file#cutting-corners don't seem to work with symlinks.

nonetrix commented 3 months ago

I spend a whole day debugging why after removing https://github.com/jeffreytse/zsh-vi-mode why it was still loading even though I couldn't even find the copyright notice on one of the files after searching my whole drive. Could this be the reason? I was just trying to switch from Zplug to doing things in Nix since Zplug was slowing things down a loooooot