# Blake's ZSH configuration file ### Pre-setup >>> # shellcheck disable=SC1090,SC2296,SC1091,SC2154,SC2015 # Helper function to source files. # Usage: careful_source "file" \ # "Error message" \ # $LINENO \ # [optional: test to run (-f, -x, -e)] \ # ["optional: operation (source, exec, command or nothing)"] \ careful_source() { if test "${4:--f}" "$1"; then ${5:-source} "$1" else echo "$2" >&2 echo "Line number: $3" >&2 fi } # for sending error messages from functions and whatnot error() { ERROR_CODE="$?" >&2 echo "(zshrc) An error occurred on line number ${1}" return $ERROR_CODE } # change cursor to a beam by default echo -ne '\e[5 q' ### <<< ### Basic shell configuration >>> ### Environment variables >>> # This has to go here because otherwise we don't know where the config files are :| export SHELL_CONFIG_DIR="${SHELL_CONFIG_DIR:-"${XDG_CONFIG_HOME:-$HOME/.config}/shell"}" # source the environment variable file ${SKIP_ENV:-false} || careful_source "$SHELL_CONFIG_DIR/env" \ "Error: could not locate env file. Things could be messed up. Check that \$SHELL_CONFIG_DIR/env exists." $LINENO # <<< ### Aliases >>> # Source the alias file ${SKIP_ALIASES:-false} || careful_source "$SHELL_CONFIG_DIR/aliases" \ "Error: could not locate alias file. You may not have any aliases. Check that \$SHELL_CONFIG_DIR points to the right place." $LINENO # <<< ### Functions >>> # Organization: functions that are really short should be put here, otherwise # they should be put in a file located in $SHELL_CONFIG_DIR/functions. If they # can be converted into a script, they should be. # # To make a "function in a file" that fits with my personal spec, simply make a # file, name it what the function is called, and put the function inside of it # just like you would if you were writing it here. # load all functions that are stored in files fnupdate() { for FN in "$SHELL_CONFIG_DIR"/functions/*;do source "$FN" done } fnupdate # shellcheck disable=SC2016 mkcd() { mkdir -p "$1" || error $LINENO cd "$1" || error $LINENO } # believe it or not, zsh makes for a fine calculator calc() { echo $(($*)) } # <<< # <<< ### Apply breaking changes with the update script >>> ${SKIP_UPDATE:-false} || careful_source "$SHELL_CONFIG_DIR/updates" \ "Error: failed to run update script" $LINENO -x "command" ### <<< ### Plugins >>> { # plugin config >>> # vim-mode cursor # syntax: "[color] [blinking] [style]" see: https://github.com/softmoth/zsh-vim-mode#mode-in-prompt export MODE_CURSOR_VIINS="blinking bar" export MODE_CURSOR_REPLACE="steady bar" export MODE_CURSOR_VICMD="steady block" export MODE_CURSOR_SEARCH="blinking underline" export MODE_CURSOR_VISUAL="steady block" export MODE_CURSOR_VLINE="steady block" # <<< # Load zinit >>> { # Install zinit if not installed if [[ ! -f "$ZINIT_HOME_DIR/bin/zinit.zsh" ]]; then print -P "%F{33}▓▒░ %F{220}Installing %F{33}DHARMA%F{220} Initiative Plugin Manager (%F{33}zdharma-continuum/zinit%F{220})…%f" command mkdir -p "$ZINIT_HOME_DIR" && command chmod g-rwX "$ZINIT_HOME_DIR" command git clone https://github.com/zdharma-continuum/zinit "$ZINIT_HOME_DIR/bin" && \ print -P "%F{33}▓▒░ %F{34}Installation successful.%f%b" || \ print -P "%F{160}▓▒░ The clone has failed.%f%b" fi # Source zinit source "$ZINIT_HOME_DIR/bin/zinit.zsh" autoload -Uz _zinit (( ${+_comps} )) && _comps[zinit]=_zinit 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 # Load a few important annexes, without Turbo # (this is currently required for annexes) zinit light-mode for \ zdharma-continuum/z-a-rust \ zdharma-continuum/z-a-as-monitor \ zdharma-continuum/z-a-patch-dl \ zdharma-continuum/z-a-bin-gem-node } # <<< # Load plugins >>> # shellcheck disable=SC2262,SC2016 { # set turbo mode and git clone depth for all plugins alias zinit='ice wait"!0" depth"1";zinit' # Special history options zinit snippet OMZ::lib/history.zsh # Some better completion options (waiting dots, etc) zinit snippet OMZ::lib/completion.zsh # Terminal titling zinit snippet OMZ::lib/termsupport.zsh # Quality of life zinit load "zsh-users/zsh-autosuggestions" zinit load "zdharma-continuum/fast-syntax-highlighting" zinit load "jeffreytse/zsh-vi-mode" zinit load "zsh-users/zsh-history-substring-search" zinit load "zsh-users/zsh-completions" ## Theme # terminal colors if [[ -f "$SHELL_CONFIG_DIR/colors.sh" ]];then # custom colors source "$SHELL_CONFIG_DIR/colors.sh" else # onedark shell colors zinit snippet 'https://github.com/chriskempson/base16-shell/blob/master/scripts/base16-onedark.sh' fi # LS Colors zinit ice atclone"dircolors -b ./src/dir_colors > colors.zsh" \ atpull'%atclone' pick"colors.zsh" nocompile'!' \ atload'zstyle ":completion:*" list-colors “${(s.:.)LS_COLORS}”' zinit light arcticicestudio/nord-dircolors # prompt zinit load "romkatv/powerlevel10k" if [[ -e "$P10K_CONFIG_LOCATION" ]]; then source "$P10K_CONFIG_LOCATION" else >&2 echo "No p10k theme selected. Please use \`p10k configure\` to make one or select an existing one like this:" >&2 echo " ln -s $SHELL_CONFIG_DIR/p10k/colorful-angular.p10k.zsh $SHELL_CONFIG_DIR/p10k/current" fi # clear plugin options set at the start of this block unalias zinit # just gonna sneak this in here, too alias zi > /dev/null && unalias zi zpl zini zplg which-command run-help fsh-alias } # <<< } # <<< ### General ZSH configuration >>> # This section is (mostly) From manjaro's "manjaro-zsh-config" (/usr/share/zsh/manjaro-zsh-config) [ -z "$HISTFILE" ] && HISTFILE="$HOME/.zsh_history" ## ZSH Options >>> { # setopt correct # Auto correct mistakes setopt extendedglob # Extended globbing. Allows using regular expressions with * [ -z "$TERMUX_VERSION" ] && setopt nocaseglob # Case insensitive globbing (and fix for termux) setopt rcexpandparam # Array expension with parameters setopt checkjobs # Warn about running processes when exiting setopt numericglobsort # Sort filenames numerically when it makes sense setopt nobeep # Most important option setopt appendhistory # Immediately append history instead of overwriting setopt inc_append_history # save commands are added to the history immediately, otherwise only when shell exits. setopt histfindnodups # If a new command is a duplicate, remove the older one setopt histignorealldups # If a new command is a duplicate, remove the older one setopt autocd # if only directory path is entered, cd there. setopt interactive_comments # allow typing comments in line setopt no_rm_star_silent # Ensure the user wants to execute 'rm *' setopt rm_star_wait # Wait before accepting 'rm *' or 'rm /path/*' setopt short_loops # allow things like 'if [ 1=1 ] { echo "okay"}' < https://zsh.sourceforge.io/Doc/Release/Shell-Grammar.html#Alternate-Forms-For-Complex-Commands setopt pipe_fail # When a pipe fails, show the non-0 exit code for the exit code } # <<< ## ZSH Completion Options >>> { # Mine # zstyle ':completion:*' completer _expand _complete _ignored _prefix # zstyle ':completion:*' expand prefix suffix # zstyle ':completion:*' file-sort access # zstyle ':completion:*' ignore-parents parent pwd directory # zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} # zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s # zstyle ':completion:*' matcher-list '' 'm:{[:lower:]}={[:upper:]}' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' 'r:|[._-]=** r:|=**' # zstyle ':completion:*' menu select=long # zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s # zstyle :compinstall filename '/home/blake/.zshrc' # Manjaro's zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case insensitive tab completion zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" # Colored completion (different colors for dirs/files/etc) zstyle ':completion:*' rehash true # automatically find new executables in path # Speed up completions zstyle ':completion:*' accept-exact '*(N)' zstyle ':completion:*' use-cache on zstyle ':completion:*' cache-path "$ZSH_CACHE_DIR" WORDCHARS=${WORDCHARS//\/[&.;]} # Don't consider certain characters part of the word } # <<< ## Keybindings >>> bindkey -v # Enable Vi mode bindkey '^[[7~' beginning-of-line # Home key bindkey '^[[H' beginning-of-line # Home key if [[ "${terminfo[khome]}" != "" ]]; then bindkey "${terminfo[khome]}" beginning-of-line # [Home] - Go to beginning of line fi bindkey '^[[8~' end-of-line # End key bindkey '^[[F' end-of-line # End key if [[ "${terminfo[kend]}" != "" ]]; then bindkey "${terminfo[kend]}" end-of-line # [End] - Go to end of line fi bindkey '^[[2~' overwrite-mode # Insert key bindkey '^[[3~' delete-char # Delete key bindkey '^[[C' forward-char # Right key bindkey '^[[D' backward-char # Left key bindkey '^[[5~' history-beginning-search-backward # Page up key bindkey '^[[6~' history-beginning-search-forward # Page down key # Navigate words with ctrl+arrow keys bindkey '^[Oc' forward-word # bindkey '^[Od' backward-word # bindkey '^[[1;5D' backward-word # bindkey '^[[1;5C' forward-word # # Delete words with ctrl+bksp/del bindkey '^H' backward-kill-word # delete previous word with ctrl+backspace bindkey '^[[3;5~' kill-word # delete next word with ctrl+delete bindkey '^[[Z' undo # Shift+tab undo last action # bind UP and DOWN arrow keys to history substring search zmodload zsh/terminfo # bindkey "$terminfo[kcuu1]" history-substring-search-up # bindkey "$terminfo[kcud1]" history-substring-search-down bindkey '^[[A' history-substring-search-up bindkey '^[[B' history-substring-search-down bindkey -M vicmd 'k' history-substring-search-up bindkey -M vicmd 'j' history-substring-search-down # <<< # Colors and compinit >>> export LESS_TERMCAP_mb=$'\E[01;32m' export LESS_TERMCAP_md=$'\E[01;32m' export LESS_TERMCAP_me=$'\E[0m' export LESS_TERMCAP_se=$'\E[0m' export LESS_TERMCAP_so=$'\E[01;47;34m' export LESS_TERMCAP_ue=$'\E[0m' export LESS_TERMCAP_us=$'\E[01;36m' export LESS=-R autoload -U compinit colors zcalc compinit -d colors # <<< # auto save and load working dir (allow `cd -` on start) >>> # Load the last working directory load_working_dir() { # load the directory (and do validation to make sure it's actually a directory) if test -f "$WORKING_DIR_SAVE_FILE"; then local PREVIOUS_WORKING_DIR PREVIOUS_WORKING_DIR="$(cat "$WORKING_DIR_SAVE_FILE")" if test -d "$(cat "$WORKING_DIR_SAVE_FILE")"; then cd "$PREVIOUS_WORKING_DIR" || error $LINENO else echo "Invalid saved working directory ($PREVIOUS_WORKING_DIR)" > /dev/null return 1 fi else echo "Invalid working directory save file ($WORKING_DIR_SAVE_FILE)" > /dev/null return 1 fi } save_working_dir() { if [ "$(pwd)" != "$HOME" ];then pwd > "$WORKING_DIR_SAVE_FILE" fi } autoload -U add-zsh-hook add-zsh-hook chpwd save_working_dir # shellchek disable=SC2164 load_working_dir && cd - > /dev/null || echo -n # Case insensitive globbing (fix for termux) [ -n "$TERMUX_VERSION" ] && (setopt nocaseglob; zstyle ':completion:*' path-completion true) # <<< # <<< # Optionally source another zshrc [ -f "$SHELL_CONFIG_DIR/zshrc.local" ] && source "$SHELL_CONFIG_DIR/zshrc.local" || true # vim:fdm=marker:fmr=>>>,<<<:et:ft=bash:sw=3