# vim: ft=zsh # # Download Patched fonts from # https://github.com/gabrielelana/awesome-terminal-fonts/tree/patching-strategy/patched # #---------------------------------- Pre Setup --------------------------------- # Source this file in your .zshrc: # source $HOME/.zsh/zshrc autoload colors; colors autoload -Uz add-zsh-hook LAST_RETURN_VALUE=0 # Characters if [[ -n $(echo '\u2603' 2>/dev/null) ]]; then MULTIBYTE_SUPPORTED="\u2603" fi if [[ -n $MULTIBYTE_SUPPORTED ]]; then UNSTAGED_CHARACTER="\ue168" CHANGES_CHARACTER="\ue16b" UNTRACKED_CHARACTER="\ue16c" BRANCH_CHARACTER="\ue822" DETACHED_CHARACTER="\ue899" REVISION_CHARACTER="\ue821" FAILED_CHARACTER="\ue125" SUCCESS_CHARACTER="\ue124" SUPERUSER_CHARACTER="\ue22b" JOBS_CHARACTER="\ue12a" NO_JOBS_CHARACTER="\u2022" AHEAD_CHARACTER="\ue174 " BEHIND_CHARACTER="\ue175 " ACTIONS_CHARACTER="\ue831" SEGMENT_SEPARATOR_FORWARD="\ue0b0" SEGMENT_SEPARATOR_BACKWARD="\ue0b2" else UNSTAGED_CHARACTER="!" CHANGES_CHARACTER="*" UNTRACKED_CHARACTER="?" BRANCH_CHARACTER="~" DETACHED_CHARACTER="%" REVISION_CHARACTER="r" FAILED_CHARACTER="X" SUCCESS_CHARACTER="V" SUPERUSER_CHARACTER="#" JOBS_CHARACTER="O" NO_JOBS_CHARACTER="." AHEAD_CHARACTER="+" BEHIND_CHARACTER="-" ACTIONS_CHARACTER="!" SEGMENT_SEPARATOR_FORWARD="" SEGMENT_SEPARATOR_BACKWARD="" fi #---------------------------------- Helpers ----------------------------------- # Search file up in directory tree. Either print path to found file or nothing find_up() { path=$(pwd) while [[ "$path" != "" ]]; do if [[ -e "$path/$1" ]]; then echo "$path/$1" return fi path=${path%/*} done } command-exists() { return $(command -v $1 >/dev/null) } NEWLINE=$'\n' ZDOTDIR=${ZDOTDIR:-$HOME/.zsh} #---------------------------------- Listings ---------------------------------- if command-exists dircolors; then eval "$(dircolors -b)" fi if command-exists exa; then alias ls='exa --git --long --all --time-style long-iso' else LSOPTS="-lAvF --color=auto" # long mode, show all, natural sort, type squiggles, friendly sizes alias ls="ls $LSOPTS" fi #---------------------------------- Tab completion ---------------------------- # Force a reload of completion system if nothing matched; this fixes installing # a program and then trying to tab-complete its name _force_rehash() { ((CURRENT == 1)) && rehash return 1 # Because we didn't really complete anything } # Always use menu completion, and make the colors pretty! zstyle ':completion:*' menu select yes zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS} # Completers to use: rehash, general completion, then various magic stuff and # spell-checking. Only allow two errors when correcting zstyle ':completion:*' completer _force_rehash _complete _ignored _match _correct _approximate _prefix zstyle ':completion:*' max-errors 2 # When looking for matches, first try exact matches, then case-insensiive, then partial word completion zstyle ':completion:*' matcher-list '' 'm:{a-z}={A-Z}' 'r:|[._-]=** r:|=**' # Turn on caching, which helps with e.g. apt zstyle ':completion:*' use-cache on zstyle ':completion:*' cache-path "$HOME/.zsh/cache" mkdir -p $HOME/.zsh/cache # Show nice warning when nothing matched zstyle ':completion:*:warnings' format '%No matches: %d%b' # Show titles for completion types and group by type zstyle ':completion:*:descriptions' format "%U%B%F{yellow}ยป %d%u%b%f" zstyle ':completion:*' group-name '' # Ignore some common useless files zstyle ':completion:*' ignored-patterns '*?.pyc' '__pycache__' zstyle ':completion:*:*:rm:*:*' ignored-patterns # Directories zstyle ':completion:*:default' list-colors "${(s.:.)LS_COLORS}" zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories zstyle ':completion:*:*:cd:*:directory-stack' menu yes select zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand' zstyle ':completion:*' squeeze-slashes true # kill: advanced kill completion zstyle ':completion::*:kill:*:*' command 'ps xf -U $USER -o pid,%cpu,cmd' zstyle ':completion::*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;32' # sudo completion zstyle ':completion:*:sudo:*' command-path append /sbin /usr/sbin SSH_HOSTS=($([[ -f $HOME/.ssh/config ]] && print -n $(cat $HOME/.ssh/config | sed '/^Host [^*]/!d;s/Host *\([^ \#]\+\)/\1/' | sort))) zstyle ':completion:*:ssh:*' hosts $SSH_HOSTS zstyle ':completion:*:scp:*' hosts $SSH_HOSTS zstyle ':completion:*:ssh:*' users # disables users completion zstyle ':completion:*:scp:*' users # disables users completion # maven completions (from zsh-users/zsh-completions) zstyle ':completion:*:*:mvn:*:matches' group 'yes' zstyle ':completion:*:*:mvn:*:options' description 'yes' zstyle ':completion:*:*:mvn:*:options' auto-description '%d' # Always do mid-word tab completion setopt complete_in_word # don't expand aliases _before_ completion has finished setopt complete_aliases #---------------------------------- Corrections ------------------------------- # dont correct arguments to dot-files CORRECT_IGNORE='[._]*' CORRECT_IGNORE_FILE='[._]*' #---------------------------------- Prediction -------------------------------- autoload predict-on autoload predict-off zle -N predict-on zle -N predict-off bindkey "^Z" predict-on # C-z bindkey "^X^Z" predict-off # C-x C-z #---------------------------------- History ----------------------------------- setopt append_history # Allow multiple terminal sessions to all append to one zsh command history setopt extended_history # save timestamp of command and duration setopt inc_append_history # Add comamnds as they are typed, don't wait until shell exit setopt hist_expire_dups_first # when trimming history, lose oldest duplicates first setopt hist_ignore_dups # Do not write events to history that are duplicates of previous events setopt hist_ignore_space # remove command line from history list when first character on the line is a space setopt hist_find_no_dups # When searching history don't display results already cycled through twice setopt hist_reduce_blanks # Remove extra blanks from each command line being added to history setopt hist_verify # don't execute, just expand history setopt share_history # imports new commands and appends typed commands to history setopt hist_no_store # remove the history (fc -l) command from the history when invoked. export HISTFILE=~/.zsh_history export HISTSIZE=1000000 export SAVEHIST=1000000 #---------------------------------- VCS --------------------------------------- autoload -Uz vcs_info zstyle ':vcs_info:*' enable git hg svn zstyle ':vcs_info:*' check-for-changes true zstyle ':vcs_info:*' get-revision true # these formats are set for PROMPT zstyle ':vcs_info:*' formats "%s $BRANCH_CHARACTER%b $REVISION_CHARACTER%i%u" zstyle ':vcs_info:*' actionformats "%s $BRANCH_CHARACTER%b $REVISION_CHARACTER%i%u [%a]" zstyle ':vcs_info:*' branchformat '%b' zstyle ':vcs_info:hg*' unstagedstr "$CHANGES_CHARACTER" zstyle ':vcs_info:hg*' hgrevformat "%r" # default "%r:%h" zstyle ':vcs_info:git*' formats "$BRANCH_CHARACTER%b%u%c%m" # git is standard zstyle ':vcs_info:git*' actionformats "$BRANCH_CHARACTER%b%u%c%m $ACTIONS_CHARACTER%a" zstyle ':vcs_info:git*' unstagedstr " $UNSTAGED_CHARACTER" zstyle ':vcs_info:git*' stagedstr " $CHANGES_CHARACTER" zstyle ':vcs_info:git*+set-message:*' hooks git-additional function +vi-git-additional() { local ahead behind local -a branchstatus ahead=$(git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l) (($ahead)) && branchstatus+=(" $AHEAD_CHARACTER${ahead}") behind=$(git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l) (($behind)) && branchstatus+=(" $BEHIND_CHARACTER${behind}") hook_com[misc]="${(j::)branchstatus}" if [[ $(git rev-parse --is-inside-work-tree 2>/dev/null) == 'true' && -n $(git status --porcelain | grep -E '^\?\?' 2>/dev/null | tail -n1) ]]; then hook_com[unstaged]+=" $UNTRACKED_CHARACTER" fi } #---------------------------------- Aliases ---------------------------------- # Use interactive sudo instead of su alias su="sudo -u root -i" # disable sudo correction for commands alias sudo="nocorrect sudo" # More powerful terminal reset # \e< - resets \e[?2l which puts terminal into VT52 mode # reset - normal terminal reset # stty sane - puts tty in sane state (like accepting input, no character translation etc.) # setterm -reset - puts reset terminal string, as identified by setterm # tput reset - puts terminal reset strings from terminfo # clear - simple clear terminal window # \033c - exactly "c" which is VT100 code for resetting terminal alias reset='echo -e "\e<"; reset; stty sane; setterm -reset; tput reset; clear; echo -e "\033c"' # Shortcuts for clipboard manipulation alias xclip-in='xclip -selection c -in' alias xclip-out='xclip -selection c -out' # Standard bd usage alias bd=". bd -si" #---------------------------------- VIM pager -------------------------------- vim_pager() { local source_file if [ ! -t 1 ]; then echo "Cannot use vim pager with non-terminal output" 1>&2 return 1 fi if [ $# -gt 0 ]; then source_file="$@" elif [ ! -t 0 ]; then source_file="-" else echo "Input stream or file name missing" 1>&2 return 2 fi vim --cmd 'let no_plugin_maps = 1' -c 'runtime! macros/less.vim' $source_file } alias vless='vim_pager' #---------------------------------- Maven ------------------------------------ # Read project information from current directory - needed for prompt maven_read_project() { local location parts location=$(find_up pom.xml) if [[ ! -r "$location" || -z $commands[xmllint] ]]; then MAVEN_PROJECT="" return 1 fi # executing xmllint takes some time, so this does it in single execution parts=($(echo "cat /*[local-name()='project']/*[local-name()='artifactId']/text()\n" \ "cat /*[local-name()='project']/*[local-name()='version']/text()\n" \ "cat /*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']/text()\n" | xmllint --shell $location 2>/dev/null | sed '/^\/ >/d' | sed '/^ -------/d')) if [[ "${#parts}" > 1 ]]; then MAVEN_PROJECT="${parts[1]}@${parts[2]}" else MAVEN_PROJECT="pom!" fi } add-zsh-hook chpwd maven_read_project #---------------------------------- package.json ------------------------------------ # Read project information from current directory - needed for prompt package_json_read_project() { local location parts location=$(find_up package.json) if [[ ! -r "$location" || -z $commands[jq] ]]; then PACKAGE_JSON_PROJECT="" return 1 fi PACKAGE_JSON_PROJECT=$(jq -r '.name + "@" + .version' $location) } add-zsh-hook chpwd package_json_read_project #---------------------------------- Miscellaneous ---------------------------- setopt extended_glob setopt correct # try to correct the spelling of commands. setopt correct_all # try to correct the spelling of all arguments in a line. setopt numeric_glob_sort # if numeric filenames are matched by a filename generation pattern, sort the filenames numerically rather than lexicographically. setopt nomatch # if there is match on file pattern, dont run command (instead of running command with unchanged parameters) setopt interactive_comments # allow comments in command line setopt multios # enable multiple input/output redirections that work as expected unsetopt beep # (dont) beep on errors unsetopt notify # (dont) report the status of background jobs immediately, rather than waiting until just before printing a prompt. unsetopt auto_cd # (dont) enter the directory that was inputed as command unsetopt auto_remove_slash # (dont) remove last slash when next character is delimiter unsetopt csh_junkie_quotes # (dont) complain if a quoted expression runs off the end of a line; prevent quoted expressions from containing un-escaped newlines. # Don't count common path separators as word characters WORDCHARS=${WORDCHARS//[&.;\/]/} # Report time if command takes too long REPORTTIME=5 TIMEFMT=$(echo "$fg[green]${SEGMENT_SEPARATOR_BACKWARD}$bg[green]$fg[black] %*Es $fg[yellow]$SEGMENT_SEPARATOR_BACKWARD$bg[yellow]$fg[black] %P $reset_color") # Don't glob with commands that expects glob patterns for command in find wget git; do alias $command="noglob $command" done # load zsh extended move autoload -Uz zmv #---------------------------------- Machine specific -------------------------- if [[ -r $HOME/.zlocal ]]; then source $HOME/.zlocal fi #---------------------------------- Post Setup -------------------------------- # at last initialize completion autoload -Uz compinit if [[ -n "${ZDOTDIR}/.zcompdump(#qN.mh+24)" ]]; then compinit -u else compinit -u -C fi store_last_return_value() { LAST_RETURN_VALUE="$?" } # Store last return value into separate variable # This must be exactly first precmd function, because other precmd might modify $? precmd_functions=(store_last_return_value $precmd_functions) zmodload zsh/complist #---------------------------------- Partials ------------------------------------ for partial in ${ZDOTDIR}/zsh.d/*.zsh; do source $partial done