home-manager icon indicating copy to clipboard operation
home-manager copied to clipboard

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

Open lukasstevens opened this issue 4 years ago • 18 comments

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

lukasstevens avatar Mar 13 '20 12:03 lukasstevens

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? 🙂

rycee avatar Mar 15 '20 21:03 rycee

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 :)

uvNikita avatar Mar 21 '20 18:03 uvNikita

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

rycee avatar Mar 24 '20 22:03 rycee

@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.

uvNikita avatar May 26 '20 12:05 uvNikita

@rycee @uvNikita Sounds good to me.

lukasstevens avatar Jul 10 '20 07:07 lukasstevens

@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 plugins are automatically compiled with zcompile
  • Compilation of the completion cache (i.e. .zcompdump)
  • Adds auto-discovery of plugin.fpath (there's no real standard, but most plugins have a subdirectory named functions that should be added to fpath. See zimfw/git for an example)
  • Adds auto-discovery of plugin.file (some plugins do pluginname.plugin.zsh, others init.zsh, etc.).
  • Autoloads all functions from the plugins fpath folder, ignoring certain files like completion functions. (e.g. autoload -Uz git-alias-lookup git-branch-current ... for zimfw/git)
  • plus a few other minor 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 avatar Jan 14 '21 03:01 colinxs

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

colinxs avatar Jan 30 '21 02:01 colinxs

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.

stale[bot] avatar Apr 30 '21 02:04 stale[bot]

I think the issue is still relevant.

lukasstevens avatar May 06 '21 14:05 lukasstevens

@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 avatar Jul 25 '21 15:07 anund

@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

anund avatar Jul 30 '21 23:07 anund

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.

stale[bot] avatar Oct 29 '21 00:10 stale[bot]

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?

lukasstevens avatar Nov 17 '21 16:11 lukasstevens

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 avatar Nov 18 '21 07:11 anund

@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.

anund avatar Dec 02 '21 09:12 anund

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

lukasstevens avatar Dec 03 '21 10:12 lukasstevens

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.

jonas-w avatar Apr 28 '24 08:04 jonas-w

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

nonetrix avatar Jun 20 '24 00:06 nonetrix