Skip to content

Instantly share code, notes, and snippets.

@mehalter
Last active March 3, 2023 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mehalter/1a34cef7891b96c67166096ce7bb4c00 to your computer and use it in GitHub Desktop.
Save mehalter/1a34cef7891b96c67166096ce7bb4c00 to your computer and use it in GitHub Desktop.
My ZSH Configuration
# Config file for Powerlevel10k with the style of Pure (https://github.com/sindresorhus/pure).
# Temporarily change options.
'builtin' 'local' '-a' 'p10k_config_opts'
[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases')
[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob')
[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand')
'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
() {
emulate -L zsh -o extended_glob
# Unset all configuration options.
unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR'
# Zsh >= 5.1 is required.
[[ $ZSH_VERSION == (5.<1->*|<6->.*) ]] || return
# Prompt colors.
local red='1'
local green='2'
local yellow='3'
local blue='4'
local magenta='5'
local cyan='6'
local grey='7'
local white='15'
# Left prompt segments.
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
# =========================[ Line #1 ]=========================
time # current time
context # user@host
dir # current directory
virtualenv # python virtual environment
vcs # git status
command_execution_time # previous command duration
# =========================[ Line #2 ]=========================
newline # \n
battery
background_jobs
prompt_char # prompt symbol
)
# Right prompt segments.
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
# =========================[ Line #1 ]=========================
# command_execution_time # previous command duration
# virtualenv # python virtual environment
# context # user@host
# time # current time
# =========================[ Line #2 ]=========================
newline # \n
)
# Basic style options that define the overall prompt look.
typeset -g POWERLEVEL9K_BACKGROUND= # transparent background
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol
typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION= # no segment icons
# Add an empty line before each prompt except the first. This doesn't emulate the bug
# in Pure that makes prompt drift down whenever you use the Alt-C binding from fzf or similar.
typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
# Magenta prompt symbol if the last command succeeded.
typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS}_FOREGROUND=$green
# Red prompt symbol if the last command failed.
typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS}_FOREGROUND=$red
# Default prompt symbol.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='➤'
# Prompt symbol in command vi mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='%BN%b'
# Prompt symbol in visual vi mode is the same as in command mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='%BV%b'
# Prompt symbol in overwrite vi mode is the same as in command mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=false
typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=$blue
typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='✦'
# Grey Python Virtual Environment.
typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=$yellow
# Don't show Python version.
typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false
typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER=
typeset -g POWERLEVEL9K_VIRTUALENV_CONTENT_EXPANSION='%B($P9K_CONTENT)%b'
# Blue current directory.
typeset -g POWERLEVEL9K_DIR_FOREGROUND=$blue
typeset -g POWERLEVEL9K_DIR_CONTENT_EXPANSION='%B$P9K_CONTENT%b'
# Context format when root: user@host. The first part white, the rest grey.
typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE="%F{$white}%n%f%F{$grey}@%m%f"
# Context format when not root: user@host. The whole thing grey.
typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE="%F{$grey}%n@%m%f"
# Don't show context unless root or in SSH.
typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_CONTENT_EXPANSION=
typeset -g POWERLEVEL9K_CONTEXT_CONTENT_EXPANSION='%B$P9K_CONTENT%b'
# Show previous command duration only if it's >= 5s.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=5
# Don't show fractional seconds. Thus, 7s rather than 7.3s.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0
# Duration format: 1d 2h 3m 4s.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s'
# Yellow previous command duration.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=$yellow
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_CONTENT_EXPANSION='%B$P9K_CONTENT%b'
# Grey Git prompt. This makes stale prompts indistinguishable from up-to-date ones.
typeset -g POWERLEVEL9K_VCS_FOREGROUND=$magenta
# Disable async loading indicator to make directories that aren't Git repositories
# indistinguishable from large Git repositories without known state.
typeset -g POWERLEVEL9K_VCS_LOADING_TEXT=
# Don't wait for Git status even for a millisecond, so that prompt always updates
# asynchronously when Git state changes.
typeset -g POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS=0
# Formatter for Git status.
function my_git_formatter() {
emulate -L zsh
if [[ -n $P9K_CONTENT ]]; then
# If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from
# gitstatus plugin). VCS_STATUS_* parameters are not available in this case.
typeset -g my_git_format=$P9K_CONTENT
return
fi
local res
local where # branch or tag
if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then
res+="${POWERLEVEL9K_VCS_BRANCH_ICON} "
where=${(V)VCS_STATUS_LOCAL_BRANCH}
elif [[ -n $VCS_STATUS_TAG ]]; then
res+="#"
where=${(V)VCS_STATUS_TAG}
fi
# If local branch name or tag is at most 32 characters long, show it in full.
# Otherwise show the first 12 … the last 12.
(( $#where > 80 )) && where[12,-64]="…"
res+="${clean}${where//\%/%%}" # escape %
# Display the current Git commit if there is no branch or tag.
# Tip: To always display the current Git commit, remove `[[ -z $where ]] &&` from the next line.
[[ -z $where ]] && res+="@${VCS_STATUS_COMMIT[1,8]}"
# Show tracking branch name if it differs from local branch.
if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then
res+=":${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape %
fi
# *42 if have stashes.
# (( VCS_STATUS_STASHES )) && res+=" *${VCS_STATUS_STASHES}"
(( VCS_STATUS_STASHES )) && res+="${POWERLEVEL9K_VCS_STASHED_ICON}"
(( VCS_STATUS_NUM_STAGED || VCS_STATUS_NUM_CONFLICTED || VCS_STATUS_NUM_UNSTAGED || VCS_STATUS_NUM_UNTRACKED )) && res+=" ["
# ~42 if have merge conflicts.
# (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ~${VCS_STATUS_NUM_CONFLICTED}"
(( VCS_STATUS_NUM_CONFLICTED )) && res+="${POWERLEVEL9K_VCS_CONFLICTED_ICON}"
# +42 if have staged changes.
# (( VCS_STATUS_NUM_STAGED )) && res+=" +${VCS_STATUS_NUM_STAGED}"
(( VCS_STATUS_NUM_STAGED )) && res+="${POWERLEVEL9K_VCS_STAGED_ICON}"
# !42 if have unstaged changes.
# (( VCS_STATUS_NUM_UNSTAGED )) && res+=" !${VCS_STATUS_NUM_UNSTAGED}"
(( VCS_STATUS_NUM_UNSTAGED )) && res+="${POWERLEVEL9K_VCS_UNSTAGED_ICON}"
# ?42 if have untracked files. It's really a question mark, your font isn't broken.
# See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon.
# Remove the next line if you don't want to see untracked files at all.
# (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}"
(( VCS_STATUS_NUM_UNTRACKED )) && res+="${POWERLEVEL9K_VCS_UNTRACKED_ICON}"
(( VCS_STATUS_NUM_STAGED || VCS_STATUS_NUM_CONFLICTED || VCS_STATUS_NUM_UNSTAGED || VCS_STATUS_NUM_UNTRACKED )) && res+="]"
# 'merge' if the repo is in an unusual state.
[[ -n $VCS_STATUS_ACTION ]] && res+=" ${VCS_STATUS_ACTION}"
# ⇣42 if behind the remote.
(( VCS_STATUS_COMMITS_BEHIND )) && res+=" ⇣${VCS_STATUS_COMMITS_BEHIND}"
# ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42.
(( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" "
(( VCS_STATUS_COMMITS_AHEAD )) && res+="⇡${VCS_STATUS_COMMITS_AHEAD}"
typeset -g my_git_format=$res
}
functions -M my_git_formatter 2>/dev/null
# Disable the default Git status formatting.
typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true
# Install our own Git status formatter.
typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='%B${$((my_git_formatter(1)))+${my_git_format}}%b'
# Cyan ahead/behind arrows.
typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=$cyan
# Don't show remote branch, current tag or stashes.
typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind)
# Don't show the branch icon.
typeset -g POWERLEVEL9K_VCS_BRANCH_ICON=''
# When in detached HEAD state, show @commit where branch normally goes.
typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@'
# Don't show staged, unstaged, untracked indicators.
typeset -g POWERLEVEL9K_VCS_STAGED_ICON='+'
typeset -g POWERLEVEL9K_VCS_UNSTAGED_ICON='!'
typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?'
typeset -g POWERLEVEL9K_VCS_CONFLICTED_ICON='~'
typeset -g POWERLEVEL9K_VCS_STASHED_ICON='~'
# Show '*' when there are staged, unstaged or untracked files.
typeset -g POWERLEVEL9K_VCS_DIRTY_ICON=
# Show '⇣' if local branch is behind remote.
typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON='⇣'
# Show '⇡' if local branch is ahead of remote.
typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON='⇡'
# Grey current time.
typeset -g POWERLEVEL9K_TIME_FOREGROUND=$yellow
# Format for the current time: 09:51:02. See `man 3 strftime`.
typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}'
typeset -g POWERLEVEL9K_TIME_CONTENT_EXPANSION='%B$P9K_CONTENT%b'
# If set to true, time will update when you hit enter. This way prompts for the past
# commands will contain the start times of their commands rather than the end times of
# their preceding commands.
typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false
typeset -g POWERLEVEL9K_BATTERY_CHARGING_FOREGROUND=$red
typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=25
typeset -g POWERLEVEL9K_BATTERY_VISUAL_IDENTIFIER_EXPANSION='󱐋'
typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_HIDE_ABOVE_THRESHOLD=25
typeset -g POWERLEVEL9K_BATTERY_CHARGING_HIDE_ABOVE_THRESHOLD=0
typeset -g POWERLEVEL9K_BATTERY_CHARGED_HIDE_ABOVE_THRESHOLD=0
typeset -g POWERLEVEL9K_BATTERY_CONTENT_EXPANSION='%B$P9K_CONTENT%b'
# Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt
# when accepting a command line. Supported values:
#
# - off: Don't change prompt when accepting a command line.
# - always: Trim down prompt when accepting a command line.
# - same-dir: Trim down prompt when accepting a command line unless this is the first command
# typed after changing current working directory.
typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off
# Instant prompt mode.
#
# - off: Disable instant prompt. Choose this if you've tried instant prompt and found
# it incompatible with your zsh configuration files.
# - quiet: Enable instant prompt and don't print warnings when detecting console output
# during zsh initialization. Choose this if you've read and understood
# https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt.
# - verbose: Enable instant prompt and print a warning when detecting console output during
# zsh initialization. Choose this if you've never tried instant prompt, haven't
# seen the warning, or if you are unsure what this all means.
typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
# Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
# For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload
# can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you
# really need it.
typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true
# If p10k is already loaded, reload configuration.
# This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true.
(( ! $+functions[p10k] )) || p10k reload
}
# Tell `p10k configure` which file it should overwrite.
typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a}
(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]}
'builtin' 'unset' 'p10k_config_opts'
# --- ufetch on startup ---
if [ -z "$QUIET_STARTUP" ]; then
ufetch
fi
# --- 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
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
unfunction 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}/zsh/history"
export SAVEHIST=10000
export KEYTIMEOUT=10
# --- setup fzf ---
[ -f /usr/share/fzf/completion.zsh ] && source /usr/share/fzf/completion.zsh
[ -f /usr/share/fzf/key-bindings.zsh ] && source /usr/share/fzf/key-bindings.zsh
export FZF_DEFAULT_OPTS="--extended"
export FZF_DEFAULT_COMMAND="fd --type f --hidden --follow"
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
# --- configure fpath ---
fpath=(
$HOME/.local/bin/zsh-completions # personal completions
${zsh_plugins}/zsh-completions/src # zsh-completions plugin
$fpath
)
# --- 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 $XDG_CACHE_HOME/zsh/zcompcache-$ZSH_VERSION # 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
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=$(tldr --color always "$word") 2>/dev/null && echo $out) || (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 ---
NVM_LAZY_LOAD=true source ${zsh_plugins}/zsh-nvm/zsh-nvm.plugin.zsh
_default_node_ver=16.19.1
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) # default node version
unfunction npm node npx corepack
# --- powerlevel10k prompt ---
source ${zsh_plugins}/powerlevel10k/powerlevel10k.zsh-theme
[ -f $ZDOTDIR/.p10k.zsh ] && source $ZDOTDIR/.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=(
$JULIA_HOME/default/bin
$HOME/node_modules/.bin
$XDG_DATA_HOME/bob/nvim-bin
$path
)
# --- source various other scripts ---
[ -f $ZDOTDIR/aliases ] && source $ZDOTDIR/aliases
[ -f $ZDOTDIR/localaliases ] && source $ZDOTDIR/localaliases
[ -f $zsh_data/shortcuts ] && source $zsh_data/shortcuts
# --- miscellaneous ---
if [ $TILIX_ID ] || [ $VTE_VERSION ]; then
source /etc/profile.d/vte.sh # Configure Virtual Terminal Emulator settings
fi
# configure nvim as manpager
if [ -n "${NVIM_LISTEN_ADDRESS+x}" ] || [ -n "${NVIM+x}" ]; then
export MANPAGER="nvr -c 'Man!' -o -"
else
export MANPAGER="nvim -c 'Man!'"
fi
gpgconf --launch gpg-agent # Start gpg agent
xhost +local:root > /dev/null # set up x11 server authority
[ -f $XDG_CONFIG_HOME/wpg/sequences ] && (cat $XDG_CONFIG_HOME/wpg/sequences &) # initialize wpgtk colors
#!/usr/bin/zsh
# default applications
alias -s c=nvim
alias -s cpp=nvim
alias -s java=nvim
alias -s md=nvim
alias -s tex=nvim
alias -s log="less -MNR"
alias ionic_dev='source ~/.local/bin/ionic_develop'
alias lf='lfub'
# AstroNvim helper functions
nvapp() {
app="${1}"
shift
NVIM_APPNAME="nvim_${app}" nvim ${@}
}
pygclip() {
pygmentize ${@} -f html -O noclasses=true,encoding=utf-8 | xclip -sel clip
}
alias update='yay -Syu --devel --assume-installed ttf-font-nerd'
alias tzupdate='timedatectl set-timezone $(curl -s --fail "https://api.ipgeolocation.io/timezone?apiKey=14b1cdd434ae4f57a61fcbbbcf34ac52" | jq -r .timezone)'
# aliases for configs
alias wget='wget --hsts-file="$XDG_CACHE_HOME/wget-hsts"'
alias dhex='dhex -f $XDG_CONFIG_HOME/dhex/dhexrc'
alias gdb='gdb -nh -x $XDG_CONFIG_HOME/gdb/init'
alias tmate='tmate -f $XDG_CONFIG_HOME/tmux/tmux.conf'
alias sbt='sbt -ivy $XDG_DATA_HOME/ivy2 -sbt-dir $XDG_DATA_HOME/sbt'
# aliases for Tmux
alias tmux='tmux -f $XDG_CONFIG_HOME/tmux/tmux.conf -2'
alias ta='tmux attach -t'
alias tnew='tmux new -s'
alias tls='tmux ls'
alias tkill='tmux kill-session -t'
alias tmuxlayout='tmux list-windows|sed "s/^.*\[layout \(.*\)\] @.*$/\1/"'
# alias firefox='firefox-developer-edition'
# weather aliases
wttrf()
{
curl -H "Accept-Language: ${LANG%_*}" wttr.in/"$1"
}
wttr()
{
wttrf "$1?u"
}
wttrm()
{
wttrf "$1?m"
}
wt()
{
wttr "$1?0"
}
# balena aliases
alias bobena='BALENARC_DATA_DIRECTORY="${BOB_DATA_DIR}" BALENARC_BALENA_URL="${BOB_TLD}" NODE_EXTRA_CA_CERTS="${BOB_CERT}" balena'
alias bobena-login='bobena login --credentials --email "${BOB_EMAIL}" --password "${BOB_PASS}"'
alias stagena='BALENARC_DATA_DIRECTORY="${BALENA_STAGING_DATA_DIR}" BALENARC_BALENA_URL="${BALENA_STAGING_TLD}" balena'
balenadl() {
TMPFILE=`mktemp`
if [[ "$1" =~ ^([0-9]+\.[0-9]+)\.[0-9]+$ ]]; then
rm -rf ${BALENARC_DATA_DIRECTORY}/balena-cli
ver="${BASH_REMATCH[1]}"
wget "https://github.com/balena-io/balena-cli/releases/download/v${ver}/balena-cli-v${ver}-linux-x64-standalone.zip" -O $TMPFILE && unzip $TMPFILE -d ${BALENARC_DATA_DIRECTORY}
rm -f $TMPFILE
fi
}
# email aliases
alias neomutt='TERM=screen-256color neomutt'
alias m='neomutt'
alias msmtpqm='msmtpq --q-mgmt'
alias mbsync='mbsync -c "$XDG_CONFIG_HOME/isync/mbsyncrc"'
# calendar aliases
alias kl='khal'
alias ikl='ikhal'
alias kla='khal -c $XDG_CONFIG_HOME/khal/academicconfig'
alias ikla='ikhal -c $XDG_CONFIG_HOME/khal/academicconfig'
# addressbook aliases
alias kd='khard'
alias kdd='khard details'
# sync aliases
alias oimap='offlineimap'
# alias vd='vdirsyncer'
alias vds='vdirsyncer sync'
# various app aliases
alias nb='newsboat'
alias nf='neofetch'
alias yt="mpsyt"
alias vi='nvim'
alias vim='nvim'
alias arc='aria2c'
alias sc='scim'
# gopass aliases
alias pls='gopass ls'
alias pnew='gopass create'
alias pshow='gopass show'
alias pedit='gopass edit'
alias pupdate='gopass update -p'
alias ptail='gopass tail'
alias ptedit='gopass tailedit'
# remarkable
remouseusb() {
if [[ "$#" == 0 ]]; then
remouse --address 10.11.99.1 --orientation left --monitor 0
elif [[ "$#" == 1 ]]; then
remouse --address 10.11.99.1 --orientation left --monitor "$1"
elif [[ "$#" == 2 ]]; then
remouse --address 10.11.99.1 --orientation "$1" --monitor "$2"
else
remouse --address 10.11.99.1 ${@}
fi
}
alias restreamcam='modprobe v4l2loopback && restream -w'
alias remapy='$XDG_DOCUMENTS_DIR/remarkable/remapy/launch.sh'
alias rcu='pushd && cd $XDG_DOCUMENTS_DIR/remarkable/rcu && make run && popd'
# python aliases
alias pip='python -m pip'
alias venv='python -m venv'
vactivate() {
venv_dir="$1"
[ -z "$1" ] && venv_dir="env"
. $venv_dir/bin/activate
}
alias pysetup='python -m pip install --upgrade pip && python -m pip install jupyter pynvim black pylint pyright'
kernnew() {
if basename $VIRTUAL_ENV 2>/dev/null >/dev/null; then
KERN_NAME=$(basename $VIRTUAL_ENV)
[[ $KERN_NAME = 'env' ]] && KERN_NAME=$(basename $(dirname $VIRTUAL_ENV))
KERN_NAME=$(echo "$KERN_NAME-$(basename $VIRTUAL_ENV)" | awk '{print tolower($0)}')
python -m ipykernel install --user --name=$KERN_NAME
fi
}
kerndel() {
if basename $VIRTUAL_ENV 2>/dev/null >/dev/null; then
KERN_NAME=$(basename $VIRTUAL_ENV)
[[ $KERN_NAME = 'env' ]] && KERN_NAME=$(basename $(dirname $VIRTUAL_ENV))
KERN_NAME=$(echo "$KERN_NAME-$(basename $VIRTUAL_ENV)" | awk '{print tolower($0)}')
jupyter kernelspec uninstall $KERN_NAME
fi
}
httpstart() {
port=8080
[ -n "$1" ] && port=$1
python -m http.server $port
}
# jupyter functions
jqt() {
kern="$(ls $XDG_DATA_HOME/jupyter/kernels | fzf -n 1)"
[ -z "$kern" ] && exit 0
setsid jupyter-qtconsole --kernel=$kern >/dev/null 2>&1 &
}
# === Julia Utilities: ===
## Download specified version of julia
jldl() {
if [[ "$1" =~ ^([0-9]+\.[0-9]+)\.[0-9]+$ ]]; then
ver="${BASH_REMATCH[1]}"
sver="${BASH_REMATCH[2]}"
wget "https://julialang-s3.julialang.org/bin/linux/x64/${sver}/julia-${ver}-linux-x86_64.tar.gz" -O - | tar xz -C ${JULIA_HOME}
fi
}
## Call base julia installations or run virtual environment if activated
jl() {
$JULIA_HOME/julia-${1}/bin/julia ${@:2}
}
## Install basic packages in new Julia virtual environment
jlsetup() { julia -e 'using Pkg; Pkg.add(["IJulia", "LanguageServer", "Revise", "PackageCompiler"]); Pkg.precompile()' }
## Create a Jupyter kernel for the current environment with a custom system image
jlsyskern() {
name="Julia (${1} kernel)"
img=$(realpath ${2})
[ -f "${img}" ] && julia -e "using IJulia; installkernel(\"${name}\", \"--project=@.\", \"-J${img}\");"
}
## Build the system image for the current virtual environment
jlbuildsysimage() {
if [ -f "./Project.toml" ]; then
julia --project -e "using PackageCompiler, Pkg; create_sysimage([Symbol(x.name) for x in values(Pkg.dependencies()) if x.is_direct_dep]; sysimage_path=\"./SysImage.so\")"
else
echo "Only run in root of a project"
fi
}
## Create a new virtual environment by name (default="env")
jlenv() {
venv_dir="${1}"
opts="${2}"
[ -z "${venv_dir}" ] && venv_dir="env"
jl ${ver} -e "using VirtualEnv; venv(\"${venv_dir}\"; ${opts})"
}
## Activate a virtual environment by name (default="env")
jlactivate() {
[ ! -z "${VIRTUAL_ENV}" ] && deactivate
venv_dir="${1}"
[ -z "${1}" ] && venv_dir="env"
[ -e "${venv_dir}" ] && . ${venv_dir}/bin/activate
}
# git aliases
alias gg="git get"
gG() { cd $GIT_PATH/$(fd -H '^.git$' --search-path ${GIT_PATH} | sed -rn 's#^'"$GIT_PATH"'/(.*)/\.git/$#\1#p' | fzf -n 1) }
bindkey -s '^g' 'gG\n'
alias lg='lazygit'
alias g='git'
alias gb='git branch'
# gcm - git commmit alias
# gcm "Commit title" -m "more optional commit paragraphs"
# gcm (patch|minor|major) "Commit title" -m "This adds the standard commit sign off"
gcm() {
change_type=""
title="${1}"
shift
if [[ "${title}" =~ ^(patch|minor|major)$ ]]; then
change_type=("-m" "Change-type: ${title}")
title="${1}"
shift
fi
git commit -S -s -m "${title}" ${@} ${change_type}
}
alias gco='git checkout'
alias gf='git fetch'
alias gfc='git clone'
alias gfm='git pull'
alias gia='git add'
alias gp='git push'
alias gpf='git push --force-with-lease'
alias gpt='git push --tags'
alias gr='git rebase'
alias gS='git submodule'
alias gSa='git submodule add'
alias gSi='git submodule init'
alias gSI='git submodule update --init --recursive'
alias gws='git status --short'
alias gwS='git status'
alias glv="git log --graph --pretty=format:'%h - %d %s (%cr) <%an>' | nvim -R -c 'set hidden nowrap keywordprg=:enew\ \|\ terminal\ \git\ --no-pager\ show | nnoremap q :bd!<cr>' -"
# git pull, merge master into branch
gpmm() { git checkout $1 && git pull && git merge -S -m "Merge master" master && git push }
# dirs aliases
da() { pushd $1 > /dev/null && dirs -v }
dr() { pushd +$1 > /dev/null && dirs -v }
alias db='popd > /dev/null && dirs -v'
alias dv='dirs -v'
# various utilities
if [ -x /usr/bin/dircolors ]; then
test -r $HOME/.dircolors && eval "$(dircolors -b $HOME/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
alias bemenu='bemenucolor'
alias systemctlu='systemctl --user'
# cp -> rsync
alias cp='rsync -ah --partial --inplace --info=progress2'
alias Rupdate='sudo Rscript -e '"'"'update.packages(checkBuilt=TRUE, ask=FALSE, repos="https://cran.rstudio.com")'"'"
alias chmox='chmod +x'
alias maketags='ctags -R .'
alias ssh='TERM=xterm-color ssh'
alias l='ls'
alias sl='ls'
alias ll='ls -alF'
alias la='ls -A'
alias makescript="fc -rnl | head -1 >"
alias histg='history | grep'
alias cmount='mount | column -t'
alias meminfo='free -m -l -t'
alias psg='ps aux | grep'
alias ipinfo="curl ifconfig.me && curl ifconfig.me/host"
alias alert='notify-send -i "$([ $? = 0 ] && echo terminal || echo error)" "$(cat $ZDOTDIR/history|tail -n1|cut -d'\'';'\'' -f2-|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias fuck='sudo /usr/bin/zsh -c "$(fc -rnl| head -1)"'
alias sudoe='sudo -E'
alias suroot='sudo -E su -p'
alias clr='clear'
mcd() { mkdir -p -- "$@"; cd -- "$@";}
cls() { cd "$1"; ls;}
crun() { make "$1"; ./$1;}
backup() { cp "$1"{,.bak};}
md5check() { md5sum "$1" | grep "$2";}
sha256check() { sha256sum "$1" | grep "$2";}
# function to control web sync services
websync() { systemctl --user $1 offlineimap-oneshot.timer; systemctl --user $1 vdirsyncer-oneshot.timer }
filetemplate() {
template=$1
file=$2
tempbase=$(basename -- "$template")
ext="${tempbase##*.}"
if [[ $file != '' ]]; then
if [[ ! $file =~ \.$ext$ ]]; then
file=$file.$ext
fi
[ ! -f $file ] && cp $template $file;
vi $file;
fi
}
# LaTeX Template aliases
alias txa="filetemplate $HOME/Documents/latex/templates/article.tex"
alias txb="filetemplate $HOME/Documents/latex/templates/beamer.tex"
alias txm="filetemplate $HOME/Documents/latex/templates/mla.tex"
# Markdown Template aliases
alias mda="filetemplate $HOME/Documents/markdown/templates/article.md"
alias mdb="filetemplate $HOME/Documents/markdown/templates/beamer.md"
alias rmda="filetemplate $HOME/Documents/markdown/templates/article.rmd"
alias rmdb="filetemplate $HOME/Documents/markdown/templates/beamer.rmd"
alias rmdj="filetemplate $HOME/Documents/markdown/templates/jdf.rmd"
alias qmda="filetemplate $HOME/Documents/markdown/templates/article.qmd"
# C compiling shortcuts for gcc
gccc() {
if [[ $1 =~ \.c$ ]]; then
gcc -std=c99 -Wall -pedantic -Wextra -Werror -O2 -g $1 -o ${1%%.*};
else
echo "$1 is not a c file"
fi
}
gcclm() {
if [[ $1 =~ \.c$ ]]; then
gcc -std=c99 -g $1 -o ${1%%.*} -lm;
else
echo "$1 is not a c file"
fi
}
# pinned director management
pinfile=${XDG_DATA_HOME:-$HOME}/pins
alias pl='if [ -f $pinfile ]; then
while read -r pin; do
key=`awk -F "\t" '"'"'{print $1}'"'"' <<< $pin`
folder=`awk -F "\t" '"'"'{print $2}'"'"' <<< $pin`
echo -e "$key:-- $folder"
done < $pinfile | column -t -s :
fi'
pa() {
if [ "$1" != "" ] && ([ ! -f "$pinfile" ] || ! grep -Pq "^$1\t" "$pinfile"); then
touch "$pinfile"
echo -e "$1\t$PWD" >> "$pinfile"
sort -o "$pinfile" "$pinfile"
pl
fi
}
pd() {
if [ "$1" != "" ] && grep -Pq "^$1\t" "$pinfile"; then
sed -i --follow-symlinks "/^$1\t/d" "$pinfile"
pl
fi
}
pe() {
if [ "$1" != "" ] && grep -Pq "^$1\t" "$pinfile"; then
sed -i --follow-symlinks "s~^$1\t.*~$1\t$PWD~" "$pinfile"
pl
fi
}
pg() {
if [ "$1" != "" ] && grep -Pq "^$1\t" "$pinfile"; then
cd "$(sed "s/^$1\t\(.*\)$/\1/;t;d" "$pinfile")" || exit
ls
fi
}
#! /usr/bin/env sh
# GOES SOMEWHERE IN PATH
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