diff options
author | romkatv <roman.perepelitsa@gmail.com> | 2019-10-12 13:02:11 +0300 |
---|---|---|
committer | romkatv <roman.perepelitsa@gmail.com> | 2019-10-12 13:02:11 +0300 |
commit | bd304edb47fbdc1bf688ab68d41c89d61e474bff (patch) | |
tree | ccbaf54b0e8a15979c1a555033780385d4bd88fb /internal | |
parent | e4849cc431f7c375577d6f306f476dc9267da132 (diff) | |
parent | 0302e68913458a2d961b2dcdd0dfc670f308fe29 (diff) |
Merge branch 'master' into screenshot
Diffstat (limited to 'internal')
-rw-r--r-- | internal/configure.zsh | 74 | ||||
-rw-r--r--[-rwxr-xr-x] | internal/icons.zsh | 435 | ||||
-rw-r--r--[-rwxr-xr-x] | internal/p10k.zsh | 1631 | ||||
-rwxr-xr-x | internal/wizard.zsh | 897 |
4 files changed, 2135 insertions, 902 deletions
diff --git a/internal/configure.zsh b/internal/configure.zsh index 924a75d1..202978f6 100644 --- a/internal/configure.zsh +++ b/internal/configure.zsh @@ -1,51 +1,77 @@ -typeset -gr __p9k_wizard_columns=70 # DO NOT SUBMIT: 76 -typeset -gr __p9k_wizard_lines=20 # DO NOT SUBMIT: 21 -typeset -gr __p9k_zd=${${ZDOTDIR:-$HOME}:A} -typeset -gr __p9k_zd_u=${${(q-)__p9k_zd}/#(#b)$HOME(|\/*)/'~'$match[1]} +typeset -gr __p9k_wizard_columns=55 +typeset -gr __p9k_wizard_lines=21 +typeset -gr __p9k_zd=${ZDOTDIR:-$HOME} +typeset -gr __p9k_zd_u=${${${(q)__p9k_zd}/#(#b)${(q)HOME}(|\/*)/'~'$match[1]}//\%/%%} typeset -gr __p9k_cfg_basename=.p10k.zsh typeset -gr __p9k_cfg_path=$__p9k_zd/$__p9k_cfg_basename typeset -gr __p9k_cfg_path_u=$__p9k_zd_u/$__p9k_cfg_basename typeset -gr __p9k_zshrc=$__p9k_zd/.zshrc typeset -gr __p9k_zshrc_u=$__p9k_zd_u/.zshrc -typeset -gr __p9k_root_dir_u=${${(q-)__p9k_root_dir}/#(#b)$HOME(|\/*)/'~'$match[1]} +typeset -gr __p9k_root_dir_u=${${${(q)__p9k_root_dir}/#(#b)${(q)HOME}(|\/*)/'~'$match[1]}//\%/%%} function _p9k_can_configure() { emulate -L zsh - setopt err_return extended_glob no_prompt_{bang,subst} prompt_{cr,percent,sp} + setopt extended_glob no_prompt_{bang,subst} prompt_percent [[ $1 == '-q' ]] && local -i q=1 || local -i q=0 function $0_error() { - (( q )) || print -P "%1F[ERROR]%f %Bp9k_configure%b: $1" >&2 - return 1 + (( q )) || print -rP "%1F[ERROR]%f %Bp10k configure%b: $1" >&2 } { - [[ -t 0 && -t 1 ]] || $0_error "no TTY" - [[ -o multibyte ]] || $0_error "multibyte option is not set" - [[ "${#$(print -P '\u276F' 2>/dev/null)}" == 1 ]] || $0_error "shell doesn't support unicode" - [[ -w $__p9k_zd ]] || $0_error "$__p9k_zd_u is not writable" - [[ ! -d $__p9k_cfg_path ]] || $0_error "$__p9k_cfg_path_u is a directory" - [[ ! -d $__p9k_zshrc ]] || $0_error "$__p9k_zshrc_u is a directory" + [[ -t 0 && -t 1 ]] || { $0_error "no TTY"; return 1 } + [[ -o multibyte ]] || { $0_error "multibyte option is not set"; return 1 } + [[ -e $__p9k_zd ]] || { $0_error "$__p9k_zd_u does not exist"; return 1 } + [[ -d $__p9k_zd ]] || { $0_error "$__p9k_zd_u is not a directory"; return 1 } + [[ -w $__p9k_zd ]] || { $0_error "$__p9k_zd_u is not writable"; return 1 } + [[ ! -d $__p9k_cfg_path ]] || { $0_error "$__p9k_cfg_path_u is a directory"; return 1 } + [[ ! -d $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u is a directory"; return 1 } - [[ ! -e $__p9k_cfg_path || -f $__p9k_cfg_path || -h $__p9k_cfg_path ]] || + [[ ! -e $__p9k_cfg_path || -f $__p9k_cfg_path || -h $__p9k_cfg_path ]] || { $0_error "$__p9k_cfg_path_u is a special file" - [[ -r $__p9k_root_dir/config/p10k-lean.zsh ]] || + return 1 + } + [[ -r $__p9k_root_dir/config/p10k-lean.zsh ]] || { $0_error "cannot read $__p9k_root_dir_u/config/p10k-lean.zsh" - [[ -r $__p9k_root_dir/config/p10k-classic.zsh ]] || + return 1 + } + [[ -r $__p9k_root_dir/config/p10k-classic.zsh ]] || { $0_error "cannot read $__p9k_root_dir_u/config/p10k-classic.zsh" - [[ ! -e $__p9k_zshrc || -f $__p9k_zshrc || -h $__p9k_zshrc ]] || + return 1 + } + [[ ! -e $__p9k_zshrc || -f $__p9k_zshrc || -h $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u a special file" - [[ ! -e $__p9k_zshrc || -r $__p9k_zshrc ]] || + return 1 + } + [[ ! -e $__p9k_zshrc || -r $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u is not readable" - [[ ! -e $__p9k_zshrc || -w $__p9k_zshrc ]] || + return 1 + } + [[ ! -e $__p9k_zshrc || -w $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u is not writable" - (( LINES >= __p9k_wizard_lines && COLUMNS >= __p9k_wizard_columns )) || + return 1 + } + (( LINES >= __p9k_wizard_lines && COLUMNS >= __p9k_wizard_columns )) || { $0_error "terminal size too small; must be at least $__p9k_wizard_columns x $__p9k_wizard_lines" + return 1 + } } always { unfunction $0_error } } function p9k_configure() { - emulate -L zsh && setopt no_hist_expand extended_glob - $__p9k_root_dir/internal/wizard.zsh -d $__p9k_root_dir -f || return - source $__p9k_cfg_path + emulate -L zsh + setopt no_hist_expand extended_glob + ( + local p=("${(@)parameters[(I)AWESOME_*|CODEPOINT_*]}") + if (( $#p )); then + typeset -x -- $p + fi + $__p9k_root_dir/internal/wizard.zsh -d $__p9k_root_dir -f + ) + local ret=$? + case $ret in + 0) source $__p9k_cfg_path;; + 69) return 0;; + *) return $ret;; + esac } diff --git a/internal/icons.zsh b/internal/icons.zsh index 57eb8ad8..b93bbb53 100755..100644 --- a/internal/icons.zsh +++ b/internal/icons.zsh @@ -3,6 +3,12 @@ typeset -gA icons function _p9k_init_icons() { [[ $+_p9k_icon_mode == 1 && $_p9k_icon_mode == $POWERLEVEL9K_MODE ]] && return typeset -g _p9k_icon_mode=$POWERLEVEL9K_MODE + zmodload zsh/langinfo + if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then + typeset -g _p9k_locale=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8} + else + typeset -g _p9k_locale= + fi case $POWERLEVEL9K_MODE in 'flat'|'awesome-patched') @@ -15,61 +21,61 @@ function _p9k_init_icons() { LEFT_SEGMENT_END_SEPARATOR ' ' # Whitespace LEFT_SUBSEGMENT_SEPARATOR '\uE0B1' # RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' # - CARRIAGE_RETURN_ICON '\u21B5' # ↵ + CARRIAGE_RETURN_ICON '\u21B5 ' # ↵ ROOT_ICON '\uE801' # - SUDO_ICON '\uF09C' # + SUDO_ICON '\uE0A2' # RUBY_ICON '\uE847 ' # - AWS_ICON '\uE895' # - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_ICON '\uE895 ' # + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\uE82F ' # - TEST_ICON '\uE891' # + TEST_ICON '\uE891 ' # TODO_ICON '\u2611' # ☑ - BATTERY_ICON '\uE894' # + BATTERY_ICON '\uE894 ' # DISK_ICON '\uE1AE ' # OK_ICON '\u2714' # ✔ FAIL_ICON '\u2718' # ✘ SYMFONY_ICON 'SF' - NODE_ICON '\u2B22' # ⬢ + NODE_ICON '\u2B22 ' # ⬢ MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ - APPLE_ICON '\uE26E' # - WINDOWS_ICON '\uE26F' # - FREEBSD_ICON '\U1F608 ' # 😈 - ANDROID_ICON '\uE270' # - LINUX_ICON '\uE271' # - LINUX_ARCH_ICON '\uE271' # - LINUX_DEBIAN_ICON '\uE271' # - LINUX_RASPBIAN_ICON '\uE271' # - LINUX_UBUNTU_ICON '\uE271' # - LINUX_CENTOS_ICON '\uE271' # - LINUX_COREOS_ICON '\uE271' # - LINUX_ELEMENTARY_ICON '\uE271' # - LINUX_MINT_ICON '\uE271' # - LINUX_FEDORA_ICON '\uE271' # - LINUX_GENTOO_ICON '\uE271' # - LINUX_MAGEIA_ICON '\uE271' # - LINUX_NIXOS_ICON '\uE271' # - LINUX_MANJARO_ICON '\uE271' # - LINUX_DEVUAN_ICON '\uE271' # - LINUX_ALPINE_ICON '\uE271' # - LINUX_AOSC_ICON '\uE271' # - LINUX_OPENSUSE_ICON '\uE271' # - LINUX_SABAYON_ICON '\uE271' # - LINUX_SLACKWARE_ICON '\uE271' # - SUNOS_ICON '\U1F31E ' # 🌞 - HOME_ICON '\uE12C' # - HOME_SUB_ICON '\uE18D' # - FOLDER_ICON '\uE818' # - NETWORK_ICON '\uE1AD' # - ETC_ICON '\uE82F' # + APPLE_ICON '\uE26E ' # + WINDOWS_ICON '\uE26F ' # + FREEBSD_ICON '\U1F608' # 😈 + ANDROID_ICON '\uE270 ' # + LINUX_ICON '\uE271 ' # + LINUX_ARCH_ICON '\uE271 ' # + LINUX_DEBIAN_ICON '\uE271 ' # + LINUX_RASPBIAN_ICON '\uE271 ' # + LINUX_UBUNTU_ICON '\uE271 ' # + LINUX_CENTOS_ICON '\uE271 ' # + LINUX_COREOS_ICON '\uE271 ' # + LINUX_ELEMENTARY_ICON '\uE271 ' # + LINUX_MINT_ICON '\uE271 ' # + LINUX_FEDORA_ICON '\uE271 ' # + LINUX_GENTOO_ICON '\uE271 ' # + LINUX_MAGEIA_ICON '\uE271 ' # + LINUX_NIXOS_ICON '\uE271 ' # + LINUX_MANJARO_ICON '\uE271 ' # + LINUX_DEVUAN_ICON '\uE271 ' # + LINUX_ALPINE_ICON '\uE271 ' # + LINUX_AOSC_ICON '\uE271 ' # + LINUX_OPENSUSE_ICON '\uE271 ' # + LINUX_SABAYON_ICON '\uE271 ' # + LINUX_SLACKWARE_ICON '\uE271 ' # + SUNOS_ICON '\U1F31E' # 🌞 + HOME_ICON '\uE12C ' # + HOME_SUB_ICON '\uE18D ' # + FOLDER_ICON '\uE818 ' # + NETWORK_ICON '\uE1AD ' # + ETC_ICON '\uE82F ' # LOAD_ICON '\uE190 ' # - SWAP_ICON '\uE87D' # + SWAP_ICON '\uE87D ' # RAM_ICON '\uE1E2 ' # - SERVER_ICON '\uE895' # - VCS_UNTRACKED_ICON '\uE16C' # - VCS_UNSTAGED_ICON '\uE17C' # - VCS_STAGED_ICON '\uE168' # + SERVER_ICON '\uE895 ' # + VCS_UNTRACKED_ICON '\uE16C ' # + VCS_UNSTAGED_ICON '\uE17C ' # + VCS_STAGED_ICON '\uE168 ' # VCS_STASH_ICON '\uE133 ' # #VCS_INCOMING_CHANGES_ICON '\uE1EB ' # #VCS_INCOMING_CHANGES_ICON '\uE80D ' # @@ -88,22 +94,27 @@ function _p9k_init_icons() { VCS_GIT_BITBUCKET_ICON '\uE20E ' # VCS_GIT_GITLAB_ICON '\uE20E ' # VCS_HG_ICON '\uE1C3 ' # - VCS_SVN_ICON '(svn) ' - RUST_ICON '(rust)' # TODO: try 𝗥. - PYTHON_ICON '\ue63c' # - SWIFT_ICON '' - GO_ICON '' - PUBLIC_IP_ICON '' + VCS_SVN_ICON 'svn' + RUST_ICON 'R' + PYTHON_ICON '\uE63C ' # (doesn't always work) + SWIFT_ICON 'Swift' + GO_ICON 'Go' + PUBLIC_IP_ICON 'IP' LOCK_ICON '\UE138' # - EXECUTION_TIME_ICON '\UE89C' # - SSH_ICON '(ssh)' - VPN_ICON '(vpn)' - KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\UF16B' # - DATE_ICON '\uE184' # - TIME_ICON '\uE12E' # + EXECUTION_TIME_ICON '\UE89C ' # + SSH_ICON 'ssh' + VPN_ICON '\UE138' + KUBERNETES_ICON '\U2388 ' # ⎈ + DROPBOX_ICON '\UF16B ' # (doesn't always work) + DATE_ICON '\uE184 ' # + TIME_ICON '\uE12E ' # JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; 'awesome-fontconfig') @@ -117,13 +128,13 @@ function _p9k_init_icons() { LEFT_SUBSEGMENT_SEPARATOR '\uE0B1' # RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' # CARRIAGE_RETURN_ICON '\u21B5' # ↵ - ROOT_ICON '\uF201' # - SUDO_ICON '\uF09C' # + ROOT_ICON '\uF201 ' # + SUDO_ICON '\uF09C ' # RUBY_ICON '\uF219 ' # - AWS_ICON '\uF270' # - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_ICON '\uF270 ' # + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\uF013 ' # - TEST_ICON '\uF291' # + TEST_ICON '\uF291 ' # TODO_ICON '\u2611' # ☑ BATTERY_ICON '\U1F50B' # 🔋 DISK_ICON '\uF0A0 ' # @@ -134,48 +145,48 @@ function _p9k_init_icons() { MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ - APPLE_ICON '\uF179' # - WINDOWS_ICON '\uF17A' # - FREEBSD_ICON '\U1F608 ' # 😈 - ANDROID_ICON '\uE17B' # - LINUX_ICON '\uF17C' # - LINUX_ARCH_ICON '\uF17C' # - LINUX_DEBIAN_ICON '\uF17C' # - LINUX_RASPBIAN_ICON '\uF17C' # - LINUX_UBUNTU_ICON '\uF17C' # - LINUX_CENTOS_ICON '\uF17C' # - LINUX_COREOS_ICON '\uF17C' # - LINUX_ELEMENTARY_ICON '\uF17C' # - LINUX_MINT_ICON '\uF17C' # - LINUX_FEDORA_ICON '\uF17C' # - LINUX_GENTOO_ICON '\uF17C' # - LINUX_MAGEIA_ICON '\uF17C' # - LINUX_NIXOS_ICON '\uF17C' # - LINUX_MANJARO_ICON '\uF17C' # - LINUX_DEVUAN_ICON '\uF17C' # - LINUX_ALPINE_ICON '\uF17C' # - LINUX_AOSC_ICON '\uF17C' # - LINUX_OPENSUSE_ICON '\uF17C' # - LINUX_SABAYON_ICON '\uF17C' # - LINUX_SLACKWARE_ICON '\uF17C' # + APPLE_ICON '\uF179 ' # + WINDOWS_ICON '\uF17A ' # + FREEBSD_ICON '\U1F608' # 😈 + ANDROID_ICON '\uE17B ' # (doesn't always work) + LINUX_ICON '\uF17C ' # + LINUX_ARCH_ICON '\uF17C ' # + LINUX_DEBIAN_ICON '\uF17C ' # + LINUX_RASPBIAN_ICON '\uF17C ' # + LINUX_UBUNTU_ICON '\uF17C ' # + LINUX_CENTOS_ICON '\uF17C ' # + LINUX_COREOS_ICON '\uF17C ' # + LINUX_ELEMENTARY_ICON '\uF17C ' # + LINUX_MINT_ICON '\uF17C ' # + LINUX_FEDORA_ICON '\uF17C ' # + LINUX_GENTOO_ICON '\uF17C ' # + LINUX_MAGEIA_ICON '\uF17C ' # + LINUX_NIXOS_ICON '\uF17C ' # + LINUX_MANJARO_ICON '\uF17C ' # + LINUX_DEVUAN_ICON '\uF17C ' # + LINUX_ALPINE_ICON '\uF17C ' # + LINUX_AOSC_ICON '\uF17C ' # + LINUX_OPENSUSE_ICON '\uF17C ' # + LINUX_SABAYON_ICON '\uF17C ' # + LINUX_SLACKWARE_ICON '\uF17C ' # SUNOS_ICON '\uF185 ' # - HOME_ICON '\uF015' # - HOME_SUB_ICON '\uF07C' # - FOLDER_ICON '\uF115' # + HOME_ICON '\uF015 ' # + HOME_SUB_ICON '\uF07C ' # + FOLDER_ICON '\uF115 ' # ETC_ICON '\uF013 ' # - NETWORK_ICON '\uF09E' # + NETWORK_ICON '\uF09E ' # LOAD_ICON '\uF080 ' # - SWAP_ICON '\uF0E4' # - RAM_ICON '\uF0E4' # - SERVER_ICON '\uF233' # - VCS_UNTRACKED_ICON '\uF059' # - VCS_UNSTAGED_ICON '\uF06A' # - VCS_STAGED_ICON '\uF055' # + SWAP_ICON '\uF0E4 ' # + RAM_ICON '\uF0E4 ' # + SERVER_ICON '\uF233 ' # + VCS_UNTRACKED_ICON '\uF059 ' # + VCS_UNSTAGED_ICON '\uF06A ' # + VCS_STAGED_ICON '\uF055 ' # VCS_STASH_ICON '\uF01C ' # VCS_INCOMING_CHANGES_ICON '\uF01A ' # VCS_OUTGOING_CHANGES_ICON '\uF01B ' # VCS_TAG_ICON '\uF217 ' # - VCS_BOOKMARK_ICON '\uF27B' # + VCS_BOOKMARK_ICON '\uF27B ' # VCS_COMMIT_ICON '\uF221 ' # VCS_BRANCH_ICON '\uF126 ' # VCS_REMOTE_BRANCH_ICON '\u2192' # → @@ -185,22 +196,27 @@ function _p9k_init_icons() { VCS_GIT_BITBUCKET_ICON '\uF171 ' # VCS_GIT_GITLAB_ICON '\uF296 ' # VCS_HG_ICON '\uF0C3 ' # - VCS_SVN_ICON '(svn) ' - RUST_ICON '\uE6A8' # - PYTHON_ICON '\ue63c' # - SWIFT_ICON '' - GO_ICON '' - PUBLIC_IP_ICON '' + VCS_SVN_ICON 'svn' + RUST_ICON '\uE6A8' # + PYTHON_ICON '\uE63C ' # + SWIFT_ICON 'Swift' + GO_ICON 'Go' + PUBLIC_IP_ICON 'IP' LOCK_ICON '\UF023' # - EXECUTION_TIME_ICON '\uF253' - SSH_ICON '(ssh)' + EXECUTION_TIME_ICON '\uF253 ' # + SSH_ICON 'ssh' VPN_ICON '\uF023' KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\UF16B' # + DROPBOX_ICON '\UF16B ' # DATE_ICON '\uF073 ' # TIME_ICON '\uF017 ' # JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; 'awesome-mapped-fontconfig') @@ -222,57 +238,57 @@ function _p9k_init_icons() { RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' # CARRIAGE_RETURN_ICON '\u21B5' # ↵ ROOT_ICON '\u'$CODEPOINT_OF_OCTICONS_ZAP # - SUDO_ICON '\u'$CODEPOINT_OF_AWESOME_UNLOCK # + SUDO_ICON '\u'$CODEPOINT_OF_AWESOME_UNLOCK' ' # RUBY_ICON '\u'$CODEPOINT_OF_OCTICONS_RUBY' ' # - AWS_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER # - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER' ' # + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\u'$CODEPOINT_OF_AWESOME_COG' ' # - TEST_ICON '\u'$CODEPOINT_OF_AWESOME_BUG # - TODO_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK_SQUARE_O # - BATTERY_ICON '\U'$CODEPOINT_OF_AWESOME_BATTERY_FULL # + TEST_ICON '\u'$CODEPOINT_OF_AWESOME_BUG' ' # + TODO_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK_SQUARE_O' ' # + BATTERY_ICON '\U'$CODEPOINT_OF_AWESOME_BATTERY_FULL' ' # DISK_ICON '\u'$CODEPOINT_OF_AWESOME_HDD_O' ' # - OK_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK # - FAIL_ICON '\u'$CODEPOINT_OF_AWESOME_TIMES # + OK_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK' ' # + FAIL_ICON '\u'$CODEPOINT_OF_AWESOME_TIMES # SYMFONY_ICON 'SF' NODE_ICON '\u2B22' # ⬢ MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ - APPLE_ICON '\u'$CODEPOINT_OF_AWESOME_APPLE # - FREEBSD_ICON '\U1F608 ' # 😈 - LINUX_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_ARCH_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_DEBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_RASPBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_UBUNTU_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_CENTOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_COREOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_ELEMENTARY_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_MINT_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_FEDORA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_GENTOO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_MAGEIA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_NIXOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_MANJARO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_DEVUAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_ALPINE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_AOSC_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_OPENSUSE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_SABAYON_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # - LINUX_SLACKWARE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX # + APPLE_ICON '\u'$CODEPOINT_OF_AWESOME_APPLE' ' # + FREEBSD_ICON '\U1F608' # 😈 + LINUX_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_ARCH_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_DEBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_RASPBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_UBUNTU_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_CENTOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_COREOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_ELEMENTARY_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_MINT_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_FEDORA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_GENTOO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_MAGEIA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_NIXOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_MANJARO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_DEVUAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_ALPINE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_AOSC_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_OPENSUSE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_SABAYON_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # + LINUX_SLACKWARE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' # SUNOS_ICON '\u'$CODEPOINT_OF_AWESOME_SUN_O' ' # - HOME_ICON '\u'$CODEPOINT_OF_AWESOME_HOME # - HOME_SUB_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_OPEN # - FOLDER_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_O # + HOME_ICON '\u'$CODEPOINT_OF_AWESOME_HOME' ' # + HOME_SUB_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_OPEN' ' # + FOLDER_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_O' ' # ETC_ICON '\u'$CODEPOINT_OF_AWESOME_COG' ' # - NETWORK_ICON '\u'$CODEPOINT_OF_AWESOME_RSS # + NETWORK_ICON '\u'$CODEPOINT_OF_AWESOME_RSS' ' # LOAD_ICON '\u'$CODEPOINT_OF_AWESOME_BAR_CHART' ' # - SWAP_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD # - RAM_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD # - SERVER_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER # - VCS_UNTRACKED_ICON '\u'$CODEPOINT_OF_AWESOME_QUESTION_CIRCLE # - VCS_UNSTAGED_ICON '\u'$CODEPOINT_OF_AWESOME_EXCLAMATION_CIRCLE # - VCS_STAGED_ICON '\u'$CODEPOINT_OF_AWESOME_PLUS_CIRCLE # + SWAP_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD' ' # + RAM_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD' ' # + SERVER_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER' ' # + VCS_UNTRACKED_ICON '\u'$CODEPOINT_OF_AWESOME_QUESTION_CIRCLE' ' # + VCS_UNSTAGED_ICON '\u'$CODEPOINT_OF_AWESOME_EXCLAMATION_CIRCLE' ' # + VCS_STAGED_ICON '\u'$CODEPOINT_OF_AWESOME_PLUS_CIRCLE' ' # VCS_STASH_ICON '\u'$CODEPOINT_OF_AWESOME_INBOX' ' # VCS_INCOMING_CHANGES_ICON '\u'$CODEPOINT_OF_AWESOME_ARROW_CIRCLE_DOWN' ' # VCS_OUTGOING_CHANGES_ICON '\u'$CODEPOINT_OF_AWESOME_ARROW_CIRCLE_UP' ' # @@ -280,28 +296,33 @@ function _p9k_init_icons() { VCS_BOOKMARK_ICON '\u'$CODEPOINT_OF_OCTICONS_BOOKMARK # VCS_COMMIT_ICON '\u'$CODEPOINT_OF_OCTICONS_GIT_COMMIT' ' # VCS_BRANCH_ICON '\u'$CODEPOINT_OF_OCTICONS_GIT_BRANCH' ' # - VCS_REMOTE_BRANCH_ICON '\u'$CODEPOINT_OF_OCTICONS_REPO_PUSH # + VCS_REMOTE_BRANCH_ICON '\u'$CODEPOINT_OF_OCTICONS_REPO_PUSH' ' # VCS_LOADING_ICON '' VCS_GIT_ICON '\u'$CODEPOINT_OF_AWESOME_GIT' ' # VCS_GIT_GITHUB_ICON '\u'$CODEPOINT_OF_AWESOME_GITHUB_ALT' ' # VCS_GIT_BITBUCKET_ICON '\u'$CODEPOINT_OF_AWESOME_BITBUCKET' ' # VCS_GIT_GITLAB_ICON '\u'$CODEPOINT_OF_AWESOME_GITLAB' ' # VCS_HG_ICON '\u'$CODEPOINT_OF_AWESOME_FLASK' ' # - VCS_SVN_ICON '(svn) ' + VCS_SVN_ICON 'svn' RUST_ICON '\uE6A8' # PYTHON_ICON '\U1F40D' # 🐍 - SWIFT_ICON '\uE655' # - PUBLIC_IP_ICON '\u'$CODEPOINT_OF_AWESOME_GLOBE # + SWIFT_ICON '\uE655 ' # + PUBLIC_IP_ICON '\u'$CODEPOINT_OF_AWESOME_GLOBE' ' # LOCK_ICON '\u'$CODEPOINT_OF_AWESOME_LOCK # - EXECUTION_TIME_ICON '\u'$CODEPOINT_OF_AWESOME_HOURGLASS_END # - SSH_ICON '(ssh)' + EXECUTION_TIME_ICON '\u'$CODEPOINT_OF_AWESOME_HOURGLASS_END' ' # + SSH_ICON 'ssh' VPN_ICON '\u'$CODEPOINT_OF_AWESOME_LOCK KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\u'$CODEPOINT_OF_AWESOME_DROPBOX # + DROPBOX_ICON '\u'$CODEPOINT_OF_AWESOME_DROPBOX' ' # DATE_ICON '\uF073 ' # TIME_ICON '\uF017 ' # JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; 'nerdfont-complete'|'nerdfont-fontconfig') @@ -316,17 +337,17 @@ function _p9k_init_icons() { LEFT_SUBSEGMENT_SEPARATOR '\uE0B1' # RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' # CARRIAGE_RETURN_ICON '\u21B5' # ↵ - ROOT_ICON '\uE614 ' # - SUDO_ICON '\uF09C' # + ROOT_ICON '\uE614' # + SUDO_ICON '\uF09C ' # RUBY_ICON '\uF219 ' # - AWS_ICON '\uF270' # - AWS_EB_ICON '\UF1BD ' # + AWS_ICON '\uF270 ' # + AWS_EB_ICON '\UF1BD' # BACKGROUND_JOBS_ICON '\uF013 ' # - TEST_ICON '\uF188' # - TODO_ICON '\uF133' # + TEST_ICON '\uF188 ' # + TODO_ICON '\uF133 ' # BATTERY_ICON '\UF240 ' # - DISK_ICON '\uF0A0' # - OK_ICON '\uF00C' # + DISK_ICON '\uF0A0 ' # + OK_ICON '\uF00C ' # FAIL_ICON '\uF00D' # SYMFONY_ICON '\uE757' # NODE_ICON '\uE617 ' # @@ -334,42 +355,42 @@ function _p9k_init_icons() { MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ APPLE_ICON '\uF179' # - WINDOWS_ICON '\uF17A' # + WINDOWS_ICON '\uF17A ' # FREEBSD_ICON '\UF30C ' # ANDROID_ICON '\uF17B' # LINUX_ARCH_ICON '\uF303' # - LINUX_CENTOS_ICON '\uF304' # - LINUX_COREOS_ICON '\uF305' # + LINUX_CENTOS_ICON '\uF304 ' # + LINUX_COREOS_ICON '\uF305 ' # LINUX_DEBIAN_ICON '\uF306' # LINUX_RASPBIAN_ICON '\uF315' # - LINUX_ELEMENTARY_ICON '\uF309' # - LINUX_FEDORA_ICON '\uF30a' # - LINUX_GENTOO_ICON '\uF30d' # + LINUX_ELEMENTARY_ICON '\uF309 ' # + LINUX_FEDORA_ICON '\uF30a ' # + LINUX_GENTOO_ICON '\uF30d ' # LINUX_MAGEIA_ICON '\uF310' # - LINUX_MINT_ICON '\uF30e' # - LINUX_NIXOS_ICON '\uF313' # - LINUX_MANJARO_ICON '\uF312' # - LINUX_DEVUAN_ICON '\uF307' # - LINUX_ALPINE_ICON '\uF300' # - LINUX_AOSC_ICON '\uF301' # - LINUX_OPENSUSE_ICON '\uF314' # - LINUX_SABAYON_ICON '\uF317' # - LINUX_SLACKWARE_ICON '\uF319' # - LINUX_UBUNTU_ICON '\uF31b' # + LINUX_MINT_ICON '\uF30e ' # + LINUX_NIXOS_ICON '\uF313 ' # + LINUX_MANJARO_ICON '\uF312 ' # + LINUX_DEVUAN_ICON '\uF307 ' # + LINUX_ALPINE_ICON '\uF300 ' # + LINUX_AOSC_ICON '\uF301 ' # + LINUX_OPENSUSE_ICON '\uF314 ' # + LINUX_SABAYON_ICON '\uF317 ' # + LINUX_SLACKWARE_ICON '\uF319 ' # + LINUX_UBUNTU_ICON '\uF31b ' # LINUX_ICON '\uF17C' # SUNOS_ICON '\uF185 ' # - HOME_ICON '\uF015' # - HOME_SUB_ICON '\uF07C' # - FOLDER_ICON '\uF115' # - ETC_ICON '\uF013' # - NETWORK_ICON '\uF1EB' # + HOME_ICON '\uF015 ' # + HOME_SUB_ICON '\uF07C ' # + FOLDER_ICON '\uF115 ' # + ETC_ICON '\uF013 ' # + NETWORK_ICON '\uF1EB ' # LOAD_ICON '\uF080 ' # - SWAP_ICON '\uF464' # - RAM_ICON '\uF0E4' # - SERVER_ICON '\uF0AE' # - VCS_UNTRACKED_ICON '\uF059' # - VCS_UNSTAGED_ICON '\uF06A' # - VCS_STAGED_ICON '\uF055' # + SWAP_ICON '\uF464 ' # + RAM_ICON '\uF0E4 ' # + SERVER_ICON '\uF0AE ' # + VCS_UNTRACKED_ICON '\uF059 ' # + VCS_UNSTAGED_ICON '\uF06A ' # + VCS_STAGED_ICON '\uF055 ' # VCS_STASH_ICON '\uF01C ' # VCS_INCOMING_CHANGES_ICON '\uF01A ' # VCS_OUTGOING_CHANGES_ICON '\uF01B ' # @@ -384,22 +405,27 @@ function _p9k_init_icons() { VCS_GIT_BITBUCKET_ICON '\uE703 ' # VCS_GIT_GITLAB_ICON '\uF296 ' # VCS_HG_ICON '\uF0C3 ' # - VCS_SVN_ICON '\uE72D ' # - RUST_ICON '\uE7A8 ' # + VCS_SVN_ICON '\uE72D' # + RUST_ICON '\uE7A8' # PYTHON_ICON '\UE73C ' # SWIFT_ICON '\uE755' # GO_ICON '\uE626' # - PUBLIC_IP_ICON '\UF0AC' # + PUBLIC_IP_ICON '\UF0AC ' # LOCK_ICON '\UF023' # - EXECUTION_TIME_ICON '\uF252' # - SSH_ICON '\uF489' # - VPN_ICON '(vpn)' + EXECUTION_TIME_ICON '\uF252 ' # + SSH_ICON '\uF489 ' # + VPN_ICON '\UF023' KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\UF16B' # + DROPBOX_ICON '\UF16B ' # DATE_ICON '\uF073 ' # TIME_ICON '\uF017 ' # JAVA_ICON '\U2615' # ☕︎ - LARAVEL_ICON '\ue73f ' # + LARAVEL_ICON '\ue73f' # + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '\uE77F' # + AZURE_ICON '\uFD03' # ﴃ ) ;; *) @@ -414,10 +440,10 @@ function _p9k_init_icons() { RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' # CARRIAGE_RETURN_ICON '\u21B5' # ↵ ROOT_ICON '\u26A1' # ⚡ - SUDO_ICON '\uE0A2' # + SUDO_ICON '' RUBY_ICON 'Ruby' AWS_ICON 'AWS' - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\u2699' # ⚙ TEST_ICON '' TODO_ICON '\u2611' # ☑ @@ -482,11 +508,11 @@ function _p9k_init_icons() { VCS_GIT_GITLAB_ICON '' VCS_HG_ICON '' VCS_SVN_ICON '' - RUST_ICON 'Rust' # TODO: try 𝗥. + RUST_ICON 'R' PYTHON_ICON 'Py' SWIFT_ICON 'Swift' GO_ICON 'Go' - PUBLIC_IP_ICON '' + PUBLIC_IP_ICON 'IP' LOCK_ICON '\UE0A2' EXECUTION_TIME_ICON '' SSH_ICON 'ssh' @@ -497,6 +523,11 @@ function _p9k_init_icons() { TIME_ICON '' JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; esac @@ -518,9 +549,11 @@ function _p9k_init_icons() { } # Sadly, this is a part of public API. Its use is emphatically discouraged. -function print_icon() { +function _p9k_print_icon() { emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} _p9k_init_icons + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale local icon_name=$1 local var_name=POWERLEVEL9K_${icon_name} if [[ -n "${(tP)var_name}" ]]; then @@ -535,9 +568,11 @@ function print_icon() { # * $1 string - If "original", then the original icons are printed, # otherwise "print_icon" is used, which takes the users # overrides into account. -function get_icon_names() { +function _p9k_get_icon_names() { emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} _p9k_init_icons + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale # Iterate over a ordered list of keys of the icons array for key in ${(@kon)icons}; do echo -n "POWERLEVEL9K_$key: " diff --git a/internal/p10k.zsh b/internal/p10k.zsh index b37fa2d0..144f1a33 100755..100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -27,7 +27,6 @@ if ! autoload -Uz is-at-least || ! is-at-least 5.1; then return 1 fi -source "${__p9k_root_dir}/internal/icons.zsh" source "${__p9k_root_dir}/internal/configure.zsh" # For compatibility with Powerlevel9k. It's not recommended to use mnemonic color @@ -89,14 +88,15 @@ typeset -grA __p9k_colors=( # # Type `getColorCode background` or `getColorCode foreground` to see the list of predefined colors. function getColorCode() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} if (( ARGC == 1 )); then case $1 in foreground) local k for k in "${(k@)__p9k_colors}"; do local v=${__p9k_colors[$k]} - print -P "%F{$v}$v - $k%f" + print -rP -- "%F{$v}$v - $k%f" done return ;; @@ -104,7 +104,7 @@ function getColorCode() { local k for k in "${(k@)__p9k_colors}"; do local v=${__p9k_colors[$k]} - print -P "%K{$v}$v - $k%k" + print -rP -- "%K{$v}$v - $k%k" done return ;; @@ -114,6 +114,26 @@ function getColorCode() { return 1 } +# Sadly, this is a part of public API. Its use is emphatically discouraged. +function print_icon() { + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} no_aliases + (( $+functions[_p9k_print_icon] )) || source "${__p9k_root_dir}/internal/icons.zsh" + _p9k_print_icon "$@" +} + +# Prints a list of configured icons. +# +# * $1 string - If "original", then the original icons are printed, +# otherwise "print_icon" is used, which takes the users +# overrides into account. +function get_icon_names() { + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} no_aliases + (( $+functions[_p9k_get_icon_names] )) || source "${__p9k_root_dir}/internal/icons.zsh" + _p9k_get_icon_names "$@" +} + # _p9k_declare <type> <uppercase-name> [default]... function _p9k_declare() { local -i set=$+parameters[$2] @@ -147,6 +167,7 @@ function _p9k_declare() { (( set )) && typeset -g _$2=${(P)2} || typeset -g _$2=$3 ;; -e) + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale if (( set )); then local v=${(P)2} typeset -g _$2=${(g::)v} @@ -169,7 +190,6 @@ function _p9k_declare() { # _p9k_prompt_length '%F{red}abc' => 3 # _p9k_prompt_length $'%{a\b%Gb%}' => 1 function _p9k_prompt_length() { - emulate -L zsh && setopt no_hist_expand extended_glob local COLUMNS=1024 local -i x y=$#1 m if (( y )); then @@ -211,44 +231,13 @@ _p9k_segment_in_use() { } function _p9k_parse_ip() { - local desiredInterface=${1:-'^[^ ]+'} - - if [[ $_p9k_os == OSX ]]; then - [[ -x /sbin/ifconfig ]] || return - local rawInterfaces && rawInterfaces="$(/sbin/ifconfig -l 2>/dev/null)" || return - local -a interfaces=(${(A)=rawInterfaces}) - local pattern="${desiredInterface}[^ ]?" - local -a relevantInterfaces - for rawInterface in $interfaces; do - [[ "$rawInterface" =~ $pattern ]] && relevantInterfaces+=$MATCH - done - local newline=$'\n' - local interfaceName interface - for interfaceName in $relevantInterfaces; do - interface="$(/sbin/ifconfig $interfaceName 2>/dev/null)" || continue - [[ "${interface}" =~ "lo[0-9]*" ]] && continue - if [[ "${interface//${newline}/}" =~ "<([^>]*)>(.*)inet[ ]+([^ ]*)" ]]; then - local ipFound="${match[3]}" - local -a interfaceStates=(${(s:,:)match[1]}) - if (( ${interfaceStates[(I)UP]} )); then - _p9k_ret=$ipFound - return - fi - fi - done - else - [[ -x /sbin/ip ]] || return - local -a interfaces=( "${(f)$(/sbin/ip -brief -4 a show 2>/dev/null)}" ) - local pattern="^${desiredInterface}[[:space:]]+UP[[:space:]]+([^/ ]+)" - local interface - for interface in "${(@)interfaces}"; do - if [[ "$interface" =~ $pattern ]]; then - _p9k_ret=$match[1] - return - fi - done - fi - + local iface_regex="^${1:-.*}\$" iface ip + for iface ip in "${(@kv)_p9k_iface}"; do + if [[ $iface =~ $iface_regex ]]; then + _p9k_ret=$ip + return 0 + fi + done return 1 } @@ -271,6 +260,7 @@ _p9k_cache_set() { # echo "caching: ${(@0q)_p9k_cache_key} => (${(q)@})" >&2 _p9k_cache[$_p9k_cache_key]="${(pj:\0:)*}0" _p9k_cache_val=("$@") + _p9k_dump_scheduled=1 } _p9k_cache_get() { @@ -279,6 +269,63 @@ _p9k_cache_get() { [[ -n $v ]] && _p9k_cache_val=("${(@0)${v[1,-2]}}") } +_p9k_cache_stat_get() { + local -H stat + local label=$1 f + shift + + _p9k_cache_stat_meta= + _p9k_cache_stat_fprint= + + for f; do + if zstat -H stat -- $f 2>/dev/null; then + _p9k_cache_stat_meta+="${(q)f} $stat[inode] $stat[mtime] $stat[size] $stat[mode]; " + fi + done + + if _p9k_cache_get $0 $label meta "$@" && [[ $_p9k_cache_val[1] == $_p9k_cache_stat_meta ]]; then + _p9k_cache_stat_fprint=$_p9k_cache_val[2] + local -a key=($0 $label fprint "$@" "$_p9k_cache_stat_fprint") + _p9k_cache_fprint_key="${(pj:\0:)key}" + shift 2 _p9k_cache_val + return + fi + + if (( $+commands[md5] )); then + local -a md5=(md5) + elif (( $+commands[md5sum] )); then + local -a md5=(md5sum -b) + else + return 1 + fi + + local fprint + for f; do + if fprint="$($md5 $f 2>/dev/null)"; then + _p9k_cache_stat_fprint+="${(q)fprint} " + fi + done + + local meta_key=$_p9k_cache_key + if _p9k_cache_get $0 $label fprint "$@" "$_p9k_cache_stat_fprint"; then + _p9k_cache_fprint_key=$_p9k_cache_key + _p9k_cache_key=$meta_key + _p9k_cache_set "$_p9k_cache_stat_meta" "$_p9k_cache_stat_fprint" "$_p9k_cache_val[@]" + shift 2 _p9k_cache_val + return + fi + + _p9k_cache_fprint_key=$_p9k_cache_key + _p9k_cache_key=$meta_key + return 1 +} + +_p9k_cache_stat_set() { + _p9k_cache_set "$_p9k_cache_stat_meta" "$_p9k_cache_stat_fprint" "$@" + _p9k_cache_key=$_p9k_cache_fprint_key + _p9k_cache_set "$@" +} + # _p9k_param prompt_foo_BAR BACKGROUND red _p9k_param() { local key="_p9k_param ${(pj:\0:)*}" @@ -329,6 +376,7 @@ _p9k_get_icon() { if [[ $_p9k_ret == $'\1'* ]]; then _p9k_ret=${_p9k_ret[2,-1]} else + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_ret=${(g::)_p9k_ret} [[ $_p9k_ret != $'\b'? ]] || _p9k_ret="%{$_p9k_ret%}" # penance for past sins fi @@ -339,9 +387,9 @@ _p9k_get_icon() { _p9k_translate_color() { if [[ $1 == <-> ]]; then # decimal color code: 255 - _p9k_ret=$1 + _p9k_ret=${(l.3..0.)1} elif [[ $1 == '#'[[:xdigit:]]## ]]; then # hexademical color code: #ffffff - _p9k_ret=$1 + _p9k_ret=${(L)1} else # named color: red # Strip prifixes if there are any. _p9k_ret=$__p9k_colors[${${${1#bg-}#fg-}#br}] @@ -375,16 +423,16 @@ _p9k_vcs_style() { local var=POWERLEVEL9K_VCS_${1}_${2}FORMAT_FOREGROUND if (( $+parameters[$var] )); then - _p9k_ret=${(P)var} + _p9k_translate_color "${(P)var}" else var=POWERLEVEL9K_VCS_${2}FORMAT_FOREGROUND if (( $+parameters[$var] )); then - _p9k_ret=${(P)var} + _p9k_translate_color "${(P)var}" else _p9k_color prompt_vcs_$1 FOREGROUND "$_p9k_color1" fi fi - + _p9k_foreground $_p9k_ret _p9k_ret=$style$_p9k_ret _p9k_cache[$key]=${_p9k_ret}. @@ -485,7 +533,7 @@ _p9k_left_prompt_segment() { # 4 # fi - local t=$#_p9k_t + local t=$(($#_p9k_t - __p9k_ksh_arrays)) _p9k_t+=$start_sep$style$left_space # 1 _p9k_t+=$style # 2 if [[ -n $fg_color && $fg_color == $bg_color ]]; then @@ -506,10 +554,15 @@ _p9k_left_prompt_segment() { local p= p+="\${_p9k_n::=}" - p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 - p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 - p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x(\$_p9k_bg|\${_p9k_bg:-0})}:+$((t+3))}}" # 3 - p+="\${_p9k_n:=$((t+4))}" # 4 + p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 + p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 + if (( __p9k_sh_glob )); then + p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x\$_p9k_bg}:+$((t+3))}}" # 3 + p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x\$${_p9k_bg:-0}}:+$((t+3))}}" # 3 + else + p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x(\$_p9k_bg|\${_p9k_bg:-0})}:+$((t+3))}}" # 3 + fi + p+="\${_p9k_n:=$((t+4))}" # 4 _p9k_param $1 VISUAL_IDENTIFIER_EXPANSION '${P9K_VISUAL_IDENTIFIER}' local icon_exp_=${_p9k_ret:+\"$_p9k_ret\"} @@ -549,6 +602,7 @@ _p9k_left_prompt_segment() { p+='${${_p9k_e:#00}:+${${_p9k_t[$_p9k_n]/'$ss'/$_p9k_ss}/'$s'/$_p9k_s}' + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_param $1 ICON_BEFORE_CONTENT '' if [[ $_p9k_ret != false ]]; then _p9k_param $1 PREFIX '' @@ -694,7 +748,7 @@ _p9k_right_prompt_segment() { # 4 # fi - local t=$#_p9k_t + local t=$(($#_p9k_t - __p9k_ksh_arrays)) _p9k_t+=$start_sep$style$left_space # 1 _p9k_t+=$w$style # 2 _p9k_t+=$w$subsep$style$left_space # 3 @@ -706,10 +760,15 @@ _p9k_right_prompt_segment() { local p= p+="\${_p9k_n::=}" - p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 - p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 - p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x(${(b)bg_color}|${(b)bg_color:-0})}:+$((t+3))}}" # 3 - p+="\${_p9k_n:=$((t+4))}" # 4 + p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 + p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 + if (( __p9k_sh_glob )); then + p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x${(b)bg_color}}:+$((t+3))}}" # 3 + p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x${(b)bg_color:-0}}:+$((t+3))}}" # 3 + else + p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x(${(b)bg_color}|${(b)bg_color:-0})}:+$((t+3))}}" # 3 + fi + p+="\${_p9k_n:=$((t+4))}" # 4 _p9k_param $1 VISUAL_IDENTIFIER_EXPANSION '${P9K_VISUAL_IDENTIFIER}' local icon_exp_=${_p9k_ret:+\"$_p9k_ret\"} @@ -749,6 +808,7 @@ _p9k_right_prompt_segment() { p+='${${_p9k_e:#00}:+${_p9k_t[$_p9k_n]/'$w'/$_p9k_w}' + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_param $1 ICON_BEFORE_CONTENT '' if [[ $_p9k_ret != true ]]; then _p9k_param $1 PREFIX '' @@ -847,104 +907,7 @@ _p9k_right_prompt_segment() { } function _p9k_prompt_segment() { "_p9k_${_p9k_prompt_side}_prompt_segment" "$@" } - -typeset -gr __p9k_prompt_segment_usage="Usage: p9k_prompt_segment [{+|-}re] [-s state] [-b bg] [-f fg] [-i icon] [-c cond] [-t text] - -Options: - -t text segment's main content; will undergo prompt expansion: '%F{blue}%T%f' will - show as blue current time; default is empty - -i icon segment's icon; default is empty - -r icon is a symbolic reference that needs to be resolved; for example, 'LOCK_ICON' - +r icon is already resolved and should be printed literally; for example, '⭐'; - this is the default; you can also use $'\u2B50' if you don't want to have - non-ascii characters in source code - -b bg background color; for example, 'blue', '4', or '#0000ff'; empty value means - transparent background, as in '%k'; default is black - -f fg foreground color; for example, 'blue', '4', or '#0000ff'; empty value means - default foreground color, as in '%f'; default is empty - -s state segment's state for the purpose of applying styling options; if you want to - to be able to use POWERLEVEL9K parameters to specify different colors or icons - depending on some property, use different states for different values of that - property - -c condition; if empty after parameter expansion and process substitution, the - segment is hidden; this is an advanced feature, use with caution; default is '1' - -e segment's main content will undergo parameter expansion and process - substitution; the content will be surrounded with double quotes and thus - should quote its own double quotes; this is an advanced feature, use with - caution - +e segment's main content should not undergo parameter expansion and process - substitution; this is the default - -h print this help message and return - -Example: 'core' segment tells you if there is a file name 'core' in the current directory. - -- Segment's icon is '⭐'. -- Segment's text is the file's size in bytes. -- If you have permissions to delete the file, state is DELETABLE. If not, it's PROTECTED. - - zmodload -F zsh/stat b:zstat - - function prompt_core() { - local size=() - if ! zstat -A size +size core 2>/dev/null; then - # No 'core' file in the current directory. - return - fi - if [[ -w . ]]; then - local state=DELETABLE - else - local state=PROTECTED - fi - p9k_prompt_segment -s \$state -i '⭐' -b black -f blue -t \${size[1]}b - } - -To enable this segment, add 'core' to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or -POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. - -Example customizations: - - # Override foreground. - POWERLEVEL9K_CORE_FOREGROUND=red - - # Override background when DELETABLE. - POWERLEVEL9K_CORE_DELETABLE_BACKGROUND=green - - # Override icon when PROTECTED. - POWERLEVEL9K_CORE_PROTECTED_VISUAL_IDENTIFIER_EXPANSION='❎' - - # Don't show file size when PROTECTED. - POWERLEVEL9K_CORE_PROTECTED_CONTENT_EXPANSION=''" - -# Type `p9k_prompt_segment -h` for usage. -function p9k_prompt_segment() { - emulate -L zsh && setopt no_hist_expand extended_glob - local opt state bg=0 fg icon cond text ref=0 expand=0 - while getopts ':s:b:f:i:c:t:re' opt; do - case $opt in - s) state=$OPTARG;; - b) bg=$OPTARG;; - f) fg=$OPTARG;; - i) icon=$OPTARG;; - c) cond=${OPTARG:-'${:-}'};; - t) text=$OPTARG;; - r) ref=1;; - e) expand=1;; - +r) ref=0;; - +e) expand=0;; - ?) echo -E - $__p9k_prompt_segment_usage >&2; return 1;; - esac - done - if (( OPTIND <= ARGC )); then - echo -E - $__p9k_prompt_segment_usage >&2 - return 1 - fi - if [[ -n $_p9k_prompt_side ]]; then - (( ref )) || icon=$'\1'$icon - "_p9k_${_p9k_prompt_side}_prompt_segment" "prompt_${_p9k_segment_name}${state:+_${(U)state}}" \ - "$bg" "${fg:-$_p9k_color1}" "$icon" "$expand" "$cond" "$text" - fi - return 0 -} +function p9k_prompt_segment() { p10k segment "$@" } function _p9k_python_version() { _p9k_cached_cmd_stdout_stderr python --version || return @@ -971,8 +934,8 @@ prompt_anaconda() { ################################################################ # AWS Profile prompt_aws() { - local aws_profile="${AWS_PROFILE:-$AWS_DEFAULT_PROFILE}" - if [[ -n "$aws_profile" ]]; then + local aws_profile="${AWS_VAULT:-${AWS_PROFILE:-$AWS_DEFAULT_PROFILE}}" + if [[ "$aws_profile" != (default|) ]]; then _p9k_prompt_segment "$0" red white 'AWS_ICON' 0 '' "${aws_profile//\%/%%}" fi } @@ -980,10 +943,23 @@ prompt_aws() { ################################################################ # Current Elastic Beanstalk environment prompt_aws_eb_env() { - [[ -r .elasticbeanstalk/config.yml ]] || return - local v=($(grep environment .elasticbeanstalk/config.yml 2>/dev/null)) - [[ $#v > 1 && -n $v[2] ]] || return - [[ -n $v ]] && _p9k_prompt_segment "$0" black green 'AWS_EB_ICON' 0 '' "${v[2]//\%/%%}" + (( $+commands[eb] )) || return + + local dir=$_p9k_pwd + while true; do + [[ $dir == / ]] && return + [[ -d $dir/.elasticbeanstalk ]] && break + dir=${dir:h} + done + + if ! _p9k_cache_stat_get $0 $dir/.elasticbeanstalk/config.yml; then + local env + env="$(command eb list 2>/dev/null)" || env= + env="${${(@M)${(@f)env}:#\* *}#\* }" + _p9k_cache_stat_set "$env" + fi + [[ -n $_p9k_cache_val[1] ]] || return + _p9k_prompt_segment "$0" black green 'AWS_EB_ICON' 0 '' "${_p9k_cache_val[1]//\%/%%}" } ################################################################ @@ -1025,7 +1001,7 @@ prompt_disk_usage() { function _p9k_read_file() { _p9k_ret='' - [[ -n $1 ]] && read -r _p9k_ret <$1 + [[ -n $1 ]] && IFS='' read -r _p9k_ret <$1 [[ -n $_p9k_ret ]] } @@ -1046,7 +1022,12 @@ prompt_battery() { case "${${(s:; :)raw_data}[2]}" in 'charging'|'finishing charge'|'AC attached') - state=CHARGING + if (( bat_percent == 100 )); then + state=CHARGED + remain='' + else + state=CHARGING + fi ;; 'discharging') (( bat_percent < _POWERLEVEL9K_BATTERY_LOW_THRESHOLD )) && state=LOW || state=DISCONNECTED @@ -1134,7 +1115,14 @@ prompt_battery() { bg=$_POWERLEVEL9K_BATTERY_LEVEL_BACKGROUND[idx] fi - _p9k_prompt_segment $0_$state "$bg" "$_p9k_battery_states[$state]" $icon 0 '' $msg + local fg=$_p9k_battery_states[$state] + if (( $#_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND )); then + local -i idx=$#_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND + (( bat_percent < 100 )) && idx=$((bat_percent * $#_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND / 100 + 1)) + fg=$_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND[idx] + fi + + _p9k_prompt_segment $0_$state "$bg" "$fg" $icon 0 '' $msg } ################################################################ @@ -1155,7 +1143,7 @@ prompt_context() { if ! _p9k_cache_get $0 "${(%):-%#}"; then local -i enabled=1 local content - if [[ $_POWERLEVEL9K_ALWAYS_SHOW_CONTEXT == 0 && -n $DEFAULT_USER && $_P9K_SSH == 0 ]]; then + if [[ $_POWERLEVEL9K_ALWAYS_SHOW_CONTEXT == 0 && -n $DEFAULT_USER && $P9K_SSH == 0 ]]; then local user="$(whoami)" if [[ $user == $DEFAULT_USER ]]; then if (( _POWERLEVEL9K_ALWAYS_SHOW_USER )); then @@ -1171,7 +1159,7 @@ prompt_context() { state="DEFAULT" if [[ "${(%):-%#}" == '#' ]]; then state="ROOT" - elif (( _P9K_SSH )); then + elif (( P9K_SSH )); then if [[ -n "$SUDO_COMMAND" ]]; then state="REMOTE_SUDO" else @@ -1184,6 +1172,7 @@ prompt_context() { if [[ -z $content ]]; then local var=POWERLEVEL9K_CONTEXT_${state}_TEMPLATE if (( $+parameters[$var] )); then + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale content=${(P)var} content=${(g::)content} else @@ -1220,7 +1209,7 @@ prompt_user() { ################################################################ # Host: machine (where am I) prompt_host() { - if (( _P9K_SSH )); then + if (( P9K_SSH )); then _p9k_prompt_segment "$0_REMOTE" "${_p9k_color1}" yellow SSH_ICON 0 '' "$_POWERLEVEL9K_HOST_TEMPLATE" else _p9k_prompt_segment "$0_LOCAL" "${_p9k_color1}" yellow HOST_ICON 0 '' "$_POWERLEVEL9K_HOST_TEMPLATE" @@ -1233,9 +1222,10 @@ prompt_host() { _p9k_custom_prompt() { local segment_name=${1:u} local command=POWERLEVEL9K_CUSTOM_${segment_name} - local -a cmd=("${(@Q)${(z)${(P)command}}}") - whence $cmd[1] &>/dev/null || return - local content="$("$cmd[@]")" + command=${(P)command} + local cmd="${(Q)${(Az)command}[1]}" + (( $+functions[$cmd] || $+commands[$cmd] )) || return + local content="$(eval $command)" [[ -n $content ]] || return _p9k_prompt_segment "prompt_custom_$segment_name" $_p9k_color2 $_p9k_color1 "CUSTOM_${segment_name}_ICON" 0 '' "$content" } @@ -1243,8 +1233,7 @@ _p9k_custom_prompt() { ################################################################ # Display the duration the command needed to run. prompt_command_execution_time() { - (( _p9k_timer_start )) || return - P9K_COMMAND_DURATION_SECONDS=$((_p9k_timer_end - _p9k_timer_start)) + (( $+P9K_COMMAND_DURATION_SECONDS )) || return (( P9K_COMMAND_DURATION_SECONDS >= _POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD )) || return if (( P9K_COMMAND_DURATION_SECONDS < 60 )); then @@ -1292,33 +1281,41 @@ function _p9k_shorten_delim_len() { ################################################################ # Dir: current working directory prompt_dir() { - (( _POWERLEVEL9K_DIR_PATH_ABSOLUTE )) && local p=$PWD || local p=${(%):-%~} - - if [[ $p == '~['* ]]; then - # If "${(%):-%~}" expands to "~[a]/]/b", is the first component "~[a]" or "~[a]/]"? - # One would expect "${(%):-%-1~}" to give the right answer but alas it always simply - # gives the segment before the first slash, which would be "~[a]" in this case. Worse, - # for "~[a/b]" it'll give the nonsensical "~[a". To solve this problem we have to - # repeat what "${(%):-%~}" does and hope that it produces the same result. - local func='' - local -a parts=() - for func in zsh_directory_name $zsh_directory_name_functions; do - if (( $+functions[$func] )) && $func d $PWD && [[ $p == '~['$reply[1]']'* ]]; then - parts+='~['$reply[1]']' - break + if (( _POWERLEVEL9K_DIR_PATH_ABSOLUTE )); then + local p=$_p9k_pwd + local -a parts=("${(s:/:)p}") + elif [[ -o auto_name_dirs ]]; then + local p=${_p9k_pwd/#(#b)$HOME(|\/*)/'~'$match[1]} + local -a parts=("${(s:/:)p}") + else + local p=${(%):-%~} + if [[ $p == '~['* ]]; then + # If "${(%):-%~}" expands to "~[a]/]/b", is the first component "~[a]" or "~[a]/]"? + # One would expect "${(%):-%-1~}" to give the right answer but alas it always simply + # gives the segment before the first slash, which would be "~[a]" in this case. Worse, + # for "~[a/b]" it'll give the nonsensical "~[a". To solve this problem we have to + # repeat what "${(%):-%~}" does and hope that it produces the same result. + local func='' + local -a parts=() + for func in zsh_directory_name $zsh_directory_name_functions; do + if (( $+functions[$func] )) && $func d $_p9k_pwd && [[ $p == '~['$reply[1]']'* ]]; then + parts+='~['$reply[1]']' + break + fi + done + if (( $#parts )); then + parts+=(${(s:/:)${p#$parts[1]}}) + else + p=$_p9k_pwd + parts=("${(s:/:)p}") fi - done - if (( $#parts )); then - parts+=(${(s:/:)${p#$parts[1]}}) else - p=$PWD - parts=("${(s:/:)p}") + local -a parts=("${(s:/:)p}") fi - else - local -a parts=("${(s:/:)p}") fi local -i fake_first=0 expand=0 + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale local delim=${_POWERLEVEL9K_SHORTEN_DELIMITER-$'\u2026'} local -i shortenlen=${_POWERLEVEL9K_SHORTEN_DIR_LENGTH:--1} @@ -1348,24 +1345,28 @@ prompt_dir() { () { [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && $+commands[jq] == 1 && $#_POWERLEVEL9K_DIR_PACKAGE_FILES > 0 ]] || return - local pat="(${(j:|:)_POWERLEVEL9K_DIR_PACKAGE_FILES})" + local pats="(${(j:|:)_POWERLEVEL9K_DIR_PACKAGE_FILES})" local -i i=$#parts - local dir=$PWD + local dir=$_p9k_pwd for (( ; i > 0; --i )); do - local pkg_file='' - for pkg_file in $dir/${~pat}(N); do - local -H stat=() - zstat -H stat -- $pkg_file 2>/dev/null || return - if ! _p9k_cache_get $0_pkg $stat[inode] $stat[mtime] $stat[size]; then - local pkg_name='' - pkg_name="$(jq -j '.name' <$pkg_file 2>/dev/null)" || pkg_name='' - _p9k_cache_set "$pkg_name" - fi - [[ -n $_p9k_cache_val[1] ]] || return - parts[1,i]=($_p9k_cache_val[1]) - fake_first=1 - return - done + local markers=($dir/${~pats}(N)) + if (( $#markers )); then + local pat= pkg_file= + for pat in $_POWERLEVEL9K_DIR_PACKAGE_FILES; do + for pkg_file in $markers; do + [[ $pkg_file == $dir/${~pat} ]] || continue + if ! _p9k_cache_stat_get $0_pkg $pkg_file; then + local pkg_name='' + pkg_name="$(jq -j '.name | select(. != null)' <$pkg_file 2>/dev/null)" || pkg_name='' + _p9k_cache_stat_set "$pkg_name" + fi + [[ -n $_p9k_cache_val[1] ]] || continue + parts[1,i]=($_p9k_cache_val[1]) + fake_first=1 + return + done + done + fi dir=${dir:h} done } @@ -1400,7 +1401,7 @@ prompt_dir() { delim=${_POWERLEVEL9K_SHORTEN_DELIMITER-'*'} local -i i=2 [[ $p[1] == / ]] && (( ++i )) - local parent="${PWD%/${(pj./.)parts[i,-1]}}" + local parent="${_p9k_pwd%/${(pj./.)parts[i,-1]}}" if (( i <= $#parts )); then local mtime=() zstat -A mtime +mtime -- ${(@)${:-{$i..$#parts}}/(#b)(*)/$parent/${(pj./.)parts[i,$match[1]]}} 2>/dev/null || mtime=() @@ -1454,7 +1455,7 @@ prompt_dir() { ;; truncate_with_folder_marker) if [[ -n $_POWERLEVEL9K_SHORTEN_FOLDER_MARKER ]]; then - local dir=$PWD + local dir=$_p9k_pwd local -a m=() local -i i=$(($#parts - 1)) for (( ; i > 1; --i )); do @@ -1478,9 +1479,9 @@ prompt_dir() { ;; esac - [[ $_POWERLEVEL9K_DIR_SHOW_WRITABLE == 1 && ! -w $PWD ]] + [[ $_POWERLEVEL9K_DIR_SHOW_WRITABLE == 1 && ! -w $_p9k_pwd ]] local w=$? - if ! _p9k_cache_get $0 $PWD $w $fake_first "${parts[@]}"; then + if ! _p9k_cache_get $0 $_p9k_pwd $p $w $fake_first "${parts[@]}"; then local state=$0 local icon='' if (( ! w )); then @@ -1489,7 +1490,7 @@ prompt_dir() { else local a='' b='' c='' for a b c in "${_POWERLEVEL9K_DIR_CLASSES[@]}"; do - if [[ $PWD == ${~a} ]]; then + if [[ $_p9k_pwd == ${~a} ]]; then [[ -n $b ]] && state+=_${(U)b} icon=$'\1'$c break @@ -1577,7 +1578,7 @@ prompt_dir() { local content="${(pj.$sep.)parts}" if (( _POWERLEVEL9K_DIR_HYPERLINK )); then - local pref=$'%{\e]8;;file://'${${PWD//\%/%%25}//'#'/%%23}$'\a%}' + local pref=$'%{\e]8;;file://'${${_p9k_pwd//\%/%%25}//'#'/%%23}$'\a%}' local suf=$'%{\e]8;;\a%}' if (( expand )); then _p9k_escape $pref @@ -1588,7 +1589,7 @@ prompt_dir() { content=$pref$content$suf fi - (( expand )) && eval "_p9k_prompt_length \"\${\${_p9k_d::=0}+}$content\"" || _p9k_ret= + (( expand )) && _p9k_prompt_length "${(e):-"\${\${_p9k_d::=0}+}$content"}" || _p9k_ret= _p9k_cache_set "$state" "$icon" "$expand" "$content" $_p9k_ret fi @@ -1619,20 +1620,23 @@ prompt_go_version() { local -a match [[ $_p9k_ret == (#b)*go([[:digit:].]##)* ]] || return local v=$match[1] - local p=$GOPATH - if [[ -z $p ]]; then - if [[ -d $HOME/go ]]; then - p=$HOME/go - else - p="$(go env GOPATH 2>/dev/null)" && [[ -n $p ]] || return + if (( _POWERLEVEL9K_GO_VERSION_PROJECT_ONLY )); then + local p=$GOPATH + if [[ -z $p ]]; then + if [[ -d $HOME/go ]]; then + p=$HOME/go + else + p="$(go env GOPATH 2>/dev/null)" && [[ -n $p ]] || return + fi + fi + if [[ $_p9k_pwd/ != $p/* && $_p9k_pwd_a/ != $p/* ]]; then + local dir=$_p9k_pwd_a + while true; do + [[ $dir == / ]] && return + [[ -e $dir/go.mod ]] && break + dir=${dir:h} + done fi - fi - if [[ $PWD/ != $p/* ]]; then - local dir=$PWD - while [[ ! -e $dir/go.mod ]]; do - [[ $dir == / ]] && return - dir=${dir:h} - done fi _p9k_prompt_segment "$0" "green" "grey93" "GO_ICON" 0 '' "${v//\%/%%}" } @@ -1708,41 +1712,37 @@ prompt_load() { (( _p9k_num_cpus )) || return if (( load > 0.7 * _p9k_num_cpus )); then - local state=critical bg=red + local state=CRITICAL bg=red elif (( load > 0.5 * _p9k_num_cpus )); then - local state=warning bg=yellow + local state=WARNING bg=yellow else - local state=normal bg=green + local state=NORMAL bg=green fi _p9k_prompt_segment $0_$state $bg "$_p9k_color1" LOAD_ICON 0 '' $load } function _p9k_cached_cmd_stdout() { - local cmd=$commands[$1] + local cmd=${commands[$1]:A} [[ -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] $stat[mode] $cmd "$@"; then + if ! _p9k_cache_stat_get $0" ${(q)*}" $cmd; then local out out="$($cmd "$@" 2>/dev/null)" - _p9k_cache_set $(( ! $? )) "$out" + _p9k_cache_stat_set $(( ! $? )) "$out" fi (( $_p9k_cache_val[1] )) || return _p9k_ret=$_p9k_cache_val[2] } function _p9k_cached_cmd_stdout_stderr() { - local cmd=$commands[$1] + local cmd=${commands[$1]:A} [[ -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] $stat[mode] $cmd "$@"; then + if ! _p9k_cache_stat_get $0" ${(q)*}" $cmd; then local out out="$($cmd "$@" 2>&1)" # this line is the only diff with _p9k_cached_cmd_stdout - _p9k_cache_set $(( ! $? )) "$out" + _p9k_cache_stat_set $(( ! $? )) "$out" fi (( $_p9k_cache_val[1] )) || return _p9k_ret=$_p9k_cache_val[2] @@ -1754,7 +1754,7 @@ prompt_node_version() { (( $+commands[node] )) || return if (( _POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY )); then - local dir=$PWD + local dir=$_p9k_pwd while true; do [[ $dir == / ]] && return [[ -e $dir/package.json ]] && break @@ -1771,9 +1771,11 @@ prompt_node_version() { 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 + while [[ -r $NVM_DIR/alias/$v ]]; do + local target= + IFS='' read -r target <$NVM_DIR/alias/$v + [[ -z $target ]] && break + (( $seen[(I)$target] )) && return seen+=$target v=$target done @@ -1864,7 +1866,7 @@ _p9k_nvm_ls_current() { # Segment to display Node version from NVM # Only prints the segment if different than the default value prompt_nvm() { - (( $+commands[nvm] )) || return + (( $+commands[nvm] || $+functions[nvm] )) || return [[ -n $NVM_DIR ]] && _p9k_nvm_ls_current || return local current=$_p9k_ret ! _p9k_nvm_ls_default || [[ $_p9k_ret != $current ]] || return @@ -1908,10 +1910,10 @@ function _p9k_nodenv_global_version() { # Segment to display nodenv information # https://github.com/nodenv/nodenv prompt_nodenv() { - (( $+commands[nodenv] )) || return + (( $+commands[nodenv] || $+functions[nodenv] )) || return _p9k_ret=$NODENV_VERSION if [[ -z $_p9k_ret ]]; then - [[ $NODENV_DIR == /* ]] && local dir=$NODENV_DIR || local dir="$PWD/$NODENV_DIR" + [[ $NODENV_DIR == /* ]] && local dir=$NODENV_DIR || local dir="$_p9k_pwd_a/$NODENV_DIR" while [[ $dir != //[^/]# ]]; do _p9k_read_nodenv_version_file $dir/.node-version && break [[ $dir == / ]] && break @@ -1934,6 +1936,23 @@ prompt_nodenv() { _p9k_prompt_segment "$0" "black" "green" 'NODE_ICON' 0 '' "${v//\%/%%}" } +prompt_dotnet_version() { + (( $+commands[dotnet] )) || return + + if (( _POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY )); then + local dir=$_p9k_pwd + while true; do + [[ $dir == / ]] && return + [[ -n $dir/(project.json|global.json|packet.dependencies|*.csproj|*.fsproj|*.xproj|*.sln)(#qN^/) ]] && break + dir=${dir:h} + done + fi + + _p9k_cached_cmd_stdout dotnet --version || return + _p9k_prompt_segment "$0" "magenta" "white" 'DOTNET_ICON' 0 '' "$_p9k_ret" +} + + ################################################################ # Segment to print a little OS icon prompt_os_icon() { @@ -1983,9 +2002,8 @@ prompt_ram() { function _p9k_read_rbenv_version_file() { [[ -r $1 ]] || return - local content - read -r content <$1 2>/dev/null - _p9k_ret="${${(A)=content}[1]}" + local rest + read _p9k_ret rest <$1 2>/dev/null [[ -n $_p9k_ret ]] } @@ -1997,10 +2015,10 @@ function _p9k_rbenv_global_version() { # Segment to display rbenv information # https://github.com/rbenv/rbenv#choosing-the-ruby-version prompt_rbenv() { - (( $+commands[rbenv] )) || return + (( $+commands[rbenv] || $+functions[rbenv] )) || return local v=$RBENV_VERSION if [[ -z $v ]]; then - [[ $RBENV_DIR == /* ]] && local dir=$RBENV_DIR || local dir="$PWD/$RBENV_DIR" + [[ $RBENV_DIR == /* ]] && local dir=$RBENV_DIR || local dir="$_p9k_pwd_a/$RBENV_DIR" while true; do if _p9k_read_rbenv_version_file $dir/.ruby-version; then v=$_p9k_ret @@ -2047,6 +2065,14 @@ prompt_rust_version() { _p9k_cached_cmd_stdout rustc --version || return local v=${${_p9k_ret#rustc }%% *} [[ -n $v ]] || return + if (( _POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY )); then + local dir=$_p9k_pwd_a + while true; do + [[ $dir == / ]] && return + [[ -e $dir/Cargo.toml ]] && break + dir=${dir:h} + done + fi _p9k_prompt_segment "$0" "darkorange" "$_p9k_color1" 'RUST_ICON' 0 '' "${v//\%/%%}" } @@ -2063,9 +2089,11 @@ prompt_rspec_stats() { ################################################################ # Segment to display Ruby Version Manager information prompt_rvm() { - (( $+commands[rvm-prompt] )) || return + (( $+commands[rvm-prompt] || $+functions[rvm-prompt] )) || return [[ $GEM_HOME == *rvm* && $ruby_string != $rvm_path/bin/ruby ]] || return - local v=${${${GEM_HOME:t}%%${rvm_gemset_separator:-@}*}#*-} + local v=${GEM_HOME:t} + (( _POWERLEVEL9K_RVM_SHOW_GEMSET )) || v=${v%%${rvm_gemset_separator:-@}*} + (( _POWERLEVEL9K_RVM_SHOW_PREFIX )) || v=${v#*-} [[ -n $v ]] || return _p9k_prompt_segment "$0" "240" "$_p9k_color1" 'RUBY_ICON' 0 '' "${v//\%/%%}" } @@ -2073,7 +2101,7 @@ prompt_rvm() { ################################################################ # Segment to display SSH icon when connected prompt_ssh() { - if [[ -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]; then + if (( P9K_SSH )); then _p9k_prompt_segment "$0" "$_p9k_color1" "yellow" 'SSH_ICON' 0 '' '' fi } @@ -2121,14 +2149,46 @@ prompt_status() { } prompt_prompt_char() { - if (( _p9k_status )); then - _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${KEYMAP:-0}:#(vicmd|vivis|vivli)}' '❯' - _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#vicmd0}' '❮' - _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + if (( __p9k_sh_glob )); then + if (( _p9k_status )); then + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' '❯' + _p9k_prompt_segment $0_ERROR_VIOWR "$_p9k_color1" 196 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' '▶' + else + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}}' '❯' + fi + _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${$((! ${#${${${${:-$_p9k_keymap$_p9k_region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' 'Ⅴ' + else + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' '❯' + _p9k_prompt_segment $0_OK_VIOWR "$_p9k_color1" 76 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' '▶' + else + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}}' '❯' + fi + _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${$((! ${#${${${${:-$_p9k_keymap$_p9k_region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' 'Ⅴ' + fi else - _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${KEYMAP:-0}:#(vicmd|vivis|vivli)}' '❯' - _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#vicmd0}' '❮' - _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + if (( _p9k_status )); then + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' '❯' + _p9k_prompt_segment $0_ERROR_VIOWR "$_p9k_color1" 196 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' '▶' + else + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${_p9k_keymap:#(vicmd|vivis|vivli)}' '❯' + fi + _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + else + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' '❯' + _p9k_prompt_segment $0_OK_VIOWR "$_p9k_color1" 76 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' '▶' + else + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${_p9k_keymap:#(vicmd|vivis|vivli)}' '❯' + fi + _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + fi fi } @@ -2227,14 +2287,12 @@ prompt_date() { prompt_todo() { local todo=$commands[todo.sh] [[ -n $todo && -r $_p9k_todo_file ]] || return - local -H stat - zstat -H stat -- $_p9k_todo_file 2>/dev/null || return - if ! _p9k_cache_get $0 $stat[inode] $stat[mtime] $stat[size]; then + if ! _p9k_cache_stat_get $0 $_p9k_todo_file; then local count="$($todo -p ls | tail -1)" if [[ $count == (#b)'TODO: '[[:digit:]]##' of '([[:digit:]]##)' '* ]]; then - _p9k_cache_set 1 $match[1] + _p9k_cache_stat_set 1 $match[1] else - _p9k_cache_set 0 0 + _p9k_cache_stat_set 0 0 fi fi (( $_p9k_cache_val[1] )) || return @@ -2251,6 +2309,7 @@ typeset -gA __p9k_vcs_states=( 'MODIFIED' '3' 'UNTRACKED' '2' 'LOADING' '8' + 'CONFLICTED' '3' ) function +vi-git-untracked() { @@ -2465,13 +2524,13 @@ _p9k_vcs_info_init() { function _p9k_vcs_status_save() { local z=$'\0' - _p9k_last_git_prompt[$VCS_STATUS_WORKDIR]=$VCS_STATUS_ACTION$z$VCS_STATUS_COMMIT\ + _p9k_gitstatus_last[$VCS_STATUS_WORKDIR]=$VCS_STATUS_ACTION$z$VCS_STATUS_COMMIT\ $z$VCS_STATUS_COMMITS_AHEAD$z$VCS_STATUS_COMMITS_BEHIND$z$VCS_STATUS_HAS_CONFLICTED\ $z$VCS_STATUS_HAS_STAGED$z$VCS_STATUS_HAS_UNSTAGED$z$VCS_STATUS_HAS_UNTRACKED\ $z$VCS_STATUS_INDEX_SIZE$z$VCS_STATUS_LOCAL_BRANCH$z$VCS_STATUS_NUM_CONFLICTED\ $z$VCS_STATUS_NUM_STAGED$z$VCS_STATUS_NUM_UNSTAGED$z$VCS_STATUS_NUM_UNTRACKED\ $z$VCS_STATUS_REMOTE_BRANCH$z$VCS_STATUS_REMOTE_NAME$z$VCS_STATUS_REMOTE_URL\ -$z$VCS_STATUS_RESULT$z$VCS_STATUS_STASHES$z$VCS_STATUS_TAG +$z$VCS_STATUS_RESULT$z$VCS_STATUS_STASHES$z$VCS_STATUS_TAG$z$VCS_STATUS_NUM_UNSTAGED_DELETED } function _p9k_vcs_status_restore() { @@ -2481,13 +2540,14 @@ function _p9k_vcs_status_restore() { VCS_STATUS_NUM_CONFLICTED VCS_STATUS_NUM_STAGED VCS_STATUS_NUM_UNSTAGED \ VCS_STATUS_NUM_UNTRACKED VCS_STATUS_REMOTE_BRANCH VCS_STATUS_REMOTE_NAME \ VCS_STATUS_REMOTE_URL VCS_STATUS_RESULT VCS_STATUS_STASHES VCS_STATUS_TAG \ + VCS_STATUS_NUM_UNSTAGED_DELETED in "${(@0)1}"; do done } function _p9k_vcs_status_for_dir() { local dir=$1 while true; do - _p9k_ret=$_p9k_last_git_prompt[$dir] + _p9k_ret=$_p9k_gitstatus_last[$dir] [[ -n $_p9k_ret ]] && return 0 [[ $dir == / ]] && return 1 dir=${dir:h} @@ -2498,7 +2558,7 @@ function _p9k_vcs_status_purge() { local dir=$1 while true; do # unset doesn't work if $dir contains weird shit - _p9k_last_git_prompt[$dir]="" + _p9k_gitstatus_last[$dir]="" _p9k_git_slow[$dir]="" [[ $dir == / ]] && break dir=${dir:h} @@ -2518,8 +2578,8 @@ function _p9k_vcs_icon() { function _p9k_vcs_render() { local state - if (( $+_p9k_next_vcs_dir )); then - if _p9k_vcs_status_for_dir ${${GIT_DIR:a}:-$PWD}; then + if (( $+_p9k_gitstatus_next_dir )); then + if _p9k_vcs_status_for_dir ${${GIT_DIR:A}:-$_p9k_pwd_a}; then _p9k_vcs_status_restore $_p9k_ret state=LOADING else @@ -2532,7 +2592,9 @@ function _p9k_vcs_render() { if (( _POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING )); then if [[ -z $state ]]; then - if [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then + if [[ $VCS_STATUS_HAS_CONFLICTED == 1 && $_POWERLEVEL9K_VCS_CONFLICTED_STATE == 1 ]]; then + state=CONFLICTED + elif [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then state=MODIFIED elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then state=UNTRACKED @@ -2565,6 +2627,7 @@ function _p9k_vcs_render() { "$VCS_STATUS_NUM_STAGED" "$VCS_STATUS_NUM_UNSTAGED" "$VCS_STATUS_NUM_UNTRACKED" + "$VCS_STATUS_HAS_CONFLICTED" "$VCS_STATUS_HAS_STAGED" "$VCS_STATUS_HAS_UNSTAGED" "$VCS_STATUS_HAS_UNTRACKED" @@ -2572,6 +2635,7 @@ function _p9k_vcs_render() { "$VCS_STATUS_COMMITS_BEHIND" "$VCS_STATUS_STASHES" "$VCS_STATUS_TAG" + "$VCS_STATUS_NUM_UNSTAGED_DELETED" ) if [[ $_POWERLEVEL9K_SHOW_CHANGESET == 1 || -z $VCS_STATUS_LOCAL_BRANCH ]]; then cache_key+=$VCS_STATUS_COMMIT @@ -2582,7 +2646,9 @@ function _p9k_vcs_render() { local content if (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)vcs-detect-changes]} )); then - if [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then + if [[ $VCS_STATUS_HAS_CONFLICTED == 1 && $_POWERLEVEL9K_VCS_CONFLICTED_STATE == 1 ]]; then + : ${state:=CONFLICTED} + elif [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then : ${state:=MODIFIED} elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then : ${state:=UNTRACKED} @@ -2614,8 +2680,24 @@ function _p9k_vcs_render() { fi if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then - (( _POWERLEVEL9K_HIDE_BRANCH_ICON )) && _p9k_ret='' || _p9k_get_icon prompt_vcs_$state VCS_BRANCH_ICON - _$0_fmt BRANCH "$ws$_p9k_ret${VCS_STATUS_LOCAL_BRANCH//\%/%%}" + local branch=$ws + if (( !_POWERLEVEL9K_HIDE_BRANCH_ICON )); then + _p9k_get_icon prompt_vcs_$state VCS_BRANCH_ICON + branch+=$_p9k_ret + fi + if (( $+_POWERLEVEL9K_VCS_SHORTEN_LENGTH && $+_POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH && + $#VCS_STATUS_LOCAL_BRANCH > _POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH && + $#VCS_STATUS_LOCAL_BRANCH > _POWERLEVEL9K_VCS_SHORTEN_LENGTH )) && + [[ $_POWERLEVEL9K_VCS_SHORTEN_STRATEGY == (truncate_middle|truncate_from_right) ]]; then + branch+=${VCS_STATUS_LOCAL_BRANCH[1,_POWERLEVEL9K_VCS_SHORTEN_LENGTH]//\%/%%}${_POWERLEVEL9K_VCS_SHORTEN_DELIMITER} + if [[ $_POWERLEVEL9K_VCS_SHORTEN_STRATEGY == truncate_middle ]]; then + _p9k_vcs_style $state BRANCH + branch+=${_p9k_ret}${VCS_STATUS_LOCAL_BRANCH[-_POWERLEVEL9K_VCS_SHORTEN_LENGTH,-1]//\%/%%} + fi + else + branch+=${VCS_STATUS_LOCAL_BRANCH//\%/%%} + fi + _$0_fmt BRANCH $branch fi if [[ $_POWERLEVEL9K_VCS_HIDE_TAGS == 0 && -n $VCS_STATUS_TAG ]]; then @@ -2674,7 +2756,8 @@ function _p9k_vcs_render() { } function _p9k_vcs_resume() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} if [[ $VCS_STATUS_RESULT == ok-async ]]; then local latency=$((EPOCHREALTIME - _p9k_gitstatus_start_time)) @@ -2686,23 +2769,23 @@ function _p9k_vcs_resume() { _p9k_vcs_status_save fi - if [[ -z $_p9k_next_vcs_dir ]]; then - unset _p9k_next_vcs_dir + if [[ -z $_p9k_gitstatus_next_dir ]]; then + unset _p9k_gitstatus_next_dir case $VCS_STATUS_RESULT in - norepo-async) (( $1 )) && _p9k_vcs_status_purge ${${GIT_DIR:a}:-$PWD};; - ok-async) (( $1 )) || _p9k_next_vcs_dir=${${GIT_DIR:a}:-$PWD};; + norepo-async) (( $1 )) && _p9k_vcs_status_purge ${${GIT_DIR:A}:-$_p9k_pwd_a};; + ok-async) (( $1 )) || _p9k_gitstatus_next_dir=${${GIT_DIR:A}:-$_p9k_pwd_a};; esac fi - if [[ -n $_p9k_next_vcs_dir ]]; then - if ! gitstatus_query -d $_p9k_next_vcs_dir -t 0 -c '_p9k_vcs_resume 1' POWERLEVEL9K; then - unset _p9k_next_vcs_dir + if [[ -n $_p9k_gitstatus_next_dir ]]; then + if ! gitstatus_query -d $_p9k_gitstatus_next_dir -t 0 -c '_p9k_vcs_resume 1' POWERLEVEL9K; then + unset _p9k_gitstatus_next_dir unset VCS_STATUS_RESULT else case $VCS_STATUS_RESULT in - tout) _p9k_next_vcs_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; - norepo-sync) _p9k_vcs_status_purge $_p9k_next_vcs_dir; unset _p9k_next_vcs_dir;; - ok-sync) _p9k_vcs_status_save; unset _p9k_next_vcs_dir;; + tout) _p9k_gitstatus_next_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; + norepo-sync) _p9k_vcs_status_purge $_p9k_gitstatus_next_dir; unset _p9k_gitstatus_next_dir;; + ok-sync) _p9k_vcs_status_save; unset _p9k_gitstatus_next_dir;; esac fi fi @@ -2711,17 +2794,16 @@ function _p9k_vcs_resume() { } function _p9k_vcs_gitstatus() { - (( _POWERLEVEL9K_DISABLE_GITSTATUS )) && return 1 if [[ $_p9k_refresh_reason == precmd ]]; then - if (( $+_p9k_next_vcs_dir )); then - _p9k_next_vcs_dir=${${GIT_DIR:a}:-$PWD} + if (( $+_p9k_gitstatus_next_dir )); then + _p9k_gitstatus_next_dir=${${GIT_DIR:A}:-$_p9k_pwd_a} else - local dir=${${GIT_DIR:a}:-$PWD} + local dir=${${GIT_DIR:A}:-$_p9k_pwd_a} local -F timeout=_POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS if ! _p9k_vcs_status_for_dir $dir; then gitstatus_query -d $dir -t $timeout -p -c '_p9k_vcs_resume 0' POWERLEVEL9K || return 1 case $VCS_STATUS_RESULT in - tout) _p9k_next_vcs_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME; return 0;; + tout) _p9k_gitstatus_next_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME; return 0;; norepo-sync) return 0;; ok-sync) _p9k_vcs_status_save;; esac @@ -2733,14 +2815,15 @@ function _p9k_vcs_gitstatus() { 1) timeout=0; break;; esac done - dir=${${GIT_DIR:a}:-$PWD} + dir=${${GIT_DIR:A}:-$_p9k_pwd_a} fi + (( _p9k_prompt_idx == 1 )) && timeout=0 if ! gitstatus_query -d $dir -t $timeout -c '_p9k_vcs_resume 1' POWERLEVEL9K; then unset VCS_STATUS_RESULT return 1 fi case $VCS_STATUS_RESULT in - tout) _p9k_next_vcs_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; + tout) _p9k_gitstatus_next_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; norepo-sync) _p9k_vcs_status_purge $dir;; ok-sync) _p9k_vcs_status_save;; esac @@ -2754,7 +2837,7 @@ function _p9k_vcs_gitstatus() { prompt_vcs() { local -a backends=($_POWERLEVEL9K_VCS_BACKENDS) - if (( ${backends[(I)git]} )) && _p9k_vcs_gitstatus; then + if (( ${backends[(I)git]} && !_p9k_gitstatus_disabled )) && _p9k_vcs_gitstatus; then _p9k_vcs_render && return backends=(${backends:#git}) fi @@ -2786,14 +2869,42 @@ prompt_vcs() { ################################################################ # Vi Mode: show editing mode (NORMAL|INSERT|VISUAL) prompt_vi_mode() { - if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then - _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${KEYMAP:-0}:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" - fi - if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then - _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" - _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + if (( __p9k_sh_glob )); then + if (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )); then + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + _p9k_prompt_segment $0_OVERWRITE "$_p9k_color1" blue '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' "$_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING" + else + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + fi + + if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${$((! ${#${${${${:-$_p9k_keymap$_p9k_region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + else + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${$((! ${#${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}})):#0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + fi else - _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)KEYMAP:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + if (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )); then + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + _p9k_prompt_segment $0_OVERWRITE "$_p9k_color1" blue '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' "$_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING" + else + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${_p9k_keymap:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + fi + + if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + else + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)_p9k_keymap:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + fi fi } @@ -2814,7 +2925,7 @@ prompt_virtualenv() { function _p9k_read_pyenv_version_file() { [[ -r $1 ]] || return local content - read -rd $'\0' content <$1 2>/dev/null + IFS='' read -rd $'\0' content <$1 2>/dev/null _p9k_ret=${${(j.:.)${(@)${=content}#python-}:-system}} } @@ -2826,10 +2937,10 @@ function _p9k_pyenv_global_version() { # Segment to display pyenv information # https://github.com/pyenv/pyenv#choosing-the-python-version prompt_pyenv() { - (( $+commands[pyenv] )) || return + (( $+commands[pyenv] || $+functions[pyenv] )) || return local v=${(j.:.)${(@)${(s.:.)PYENV_VERSION}#python-}} if [[ -z $v ]]; then - [[ $PYENV_DIR == /* ]] && local dir=$PYENV_DIR || local dir="$PWD/$PYENV_DIR" + [[ $PYENV_DIR == /* ]] && local dir=$PYENV_DIR || local dir="$_p9k_pwd_a/$PYENV_DIR" while true; do if _p9k_read_pyenv_version_file $dir/.python-version; then v=$_p9k_ret @@ -2876,7 +2987,7 @@ prompt_swift_version() { ################################################################ # dir_writable: Display information about the user's permission to write in the current directory prompt_dir_writable() { - if [[ ! -w "$PWD" ]]; then + if [[ ! -w "$_p9k_pwd" ]]; then _p9k_prompt_segment "$0_FORBIDDEN" "red" "yellow1" 'LOCK_ICON' 0 '' '' fi } @@ -2886,15 +2997,7 @@ prompt_dir_writable() { prompt_kubecontext() { (( $+commands[kubectl] )) || return - local cfg - local -a key - for cfg in ${(s.:.)${KUBECONFIG:-$HOME/.kube/config}}; do - local -H stat - zstat -H stat -- $cfg 2>/dev/null || continue - key+=($cfg $stat[inode] $stat[mtime] $stat[size] $stat[mode]) - done - - if ! _p9k_cache_get $0 "${key[@]}"; then + if ! _p9k_cache_stat_get $0 ${(s.:.)${KUBECONFIG:-$HOME/.kube/config}}; then local name namespace cluster cloud_name cloud_account cloud_zone cloud_cluster text state () { local cfg && cfg=(${(f)"$(kubectl config view -o=yaml 2>/dev/null)"}) || return @@ -2954,7 +3057,7 @@ prompt_kubecontext() { fi done fi - _p9k_cache_set "$name" "$namespace" "$cluster" "$cloud_name" "$cloud_account" "$cloud_zone" "$cloud_cluster" "$text" "$state" + _p9k_cache_stat_set "$name" "$namespace" "$cluster" "$cloud_name" "$cloud_account" "$cloud_zone" "$cloud_cluster" "$text" "$state" fi typeset -g P9K_KUBECONTEXT_NAME=$_p9k_cache_val[1] @@ -2996,8 +3099,25 @@ prompt_java_version() { _p9k_prompt_segment "$0" "red" "white" "JAVA_ICON" 0 '' "${v//\%/%%}" } +prompt_azure() { + (( $+commands[az] )) || return + local cfg=${AZURE_CONFIG_DIR:-$HOME/.azure}/azureProfile.json + if ! _p9k_cache_stat_get $0 $cfg; then + local name + if (( $+commands[jq] )) && name="$(jq -r '[.subscriptions[]|select(.isDefault==true)|.name][]|strings' $cfg 2>/dev/null)"; then + name=${name%%$'\n'*} + elif ! name="$(az account show --query name --output tsv 2>/dev/null)"; then + name= + fi + _p9k_cache_stat_set "$name" + fi + [[ -n $_p9k_cache_val[1] ]] || return + _p9k_prompt_segment "$0" "blue" "white" "AZURE_ICON" 0 '' "${_p9k_cache_val[1]//\%/%%}" +} + typeset -gra __p9k_nordvpn_tag=( P9K_NORDVPN_STATUS + P9K_NORDVPN_TECHNOLOGY P9K_NORDVPN_PROTOCOL P9K_NORDVPN_IP_ADDRESS P9K_NORDVPN_SERVER @@ -3017,12 +3137,11 @@ function _p9k_fetch_nordvpn_status() { IFS='' read -t 0.25 -r tag <&3 tag=$'\015' while true; do - tag=${__p9k_char2byte[${(q+)tag}]:-0} + tag=$((#tag)) (( (tag >>= 3) && tag <= $#__p9k_nordvpn_tag )) || break tag=$__p9k_nordvpn_tag[tag] sysread -c n -s 1 -t 0.25 len <&3 - len=${__p9k_char2byte[${(q+)len}]} - [[ -n $len ]] + len=$((#len)) val= (( ! len )) || { sysread -c n -s $len -t 0.25 val <&3 @@ -3052,6 +3171,7 @@ function _p9k_fetch_nordvpn_status() { # # - P9K_NORDVPN_STATUS # - P9K_NORDVPN_PROTOCOL +# - P9K_NORDVPN_TECHNOLOGY # - P9K_NORDVPN_IP_ADDRESS # - P9K_NORDVPN_SERVER # - P9K_NORDVPN_COUNTRY @@ -3096,6 +3216,34 @@ function prompt_nordvpn() { esac } +function prompt_ranger() { + [[ -n $RANGER_LEVEL ]] || return + _p9k_prompt_segment $0 $_p9k_color1 yellow RANGER_ICON 0 '' $RANGER_LEVEL +} + +function prompt_terraform() { + (( $+commands[terraform] )) || return + local ws=default + if [[ -n $TF_WORKSPACE ]]; then + ws=$TF_WORKSPACE + else + local f=${TF_DATA_DIR:-.terraform}/environment + [[ -r $f ]] && _p9k_read_file $f && ws=$_p9k_ret + fi + ws=${${ws##[[:space:]]#}%%[[:space:]]#} + [[ $ws == default ]] || _p9k_prompt_segment $0 $_p9k_color1 blue TERRAFORM_ICON 0 '' $ws +} + +function prompt_proxy() { + local -U p=( + $all_proxy $http_proxy $https_proxy $ftp_proxy + $ALL_PROXY $HTTP_PROXY $HTTPS_PROXY $FTP_PROXY) + p=(${(@)${(@)${(@)p#*://}##*@}%%/*}) + (( $#p )) || return + (( $#p == 1 )) || p=("") + _p9k_prompt_segment $0 $_p9k_color1 blue PROXY_ICON 0 '' "$p[1]" +} + _p9k_preexec() { if (( $+_p9k_real_zle_rprompt_indent )); then if [[ -n $_p9k_real_zle_rprompt_indent ]]; then @@ -3109,6 +3257,21 @@ _p9k_preexec() { _p9k_timer_start=EPOCHREALTIME } +function _p9k_set_iface() { + _p9k_iface=() + [[ -x /sbin/ifconfig ]] || return + local line + local iface + for line in ${(f)"$(/sbin/ifconfig 2>/dev/null)"}; do + if [[ $line == (#b)([^[:space:]]##):[[:space:]]##flags=(<->)'<'* ]]; then + [[ $match[2] == *[13579] ]] && iface=$match[1] || iface= + elif [[ -n $iface && $line == (#b)[[:space:]]##inet[[:space:]]##([0-9.]##)* ]]; then + _p9k_iface[$iface]=$match[1] + iface= + fi + done +} + function _p9k_build_segment() { _p9k_segment_name=${_p9k_segment_name%_joined} if [[ $_p9k_segment_name == custom_* ]]; then @@ -3120,9 +3283,15 @@ function _p9k_build_segment() { } function _p9k_set_prompt() { + local ifs=$IFS + IFS=$' \t\n\0' + _p9k_pwd=${(%):-%/} + _p9k_pwd_a=${_p9k_pwd:A} PROMPT=$_p9k_prompt_prefix_left RPROMPT= + (( _p9k_fetch_iface )) && _p9k_set_iface + local -i left_idx=1 right_idx=1 num_lines=$#_p9k_line_segments_left i for i in {1..$num_lines}; do local right= @@ -3162,7 +3331,7 @@ function _p9k_set_prompt() { PROMPT+='${${_p9k_g::=0}+}' fi if [[ $_POWERLEVEL9K_DIR_MAX_LENGTH == <->('%'|) ]]; then - local lim + local lim= if [[ $_POWERLEVEL9K_DIR_MAX_LENGTH[-1] == '%' ]]; then lim="$_p9k_dir_len-$((0.01*$_POWERLEVEL9K_DIR_MAX_LENGTH[1,-2]))*_p9k_clm" else @@ -3198,17 +3367,19 @@ function _p9k_set_prompt() { _p9k_prompt_side= (( $#_p9k_cache < _POWERLEVEL9K_MAX_CACHE_SIZE )) || _p9k_cache=() + IFS=$ifs } function _p9k_update_prompt() { _p9k_refresh_reason=$1 _p9k_set_prompt _p9k_refresh_reason='' - zle && zle .reset-prompt && zle -R + _p9k_reset_prompt } powerlevel9k_refresh_prompt_inplace() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} (( __p9k_enabled )) || return _p9k_refresh_reason=precmd _p9k_set_prompt @@ -3217,11 +3388,12 @@ powerlevel9k_refresh_prompt_inplace() { p9k_refresh_prompt_inplace() { powerlevel9k_refresh_prompt_inplace } +typeset -gi __p9k_sh_glob +typeset -gi __p9k_ksh_arrays typeset -gi __p9k_new_status typeset -ga __p9k_new_pipestatus _p9k_save_status() { - emulate -L zsh && setopt no_hist_expand extended_glob local -i pipe if (( !$+_p9k_line_finished )); then : # SIGINT @@ -3265,51 +3437,157 @@ _p9k_save_status() { fi } -_p9k_precmd() { - __p9k_new_status=$? - __p9k_new_pipestatus=($pipestatus) +function _p9k_dump_state() { + is-at-least 5.4 || return # `typeset -g` doesn't roundtrip in zsh prior to 5.4. + local dir=${__p9k_dump_file:h} + [[ -d $dir ]] || mkdir -pm 0700 $dir || return + [[ -w $dir ]] || return + local tmp=$__p9k_dump_file.$$-$EPOCHREALTIME-$RANDOM + local -i fd + sysopen -a -m 600 -o creat,trunc -u fd $tmp || return + { + local include='_POWERLEVEL9K_*|_p9k_*|icons|OS|DEFAULT_COLOR|DEFAULT_COLOR_INVERTED' + local exclude='_p9k_gitstatus_*|_p9k_cache_stat_meta|_p9k_cache_stat_fprint|_p9k_cache_fprint_key|_p9k_param_sig|_p9k_public_ip|_p9k_prompt|_p9k_prompt_idx|_p9k_dump_pid|_p9k_dump_scheduled|_p9k_line_finished|_p9k_preexec_cmd|_p9k_status|_p9k_pipestatus|_p9k_timer_start|_p9k_region_active|_p9k_keymap|_p9k_zle_state|_p9k_async_pump_*' + typeset -g __p9k_cached_param_sig=$_p9k_param_sig + typeset -p __p9k_cached_param_sig >&$fd || return + unset __p9k_cached_param_sig + (( $+_p9k_preinit )) && { print -r -- $_p9k_preinit >&$fd || return } + print -r -- '_p9k_restore_state_impl() {' >&$fd || return + typeset -pm "($include)~($exclude)" >&$fd || return + print -r -- '}' >&$fd || return + } always { + exec {fd}>&- + } + zf_mv -f $tmp $__p9k_dump_file || return + if [[ ${(%):-%#} == % ]]; then + zcompile $__p9k_dump_file || zf_rm -f $__p9k_dump_file.zwc + fi +} - if (( $+_p9k_real_zle_rprompt_indent )); then - if [[ -n $_p9k_real_zle_rprompt_indent ]]; then - ZLE_RPROMPT_INDENT=$_p9k_real_zle_rprompt_indent - else - unset ZLE_RPROMPT_INDENT +function _p9k_restore_state() { + { + [[ $__p9k_cached_param_sig == $_p9k_param_sig ]] || return + (( $+functions[_p9k_restore_state_impl] )) || return + _p9k_restore_state_impl + _p9k_state_restored=1 + } always { + unset __p9k_cached_param_sig + if (( !_p9k_state_restored && $+functions[_p9k_preinit] )); then + unfunction _p9k_preinit + (( $+functions[gitstatus_stop] )) && gitstatus_stop POWERLEVEL9K + fi + } +} + +_p9k_precmd_impl() { + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + + (( __p9k_enabled )) || return + + if ! zle || [[ -z $_p9k_param_sig ]]; then + if zle; then + __p9k_new_status=0 + __p9k_new_pipestatus=(0) fi - unset _p9k_real_zle_rprompt_indent - fi - if _p9k_must_init; then - if (( !__p9k_configured )); then - __p9k_configured=1 - if [[ "${parameters[(I)POWERLEVEL9K_*]}" == (POWERLEVEL9K_MODE|) ]] && _p9k_can_configure -q; then - if $__p9k_root_dir/internal/wizard.zsh -d $__p9k_root_dir; then - source $__p9k_cfg_path - _p9k_must_init + print -rn "${_p9k_prompt_newline:-}" + + if (( $+_p9k_real_zle_rprompt_indent )); then + if [[ -n $_p9k_real_zle_rprompt_indent ]]; then + ZLE_RPROMPT_INDENT=$_p9k_real_zle_rprompt_indent + else + unset ZLE_RPROMPT_INDENT + fi + unset _p9k_real_zle_rprompt_indent + fi + + if _p9k_must_init; then + if (( !__p9k_configured )); then + __p9k_configured=1 + if [[ "${parameters[(I)POWERLEVEL9K_*]}" == (POWERLEVEL9K_MODE|) ]] && _p9k_can_configure -q; then + ( + local p=("${(@)parameters[(I)AWESOME_*|CODEPOINT_*]}") + if (( $#p )); then + typeset -x -- "$p" + fi + "$__p9k_root_dir"/internal/wizard.zsh -d "$__p9k_root_dir" + ) + if (( ! $? )); then + source "$__p9k_cfg_path" + _p9k_must_init + fi fi fi + _p9k_init + fi + + if (( _p9k_timer_start )); then + typeset -gF P9K_COMMAND_DURATION_SECONDS=$((EPOCHREALTIME - _p9k_timer_start)) + else + unset P9K_COMMAND_DURATION_SECONDS + fi + _p9k_save_status + + _p9k_timer_start=0 + _p9k_region_active=0 + + unset _p9k_line_finished + unset _p9k_preexec_cmd + _p9k_keymap=main + _p9k_zle_state=insert + + if ! zle; then + (( ++_p9k_prompt_idx )) fi - _p9k_init fi - unsetopt localoptions - prompt_opts=(cr percent sp subst) - setopt nopromptbang prompt{cr,percent,sp,subst} + _p9k_refresh_reason=precmd + _p9k_set_prompt + _p9k_refresh_reason='' - _p9k_timer_end=EPOCHREALTIME - _p9k_save_status + if ! zle && { (( ! _p9k_dump_pid )) || ! kill -0 $_p9k_dump_pid 2>/dev/null }; then + _p9k_dump_pid=0 + if (( _p9k_prompt_idx == 1 && !_p9k_state_restored )); then + _p9k_dump_state + _p9k_dump_scheduled=0 + elif (( _p9k_dump_scheduled )); then + _p9k_dump_state &! + _p9k_dump_pid=$! + _p9k_dump_scheduled=0 + fi + fi +} - powerlevel9k_refresh_prompt_inplace +_p9k_precmd() { + __p9k_new_status=$? + __p9k_new_pipestatus=($pipestatus) + [[ -o ksh_arrays ]] && __p9k_ksh_arrays=1 || __p9k_ksh_arrays=0 + [[ -o sh_glob ]] && __p9k_sh_glob=1 || __p9k_sh_glob=0 - unset _p9k_line_finished - unset _p9k_preexec_cmd - _p9k_timer_start=0 - _p9k_region_active=0 + unsetopt localoptions + prompt_opts=(percent subst) + [[ ! -o prompt_sp ]] || prompt_opts+=sp + [[ ! -o prompt_cr ]] || prompt_opts+=cr + setopt nopromptbang prompt_percent prompt_subst + + _p9k_precmd_impl } -function _p9k_zle_keymap_select() { +function _p9k_reset_prompt() { + (( __p9k_ksh_arrays )) && setopt ksh_arrays + (( __p9k_sh_glob )) && setopt sh_glob zle && zle .reset-prompt && zle -R } +function _p9k_zle_keymap_select() { + _p9k_reset_prompt +} + +function _p9k_zle_state_changed() { + _p9k_reset_prompt +} + _p9k_deinit_async_pump() { if (( _p9k_async_pump_lock_fd )); then zsystem flock -u $_p9k_async_pump_lock_fd @@ -3332,12 +3610,18 @@ _p9k_deinit_async_pump() { rm -f $_p9k_async_pump_lock _p9k_async_pump_lock='' fi + _p9k_async_pump_subshell=-1 + _p9k_async_pump_shell_pid=-1 add-zsh-hook -D zshexit _p9k_kill_async_pump } function _p9k_on_async_message() { - emulate -L zsh && setopt no_hist_expand extended_glob - (( ARGC == 1 )) || return + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + if (( ARGC != 1 )); then + _p9k_deinit_async_pump + return + fi local msg='' IFS='' while read -r -t -u $1 msg; do [[ $__p9k_enabled == 1 && $1 == $_p9k_async_pump_fd ]] && eval $_p9k_async_pump_line$msg @@ -3345,12 +3629,13 @@ function _p9k_on_async_message() { msg= done _p9k_async_pump_line+=$msg - [[ $__p9k_enabled == 1 && $1 == $_p9k_async_pump_fd ]] && zle && zle .reset-prompt && zle -R + [[ $__p9k_enabled == 1 && $1 == $_p9k_async_pump_fd ]] && _p9k_reset_prompt } function _p9k_async_pump() { emulate -L zsh || return - setopt noaliases no_hist_expand extended_glob || return + setopt no_aliases no_hist_expand extended_glob || return + setopt no_prompt_bang prompt_{percent,subst} || return zmodload zsh/system zsh/datetime || return echo $$ || return @@ -3411,8 +3696,9 @@ function _p9k_async_pump() { } function _p9k_kill_async_pump() { - emulate -L zsh && setopt no_hist_expand extended_glob - if (( ZSH_SUBSHELL == _p9k_async_pump_subshell )); then + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + if [[ $ZSH_SUBSHELL == $_p9k_async_pump_subshell && $$ == $_p9k_async_pump_shell_pid ]]; then _p9k_deinit_async_pump fi } @@ -3426,8 +3712,9 @@ _p9k_init_async_pump() { _p9k_start_async_pump() { setopt err_return no_bg_nice - _p9k_async_pump_lock="$(mktemp ${TMPDIR:-/tmp}/p9k-$$-async-pump-lock.XXXXXXXXXX)" - _p9k_async_pump_fifo="$(mktemp -u ${TMPDIR:-/tmp}/p9k-$$-async-pump-fifo.XXXXXXXXXX)" + _p9k_async_pump_lock=${TMPDIR:-/tmp}/p9k-$$-async-pump-lock.$EPOCHREALTIME.$RANDOM + _p9k_async_pump_fifo=${TMPDIR:-/tmp}/p9k-$$-async-pump-fifo.$EPOCHREALTIME.$RANDOM + echo -n >$_p9k_async_pump_lock mkfifo $_p9k_async_pump_fifo sysopen -rw -o cloexec,sync -u _p9k_async_pump_fd $_p9k_async_pump_fifo zle -F $_p9k_async_pump_fd _p9k_on_async_message @@ -3447,16 +3734,17 @@ _p9k_init_async_pump() { cmd="$setsid zsh -dfxc ${(q)cmd} &!" zsh -dfmxc $cmd </dev/null >&$_p9k_async_pump_fd 2>/dev/null &! - read -t 5 -r -u $_p9k_async_pump_fd _p9k_async_pump_pid && (( _p9k_async_pump_pid )) + IFS='' read -t 5 -r -u $_p9k_async_pump_fd _p9k_async_pump_pid && (( _p9k_async_pump_pid )) _p9k_async_pump_subshell=$ZSH_SUBSHELL + _p9k_async_pump_shell_pid=$$ add-zsh-hook zshexit _p9k_kill_async_pump } if ! _p9k_start_async_pump ; then - >&2 print -P "%F{red}[ERROR]%f Powerlevel10k failed to start async worker. The following segments may malfunction: " - (( public_ip )) && >&2 print -P " - %F{green}public_ip%f" - (( time_realtime )) && >&2 print -P " - %F{green}time%f" + >&2 print -rP -- "%F{red}[ERROR]%f Powerlevel10k failed to start async worker. The following segments may malfunction: " + (( public_ip )) && >&2 print -rP -- " - %F{green}public_ip%f" + (( time_realtime )) && >&2 print -rP -- " - %F{green}time%f" _p9k_deinit_async_pump fi } @@ -3478,15 +3766,21 @@ function _p9k_prompt_overflow_bug() { } _p9k_init_vars() { + typeset -gi _p9k_dump_scheduled + typeset -gi _p9k_dump_pid + typeset -gi _p9k_prompt_idx + typeset -gi _p9k_state_restored typeset -gi _p9k_reset_on_line_finish typeset -gF _p9k_timer_start - typeset -gF _p9k_timer_end typeset -gi _p9k_status typeset -ga _p9k_pipestatus typeset -g _p9k_param_sig typeset -g _p9k_ret typeset -g _p9k_cache_key typeset -ga _p9k_cache_val + typeset -g _p9k_cache_stat_meta + typeset -g _p9k_cache_stat_fprint + typeset -g _p9k_cache_fprint_key typeset -gA _p9k_cache typeset -ga _p9k_t typeset -g _p9k_n @@ -3496,10 +3790,11 @@ _p9k_init_vars() { typeset -ga _p9k_right_join typeset -g _p9k_public_ip typeset -g _p9k_todo_file - # git workdir => the last prompt we've shown for it - typeset -gA _p9k_last_git_prompt # git workdir => 1 if gitstatus is slow on it, 0 if it's fast. typeset -gA _p9k_git_slow + # git workdir => the last state we've seen for it + typeset -gA _p9k_gitstatus_last + typeset -gi _p9k_gitstatus_disabled typeset -gF _p9k_gitstatus_start_time typeset -g _p9k_prompt typeset -g _p9k_rprompt @@ -3516,6 +3811,7 @@ _p9k_init_vars() { typeset -gi _p9k_async_pump_fd typeset -gi _p9k_async_pump_pid typeset -gi _p9k_async_pump_subshell + typeset -gi _p9k_async_pump_shell_pid typeset -ga _p9k_line_segments_left typeset -ga _p9k_line_segments_right typeset -ga _p9k_line_prefix_left @@ -3534,6 +3830,7 @@ _p9k_init_vars() { typeset -gi _p9k_g typeset -gi _p9k_ind typeset -g _p9k_gap_pre + typeset -g _p9k_prompt_newline typeset -g _p9k_prompt_prefix_left typeset -g _p9k_prompt_prefix_right typeset -g _p9k_prompt_suffix_left @@ -3553,8 +3850,16 @@ _p9k_init_vars() { typeset -g _p9k_w typeset -gi _p9k_dir_len typeset -gi _p9k_num_cpus + typeset -g _p9k_pwd + typeset -g _p9k_pwd_a + typeset -gA _p9k_iface + typeset -gi _p9k_fetch_iface + typeset -g _p9k_keymap + typeset -g _p9k_zle_state + typeset -g _p9k_uname + typeset -g _p9k_uname_o + typeset -g _p9k_uname_m - typeset -gF P9K_COMMAND_DURATION_SECONDS typeset -g P9K_VISUAL_IDENTIFIER typeset -g P9K_CONTENT typeset -g P9K_GAP @@ -3575,7 +3880,8 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_VCS_SHORTEN_LENGTH _p9k_declare -i POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH _p9k_declare -s POWERLEVEL9K_VCS_SHORTEN_STRATEGY - _p9k_declare -s POWERLEVEL9K_VCS_SHORTEN_DELIMITER + _p9k_declare -e POWERLEVEL9K_VCS_SHORTEN_DELIMITER '\u2026' + _p9k_declare -b POWERLEVEL9K_VCS_CONFLICTED_STATE 0 _p9k_declare -b POWERLEVEL9K_HIDE_BRANCH_ICON 0 _p9k_declare -b POWERLEVEL9K_VCS_HIDE_TAGS 0 _p9k_declare -i POWERLEVEL9K_CHANGESET_HASH_LENGTH 8 @@ -3594,10 +3900,12 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_BATTERY_LOW_THRESHOLD 10 _p9k_declare -i POWERLEVEL9K_BATTERY_HIDE_ABOVE_THRESHOLD 999 _p9k_declare -a POWERLEVEL9K_BATTERY_LEVEL_BACKGROUND -- + _p9k_declare -a POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND -- _p9k_declare -b POWERLEVEL9K_BATTERY_VERBOSE 1 if [[ $parameters[POWERLEVEL9K_BATTERY_STAGES] == scalar ]]; then _p9k_declare -e POWERLEVEL9K_BATTERY_STAGES else + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_declare -a POWERLEVEL9K_BATTERY_STAGES -- _POWERLEVEL9K_BATTERY_STAGES=("${(@g::)_POWERLEVEL9K_BATTERY_STAGES}") fi @@ -3618,7 +3926,7 @@ _p9k_init_params() { _p9k_declare -e POWERLEVEL9K_DIR_PATH_SEPARATOR "/" _p9k_declare -e POWERLEVEL9K_HOME_FOLDER_ABBREVIATION "~" _p9k_declare -b POWERLEVEL9K_DIR_PATH_HIGHLIGHT_BOLD 0 - _p9k_declare -b POWERLEVEL9K_DIR_ANCHORS_BOLD 0 + _p9k_declare -b POWERLEVEL9K_DIR_ANCHOR_BOLD 0 _p9k_declare -b POWERLEVEL9K_DIR_PATH_ABSOLUTE 0 _p9k_declare -b POWERLEVEL9K_DIR_SHOW_WRITABLE 0 _p9k_declare -b POWERLEVEL9K_DIR_OMIT_FIRST_CHARACTER 0 @@ -3628,7 +3936,24 @@ _p9k_init_params() { _p9k_declare -s POWERLEVEL9K_DIR_PATH_HIGHLIGHT_FOREGROUND _p9k_declare -s POWERLEVEL9K_DIR_ANCHOR_FOREGROUND _p9k_declare -s POWERLEVEL9K_DIR_SHORTENED_FOREGROUND - _p9k_declare -s POWERLEVEL9K_SHORTEN_FOLDER_MARKER "(.shorten_folder_marker|.bzr|CVS|.git|.hg|.svn|.terraform|.citc)" + local markers=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .ruby-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + ) + _p9k_declare -s POWERLEVEL9K_SHORTEN_FOLDER_MARKER "(${(j:|:)markers})" # Shorten directory if it's longer than this even if there is space for it. # The value can be either absolute (e.g., '80') or a percentage of terminal # width (e.g, '50%'). If empty, directory will be shortened only when prompt @@ -3678,12 +4003,17 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_SHORTEN_DELIMITER_LENGTH _p9k_declare -e POWERLEVEL9K_SHORTEN_DELIMITER _p9k_declare -i POWERLEVEL9K_SHORTEN_DIR_LENGTH - _p9k_declare -s POWERLEVEL9K_IP_INTERFACE "^[^ ]+" - _p9k_declare -s POWERLEVEL9K_VPN_IP_INTERFACE "tun" + _p9k_declare -s POWERLEVEL9K_IP_INTERFACE "" + _p9k_declare -s POWERLEVEL9K_VPN_IP_INTERFACE "(wg|(.*tun))[0-9]*" _p9k_declare -i POWERLEVEL9K_LOAD_WHICH 5 _p9k_declare -b POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW 0 _p9k_declare -b POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY 0 + _p9k_declare -b POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY 1 + _p9k_declare -b POWERLEVEL9K_GO_VERSION_PROJECT_ONLY 1 + _p9k_declare -b POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY 1 _p9k_declare -b POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -b POWERLEVEL9K_RVM_SHOW_GEMSET 0 + _p9k_declare -b POWERLEVEL9K_RVM_SHOW_PREFIX 0 _p9k_declare -b POWERLEVEL9K_CHRUBY_SHOW_VERSION 1 _p9k_declare -b POWERLEVEL9K_CHRUBY_SHOW_ENGINE 1 _p9k_declare -b POWERLEVEL9K_STATUS_CROSS 0 @@ -3722,6 +4052,7 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_VCS_STAGED_MAX_NUM 1 _p9k_declare -i POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM 1 _p9k_declare -i POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM 1 + _p9k_declare -i POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM 1 _p9k_declare -i POWERLEVEL9K_VCS_COMMITS_AHEAD_MAX_NUM -1 _p9k_declare -i POWERLEVEL9K_VCS_COMMITS_BEHIND_MAX_NUM -1 _p9k_declare -b POWERLEVEL9K_DISABLE_GITSTATUS 0 @@ -3729,6 +4060,8 @@ _p9k_init_params() { _p9k_declare -e POWERLEVEL9K_VI_COMMAND_MODE_STRING "NORMAL" # VISUAL mode is shown as NORMAL unless POWERLEVEL9K_VI_VISUAL_MODE_STRING is explicitly set. _p9k_declare -e POWERLEVEL9K_VI_VISUAL_MODE_STRING + # OVERWRITE mode is shown as INSERT unless POWERLEVEL9K_VI_OVERWRITE_MODE_STRING is explicitly set. + _p9k_declare -e POWERLEVEL9K_VI_OVERWRITE_MODE_STRING _p9k_declare -b POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION 1 _p9k_declare -e POWERLEVEL9K_VIRTUALENV_LEFT_DELIMITER "(" _p9k_declare -e POWERLEVEL9K_VIRTUALENV_RIGHT_DELIMITER ")" @@ -3769,6 +4102,31 @@ _p9k_init_params() { # # These correspond to `java -fullversion` and `java -version` respectively. _p9k_declare -b POWERLEVEL9K_JAVA_VERSION_FULL 1 + _p9k_declare -b POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE 0 + + local -i i=1 + while (( i <= $#_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS )); do + local segment=${(U)_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[i]} + local var=POWERLEVEL9K_${segment}_LEFT_DISABLED + (( $+parameters[$var] )) || var=POWERLEVEL9K_${segment}_DISABLED + if [[ ${(P)var} == true ]]; then + _POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[i,i]=() + else + (( ++i )) + fi + done + + local -i i=1 + while (( i <= $#_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS )); do + local segment=${(U)_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[i]} + local var=POWERLEVEL9K_${segment}_RIGHT_DISABLED + (( $+parameters[$var] )) || var=POWERLEVEL9K_${segment}_DISABLED + if [[ ${(P)var} == true ]]; then + _POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[i,i]=() + else + (( ++i )) + fi + done } typeset -ga __p9k_wrapped_zle_widgets @@ -3792,7 +4150,9 @@ _p9k_wrap_zle_widget() { local wrapper=_p9k_wrapper_$widget_$hook eval "function ${(q)wrapper}() { - ${(q)hook} \"\$@\" + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + (( __p9k_enabled )) && ${(q)hook} \"\$@\" (( \$+widgets[${(q)orig}] )) && zle ${(q)orig} -- \"\$@\" }" @@ -3800,18 +4160,18 @@ _p9k_wrap_zle_widget() { } function _p9k_zle_line_finish() { - (( __p9k_enabled )) || return _p9k_line_finished= - (( _p9k_reset_on_line_finish )) && zle && zle .reset-prompt && zle -R + if (( _p9k_reset_on_line_finish )); then + _p9k_reset_prompt + fi } function _p9k_zle_line_pre_redraw() { - (( __p9k_enabled )) || return [[ ${KEYMAP:-} == vicmd ]] || return 0 local region=${${REGION_ACTIVE:-0}/2/1} [[ $region != $_p9k_region_active ]] || return 0 _p9k_region_active=$region - zle && zle .reset-prompt && zle -R + _p9k_reset_prompt } prompt__p9k_internal_nothing() { @@ -3824,8 +4184,8 @@ _p9k_build_gap_post() { local char=${_p9k_ret:- } _p9k_prompt_length $char if (( _p9k_ret != 1 || $#char != 1 )); then - print -P "%F{red}WARNING!%f %BMULTILINE_${(U)1}_PROMPT_GAP_CHAR%b is not one character long. Will use ' '." - print -P "Either change the value of %BPOWERLEVEL9K_MULTILINE_${(U)1}_PROMPT_GAP_CHAR%b or remove it." + print -rP -- "%F{red}WARNING!%f %BMULTILINE_${(U)1}_PROMPT_GAP_CHAR%b is not one character long. Will use ' '." + print -rP -- "Either change the value of %BPOWERLEVEL9K_MULTILINE_${(U)1}_PROMPT_GAP_CHAR%b or remove it." char=' ' fi local style @@ -3846,11 +4206,16 @@ _p9k_build_gap_post() { _p9k_ret+='${:-"'$exp'"}' style=1 fi - _p9k_ret+=$'$_p9k_rprompt$_p9k_t[$((1+!_p9k_ind))]}:-\n}' + if (( __p9k_ksh_arrays )); then + _p9k_ret+=$'$_p9k_rprompt${_p9k_t[$((!_p9k_ind))]}}:-\n}' + else + _p9k_ret+=$'$_p9k_rprompt${_p9k_t[$((1+!_p9k_ind))]}}:-\n}' + fi [[ -n $style ]] && _p9k_ret+='%b%k%f' } _p9k_init_lines() { + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale local -a left_segments=($_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS) local -a right_segments=($_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS) @@ -3963,6 +4328,13 @@ _p9k_init_lines() { fi } +_p9k_all_params_eq() { + local key + for key in ${parameters[(I)${~1}]}; do + [[ ${(P)key} == $2 ]] || return + done +} + _p9k_init_prompt() { _p9k_init_lines @@ -3981,15 +4353,24 @@ _p9k_init_prompt() { _p9k_prompt_suffix_left='${${COLUMNS::=$_p9k_clm}+}' _p9k_prompt_suffix_right='${${COLUMNS::=$_p9k_clm}+}' + if _p9k_segment_in_use vi_mode || _p9k_segment_in_use prompt_char; then + _p9k_prompt_prefix_left+='${${_p9k_keymap::=${KEYMAP:-$_p9k_keymap}}+}' + fi + if { _p9k_segment_in_use vi_mode && (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )) } || + { _p9k_segment_in_use prompt_char && (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )) }; then + _p9k_prompt_prefix_left+='${${_p9k_zle_state::=${ZLE_STATE:-$_p9k_zle_state}}+}' + fi _p9k_prompt_prefix_left+='%b%k%f' # Bug fixed in: https://github.com/zsh-users/zsh/commit/3eea35d0853bddae13fa6f122669935a01618bf9. # If affects most terminals when RPROMPT is non-empty and ZLE_RPROMPT_INDENT is zero. # We can work around it as long as RPROMPT ends with a space. if [[ -n $_p9k_line_segments_right[-1] && $_p9k_line_never_empty_right[-1] == 0 && - $ZLE_RPROMPT_INDENT == 0 && ${POWERLEVEL9K_WHITESPACE_BETWEEN_RIGHT_SEGMENTS:- } == ' ' && - -z "$(typeset -m 'POWERLEVEL9K_*(RIGHT_RIGHT_WHITESPACE|RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL)')" ]] && - ! is-at-least 5.7.2; then + $ZLE_RPROMPT_INDENT == 0 ]] && + _p9k_all_params_eq 'POWERLEVEL9K_*WHITESPACE_BETWEEN_RIGHT_SEGMENTS' ' ' && + _p9k_all_params_eq 'POWERLEVEL9K_*RIGHT_RIGHT_WHITESPACE' ' ' && + _p9k_all_params_eq 'POWERLEVEL9K_*RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL' '' && + ! is-at-least 5.7.2; then _p9k_emulate_zero_rprompt_indent=1 _p9k_prompt_prefix_left+='${${:-${_p9k_real_zle_rprompt_indent:=$ZLE_RPROMPT_INDENT}${ZLE_RPROMPT_INDENT::=1}${_p9k_ind::=0}}+}' _p9k_line_suffix_right[-1]='${_p9k_sss:+${_p9k_sss% }%E}' @@ -3999,7 +4380,7 @@ _p9k_init_prompt() { fi if (( _POWERLEVEL9K_PROMPT_ADD_NEWLINE )); then - repeat $_POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT _p9k_prompt_prefix_left+=$'\n' + repeat $_POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT _p9k_prompt_newline+=$'\n' fi _p9k_t=($'\n' '') @@ -4019,11 +4400,15 @@ _p9k_init_prompt() { [[ $ruler_char == '.' ]] && local sep=',' || local sep='.' local ruler_len='${$((_p9k_clm-_p9k_ind))/#-*/0}' _p9k_prompt_prefix_left+="\${(pl$sep$ruler_len$sep$sep${(q)ruler_char}$sep)}%k%f" - _p9k_prompt_prefix_left+='$_p9k_t[$((1+!_p9k_ind))]' + if (( __p9k_ksh_arrays )); then + _p9k_prompt_prefix_left+='${_p9k_t[$((!_p9k_ind))]}' + else + _p9k_prompt_prefix_left+='${_p9k_t[$((1+!_p9k_ind))]}' + fi else - print -P "%F{red}WARNING!%f %BPOWERLEVEL9K_RULER_CHAR%b is not one character long. Ruler won't be rendered." - print -P "Either change the value of %BPOWERLEVEL9K_RULER_CHAR%b or set %BPOWERLEVEL9K_SHOW_RULER=false%b to" - print -P "disable ruler." + print -rP -- "%F{red}WARNING!%f %BPOWERLEVEL9K_RULER_CHAR%b is not one character long. Ruler won't be rendered." + print -rP -- "Either change the value of %BPOWERLEVEL9K_RULER_CHAR%b or set %BPOWERLEVEL9K_SHOW_RULER=false%b to" + print -rP -- "disable ruler." fi fi @@ -4034,10 +4419,6 @@ _p9k_init_prompt() { [[ -o transient_rprompt && -n "$_p9k_line_segments_right[1,-2]" ]] || ( _p9k_segment_in_use time && (( _POWERLEVEL9K_TIME_UPDATE_ON_COMMAND )) ) _p9k_reset_on_line_finish=$((!$?)) - - if (( _p9k_reset_on_line_finish )) || _p9k_segment_in_use status; then - _p9k_wrap_zle_widget zle-line-finish _p9k_zle_line_finish - fi } _p9k_init_ssh() { @@ -4046,38 +4427,42 @@ _p9k_init_ssh() { # # License: https://github.com/sindresorhus/pure/blob/e8abf9d37185ec9b7b4398ca9c5eba555a1028eb/license. - [[ -n $_P9K_SSH ]] && return - export _P9K_SSH=0 + [[ -n $P9K_SSH ]] && return + typeset -gix P9K_SSH=0 if [[ -n $SSH_CLIENT || -n $SSH_TTY || -n $SSH_CONNECTION ]]; then - _P9K_SSH=1 + P9K_SSH=1 return fi # When changing user on a remote system, the $SSH_CONNECTION environment variable can be lost. # Attempt detection via `who`. (( $+commands[who] )) || return - local w && w="$(who -m 2>/dev/null)" || w=${(@M)${(f)"$(who 2>/dev/null)"}:#*[[:space:]]${TTY#/dev/}[[:space:]]*} local ipv6='(([0-9a-fA-F]+:)|:){2,}[0-9a-fA-F]+' # Simplified, only checks partial pattern. local ipv4='([0-9]{1,3}\.){3}[0-9]+' # Simplified, allows invalid ranges. # Assume two non-consecutive periods represents a hostname. Matches `x.y.z`, but not `x.y`. local hostname='([.][^. ]+){2}' + local w + w="$(who -m 2>/dev/null)" || w=${(@M)${(f)"$(who 2>/dev/null)"}:#*[[:space:]]${TTY#/dev/}[[:space:]]*} + # Usually the remote address is surrounded by parenthesis but not on all systems (e.g., Busybox). - [[ $w =~ "\(?($ipv4|$ipv6|$hostname)\)?\$" ]] && _P9K_SSH=1 + [[ $w =~ "\(?($ipv4|$ipv6|$hostname)\)?\$" ]] && P9K_SSH=1 } _p9k_must_init() { - emulate -L zsh && setopt no_hist_expand extended_glob - local -a param_keys=( - ${(o)parameters[(I)(POWERLEVEL9K_*|GITSTATUS_LOG_LEVEL|GITSTATUS_ENABLE_LOGGING|GITSTATUS_DAEMON|GITSTATUS_NUM_THREADS|DEFAULT_USER|ZLE_RPROMPT_INDENT)]}) + local -a param_keys=(${(o)parameters[(I)POWERLEVEL9K_*]}) local IFS param_sig IFS=$'\1' param_sig="${(@)param_keys:/(#b)(*)/$match[1]=\$$match[1]}" - IFS=$'\2' eval "param_sig=x\"$param_sig\"" - [[ -o transient_rprompt ]] && param_sig+=t + param_sig+=( + '${ZSH_VERSION}' '${ZSH_PATCHLEVEL}' '${(%):-%n}' '${GITSTATUS_LOG_LEVEL}' + '${GITSTATUS_ENABLE_LOGGING}' '${GITSTATUS_DAEMON}' '${GITSTATUS_NUM_THREADS}' + '${DEFAULT_USER}' '${ZLE_RPROMPT_INDENT}' '${P9K_SSH}' '${__p9k_ksh_arrays}' + '${__p9k_sh_glob}' '${parameters[transient_rprompt]}' 'v8') + IFS=$'\2' param_sig="${(e)param_sig}" [[ $param_sig == $_p9k_param_sig ]] && return 1 [[ -n $_p9k_param_sig ]] && _p9k_deinit - _p9k_param_sig=$param_sig + typeset -g _p9k_param_sig=$param_sig } function _p9k_set_os() { @@ -4086,20 +4471,23 @@ function _p9k_set_os() { _p9k_os_icon=$_p9k_ret } -_p9k_init() { - emulate -L zsh && setopt no_hist_expand extended_glob - +function _p9k_init_cacheable() { + (( $+functions[_p9k_init_icons] )) || { + setopt no_aliases + source "${__p9k_root_dir}/internal/icons.zsh" + } _p9k_init_icons - _p9k_init_vars _p9k_init_params _p9k_init_prompt - _p9k_init_ssh - local uname="$(uname)" - if [[ $uname == Linux && "$(uname -o 2>/dev/null)" == Android ]]; then + _p9k_uname="$(uname)" + [[ $_p9k_uname == Linux ]] && _p9k_uname_o="$(uname -o 2>/dev/null)" + _p9k_uname_m="$(uname -m)" + + if [[ $_p9k_uname == Linux && _p9k_uname_o == Android ]]; then _p9k_set_os Android ANDROID_ICON else - case $uname in + case $_p9k_uname in SunOS) _p9k_set_os Solaris SUNOS_ICON;; Darwin) _p9k_set_os OSX APPLE_ICON;; CYGWIN_NT-* | MSYS_NT-*) _p9k_set_os Windows WINDOWS_ICON;; @@ -4107,9 +4495,12 @@ _p9k_init() { Linux) _p9k_os='Linux' local os_release_id - [[ -f /etc/os-release && - "${(f)$((</etc/os-release) 2>/dev/null)}" =~ "ID=([A-Za-z]+)" ]] && os_release_id="${match[1]}" - case "$os_release_id" in + if [[ -r /etc/os-release ]]; then + local lines=(${(f)"$(</etc/os-release)"}) + lines=(${(@M)lines:#ID=*}) + (( $#lines == 1 )) && os_release_id=${lines[1]#ID=} + fi + case $os_release_id in *arch*) _p9k_set_os Linux LINUX_ARCH_ICON;; *debian*) _p9k_set_os Linux LINUX_DEBIAN_ICON;; *raspbian*) _p9k_set_os Linux LINUX_RASPBIAN_ICON;; @@ -4178,46 +4569,138 @@ _p9k_init() { fi done - if [[ -n $POWERLEVEL9K_RIGHT_SEGMENT_END_SEPARATOR ]]; then - print -P "%F{yellow}WARNING!%f %F{red}POWERLEVEL9K_RIGHT_SEGMENT_END_SEPARATOR%f is no longer supported!" - print -P "" - print -P "To fix your prompt, replace %F{red}POWERLEVEL9K_RIGHT_SEGMENT_END_SEPARATOR%f with" - print -P "%F{green}POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL%f." - print -P "" - print -P " %F{red} - POWERLEVEL9K_RIGHT_SEGMENT_END_SEPARATOR=${(qqq)${POWERLEVEL9K_RIGHT_SEGMENT_END_SEPARATOR//\%/%%}}%f" - print -P " %F{green} + POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL=${(qqq)${POWERLEVEL9K_RIGHT_SEGMENT_END_SEPARATOR//\%/%%}}%f" - if [[ -n $POWERLEVEL9K_LEFT_SEGMENT_END_SEPARATOR ]]; then - print -P "" - print -P "While at it, also replace %F{red}POWERLEVEL9K_LEFT_SEGMENT_END_SEPARATOR%f with" - print -P "%F{green}POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL%f. The new option, unlike" - print -P "the old, works correctly in multiline prompts." - print -P "" - print -P " %F{red} - POWERLEVEL9K_LEFT_SEGMENT_END_SEPARATOR=${(qqq)${POWERLEVEL9K_LEFT_SEGMENT_END_SEPARATOR//\%/%%}}%f" - print -P " %F{green} + POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=${(qqq)${POWERLEVEL9K_LEFT_SEGMENT_END_SEPARATOR//\%/%%}}%f" + case $_p9k_os in + OSX) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.logicalcpu 2>/dev/null)";; + BSD) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.ncpu 2>/dev/null)";; + *) (( $+commands[nproc] )) && _p9k_num_cpus="$(nproc 2>/dev/null)";; + esac + + if _p9k_segment_in_use dir; then + if (( $+_POWERLEVEL9K_DIR_CLASSES )); then + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale + local -i i=3 + for ((; i <= $#_POWERLEVEL9K_DIR_CLASSES; i+=3)); do + _POWERLEVEL9K_DIR_CLASSES[i]=${(g::)_POWERLEVEL9K_DIR_CLASSES[i]} + done + else + typeset -ga _POWERLEVEL9K_DIR_CLASSES=() + _p9k_get_icon prompt_dir_ETC ETC_ICON + _POWERLEVEL9K_DIR_CLASSES+=('/etc|/etc/*' ETC "$_p9k_ret") + _p9k_get_icon prompt_dir_HOME HOME_ICON + _POWERLEVEL9K_DIR_CLASSES+=('~' HOME "$_p9k_ret") + _p9k_get_icon prompt_dir_HOME_SUBFOLDER HOME_SUB_ICON + _POWERLEVEL9K_DIR_CLASSES+=('~/*' HOME_SUBFOLDER "$_p9k_ret") + _p9k_get_icon prompt_dir_DEFAULT FOLDER_ICON + _POWERLEVEL9K_DIR_CLASSES+=('*' DEFAULT "$_p9k_ret") fi - print -P "" - print -P "To get rid of this warning without changing the appearance of your prompt," - print -P "remove %F{red}POWERLEVEL9K_RIGHT_SEGMENT_END_SEPARATOR%f from your config" - fi - - if _p9k_segment_in_use longstatus; then - print -P '%F{yellow}WARNING!%f The "longstatus" segment is deprecated. Use "%F{blue}status%f" instead.' - print -P 'For more informations, have a look at https://github.com/bhilburn/powerlevel9k/blob/master/CHANGELOG.md.' - fi - - if _p9k_segment_in_use vcs; then - _p9k_vcs_info_init - if [[ $_POWERLEVEL9K_DISABLE_GITSTATUS == 0 && -n $_POWERLEVEL9K_VCS_BACKENDS[(r)git] ]]; then - source ${_POWERLEVEL9K_GITSTATUS_DIR:-${__p9k_root_dir}/gitstatus}/gitstatus.plugin.zsh - gitstatus_start \ - -s $_POWERLEVEL9K_VCS_STAGED_MAX_NUM \ - -u $_POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM \ - -d $_POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM \ - -m $_POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY \ - POWERLEVEL9K + fi + + if _p9k_segment_in_use status; then + typeset -g _p9k_exitcode2str=({0..255}) + local -i i=2 + if (( !_POWERLEVEL9K_STATUS_HIDE_SIGNAME )); then + for ((; i <= $#signals; ++i)); do + local sig=$signals[i] + (( _POWERLEVEL9K_STATUS_VERBOSE_SIGNAME )) && sig="SIG${sig}($((i-1)))" + _p9k_exitcode2str[$((128+i))]=$sig + done fi fi + if [[ -n $_POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE ]] && _p9k_segment_in_use public_ip || + _p9k_segment_in_use ip || _p9k_segment_in_use vpn_ip; then + _p9k_fetch_iface=1 + fi +} + +_p9k_init_vcs() { + _p9k_segment_in_use vcs || return + _p9k_vcs_info_init + if (( $+functions[_p9k_preinit] )); then + (( $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )) && gitstatus_start POWERLEVEL9K || _p9k_gitstatus_disabled=1 + return + fi + if (( _POWERLEVEL9K_DISABLE_GITSTATUS )); then + _p9k_gitstatus_disabled=1 + return + fi + (( $_POWERLEVEL9K_VCS_BACKENDS[(I)git] )) || return + + local gitstatus_dir=${_POWERLEVEL9K_GITSTATUS_DIR:-${__p9k_root_dir}/gitstatus} + if [[ -z $GITSTATUS_DAEMON && $_p9k_uname == i686 && -z $gitstatus_dir/bin/*-i686(-static|)(#qN) ]]; then + _p9k_gitstatus_disabled=1 + >&2 echo -E - "${(%):-[%1FERROR%f]: %BPowerlevel10k%b is unable to use %Bgitstatus%b. Git prompt will be slow.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):-Reason: There is no %Bgitstatusd%b binary for i686 (32-bit Intel architecture).}" + >&2 echo -E - "" + >&2 echo -E - "${(%):-You can:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Do nothing.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill%b see this error message every time you start zsh.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bslow%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Set %BPOWERLEVEL9K_DISABLE_GITSTATUS=true%b at the bottom of %B$__p9k_zshrc_u%b.}" + >&2 echo -E - "${(%):- You can do this by running the following command:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- %2Fecho%f %3F'POWERLEVEL9K_DISABLE_GITSTATUS=true'%f >>! $__p9k_zshrc_u}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bslow%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Upgrade to a 64-bit OS.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bfast%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Compile %Bgitstatusd%b and set %BGITSTATUS_DAEMON=/path/to/gitstatusd%b at}" + >&2 echo -E - "${(%):- the bottom of %B$__p9k_zshrc_u%b. See instructions at}" + >&2 echo -E - "${(%):- https://github.com/romkatv/gitstatus/blob/master/README.md#compiling.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bfast%b.}" + return + fi + + local daemon=${GITSTATUS_DAEMON} + if [[ -z $daemon ]]; then + daemon=$gitstatus_dir/bin/gitstatusd- + [[ $_p9k_uname_o == Android ]] && daemon+=android || daemon+=${_p9k_uname:l} + daemon+=-${_p9k_uname_m:l} + fi + local -i threads=${GITSTATUS_NUM_THREADS:-0} + if (( threads <= 0 )); then + threads=$(( _p9k_num_cpus * 2 )) + (( threads > 0 )) || threads=8 + (( threads <= 32 )) || threads=32 + fi + typeset -g _p9k_preinit="function _p9k_preinit() { + [[ -r ${(q)gitstatus_dir}/gitstatus.plugin.zsh ]] || return + source ${(q)gitstatus_dir}/gitstatus.plugin.zsh || return + GITSTATUS_DAEMON=${(q)daemon} GITSTATUS_NUM_THREADS=$threads \ + GITSTATUS_LOG_LEVEL=${(q)GITSTATUS_LOG_LEVEL} \ + GITSTATUS_ENABLE_LOGGING=${(q)GITSTATUS_ENABLE_LOGGING} gitstatus_start \ + -s $_POWERLEVEL9K_VCS_STAGED_MAX_NUM \ + -u $_POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM \ + -d $_POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM \ + -c $_POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM \ + -m $_POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY \ + -a POWERLEVEL9K + }" + source ${gitstatus_dir}/gitstatus.plugin.zsh + GITSTATUS_DAEMON=$daemon GITSTATUS_NUM_THREADS=$threads gitstatus_start \ + -s $_POWERLEVEL9K_VCS_STAGED_MAX_NUM \ + -u $_POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM \ + -d $_POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM \ + -c $_POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM \ + -m $_POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY \ + POWERLEVEL9K || _p9k_gitstatus_disabled=1 +} + +_p9k_init() { + _p9k_init_vars + _p9k_restore_state || _p9k_init_cacheable + if _p9k_segment_in_use todo; then local todo=$commands[todo.sh] if [[ -n $todo ]]; then @@ -4235,82 +4718,47 @@ _p9k_init() { fi fi - if _p9k_segment_in_use load; then - case $_p9k_os in - OSX) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.logicalcpu 2>/dev/null)";; - BSD) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.ncpu 2>/dev/null)";; - *) (( $+commands[nproc] )) && _p9k_num_cpus="$(nproc 2>/dev/null)";; - esac + if (( _p9k_reset_on_line_finish )) || _p9k_segment_in_use status; then + _p9k_wrap_zle_widget zle-line-finish _p9k_zle_line_finish fi - if _p9k_segment_in_use dir; then - if (( $+_POWERLEVEL9K_DIR_CLASSES )); then - local -i i=3 - for ((; i <= $#_POWERLEVEL9K_DIR_CLASSES; i+=3)); do - _POWERLEVEL9K_DIR_CLASSES[i]=${(g::)_POWERLEVEL9K_DIR_CLASSES[i]} - done - else - typeset -ga _POWERLEVEL9K_DIR_CLASSES=() - _p9k_get_icon prompt_dir_ETC ETC_ICON - _POWERLEVEL9K_DIR_CLASSES+=('/etc|/etc/*' ETC "$_p9k_ret") - _p9k_get_icon prompt_dir_HOME HOME_ICON - _POWERLEVEL9K_DIR_CLASSES+=('~' HOME "$_p9k_ret") - _p9k_get_icon prompt_dir_HOME_SUBFOLDER HOME_SUB_ICON - _POWERLEVEL9K_DIR_CLASSES+=('~/*' HOME_SUBFOLDER "$_p9k_ret") - _p9k_get_icon prompt_dir_DEFAULT FOLDER_ICON - _POWERLEVEL9K_DIR_CLASSES+=('*' DEFAULT "$_p9k_ret") - fi + if _p9k_segment_in_use vi_mode || _p9k_segment_in_use prompt_char; then + _p9k_wrap_zle_widget zle-keymap-select _p9k_zle_keymap_select fi - _p9k_init_async_pump - if _p9k_segment_in_use vi_mode && (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )) || _p9k_segment_in_use prompt_char; then _p9k_wrap_zle_widget zle-line-pre-redraw _p9k_zle_line_pre_redraw fi - if _p9k_segment_in_use dir && - [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && $+commands[jq] == 0 ]]; then - >&2 print -P '%F{yellow}WARNING!%f %BPOWERLEVEL9K_SHORTEN_STRATEGY=truncate_with_package_name%b requires %F{green}jq%f.' - >&2 print -P 'Either install %F{green}jq%f or change the value of %BPOWERLEVEL9K_SHORTEN_STRATEGY%b.' + if { _p9k_segment_in_use vi_mode && (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )) } || + { _p9k_segment_in_use prompt_char && (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )) }; then + _p9k_wrap_zle_widget overwrite-mode _p9k_zle_state_changed + _p9k_wrap_zle_widget vi-replace _p9k_zle_state_changed fi - if (( !$+__p9k_char2byte )) && _p9k_segment_in_use nordvpn; then - typeset -gA __p9k_char2byte=() - local -i x=0 y=0 - for x in {0..7}; do - for y in {0..7}; do - __p9k_char2byte[${(q+)${(g:o:):-\\$x$y}}]=$((8*x+y)) - done - done - typeset -grA __p9k_char2byte - fi - - if _p9k_segment_in_use status; then - typeset -g _p9k_exitcode2str=({0..255}) - local -i i=2 - if (( !_POWERLEVEL9K_STATUS_HIDE_SIGNAME )); then - for ((; i <= $#signals; ++i)); do - local sig=$signals[i] - (( _POWERLEVEL9K_STATUS_VERBOSE_SIGNAME )) && sig="SIG${sig}($((i-1)))" - _p9k_exitcode2str[$((128+i))]=$sig - done - fi + if _p9k_segment_in_use dir && + [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && $+commands[jq] == 0 ]]; then + print -rP -- '%F{yellow}WARNING!%f %BPOWERLEVEL9K_SHORTEN_STRATEGY=truncate_with_package_name%b requires %F{green}jq%f.' + print -rP -- 'Either install %F{green}jq%f or change the value of %BPOWERLEVEL9K_SHORTEN_STRATEGY%b.' fi - _p9k_wrap_zle_widget zle-keymap-select _p9k_zle_keymap_select + _p9k_init_async_pump + _p9k_init_vcs } _p9k_deinit() { (( $+functions[gitstatus_stop] )) && gitstatus_stop POWERLEVEL9K _p9k_deinit_async_pump - unset -m '(_POWERLEVEL9K_|P9K_|_p9k_)*' + (( _p9k_dump_pid )) && wait $_p9k_dump_pid 2>/dev/null + unset -m '(_POWERLEVEL9K_|P9K_|_p9k_)*~P9K_SSH' } typeset -gi __p9k_enabled=0 typeset -gi __p9k_configured=0 prompt_powerlevel9k_setup() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} prompt_powerlevel9k_teardown __p9k_enabled=1 add-zsh-hook preexec _p9k_preexec @@ -4318,7 +4766,8 @@ prompt_powerlevel9k_setup() { } prompt_powerlevel9k_teardown() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} add-zsh-hook -D precmd '(_p9k_|powerlevel9k_)*' add-zsh-hook -D preexec '(_p9k_|powerlevel9k_)*' PROMPT='%m%# ' @@ -4329,13 +4778,175 @@ prompt_powerlevel9k_teardown() { fi } -autoload -Uz colors && colors +typeset -gr __p9k_p10k_usage="Usage: %2Fp10k%f %Bcommand%b [options] + +Commands: + + %Bconfigure%b run interactive configuration wizard + %Bsegment%b print a user-defined prompt segment + %Bhelp%b print this help message" + +typeset -gr __p9k_p10k_segment_usage="Usage: %2Fp10k%f %Bsegment%b [-h] [{+|-}re] [-s state] [-b bg] [-f fg] [-i icon] [-c cond] [-t text] + +Print a user-defined prompt segment. Can be called only during prompt rendering. + +Options: + -t text segment's main content; will undergo prompt expansion: '%%F{blue}%%*%%f' will + show as %F{blue}%*%f; default is empty + -i icon segment's icon; default is empty + -r icon is a symbolic reference that needs to be resolved; for example, 'LOCK_ICON' + +r icon is already resolved and should be printed literally; for example, '⭐'; + this is the default; you can also use \$'\u2B50' if you don't want to have + non-ascii characters in source code + -b bg background color; for example, 'blue', '4', or '#0000ff'; empty value means + transparent background, as in '%%k'; default is black + -f fg foreground color; for example, 'blue', '4', or '#0000ff'; empty value means + default foreground color, as in '%%f'; default is empty + -s state segment's state for the purpose of applying styling options; if you want to + to be able to use POWERLEVEL9K parameters to specify different colors or icons + depending on some property, use different states for different values of that + property + -c condition; if empty after parameter expansion and process substitution, the + segment is hidden; this is an advanced feature, use with caution; default is '1' + -e segment's main content will undergo parameter expansion and process + substitution; the content will be surrounded with double quotes and thus + should quote its own double quotes; this is an advanced feature, use with + caution + +e segment's main content should not undergo parameter expansion and process + substitution; this is the default + -h print this help message + +Example: 'core' segment tells you if there is a file name 'core' in the current directory. + +- Segment's icon is '⭐'. +- Segment's text is the file's size in bytes. +- If you have permissions to delete the file, state is DELETABLE. If not, it's PROTECTED. + + zmodload -F zsh/stat b:zstat + + function prompt_core() { + local size=() + if ! zstat -A size +size core 2>/dev/null; then + # No 'core' file in the current directory. + return + fi + if [[ -w . ]]; then + local state=DELETABLE + else + local state=PROTECTED + fi + p10k segment -s \\\$state -i '⭐' -f blue -t \\\${size[1]}b + } + +To enable this segment, add 'core' to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or +POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. + +Example customizations: + + # Override default foreground. + POWERLEVEL9K_CORE_FOREGROUND=red + + # Override foreground when DELETABLE. + POWERLEVEL9K_CORE_DELETABLE_BACKGROUND=green + + # Override icon when PROTECTED. + POWERLEVEL9K_CORE_PROTECTED_VISUAL_IDENTIFIER_EXPANSION='❎' + + # Don't show file size when PROTECTED. + POWERLEVEL9K_CORE_PROTECTED_CONTENT_EXPANSION=''" + +typeset -gr __p9k_p10k_configure_usage="Usage: %2Fp10k%f %Bconfigure%b + +Run interactive configuration wizard." + +function p10k() { + emulate -L zsh + setopt no_hist_expand extended_glob prompt_percent prompt_subst + + if (( !ARGC )); then + print -rP -- $__p9k_p10k_usage >&2 + return 1 + fi + + case $1 in + segment) + shift + local -i num_opts=ARGC + local opt state bg=0 fg icon cond text ref=0 expand=0 + while getopts ':s:b:f:i:c:t:reh' opt; do + case $opt in + s) state=$OPTARG;; + b) bg=$OPTARG;; + f) fg=$OPTARG;; + i) icon=$OPTARG;; + c) cond=${OPTARG:-'${:-}'};; + t) text=$OPTARG;; + r) ref=1;; + e) expand=1;; + +r) ref=0;; + +e) expand=0;; + h) print -rP -- $__p9k_p10k_segment_usage; return 0;; + ?) print -rP -- $__p9k_p10k_segment_usage >&2; return 1;; + esac + done + if (( OPTIND <= ARGC )); then + print -rP -- $__p9k_p10k_segment_usage >&2 + return 1 + fi + if [[ -z $_p9k_prompt_side ]]; then + print -rP -- "%1F[ERROR]%f %Bp10k segment%b: can be called only during prompt rendering." >&2 + if (( !ARGC )); then + print -rP -- "" + print -rP -- "For help, type:" >&2 + print -rP -- "" + print -rP -- " %2Fp10k%f %Bhelp%b %Bsegment%b" >&2 + fi + return 1 + fi + (( ref )) || icon=$'\1'$icon + "_p9k_${_p9k_prompt_side}_prompt_segment" "prompt_${_p9k_segment_name}${state:+_${(U)state}}" \ + "$bg" "${fg:-$_p9k_color1}" "$icon" "$expand" "$cond" "$text" + return 0 + ;; + configure) + if (( ARGC > 1 )); then + print -rP -- $__p9k_p10k_configure_usage >&2 + return 1 + fi + p9k_configure "$@" + ;; + help) + local var=__p9k_p10k_$2_usage + if (( $+parameters[$var] )); then + print -rP -- ${(P)var} + return 0 + elif (( ARGC == 1 )); then + print -rP -- $__p9k_p10k_usage + return 0 + else + print -rP -- $__p9k_p10k_usage >&2 + return 1 + fi + ;; + *) + print -rP -- $__p9k_p10k_usage >&2 + return 1 + ;; + esac +} + +# Hook for zplugin. +powerlevel10k_plugin_unload() { prompt_powerlevel9k_teardown; } + autoload -Uz add-zsh-hook zmodload zsh/datetime zmodload zsh/mathfunc +zmodload zsh/parameter zmodload zsh/system zmodload -F zsh/stat b:zstat zmodload -F zsh/net/socket b:zsocket +zmodload -F zsh/files b:zf_mv b:zf_rm +_p9k_init_ssh prompt_powerlevel9k_setup diff --git a/internal/wizard.zsh b/internal/wizard.zsh index 7c94934d..77b72b2f 100755 --- a/internal/wizard.zsh +++ b/internal/wizard.zsh @@ -4,7 +4,11 @@ emulate -L zsh setopt noaliases () { -setopt extended_glob no_prompt_{bang,subst} prompt_{cr,percent,sp} +setopt extended_glob no_prompt_{bang,subst} prompt_percent typeset_silent +zmodload zsh/langinfo +if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then + local LC_ALL=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8} +fi typeset -g __p9k_root_dir typeset -gi force=0 @@ -15,7 +19,7 @@ while getopts 'd:f' opt; do d) __p9k_root_dir=$OPTARG;; f) force=1;; +f) force=0;; - '?') return 1;; + \?) return 1;; esac done @@ -31,14 +35,21 @@ typeset -gri force source $__p9k_root_dir/internal/configure.zsh || return +typeset -r font_base_url='https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts' +typeset -ri wizard_columns=$((COLUMNS < 80 ? COLUMNS : 80)) + typeset -i prompt_indent=2 typeset -i rprompt_indent=2 -typeset -ra bg_color=(238 236 234) -typeset -ra frame_color=(242 240 238) -typeset -ra sep_color=(246 244 242) -typeset -ra prefix_color=(248 246 244) +typeset -ra bg_color=(240 238 236 234) +typeset -ra frame_color=(244 242 240 238) +typeset -ra sep_color=(248 246 244 242) +typeset -ra prefix_color=(250 248 246 244) +typeset -r left_circle='\uE0B6' +typeset -r right_circle='\uE0B4' +typeset -r left_arc='\uE0B7' +typeset -r right_arc='\uE0B5' typeset -r left_triangle='\uE0B2' typeset -r right_triangle='\uE0B0' typeset -r left_angle='\uE0B3' @@ -51,22 +62,42 @@ typeset -r vertical_bar='|' typeset -r slanted_bar='\uE0BD' typeset -ra lean_left=( - '' '%31F$extra_icons[1]%B%39F~%b%31F/%B%39Fpowerlevel10k%b%f $prefixes[1]%76F$extra_icons[2]master ⇡2%f ' + '' '${extra_icons[1]:+$extra_icons[1] }%31F$extra_icons[2]%B%39F~%b%31F/%B%39Fsrc%b%f $prefixes[1]%76F$extra_icons[3]master%f ' '' '%76F❯%f █' ) typeset -ra lean_right=( - ' $prefixes[2]%134F⎈ minikube%f' '' + ' $prefixes[2]%101F$extra_icons[4]5s%f${show_time:+ $prefixes[3]%66F$extra_icons[5]16:23:42%f}' '' '' '' ) typeset -ra classic_left=( - '%$frame_color[$color]F╭─' '%F{$bg_color[$color]}$left_tail%K{$bg_color[$color]} %31F$extra_icons[1]%B%39F~%b%K{$bg_color[$color]}%31F/%B%39Fpowerlevel10k%b%K{$bg_color[$color]} %$sep_color[$color]F$left_subsep%f %$prefix_color[$color]F$prefixes[1]%76F$extra_icons[2]master ⇡2 %k%$bg_color[$color]F$left_head%f' + '%$frame_color[$color]F╭─' '%F{$bg_color[$color]}$left_tail%K{$bg_color[$color]} ${extra_icons[1]:+$extra_icons[1]%K{$bg_color[$color]\} %$sep_color[$color]F$left_subsep%f }%31F$extra_icons[2]%B%39F~%b%K{$bg_color[$color]}%31F/%B%39Fsrc%b%K{$bg_color[$color]} %$sep_color[$color]F$left_subsep%f %$prefix_color[$color]F$prefixes[1]%76F$extra_icons[3]master %k%$bg_color[$color]F$left_head%f' '%$frame_color[$color]F╰─' '%f █' ) typeset -ra classic_right=( - '%$bg_color[$color]F$right_head%K{$bg_color[$color]}%f %$prefix_color[$color]F$prefixes[2]%134Fminikube ⎈ %k%F{$bg_color[$color]}$right_tail%f' '%$frame_color[$color]F─╮%f' + '%$bg_color[$color]F$right_head%K{$bg_color[$color]}%f %$prefix_color[$color]F$prefixes[2]%101F5s $extra_icons[4]${show_time:+%$sep_color[$color]F$right_subsep %$prefix_color[$color]F$prefixes[3]%66F16:23:42 $extra_icons[5]}%k%F{$bg_color[$color]}$right_tail%f' '%$frame_color[$color]F─╮%f' + '' '%$frame_color[$color]F─╯%f' +) + +typeset -ra pure_left=( + '' '%4F~/src%f %242Fmaster%f %3F5s%f' + '' '%5F❯%f █' +) + +typeset -ra pure_right=( + '' '' + '' '' +) + +typeset -ra rainbow_left=( + '%$frame_color[$color]F╭─' '%F{${${extra_icons[1]:+0}:-4}}$left_tail${extra_icons[1]:+%K{0\} $extra_icons[1] %K{4\}%0F$left_sep}%K{4}%254F $extra_icons[2]%B%255F~%b%K{4}%254F/%B%255Fsrc%b%K{4} %K{2}%4F$left_sep %0F$prefixes[1]$extra_icons[3]master %k%2F$left_head%f' + '%$frame_color[$color]F╰─' '%f █' +) + +typeset -ra rainbow_right=( + '%3F$right_head%K{3} %0F$prefixes[2]5s $extra_icons[4]%3F${show_time:+%7F$right_sep%K{7\} %0F$prefixes[3]16:23:42 $extra_icons[5]%7F}%k$right_tail%f' '%$frame_color[$color]F─╮%f' '' '%$frame_color[$color]F─╯%f' ) @@ -101,11 +132,16 @@ function print_prompt() { (( left_frame )) || left=('' $left[2] '' '%76F❯%f █') (( right_frame )) || right=($right[1] '' '' '') fi + local -i right_indent=rprompt_indent + local -i width=$(prompt_length ${(g::):-$left[1]$left[2]$right[1]$right[2]}) + while (( wizard_columns - width <= prompt_indent + right_indent )); do + (( --right_indent )) + done local -i i for ((i = 1; i < $#left; i+=2)); do local l=${(g::):-$left[i]$left[i+1]} local r=${(g::):-$right[i]$right[i+1]} - local -i gap=$((__p9k_wizard_columns - prompt_indent - rprompt_indent - $(prompt_length $l$r))) + local -i gap=$((wizard_columns - prompt_indent - right_indent - $(prompt_length $l$r))) (( num_lines == 2 && i == 1 )) && local fill=$gap_char || local fill=' ' print -n -- ${(pl:$prompt_indent:: :)} print -nP -- $l @@ -118,10 +154,38 @@ function href() { print -r -- $'%{\e]8;;'${1//\%/%%}$'\a%}'${1//\%/%%}$'%{\e]8;;\a%}' } -function centered() { - local n=$(prompt_length ${(g::)1}) - print -n -- ${(pl:$(((__p9k_wizard_columns - n) / 2)):: :)} - print -P -- $1 +function flowing() { + local opt + local -i centered indentation + while getopts 'ci:' opt; do + case $opt in + i) indentation=$OPTARG;; + c) centered=1;; + +c) centered=0;; + \?) exit 1;; + esac + done + shift $((OPTIND-1)) + local line word lines=() + for word in "$@"; do + local n=$(prompt_length ${(g::):-"$line $word"}) + if (( n > wizard_columns )); then + [[ -z $line ]] || lines+=$line + line= + fi + if [[ -n $line ]]; then + line+=' ' + elif (( $#lines )); then + line=${(pl:$indentation:: :)} + fi + line+=$word + done + [[ -z $line ]] || lines+=$line + for line in $lines; do + local n=$(prompt_length ${(g::)line}) + (( centered && n < wizard_columns )) && print -n -- ${(pl:$(((wizard_columns - n) / 2)):: :)} + print -P -- $line + done } function clear() { @@ -135,11 +199,15 @@ function clear() { } function quit() { - clear + if [[ $1 == '-c' ]]; then + print -P "" + else + clear + fi if (( force )); then print -P "Powerlevel10k configuration wizard has been aborted. To run it again, type:" print -P "" - print -P " %2Fp9k_configure%f" + print -P " %2Fp10k%f %Bconfigure%b" print -P "" else print -P "Powerlevel10k configuration wizard has been aborted. It will run again" @@ -151,54 +219,212 @@ function quit() { print -P "" print -P "To run Powerlevel10k configuration wizard right now, type:" print -P "" - print -P " %2Fp9k_configure%f" + print -P " %2Fp10k%f %Bconfigure%b" print -P "" fi exit 1 } -function ask_diamond() { - while true; do - clear - if (( force )); then - print -P "This is %4FPowerlevel10k configuration wizard%f. It will ask you a few" - print -P "questions and configure your prompt." +local -i greeting_printed=0 + +function print_greeting() { + (( greeting_printed )) && return + if (( force )); then + flowing -c This is %4FPowerlevel10k configuration wizard%f. \ + It will ask you a few questions and configure your prompt. + else + flowing -c This is %4FPowerlevel10k configuration wizard%f. \ + You are seeing it because you haven\'t defined any \ + Powerlevel10k configuration options. It will ask \ + you a few questions and configure your prompt. + fi + print -P "" +} + +function iterm_get() { + /usr/libexec/PlistBuddy -c "Print :$1" ~/Library/Preferences/com.googlecode.iterm2.plist +} + +local terminal iterm2_font_size + +function can_install_font() { + [[ $P9K_SSH == 0 ]] || return + if [[ "$(uname)" == Linux && "$(uname -o)" == Android ]]; then + (( $+commands[termux-reload-settings] )) || return + (( $+commands[curl] )) || return + if [[ -f ~/.termux/font.ttf ]]; then + [[ -r ~/.termux/font.ttf ]] || return + [[ -w ~/.termux/font.ttf ]] || return + ! grep -q 'MesloLGS NF' ~/.termux/font.ttf 2>/dev/null || return + fi + if [[ -f ~/.termux ]]; then + [[ -d ~/.termux && -w ~/.termux ]] || return else - print -P "This is %4FPowerlevel10k configuration wizard%f. You are seeing it because" - print -P "you haven't defined any Powerlevel10k configuration options. It will" - print -P "ask you a few questions and configure your prompt." + [[ -w ~ ]] || return fi + terminal=Termux + return + fi + if [[ "$(uname)" == Darwin && $TERM_PROGRAM == iTerm.app ]]; then + (( $+commands[curl] )) || return + [[ $TERM_PROGRAM_VERSION == [2-9]* ]] || return + if [[ -f ~/Library/Fonts ]]; then + [[ -d ~/Library/Fonts && -w ~/Library/Fonts ]] || return + else + [[ -d ~/Library && -w ~/Library ]] || return + fi + [[ -x /usr/libexec/PlistBuddy ]] || return + [[ -x /usr/bin/plutil ]] || return + [[ -x /usr/bin/defaults ]] || return + [[ -f ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + [[ -r ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + [[ -w ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + local guid1 && guid1="$(iterm_get '"Default Bookmark Guid"' 2>/dev/null)" || return + local guid2 && guid2="$(iterm_get '"New Bookmarks":0:"Guid"' 2>/dev/null)" || return + local font && font="$(iterm_get '"New Bookmarks":0:"Normal Font"' 2>/dev/null)" || return + [[ $guid1 == $guid2 ]] || return + [[ $font != 'MesloLGSNer-Regular '<-> ]] || return + [[ $font == (#b)*' '(<->) ]] || return + iterm2_font_size=$match[1] + terminal=iTerm2 + return + fi + return 1 +} + +function run_command() { + local msg=$1 + shift + [[ -n $msg ]] && print -nP -- "$msg ..." + local err && err="$("$@" 2>&1)" || { + print -P " %1FERROR%f" + print -P "" + print -nP "%BCommand:%b " + print -r -- "${(@q)*}" + if [[ -n $err ]]; then + print -P "" + print -r -- $err + fi + quit -c + } + [[ -n $msg ]] && print -P " %2FOK%f" +} + +function install_font() { + clear + case $terminal in + Termux) + mkdir -p ~/.termux || quit -c + run_command "Downloading %BMesloLGS NF Regular.ttf%b" \ + curl -fsSL -o ~/.termux/font.ttf "$font_base_url/MesloLGS%20NF%20Regular.ttf" + run_command "Reloading %BTermux%b settings" termux-reload-settings + ;; + iTerm2) + mkdir -p ~/Library/Fonts || quit -c + local style + for style in Regular Bold Italic 'Bold Italic'; do + local file="MesloLGS NF ${style}.ttf" + run_command "Downloading %B$file%b" \ + curl -fsSL -o ~/Library/Fonts/$file "$font_base_url/${file// /%20}" + done + print -nP -- "Changing %BiTerm2%b settings ..." + local k v settings=( + '"Normal Font"' '"MesloLGSNer-Regular '$iterm2_font_size'"' + '"Horizontal Spacing"' 1 + '"Vertical Spacing"' 1 + '"Use Bold Font"' 1 + '"Use Bright Bold"' 1 + '"Use Italic Font"' 1 + '"Use Non-ASCII Font"' 0 + '"Ambiguous Double Width"' 0 + '"Terminal Type"' '"xterm-256color"' + ) + for k v in $settings; do + run_command "" /usr/libexec/PlistBuddy -c \ + "Set :\"New Bookmarks\":0:$k $v" ~/Library/Preferences/com.googlecode.iterm2.plist + done + print -P " %2FOK%f" + run_command "Updating %BiTerm2%b settings cache" /usr/bin/defaults read com.googlecode.iterm2 + clear + print -P "%2FMeslo Nerd Font%f successfully installed." + print -P "" + print -P "Please %Brestart iTerm2%b for the changes to take effect." + print -P "" + flowing +c -i 5 " 1. Click" "%BiTerm2 → Quit iTerm2%b" or press "%B⌘ Q%b." + flowing +c -i 5 " 2. Open %BiTerm2%b." + print -P "" + exit 69 + ;; + esac +} + +function ask_font() { + can_install_font || return 0 + while true; do + clear + print_greeting + flowing -c "%BInstall %b%2FMeslo Nerd Font%f%B?%b" + print -P "" + print -P "" + print -P "%B(y) Yes (recommended).%b" + print -P "" + print -P "%B(n) No. Use the current font.%b" print -P "" - centered "%BDoes this look like a %b%2Fdiamond%f%B (square rotated 45 degrees)?%b" - centered "reference: $(href https://graphemica.com/%E2%97%86)" + print -P "(q) Quit and do nothing." print -P "" - centered "---> \uE0B2\uE0B0 <---" + + local key= + read -k key${(%):-"?%BChoice [ynq]: %b"} || quit -c + case $key in + q) quit;; + y) install_font; break;; + n) break;; + esac + done + greeting_printed=1 +} + +function ask_diamond() { + while true; do + local extra= + clear + print_greeting + flowing -c "%BDoes this look like a %b%2Fdiamond%f%B (rotated square)?%b" + flowing -c "reference: $(href https://graphemica.com/%E2%97%86)" + print -P "" + flowing -c -- "---> \uE0B2\uE0B0 <---" print -P "" print -P "%B(y) Yes.%b" print -P "" print -P "%B(n) No.%b" print -P "" + if can_install_font; then + extra+=r + print -P "(r) Restart from the beginning." + fi print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [ynq]: %b"} || quit + read -k key${(%):-"?%BChoice [yn${extra}q]: %b"} || quit -c case $key in q) quit;; + r) [[ $extra == *r* ]] && { greeting_printed=1; return 1 };; y) cap_diamond=1; break;; n) cap_diamond=0; break;; esac done + greeting_printed=1 } function ask_lock() { while true; do clear - [[ -n $2 ]] && centered "$2" - centered "%BDoes this look like a %b%2Flock%f%B?%b" - centered "reference: $(href https://fontawesome.com/icons/lock)" + [[ -n $2 ]] && flowing -c "$2" + flowing -c "%BDoes this look like a %b%2Flock%f%B?%b" + flowing -c "reference: $(href https://fontawesome.com/icons/lock)" print -P "" - centered "---> $1 <---" + flowing -c -- "---> $1 <---" print -P "" print -P "%B(y) Yes.%b" print -P "" @@ -209,7 +435,7 @@ function ask_lock() { print -P "" local key= - read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -222,10 +448,10 @@ function ask_lock() { function ask_python() { while true; do clear - centered "%BDoes this look like a %b%2FPython logo%f%B?%b" - centered "reference: $(href https://fontawesome.com/icons/python)" + flowing -c "%BDoes this look like a %b%2FPython logo%f%B?%b" + flowing -c "reference: $(href https://fontawesome.com/icons/python)" print -P "" - centered "---> \uE63C <---" + flowing -c -- "---> \uE63C <---" print -P "" print -P "%B(y) Yes.%b" print -P "" @@ -236,7 +462,7 @@ function ask_python() { print -P "" local key= - read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -246,6 +472,33 @@ function ask_python() { done } +function ask_debian() { + while true; do + clear + flowing -c "%BDoes this look like a %b%2FDebian logo%f%B (swirl/spiral)?%b" + flowing -c "reference: $(href https://debian.org/logos/openlogo-nd.svg)" + print -P "" + flowing -c -- "---> \uF306 <---" + print -P "" + print -P "%B(y) Yes.%b" + print -P "" + print -P "%B(n) No.%b" + print -P "" + print -P "(r) Restart from the beginning." + print -P "(q) Quit and do nothing." + print -P "" + + local key= + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c + case $key in + q) quit;; + r) return 1;; + y) cap_debian=1; break;; + n) cap_debian=0; break;; + esac + done +} + function ask_narrow_icons() { if [[ $POWERLEVEL9K_MODE == (powerline|compatible) ]]; then cap_narrow_icons=0 @@ -257,14 +510,17 @@ function ask_narrow_icons() { text+="%3F${icons[DATE_ICON]// }%fX" text+="%4F${icons[TIME_ICON]// }%fX" text+="%5F${icons[RUBY_ICON]// }%fX" - text+="%6F${icons[AWS_EB_ICON]// }%fX" + text+="%6F${icons[HOME_ICON]// }%fX" + text+="%1F${icons[HOME_SUB_ICON]// }%fX" + text+="%2F${icons[FOLDER_ICON]// }%fX" + text+="%3F${icons[RAM_ICON]// }%fX" while true; do clear - centered "%BDo all these icons %b%2Ffit between the crosses%f%B?%b" + flowing -c "%BDo all these icons %b%2Ffit between the crosses%f%B?%b" print -P "" - centered "---> $text <---" + flowing -c -- "---> $text <---" print -P "" - print -P "%B(y) Yes. Icons are very close to the crosses but there is %b%2Fno overlap%f%B.%b" + flowing +c -i 5 "%B(y) Yes." Icons are very close to the crosses but there is "%b%2Fno overlap%f%B.%b" print -P "" print -P "%B(n) No. Some icons %b%2Foverlap%f%B neighbouring crosses.%b" print -P "" @@ -273,98 +529,258 @@ function ask_narrow_icons() { print -P "" local key= - read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; y) cap_narrow_icons=1; options+='small icons'; break;; - n) cap_narrow_icons=0; break;; + n) cap_narrow_icons=0; options+='large icons'; break;; esac done } function ask_style() { + if (( cap_diamond && LINES < 26 )); then + local nl='' + else + local nl=$'\n' + fi while true; do clear - centered "%BPrompt Style%b" - print -P "" + flowing -c "%BPrompt Style%b" + print -n $nl print -P "%B(1) Lean.%b" - print -P "" + print -n $nl style=lean print_prompt print -P "" print -P "%B(2) Classic.%b" - print -P "" + print -n $nl style=classic print_prompt print -P "" + print -P "%B(3) Rainbow.%b" + print -n $nl + style=rainbow print_prompt + print -P "" + print -P "%B(4) Pure.%b" + print -n $nl + style=pure print_prompt + print -P "" print -P "(r) Restart from the beginning." print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; 1) style=lean; options+=lean; break;; 2) style=classic; options+=classic; break;; + 3) style=rainbow; options+=rainbow; break;; + 4) style=pure; empty_line=1; options+=pure; break;; esac done } function ask_color() { [[ $style != classic ]] && return + if [[ $LINES -lt 26 ]]; then + local nl='' + else + local nl=$'\n' + fi while true; do clear - centered "%BPrompt Color%b" + flowing -c "%BPrompt Color%b" + print -n $nl + print -P "%B(1) Lightest.%b" + print -n $nl + color=1 print_prompt + print -P "" + print -P "%B(2) Light.%b" + print -n $nl + color=2 print_prompt print -P "" - print -P "%B(1) Light.%b" + print -P "%B(3) Dark.%b" + print -n $nl + color=3 print_prompt print -P "" - color=1 print_prompt + print -P "%B(4) Darkest.%b" + print -n $nl + color=4 print_prompt print -P "" - print -P "%B(2) Medium.%b" + print -P "(r) Restart from the beginning." + print -P "(q) Quit and do nothing." print -P "" + + local key= + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c + case $key in + q) quit;; + r) return 1;; + 1) color=1; options+=lightest; break;; + 2) color=2; options+=light; break;; + 3) color=3; options+=dark; break;; + 4) color=4; options+=darkest; break;; + esac + done +} + +function ask_frame_color() { + [[ $style != rainbow || $num_lines == 1 ]] && return + [[ $gap_char == ' ' && $left_frame == 0 && $right_frame == 0 ]] && return + if [[ $LINES -lt 26 ]]; then + local nl='' + else + local nl=$'\n' + fi + while true; do + clear + flowing -c "%BFrame Color%b" + print -n $nl + print -P "%B(1) Lightest.%b" + print -n $nl + color=1 print_prompt + print -P "" + print -P "%B(2) Light.%b" + print -n $nl color=2 print_prompt print -P "" print -P "%B(3) Dark.%b" - print -P "" + print -n $nl color=3 print_prompt print -P "" + print -P "%B(4) Darkest.%b" + print -n $nl + color=4 print_prompt + print -P "" print -P "(r) Restart from the beginning." print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [123rq]: %b"} || quit + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; - 1) color=1; options+=light; break;; - 2) color=2; options+=medium; break;; + 1) color=1; options+=lightest; break;; + 2) color=2; options+=light; break;; 3) color=3; options+=dark; break;; + 4) color=4; options+=darkest; break;; + esac + done +} + +function ask_time() { + if (( wizard_columns < 80 )); then + show_time= + return + fi + + while true; do + clear + flowing -c "%BShow current time?%b" + print -P "" + print -P "%B(y) Yes.%b" + print -P "" + show_time=1 print_prompt + print -P "" + print -P "%B(n) No.%b" + print -P "" + show_time= print_prompt + print -P "" + print -P "(r) Restart from the beginning." + print -P "(q) Quit and do nothing." + print -P "" + + local key= + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c + case $key in + q) quit;; + r) return 1;; + y) show_time=1; options+=time; break;; + n) show_time=; break;; esac done } +function os_icon_name() { + local uname="$(uname)" + if [[ $uname == Linux && "$(uname -o 2>/dev/null)" == Android ]]; then + echo ANDROID_ICON + else + case $uname in + SunOS) echo SUNOS_ICON;; + Darwin) echo APPLE_ICON;; + CYGWIN_NT-* | MSYS_NT-*) echo WINDOWS_ICON;; + FreeBSD|OpenBSD|DragonFly) echo FREEBSD_ICON;; + Linux) + local os_release_id + if [[ -r /etc/os-release ]]; then + local lines=(${(f)"$(</etc/os-release)"}) + lines=(${(@M)lines:#ID=*}) + (( $#lines == 1 )) && os_release_id=${lines[1]#ID=} + fi + case $os_release_id in + *arch*) echo LINUX_ARCH_ICON;; + *debian*) echo LINUX_DEBIAN_ICON;; + *raspbian*) echo LINUX_RASPBIAN_ICON;; + *ubuntu*) echo LINUX_UBUNTU_ICON;; + *elementary*) echo LINUX_ELEMENTARY_ICON;; + *fedora*) echo LINUX_FEDORA_ICON;; + *coreos*) echo LINUX_COREOS_ICON;; + *gentoo*) echo LINUX_GENTOO_ICON;; + *mageia*) echo LINUX_MAGEIA_ICON;; + *centos*) echo LINUX_CENTOS_ICON;; + *opensuse*|*tumbleweed*) echo LINUX_OPENSUSE_ICON;; + *sabayon*) echo LINUX_SABAYON_ICON;; + *slackware*) echo LINUX_SLACKWARE_ICON;; + *linuxmint*) echo LINUX_MINT_ICON;; + *alpine*) echo LINUX_ALPINE_ICON;; + *aosc*) echo LINUX_AOSC_ICON;; + *nixos*) echo LINUX_NIXOS_ICON;; + *devuan*) echo LINUX_DEVUAN_ICON;; + *manjaro*) echo LINUX_MANJARO_ICON;; + *) echo LINUX_ICON;; + esac + ;; + esac + fi +} + function ask_extra_icons() { if [[ $POWERLEVEL9K_MODE == (powerline|compatible) ]]; then return fi + local os_icon=${(g::)icons[$(os_icon_name)]} local dir_icon=${(g::)icons[HOME_SUB_ICON]} local vcs_icon=${(g::)icons[VCS_GIT_GITHUB_ICON]} local branch_icon=${(g::)icons[VCS_BRANCH_ICON]} + local duration_icon=${(g::)icons[EXECUTION_TIME_ICON]} + local time_icon=${(g::)icons[TIME_ICON]} if (( cap_narrow_icons )); then + os_icon=${os_icon// } dir_icon=${dir_icon// } vcs_icon=${vcs_icon// } - branch_icon=${branch_icon// } + duration_icon=${duration_icon// } + time_icon=${time_icon// } fi - local many=("$dir_icon " "$vcs_icon $branch_icon ") + branch_icon=${branch_icon// } + if [[ $style == (classic|rainbow) ]]; then + os_icon="%255F$os_icon%f" + else + os_icon="%f$os_icon" + fi + os_icon="%B$os_icon%b" + local few=('' '' '' '' '') + local many=("$os_icon" "$dir_icon " "$vcs_icon $branch_icon " "$duration_icon " "$time_icon ") while true; do clear - centered "%BIcons%b" + flowing -c "%BIcons%b" print -P "" print -P "%B(1) Few icons.%b" print -P "" - extra_icons=('' '') print_prompt + extra_icons=("$few[@]") print_prompt print -P "" print -P "%B(2) Many icons.%b" print -P "" @@ -375,25 +791,31 @@ function ask_extra_icons() { print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; - 1) extra_icons=('' ''); options+='few icons'; break;; + 1) extra_icons=("$few[@]"); options+='few icons'; break;; 2) extra_icons=("$many[@]"); options+='many icons'; break;; esac done } function ask_prefixes() { - local fluent=('on ' 'at ') + local concise=('' '' '') + local fluent=('on ' 'took ' 'at ') + if (( wizard_columns < 80 )); then + prefixes=("$concise[@]") + options+=concise + return + fi while true; do clear - centered "%BPrompt Flow%b" + flowing -c "%BPrompt Flow%b" print -P "" print -P "%B(1) Concise.%b" print -P "" - prefixes=('' '') print_prompt + prefixes=("$concise[@]") print_prompt print -P "" print -P "%B(2) Fluent.%b" print -P "" @@ -404,46 +826,60 @@ function ask_prefixes() { print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; - 1) prefixes=('' ''); break;; + 1) prefixes=("$concise[@]"); options+=concise; break;; 2) prefixes=("$fluent[@]"); options+=fluent; break;; esac done } function ask_separators() { - if [[ $style != classic || $cap_diamond != 1 ]]; then + if [[ $style != (classic|rainbow) || $cap_diamond != 1 ]]; then return fi + if [[ $POWERLEVEL9K_MODE == nerdfont-complete && $LINES -lt 26 ]]; then + local nl='' + else + local nl=$'\n' + fi while true; do local extra= clear - centered "%BPrompt Separators%b" - print -P " separator" - print -P "%B(1) Angled.%b |" - print -P " v" + flowing -c "%BPrompt Separators%b" + if [[ -n $nl ]]; then + print -P " separator" + print -P "%B(1) Angled.%b /" + print -P " /" + else + print -P "%B(1) Angled.%b" + fi left_sep=$right_triangle right_sep=$left_triangle left_subsep=$right_angle right_subsep=$left_angle print_prompt print -P "" print -P "%B(2) Vertical.%b" - print -P "" + print -n $nl left_sep='' right_sep='' left_subsep=$vertical_bar right_subsep=$vertical_bar print_prompt print -P "" if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then extra+=3 print -P "%B(3) Slanted.%b" - print -P "" + print -n $nl left_sep=$down_triangle right_sep=$up_triangle left_subsep=$slanted_bar right_subsep=$slanted_bar print_prompt print -P "" + extra+=4 + print -P "%B(4) Round.%b" + print -n $nl + left_sep=$right_circle right_sep=$left_circle left_subsep=$right_arc right_subsep=$left_arc print_prompt + print -P "" fi print -P "(r) Restart from the beginning." print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [12${extra}rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12${extra}rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -452,7 +888,7 @@ function ask_separators() { right_sep=$left_triangle left_subsep=$right_angle right_subsep=$left_angle - options+='angled sep' + options+='angled separators' break ;; 2) @@ -460,7 +896,7 @@ function ask_separators() { right_sep='' left_subsep=$vertical_bar right_subsep=$vertical_bar - options+='vertical sep' + options+='vertical separators' break ;; 3) @@ -469,7 +905,17 @@ function ask_separators() { right_sep=$up_triangle left_subsep=$slanted_bar right_subsep=$slanted_bar - options+='slanted sep' + options+='slanted separators' + break + fi + ;; + 4) + if [[ $extra == *4* ]]; then + left_sep=$right_circle + right_sep=$left_circle + left_subsep=$right_arc + right_subsep=$left_arc + options+='round separators' break fi ;; @@ -478,35 +924,49 @@ function ask_separators() { } function ask_heads() { - if [[ $style != classic || $cap_diamond != 1 ]]; then + if [[ $style != (classic|rainbow) || $cap_diamond != 1 ]]; then return fi + if [[ $POWERLEVEL9K_MODE == nerdfont-complete && $LINES -lt 26 ]]; then + local nl='' + else + local nl=$'\n' + fi while true; do local extra= clear - centered "%BPrompt Heads%b" - print -P "" - print -P "%B(1) Sharp.%b" - print -P "" + flowing -c "%BPrompt Heads%b" + if [[ -n $nl ]]; then + print -P " head" + print -P "%B(1) Sharp.%b |" + print -P " v" + else + print -P "%B(1) Sharp.%b" + fi left_head=$right_triangle right_head=$left_triangle print_prompt print -P "" print -P "%B(2) Blurred.%b" - print -P "" + print -n $nl left_head=$fade_out right_head=$fade_in print_prompt print -P "" if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then extra+=3 print -P "%B(3) Slanted.%b" - print -P "" + print -n $nl left_head=$down_triangle right_head=$up_triangle print_prompt print -P "" + extra+=4 + print -P "%B(4) Round.%b" + print -n $nl + left_head=$right_circle right_head=$left_circle print_prompt + print -P "" fi print -P "(r) Restart from the beginning." print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12${extra}rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -520,16 +980,23 @@ function ask_heads() { break fi ;; + 4) + if [[ $extra == *4* ]]; then + left_head=$right_circle + right_head=$left_circle + options+='round heads' + break + fi + ;; esac done } function ask_tails() { - if [[ $style != classic ]]; then + if [[ $style != (classic|rainbow) ]]; then return fi - - if [[ $POWERLEVEL9K_MODE == nerdfont-complete && $LINES -lt 26 ]]; then + if [[ $POWERLEVEL9K_MODE == nerdfont-complete && $LINES -lt 31 ]]; then local nl='' else local nl=$'\n' @@ -537,7 +1004,7 @@ function ask_tails() { while true; do local extra= clear - centered "%BPrompt Tails%b" + flowing -c "%BPrompt Tails%b" print -n $nl print -P "%B(1) Flat.%b" print -n $nl @@ -559,6 +1026,13 @@ function ask_tails() { print -n $nl left_tail=$up_triangle right_tail=$down_triangle print_prompt print -P "" + if (( LINES >= 25 )); then + extra+=5 + print -P "%B(5) Round.%b" + print -n $nl + left_tail=$left_circle right_tail=$right_circle print_prompt + print -P "" + fi fi fi print -P "(r) Restart from the beginning." @@ -566,7 +1040,7 @@ function ask_tails() { print -P "" local key= - read -k key${(%):-"?%BChoice [12${extra}rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12${extra}rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -588,6 +1062,14 @@ function ask_tails() { break fi ;; + 5) + if [[ $extra == *5* ]]; then + left_tail=$left_circle + right_tail=$right_circle + options+='round tails' + break + fi + ;; esac done } @@ -595,7 +1077,7 @@ function ask_tails() { function ask_num_lines() { while true; do clear - centered "%BPrompt Height%b" + flowing -c "%BPrompt Height%b" print -P "" print -P "%B(1) One line.%b" print -P "" @@ -610,7 +1092,7 @@ function ask_num_lines() { print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -626,7 +1108,7 @@ function ask_gap_char() { fi while true; do clear - centered "%BPrompt Connection%b" + flowing -c "%BPrompt Connection%b" print -P "" print -P "%B(1) Disconnected.%b" print -P "" @@ -645,7 +1127,7 @@ function ask_gap_char() { print -P "" local key= - read -k key${(%):-"?%BChoice [123rq]: %b"} || quit + read -k key${(%):-"?%BChoice [123rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -657,14 +1139,14 @@ function ask_gap_char() { } function ask_frame() { - if [[ $style != classic || $num_lines != 2 ]]; then + if [[ $style != (classic|rainbow) || $num_lines != 2 ]]; then return fi (( LINES >= 26 )) && local nl=$'\n' || local nl='' while true; do clear - centered "%BPrompt Frame%b" + flowing -c "%BPrompt Frame%b" print -n $nl print -P "%B(1) No frame.%b" print -n $nl @@ -687,7 +1169,7 @@ function ask_frame() { print -P "" local key= - read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -702,7 +1184,7 @@ function ask_frame() { function ask_empty_line() { while true; do clear - centered "%BPrompt Spacing%b" + flowing -c "%BPrompt Spacing%b" print -P "" print -P "%B(1) Compact.%b" print -P "" @@ -720,7 +1202,7 @@ function ask_empty_line() { print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -733,7 +1215,7 @@ function ask_empty_line() { function ask_confirm() { while true; do clear - centered "%BLooks good?%b" + flowing -c "%BLooks good?%b" print -P "" print_prompt (( empty_line )) && print -P "" @@ -746,7 +1228,7 @@ function ask_confirm() { print -P "" local key= - read -k key${(%):-"?%BChoice [yrq]: %b"} || quit + read -k key${(%):-"?%BChoice [yrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -763,8 +1245,8 @@ function ask_config_overwrite() { fi while true; do clear - centered "Powerlevel10k config file already exists." - centered "%BOverwrite %b%2F$__p9k_cfg_path_u%f%B?%b" + flowing -c "Powerlevel10k config file already exists." + flowing -c "%BOverwrite" "%b%2F${__p9k_cfg_path_u//\\/\\\\}%f%B?%b" print -P "" print -P "%B(y) Yes.%b" print -P "" @@ -773,13 +1255,14 @@ function ask_config_overwrite() { print -P "" local key= - read -k key${(%):-"?%BChoice [yrq]: %b"} || quit + read -k key${(%):-"?%BChoice [yrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; y) - config_backup="$(mktemp ${TMPDIR:-/tmp}/$__p9k_cfg_basename.XXXXXXXXXX)" || return 1 - cp $__p9k_cfg_path $config_backup + config_backup="$(mktemp ${TMPDIR:-/tmp}/$__p9k_cfg_basename.XXXXXXXXXX)" || exit 1 + cp $__p9k_cfg_path $config_backup || exit 1 + config_backup_u=${${TMPDIR:+\$TMPDIR}:-/tmp}/${(q-)config_backup:t} write_config=1 break ;; @@ -788,6 +1271,14 @@ function ask_config_overwrite() { } function generate_config() { + if [[ $style == pure ]]; then + if [[ -e $__p9k_cfg_path ]]; then + unlink $__p9k_cfg_path || return + fi + cp $__p9k_root_dir/config/p10k-$style.zsh $__p9k_cfg_path || return + return + fi + local base && base="$(<$__p9k_root_dir/config/p10k-$style.zsh)" || return local lines=("${(@f)base}") @@ -799,23 +1290,57 @@ function generate_config() { lines=("${(@)lines/#(#b)([[:space:]]#)\# $1( |)/$match[1]$1$match[2]$match[2]}") } + function rep() { + lines=("${(@)lines//$1/$2}") + } + sub MODE $POWERLEVEL9K_MODE if (( cap_narrow_icons )); then + uncomment 'typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION' sub VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER// }'" sub BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER// }'" + sub VPN_IP_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER// }'" + sub OS_ICON_CONTENT_EXPANSION "'%B\${P9K_CONTENT// }'" else sub VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER}'" sub BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER}'" + sub VPN_IP_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER}'" fi if [[ $POWERLEVEL9K_MODE == compatible ]]; then - # Many fonts don't have the gear icon. + # Many fonts don't have the gear or the lock icon. sub BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION "'⇶'" + uncomment 'typeset -g POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION' + sub DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION "'∅'" + fi + + if [[ $POWERLEVEL9K_MODE == (awesome-patched|awesome-fontconfig) && $cap_python == 0 ]]; then + uncomment 'typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_PYTHON_ICON' + sub VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub ANACONDA_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub PYENV_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub PYTHON_ICON "'🐍'" + fi + + if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then + sub BATTERY_STAGES "\$'\uf58d\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf578'" fi - if [[ $style == classic ]]; then - sub BACKGROUND $bg_color[$color] + if [[ $style == (classic|rainbow) ]]; then + if [[ $style == classic ]]; then + sub BACKGROUND $bg_color[$color] + sub LEFT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$left_subsep'" + sub RIGHT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$right_subsep'" + sub VCS_LOADING_FOREGROUND $sep_color[$color] + rep '%248F' "%$prefix_color[$color]F" + else + sub LEFT_SUBSEGMENT_SEPARATOR "'$left_subsep'" + sub RIGHT_SUBSEGMENT_SEPARATOR "'$right_subsep'" + fi sub MULTILINE_FIRST_PROMPT_GAP_FOREGROUND $frame_color[$color] sub MULTILINE_FIRST_PROMPT_PREFIX "'%$frame_color[$color]F╭─'" sub MULTILINE_NEWLINE_PROMPT_PREFIX "'%$frame_color[$color]F├─'" @@ -823,8 +1348,6 @@ function generate_config() { sub MULTILINE_FIRST_PROMPT_SUFFIX "'%$frame_color[$color]F─╮'" sub MULTILINE_NEWLINE_PROMPT_SUFFIX "'%$frame_color[$color]F─┤'" sub MULTILINE_LAST_PROMPT_SUFFIX "'%$frame_color[$color]F─╯'" - sub LEFT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$left_subsep'" - sub RIGHT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$right_subsep'" sub LEFT_SEGMENT_SEPARATOR "'$left_sep'" sub RIGHT_SEGMENT_SEPARATOR "'$right_sep'" sub LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL "'$left_tail'" @@ -833,10 +1356,14 @@ function generate_config() { sub RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL "'$right_tail'" fi + if [[ -n $show_time ]]; then + uncomment time + fi + if [[ -n ${(j::)extra_icons} ]]; then - local branch_icon=$icons[VCS_BRANCH_ICON] - (( cap_narrow_icons )) && branch_icon=${branch_icon// } + local branch_icon=${icons[VCS_BRANCH_ICON]// } sub VCS_BRANCH_ICON "'$branch_icon '" + uncomment os_icon else uncomment 'typeset -g POWERLEVEL9K_DIR_CLASSES' uncomment 'typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION' @@ -853,14 +1380,19 @@ function generate_config() { uncomment 'typeset -g POWERLEVEL9K_CONTEXT_PREFIX' uncomment 'typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX' uncomment 'typeset -g POWERLEVEL9K_TIME_PREFIX' - [[ $style == classic ]] && local fg="%$prefix_color[$color]F" || local fg="%f" - sub VCS_PREFIX "'${fg}on '" - sub COMMAND_EXECUTION_TIME_PREFIX "'${fg}took '" - sub CONTEXT_PREFIX "'${fg}with '" - sub KUBECONTEXT_PREFIX "'${fg}at '" - sub TIME_PREFIX "'${fg}at '" - sub CONTEXT_TEMPLATE "'%n$fg at %180F%m'" - sub CONTEXT_ROOT_TEMPLATE "'%n$fg at %227F%m'" + if [[ $style == (lean|classic) ]]; then + [[ $style == classic ]] && local fg="%$prefix_color[$color]F" || local fg="%f" + sub VCS_PREFIX "'${fg}on '" + sub COMMAND_EXECUTION_TIME_PREFIX "'${fg}took '" + sub CONTEXT_PREFIX "'${fg}with '" + sub KUBECONTEXT_PREFIX "'${fg}at '" + sub TIME_PREFIX "'${fg}at '" + sub CONTEXT_TEMPLATE "'%n$fg at %180F%m'" + sub CONTEXT_ROOT_TEMPLATE "'%n$fg at %227F%m'" + else + sub CONTEXT_TEMPLATE "'%n at %m'" + sub CONTEXT_ROOT_TEMPLATE "'%n at %m'" + fi fi if (( num_lines == 1 )); then @@ -874,7 +1406,7 @@ function generate_config() { sub MULTILINE_FIRST_PROMPT_GAP_CHAR "'$gap_char'" - if [[ $style == classic && $num_lines == 2 ]]; then + if [[ $style == (classic|rainbow) && $num_lines == 2 ]]; then if (( ! right_frame )); then sub MULTILINE_FIRST_PROMPT_SUFFIX '' sub MULTILINE_NEWLINE_PROMPT_SUFFIX '' @@ -901,8 +1433,19 @@ function generate_config() { fi fi header+=$'.\n' - header+="# Wizard options: ${(j:, :)options}" - header+=$'.\n#' + local line="# Wizard options: $options[1]" + local opt + for opt in $options[2,-1]; do + if (( $#line + $#opt > 85 )); then + header+=$line + header+=$',\n' + line="# $opt" + else + line+=", $opt" + fi + done + header+=$line + header+=$'.\n# Type `p10k configure` to generate another config.\n#' if [[ -e $__p9k_cfg_path ]]; then unlink $__p9k_cfg_path || return 1 @@ -913,28 +1456,27 @@ function generate_config() { function write_zshrc() { if [[ -e $__p9k_zshrc ]]; then local lines=(${(f)"$(<$__p9k_zshrc)"}) - local f1=$__p9k_cfg_path - local f2=$__p9k_cfg_path_u - local f3=${__p9k_cfg_path_u/#\~\//\$HOME\/} - local f4=${__p9k_cfg_path_u/#\~\//\"\$HOME\"\/} - local f5="'$f1'" - local f6="\"$f1\"" - local f7="\"$f3\"" - if [[ -n ${(@M)lines:#(#b)source[[:space:]]##($f1|$f2|$f3|$f4|$f5|$f6|$f7)*} ]]; then - print -P "No changes have been made to %4F$__p9k_zshrc_u%f because it already sources %2F$__p9k_cfg_path_u%f." + local f0=$__p9k_cfg_path + local f1=${(q)f0} + local f2=${(q-)f0} + local f3=${(qq)f0} + local f4=${(qqq)f0} + local g1=${${(q)__p9k_cfg_path}/#(#b)${(q)HOME}\//'~/'} + if [[ -n ${(@M)lines:#(#b)[^#]#([^[:IDENT:]]|)source[[:space:]]##($f1|$f2|$f3|$f4|$g1)(|[[:space:]]*|'#'*)} ]]; then + flowing +c No changes have been made to %4F$__p9k_zshrc_u%f because it already sources %2F$__p9k_cfg_path_u%f. return fi fi local comments=( - "# To customize prompt, run \`p9k_configure\` or edit $__p9k_cfg_path_u." + "# To customize prompt, run \`p10k configure\` or edit $__p9k_cfg_path_u." ) - print -lr -- "" $comments "source $__p9k_cfg_path_u" >>$__p9k_zshrc + print -lrP -- "" $comments "[[ -f $__p9k_cfg_path_u ]] && source $__p9k_cfg_path_u" >>$__p9k_zshrc - print -P "" - print -P "The following lines have been appended to %4F$__p9k_zshrc_u%f:" - print -P "" - print -lP -- ' '${^comments} " %2Fsource%f %B$__p9k_cfg_path_u%b" + print -rP "" + flowing +c The following lines have been appended to %4F$__p9k_zshrc_u%f: + print -rP "" + print -lrP -- ' '${^comments} " %3F[[%f %B-f $__p9k_cfg_path_u%b %3F]]%f && %2Fsource%f %B$__p9k_cfg_path_u%b" } if (( force )); then @@ -946,31 +1488,42 @@ fi source $__p9k_root_dir/internal/icons.zsh || return while true; do - local POWERLEVEL9K_MODE= style= config_backup= gap_char=' ' - local left_subsep= right_subsep= left_tail= right_tail= left_head= right_head= - local -i num_lines=0 write_config=0 empty_line=0 color=1 left_frame=1 right_frame=1 - local -i cap_diamond=0 cap_python=0 cap_narrow_icons=0 cap_lock=0 - local -a extra_icons=('' '') + local POWERLEVEL9K_MODE= style= config_backup= config_backup_u= gap_char=' ' + local left_subsep= right_subsep= left_tail= right_tail= left_head= right_head= show_time= + local -i num_lines=0 write_config=0 empty_line=0 color=2 left_frame=1 right_frame=1 + local -i cap_diamond=0 cap_python=0 cap_debian=0 cap_narrow_icons=0 cap_lock=0 + local -a extra_icons=('' '' '') local -a prefixes=('' '') local -a options=() + ask_font || continue ask_diamond || continue - if [[ -n $AWESOME_GLYPHS_LOADED ]]; then + if [[ $AWESOME_GLYPHS_LOADED == 1 ]]; then POWERLEVEL9K_MODE=awesome-mapped-fontconfig else ask_lock '\uF023' || continue if (( ! cap_lock )); then ask_lock '\uE138' "Let's try another one." || continue if (( cap_lock )); then - (( cap_diamond )) && POWERLEVEL9K_MODE=awesome-patched || POWERLEVEL9K_MODE=flat + if (( cap_diamond )); then + POWERLEVEL9K_MODE=awesome-patched + ask_python || continue + else + POWERLEVEL9K_MODE=flat + fi else (( cap_diamond )) && POWERLEVEL9K_MODE=powerline || POWERLEVEL9K_MODE=compatible fi elif (( ! cap_diamond )); then POWERLEVEL9K_MODE=awesome-fontconfig else - ask_python || continue - (( cap_python )) && POWERLEVEL9K_MODE=awesome-fontconfig || POWERLEVEL9K_MODE=nerdfont-complete + ask_debian || continue + if (( cap_debian )); then + POWERLEVEL9K_MODE=nerdfont-complete + else + POWERLEVEL9K_MODE=awesome-fontconfig + ask_python || continue + fi fi fi if [[ $POWERLEVEL9K_MODE == powerline ]]; then @@ -980,12 +1533,17 @@ while true; do else options+="$POWERLEVEL9K_MODE" fi + (( cap_python )) && options[-1]+=' + python' if (( cap_diamond )); then + left_sep=$right_triangle + right_sep=$left_triangle left_subsep=$right_angle right_subsep=$left_angle left_head=$right_triangle right_head=$left_triangle else + left_sep= + right_sep= left_subsep=$vertical_bar right_subsep=$vertical_bar left_head=$fade_out @@ -1085,16 +1643,20 @@ while true; do return 1 ask_style || continue - ask_color || continue - ask_separators || continue - ask_heads || continue - ask_tails || continue - ask_num_lines || continue - ask_gap_char || continue - ask_frame || continue - ask_empty_line || continue - ask_extra_icons || continue - ask_prefixes || continue + if [[ $style != pure ]]; then + ask_color || continue + ask_time || continue + ask_separators || continue + ask_heads || continue + ask_tails || continue + ask_num_lines || continue + ask_gap_char || continue + ask_frame || continue + ask_frame_color || continue + ask_empty_line || continue + ask_extra_icons || continue + ask_prefixes || continue + fi ask_confirm || continue ask_config_overwrite || continue break @@ -1102,9 +1664,9 @@ done clear -print -P "Powerlevel10k configuration has been written to %2F$__p9k_cfg_path_u%f." +flowing +c Powerlevel10k configuration has been written to %2F$__p9k_cfg_path_u%f. if [[ -n $config_backup ]]; then - print -P "The backup of the previuos version is at %3F$config_backup%f." + flowing +c The backup of the previous version is at %3F$config_backup_u%f. fi if (( write_config )); then @@ -1113,9 +1675,8 @@ fi write_zshrc || return -print -P "" -print -P "File feature requests and bug reports at $(href https://github.com/romkatv/powerlevel10k/issues)." -print -P "Send praise and complaints to $(href https://www.reddit.com/r/zsh)." -print -P "" +print -rP "" +flowing +c File feature requests and bug reports at "$(href https://github.com/romkatv/powerlevel10k/issues)." +print -rP "" } "$@" |