From a12f7ac8eefd47cd9b58b0ff77c576e194029a0c Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 12:50:51 +0100 Subject: [PATCH 01/10] when the user's locale is misconfigured, set it to utf8 at the top level fixes #469 --- internal/icons.zsh | 8 -------- internal/p10k.zsh | 36 +++++++++++++++++++++++++----------- internal/wizard.zsh | 7 ------- powerlevel10k.zsh-theme | 4 ++-- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/internal/icons.zsh b/internal/icons.zsh index 012c520a..9c672b38 100644 --- a/internal/icons.zsh +++ b/internal/icons.zsh @@ -3,12 +3,6 @@ typeset -gA icons function _p9k_init_icons() { [[ $+_p9k_icon_mode == 1 && $_p9k_icon_mode == $POWERLEVEL9K_MODE/$POWERLEVEL9K_LEGACY_ICON_SPACING ]] && return typeset -g _p9k_icon_mode=$POWERLEVEL9K_MODE/$POWERLEVEL9K_LEGACY_ICON_SPACING - 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 if [[ $POWERLEVEL9K_LEGACY_ICON_SPACING == true ]]; then local s= @@ -614,7 +608,6 @@ function _p9k_init_icons() { # Sadly, this is a part of public API. Its use is emphatically discouraged. function _p9k_print_icon() { _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 @@ -631,7 +624,6 @@ function _p9k_print_icon() { # overrides into account. function _p9k_get_icon_names() { _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 9ba33a78..e2a98408 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -1,4 +1,4 @@ -if [[ $__p9k_sourced != 4 ]]; then +if [[ $__p9k_sourced != 5 ]]; then >&2 print -P "" >&2 print -P "[%F{1}ERROR%f]: Corrupted powerlevel10k installation." >&2 print -P "" @@ -140,6 +140,10 @@ function getColorCode() { # Sadly, this is a part of public API. Its use is emphatically discouraged. function print_icon() { eval "$__p9k_intro" + if (( ! $+_p9k__locale )); then + _p9k_init_locale + [[ -z $_p9k__locale ]] || local LC_ALL=$_p9k__locale + fi (( $+functions[_p9k_print_icon] )) || source "${__p9k_root_dir}/internal/icons.zsh" _p9k_print_icon "$@" } @@ -151,6 +155,10 @@ function print_icon() { # overrides into account. function get_icon_names() { eval "$__p9k_intro" + if (( ! $+_p9k__locale )); then + _p9k_init_locale + [[ -z $_p9k__locale ]] || local LC_ALL=$_p9k__locale + fi (( $+functions[_p9k_get_icon_names] )) || source "${__p9k_root_dir}/internal/icons.zsh" _p9k_get_icon_names "$@" } @@ -188,7 +196,6 @@ 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} @@ -529,7 +536,6 @@ _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 @@ -767,7 +773,6 @@ _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 '' @@ -988,7 +993,6 @@ _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 '' @@ -1503,7 +1507,6 @@ prompt_context() { if [[ -z $text ]]; then local var=_POWERLEVEL9K_CONTEXT_${state}_TEMPLATE if (( $+parameters[$var] )); then - [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale text=${(P)var} text=${(g::)text} else @@ -1677,7 +1680,6 @@ prompt_dir() { 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} @@ -4804,7 +4806,7 @@ _p9k_dump_instant_prompt() { local prompt_dir=${(q)prompt_dir} zmodload zsh/langinfo if [[ \${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then - local lc=${(q)${${${_p9k_locale:-${(M)LC_CTYPE:#*.(utf|UTF)(-|)8}}:-${(M)LC_ALL:#*.(utf|UTF)(-|)8}}}:-${(M)LANG:#*.(utf|UTF)(-|)8}} + local lc=${(q)${${${_p9k__locale:-${(M)LC_CTYPE:#*.(utf|UTF)(-|)8}}:-${(M)LC_ALL:#*.(utf|UTF)(-|)8}}}:-${(M)LANG:#*.(utf|UTF)(-|)8}} local LC_ALL=\${lc:-\${\${(@M)\$(locale -a 2>/dev/null):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8}} fi" >&$fd print -r -- ' @@ -5417,6 +5419,11 @@ _p9k_precmd_impl() { (( __p9k_enabled )) || return + if (( ! $+_p9k__locale )); then + _p9k_init_locale + [[ -z $_p9k__locale ]] || local LC_ALL=$_p9k__locale + fi + if ! zle || [[ -z $_p9k__param_sig ]]; then if zle; then __p9k_new_status=0 @@ -5562,6 +5569,15 @@ function _p9k_prompt_overflow_bug() { is-at-least 5.5 && ! is-at-least 5.7.2 } +function _p9k_init_locale() { + 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 +} + typeset -g _p9k__param_pat typeset -g _p9k__param_sig @@ -6289,7 +6305,6 @@ _p9k_build_gap_post() { } _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) @@ -6586,7 +6601,7 @@ _p9k_must_init() { [[ $sig == $_p9k__param_sig ]] && return 1 _p9k_deinit fi - _p9k__param_pat=$'v36\1'${ZSH_VERSION}$'\1'${ZSH_PATCHLEVEL}$'\1' + _p9k__param_pat=$'v37\1'${ZSH_VERSION}$'\1'${ZSH_PATCHLEVEL}$'\1' _p9k__param_pat+=$'${#parameters[(I)POWERLEVEL9K_*]}\1${(%):-%n%#}\1$GITSTATUS_LOG_LEVEL\1' _p9k__param_pat+=$'$GITSTATUS_ENABLE_LOGGING\1$GITSTATUS_DAEMON\1$GITSTATUS_NUM_THREADS\1' _p9k__param_pat+=$'$DEFAULT_USER\1${ZLE_RPROMPT_INDENT:-1}\1$P9K_SSH\1$__p9k_ksh_arrays' @@ -6748,7 +6763,6 @@ function _p9k_init_cacheable() { 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]} diff --git a/internal/wizard.zsh b/internal/wizard.zsh index 016ab84e..66150bb0 100755 --- a/internal/wizard.zsh +++ b/internal/wizard.zsh @@ -1,10 +1,3 @@ -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 - -zmodload -F zsh/files b:zf_mv b:zf_rm - local -i force=0 local opt diff --git a/powerlevel10k.zsh-theme b/powerlevel10k.zsh-theme index fd01648a..9bb680fe 100644 --- a/powerlevel10k.zsh-theme +++ b/powerlevel10k.zsh-theme @@ -23,7 +23,7 @@ local -a match mbegin mend reply local -i MBEGIN MEND OPTIND local MATCH REPLY OPTARG IFS=$'\'' \t\n\0'\'' - [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale' + [[ -z $_p9k__locale ]] || local LC_ALL=$_p9k__locale' () { eval "$__p9k_intro" @@ -35,7 +35,7 @@ if [[ $__p9k_dump_file != $__p9k_instant_prompt_dump_file ]] && (( ! $+functions[_p9k_preinit] )) && source $__p9k_dump_file 2>/dev/null && (( $+functions[_p9k_preinit] )); then _p9k_preinit fi - typeset -gr __p9k_sourced=4 + typeset -gr __p9k_sourced=5 if [[ -w $__p9k_root_dir && -w $__p9k_root_dir/internal && -w $__p9k_root_dir/gitstatus && ${(%):-%#} == % ]]; then local f for f in $__p9k_root_dir/{powerlevel9k.zsh-theme,powerlevel10k.zsh-theme,internal/p10k.zsh,internal/icons.zsh,internal/configure.zsh,internal/worker.zsh,internal/parser.zsh,gitstatus/gitstatus.plugin.zsh}; do From 7354eeaa96e04eaec8e2a9a33801e26c88df3c68 Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 14:37:43 +0100 Subject: [PATCH 02/10] workaround for a bug in sysread There is a bug in sysread from zsh/system. It triggers in the following case: 1. zsh has been compiled with HAVE_SELECT and without HAVE_POLL. 2. sysread is called with timeout (-t). 3. the input file descriptor is valid but there is no data to read. 4. errno happens to be EINTR prior to the call to sysread. This results in an infinite loop in sysread: while ((ret = select(infd+1, (SELECT_ARG_2_T) &fds, NULL, NULL,&select_tv)) < 1) { if (errno != EINTR || errflag || retflag || breaks || contflag) break; } Here select() keeps returning 0, indicating timeout. This is not an error, so errno doesn't get set. If it was EINTR prior to the call, it stays EINTR, and the loop keeps spinning. As a workaround, powerlevel10k sets errno to ENOTTY (any value other than EINTR will do) prior to calling sysread with timeout. --- internal/p10k.zsh | 37 +++++++++++++++++++++---------------- internal/worker.zsh | 2 ++ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/internal/p10k.zsh b/internal/p10k.zsh index e2a98408..912a990e 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -4154,22 +4154,27 @@ function _p9k_fetch_nordvpn_status() { >&$fd echo -nE - $'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n\0\0\0\4\1\0\0\0\0\0\0N\1\4\0\0\0\1\203\206E\221bA\226\223\325\\k\337\31i=LnH\323j?A\223\266\243y\270\303\fYmLT{$\357]R.\203\223\257_\213\35u\320b\r&=LMedz\212\232\312\310\264\307`+\210K\203@\2te\206M\2035\5\261\37\0\0\5\0\1\0\0\0\1\0\0\0\0\0' local tag len val local -i n - IFS='' read -t 0.25 -r tag <&3 - tag=$'\015' - while true; do - 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=$((#len)) - val= - (( ! len )) || { - sysread -c n -s $len -t 0.25 val <&3 - (( n == len )) - } - typeset -g $tag=$val - sysread -c n -s 1 -t 0.25 tag <&3 - done + { + IFS='' read -t 0.25 -r tag + tag=$'\015' + while true; do + tag=$((#tag)) + (( (tag >>= 3) && tag <= $#__p9k_nordvpn_tag )) || break + tag=$__p9k_nordvpn_tag[tag] + [[ -t $fd ]] || true + sysread -c n -s 1 -t 0.25 len + len=$((#len)) + val= + (( ! len )) || { + [[ -t $fd ]] || true + sysread -c n -s $len -t 0.25 val + (( n == len )) + } + typeset -g $tag=$val + [[ -t $fd ]] || true + sysread -c n -s 1 -t 0.25 tag + done + } <&$fd } always { exec {fd}>&- } diff --git a/internal/worker.zsh b/internal/worker.zsh index ce38af98..cca786fc 100644 --- a/internal/worker.zsh +++ b/internal/worker.zsh @@ -34,6 +34,7 @@ function _p9k_worker_main() { if [[ $fd == 0 ]]; then local buf= while true; do + [[ -t 0 ]] sysread -t 0 'buf[$#buf+1]' && continue (( $? == 4 )) || return [[ $buf[-1] == (|$'\x1e') ]] && break @@ -115,6 +116,7 @@ function _p9k_worker_receive() { local buf resp while true; do + [[ -t $_p9k__worker_resp_fd ]] sysread -t 0 -i $_p9k__worker_resp_fd 'buf[$#buf+1]' && continue (( $? == 4 )) || return [[ $buf == (|*$'\x1e')$'\x05'# ]] && break From d9b9aa43833f03987d16130b5c5fb259880869f6 Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 16:22:44 +0100 Subject: [PATCH 03/10] add network bandwidth stats to `ip` segment --- internal/p10k.zsh | 82 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/internal/p10k.zsh b/internal/p10k.zsh index 912a990e..4fc1da58 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -2067,7 +2067,7 @@ _p9k_prompt_detect_virt_init() { # Segment to display the current IP address prompt_ip() { local -i len=$#_p9k__prompt - _p9k_prompt_segment "$0" "cyan" "$_p9k_color1" 'NETWORK_ICON' 1 '$_p9k__ip_ip' '$_p9k__ip_ip' + _p9k_prompt_segment "$0" "cyan" "$_p9k_color1" 'NETWORK_ICON' 1 '$P9K_IP_IP' '$P9K_IP_IP' typeset -g "_p9k__segment_val_${_p9k_prompt_side}[_p9k_segment_index]"=$_p9k__prompt[len+1,-1] } @@ -4540,15 +4540,21 @@ _p9k_preexec2() { function _p9k_prompt_net_iface_init() { typeset -g _p9k__public_ip_vpn= typeset -g _p9k__public_ip_not_vpn= - typeset -g _p9k__ip_ip= + typeset -g P9K_IP_IP= + typeset -g P9K_IP_INTERFACE= + typeset -g P9K_IP_TX_BYTES= + typeset -g P9K_IP_RX_BYTES= + typeset -g P9K_IP_TX_RATE= + typeset -g P9K_IP_RX_RATE= + typeset -g _p9__ip_timestamp= typeset -g _p9k__vpn_ip_ip= [[ -z $_POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE ]] && _p9k__public_ip_not_vpn=1 _p9k__async_segments_compute+=_p9k_prompt_net_iface_compute } -# reads `iface2ip` and sets `ip` +# reads `iface2ip` and sets `iface` and `ip` function _p9k_prompt_net_iface_match() { - local iface_regex="^($1)\$" iface + local iface_regex="^($1)\$" for iface ip in "${(@kv)iface2ip}"; do [[ $iface =~ $iface_regex ]] && return done @@ -4561,13 +4567,13 @@ function _p9k_prompt_net_iface_compute() { function _p9k_prompt_net_iface_async() { local iface ip line var - typeset -A iface2ip + typeset -a iface2ip if [[ -x /sbin/ifconfig ]]; then 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 - iface2ip[$iface]=$match[1] + iface2ip+=($iface $match[1]) iface= fi done @@ -4576,7 +4582,7 @@ function _p9k_prompt_net_iface_async() { if [[ $line == (#b)<->:[[:space:]]##([^:]##):[[:space:]]##\<([^\>]#)\>* ]]; then [[ ,$match[2], == *,UP,* ]] && iface=$match[1] || iface= elif [[ -n $iface && $line == (#b)[[:space:]]##inet[[:space:]]##([0-9.]##)* ]]; then - iface2ip[$iface]=$match[1] + iface2ip+=($iface $match[1]) iface= fi done @@ -4590,9 +4596,40 @@ function _p9k_prompt_net_iface_async() { local public_ip_not_vpn=1 fi if _p9k_prompt_net_iface_match $_POWERLEVEL9K_IP_INTERFACE; then - local ip_ip=$ip + local ip_ip=$ip ip_interface=$iface ip_timestamp=$EPOCHREALTIME + local ip_tx_bytes=0 ip_rx_bytes=0 ip_tx_rate='0 Bps' ip_rx_rate='0 Bps' + if [[ $_p9k_os == (Linux|Android) ]]; then + if [[ -r /sys/class/net/$iface/statistics/rx_bytes ]] && + _p9k_read_file /sys/class/net/$iface/statistics/rx_bytes; then + ip_rx_bytes=$_p9k_ret + fi + if [[ -r /sys/class/net/$iface/statistics/tx_bytes ]] && + _p9k_read_file /sys/class/net/$iface/statistics/tx_bytes; then + ip_tx_bytes=$_p9k_ret + fi + elif [[ $_p9k_os == (BSD|OSX) && $commands[netstat] == 1 ]]; then + local -a ns + if ns="$(netstat -inbI $iface)"; then + for line in ${${(f)ns}:1}; do + (( ip_rx_bytes += ${line[(w)8]} )) + (( ip_tx_bytes += ${line[(w)11]} )) + done + fi + fi + if [[ $ip_ip == $P9K_IP_IP && $iface == $P9K_IP_INTERFACE ]]; then + local -F t='ip_timestamp - _p9__ip_timestamp' + if (( t <= 0 )); then + ip_tx_rate=$P9K_IP_TX_RATE + ip_rx_rate=$P9K_IP_RX_RATE + else + _p9k_human_readable_bytes $((8 * (ip_tx_bytes - P9K_IP_TX_BYTES) / t)) + ip_tx_rate="$_p9k_ret[1,-2] $_p9k_ret[-1]bps" + _p9k_human_readable_bytes $((8 * (ip_rx_bytes - P9K_IP_RX_BYTES) / t)) + ip_rx_rate="$_p9k_ret[1,-2] $_p9k_ret[-1]bps" + fi + fi else - local ip_ip= + local ip_ip= ip_interface= ip_tx_bytes= ip_rx_bytes= ip_tx_rate= ip_rx_rate= ip_timestamp= fi if _p9k_prompt_net_iface_match $_POWERLEVEL9K_VPN_IP_INTERFACE; then local vpn_ip_ip=$ip @@ -4601,13 +4638,34 @@ function _p9k_prompt_net_iface_async() { fi [[ $_p9k__public_ip_vpn == $public_ip_vpn && $_p9k__public_ip_not_vpn == $public_ip_not_vpn && - $_p9k__ip_ip == $ip_ip && + $P9K_IP_IP == $ip_ip && + $P9K_IP_INTERFACE == $ip_interface && + $P9K_IP_TX_BYTES == $ip_tx_bytes && + $P9K_IP_RX_BYTES == $ip_rx_bytes && + $P9K_IP_TX_RATE == $ip_tx_rate && + $P9K_IP_RX_RATE == $ip_rx_rate && $_p9k__vpn_ip_ip == $vpn_ip_ip ]] && return 1 _p9k__public_ip_vpn=$public_ip_vpn _p9k__public_ip_not_vpn=$public_ip_not_vpn - _p9k__ip_ip=$ip_ip + P9K_IP_IP=$ip_ip + P9K_IP_INTERFACE=$ip_interface + P9K_IP_TX_BYTES=$ip_tx_bytes + P9K_IP_RX_BYTES=$ip_rx_bytes + P9K_IP_TX_RATE=$ip_tx_rate + P9K_IP_RX_RATE=$ip_rx_rate + _p9__ip_timestamp=$ip_timestamp _p9k__vpn_ip_ip=$vpn_ip_ip - _p9k_print_params _p9k__public_ip_vpn _p9k__public_ip_not_vpn _p9k__ip_ip _p9k__vpn_ip_ip + _p9k_print_params \ + _p9k__public_ip_vpn \ + _p9k__public_ip_not_vpn \ + P9K_IP_IP \ + P9K_IP_INTERFACE \ + P9K_IP_TX_BYTES \ + P9K_IP_RX_BYTES \ + P9K_IP_TX_RATE \ + P9K_IP_RX_RATE \ + _p9__ip_timestamp \ + _p9k__vpn_ip_ip echo -E - 'reset=1' } From 80015c7c71d0ff8aa2b26655a576b70f3b089025 Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 16:33:46 +0100 Subject: [PATCH 04/10] fix netstat parsing on macos --- internal/p10k.zsh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/internal/p10k.zsh b/internal/p10k.zsh index 4fc1da58..34663187 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -4608,11 +4608,14 @@ function _p9k_prompt_net_iface_async() { ip_tx_bytes=$_p9k_ret fi elif [[ $_p9k_os == (BSD|OSX) && $commands[netstat] == 1 ]]; then - local -a ns - if ns="$(netstat -inbI $iface)"; then - for line in ${${(f)ns}:1}; do - (( ip_rx_bytes += ${line[(w)8]} )) - (( ip_tx_bytes += ${line[(w)11]} )) + local -a lines + if lines=(${(f)"$(netstat -inbI $iface)"}); then + local header=($=lines[1]) + local -i rx_idx=$header[(Ie)Ibytes] + local -i tx_idx=$header[(Ie)Obytes] + for line in ${lines:1}; do + (( ip_rx_bytes += ${line[(w)rx_idx]} )) + (( ip_tx_bytes += ${line[(w)tx_idx]} )) done fi fi From 01cce2c4eb91bbcfa08394b452f88b872df356f5 Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 16:38:09 +0100 Subject: [PATCH 05/10] fix netstat parsing on macos --- internal/p10k.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/p10k.zsh b/internal/p10k.zsh index 34663187..7fe3f237 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -4607,7 +4607,7 @@ function _p9k_prompt_net_iface_async() { _p9k_read_file /sys/class/net/$iface/statistics/tx_bytes; then ip_tx_bytes=$_p9k_ret fi - elif [[ $_p9k_os == (BSD|OSX) && $commands[netstat] == 1 ]]; then + elif [[ $_p9k_os == (BSD|OSX) && $+commands[netstat] == 1 ]]; then local -a lines if lines=(${(f)"$(netstat -inbI $iface)"}); then local header=($=lines[1]) From 75e5712cd036feb13307abdcbca71f634bed1ecd Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 17:26:16 +0100 Subject: [PATCH 06/10] slightly shorter bandwidth display --- internal/p10k.zsh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/p10k.zsh b/internal/p10k.zsh index 7fe3f237..d44417b2 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -4597,7 +4597,7 @@ function _p9k_prompt_net_iface_async() { fi if _p9k_prompt_net_iface_match $_POWERLEVEL9K_IP_INTERFACE; then local ip_ip=$ip ip_interface=$iface ip_timestamp=$EPOCHREALTIME - local ip_tx_bytes=0 ip_rx_bytes=0 ip_tx_rate='0 Bps' ip_rx_rate='0 Bps' + local ip_tx_bytes=0 ip_rx_bytes=0 ip_tx_rate='0 B/s' ip_rx_rate='0 B/s' if [[ $_p9k_os == (Linux|Android) ]]; then if [[ -r /sys/class/net/$iface/statistics/rx_bytes ]] && _p9k_read_file /sys/class/net/$iface/statistics/rx_bytes; then @@ -4625,10 +4625,10 @@ function _p9k_prompt_net_iface_async() { ip_tx_rate=$P9K_IP_TX_RATE ip_rx_rate=$P9K_IP_RX_RATE else - _p9k_human_readable_bytes $((8 * (ip_tx_bytes - P9K_IP_TX_BYTES) / t)) - ip_tx_rate="$_p9k_ret[1,-2] $_p9k_ret[-1]bps" - _p9k_human_readable_bytes $((8 * (ip_rx_bytes - P9K_IP_RX_BYTES) / t)) - ip_rx_rate="$_p9k_ret[1,-2] $_p9k_ret[-1]bps" + _p9k_human_readable_bytes $(((ip_tx_bytes - P9K_IP_TX_BYTES) / t)) + [[ $_p9k_ret == *B ]] && ip_tx_rate="$_p9k_ret[1,-2] B/s" || ip_tx_rate="$_p9k_ret[1,-2] $_p9k_ret[-1]iB/s" + _p9k_human_readable_bytes $(((ip_rx_bytes - P9K_IP_RX_BYTES) / t)) + [[ $_p9k_ret == *B ]] && ip_rx_rate="$_p9k_ret[1,-2] B/s" || ip_rx_rate="$_p9k_ret[1,-2] $_p9k_ret[-1]iB/s" fi fi else From 73e24180a037016ffdddcddd154d962ff6bac247 Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 17:26:28 +0100 Subject: [PATCH 07/10] add `ip` to config templates --- config/p10k-classic.zsh | 25 +++++++++++++++++++++++-- config/p10k-lean-8colors.zsh | 25 +++++++++++++++++++++++-- config/p10k-lean.zsh | 25 +++++++++++++++++++++++-- config/p10k-rainbow.zsh | 26 ++++++++++++++++++++++++-- 4 files changed, 93 insertions(+), 8 deletions(-) diff --git a/config/p10k-classic.zsh b/config/p10k-classic.zsh index 8801de27..f248d005 100644 --- a/config/p10k-classic.zsh +++ b/config/p10k-classic.zsh @@ -90,6 +90,7 @@ # time # current time # =========================[ Line #2 ]========================= newline # \n + # ip # ip address and bandwidth usage for a specified network interface # public_ip # public IP address # proxy # system-wide http/https/ftp proxy # battery # internal battery @@ -1085,12 +1086,32 @@ # When on VPN, show just an icon without the IP address. # Tip: To display the private IP address when on VPN, remove the next line. typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= - # Regular expression for the VPN network interface. Run ifconfig while on VPN to see the - # name of the interface. + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' # Custom icon. # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_FOREGROUND=38 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='%70F⇣$P9K_IP_RX_RATE %215F⇡$P9K_IP_TX_RATE %38F$P9K_IP_IP' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + #########################[ proxy: system-wide http/https/ftp proxy ]########################## # Proxy color. typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68 diff --git a/config/p10k-lean-8colors.zsh b/config/p10k-lean-8colors.zsh index f34d2680..03051490 100644 --- a/config/p10k-lean-8colors.zsh +++ b/config/p10k-lean-8colors.zsh @@ -89,6 +89,7 @@ # time # current time # =========================[ Line #2 ]========================= newline # \n + # ip # ip address and bandwidth usage for a specified network interface # public_ip # public IP address # proxy # system-wide http/https/ftp proxy # battery # internal battery @@ -1064,12 +1065,32 @@ # When on VPN, show just an icon without the IP address. # Tip: To display the private IP address when on VPN, remove the next line. typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= - # Regular expression for the VPN network interface. Run ifconfig while on VPN to see the - # name of the interface. + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' # Custom icon. # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_FOREGROUND=4 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='$P9K_IP_IP %2F⇣$P9K_IP_RX_RATE %3F⇡$P9K_IP_TX_RATE' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + #########################[ proxy: system-wide http/https/ftp proxy ]########################## # Proxy color. typeset -g POWERLEVEL9K_PROXY_FOREGROUND=2 diff --git a/config/p10k-lean.zsh b/config/p10k-lean.zsh index 48bf1e26..81d0d429 100644 --- a/config/p10k-lean.zsh +++ b/config/p10k-lean.zsh @@ -89,6 +89,7 @@ # time # current time # =========================[ Line #2 ]========================= newline + # ip # ip address and bandwidth usage for a specified network interface # public_ip # public IP address # proxy # system-wide http/https/ftp proxy # battery # internal battery @@ -1064,12 +1065,32 @@ # When on VPN, show just an icon without the IP address. # Tip: To display the private IP address when on VPN, remove the next line. typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= - # Regular expression for the VPN network interface. Run ifconfig while on VPN to see the - # name of the interface. + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' # Custom icon. # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_FOREGROUND=38 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='$P9K_IP_IP %70F⇣$P9K_IP_RX_RATE %215F⇡$P9K_IP_TX_RATE' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + #########################[ proxy: system-wide http/https/ftp proxy ]########################## # Proxy color. typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68 diff --git a/config/p10k-rainbow.zsh b/config/p10k-rainbow.zsh index 426973ea..006461e9 100644 --- a/config/p10k-rainbow.zsh +++ b/config/p10k-rainbow.zsh @@ -90,6 +90,7 @@ # time # current time # =========================[ Line #2 ]========================= newline + # ip # ip address and bandwidth usage for a specified network interface # public_ip # public IP address # proxy # system-wide http/https/ftp proxy # battery # internal battery @@ -1127,12 +1128,33 @@ # When on VPN, show just an icon without the IP address. # Tip: To display the private IP address when on VPN, remove the next line. typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= - # Regular expression for the VPN network interface. Run ifconfig while on VPN to see the - # name of the interface. + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' # Custom icon. # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_BACKGROUND=4 + typeset -g POWERLEVEL9K_IP_FOREGROUND=0 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='⇣$P9K_IP_RX_RATE ⇡$P9K_IP_TX_RATE $P9K_IP_IP' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + #########################[ proxy: system-wide http/https/ftp proxy ]########################## # Proxy color. # typeset -g POWERLEVEL9K_PROXY_FOREGROUND=4 From be7e7b3b1583243f2408871c51a3946eafd179bf Mon Sep 17 00:00:00 2001 From: romkatv Date: Wed, 5 Feb 2020 17:51:08 +0100 Subject: [PATCH 08/10] add `ip` to docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7b7c7572..cd04de9d 100644 --- a/README.md +++ b/README.md @@ -298,6 +298,7 @@ enable as many segments as you like. It won't slow down your prompt or Zsh start | `todo` | [todo](https://github.com/todotxt/todo.txt-cli) items | | `timewarrior` | [timewarrior](https://timewarrior.net/) tracking status | | `vpn_ip` | virtual private network indicator | +| `ip` | ip address and bandwidth usage for a specified network interface | | `load` | CPU load | | `disk_usage` | disk usage | | `ram` | free RAM | From a06bbdc1963be2981995ce1feddb1f94800759ae Mon Sep 17 00:00:00 2001 From: David Ward Date: Wed, 5 Feb 2020 15:00:56 -0500 Subject: [PATCH 09/10] respect TIMEWARRIORDB environment variable (#471) Signed-off-by: David Ward --- internal/p10k.zsh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/p10k.zsh b/internal/p10k.zsh index d44417b2..03558340 100644 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -4362,8 +4362,9 @@ function instant_prompt_direnv() { function prompt_timewarrior() { local -a stat + local timewarriordb=${TIMEWARRIORDB:-~/.timewarrior} if [[ -n $_p9k_timewarrior_file_name ]]; then - zstat -A stat +mtime -- ~/.timewarrior/data $_p9k_timewarrior_file_name 2>/dev/null || stat=() + zstat -A stat +mtime -- ${timewarriordb}/data $_p9k_timewarrior_file_name 2>/dev/null || stat=() if [[ $stat[1] == $_p9k_timewarrior_dir_mtime && $stat[2] == $_p9k_timewarrior_file_mtime ]]; then if (( $+_p9k_timewarrior_tags )); then _p9k_prompt_segment $0 grey 255 TIMEWARRIOR_ICON 0 '' "${_p9k_timewarrior_tags//\%/%%}" @@ -4371,7 +4372,7 @@ function prompt_timewarrior() { return fi fi - if [[ ! -d ~/.timewarrior/data ]]; then + if [[ ! -d ${timewarriordb}/data ]]; then _p9k_timewarrior_dir_mtime=0 _p9k_timewarrior_file_mtime=0 _p9k_timewarrior_file_name= @@ -4379,12 +4380,12 @@ function prompt_timewarrior() { return fi if [[ $stat[1] != $_p9k_timewarrior_dir_mtime ]]; then - local -a files=(~/.timewarrior/data/<->-<->.data(.N)) + local -a files=(${timewarriordb}/data/<->-<->.data(.N)) if (( ! $#files )); then - if (( $#stat )) || zstat -A stat +mtime -- ~/.timewarrior/data 2>/dev/null; then + if (( $#stat )) || zstat -A stat +mtime -- ${timewarriordb}/data 2>/dev/null; then _p9k_timewarrior_dir_mtime=$stat[1] _p9k_timewarrior_file_mtime=$stat[1] - _p9k_timewarrior_file_name=~/.timewarrior/data + _p9k_timewarrior_file_name=${timewarriordb}/data else _p9k_timewarrior_dir_mtime=0 _p9k_timewarrior_file_mtime=0 @@ -4395,7 +4396,7 @@ function prompt_timewarrior() { fi _p9k_timewarrior_file_name=${${(AO)files}[1]} fi - if ! zstat -A stat +mtime -- ~/.timewarrior/data $_p9k_timewarrior_file_name 2>/dev/null; then + if ! zstat -A stat +mtime -- ${timewarriordb}/data $_p9k_timewarrior_file_name 2>/dev/null; then _p9k_timewarrior_dir_mtime=0 _p9k_timewarrior_file_mtime=0 _p9k_timewarrior_file_name= From d7168759181d2b80689637b87083bca3e5279935 Mon Sep 17 00:00:00 2001 From: romkatv Date: Thu, 6 Feb 2020 08:44:03 +0100 Subject: [PATCH 10/10] replace terraform icon; several terminals have bugs that prevent them from rendering the current icon correctly --- internal/icons.zsh | 10 +++++----- internal/wizard.zsh | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/internal/icons.zsh b/internal/icons.zsh index 9c672b38..f5f4065b 100644 --- a/internal/icons.zsh +++ b/internal/icons.zsh @@ -115,7 +115,7 @@ function _p9k_init_icons() { RANGER_ICON '\u2B50' # ⭐ MIDNIGHT_COMMANDER_ICON 'mc' VIM_ICON 'vim' - TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + TERRAFORM_ICON 'tf' PROXY_ICON '\u2B82' # ⮂ DOTNET_ICON '.NET' AZURE_ICON '\u2601' # ☁ @@ -228,7 +228,7 @@ function _p9k_init_icons() { RANGER_ICON '\u2B50' # ⭐ MIDNIGHT_COMMANDER_ICON 'mc' VIM_ICON 'vim' - TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + TERRAFORM_ICON 'tf' PROXY_ICON '\u2B82' # ⮂ DOTNET_ICON '.NET' AZURE_ICON '\u2601' # ☁ @@ -345,7 +345,7 @@ function _p9k_init_icons() { RANGER_ICON '\u2B50' # ⭐ MIDNIGHT_COMMANDER_ICON 'mc' VIM_ICON 'vim' - TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + TERRAFORM_ICON 'tf' PROXY_ICON '\u2B82' # ⮂ DOTNET_ICON '.NET' AZURE_ICON '\u2601' # ☁ @@ -459,7 +459,7 @@ function _p9k_init_icons() { RANGER_ICON '\uF00b' #  MIDNIGHT_COMMANDER_ICON 'mc' VIM_ICON '\uE62B' #  - TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + TERRAFORM_ICON '\uF1BB' #  PROXY_ICON '\u2B82' # ⮂ DOTNET_ICON '\uE77F' #  AZURE_ICON '\uFD03' # ﴃ @@ -572,7 +572,7 @@ function _p9k_init_icons() { RANGER_ICON '\u2B50' # ⭐ MIDNIGHT_COMMANDER_ICON 'mc' VIM_ICON 'vim' - TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + TERRAFORM_ICON 'tf' PROXY_ICON '\u2194' # ↔ DOTNET_ICON '.NET' AZURE_ICON '\u2601' # ☁ diff --git a/internal/wizard.zsh b/internal/wizard.zsh index 66150bb0..8162b7c2 100755 --- a/internal/wizard.zsh +++ b/internal/wizard.zsh @@ -1564,8 +1564,6 @@ function generate_config() { if [[ $POWERLEVEL9K_MODE == (compatible|powerline) ]]; then uncomment 'typeset -g POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION' sub DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION "'∅'" - uncomment 'typeset -g POWERLEVEL9K_TERRAFORM_VISUAL_IDENTIFIER_EXPANSION' - sub TERRAFORM_VISUAL_IDENTIFIER_EXPANSION "'tf'" uncomment 'typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION' sub RANGER_VISUAL_IDENTIFIER_EXPANSION "'▲'" uncomment 'typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION'