first commit
This commit is contained in:
commit
ce6d203365
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Matthew Rothenberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
82
README.md
Normal file
82
README.md
Normal file
@ -0,0 +1,82 @@
|
||||
# evalcache
|
||||
|
||||
> zsh plugin to cache the output of a binary initialization command, intended
|
||||
> to help lower shell startup time.
|
||||
|
||||
## What it does
|
||||
|
||||
There are lots of shell wrapper tools that follow the pattern of asking you to
|
||||
eval a specific init command in your shell startup, for example, rbenv asks:
|
||||
|
||||
eval "$(hub alias -s)"
|
||||
|
||||
While this is very convenient, the reality is there is a small amount of
|
||||
overhead associated with shelling out to this, and the output is almost always
|
||||
actually static in all of the tools I know. So why bear this cost every time
|
||||
you open a new tab in your shell?
|
||||
|
||||
Instead, after you load this plugin, you can replace that same command with:
|
||||
|
||||
_evalcache hub alias -s
|
||||
|
||||
The first time this runs, it will cache the output of the command to a file,
|
||||
which will be sourced in the future instead when it exists.
|
||||
|
||||
If you update a tool and expect for some reason that it's initialization might
|
||||
have changed, you can simply clear the cache and it will be regenerated.
|
||||
|
||||
It also gracefully degrades to a no-op if the tool is no longer installed.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Some informal benchmarks from my MacBook on my .zshrc:
|
||||
|
||||
| command | without | first run | subsequent runs | savings |
|
||||
| ------------ | ------: | --------: | --------------: | ------: |
|
||||
| rbenv init | ~65ms | ~65ms | ~8ms | 88% |
|
||||
| hub alias | ~30ms | ~30ms | ~6ms | 80% |
|
||||
| scmpuff init | ~24ms | ~25ms | ~10ms | 58% |
|
||||
|
||||
The difference isn't huge, but can be handy in shaving down shell startup time,
|
||||
especially if you use a bunch of these tools. Every millisecond counts!
|
||||
|
||||
## Options
|
||||
|
||||
- `$ZSH_EVALCACHE_DIR`: cache files storage, default `$HOME/.zsh-evalcache`.
|
||||
- `$ZSH_EVALCACHE_DISABLE`: set to `true` if you wish to bypass evalcache.
|
||||
|
||||
There is a convenience function to clear the cache called `_evalcache_clear`.
|
||||
|
||||
## Installation
|
||||
|
||||
### [Antigen](https://github.com/zsh-users/antigen)
|
||||
|
||||
Add `antigen bundle mroth/evalcache` to your `.zshrc` with your other bundle commands.
|
||||
|
||||
Antigen will handle cloning the plugin for you automatically the next time you start zsh. You can also add the plugin to a running zsh with `antigen bundle mroth/evalcache` for testing before adding it to your `.zshrc`.
|
||||
|
||||
### [Fig](https://fig.io)
|
||||
|
||||
Fig adds apps, shortcuts, and autocomplete to your existing terminal.
|
||||
|
||||
Install `evalcache` in just one click.
|
||||
|
||||
<a href="https://fig.io/plugins/other/evalcache_mroth" target="_blank"><img src="https://fig.io/badges/install-with-fig.svg" /></a>
|
||||
|
||||
### [Oh-My-Zsh](http://ohmyz.sh/)
|
||||
|
||||
1. Clone this repository into `$ZSH_CUSTOM/plugins` (by default `~/.oh-my-zsh/custom/plugins`)
|
||||
|
||||
```sh
|
||||
git clone https://github.com/mroth/evalcache ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/evalcache
|
||||
```
|
||||
|
||||
2. Edit `~/.zshrc` to add _evalcache_ to your plugin list,
|
||||
```diff
|
||||
- plugins=(...)
|
||||
+ plugins=(... evalcache)
|
||||
```
|
||||
|
||||
### [Zgen](https://github.com/tarjoilija/zgen)
|
||||
|
||||
Add `zgen load mroth/evalcache` to your `.zshrc` file in the same function you're doing your other `zgen load` calls in. Zgen will handle automatically cloning the plugin for you the next time you do a `zgen save`.
|
||||
50
evalcache.plugin.zsh
Normal file
50
evalcache.plugin.zsh
Normal file
@ -0,0 +1,50 @@
|
||||
# Caches the output of a binary initialization command, to avoid the time to
|
||||
# execute it in the future.
|
||||
#
|
||||
# Usage: _evalcache [NAME=VALUE]... COMMAND [ARG]...
|
||||
|
||||
# default cache directory
|
||||
export ZSH_EVALCACHE_DIR=${ZSH_EVALCACHE_DIR:-"$HOME/.zsh-evalcache"}
|
||||
|
||||
function _evalcache () {
|
||||
local cmdHash="nohash" data="$*" name
|
||||
|
||||
# use the first non-variable argument as the name
|
||||
for name in $@; do
|
||||
if [ "${name}" = "${name#[A-Za-z_][A-Za-z0-9_]*=}" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# if command is a function, include its definition in data
|
||||
if typeset -f "${name}" > /dev/null; then
|
||||
data=${data}$(typeset -f "${name}")
|
||||
fi
|
||||
|
||||
if builtin command -v md5 > /dev/null; then
|
||||
cmdHash=$(echo -n "${data}" | md5)
|
||||
elif builtin command -v md5sum > /dev/null; then
|
||||
cmdHash=$(echo -n "${data}" | md5sum | cut -d' ' -f1)
|
||||
fi
|
||||
|
||||
local cacheFile="$ZSH_EVALCACHE_DIR/init-${name##*/}-${cmdHash}.sh"
|
||||
|
||||
if [ "$ZSH_EVALCACHE_DISABLE" = "true" ]; then
|
||||
eval ${(q)@}
|
||||
elif [ -s "$cacheFile" ]; then
|
||||
source "$cacheFile"
|
||||
else
|
||||
if type "${name}" > /dev/null; then
|
||||
echo "evalcache: ${name} initialization not cached, caching output of: $*" >&2
|
||||
mkdir -p "$ZSH_EVALCACHE_DIR"
|
||||
eval ${(q)@} > "$cacheFile"
|
||||
source "$cacheFile"
|
||||
else
|
||||
echo "evalcache: ERROR: ${name} is not installed or in PATH" >&2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function _evalcache_clear () {
|
||||
rm -i "$ZSH_EVALCACHE_DIR"/init-*.sh
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user