nix-community / home-manager

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

Recommendation regarding zsh compinit #3965

Open nh2 opened 1 year ago

nh2 commented 1 year ago

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:

Here is my concrete setup:

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:

https://github.com/nix-community/home-manager/blob/78ceec68f29ed56d6118617e9f0f588bf164067f/modules/programs/zsh.nix#L519-L524

        # 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 commented 1 year ago

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

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[bot] commented 1 year ago

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.

dongho-jung commented 1 year ago

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[bot] commented 11 months ago

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.