aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorromkatv <roman.perepelitsa@gmail.com>2019-05-21 13:26:34 +0300
committerromkatv <roman.perepelitsa@gmail.com>2019-05-21 13:26:34 +0300
commit5800b79f513171078aed01aaf434937c25d6c172 (patch)
tree2897f7a6d601be3682e0f5e416962e089a9d4ab9
parent4e81de532228ec360af488e25c1522cc8bfd7d64 (diff)
speed up node_version and nvm prompts; fixes #12
-rwxr-xr-xpowerlevel9k.zsh-theme154
1 files changed, 123 insertions, 31 deletions
diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme
index a91f827a..ef99f010 100755
--- a/powerlevel9k.zsh-theme
+++ b/powerlevel9k.zsh-theme
@@ -1130,36 +1130,133 @@ prompt_load() {
"$1_prompt_segment" "${0}_${current_state}" "$2" "${load_states[$current_state]}" "$DEFAULT_COLOR" 'LOAD_ICON' 0 '' "$load_avg"
}
+function _p9k_cached_cmd_stdout() {
+ local cmd=$commands[$1]
+ [[ -n $cmd ]] || return
+ shift
+ local -H stat
+ zstat -H stat -- $cmd 2>/dev/null || return
+ if ! _p9k_cache_get "$0" "$stat[inode]" "$stat[mtime]" "$stat[size]" "$cmd" "$@"; then
+ local out
+ out=$($cmd "$@" 2>/dev/null)
+ _p9k_cache_set $(( ! $? )) "$out"
+ fi
+ (( $_P9K_CACHE_VAL[1] )) || return
+ _P9K_RETVAL=$_P9K_CACHE_VAL[2]
+}
+
################################################################
# Segment to diplay Node version
set_default P9K_NODE_VERSION_PROJECT_ONLY false
prompt_node_version() {
- if [ "$P9K_NODE_VERSION_PROJECT_ONLY" = true ] ; then
- local foundProject=false # Variable to stop searching if a project is found
- local currentDir=$(pwd) # Variable to iterate through the path ancestry tree
+ (( $+commands[node] )) || return
- # Search as long as no project could been found or until the root directory
- # has been reached
- while [ "$foundProject" = false -a ! "$currentDir" = "/" ] ; do
-
- # Check if directory contains a project description
- if [[ -e "$currentDir/package.json" ]] ; then
- foundProject=true
- break
- fi
- # Go to the parent directory
- currentDir="$(dirname "$currentDir")"
+ if [[ $P9K_NODE_VERSION_PROJECT_ONLY == true ]] ; then
+ local dir=$PWD
+ while true; do
+ [[ $dir == / ]] && return
+ [[ -e $dir/package.json ]] && break
+ dir=${dir:h}
done
fi
- # Show version if a project has been found, or set to always show
- if [ "$P9K_NODE_VERSION_PROJECT_ONLY" != true -o "$foundProject" = true ] ; then
- # Get the node version
- local node_version=$(node -v 2>/dev/null)
+ _p9k_cached_cmd_stdout node --version && [[ $_P9K_RETVAL == v?* ]] || return
+ "$1_prompt_segment" "$0" "$2" "green" "white" 'NODE_ICON' 0 '' "${_P9K_RETVAL#v}"
+}
+
+# Almost the same as `nvm_version default` but faster. The differences shouldn't affect
+# the observable behavior of Powerlevel10k.
+function _p9k_nvm_ls_default() {
+ local v=default
+ local -a seen=($v)
+ local target
+ while [[ -r $NVM_DIR/alias/$v ]] && read target <$NVM_DIR/alias/$v; do
+ [[ -n $target && ${seen[(I)$target]} == 0 ]] || return
+ seen+=$target
+ v=$target
+ done
+
+ case $v in
+ default|N/A)
+ return 1
+ ;;
+ system|v)
+ _P9K_RETVAL=system
+ return
+ ;;
+ iojs-[0-9]*)
+ v=iojs-v${v#iojs-}
+ ;;
+ [0-9]*)
+ v=v$v
+ ;;
+ esac
+
+ if [[ $v == v*.*.* ]]; then
+ if [[ -x $NVM_DIR/versions/node/$v/bin/node || -x $NVM_DIR/$v/bin/node ]]; then
+ _P9K_RETVAL=$v
+ return
+ elif [[ -x $NVM_DIR/versions/io.js/$v/bin/node ]]; then
+ _P9K_RETVAL=iojs-$v
+ return
+ else
+ return 1
+ fi
+ fi
+
+ local -a dirs=()
+ case $v in
+ node|node-|stable)
+ dirs=($NVM_DIR/versions/node $NVM_DIR)
+ v='(v[1-9]*|v0.*[02468].*)'
+ ;;
+ unstable)
+ dirs=($NVM_DIR/versions/node $NVM_DIR)
+ v='v0.*[13579].*'
+ ;;
+ iojs*)
+ dirs=($NVM_DIR/versions/io.js)
+ v=v${${${v#iojs}#-}#v}'*'
+ ;;
+ *)
+ dirs=($NVM_DIR/versions/node $NVM_DIR $NVM_DIR/versions/io.js)
+ v=v${v#v}'*'
+ ;;
+ esac
+
+ local -a matches=(${^dirs}/${~v}(/N))
+ (( $#matches )) || return
+
+ emulate -L zsh && setopt extendedglob
+
+ local max path
+ local -a match
+ for path in ${(Oa)matches}; do
+ [[ ${path:t} == (#b)v(*).(*).(*) ]] || continue
+ v=${(j::)${(@l:6::0:)match}}
+ [[ $v > $max ]] || continue
+ max=$v
+ _P9K_RETVAL=${path:t}
+ [[ ${path:h:t} != io.js ]] || _P9K_RETVAL=iojs-$_P9K_RETVAL
+ done
+
+ [[ -n $max ]]
+}
- # Return if node is not installed
- [[ -z "${node_version}" ]] && return
- "$1_prompt_segment" "$0" "$2" "green" "white" 'NODE_ICON' 0 '' "${${node_version:1}//\%/%%}"
+# The same as `nvm_version current` but faster.
+_p9k_nvm_ls_current() {
+ local node_path=${commands[node]:A}
+ [[ -n $node_path ]] || return
+
+ local nvm_dir=${NVM_DIR:A}
+ if [[ -n $nvm_dir && $node_path == $nvm_dir/versions/io.js/* ]]; then
+ _p9k_cached_cmd_stdout iojs --version || return
+ _P9K_RETVAL=iojs-v${_P9K_RETVAL#v}
+ elif [[ -n $nvm_dir && $node_path == $nvm_dir/* ]]; then
+ _p9k_cached_cmd_stdout node --version || return
+ _P9K_RETVAL=v${_P9K_RETVAL#v}
+ else
+ _P9K_RETVAL=system
fi
}
@@ -1167,16 +1264,10 @@ prompt_node_version() {
# Segment to display Node version from NVM
# Only prints the segment if different than the default value
prompt_nvm() {
- local node_version nvm_default
- (( $+functions[nvm_version] )) || return
-
- node_version=$(nvm_version current)
- [[ -z "${node_version}" || ${node_version} == "none" ]] && return
-
- nvm_default=$(nvm_version default)
- [[ "$node_version" =~ "$nvm_default" ]] && return
-
- $1_prompt_segment "$0" "$2" "magenta" "black" 'NODE_ICON' 0 '' "${${node_version:1}//\%/%%}"
+ [[ -n $NVM_DIR ]] && _p9k_nvm_ls_current || return
+ local current=$_P9K_RETVAL
+ ! _p9k_nvm_ls_default || [[ $_P9K_RETVAL != $current ]] || return
+ $1_prompt_segment "$0" "$2" "magenta" "black" 'NODE_ICON' 0 '' "${${current#v}//\%/%%}"
}
################################################################
@@ -2405,5 +2496,6 @@ autoload -Uz add-zsh-hook
zmodload zsh/datetime
zmodload zsh/mathfunc
zmodload zsh/system
+zmodload -F zsh/stat b:zstat
prompt_powerlevel9k_setup "$@"