diff --git a/functions/utilities.zsh b/functions/utilities.zsh index 95f89d9..8c18bb4 100755 --- a/functions/utilities.zsh +++ b/functions/utilities.zsh @@ -373,3 +373,58 @@ function upsearch () { popd > /dev/null fi } + +# Parse IP address from ifconfig on OSX and from IP on Linux +# Parameters: +# $1 - string The desired Interface +# $2 - string A root prefix for testing purposes +function p9k::parseIp() { + local desiredInterface="${1}" + + if [[ -z "${desiredInterface}" ]]; then + desiredInterface="^[^ ]+" + fi + + local ROOT_PREFIX="${2}" + if [[ "$OS" == "OSX" ]]; then + # Get a plain list of all interfaces + local rawInterfaces="$(${ROOT_PREFIX}/sbin/ifconfig -l 2>/dev/null)" + # Parse into array (split by whitespace) + local -a interfaces + interfaces=(${=rawInterfaces}) + # Parse only relevant interface names + local pattern="${desiredInterface}[^ ]?" + local -a relevantInterfaces + for rawInterface in $interfaces; do + [[ "$rawInterface" =~ $pattern ]] && relevantInterfaces+=( $MATCH ) + done + local newline=$'\n' + for interfaceName in $relevantInterfaces; do + local interface="$(${ROOT_PREFIX}/sbin/ifconfig $interfaceName 2>/dev/null)" + if [[ "${interface}" =~ "lo[0-9]*" ]]; then + continue + fi + # Check if interface is UP. + if [[ "${interface//${newline}/}" =~ "<([^>]*)>(.*)inet[ ]+([^ ]*)" ]]; then + local ipFound="${match[3]}" + local -a interfaceStates=(${(s:,:)match[1]}) + if [[ "${interfaceStates[(r)UP]}" == "UP" ]]; then + echo "${ipFound}" + return 0 + fi + fi + done + else + local -a interfaces + interfaces=( "${(f)$(${ROOT_PREFIX}/sbin/ip -brief -4 a show 2>/dev/null)}" ) + local pattern="^${desiredInterface}[ ]+UP[ ]+([^/ ]+)" + for interface in "${(@)interfaces}"; do + if [[ "$interface" =~ $pattern ]]; then + echo "${match[1]}" + return 0 + fi + done + fi + + return 1 +} diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme index 23f2169..f3c8a6b 100755 --- a/powerlevel9k.zsh-theme +++ b/powerlevel9k.zsh-theme @@ -605,7 +605,9 @@ prompt_battery() { # * $1 Alignment: string - left|right # * $2 Index: integer # * $3 Joined: bool - If the segment should be joined +# * $4 Root Prefix: string - Root prefix for testing purposes prompt_public_ip() { + local ROOT_PREFIX="${4}" # set default values for segment set_default POWERLEVEL9K_PUBLIC_IP_TIMEOUT "300" set_default POWERLEVEL9K_PUBLIC_IP_NONE "" @@ -633,7 +635,7 @@ prompt_public_ip() { # grab a fresh IP if needed local fresh_ip - if [[ $refresh_ip =~ true && -w $POWERLEVEL9K_PUBLIC_IP_FILE ]]; then + if [[ $refresh_ip == true && -w $POWERLEVEL9K_PUBLIC_IP_FILE ]]; then for method in "${POWERLEVEL9K_PUBLIC_IP_METHODS[@]}"; do case $method in 'dig') @@ -669,11 +671,10 @@ prompt_public_ip() { icon='PUBLIC_IP_ICON' # Check VPN is on if VPN interface is set if [[ -n $POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE ]]; then - for vpn_iface in $(/sbin/ifconfig | grep -e ^"$POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE" | cut -d":" -f1) - do + local vpnIp="$(p9k::parseIp "${POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE}" "${ROOT_PREFIX}")" + if [[ -n "$vpnIp" ]]; then icon='VPN_ICON' - break - done + fi fi $1_prompt_segment "$0" "$2" "$DEFAULT_COLOR" "$DEFAULT_COLOR_INVERTED" "${public_ip}" "$icon" fi @@ -969,6 +970,8 @@ prompt_dir() { package_path=${$(pwd)%%/.git*} fi + [[ ${(L)POWERLEVEL9K_DIR_PATH_ABSOLUTE} != "true" ]] && package_path=${package_path/$HOME/"~"} + # Replace the shortest possible match of the marked folder from # the current path. Remove the amount of characters up to the # folder marker from the left. Count only the visible characters @@ -1167,31 +1170,8 @@ prompt_icons_test() { ################################################################ # Segment to display the current IP address prompt_ip() { - if [[ "$OS" == "OSX" ]]; then - if defined POWERLEVEL9K_IP_INTERFACE; then - # Get the IP address of the specified interface. - ip=$(ipconfig getifaddr "$POWERLEVEL9K_IP_INTERFACE") - else - local interfaces callback - # Get network interface names ordered by service precedence. - interfaces=$(networksetup -listnetworkserviceorder | grep -o "Device:\s*[a-z0-9]*" | grep -o -E '[a-z0-9]*$') - callback='ipconfig getifaddr $item' - - ip=$(getRelevantItem "$interfaces" "$callback") - fi - else - if defined POWERLEVEL9K_IP_INTERFACE; then - # Get the IP address of the specified interface. - ip=$(ip -4 a show "$POWERLEVEL9K_IP_INTERFACE" | grep -o "inet\s*[0-9.]*" | grep -o -E "[0-9.]+") - else - local interfaces callback - # Get all network interface names that are up - interfaces=$(ip link ls up | grep -o -E ":\s+[a-z0-9]+:" | grep -v "lo" | grep -o -E "[a-z0-9]+") - callback='ip -4 a show $item | grep -o "inet\s*[0-9.]*" | grep -o -E "[0-9.]+"' - - ip=$(getRelevantItem "$interfaces" "$callback") - fi - fi + local ROOT_PREFIX="${4}" + local ip=$(p9k::parseIp "${POWERLEVEL9K_IP_INTERFACE}" "${ROOT_PREFIX}") if [[ -n "$ip" ]]; then "$1_prompt_segment" "$0" "$2" "cyan" "$DEFAULT_COLOR" "$ip" 'NETWORK_ICON' @@ -1203,11 +1183,12 @@ prompt_ip() { set_default POWERLEVEL9K_VPN_IP_INTERFACE "tun" # prompt if vpn active prompt_vpn_ip() { - for vpn_iface in $(/sbin/ifconfig | grep -e "^${POWERLEVEL9K_VPN_IP_INTERFACE}" | cut -d":" -f1) - do - ip=$(/sbin/ifconfig "$vpn_iface" | grep -o "inet\s.*" | cut -d' ' -f2) + local ROOT_PREFIX="${4}" + local ip=$(p9k::parseIp "${POWERLEVEL9K_VPN_IP_INTERFACE}" "${ROOT_PREFIX}") + + if [[ -n "${ip}" ]]; then "$1_prompt_segment" "$0" "$2" "cyan" "$DEFAULT_COLOR" "$ip" 'VPN_ICON' - done + fi } ################################################################