{"id":13594385,"url":"https://github.com/romkatv/zsh-defer","last_synced_at":"2025-04-06T02:12:06.170Z","repository":{"id":45574512,"uuid":"222927141","full_name":"romkatv/zsh-defer","owner":"romkatv","description":"Deferred execution of Zsh commands","archived":false,"fork":false,"pushed_at":"2024-02-10T06:30:37.000Z","size":96,"stargazers_count":380,"open_issues_count":0,"forks_count":11,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-30T01:11:15.236Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/romkatv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-11-20T11:57:11.000Z","updated_at":"2025-03-28T17:26:51.000Z","dependencies_parsed_at":"2024-01-03T04:16:32.877Z","dependency_job_id":"d2fe23e3-c5e8-4ac5-b80b-4743ee555f91","html_url":"https://github.com/romkatv/zsh-defer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romkatv%2Fzsh-defer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romkatv%2Fzsh-defer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romkatv%2Fzsh-defer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romkatv%2Fzsh-defer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/romkatv","download_url":"https://codeload.github.com/romkatv/zsh-defer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247423515,"owners_count":20936626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T16:01:32.670Z","updated_at":"2025-04-06T02:12:06.147Z","avatar_url":"https://github.com/romkatv.png","language":"Shell","funding_links":[],"categories":["Plugins","Shell"],"sub_categories":["ZSH on Windows"],"readme":"# zsh-defer: Deferred execution of zsh commands\n\n`zsh-defer` defers execution of a zsh command until zsh has nothing else to do and is waiting for\nuser input. Its intended purpose is staged zsh startup. It works similarly to *Turbo mode* in\n[zinit](https://github.com/zdharma-continuum/zinit).\n\nFeatures:\n\n- **Small and clean**: The API consists of a single function implemented in ~150 lines of\n  straightforward zsh.\n- **Fast to load**: It takes under 1ms to source `zsh-defer.plugin.zsh`.\n- **Easy to use**: `source slow.zsh` =\u003e `zsh-defer source slow.zsh`.\n- **Plugin manager agnostic**: Can be used with any plugin manager or even without one.\n\n## Table of Contents\n\n1. [Installation](#installation)\n1. [Usage](#usage)\n1. [Example](#example)\n1. [Caveats](#caveats)\n1. [FAQ](#faq)\n   1. [Is it possible to autoload zsh-defer?](#is-it-possible-to-autoload-zsh-defer)\n   1. [Is it possible to find out from within a command whether it's being executed by zsh-defer?](#is-it-possible-to-find-out-from-within-a-command-whether-its-being-executed-by-zsh-defer)\n   1. [Is zsh-defer a plugin manager?](#is-zsh-defer-a-plugin-manager)\n   1. [How useful is it?](#how-useful-is-it)\n   1. [Is zsh-defer compatible with Instant Prompt in Powerlevel10k?](#is-zsh-defer-compatible-with-instant-prompt-in-powerlevel10k)\n   1. [Can I use zsh-defer together with zinit?](#can-i-use-zsh-defer-together-with-zinit)\n   1. [How does zsh-defer compare to Turbo mode in zinit?](#how-does-zsh-defer-compare-to-turbo-mode-in-zinit)\n   1. [Why so many references to and comparisons with zinit?](#why-so-many-references-to-and-comparisons-with-zinit)\n\n## Installation\n\n1. Clone the repo.\n```zsh\ngit clone https://github.com/romkatv/zsh-defer.git ~/zsh-defer\n```\n2. Add the following line at the top of `~/.zshrc`:\n```zsh\nsource ~/zsh-defer/zsh-defer.plugin.zsh\n```\n\n*Using a plugin manager? You can install zsh-defer the same way as any other zsh plugin hosted on\nGitHub.*\n\n## Usage\n\n```text\nzsh-defer [{+|-}12dmshpr] [-t delay] word...\nzsh-defer [{+|-}12dmshpr] [-t delay] -c list\n```\n\nQueues up the specified command for deferred execution. Whenever zle is idle, the next command is\npopped from the queue. If the command has been queued up with `-t delay`, execution of the command\nand all deferred commands after it is delayed by the specified number of seconds (non-negative real\nnumber) without blocking zle. Duration can be specified in any format accepted by `sleep(1)`. After\nthat the command is executed either as `word...` with every word quoted, or, if `-c` is specified,\nas `eval list`. Commands are executed in the same order they are queued up.\n\nOptions can be used to enable (`+x`) or disable (`-x`) extra actions taken during and after the\nexecution of the command. By default, all actions are enabled. The same option can be enabled or\ndisabled more than once -- the last instance wins.\n\n| **Option** | **Action**                                                                                                    |\n| ---------- |---------------------------------------------------------------------------------------------------------------|\n| *1*        | Redirect standard output to `/dev/null`.                                                                      |\n| *2*        | Redirect standard error to `/dev/null`.                                                                       |\n| *d*        | Call `chpwd` hooks.                                                                                           |\n| *m*        | Call `precmd` hooks.                                                                                          |\n| *s*        | Invalidate suggestions from [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions).          |\n| *z*        | Invalidate highlighting from [zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting). |\n| *p*        | Call `zle reset-prompt`.                                                                                      |\n| *r*        | Call `zle -R`.                                                                                                |\n| *a*        | Shorthand for all options: *12dmszpr*.                                                                        |\n\n## Example\n\nHere's an example of `~/.zshrc` that uses `zsh-defer` to achieve staged zsh startup. When starting\nzsh, it takes only a few milliseconds for this `~/.zshrc` to be evaluated and for prompt to appear.\nAfter that, prompt and the command line buffer are refreshed and buffered keyboard input are\nprocessed after the execution of every deferred command.\n\n```zsh\nsource ~/zsh-defer/zsh-defer.plugin.zsh\n\nPS1=\"%F{12}%~%f \"\nRPS1=\"%F{240}loading%f\"\nsetopt promp_subst\n\nzsh-defer source ~/zsh-autosuggestions/zsh-autosuggestions.zsh\nzsh-defer source ~/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh\nzsh-defer source ~/.nvm/nvm.sh\nzsh-defer -c 'RPS1=\"%F{2}\\$(git rev-parse --abbrev-ref HEAD 2\u003e/dev/null)%f\"'\n```\n\nZsh startup without `zsh-defer`. Prompt appears once everything is loaded.\n\n![zsh startup without zsh-defer](https://raw.githubusercontent.com/romkatv/zsh-defer/master/docs/zsh-startup-without-defer.gif)\n\nZsh startup with `zsh-defer`. Prompt appears instantly and gets updated after every startup stage.\n\n![zsh startup with zsh-defer](https://raw.githubusercontent.com/romkatv/zsh-defer/master/docs/zsh-startup-with-defer.gif)\n\n1. zsh-autosuggestions is loaded: completion suggestion appears.\n2. zsh-highlighting is loaded: `nvm` in the command line turns red (no such command).\n3. nvm is loaded: `nvm` turns green (recognized command).\n4. `RPS1` is set: the name of the current Git branch appears.\n\n## Caveats\n\n`zsh-defer` executes commands from zle. This has several ramifications.\n\n- Commands cannot read standard input. Thus, commands that may require keyboard input should not be\n  deferred.\n- Output from commands can be invisible and can cause prompt to be reprinted. This is the reason\n  why `zsh-defer` redirects standard output and standard error to `/dev/null` by default. This\n  behavior can be disabled with `+1` and `+2`.\n- Some plugins don't expect to be sourced from zle and may fail to properly initialize.\n  - Corollary: It's often necessary to rely on implementation details of plugins in order to load\n    them from zle. This exposes the user to much higher risk of breakage when updating plugins.\n    The default options in `zsh-defer` can help you sidestep these issues in many cases but not\n    always.\n\n`zsh-defer` executes commands in function scope with `LOCAL_OPTIONS`, `LOCAL_PATTERNS` and\n`LOCAL_TRAPS` options. This can break initialization scripts that use `typeset` without explicit\n`-g`, set options, change patterns or install traps.\n\n## FAQ\n\n### Is it possible to autoload zsh-defer?\n\nYes.\n\nInstead of this:\n\n```zsh\nsource ~/zsh-defer/zsh-defer.plugin.zsh\n```\n\nYou can do this:\n\n```zsh\nautoload -Uz ~/zsh-defer/zsh-defer\n```\n\n### Is it possible to find out from within a command whether it's being executed by zsh-defer?\n\nYes. Check whether `zsh_defer_options` parameter is set.\n\n```zsh\nfunction say-hi() {\n  if (( $+zsh_defer_options )); then\n    echo \"Hello from zsh-defer with options: $zsh_defer_options\" \u003e\u003e/tmp/log\n  else\n    echo \"Hello from without zsh-defer\" \u003e\u003e/tmp/log\n  fi\n}\n\nsay-hi            # Hello from without zsh-defer\nzsh-defer say-hi  # Hello from zsh-defer with options: 12dmshp\n```\n\n### Is zsh-defer a plugin manager?\n\nNo. `zsh-defer` is a function that allows you to defer execution of zsh commands. You can use it\non its own or with a plugin manager.\n\n### How useful is it?\n\n[About as useful](https://github.com/romkatv/zsh-bench#deferred-initialization) as Turbo mode in\nzinit.\n\n### Is zsh-defer compatible with Instant Prompt in Powerlevel10k?\n\nYes. Although if you are using [Powerlevel10k](https://github.com/romkatv/powerlevel10k/) with\n[Instant Prompt](https://github.com/romkatv/zsh-bench#instant-prompt) you almost certainly don't\nneed to use deferred loading of any kind.\n\n### Can I use zsh-defer together with zinit?\n\nYes, both ways.\n\nYou can load `zsh-defer` with zinit the same way as any other plugin.\n\n```zsh\nzinit light romkatv/zsh-defer\n```\n\nYou can defer a `zinit` command with `zsh-defer` the same way as any other command.\n\n```zsh\nzsh-defer zinit light zsh-users/zsh-autosuggestions\nzsh-defer zinit light zsh-users/zsh-syntax-highlighting\n```\n\n### How does zsh-defer compare to Turbo mode in zinit?\n\nThey are quite similar. Both allow you to defer execution of a zsh command and both execute the\ncommand from zle, with all the [negative consequences](#caveats) that this entails.\n\n`zsh-defer` is most useful to those who don't use zinit as it gives them access to Turbo mode that\nthey otherwise didn't have. However, there are also a few minor benefits to using\n`zsh-defer zinit light` compared to the builtin Turbo mode:\n\n- `zsh-defer` guarantees that all buffered keyboard input gets processed before every deferred\n  command.\n- The argument of `-t` can be fractional.\n- The default options of `zsh-defer` are fairly effective at mitigating the\n  [negative side effects](#caveats) of deferred loading.\n- Options provide full flexibility that hardcore zsh users might desire.\n- `zsh-defer` has a short and easy-to-understand implementation.\n\n*Has zinit closed the gap on one or more of these points? Please send a PR removing them from the\nlist.*\n\nOn the other hand, `zinit ice wait` has its own advantages:\n\n- *I don't know any. Please help expanding this section.*\n\n### Why so many references to and comparisons with zinit?\n\nTurbo mode in zinit is the only other robust implementation of deferred zsh command execution that\nI'm aware of. There is also `zsh/sched` but it's underpowered by comparison.\n\nNote that `zsh-defer` is not a plugin manager and thus not an alternative to zinit.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromkatv%2Fzsh-defer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromkatv%2Fzsh-defer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromkatv%2Fzsh-defer/lists"}