mirror of
https://github.com/jimeh/dotfiles.git
synced 2026-02-19 11:06:41 +00:00
feat(shell): create cached-eval helper to improve shell startup speed.
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
if command-exists zoxide; then
|
if command-exists zoxide; then
|
||||||
eval "$(zoxide init --cmd zox zsh)"
|
cached-eval "$(command -v zoxide)" zoxide init --cmd zox zsh
|
||||||
|
|
||||||
# Use functions to allow regular zsh completion for cd to work.
|
# Use functions to allow regular zsh completion for cd to work.
|
||||||
cd() { __zoxide_z "$@"; }
|
cd() { __zoxide_z "$@"; }
|
||||||
|
|||||||
51
zshenv
51
zshenv
@@ -74,6 +74,54 @@ source-if-exists() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# cached-eval executes a command with arguments and caches the output. On
|
||||||
|
# subsequent calls, if the source file has not changed, the output is sourced
|
||||||
|
# from the cache instead of re-executing the command. This optimizes performance
|
||||||
|
# for commands that are costly to execute but result in the same output unless
|
||||||
|
# their source files change.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
#
|
||||||
|
# $1 - source_file: The path to the source file that the command depends on.
|
||||||
|
# If this file is newer than the cache, the command is
|
||||||
|
# re-executed and the cache is updated.
|
||||||
|
# $2 - cmd: The command to execute.
|
||||||
|
# $@ - args: Additional arguments to pass to the command.
|
||||||
|
#
|
||||||
|
# Example usage:
|
||||||
|
#
|
||||||
|
# cached-eval "$(command -v direnv)" direnv hook zsh
|
||||||
|
# cached-eval "$(command -v mise)" mise activate zsh
|
||||||
|
#
|
||||||
|
# The above commands will cache the output of `direnv hook zsh` and `mise
|
||||||
|
# activate zsh` respectively. If the source file is newer than the cache, the
|
||||||
|
# command is re-executed and cache is updated.
|
||||||
|
cached-eval() {
|
||||||
|
local source_file="$1"
|
||||||
|
local cmd="$2"
|
||||||
|
shift 2
|
||||||
|
local args="$@"
|
||||||
|
local full_cmd="$cmd $args"
|
||||||
|
local cache_dir="${ZSH_CACHED_EVAL_DIR:-$HOME/.local/share/zsh/cached-eval}"
|
||||||
|
|
||||||
|
if [[ -z "$(command -v "$cmd")" ]]; then
|
||||||
|
echo "cached-eval: Command not found: $cmd" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local cache_hash="$(echo -n "$full_cmd" | md5sum | awk '{print $1}')"
|
||||||
|
local cache_file="${cache_dir}/$(basename "$cmd")_${cache_hash}.zsh"
|
||||||
|
|
||||||
|
if [[ ! -f "$cache_file" || "$source_file" -nt "$cache_file" ]]; then
|
||||||
|
mkdir -p "$cache_dir"
|
||||||
|
echo "cached-eval: Updating cache for: $full_cmd --> $cache_file" >&2
|
||||||
|
echo -e "#\n# Generated by cached-eval: $full_cmd\n#\n" >| "$cache_file"
|
||||||
|
eval "$full_cmd" >>| "$cache_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "$cache_file"
|
||||||
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# System Environment Setup
|
# System Environment Setup
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -98,6 +146,7 @@ fi
|
|||||||
|
|
||||||
export DOTZSH_SITEFUNS="$DOTZSH/site-functions"
|
export DOTZSH_SITEFUNS="$DOTZSH/site-functions"
|
||||||
export ZSH_COMPLETIONS="$HOME/.local/share/zsh/completions"
|
export ZSH_COMPLETIONS="$HOME/.local/share/zsh/completions"
|
||||||
|
export ZSH_CACHED_EVAL_DIR="$HOME/.local/share/zsh/cached-eval"
|
||||||
|
|
||||||
# Ensure basic systems paths are in desired order
|
# Ensure basic systems paths are in desired order
|
||||||
path_prepend "/bin"
|
path_prepend "/bin"
|
||||||
@@ -129,7 +178,7 @@ fi
|
|||||||
|
|
||||||
# Homebrew on Apple Silicon
|
# Homebrew on Apple Silicon
|
||||||
if [ -f "/opt/homebrew/bin/brew" ]; then
|
if [ -f "/opt/homebrew/bin/brew" ]; then
|
||||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
cached-eval /opt/homebrew/bin/brew /opt/homebrew/bin/brew shellenv
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command-exists brew; then
|
if command-exists brew; then
|
||||||
|
|||||||
134
zshrc
134
zshrc
@@ -52,58 +52,72 @@ zinit light-mode wait lucid atload"!_zsh_autosuggest_start" \
|
|||||||
for @zsh-users/zsh-autosuggestions
|
for @zsh-users/zsh-autosuggestions
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Completion
|
# Helpers
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# Group completions by type under group headings
|
# setup-completions is a helper function to set up shell completions for a given
|
||||||
zstyle ':completion:*' group-name ''
|
# command. It generates Zsh completion scripts and places them in the specified
|
||||||
zstyle ':completion:*:descriptions' format '%B%d%b'
|
# completions directory. If the completion file already exists, it checks if the
|
||||||
|
# source file has been updated and regenerates the completions if necessary.
|
||||||
# Improve selection of Makefile completions - from:
|
|
||||||
# https://github.com/zsh-users/zsh-completions/issues/541#issuecomment-384223016
|
|
||||||
zstyle ':completion:*:make:*:targets' call-command true
|
|
||||||
zstyle ':completion:*:make:*' tag-order targets
|
|
||||||
|
|
||||||
if [ -d "$ZSH_COMPLETIONS" ]; then fpath=("$ZSH_COMPLETIONS" $fpath); fi
|
|
||||||
if [ -d "$DOTZSH_SITEFUNS" ]; then fpath=("$DOTZSH_SITEFUNS" $fpath); fi
|
|
||||||
if [ -d "$BREW_SITEFUNS" ]; then fpath=("$BREW_SITEFUNS" $fpath); fi
|
|
||||||
|
|
||||||
autoload -Uz compinit
|
|
||||||
compinit
|
|
||||||
|
|
||||||
# setup-completions is a helper function to setup completions for a given
|
|
||||||
# command. It takes the command name, the source of the completion, and the
|
|
||||||
# command to run to generate the completions.
|
|
||||||
#
|
#
|
||||||
# Source should be a file that the completions are generated from. For example,
|
# Arguments:
|
||||||
# for rustup, the source is the rustup binary. If completions file has already
|
|
||||||
# been generated, the source file is used to determine if the completions need
|
|
||||||
# to be re-generated.
|
|
||||||
#
|
#
|
||||||
# The command to run to generate the completions should be a command that
|
# $1 - cmd: The name of the command for which completions are being
|
||||||
# generates zsh completions. For example, for rustup, the command is:
|
# set up.
|
||||||
#
|
# $2 - source: The source file used to determine if completions need to
|
||||||
# rustup completions zsh
|
# be re-generated. For example, the binary file of the
|
||||||
|
# command (e.g., rustup).
|
||||||
|
# $@ - args: The command to run to generate the completions. This
|
||||||
|
# should produce Zsh completion scripts.
|
||||||
#
|
#
|
||||||
# Example usage:
|
# Example usage:
|
||||||
#
|
#
|
||||||
# setup-completions rustup "$(command -v rustup)" rustup completions zsh
|
# setup-completions rustup "$(command -v rustup)" rustup completions zsh
|
||||||
#
|
#
|
||||||
# This will generate the completions for rustup and place them in the
|
# This example sets up completions for the 'rustup' command by running
|
||||||
# ZSH_COMPLETIONS directory.
|
# 'rustup completions zsh', and places the generated completion script in the
|
||||||
|
# appropriate completions directory. If the source file is newer than the target
|
||||||
|
# completion file, the command is re-executed and the completion script is
|
||||||
|
# updated.
|
||||||
|
#
|
||||||
|
# The completions are placed in the directory specified by the ZSH_COMPLETIONS
|
||||||
|
# environment variable. If ZSH_COMPLETIONS is not set, the completions are
|
||||||
|
# placed in $HOME/.zsh/completions by default.
|
||||||
setup-completions() {
|
setup-completions() {
|
||||||
local cmd="$1"
|
local cmd="$1"
|
||||||
local source="$2"
|
local source="$2"
|
||||||
shift 2
|
local setup_cmd="$3"
|
||||||
local target
|
shift 3
|
||||||
target="${ZSH_COMPLETIONS}/_${cmd}"
|
|
||||||
|
|
||||||
if [ ! -f "$target" ] || [ "$target" -ot "$source" ]; then
|
local target_dir="${ZSH_COMPLETIONS:-$HOME/.zsh/completions}"
|
||||||
echo "Setting up completion for $cmd -- $target"
|
local target_file="${target_dir}/_${cmd}"
|
||||||
mkdir -p "$(dirname "$target")"
|
|
||||||
"$@" > "$target"
|
if [[ -z "$(command -v "$cmd")" ]]; then
|
||||||
chmod +x "$target"
|
echo "setup-completions: Command not found: $cmd" >&2
|
||||||
autoload -U compinit && compinit
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$(command -v "$setup_cmd")" ]]; then
|
||||||
|
echo "setup-completions: Command not found: $setup_cmd" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$cmd" || -z "$source" || -z "$setup_cmd" ]]; then
|
||||||
|
echo "setup-completions: Missing required arguments." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the target completion file needs to be updated
|
||||||
|
if [[ ! -f "$target_file" || "$source" -nt "$target_file" ]]; then
|
||||||
|
echo "setup-completions: Setting up completion for $cmd --> $target_file" >&2
|
||||||
|
mkdir -p "$target_dir"
|
||||||
|
"$setup_cmd" "$@" >| "$target_file"
|
||||||
|
chmod +x "$target_file"
|
||||||
|
|
||||||
|
# Only run compinit if not already loaded
|
||||||
|
if ! (whence -w compinit &> /dev/null); then
|
||||||
|
autoload -U compinit && compinit
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +189,26 @@ convert-alias-to-function() {
|
|||||||
eval "$(convert-alias-source-to-function-source "$alias_source")"
|
eval "$(convert-alias-source-to-function-source "$alias_source")"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# Completion
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
# Group completions by type under group headings
|
||||||
|
zstyle ':completion:*' group-name ''
|
||||||
|
zstyle ':completion:*:descriptions' format '%B%d%b'
|
||||||
|
|
||||||
|
# Improve selection of Makefile completions - from:
|
||||||
|
# https://github.com/zsh-users/zsh-completions/issues/541#issuecomment-384223016
|
||||||
|
zstyle ':completion:*:make:*:targets' call-command true
|
||||||
|
zstyle ':completion:*:make:*' tag-order targets
|
||||||
|
|
||||||
|
if [ -d "$ZSH_COMPLETIONS" ]; then fpath=("$ZSH_COMPLETIONS" $fpath); fi
|
||||||
|
if [ -d "$DOTZSH_SITEFUNS" ]; then fpath=("$DOTZSH_SITEFUNS" $fpath); fi
|
||||||
|
if [ -d "$BREW_SITEFUNS" ]; then fpath=("$BREW_SITEFUNS" $fpath); fi
|
||||||
|
|
||||||
|
autoload -Uz compinit
|
||||||
|
compinit
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Edit command line
|
# Edit command line
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -197,7 +231,7 @@ fi
|
|||||||
|
|
||||||
# If available, make sure to load direnv shell hook before mise.
|
# If available, make sure to load direnv shell hook before mise.
|
||||||
if command-exists direnv; then
|
if command-exists direnv; then
|
||||||
eval "$(direnv hook zsh)"
|
cached-eval "$(command -v direnv)" direnv hook zsh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MISE_HOME="$HOME/.local/share/mise"
|
MISE_HOME="$HOME/.local/share/mise"
|
||||||
@@ -205,19 +239,14 @@ MISE_ZSH_INIT="$MISE_HOME/shell/init.zsh"
|
|||||||
export MISE_INSTALL_PATH="$MISE_HOME/bin/mise"
|
export MISE_INSTALL_PATH="$MISE_HOME/bin/mise"
|
||||||
|
|
||||||
if ! command-exists mise; then
|
if ! command-exists mise; then
|
||||||
read -q 'REPLY?mise is not installed, install with `curl https://mise.jdx.dev/install.sh | sh`? [y/N]:' &&
|
read -q 'REPLY?mise is not installed, install with `curl https://mise.run | sh`? [y/N]:' &&
|
||||||
echo && curl https://mise.jdx.dev/install.sh | sh
|
echo && curl https://mise.run | sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command-exists mise; then
|
if command-exists mise; then
|
||||||
alias mi="mise"
|
alias mi="mise"
|
||||||
|
|
||||||
if [ ! -f "$MISE_ZSH_INIT" ] || [ "$MISE_ZSH_INIT" -ot "$MISE_INSTALL_PATH" ]; then
|
cached-eval "$MISE_INSTALL_PATH" mise activate zsh
|
||||||
mkdir -p "$(dirname "$MISE_ZSH_INIT")"
|
|
||||||
"$MISE_INSTALL_PATH" activate zsh > "$MISE_ZSH_INIT"
|
|
||||||
fi
|
|
||||||
source "$MISE_ZSH_INIT"
|
|
||||||
|
|
||||||
setup-completions mise "$MISE_INSTALL_PATH" mise completions zsh
|
setup-completions mise "$MISE_INSTALL_PATH" mise completions zsh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -231,13 +260,8 @@ if ! command-exists starship && [ -f "$MISE_INSTALL_PATH" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if command-exists starship; then
|
if command-exists starship; then
|
||||||
eval "$(starship init zsh --print-full-init)"
|
cached-eval "$(command -v starship)" starship init zsh --print-full-init
|
||||||
|
setup-completions starship "$(command -v starship)" starship completions zsh
|
||||||
_starship() {
|
|
||||||
unset -f _starship
|
|
||||||
eval "$(starship completions zsh)"
|
|
||||||
}
|
|
||||||
compctl -K _starship starship
|
|
||||||
else
|
else
|
||||||
echo "WARN: starship not found, skipping prompt setup" >&2
|
echo "WARN: starship not found, skipping prompt setup" >&2
|
||||||
echo " install with: mise install starship" >&2
|
echo " install with: mise install starship" >&2
|
||||||
|
|||||||
Reference in New Issue
Block a user