# My zsh config file. One day, I may actually learn about zsh instead # of just haphazardly tossing crap at it. # basic setup / options {{{ # Common path, aliases, functions, etc. for both zsh and bash: source ~/.sh_common autoload -U add-zsh-hook autoload -Uz compinit export HISTFILE=~/.histfile export HISTSIZE=15000 export SAVEHIST=9999999 # vi-style cycling through completions on repeated tab presses: setopt menu_complete # Allow arrow-key selection of completion items from a menu: zstyle ':completion:*' menu select # Auto-rehash so that when stuff is installed you can tab-complete it # immediately (I have no idea what performance penalty this incurs): zstyle ':completion:*' rehash true setopt prompt_subst setopt inc_append_history setopt hist_ignore_space setopt hist_ignore_dups setopt autocd setopt extendedglob setopt autopushd pushdminus setopt printexitvalue unsetopt beep bindkey -e # Add completion for custom git commands I've written as shell scripts: # https://stackoverflow.com/questions/38725102/how-to-add-custom-git-command-to-zsh-completion zstyle ':completion:*:*:git:*' user-commands sel-changed:'select from changed files' \ edit-changed:'edit from selected changed files' \ do:'execute command from top of repo' zstyle :compinstall filename '/home/brennen/.zshrc' compinit # }}} # keybindings {{{ # You can get bindkey strings with Ctrl-v followed by your key sequence. # https://wiki.archlinux.org/index.php/Zsh#History_search # Search up/down for matching thing on arrows - you can still use ctrl-n / # ctrl-p to move up and down in the overall command history: autoload -Uz up-line-or-beginning-search down-line-or-beginning-search zle -N up-line-or-beginning-search zle -N down-line-or-beginning-search [[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-beginning-search [[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-beginning-search # https://wiki.archlinux.org/index.php/Zsh#File_manager_key_binds # Alt-Left for previous directory and Alt-Up for parent cd_undo_key () { echo popd zle reset-prompt ls zle reset-prompt } cd_parent_key () { echo pushd .. zle reset-prompt ls zle reset-prompt } zle -N cd_parent_key zle -N cd_undo_key bindkey '^[[1;3A' cd_parent_key bindkey '^[[1;3D' cd_undo_key # Invoke h history function from .sh_common with Alt-H: invoke_h () { h zle reset-prompt } zle -N invoke_h bindkey '^[H' invoke_h # fzf fuzzyfinder for use with Alt-c, Ctrl-r, Ctrl-t: [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh # }}} # prompt configuration {{{ # Grab some colors: autoload colors zsh/terminfo if [[ "$terminfo[colors]" -ge 8 ]]; then colors fi for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do eval PR_$color='%{$terminfo[bold]$fg[${(L)color}]%}' eval PR_LIGHT_$color='%{$fg[${(L)color}]%}' (( count = $count + 1 )) done PR_NO_COLOR="%{$terminfo[sgr0]%}" # Next, do per-host color and sigils. # # Since this will be used in a $PS1, colors can be either of the named values # from the above loop, or numerical escapes like %F{nnn} for Foreground and # %K{nnn} for background. The latter will only work on 256 color terminals, # although I'm not sure what the failure mode looks like. # # Great for sigils: # https://en.wikipedia.org/wiki/Unicode_Geometric_Shapes # https://en.wikipedia.org/wiki/List_of_symbols PR_SIGIL=\$ PR_PATH_COLOR=$PR_BLUE; PR_TIME_COLOR=$PR_LIGHT_BLUE PR_GIT_COLOR=$PR_NO_COLOR PR_SIGIL_COLOR=$PR_NO_COLOR case "$HOST" in 'catastrophe') PR_HOST_COLOR=$PR_LIGHT_BLUE ;; 'desiderata') PR_HOST_COLOR=$PR_LIGHT_BLUE PR_SIGIL=★ ;; 'escalation') PR_HOST_COLOR=$PR_LIGHT_GREEN PR_SIGIL=✩ ;; 'errata') PR_HOST_COLOR=$PR_LIGHT_BLUE PR_SIGIL=☾ ;; 'externality') PR_HOST_COLOR=$PR_LIGHT_GREEN PR_SIGIL=✩ ;; 'exuberance') PR_HOST_COLOR=$PR_LIGHT_YELLOW PR_SIGIL=★ ;; 'fragility') PR_HOST_COLOR=$PR_WHITE PR_SIGIL=❄ ;; 'inertia') PR_HOST_COLOR='%F{27}' PR_TIME_COLOR='%F{29}' PR_GIT_COLOR='%F{93}' PR_SIGIL_COLOR=$PR_HOST_COLOR # PR_SIGIL=▣ PR_SIGIL=$(fragment-bullet) ;; 'metaphor') PR_HOST_COLOR='%F{69}' PR_TIME_COLOR='%F{161}' PR_GIT_COLOR='%F{32}' PR_PATH_COLOR='%F{242}' PR_SIGIL_COLOR='%F{220}' # see bin/fragment-bullet: PR_SIGIL=$(fragment-bullet) ;; 'novena-edward-norway') PR_HOST_COLOR=$PR_LIGHT_BLUE PR_SIGIL=❄ ;; 'pisces') PR_HOST_COLOR=$PR_GREEN ;; 'raspberrypi') PR_HOST_COLOR=$PR_MAGENTA ;; 'kropotkin') PR_HOST_COLOR=$PR_BLUE ;; *) PR_HOST_COLOR=$PR_BLUE ;; esac # Stash values here for inclusion at beginning of prompt: pr_meta="" # Run to install some color swatches in the prompt for experimenting with # host colors and such: function colortest { colortest="" for c in `seq 0 256`; do colortest="$colortest %K{$c} $c " done pr_meta="$colortest " } # Reset the prompt on every command to get that parse_git_branch function to # run. Because this runs before every command, there's no need to set PS1 # elsewhere. Also sets xterm title (which works for other terminals as well): function precmd { # http://tldp.org/HOWTO/Xterm-Title-4.html case $TERM in xterm*) print -Pn "\e]0;%n@%m: %~\a" ;; esac pr_time="$PR_TIME_COLOR%*$PR_NO_COLOR" pr_userhost="$PR_HOST_COLOR%n@%m$PR_NO_COLOR" pr_path="$PR_PATH_COLOR%~$PR_NO_COLOR" # A conditional expression - if there're one or more background jobs, # display [number of jobs] # http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html pr_jobs="%1(j.[%j] .)" pr_sigil="$PR_SIGIL_COLOR$PR_SIGIL$PR_NO_COLOR" # __git_ps1 takes 2 parameters: Stuff for before the git prompt and stuff # for after. See .sh_common - if the git prompt is available, it'll use # that; otherwise it's a fallback to the much simpler parse_git_branch # defined there. __git_ps1 "$pr_meta$pr_time $pr_userhost:$pr_path" " $pr_jobs$pr_sigil " } # This will reset the prompt every so often - it definitely shouldn't happen # in situations where, for example, the git status prompt might be really # expensive - but it _is_ kind of neat: # TMOUT=15 # TRAPALRM() { zle reset-prompt; } # }}} # history {{{ # Record directory history to a simple text file: function chpwd { echo "$PWD" >> ~/.directory_history } # Record command history using commandlog: # https://code.p1k3.com/gitea/brennen/commandlog # https://p1k3.com/topics/commandlog/ function bpb_preexec { # http://zsh.sourceforge.net/Doc/Release/Functions.html # Log the current command, if commandlog is available - $commands seems # to be where available commands are hashed: (( $+commands[commandlog] )) && commandlog add "$@" } add-zsh-hook preexec bpb_preexec # }}} # syntax highlighting {{{ # https://github.com/zsh-users/zsh-syntax-highlighting # Fish-style syntax highlighting - must be last thing sourced, install with: # sudo apt-get install zsh-syntax-highlighting ZSH_SYNTAX_HIGHLIGHTING_PATH=/usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh [ -f "$ZSH_SYNTAX_HIGHLIGHTING_PATH" ] && source "$ZSH_SYNTAX_HIGHLIGHTING_PATH" # }}}