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

Recommendation regarding zsh compinit #3965

Open
nh2 opened this issue May 8, 2023 · 4 comments
Open

Recommendation regarding zsh compinit #3965

nh2 opened this issue May 8, 2023 · 4 comments

Comments

@nh2
Copy link
Contributor

nh2 commented May 8, 2023

Hi, a hit an issue with zsh that starting a new shell (by opening a new terminal, typing zsh, or benchmarking with command time zsh -i -l -c ':') took ~300 ms, causing a noticeable, annoying delay.

Using zprof (e.g. as described here) showed that compinit and compaudit took > 85% of that time, and that they were called repeatedly (3 times for me). Both are related to zsh's completion system.

After a bit of reasearch, e.g. mainly https://dev.to/djmoch/zsh-compinit--rtfm-47kg, I learned that during zsh startup:

  • You need to initialise the zsh completion system once by calling compinit
  • By default (when not calling it with -C), it also creates a cache file .zcompdump; this takes extra long
  • Any time you add some completions afterwards during zsh startup (e.g. via home-manager's plugins for other shell-integrating software like atuin, fzf, or skim) which modifies the fpath (if I understood it right), zsh automatitically has to re-run compinit.

Here is my concrete setup:

  • Using global NixOS config in /etc/nixos/configuration.nix (where I load the grml zsh config)
  • A bit of extra user-specific config in home-manager's home.nix

Because of that, I get compinit calls in:

In the latter, it seems home-manager already knows about the problem, because there's a comment:

# Oh-My-Zsh/Prezto calls compinit during initialization,
# calling it twice causes slight start up slowdown
# as all $fpath entries will be traversed again.
${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable)
cfg.completionInit
}

        # Oh-My-Zsh/Prezto calls compinit during initialization,
        # calling it twice causes slight start up slowdown
        # as all $fpath entries will be traversed again.

My issue request:

home-manager should give some advice what to do in such situations, to minimise compinit/startup time e.g. when mixed NixOS/home-manager zsh configs are in use.

@nh2
Copy link
Contributor Author

nh2 commented May 8, 2023

I currently came up with the following workaround:

In /etc/nixos/configuration.nix:

  # zsh
  programs.zsh.enable = true;
  programs.zsh.interactiveShellInit = ''
    # Enable the below for profiling zsh's startup speed.
    # Once enabled, get numbers using:
    #     zsh -i -l -c 'zprof'
    #zmodload zsh/zprof

    # Disable `compaudit` being invoked from GRML cominit call.
    # See: https://grml.org/zsh/grmlzshrc.html
    # This speeds up shell loading.
    zstyle ':grml:completion:compinit' arguments -C

    # Load grml's zshrc.
    # Note that loading grml's zshrc here will override NixOS settings such as
    # `programs.zsh.histSize`, so they will have to be set again below.
    source ${pkgs.grml-zsh-config}/etc/zsh/zshrc

    # From https://htr3n.github.io/2018/07/faster-zsh/
    # Theoretically it should not be needed (as described on https://dev.to/djmoch/zsh-compinit--rtfm-47kg)
    # but I couldn't figure out how to make the GRML zshrc do only a single compinit
    # without compaudit but generating .zcompdump (I use `-C` for
    # `:grml:completion:compinit` above to avoid compaudit but that also skips
    # generating `.zcompdump` apparently).
    # Snippet based on https://gist.github.com/ctechols/ca1035271ad134841284
    autoload -Uz compinit
    if [[ -n ${ZDOTDIR:-$HOME}/.zcompdump(#qN.mh+24) ]]; then
      compinit
    else
      # We don't do `compinit -C` here because the GRML zshrc already did it above.
    fi
  '';
  programs.zsh.promptInit = ""; # otherwise it'll override the grml prompt

  # Speed up zsh start by running compinit manually (see config above).
  programs.zsh.enableGlobalCompInit = false;

In home.nix:

    zsh = {
      enable = true;
      # Using GRML zshrc in /etc/nixos/configuration.nix currently
      # instead of `oh-my-zsh` because so far it cannot properly show
      # git rebases in the prompt, which I care a lot about.

      # My global NixOS config does `compinit` already.
      # Disabling it in my user's `.zshrc` because calling it multiple
      # times causes startup delay, see:
      #     https://github.com/nix-community/home-manager/blob/990b82ecd31f6372bc4c3f39a9171961bc370a22/modules/programs/zsh.nix#L518-L524
      enableCompletion = false;
    };

So in summary, I

  • tell both NixOS's and home-manager's zsh module to not call compinit, because GRML does it already
  • I tell the GRML call to pass -C so that it doesn't run compaudit (which I try to avoid overall)
  • I use the approach that many blogs link to (https://gist.github.com/ctechols/ca1035271ad134841284) to run full compinit (without -C) only once per day, instead of at each zsh startup.

This works, but I am not sure if it is optimal, and it also means that if compaudit prints any warnings, I only get the chance to see them once per day (which I guess is fine for me).

@stale
Copy link

stale bot commented Aug 6, 2023

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve 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

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 stale bot added the status: stale label Aug 6, 2023
@dongho-jung
Copy link

dongho-jung commented Oct 1, 2023

thanks, you saved my day indeed


EDIT. I found that when I use zplug, it compinit on behalf of me so I could get rid of compinit things from my nixes

@stale stale bot removed the status: stale label Oct 1, 2023
Copy link

stale bot commented Dec 31, 2023

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve 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

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.

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

No branches or pull requests

5 participants