diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/cli.zsh | 426 | ||||
| -rw-r--r-- | lib/clipboard.zsh | 125 | ||||
| -rw-r--r-- | lib/compfix.zsh | 2 | ||||
| -rw-r--r-- | lib/completion.zsh | 22 | ||||
| -rw-r--r-- | lib/diagnostics.zsh | 10 | ||||
| -rw-r--r-- | lib/directories.zsh | 10 | ||||
| -rw-r--r-- | lib/functions.zsh | 47 | ||||
| -rw-r--r-- | lib/git.zsh | 253 | ||||
| -rw-r--r-- | lib/grep.zsh | 57 | ||||
| -rw-r--r-- | lib/history.zsh | 12 | ||||
| -rw-r--r-- | lib/key-bindings.zsh | 107 | ||||
| -rw-r--r-- | lib/misc.zsh | 34 | ||||
| -rw-r--r-- | lib/nvm.zsh | 9 | ||||
| -rw-r--r-- | lib/prompt_info_functions.zsh | 20 | ||||
| -rw-r--r-- | lib/spectrum.zsh | 26 | ||||
| -rw-r--r-- | lib/termsupport.zsh | 88 | ||||
| -rw-r--r-- | lib/theme-and-appearance.zsh | 12 | 
17 files changed, 946 insertions, 314 deletions
| diff --git a/lib/cli.zsh b/lib/cli.zsh new file mode 100644 index 000000000..38e2f72f8 --- /dev/null +++ b/lib/cli.zsh @@ -0,0 +1,426 @@ +#!/usr/bin/env zsh + +function omz { +  [[ $# -gt 0 ]] || { +    _omz::help +    return 1 +  } + +  local command="$1" +  shift + +  # Subcommand functions start with _ so that they don't +  # appear as completion entries when looking for `omz` +  (( $+functions[_omz::$command] )) || { +    _omz::help +    return 1 +  } + +  _omz::$command "$@" +} + +function _omz { +  local -a cmds subcmds +  cmds=( +    'changelog:Print the changelog' +    'help:Usage information' +    'plugin:Manage plugins' +    'pr:Manage Oh My Zsh Pull Requests' +    'theme:Manage themes' +    'update:Update Oh My Zsh' +  ) + +  if (( CURRENT == 2 )); then +    _describe 'command' cmds +  elif (( CURRENT == 3 )); then +    case "$words[2]" in +      changelog) local -a refs +        refs=("${(@f)$(command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}") +        _describe 'command' refs ;; +      plugin) subcmds=('info:Get plugin information' 'list:List plugins') +        _describe 'command' subcmds ;; +      pr) subcmds=('test:Test a Pull Request' 'clean:Delete all Pull Request branches') +        _describe 'command' subcmds ;; +      theme) subcmds=('use:Load a theme' 'list:List themes') +        _describe 'command' subcmds ;; +    esac +  elif (( CURRENT == 4 )); then +    case "$words[2]::$words[3]" in +      plugin::info) compadd "$ZSH"/plugins/*/README.md(.N:h:t) \ +        "$ZSH_CUSTOM"/plugins/*/README.md(.N:h:t) ;; +      theme::use) compadd "$ZSH"/themes/*.zsh-theme(.N:t:r) \ +        "$ZSH_CUSTOM"/**/*.zsh-theme(.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::) ;; +    esac +  fi + +  return 0 +} + +compdef _omz omz + +## Utility functions + +function _omz::confirm { +  # If question supplied, ask it before reading the answer +  # NOTE: uses the logname of the caller function +  if [[ -n "$1" ]]; then +    _omz::log prompt "$1" "${${functrace[1]#_}%:*}" +  fi + +  # Read one character +  read -r -k 1 + +  # If no newline entered, add a newline +  if [[ "$REPLY" != $'\n' ]]; then +    echo +  fi +} + +function _omz::log { +  # if promptsubst is set, a message with `` or $() +  # will be run even if quoted due to `print -P` +  setopt localoptions nopromptsubst + +  # $1 = info|warn|error|debug +  # $2 = text +  # $3 = (optional) name of the logger + +  local logtype=$1 +  local logname=${3:-${${functrace[1]#_}%:*}} + +  # Don't print anything if debug is not active +  if [[ $logtype = debug && -z $_OMZ_DEBUG ]]; then +    return +  fi + +  # Choose coloring based on log type +  case "$logtype" in +    prompt) print -Pn "%S%F{blue}$logname%f%s: $2" ;; +    debug) print -P "%F{white}$logname%f: $2" ;; +    info) print -P "%F{green}$logname%f: $2" ;; +    warn) print -P "%S%F{yellow}$logname%f%s: $2" ;; +    error) print -P "%S%F{red}$logname%f%s: $2" ;; +  esac >&2 +} + +## User-facing commands + +function _omz::help { +  cat <<EOF +Usage: omz <command> [options] + +Available commands: + +  help                Print this help message +  changelog           Print the changelog +  plugin <command>    Manage plugins +  pr     <command>    Manage Oh My Zsh Pull Requests +  theme  <command>    Manage themes +  update              Update Oh My Zsh + +EOF +} + +function _omz::changelog { +  local version=${1:-HEAD} format=${3:-"--text"} + +  if ! command git -C "$ZSH" show-ref --verify refs/heads/$version &>/dev/null && \ +    ! command git -C "$ZSH" show-ref --verify refs/tags/$version &>/dev/null && \ +    ! command git -C "$ZSH" rev-parse --verify "${version}^{commit}" &>/dev/null; then +    cat <<EOF +Usage: omz changelog [version] + +NOTE: <version> must be a valid branch, tag or commit. +EOF +    return 1 +  fi + +  "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format" +} + +function _omz::plugin { +  (( $# > 0 && $+functions[_omz::plugin::$1] )) || { +    cat <<EOF +Usage: omz plugin <command> [options] + +Available commands: + +  info <plugin>   Get information of a plugin +  list            List all available Oh My Zsh plugins + +EOF +    return 1 +  } + +  local command="$1" +  shift + +  _omz::plugin::$command "$@" +} + +function _omz::plugin::info { +  if [[ -z "$1" ]]; then +    echo >&2 "Usage: omz plugin info <plugin>" +    return 1 +  fi + +  local readme +  for readme in "$ZSH_CUSTOM/plugins/$1/README.md" "$ZSH/plugins/$1/README.md"; do +    if [[ -f "$readme" ]]; then +      (( ${+commands[less]} )) && less "$readme" || cat "$readme" +      return 0 +    fi +  done + +  if [[ -d "$ZSH_CUSTOM/plugins/$1" || -d "$ZSH/plugins/$1" ]]; then +    _omz::log error "the '$1' plugin doesn't have a README file" +  else +    _omz::log error "'$1' plugin not found" +  fi + +  return 1 +} + +function _omz::plugin::list { +  local -a custom_plugins builtin_plugins +  custom_plugins=("$ZSH_CUSTOM"/plugins/*(-/N:t)) +  builtin_plugins=("$ZSH"/plugins/*(-/N:t)) + +  # If the command is being piped, print all found line by line +  if [[ ! -t 1 ]]; then +    print -l ${(q-)custom_plugins} ${(q-)builtin_plugins} +    return +  fi + +  if (( ${#custom_plugins} )); then +    print -P "%U%BCustom plugins%b%u:" +    print -l ${(q-)custom_plugins} | column +  fi + +  if (( ${#builtin_plugins} )); then +    (( ${#custom_plugins} )) && echo # add a line of separation + +    print -P "%U%BBuilt-in plugins%b%u:" +    print -l ${(q-)builtin_plugins} | column +  fi +} + +function _omz::pr { +  (( $# > 0 && $+functions[_omz::pr::$1] )) || { +    cat <<EOF +Usage: omz pr <command> [options] + +Available commands: + +  clean                       Delete all PR branches (ohmyzsh/pull-*) +  test <PR_number_or_URL>     Fetch PR #NUMBER and rebase against master + +EOF +    return 1 +  } + +  local command="$1" +  shift + +  _omz::pr::$command "$@" +} + +function _omz::pr::clean { +  ( +    set -e +    builtin cd -q "$ZSH" + +    # Check if there are PR branches +    local fmt branches +    fmt="%(color:bold blue)%(align:18,right)%(refname:short)%(end)%(color:reset) %(color:dim bold red)%(objectname:short)%(color:reset) %(color:yellow)%(contents:subject)" +    branches="$(command git for-each-ref --sort=-committerdate --color --format="$fmt" "refs/heads/ohmyzsh/pull-*")" + +    # Exit if there are no PR branches +    if [[ -z "$branches" ]]; then +      _omz::log info "there are no Pull Request branches to remove." +      return +    fi + +    # Print found PR branches +    echo "$branches\n" +    # Confirm before removing the branches +    _omz::confirm "do you want remove these Pull Request branches? [Y/n] " +    # Only proceed if the answer is a valid yes option +    [[ "$REPLY" != [yY$'\n'] ]] && return + +    _omz::log info "removing all Oh My Zsh Pull Request branches..." +    command git branch --list 'ohmyzsh/pull-*' | while read branch; do +      command git branch -D "$branch" +    done +  ) +} + +function _omz::pr::test { +  # Allow $1 to be a URL to the pull request +  if [[ "$1" = https://* ]]; then +    1="${1:t}" +  fi + +  # Check the input +  if ! [[ -n "$1" && "$1" =~ ^[[:digit:]]+$ ]]; then +    echo >&2 "Usage: omz pr test <PR_NUMBER_or_URL>" +    return 1 +  fi + +  # Save current git HEAD +  local branch +  branch=$(builtin cd -q "$ZSH"; git symbolic-ref --short HEAD) || { +    _omz::log error "error when getting the current git branch. Aborting..." +    return 1 +  } + + +  # Fetch PR onto ohmyzsh/pull-<PR_NUMBER> branch and rebase against master +  # If any of these operations fail, undo the changes made +  ( +    set -e +    builtin cd -q "$ZSH" + +    # Get the ohmyzsh git remote +    command git remote -v | while read remote url _; do +      case "$url" in +      https://github.com/ohmyzsh/ohmyzsh(|.git)) found=1; break ;; +      git@github.com:ohmyzsh/ohmyzsh(|.git)) found=1; break ;; +      esac +    done + +    (( $found )) || { +      _omz::log error "could not found the ohmyzsh git remote. Aborting..." +      return 1 +    } + +    # Fetch pull request head +    _omz::log info "fetching PR #$1 to ohmyzsh/pull-$1..." +    command git fetch -f "$remote" refs/pull/$1/head:ohmyzsh/pull-$1 || { +      _omz::log error "error when trying to fetch PR #$1." +      return 1 +    } + +    # Rebase pull request branch against the current master +    _omz::log info "rebasing PR #$1..." +    command git rebase master ohmyzsh/pull-$1 || { +      command git rebase --abort &>/dev/null +      _omz::log warn "could not rebase PR #$1 on top of master." +      _omz::log warn "you might not see the latest stable changes." +      _omz::log info "run \`zsh\` to test the changes." +      return 1 +    } + +    _omz::log info "fetch of PR #${1} successful." +  ) + +  # If there was an error, abort running zsh to test the PR +  [[ $? -eq 0 ]] || return 1 + +  # Run zsh to test the changes +  _omz::log info "running \`zsh\` to test the changes. Run \`exit\` to go back." +  command zsh -l + +  # After testing, go back to the previous HEAD if the user wants +  _omz::confirm "do you want to go back to the previous branch? [Y/n] " +  # Only proceed if the answer is a valid yes option +  [[ "$REPLY" != [yY$'\n'] ]] && return + +  ( +    set -e +    builtin cd -q "$ZSH" + +    command git checkout "$branch" -- || { +      _omz::log error "could not go back to the previous branch ('$branch')." +      return 1 +    } +  ) +} + +function _omz::theme { +  (( $# > 0 && $+functions[_omz::theme::$1] )) || { +    cat <<EOF +Usage: omz theme <command> [options] + +Available commands: + +  list            List all available Oh My Zsh themes +  use <theme>     Load an Oh My Zsh theme + +EOF +    return 1 +  } + +  local command="$1" +  shift + +  _omz::theme::$command "$@" +} + +function _omz::theme::list { +  local -a custom_themes builtin_themes +  custom_themes=("$ZSH_CUSTOM"/**/*.zsh-theme(-.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::)) +  builtin_themes=("$ZSH"/themes/*.zsh-theme(-.N:t:r)) + +  # If the command is being piped, print all found line by line +  if [[ ! -t 1 ]]; then +    print -l ${(q-)custom_themes} ${(q-)builtin_themes} +    return +  fi + +  if (( ${#custom_themes} )); then +    print -P "%U%BCustom themes%b%u:" +    print -l ${(q-)custom_themes} | column +  fi + +  if (( ${#builtin_themes} )); then +    (( ${#custom_themes} )) && echo # add a line of separation + +    print -P "%U%BBuilt-in themes%b%u:" +    print -l ${(q-)builtin_themes} | column +  fi +} + +function _omz::theme::use { +  if [[ -z "$1" ]]; then +    echo >&2 "Usage: omz theme use <theme>" +    return 1 +  fi + +  # Respect compatibility with old lookup order +  if [[ -f "$ZSH_CUSTOM/$1.zsh-theme" ]]; then +    source "$ZSH_CUSTOM/$1.zsh-theme" +  elif [[ -f "$ZSH_CUSTOM/themes/$1.zsh-theme" ]]; then +    source "$ZSH_CUSTOM/themes/$1.zsh-theme" +  elif [[ -f "$ZSH/themes/$1.zsh-theme" ]]; then +    source "$ZSH/themes/$1.zsh-theme" +  else +    _omz::log error "theme '$1' not found" +    return 1 +  fi +} + +function _omz::update { +  local last_commit=$(cd "$ZSH"; git rev-parse HEAD) + +  # Run update script +  if [[ "$1" != --unattended ]]; then +    ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" --interactive +  else +    ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" +  fi + +  # Update last updated file +  zmodload zsh/datetime +  echo "LAST_EPOCH=$(( EPOCHSECONDS / 60 / 60 / 24 ))" >! "${ZSH_CACHE_DIR}/.zsh-update" +  # Remove update lock if it exists +  command rm -rf "$ZSH/log/update.lock" + +  # Restart the zsh session if there were changes +  if [[ "$1" != --unattended && "$(cd "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then +    # Old zsh versions don't have ZSH_ARGZERO +    local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}" +    # Check whether to run a login shell +    [[ "$zsh" = -* || -o login ]] && exec -l "${zsh#-}" || exec "$zsh" +  fi +} diff --git a/lib/clipboard.zsh b/lib/clipboard.zsh index 2c93d1bb5..122145f15 100644 --- a/lib/clipboard.zsh +++ b/lib/clipboard.zsh @@ -3,10 +3,23 @@  # This file has support for doing system clipboard copy and paste operations  # from the command line in a generic cross-platform fashion.  # -# On OS X and Windows, the main system clipboard or "pasteboard" is used. On other -# Unix-like OSes, this considers the X Windows CLIPBOARD selection to be the -# "system clipboard", and the X Windows `xclip` command must be installed. - +# This is uses essentially the same heuristic as neovim, with the additional +# special support for Cygwin. +# See: https://github.com/neovim/neovim/blob/e682d799fa3cf2e80a02d00c6ea874599d58f0e7/runtime/autoload/provider/clipboard.vim#L55-L121 +# +# - pbcopy, pbpaste (macOS) +# - cygwin (Windows running Cygwin) +# - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set) +# - xclip (if $DISPLAY is set) +# - xsel (if $DISPLAY is set) +# - lemonade (for SSH) https://github.com/pocke/lemonade +# - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/ +# - win32yank (Windows) +# - tmux (if $TMUX is set) +# +# Defines two functions, clipcopy and clippaste, based on the detected platform. +## +#  # clipcopy - Copy data to clipboard  #  # Usage: @@ -15,41 +28,8 @@  #  #  clipcopy <file>         - copies a file's contents to clipboard  # -function clipcopy() { -  emulate -L zsh -  local file=$1 -  if [[ $OSTYPE == darwin* ]]; then -    if [[ -z $file ]]; then -      pbcopy -    else -      cat $file | pbcopy -    fi -  elif [[ $OSTYPE == cygwin* ]]; then -    if [[ -z $file ]]; then -      cat > /dev/clipboard -    else -      cat $file > /dev/clipboard -    fi -  else -    if (( $+commands[xclip] )); then -      if [[ -z $file ]]; then -        xclip -in -selection clipboard -      else -        xclip -in -selection clipboard $file -      fi -    elif (( $+commands[xsel] )); then -      if [[ -z $file ]]; then -        xsel --clipboard --input  -      else -        cat "$file" | xsel --clipboard --input -      fi -    else -      print "clipcopy: Platform $OSTYPE not supported or xclip/xsel not installed" >&2 -      return 1 -    fi -  fi -} - +## +#  # clippaste - "Paste" data from clipboard to stdout  #  # Usage: @@ -67,20 +47,61 @@ function clipcopy() {  #  #   # Paste to a file  #   clippaste > file.txt -function clippaste() { +# +function detect-clipboard() {    emulate -L zsh -  if [[ $OSTYPE == darwin* ]]; then -    pbpaste -  elif [[ $OSTYPE == cygwin* ]]; then -    cat /dev/clipboard + +  if [[ "${OSTYPE}" == darwin* ]] && (( ${+commands[pbcopy]} )) && (( ${+commands[pbpaste]} )); then +    function clipcopy() { pbcopy < "${1:-/dev/stdin}"; } +    function clippaste() { pbpaste; } +  elif [[ "${OSTYPE}" == (cygwin|msys)* ]]; then +    function clipcopy() { cat "${1:-/dev/stdin}" > /dev/clipboard; } +    function clippaste() { cat /dev/clipboard; } +  elif [ -n "${WAYLAND_DISPLAY:-}" ] && (( ${+commands[wl-copy]} )) && (( ${+commands[wl-paste]} )); then +    function clipcopy() { wl-copy < "${1:-/dev/stdin}"; } +    function clippaste() { wl-paste; } +  elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then +    function clipcopy() { xclip -in -selection clipboard < "${1:-/dev/stdin}"; } +    function clippaste() { xclip -out -selection clipboard; } +  elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xsel]} )); then +    function clipcopy() { xsel --clipboard --input < "${1:-/dev/stdin}"; } +    function clippaste() { xsel --clipboard --output; } +  elif (( ${+commands[lemonade]} )); then +    function clipcopy() { lemonade copy < "${1:-/dev/stdin}"; } +    function clippaste() { lemonade paste; } +  elif (( ${+commands[doitclient]} )); then +    function clipcopy() { doitclient wclip < "${1:-/dev/stdin}"; } +    function clippaste() { doitclient wclip -r; } +  elif (( ${+commands[win32yank]} )); then +    function clipcopy() { win32yank -i < "${1:-/dev/stdin}"; } +    function clippaste() { win32yank -o; } +  elif [[ $OSTYPE == linux-android* ]] && (( $+commands[termux-clipboard-set] )); then +    function clipcopy() { termux-clipboard-set "${1:-/dev/stdin}"; } +    function clippaste() { termux-clipboard-get; } +  elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then +    function clipcopy() { tmux load-buffer "${1:--}"; } +    function clippaste() { tmux save-buffer -; } +  elif [[ $(uname -r) = *icrosoft* ]]; then +    function clipcopy() { clip.exe < "${1:-/dev/stdin}"; } +    function clippaste() { powershell.exe -noprofile -command Get-Clipboard; }    else -    if (( $+commands[xclip] )); then -      xclip -out -selection clipboard -    elif (( $+commands[xsel] )); then -      xsel --clipboard --output -    else -      print "clipcopy: Platform $OSTYPE not supported or xclip/xsel not installed" >&2 -      return 1 -    fi +    function _retry_clipboard_detection_or_fail() { +      local clipcmd="${1}"; shift +      if detect-clipboard; then +        "${clipcmd}" "$@" +      else +        print "${clipcmd}: Platform $OSTYPE not supported or xclip/xsel not installed" >&2 +        return 1 +      fi +    } +    function clipcopy() { _retry_clipboard_detection_or_fail clipcopy "$@"; } +    function clippaste() { _retry_clipboard_detection_or_fail clippaste "$@"; } +    return 1    fi  } + +# Detect at startup. A non-zero exit here indicates that the dummy clipboards were set, +# which is not really an error. If the user calls them, they will attempt to redetect +# (for example, perhaps the user has now installed xclip) and then either print an error +# or proceed successfully. +detect-clipboard || true diff --git a/lib/compfix.zsh b/lib/compfix.zsh index 68decc1ed..b09b283f2 100644 --- a/lib/compfix.zsh +++ b/lib/compfix.zsh @@ -18,7 +18,7 @@ function handle_completion_insecurities() {    insecure_dirs=( ${(f@):-"$(compaudit 2>/dev/null)"} )    # If no such directories exist, get us out of here. -  (( ! ${#insecure_dirs} )) && return +  [[ -z "${insecure_dirs}" ]] && return    # List ownership and permissions of all insecure directories.    print "[oh-my-zsh] Insecure completion-dependent directories detected:" diff --git a/lib/completion.zsh b/lib/completion.zsh index c7db2eb7b..ebaab0856 100644 --- a/lib/completion.zsh +++ b/lib/completion.zsh @@ -32,17 +32,17 @@ zstyle ':completion:*' list-colors ''  zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01'  if [[ "$OSTYPE" = solaris* ]]; then -  zstyle ':completion:*:*:*:*:processes' command "ps -u $USER -o pid,user,comm" +  zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm"  else -  zstyle ':completion:*:*:*:*:processes' command "ps -u $USER -o pid,user,comm -w -w" +  zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm -w -w"  fi  # disable named-directories autocompletion  zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories  # Use caching so that commands like apt and dpkg complete are useable -zstyle ':completion::complete:*' use-cache 1 -zstyle ':completion::complete:*' cache-path $ZSH_CACHE_DIR +zstyle ':completion:*' use-cache yes +zstyle ':completion:*' cache-path $ZSH_CACHE_DIR  # Don't complete uninteresting users  zstyle ':completion:*:*:*:users' ignored-patterns \ @@ -60,14 +60,16 @@ zstyle '*' single-ignored show  if [[ $COMPLETION_WAITING_DOTS = true ]]; then    expand-or-complete-with-dots() { -    # toggle line-wrapping off and back on again -    [[ -n "$terminfo[rmam]" && -n "$terminfo[smam]" ]] && echoti rmam -    print -Pn "%{%F{red}......%f%}" -    [[ -n "$terminfo[rmam]" && -n "$terminfo[smam]" ]] && echoti smam - +    print -Pn "%F{red}…%f"      zle expand-or-complete      zle redisplay    }    zle -N expand-or-complete-with-dots -  bindkey "^I" expand-or-complete-with-dots +  # Set the function as the default tab completion widget +  bindkey -M emacs "^I" expand-or-complete-with-dots +  bindkey -M viins "^I" expand-or-complete-with-dots +  bindkey -M vicmd "^I" expand-or-complete-with-dots  fi + +# automatically load bash completion functions +autoload -U +X bashcompinit && bashcompinit diff --git a/lib/diagnostics.zsh b/lib/diagnostics.zsh index 9c9905e4d..650520797 100644 --- a/lib/diagnostics.zsh +++ b/lib/diagnostics.zsh @@ -112,7 +112,7 @@ function _omz_diag_dump_one_big_text() {    command uname -a    builtin echo OSTYPE=$OSTYPE    builtin echo ZSH_VERSION=$ZSH_VERSION -  builtin echo User: $USER +  builtin echo User: $USERNAME    builtin echo umask: $(umask)    builtin echo    _omz_diag_dump_os_specific_version @@ -192,19 +192,19 @@ function _omz_diag_dump_one_big_text() {    command ls -ld ~/.oh*    builtin echo    builtin echo oh-my-zsh git state: -  (cd $ZSH && builtin echo "HEAD: $(git rev-parse HEAD)" && git remote -v && git status | command grep "[^[:space:]]") +  (builtin cd $ZSH && builtin echo "HEAD: $(git rev-parse HEAD)" && git remote -v && git status | command grep "[^[:space:]]")    if [[ $verbose -ge 1 ]]; then -    (cd $ZSH && git reflog --date=default | command grep pull) +    (builtin cd $ZSH && git reflog --date=default | command grep pull)    fi    builtin echo    if [[ -e $ZSH_CUSTOM ]]; then      local custom_dir=$ZSH_CUSTOM      if [[ -h $custom_dir ]]; then -      custom_dir=$(cd $custom_dir && pwd -P) +      custom_dir=$(builtin cd $custom_dir && pwd -P)      fi      builtin echo "oh-my-zsh custom dir:"      builtin echo "   $ZSH_CUSTOM ($custom_dir)" -    (cd ${custom_dir:h} && command find ${custom_dir:t} -name .git -prune -o -print) +    (builtin cd ${custom_dir:h} && command find ${custom_dir:t} -name .git -prune -o -print)      builtin echo    fi diff --git a/lib/directories.zsh b/lib/directories.zsh index 14064b86f..cf87bd7e4 100644 --- a/lib/directories.zsh +++ b/lib/directories.zsh @@ -21,7 +21,15 @@ alias 9='cd -9'  alias md='mkdir -p'  alias rd=rmdir -alias d='dirs -v | head -10' + +function d () { +  if [[ -n $1 ]]; then +    dirs "$@" +  else +    dirs -v | head -10 +  fi +} +compdef _dirs d  # List directory contents  alias lsa='ls -lah' diff --git a/lib/functions.zsh b/lib/functions.zsh index 4ef8920f6..9cc735196 100644 --- a/lib/functions.zsh +++ b/lib/functions.zsh @@ -1,16 +1,19 @@  function zsh_stats() { -  fc -l 1 | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n20 +  fc -l 1 \ +    | awk '{ CMD[$2]++; count++; } END { for (a in CMD) print CMD[a] " " CMD[a]*100/count "% " a }' \ +    | grep -v "./" | sort -nr | head -20 | column -c3 -s " " -t | nl  }  function uninstall_oh_my_zsh() { -  env ZSH=$ZSH sh $ZSH/tools/uninstall.sh +  env ZSH="$ZSH" sh "$ZSH/tools/uninstall.sh"  }  function upgrade_oh_my_zsh() { -  env ZSH=$ZSH sh $ZSH/tools/upgrade.sh +  echo >&2 "${fg[yellow]}Note: \`$0\` is deprecated. Use \`omz update\` instead.$reset_color" +  omz update  } -function take() { +function takedir() {    mkdir -p $@ && cd ${@:$#}  } @@ -21,7 +24,7 @@ function open_command() {    case "$OSTYPE" in      darwin*)  open_cmd='open' ;;      cygwin*)  open_cmd='cygstart' ;; -    linux*)   ! [[ $(uname -a) =~ "Microsoft" ]] && open_cmd='xdg-open' || { +    linux*)   [[ "$(uname -r)" != *icrosoft* ]] && open_cmd='nohup xdg-open' || {                  open_cmd='cmd.exe /c start ""'                  [[ -e "$1" ]] && { 1="$(wslpath -w "${1:a}")" || return 1 }                } ;; @@ -31,11 +34,30 @@ function open_command() {                ;;    esac -  # don't use nohup on OSX -  if [[ "$OSTYPE" == darwin* ]]; then -    ${=open_cmd} "$@" &>/dev/null +  ${=open_cmd} "$@" &>/dev/null +} + +function takeurl() { +  data=$(mktemp) +  curl -L $1 > $data +  tar xf $data +  thedir=$(tar tf $data | head -1) +  rm $data +  cd $thedir +} + +function takegit() { +  git clone $1 +  cd $(basename ${1%%.git}) +} + +function take() { +  if [[ $1 =~ ^(https?|ftp).*\.tar\.(gz|bz2|xz)$ ]]; then +    takeurl $1 +  elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then +    takegit $1    else -    nohup ${=open_cmd} "$@" &>/dev/null +    takedir $1    fi  } @@ -79,7 +101,7 @@ function try_alias_value() {  #    0 if the variable exists, 3 if it was set  #  function default() { -    test `typeset +m "$1"` && return 0 +    (( $+parameters[$1] )) && return 0      typeset -g "$1"="$2"   && return 3  } @@ -93,8 +115,8 @@ function default() {  #    0 if the env variable exists, 3 if it was set  #  function env_default() { -    env | grep -q "^$1=" && return 0 -    export "$1=$2"       && return 3 +    [[ ${parameters[$1]} = *-export* ]] && return 0 +    export "$1=$2" && return 3  } @@ -127,6 +149,7 @@ zmodload zsh/langinfo  #    -P causes spaces to be encoded as '%20' instead of '+'  function omz_urlencode() {    emulate -L zsh +  local -a opts    zparseopts -D -E -a opts r m P    local in_str=$1 diff --git a/lib/git.zsh b/lib/git.zsh index b92373153..c9363274c 100644 --- a/lib/git.zsh +++ b/lib/git.zsh @@ -1,26 +1,57 @@ -# Outputs current branch info in prompt format +# The git prompt's git commands are read-only and should not interfere with +# other processes. This environment variable is equivalent to running with `git +# --no-optional-locks`, but falls back gracefully for older versions of git. +# See git(1) for and git-status(1) for a description of that flag. +# +# We wrap in a local function instead of exporting the variable directly in +# order to avoid interfering with manually-run git commands by the user. +function __git_prompt_git() { +  GIT_OPTIONAL_LOCKS=0 command git "$@" +} +  function git_prompt_info() { +  # If we are on a folder not tracked by git, get out. +  # Otherwise, check for hide-info at global and local repository level +  if ! __git_prompt_git rev-parse --git-dir &> /dev/null \ +     || [[ "$(__git_prompt_git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then +    return 0 +  fi +    local ref -  if [[ "$(command git config --get oh-my-zsh.hide-status 2>/dev/null)" != "1" ]]; then -    ref=$(command git symbolic-ref HEAD 2> /dev/null) || \ -    ref=$(command git rev-parse --short HEAD 2> /dev/null) || return 0 -    echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX" +  ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \ +  || ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \ +  || return 0 + +  # Use global ZSH_THEME_GIT_SHOW_UPSTREAM=1 for including upstream remote info +  local upstream +  if (( ${+ZSH_THEME_GIT_SHOW_UPSTREAM} )); then +    upstream=$(__git_prompt_git rev-parse --abbrev-ref --symbolic-full-name "@{upstream}" 2>/dev/null) \ +    && upstream=" -> ${upstream}"    fi + +  echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref}${upstream}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"  }  # Checks if working tree is dirty  function parse_git_dirty() { -  local STATUS='' +  local STATUS    local -a FLAGS    FLAGS=('--porcelain') -  if [[ "$(command git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then -    if [[ $POST_1_7_2_GIT -gt 0 ]]; then -      FLAGS+='--ignore-submodules=dirty' -    fi -    if [[ "$DISABLE_UNTRACKED_FILES_DIRTY" == "true" ]]; then +  if [[ "$(__git_prompt_git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then +    if [[ "${DISABLE_UNTRACKED_FILES_DIRTY:-}" == "true" ]]; then        FLAGS+='--untracked-files=no'      fi -    STATUS=$(command git status ${FLAGS} 2> /dev/null | tail -n1) +    case "${GIT_STATUS_IGNORE_SUBMODULES:-}" in +      git) +        # let git decide (this respects per-repo config in .gitmodules) +        ;; +      *) +        # if unset: ignore dirty submodules +        # other values are passed to --ignore-submodules +        FLAGS+="--ignore-submodules=${GIT_STATUS_IGNORE_SUBMODULES:-dirty}" +        ;; +    esac +    STATUS=$(__git_prompt_git status ${FLAGS} 2> /dev/null | tail -1)    fi    if [[ -n $STATUS ]]; then      echo "$ZSH_THEME_GIT_PROMPT_DIRTY" @@ -32,10 +63,10 @@ function parse_git_dirty() {  # Gets the difference between the local and remote branches  function git_remote_status() {      local remote ahead behind git_remote_status git_remote_status_detailed -    remote=${$(command git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/} +    remote=${$(__git_prompt_git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/}      if [[ -n ${remote} ]]; then -        ahead=$(command git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l) -        behind=$(command git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l) +        ahead=$(__git_prompt_git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l) +        behind=$(__git_prompt_git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l)          if [[ $ahead -eq 0 ]] && [[ $behind -eq 0 ]]; then              git_remote_status="$ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE" @@ -64,11 +95,11 @@ function git_remote_status() {  # it's not a symbolic ref, but in a Git repo.  function git_current_branch() {    local ref -  ref=$(command git symbolic-ref --quiet HEAD 2> /dev/null) +  ref=$(__git_prompt_git symbolic-ref --quiet HEAD 2> /dev/null)    local ret=$?    if [[ $ret != 0 ]]; then      [[ $ret == 128 ]] && return  # no git repo. -    ref=$(command git rev-parse --short HEAD 2> /dev/null) || return +    ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) || return    fi    echo ${ref#refs/heads/}  } @@ -76,8 +107,8 @@ function git_current_branch() {  # Gets the number of commits ahead from remote  function git_commits_ahead() { -  if command git rev-parse --git-dir &>/dev/null; then -    local commits="$(git rev-list --count @{upstream}..HEAD 2>/dev/null)" +  if __git_prompt_git rev-parse --git-dir &>/dev/null; then +    local commits="$(__git_prompt_git rev-list --count @{upstream}..HEAD 2>/dev/null)"      if [[ -n "$commits" && "$commits" != 0 ]]; then        echo "$ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX$commits$ZSH_THEME_GIT_COMMITS_AHEAD_SUFFIX"      fi @@ -86,8 +117,8 @@ function git_commits_ahead() {  # Gets the number of commits behind remote  function git_commits_behind() { -  if command git rev-parse --git-dir &>/dev/null; then -    local commits="$(git rev-list --count HEAD..@{upstream} 2>/dev/null)" +  if __git_prompt_git rev-parse --git-dir &>/dev/null; then +    local commits="$(__git_prompt_git rev-list --count HEAD..@{upstream} 2>/dev/null)"      if [[ -n "$commits" && "$commits" != 0 ]]; then        echo "$ZSH_THEME_GIT_COMMITS_BEHIND_PREFIX$commits$ZSH_THEME_GIT_COMMITS_BEHIND_SUFFIX"      fi @@ -96,21 +127,21 @@ function git_commits_behind() {  # Outputs if current branch is ahead of remote  function git_prompt_ahead() { -  if [[ -n "$(command git rev-list origin/$(git_current_branch)..HEAD 2> /dev/null)" ]]; then +  if [[ -n "$(__git_prompt_git rev-list origin/$(git_current_branch)..HEAD 2> /dev/null)" ]]; then      echo "$ZSH_THEME_GIT_PROMPT_AHEAD"    fi  }  # Outputs if current branch is behind remote  function git_prompt_behind() { -  if [[ -n "$(command git rev-list HEAD..origin/$(git_current_branch) 2> /dev/null)" ]]; then +  if [[ -n "$(__git_prompt_git rev-list HEAD..origin/$(git_current_branch) 2> /dev/null)" ]]; then      echo "$ZSH_THEME_GIT_PROMPT_BEHIND"    fi  }  # Outputs if current branch exists on remote or not  function git_prompt_remote() { -  if [[ -n "$(command git show-ref origin/$(git_current_branch) 2> /dev/null)" ]]; then +  if [[ -n "$(__git_prompt_git show-ref origin/$(git_current_branch) 2> /dev/null)" ]]; then      echo "$ZSH_THEME_GIT_PROMPT_REMOTE_EXISTS"    else      echo "$ZSH_THEME_GIT_PROMPT_REMOTE_MISSING" @@ -120,102 +151,130 @@ function git_prompt_remote() {  # Formats prompt string for current git commit short SHA  function git_prompt_short_sha() {    local SHA -  SHA=$(command git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" +  SHA=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"  }  # Formats prompt string for current git commit long SHA  function git_prompt_long_sha() {    local SHA -  SHA=$(command git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" +  SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"  } -# Get the status of the working tree  function git_prompt_status() { -  local INDEX STATUS -  INDEX=$(command git status --porcelain -b 2> /dev/null) -  STATUS="" -  if $(echo "$INDEX" | command grep -E '^\?\? ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS" -  fi -  if $(echo "$INDEX" | grep '^A  ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS" -  elif $(echo "$INDEX" | grep '^M  ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS" -  elif $(echo "$INDEX" | grep '^MM ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS" -  fi -  if $(echo "$INDEX" | grep '^ M ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" -  elif $(echo "$INDEX" | grep '^AM ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" -  elif $(echo "$INDEX" | grep '^MM ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" -  elif $(echo "$INDEX" | grep '^ T ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" -  fi -  if $(echo "$INDEX" | grep '^R  ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_RENAMED$STATUS" -  fi -  if $(echo "$INDEX" | grep '^ D ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" -  elif $(echo "$INDEX" | grep '^D  ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" -  elif $(echo "$INDEX" | grep '^AD ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" -  fi -  if $(command git rev-parse --verify refs/stash >/dev/null 2>&1); then -    STATUS="$ZSH_THEME_GIT_PROMPT_STASHED$STATUS" -  fi -  if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS" -  fi -  if $(echo "$INDEX" | grep '^## [^ ]\+ .*ahead' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_AHEAD$STATUS" +  [[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return + +  # Maps a git status prefix to an internal constant +  # This cannot use the prompt constants, as they may be empty +  local -A prefix_constant_map +  prefix_constant_map=( +    '\?\? '     'UNTRACKED' +    'A  '       'ADDED' +    'M  '       'ADDED' +    'MM '       'MODIFIED' +    ' M '       'MODIFIED' +    'AM '       'MODIFIED' +    ' T '       'MODIFIED' +    'R  '       'RENAMED' +    ' D '       'DELETED' +    'D  '       'DELETED' +    'UU '       'UNMERGED' +    'ahead'     'AHEAD' +    'behind'    'BEHIND' +    'diverged'  'DIVERGED' +    'stashed'   'STASHED' +  ) + +  # Maps the internal constant to the prompt theme +  local -A constant_prompt_map +  constant_prompt_map=( +    'UNTRACKED' "$ZSH_THEME_GIT_PROMPT_UNTRACKED" +    'ADDED'     "$ZSH_THEME_GIT_PROMPT_ADDED" +    'MODIFIED'  "$ZSH_THEME_GIT_PROMPT_MODIFIED" +    'RENAMED'   "$ZSH_THEME_GIT_PROMPT_RENAMED" +    'DELETED'   "$ZSH_THEME_GIT_PROMPT_DELETED" +    'UNMERGED'  "$ZSH_THEME_GIT_PROMPT_UNMERGED" +    'AHEAD'     "$ZSH_THEME_GIT_PROMPT_AHEAD" +    'BEHIND'    "$ZSH_THEME_GIT_PROMPT_BEHIND" +    'DIVERGED'  "$ZSH_THEME_GIT_PROMPT_DIVERGED" +    'STASHED'   "$ZSH_THEME_GIT_PROMPT_STASHED" +  ) + +  # The order that the prompt displays should be added to the prompt +  local status_constants +  status_constants=( +    UNTRACKED ADDED MODIFIED RENAMED DELETED +    STASHED UNMERGED AHEAD BEHIND DIVERGED +  ) + +  local status_text="$(__git_prompt_git status --porcelain -b 2> /dev/null)" + +  # Don't continue on a catastrophic failure +  if [[ $? -eq 128 ]]; then +    return 1    fi -  if $(echo "$INDEX" | grep '^## [^ ]\+ .*behind' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_BEHIND$STATUS" + +  # A lookup table of each git status encountered +  local -A statuses_seen + +  if __git_prompt_git rev-parse --verify refs/stash &>/dev/null; then +    statuses_seen[STASHED]=1    fi -  if $(echo "$INDEX" | grep '^## [^ ]\+ .*diverged' &> /dev/null); then -    STATUS="$ZSH_THEME_GIT_PROMPT_DIVERGED$STATUS" + +  local status_lines +  status_lines=("${(@f)${status_text}}") + +  # If the tracking line exists, get and parse it +  if [[ "$status_lines[1]" =~ "^## [^ ]+ \[(.*)\]" ]]; then +    local branch_statuses +    branch_statuses=("${(@s/,/)match}") +    for branch_status in $branch_statuses; do +      if [[ ! $branch_status =~ "(behind|diverged|ahead) ([0-9]+)?" ]]; then +        continue +      fi +      local last_parsed_status=$prefix_constant_map[$match[1]] +      statuses_seen[$last_parsed_status]=$match[2] +    done    fi -  echo $STATUS -} - -# Compares the provided version of git to the version installed and on path -# Outputs -1, 0, or 1 if the installed version is less than, equal to, or -# greater than the input version, respectively. -function git_compare_version() { -  local INPUT_GIT_VERSION INSTALLED_GIT_VERSION i -  INPUT_GIT_VERSION=(${(s/./)1}) -  INSTALLED_GIT_VERSION=($(command git --version 2>/dev/null)) -  INSTALLED_GIT_VERSION=(${(s/./)INSTALLED_GIT_VERSION[3]}) - -  for i in {1..3}; do -    if [[ $INSTALLED_GIT_VERSION[$i] -gt $INPUT_GIT_VERSION[$i] ]]; then -      echo 1 -      return 0 + +  # For each status prefix, do a regex comparison +  for status_prefix in ${(k)prefix_constant_map}; do +    local status_constant="${prefix_constant_map[$status_prefix]}" +    local status_regex=$'(^|\n)'"$status_prefix" + +    if [[ "$status_text" =~ $status_regex ]]; then +      statuses_seen[$status_constant]=1      fi -    if [[ $INSTALLED_GIT_VERSION[$i] -lt $INPUT_GIT_VERSION[$i] ]]; then -      echo -1 -      return 0 +  done + +  # Display the seen statuses in the order specified +  local status_prompt +  for status_constant in $status_constants; do +    if (( ${+statuses_seen[$status_constant]} )); then +      local next_display=$constant_prompt_map[$status_constant] +      status_prompt="$next_display$status_prompt"      fi    done -  echo 0 + +  echo $status_prompt  }  # Outputs the name of the current user  # Usage example: $(git_current_user_name)  function git_current_user_name() { -  command git config user.name 2>/dev/null +  __git_prompt_git config user.name 2>/dev/null  }  # Outputs the email of the current user  # Usage example: $(git_current_user_email)  function git_current_user_email() { -  command git config user.email 2>/dev/null +  __git_prompt_git config user.email 2>/dev/null  } -# This is unlikely to change so make it all statically assigned -POST_1_7_2_GIT=$(git_compare_version "1.7.2") -# Clean up the namespace slightly by removing the checker function -unfunction git_compare_version +# Output the name of the root directory of the git repository +# Usage example: $(git_repo_name) +function git_repo_name() { +  local repo_path +  if repo_path="$(__git_prompt_git rev-parse --show-toplevel 2>/dev/null)" && [[ -n "$repo_path" ]]; then +    echo ${repo_path:t} +  fi +} diff --git a/lib/grep.zsh b/lib/grep.zsh index abc1650a1..a725e0f26 100644 --- a/lib/grep.zsh +++ b/lib/grep.zsh @@ -1,28 +1,41 @@ -# is x grep argument available? -grep-flag-available() { -    echo | grep $1 "" >/dev/null 2>&1 -} +__GREP_CACHE_FILE="$ZSH_CACHE_DIR"/grep-alias -GREP_OPTIONS="" +# See if there's a cache file modified in the last day +__GREP_ALIAS_CACHES=("$__GREP_CACHE_FILE"(Nm-1)) +if [[ -n "$__GREP_ALIAS_CACHES" ]]; then +    source "$__GREP_CACHE_FILE" +else +    grep-flags-available() { +        command grep "$@" "" &>/dev/null <<< "" +    } -# color grep results -if grep-flag-available --color=auto; then -    GREP_OPTIONS+=" --color=auto" -fi +    # Ignore these folders (if the necessary grep flags are available) +    EXC_FOLDERS="{.bzr,CVS,.git,.hg,.svn,.idea,.tox}" -# ignore VCS folders (if the necessary grep flags are available) -VCS_FOLDERS="{.bzr,CVS,.git,.hg,.svn}" +    # Check for --exclude-dir, otherwise check for --exclude. If --exclude +    # isn't available, --color won't be either (they were released at the same +    # time (v2.5): https://git.savannah.gnu.org/cgit/grep.git/tree/NEWS?id=1236f007 +    if grep-flags-available --color=auto --exclude-dir=.cvs; then +        GREP_OPTIONS="--color=auto --exclude-dir=$EXC_FOLDERS" +    elif grep-flags-available --color=auto --exclude=.cvs; then +        GREP_OPTIONS="--color=auto --exclude=$EXC_FOLDERS" +    fi -if grep-flag-available --exclude-dir=.cvs; then -    GREP_OPTIONS+=" --exclude-dir=$VCS_FOLDERS" -elif grep-flag-available --exclude=.cvs; then -    GREP_OPTIONS+=" --exclude=$VCS_FOLDERS" -fi +    if [[ -n "$GREP_OPTIONS" ]]; then +        # export grep, egrep and fgrep settings +        alias grep="grep $GREP_OPTIONS" +        alias egrep="egrep $GREP_OPTIONS" +        alias fgrep="fgrep $GREP_OPTIONS" -# export grep settings -alias grep="grep $GREP_OPTIONS" +        # write to cache file if cache directory is writable +        if [[ -w "$ZSH_CACHE_DIR" ]]; then +            alias -L grep egrep fgrep >| "$__GREP_CACHE_FILE" +        fi +    fi + +    # Clean up +    unset GREP_OPTIONS EXC_FOLDERS +    unfunction grep-flags-available +fi -# clean up -unset GREP_OPTIONS -unset VCS_FOLDERS -unfunction grep-flag-available +unset __GREP_CACHE_FILE __GREP_ALIAS_CACHES diff --git a/lib/history.zsh b/lib/history.zsh index d8bbd41c4..794076904 100644 --- a/lib/history.zsh +++ b/lib/history.zsh @@ -6,18 +6,19 @@ function omz_history {    if [[ -n "$clear" ]]; then      # if -c provided, clobber the history file      echo -n >| "$HISTFILE" -    echo >&2 History file deleted. Reload the session to see its effects. +    fc -p "$HISTFILE" +    echo >&2 History file deleted.    elif [[ -n "$list" ]]; then      # if -l provided, run as if calling `fc' directly      builtin fc "$@"    else      # unless a number is provided, show all history events (starting from 1) -    [[ ${@[-1]} = *[0-9]* ]] && builtin fc -l "$@" || builtin fc -l "$@" 1 +    [[ ${@[-1]-} = *[0-9]* ]] && builtin fc -l "$@" || builtin fc -l "$@" 1    fi  }  # Timestamp format -case $HIST_STAMPS in +case ${HIST_STAMPS-} in    "mm/dd/yyyy") alias history='omz_history -f' ;;    "dd.mm.yyyy") alias history='omz_history -E' ;;    "yyyy-mm-dd") alias history='omz_history -i' ;; @@ -27,8 +28,8 @@ esac  ## History file configuration  [ -z "$HISTFILE" ] && HISTFILE="$HOME/.zsh_history" -HISTSIZE=50000 -SAVEHIST=10000 +[ "$HISTSIZE" -lt 50000 ] && HISTSIZE=50000 +[ "$SAVEHIST" -lt 10000 ] && SAVEHIST=10000  ## History command configuration  setopt extended_history       # record timestamp of command in HISTFILE @@ -36,5 +37,4 @@ setopt hist_expire_dups_first # delete duplicates first when HISTFILE size excee  setopt hist_ignore_dups       # ignore duplicated commands history list  setopt hist_ignore_space      # ignore commands that start with space  setopt hist_verify            # show command with history expansion to user before running it -setopt inc_append_history     # add commands to HISTFILE in order of execution  setopt share_history          # share command history data diff --git a/lib/key-bindings.zsh b/lib/key-bindings.zsh index 0e056dc72..aaa73046e 100644 --- a/lib/key-bindings.zsh +++ b/lib/key-bindings.zsh @@ -15,56 +15,101 @@ if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then    zle -N zle-line-finish  fi -bindkey -e                                            # Use emacs key bindings +# Use emacs key bindings +bindkey -e -bindkey '\ew' kill-region                             # [Esc-w] - Kill from the cursor to the mark -bindkey -s '\el' 'ls\n'                               # [Esc-l] - run command: ls -bindkey '^r' history-incremental-search-backward      # [Ctrl-r] - Search backward incrementally for a specified string. The string may begin with ^ to anchor the search to the beginning of the line. -if [[ "${terminfo[kpp]}" != "" ]]; then -  bindkey "${terminfo[kpp]}" up-line-or-history       # [PageUp] - Up a line of history +# [PageUp] - Up a line of history +if [[ -n "${terminfo[kpp]}" ]]; then +  bindkey -M emacs "${terminfo[kpp]}" up-line-or-history +  bindkey -M viins "${terminfo[kpp]}" up-line-or-history +  bindkey -M vicmd "${terminfo[kpp]}" up-line-or-history  fi -if [[ "${terminfo[knp]}" != "" ]]; then -  bindkey "${terminfo[knp]}" down-line-or-history     # [PageDown] - Down a line of history +# [PageDown] - Down a line of history +if [[ -n "${terminfo[knp]}" ]]; then +  bindkey -M emacs "${terminfo[knp]}" down-line-or-history +  bindkey -M viins "${terminfo[knp]}" down-line-or-history +  bindkey -M vicmd "${terminfo[knp]}" down-line-or-history  fi -# start typing + [Up-Arrow] - fuzzy find history forward -if [[ "${terminfo[kcuu1]}" != "" ]]; then +# Start typing + [Up-Arrow] - fuzzy find history forward +if [[ -n "${terminfo[kcuu1]}" ]]; then    autoload -U up-line-or-beginning-search    zle -N up-line-or-beginning-search -  bindkey "${terminfo[kcuu1]}" up-line-or-beginning-search + +  bindkey -M emacs "${terminfo[kcuu1]}" up-line-or-beginning-search +  bindkey -M viins "${terminfo[kcuu1]}" up-line-or-beginning-search +  bindkey -M vicmd "${terminfo[kcuu1]}" up-line-or-beginning-search  fi -# start typing + [Down-Arrow] - fuzzy find history backward -if [[ "${terminfo[kcud1]}" != "" ]]; then +# Start typing + [Down-Arrow] - fuzzy find history backward +if [[ -n "${terminfo[kcud1]}" ]]; then    autoload -U down-line-or-beginning-search    zle -N down-line-or-beginning-search -  bindkey "${terminfo[kcud1]}" down-line-or-beginning-search + +  bindkey -M emacs "${terminfo[kcud1]}" down-line-or-beginning-search +  bindkey -M viins "${terminfo[kcud1]}" down-line-or-beginning-search +  bindkey -M vicmd "${terminfo[kcud1]}" down-line-or-beginning-search  fi -if [[ "${terminfo[khome]}" != "" ]]; then -  bindkey "${terminfo[khome]}" beginning-of-line      # [Home] - Go to beginning of line +# [Home] - Go to beginning of line +if [[ -n "${terminfo[khome]}" ]]; then +  bindkey -M emacs "${terminfo[khome]}" beginning-of-line +  bindkey -M viins "${terminfo[khome]}" beginning-of-line +  bindkey -M vicmd "${terminfo[khome]}" beginning-of-line  fi -if [[ "${terminfo[kend]}" != "" ]]; then -  bindkey "${terminfo[kend]}"  end-of-line            # [End] - Go to end of line +# [End] - Go to end of line +if [[ -n "${terminfo[kend]}" ]]; then +  bindkey -M emacs "${terminfo[kend]}"  end-of-line +  bindkey -M viins "${terminfo[kend]}"  end-of-line +  bindkey -M vicmd "${terminfo[kend]}"  end-of-line  fi -bindkey ' ' magic-space                               # [Space] - do history expansion - -bindkey '^[[1;5C' forward-word                        # [Ctrl-RightArrow] - move forward one word -bindkey '^[[1;5D' backward-word                       # [Ctrl-LeftArrow] - move backward one word - -if [[ "${terminfo[kcbt]}" != "" ]]; then -  bindkey "${terminfo[kcbt]}" reverse-menu-complete   # [Shift-Tab] - move through the completion menu backwards +# [Shift-Tab] - move through the completion menu backwards +if [[ -n "${terminfo[kcbt]}" ]]; then +  bindkey -M emacs "${terminfo[kcbt]}" reverse-menu-complete +  bindkey -M viins "${terminfo[kcbt]}" reverse-menu-complete +  bindkey -M vicmd "${terminfo[kcbt]}" reverse-menu-complete  fi -bindkey '^?' backward-delete-char                     # [Backspace] - delete backward -if [[ "${terminfo[kdch1]}" != "" ]]; then -  bindkey "${terminfo[kdch1]}" delete-char            # [Delete] - delete forward +# [Backspace] - delete backward +bindkey -M emacs '^?' backward-delete-char +bindkey -M viins '^?' backward-delete-char +bindkey -M vicmd '^?' backward-delete-char +# [Delete] - delete forward +if [[ -n "${terminfo[kdch1]}" ]]; then +  bindkey -M emacs "${terminfo[kdch1]}" delete-char +  bindkey -M viins "${terminfo[kdch1]}" delete-char +  bindkey -M vicmd "${terminfo[kdch1]}" delete-char  else -  bindkey "^[[3~" delete-char -  bindkey "^[3;5~" delete-char -  bindkey "\e[3~" delete-char +  bindkey -M emacs "^[[3~" delete-char +  bindkey -M viins "^[[3~" delete-char +  bindkey -M vicmd "^[[3~" delete-char + +  bindkey -M emacs "^[3;5~" delete-char +  bindkey -M viins "^[3;5~" delete-char +  bindkey -M vicmd "^[3;5~" delete-char  fi +# [Ctrl-Delete] - delete whole forward-word +bindkey -M emacs '^[[3;5~' kill-word +bindkey -M viins '^[[3;5~' kill-word +bindkey -M vicmd '^[[3;5~' kill-word + +# [Ctrl-RightArrow] - move forward one word +bindkey -M emacs '^[[1;5C' forward-word +bindkey -M viins '^[[1;5C' forward-word +bindkey -M vicmd '^[[1;5C' forward-word +# [Ctrl-LeftArrow] - move backward one word +bindkey -M emacs '^[[1;5D' backward-word +bindkey -M viins '^[[1;5D' backward-word +bindkey -M vicmd '^[[1;5D' backward-word + + +bindkey '\ew' kill-region                             # [Esc-w] - Kill from the cursor to the mark +bindkey -s '\el' 'ls\n'                               # [Esc-l] - run command: ls +bindkey '^r' history-incremental-search-backward      # [Ctrl-r] - Search backward incrementally for a specified string. The string may begin with ^ to anchor the search to the beginning of the line. +bindkey ' ' magic-space                               # [Space] - don't do history expansion + +  # Edit the current command line in $EDITOR  autoload -U edit-command-line  zle -N edit-command-line diff --git a/lib/misc.zsh b/lib/misc.zsh index f45c10757..a5d3af998 100644 --- a/lib/misc.zsh +++ b/lib/misc.zsh @@ -1,17 +1,17 @@ -## Load smart urls if available -# bracketed-paste-magic is known buggy in zsh 5.1.1 (only), so skip it there; see #4434  autoload -Uz is-at-least -if [[ $ZSH_VERSION != 5.1.1 ]]; then + +# *-magic is known buggy in some versions; disable if so +if [[ $DISABLE_MAGIC_FUNCTIONS != true ]]; then    for d in $fpath; do -  	if [[ -e "$d/url-quote-magic" ]]; then -  		if is-at-least 5.1; then -  			autoload -Uz bracketed-paste-magic -  			zle -N bracketed-paste bracketed-paste-magic -  		fi -  		autoload -Uz url-quote-magic -  		zle -N self-insert url-quote-magic -      break -  	fi +    if [[ -e "$d/url-quote-magic" ]]; then +      if is-at-least 5.1; then +        autoload -Uz bracketed-paste-magic +        zle -N bracketed-paste bracketed-paste-magic +      fi +      autoload -Uz url-quote-magic +      zle -N self-insert url-quote-magic +    break +    fi    done  fi @@ -22,20 +22,14 @@ env_default 'PAGER' 'less'  env_default 'LESS' '-R'  ## super user alias -alias _='sudo' -alias please='sudo' +alias _='sudo '  ## more intelligent acking for ubuntu users -if which ack-grep &> /dev/null; then +if (( $+commands[ack-grep] )); then    alias afind='ack-grep -il'  else    alias afind='ack -il'  fi -# only define LC_CTYPE if undefined -if [[ -z "$LC_CTYPE" && -z "$LC_ALL" ]]; then -	export LC_CTYPE=${LANG%%:*} # pick the first entry from LANG -fi -  # recognize comments  setopt interactivecomments diff --git a/lib/nvm.zsh b/lib/nvm.zsh index 4a8b6811e..2fe57a8f4 100644 --- a/lib/nvm.zsh +++ b/lib/nvm.zsh @@ -1,9 +1,6 @@ -# get the node.js version +# get the nvm-controlled node.js version  function nvm_prompt_info() { -  [[ -f "$NVM_DIR/nvm.sh" ]] || return -  local nvm_prompt -  nvm_prompt=$(node -v 2>/dev/null) -  [[ "${nvm_prompt}x" == "x" ]] && return -  nvm_prompt=${nvm_prompt:1} +  which nvm &>/dev/null || return +  local nvm_prompt=${$(nvm current)#v}    echo "${ZSH_THEME_NVM_PROMPT_PREFIX}${nvm_prompt}${ZSH_THEME_NVM_PROMPT_SUFFIX}"  } diff --git a/lib/prompt_info_functions.zsh b/lib/prompt_info_functions.zsh index 1d5c23e41..48f033da6 100644 --- a/lib/prompt_info_functions.zsh +++ b/lib/prompt_info_functions.zsh @@ -10,9 +10,16 @@  # Dummy implementations that return false to prevent command_not_found  # errors with themes, that implement these functions  # Real implementations will be used when the respective plugins are loaded -function chruby_prompt_info hg_prompt_info pyenv_prompt_info \ -  rbenv_prompt_info svn_prompt_info vi_mode_prompt_info \ -  virtualenv_prompt_info jenv_prompt_info { +function chruby_prompt_info \ +  rbenv_prompt_info \ +  hg_prompt_info \ +  pyenv_prompt_info \ +  svn_prompt_info \ +  vi_mode_prompt_info \ +  virtualenv_prompt_info \ +  jenv_prompt_info \ +  tf_prompt_info \ +{    return 1  } @@ -22,10 +29,13 @@ function rvm_prompt_info() {    [ -f $HOME/.rvm/bin/rvm-prompt ] || return 1    local rvm_prompt    rvm_prompt=$($HOME/.rvm/bin/rvm-prompt ${=ZSH_THEME_RVM_PROMPT_OPTIONS} 2>/dev/null) -  [[ "${rvm_prompt}x" == "x" ]] && return 1 -  echo "${ZSH_THEME_RVM_PROMPT_PREFIX:=(}${rvm_prompt}${ZSH_THEME_RVM_PROMPT_SUFFIX:=)}" +  [[ -z "${rvm_prompt}" ]] && return 1 +  echo "${ZSH_THEME_RUBY_PROMPT_PREFIX}${rvm_prompt}${ZSH_THEME_RUBY_PROMPT_SUFFIX}"  } +ZSH_THEME_RVM_PROMPT_OPTIONS="i v g" + +  # use this to enable users to see their ruby version, no matter which  # version management system they use  function ruby_prompt_info() { diff --git a/lib/spectrum.zsh b/lib/spectrum.zsh index 312ab2248..d5c22a8c5 100644 --- a/lib/spectrum.zsh +++ b/lib/spectrum.zsh @@ -1,4 +1,3 @@ -#! /bin/zsh  # A script to make using 256 colors in zsh less painful.  # P.C. Shyamshankar <sykora@lucentbeing.com>  # Copied from https://github.com/sykora/etc/blob/master/zsh/functions/spectrum/ @@ -6,32 +5,31 @@  typeset -AHg FX FG BG  FX=( -    reset     "%{[00m%}" -    bold      "%{[01m%}" no-bold      "%{[22m%}" -    italic    "%{[03m%}" no-italic    "%{[23m%}" -    underline "%{[04m%}" no-underline "%{[24m%}" -    blink     "%{[05m%}" no-blink     "%{[25m%}" -    reverse   "%{[07m%}" no-reverse   "%{[27m%}" +  reset     "%{[00m%}" +  bold      "%{[01m%}" no-bold      "%{[22m%}" +  italic    "%{[03m%}" no-italic    "%{[23m%}" +  underline "%{[04m%}" no-underline "%{[24m%}" +  blink     "%{[05m%}" no-blink     "%{[25m%}" +  reverse   "%{[07m%}" no-reverse   "%{[27m%}"  )  for color in {000..255}; do -    FG[$color]="%{[38;5;${color}m%}" -    BG[$color]="%{[48;5;${color}m%}" +  FG[$color]="%{[38;5;${color}m%}" +  BG[$color]="%{[48;5;${color}m%}"  done - -ZSH_SPECTRUM_TEXT=${ZSH_SPECTRUM_TEXT:-Arma virumque cano Troiae qui primus ab oris} -  # Show all 256 colors with color number  function spectrum_ls() { +  local ZSH_SPECTRUM_TEXT=${ZSH_SPECTRUM_TEXT:-Arma virumque cano Troiae qui primus ab oris}    for code in {000..255}; do -    print -P -- "$code: %{$FG[$code]%}$ZSH_SPECTRUM_TEXT%{$reset_color%}" +    print -P -- "$code: $FG[$code]$ZSH_SPECTRUM_TEXT%{$reset_color%}"    done  }  # Show all 256 colors where the background is set to specific color  function spectrum_bls() { +  local ZSH_SPECTRUM_TEXT=${ZSH_SPECTRUM_TEXT:-Arma virumque cano Troiae qui primus ab oris}    for code in {000..255}; do -    print -P -- "$code: %{$BG[$code]%}$ZSH_SPECTRUM_TEXT%{$reset_color%}" +    print -P -- "$code: $BG[$code]$ZSH_SPECTRUM_TEXT%{$reset_color%}"    done  } diff --git a/lib/termsupport.zsh b/lib/termsupport.zsh index 87d55ee89..33451ef1f 100644 --- a/lib/termsupport.zsh +++ b/lib/termsupport.zsh @@ -10,39 +10,39 @@ function title {    emulate -L zsh    setopt prompt_subst -  [[ "$EMACS" == *term* ]] && return +  [[ "$INSIDE_EMACS" == *term* ]] && return    # if $2 is unset use $1 as default    # if it is set and empty, leave it as is    : ${2=$1}    case "$TERM" in -    cygwin|xterm*|putty*|rxvt*|ansi) -      print -Pn "\e]2;$2:q\a" # set window name -      print -Pn "\e]1;$1:q\a" # set tab name +    cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty|st*) +      print -Pn "\e]2;${2:q}\a" # set window name +      print -Pn "\e]1;${1:q}\a" # set tab name        ;; -    screen*) -      print -Pn "\ek$1:q\e\\" # set screen hardstatus +    screen*|tmux*) +      print -Pn "\ek${1:q}\e\\" # set screen hardstatus        ;;      *)        if [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then -        print -Pn "\e]2;$2:q\a" # set window name -        print -Pn "\e]1;$1:q\a" # set tab name +        print -Pn "\e]2;${2:q}\a" # set window name +        print -Pn "\e]1;${1:q}\a" # set tab name        else          # Try to use terminfo to set the title          # If the feature is available set title          if [[ -n "$terminfo[fsl]" ]] && [[ -n "$terminfo[tsl]" ]]; then -	  echoti tsl -	  print -Pn "$1" -	  echoti fsl -	fi +          echoti tsl +          print -Pn "$1" +          echoti fsl +        fi        fi        ;;    esac  }  ZSH_THEME_TERM_TAB_TITLE_IDLE="%15<..<%~%<<" #15 char left truncated PWD -ZSH_THEME_TERM_TITLE_IDLE="%n@%m: %~" +ZSH_THEME_TERM_TITLE_IDLE="%n@%m:%~"  # Avoid duplication of directory in terminals with independent dir display  if [[ "$TERM_PROGRAM" == Apple_Terminal ]]; then    ZSH_THEME_TERM_TITLE_IDLE="%n@%m" @@ -50,22 +50,52 @@ fi  # Runs before showing the prompt  function omz_termsupport_precmd { -  emulate -L zsh - -  if [[ "$DISABLE_AUTO_TITLE" == true ]]; then -    return -  fi - +  [[ "${DISABLE_AUTO_TITLE:-}" == true ]] && return    title $ZSH_THEME_TERM_TAB_TITLE_IDLE $ZSH_THEME_TERM_TITLE_IDLE  }  # Runs before executing the command  function omz_termsupport_preexec { +  [[ "${DISABLE_AUTO_TITLE:-}" == true ]] && return +    emulate -L zsh    setopt extended_glob -  if [[ "$DISABLE_AUTO_TITLE" == true ]]; then -    return +  # split command into array of arguments +  local -a cmdargs +  cmdargs=("${(z)2}") +  # if running fg, extract the command from the job description +  if [[ "${cmdargs[1]}" = fg ]]; then +    # get the job id from the first argument passed to the fg command +    local job_id jobspec="${cmdargs[2]#%}" +    # logic based on jobs arguments: +    # http://zsh.sourceforge.net/Doc/Release/Jobs-_0026-Signals.html#Jobs +    # https://www.zsh.org/mla/users/2007/msg00704.html +    case "$jobspec" in +      <->) # %number argument: +        # use the same <number> passed as an argument +        job_id=${jobspec} ;; +      ""|%|+) # empty, %% or %+ argument: +        # use the current job, which appears with a + in $jobstates: +        # suspended:+:5071=suspended (tty output) +        job_id=${(k)jobstates[(r)*:+:*]} ;; +      -) # %- argument: +        # use the previous job, which appears with a - in $jobstates: +        # suspended:-:6493=suspended (signal) +        job_id=${(k)jobstates[(r)*:-:*]} ;; +      [?]*) # %?string argument: +        # use $jobtexts to match for a job whose command *contains* <string> +        job_id=${(k)jobtexts[(r)*${(Q)jobspec}*]} ;; +      *) # %string argument: +        # use $jobtexts to match for a job whose command *starts with* <string> +        job_id=${(k)jobtexts[(r)${(Q)jobspec}*]} ;; +    esac + +    # override preexec function arguments with job command +    if [[ -n "${jobtexts[$job_id]}" ]]; then +      1="${jobtexts[$job_id]}" +      2="${jobtexts[$job_id]}" +    fi    fi    # cmd name only, or if this is sudo or ssh, the next cmd @@ -75,8 +105,9 @@ function omz_termsupport_preexec {    title '$CMD' '%100>...>$LINE%<<'  } -precmd_functions+=(omz_termsupport_precmd) -preexec_functions+=(omz_termsupport_preexec) +autoload -U add-zsh-hook +add-zsh-hook precmd omz_termsupport_precmd +add-zsh-hook preexec omz_termsupport_preexec  # Keep Apple Terminal.app's current working directory updated @@ -90,16 +121,17 @@ if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then    function update_terminalapp_cwd() {      emulate -L zsh -    # Percent-encode the pathname. -    local URL_PATH="$(omz_urlencode -P $PWD)" -    [[ $? != 0 ]] && return 1 +    # Percent-encode the host and path names. +    local URL_HOST URL_PATH +    URL_HOST="$(omz_urlencode -P $HOST)" || return 1 +    URL_PATH="$(omz_urlencode -P $PWD)" || return 1      # Undocumented Terminal.app-specific control sequence -    printf '\e]7;%s\a' "file://$HOST$URL_PATH" +    printf '\e]7;%s\a' "file://$URL_HOST$URL_PATH"    }    # Use a precmd hook instead of a chpwd hook to avoid contaminating output -  precmd_functions+=(update_terminalapp_cwd) +  add-zsh-hook precmd update_terminalapp_cwd    # Run once to get initial cwd set    update_terminalapp_cwd  fi diff --git a/lib/theme-and-appearance.zsh b/lib/theme-and-appearance.zsh index 96f34aa81..0b71de372 100644 --- a/lib/theme-and-appearance.zsh +++ b/lib/theme-and-appearance.zsh @@ -19,7 +19,7 @@ if [[ "$DISABLE_LS_COLORS" != "true" ]]; then      # coreutils, so prefer it to "gls".      gls --color -d . &>/dev/null && alias ls='gls --color=tty'      colorls -G -d . &>/dev/null && alias ls='colorls -G' -  elif [[ "$OSTYPE" == darwin* ]]; then +  elif [[ "$OSTYPE" == (darwin|freebsd)* ]]; then      # this is a good alias, it works by default just using $LSCOLORS      ls -G . &>/dev/null && alias ls='ls -G' @@ -39,17 +39,21 @@ if [[ "$DISABLE_LS_COLORS" != "true" ]]; then    fi  fi +# enable diff color if possible. +if command diff --color . . &>/dev/null; then +  alias diff='diff --color' +fi +  setopt auto_cd  setopt multios  setopt prompt_subst  [[ -n "$WINDOW" ]] && SCREEN_NO="%B$WINDOW%b " || SCREEN_NO="" -# Apply theming defaults -PS1="%n@%m:%~%# " -  # git theming default: Variables for theming the git info prompt  ZSH_THEME_GIT_PROMPT_PREFIX="git:("         # Prefix at the very beginning of the prompt, before the branch name  ZSH_THEME_GIT_PROMPT_SUFFIX=")"             # At the very end of the prompt  ZSH_THEME_GIT_PROMPT_DIRTY="*"              # Text to display if the branch is dirty  ZSH_THEME_GIT_PROMPT_CLEAN=""               # Text to display if the branch is clean +ZSH_THEME_RUBY_PROMPT_PREFIX="(" +ZSH_THEME_RUBY_PROMPT_SUFFIX=")" | 
