Powerlevel10k

repository·master·Indexed 12 days ago

https://github.com/romkatv/powerlevel10k

A highly optimized Zsh theme designed for speed and flexibility. It features a configuration wizard via `p10k configure`, an Instant Prompt feature to reduce startup lag, and integrated support for gitstatus for high-performance git status reporting in Zsh and Bash.

Tokens
18.6K
Snippets
61
Records
82
Agent score
95%

What's inside Powerlevel10k

  1. Call `getdents64()` directly for maximum performance

    master

    For the highest performance, bypass the POSIX readdir() interface and call the Linux getdents64 system call directly. This requires defining a custom dirent64_t structure and managing an Arena for memory allocation. This approach yields a ~37.8% speedup over the baseline (v1).

    struct dirent64_t {
      ino64_t d_ino;
      off64_t d_off;
      unsigned short d_reclen;
      unsigned char d_type;
      char d_name[];
    };
    
    void ListDir(int parent_fd, Arena& arena, vector<char*>& entries) {
      entries.clear();
      int dir_fd = openat(parent_fd, dirname, O_NOATIME | O_RDONLY | O_DIRECTORY | O_CLOEXEC);
      if (dir_fd < 0) return;
      arena.Clear();
      while (true) {
        char* buf = arena.Alloc();
        int n = syscall(SYS_getdents64, dir_fd, buf, Arena::kBlockSize);
        if (n <= 0) {
          if (n) entries.clear();
          break;
        }
        for (int pos = 0; pos < n;) {
          auto* ent = reinterpret_cast<dirent64_t*>(buf + pos);
          if (!Dots(ent->d_name)) entries.push_back(ent->d_name);
          pos += ent->d_reclen;
        }
      }
      sort(entries.begin(), entries.end(),
           [](const char* a, const char* b) { return strcmp(a, b) < 0; });
      close(dir_fd);
    }
  2. Maintain Powerlevel9k compatibility

    master

    Powerlevel10k is designed to be backward compatible with Powerlevel9k configurations. All parameters recognized by Powerlevel9k are supported in Powerlevel10k. For consistency, all Powerlevel10k-specific parameters still use the POWERLEVEL9K_ prefix.

    Key Compatibility Notes:

    • VCS Backends: By default, only git is enabled in P10k for performance. To use svn or hg, you must explicitly add them to POWERLEVEL9K_VCS_BACKENDS (note: this may significantly slow down the prompt).
    • Legacy Spacing: If you want the exact icon spacing used in Powerlevel9k, set POWERLEVEL9K_LEGACY_ICON_SPACING=true.
    • Right Prompt Indent: To match Powerlevel9k's right prompt behavior (removing the extra trailing space), set ZLE_RPROMPT_INDENT=0.
  3. Use Show On Command to declutter your prompt

    master

    The Show On Command feature makes specific prompt segments appear only when you are typing commands relevant to them. For example, a kubecontext segment can be configured to appear only when you invoke kubectl, helm, or kubens.

    To customize this, edit ~/.p10k.zsh and search for SHOW_ON_COMMAND. You can either remove the parameter to make the segment always visible or modify the list of tools that trigger it.

    # Show prompt segment "kubecontext" only when the command you are typing invokes one of these tools.
    typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens'
  4. Migrate from Powerlevel9k to Powerlevel10k

    master
    If you are upgrading from Powerlevel9k, do not remove your existing configuration options. Powerlevel10k is designed to recognize and pick up Powerlevel9k configuration settings, allowing you to maintain the same prompt UI you are accustomed to.
  5. Access file type via `dirent64_t` memory layout

    master
    When using the getdents64 optimization, the d_type field (which distinguishes between regular files and directories) is located at an offset of -1 relative to the d_name field in the dirent64_t structure. This allows callers to check the file type at zero additional cost during the directory traversal.
  6. What Powerlevel10k affects in the shell

    master

    Powerlevel10k is strictly a prompt theme. It defines the prompt and sets prompt-related Zsh options and the PS1 and RPS1 parameters.

    It does NOT affect:

    • Terminal window/tab titles.
    • Colors used by commands like ls.
    • Git command behavior.
    • Tab completions (style or content).
    • Command line syntax highlighting or autosuggestions.
    • Key bindings or aliases.
    • Any commands other than the p10k utility.
  7. Optimization techniques for fast directory listing (ListDir)

    master

    The ListDir() function in gitstatus has been optimized through several iterations to minimize userspace CPU time. The most significant bottleneck identified was strcmp() during sorting, which performs $O(N^2)$ comparisons for small collections due to Insertion Sort.

    To achieve maximum performance (v5), the implementation uses the following strategies:

    1. Direct System Calls: Using getdents64() directly instead of standard library wrappers.
    2. Memory Alignment & Vectorization: To avoid the overhead of memcmp() checking unaligned pointers byte-by-byte, the implementation uses ByteSwap64 to align the first 8 bytes of the filename. This allows memcmp() to immediately utilize vectorized loops.
    3. Custom Sorting Logic: A custom comparator is used with std::sort that reads the first 64 bits of the filename as a uint64_t for rapid comparison, falling back to memcmp for the remaining bytes if the prefixes are equal.

    Performance Evolution

    versionoptimizationscore
    v1baseline100.0
    v2avoid heap allocations112.7
    v3open directories with openat()116.2
    v4call getdents64() directly137.8
    v5hand-optimize strcmp()143.3

    Final optimized versions spend approximately 97% of CPU time in the kernel, leaving minimal room for further userspace optimization.

    // Example of the v5 optimized sorting comparator logic
    sort(entries.begin(), entries.end(), [](const char* a, const char* b) {
      uint64_t x = Read64(a);
      uint64_t y = Read64(b);
      return x < y || (x == y && a != b && memcmp(a + 5, b + 5, 256) < 0);
    });
  8. Enable Instant Prompt to reduce Zsh startup lag

    master

    If your .zshrc loads slow plugins (like pyenv or nvm), Powerlevel10k's Instant Prompt feature can print the prompt immediately upon startup, allowing you to start typing while plugins continue to load in the background.

    You can enable this feature either through the p10k configure wizard or by manual configuration.

  9. Configure Instant Prompt

    master

    Instant prompt speeds up Zsh startup by rendering the prompt before the rest of the initialization is complete. You can enable it via p10k configure or by manually adding the preamble to the very top of your ~/.zshrc.

    Important Rules:

    1. Copy the preamble code verbatim.
    2. Any initialization code that requires console input (e.g., password prompts, [y/n] confirmations) must be placed above the instant prompt block.
    3. Code that only prints to the console (without reading input) can go below, but output might appear uncolored.

    Configuration Options (POWERLEVEL9K_INSTANT_PROMPT):

    • off: Completely disables instant prompt.
    • quiet: Silences warnings about console output during initialization (recommended if you have non-interactive print statements).
    • verbose (default): Prints a warning if console output is detected during initialization.
    # Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
    # Initialization code that may require console input (password prompts, [y/n]
    # confirmations, etc.) must go above this block; everything else may go below.
    if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
      source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
    fi
  10. Understand the performance optimizations of gitstatusd

    master

    gitstatusd is designed for high-performance git status reporting, significantly outperforming standard tools like libgit2 or git status in many scenarios. Its speed is derived from several key architectural choices:

    • Efficient System Calls: Instead of using lstat() (which requires path lookups for every subdirectory), it uses fstatat() and openat(), which operate relative to a parent directory file descriptor. This reduces CPU time in the kernel.
    • Parallelism: The diffing algorithm is designed for multi-threading, allowing it to utilize multiple CPU cores to scan the index and workdir in parallel with near-perfect scaling.
    • Untracked Cache: It remembers the last modification time of directories. On subsequent scans, if a directory's modification time hasn't changed, gitstatusd skips re-scanning it for untracked files.
    • Optimized Data Structures: It uses performance-conscious coding styles and efficient algorithms to reduce CPU time in userspace.
    • Direct System Calls: On Linux, it uses the getdents64 system call directly to bypass glibc wrappers, improving directory listing speed.
  11. Use `openat()` to reduce directory lookup overhead

    master

    Standard opendir() calls are expensive because they perform a full path lookup for every subdirectory. If the caller already holds a file descriptor to the parent directory, use openat() with flags like O_NOATIME, O_RDONLY, O_DIRECTORY, and O_CLOEXEC to perform a single lookup. This provides an additional ~3.5% speedup.

    void ListDir(int parent_fd, const char* dirname, string& arena, vector<char*>& entries) {
      entries.clear();
      int dir_fd = openat(parent_fd, dirname, O_NOATIME | O_RDONLY | O_DIRECTORY | O_CLOEXEC);
      if (dir_fd < 0) return;
      if (DIR* dir = fdopendir(dir_fd)) {
        // ... implementation using readdir ...
        closedir(dir);
      } else {
        close(dir_fd);
      }
    }