home-manager
home-manager copied to clipboard
Changing .zshrc should delete .zshrc.zwc file on home-manager switch
Since zsh compiles .zshrc to .zshrc.zwc, changes of .zshrc are sometimes not picked up.
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? 🙂
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 :)
Would it be possible to compile the file at generation build time and link the compiled version into place?
@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.
@rycee @uvNikita Sounds good to me.
@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 namedfunctions
that should be added tofpath
. See zimfw/git for an example) - Adds auto-discovery of
plugin.file
(some plugins dopluginname.plugin.zsh
, othersinit.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!
Another constraint that I recently learned: any compilation would have to occur after linkGeneration
if the files being zcompile
'ed source any other files.
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.
I think the issue is still relevant.
@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;
})
@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
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.
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?
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)
@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.
- flag configured compilation based on a sketch above
- 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.
I think a warning would be great and cover most use cases.
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.
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