Skip to content

Instantly share code, notes, and snippets.

@mehalter
Last active March 19, 2024 22:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mehalter/2809925b6e266b3574c7deab3dae711a to your computer and use it in GitHub Desktop.
Save mehalter/2809925b6e266b3574c7deab3dae711a to your computer and use it in GitHub Desktop.
Sharable ZSH Configuration
# assumed commands:
# git (plugin management)
# wget (downloading preview script)
# bat (tab preview)
# delta (tab preview)
# w3m (tab preview)
# bsdtar (tab preview)
# jq (tab preview)
# mediainfo (tab preview)
# odt2txt (tab preview)
# --- powerlevel10k instant prompt ---
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
# --- zsh data directories ---
zsh_data="${XDG_DATA_HOME:-$HOME/.local/share}/zsh"
[ ! -d ${zsh_data} ] && mkdir -p ${zsh_data}
zsh_cache="${XDG_CACHE_HOME:-$HOME/.cache}/zsh"
[ ! -d ${zsh_cache} ] && mkdir -p ${zsh_cache}
zsh_plugins="${zsh_data}/plugins"
[ ! -d ${zsh_plugins} ] && mkdir -p ${zsh_plugins}
# --- minimal zsh plugin manager ---
function zsh_install_missing_plugins() {
function zcompile-many() { local f; for f; do zcompile -R -- "$f".zwc "$f"; done }
function clone-plugin() {
local plugin="$(basename ${1})"
echo "Installing ${plugin}"
git clone --quiet --depth=1 "${1}.git" ${zsh_plugins}/${plugin} > /dev/null
}
# clone plugins, add more plugin downloads here with optional compilation calls to improve startup
if [[ ! -e ${zsh_plugins}/zsh-completions ]]; then
clone-plugin "https://github.com/zsh-users/zsh-completions"
fi
if [[ ! -e ${zsh_plugins}/fzf-tab ]]; then
clone-plugin "https://github.com/Aloxaf/fzf-tab"
zcompile-many ${zsh_plugins}/fzf-tab/*.zsh
fi
if [[ ! -e ${zsh_plugins}/zsh-syntax-highlighting ]]; then
clone-plugin "https://github.com/zsh-users/zsh-syntax-highlighting"
zcompile-many ${zsh_plugins}/zsh-syntax-highlighting/{zsh-syntax-highlighting.zsh,highlighters/*/*.zsh}
fi
if [[ ! -e ${zsh_plugins}/zsh-autosuggestions ]]; then
clone-plugin "https://github.com/zsh-users/zsh-autosuggestions"
zcompile-many ${zsh_plugins}/zsh-autosuggestions/{zsh-autosuggestions.zsh,src/**/*.zsh}
fi
if [[ ! -e ${zsh_plugins}/zsh-nvm ]]; then
clone-plugin "https://github.com/lukechilds/zsh-nvm"
zcompile-many ${zsh_plugins}/zsh-nvm/zsh-nvm.plugin.zsh
fi
if [[ ! -e ${zsh_plugins}/powerlevel10k ]]; then
clone-plugin "https://github.com/romkatv/powerlevel10k"
make -C ${zsh_plugins}/powerlevel10k pkg > /dev/null || echo "Error building powerlevel10k"
fi
unfunction zcompile-many clone-plugin
}
# --- zsh plugin manager updater ---
function zsh_update_plugins() { rm -rf ${zsh_plugins}/**; zsh_install_missing_plugins }
# --- install zsh plugins ---
zsh_install_missing_plugins
# --- configure zsh options ---
setopt autocd
setopt bash_rematch
setopt correct
setopt hist_ignore_all_dups
setopt hist_ignore_space
setopt hist_reduce_blanks
setopt hist_verify
setopt inc_append_history
setopt interactivecomments
export HISTIGNORE="&:ls:[bf]g:exit:reset:clear:cd:cd ..:cd.."
export HISTSIZE=25000
export HISTFILE="${XDG_STATE_HOME-$HOME/.local/state}/zsh/history"
export SAVEHIST=10000
export KEYTIMEOUT=10
# --- setup fzf ---
export FZF_HOME=${XDG_CONFIG_HOME:-$HOME/.config}/fzf
if [ ! -d ${FZF_HOME} ]; then
git clone --depth 1 https://github.com/junegunn/fzf.git ${FZF_HOME}
${FZF_HOME}/install --xdg --no-update-rc
fi
function zsh_update_fzf() {
if test "$(git -C ${FZF_HOME} rev-parse HEAD)" = "$(git -C ${FZF_HOME} rev-parse master)"; then
echo "No updates for FZF"
else
echo "Pulling the latest FZF..."
git -C ${FZF_HOME} reset --hard master
git -C ${FZF_HOME} pull
echo "Updating FZF..."
${FZF_HOME}/install
fi
}
[ -f "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.zsh ] && source "${XDG_CONFIG_HOME:-$HOME/.config}"/fzf/fzf.zsh
export FZF_DEFAULT_OPTS="--extended"
export FZF_DEFAULT_COMMAND="fd --type f --hidden --follow"
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
# --- completion ---
autoload -Uz compinit
comp_cache=${zsh_cache}/zcompdump-${ZSH_VERSION}
compinit -d ${comp_cache}
[[ ${comp_cache}.zwc -nt ${comp_cache} ]] || zcompile -R -- "${comp_cache}".zwc "${comp_cache}" # compile completion cache
zstyle ':completion:*' cache-path ${zsh_cache} # cache path
zstyle ':completion:*' menu select # select completions with arrow keys
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} # use ls colors
zstyle ':completion:*' completer _complete # approximate completion matches
zstyle ':completion:*' matcher-list '' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' '+l:|=* r:|=*' # case insensitive, partial word, substring
zstyle ':completion::complete:*' use-cache 1 # use cache
zstyle ':completion:*:git-checkout:*' sort false # don't sort git checkout
zstyle ':completion:*:descriptions' format '[%d]' # enable group supported descriptions
# === PLUGINS ===
# --- fzf-tab ---
source ${zsh_plugins}/fzf-tab/fzf-tab.plugin.zsh
# download preview script if it doesn't exist
if [ ! -f ${HOME}/.local/bin/preview ]; then
mkdir -p ${HOME}/.local/bin
wget -O ${HOME}/.local/bin/preview -- \
https://gist.githubusercontent.com/mehalter/2809925b6e266b3574c7deab3dae711a/raw/1d8f001c871af3bfc5139260ed7f1301929df15a/preview
chmod +x ${HOME}/.local/bin/preview
fi
zstyle ':fzf-tab:*' switch-group ',' '.' # switch groups with ,/.
zstyle ':fzf-tab:complete:*:options' fzf-preview # disable options preview
zstyle ':fzf-tab:complete:*:argument-1' fzf-preview # disable subcommand preview
zstyle ':fzf-tab:complete:(nvapp|pg|pd|pe|td|te):*' fzf-preview # disable preview for my own zsh completion
zstyle ':fzf-tab:complete:-command-:*' fzf-preview '(out=$(MANWIDTH=$FZF_PREVIEW_COLUMNS man "$word") 2>/dev/null && echo $out) || (out=$(which "$word") && echo $out) || echo "${(P)word}"'
zstyle ':fzf-tab:complete:*:*' fzf-preview 'preview ${(Q)realpath}'
zstyle ':fzf-tab:complete:systemctl-*:*' fzf-preview 'SYSTEMD_COLORS=1 systemctl status $word'
zstyle ':fzf-tab:complete:(-command-|-parameter-|-brace-parameter-|export|unset|expand):*' fzf-preview 'echo ${(P)word}'
zstyle ':fzf-tab:complete:git-log:*' fzf-preview 'git log --color=always $word'
zstyle ':fzf-tab:complete:git-help:*' fzf-preview 'git help $word | bat -plman --color=always'
zstyle ':fzf-tab:complete:git-(add|diff|restore):*' fzf-preview 'git diff $word | delta'
zstyle ':fzf-tab:complete:git-show:*' fzf-preview \
'case "$group" in
"commit tag") git show --color=always $word ;;
*) git show --color=always $word | delta ;;
esac'
zstyle ':fzf-tab:complete:git-checkout:*' fzf-preview \
'case "$group" in
"modified file") git diff $word | delta ;;
"recent commit object name") git show --color=always $word | delta ;;
*) git log --color=always $word ;;
esac'
# --- zsh-syntax-highlighting ---
source ${zsh_plugins}/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
# --- zsh-autosuggestions ---
source ${zsh_plugins}/zsh-autosuggestions/zsh-autosuggestions.zsh
# --- nvm ---
_default_node_ver=16.19.1 # set default node version
export NVM_DIR=${XDG_DATA_HOME:-$HOME/.local/share}/nvm
NVM_LAZY_LOAD=true source ${zsh_plugins}/zsh-nvm/zsh-nvm.plugin.zsh
if [ ! -d ${NVM_DIR}/versions/node/v${_default_node_ver} ]; then
nvm install ${_default_node_ver} && nvm use ${_default_node_ver}
fi
path=(${NVM_DIR}/versions/node/v${_default_node_ver}/bin $path)
unfunction npm node npx corepack # don't lazy load node, just nvm
# --- powerlevel10k prompt ---
source ${zsh_plugins}/powerlevel10k/powerlevel10k.zsh-theme
[ -f ${ZDOTDIR:-$HOME}/.p10k.zsh ] && source ${ZDOTDIR:-$HOME}/.p10k.zsh
# === END PLUGINS ===
# --- keybindings ---
autoload -Uz edit-command-line
function zle-keymap-select() { zle reset-prompt; zle -R }
zle -N edit-command-line
zle -N zle-keymap-select
bindkey -v
if [[ $TERM == tmux* ]]; then
bindkey '^[[1~' beginning-of-line
bindkey '^[[4~' end-of-line
else
bindkey '^[[H' beginning-of-line
bindkey '^[[F' end-of-line
fi
bindkey '^[[3~' delete-char
bindkey -M viins '^a' vi-beginning-of-line
bindkey -M viins '^e' vi-end-of-line
bindkey -M viins '^k' kill-line
bindkey -M vicmd '?' history-incremental-search-backward
bindkey -M vicmd '/' history-incremental-search-forward
bindkey "^?" backward-delete-char
bindkey '^x^e' edit-command-line
bindkey '^ ' autosuggest-accept
# expand ... to ../.. recursively
function _rationalise-dot { # This was written entirely by Mikael Magnusson (Mikachu)
local MATCH # keep the regex match from leaking to the environment
if [[ $LBUFFER =~ '(^|/| | |'$'\n''|\||;|&)\.\.$' ]]; then
LBUFFER+=/
zle self-insert
zle self-insert
else
zle self-insert
fi
}
zle -N _rationalise-dot
bindkey . _rationalise-dot
bindkey -M isearch . self-insert # without this, typing . aborts incr history search
# --- configure path ---
path=(
$HOME/.local/bin,
# add more directories to the path if you want
$path
)
# --- source various other scripts ---
# source ${ZDOTDIR:-$HOME}/.aliases
# --- miscellaneous ---
# # configure nvim as manpager (requires neovim-remote)
# if [ -n "${NVIM_LISTEN_ADDRESS+x}" ] || [ -n "${NVIM+x}" ]; then
# export MANPAGER="nvr -c 'Man!' -o -"
# else
# export MANPAGER="nvim -c 'Man!'"
# fi
#! /usr/bin/env sh
case $(file -bL --mime-type "$1") in
cannot\ open*) exit ;;
inode/directory) ls --color=always "$1" ;;
text/html) w3m -O UTF-8 -dump "$1" ;;
text/troff) man ./"$1" ;;
application/gzip | application/x-tar | application/zip | application/x-7z-compressed | application/vnd.rar | application/x-bzip*) bsdtar --list --file "$1" ;;
application/json) jq --color-output . "$1" ;;
audio/* | image/* | application/octet-stream) mediainfo "$1" || exit 1 ;;
*opendocument*) odt2txt "$1" ;;
application/pgp-encrypted) gpg -d -- "$1" ;;
text/* | */xml) bat --style="plain" --color=always "$1" ;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment