diff --git a/; b/; new file mode 100644 index 00000000..4d6b9e6a --- /dev/null +++ b/; @@ -0,0 +1,3216 @@ +#!/usr/bin/env bash +# set -x +# vim: fdm=marker:noai:ts=4:sw=4 +# +# Neofetch info about your system +# https://github.com/dylanaraps/neofetch +# +# Required Dependencies: +# Bash 3.0+ +# xprop +# [Linux / BSD / Windows] Uptime detection: procps or procps-ng +# +# Optional Dependencies: (You'll lose these features without them) +# Displaying Images: w3m + w3m-img +# Image Cropping: ImageMagick +# Displaying song with Google Play Music: gpmdp-bash +# [ Linux / BSD ] Wallpaper Display: feh, nitrogen or gsettings +# [ Linux / BSD ] Current Song: mpc, cmus, moc +# [ Linux ] Current Song: spotify +# [ Linux / BSD ] Resolution detection: xorg-xdpyinfo +# [ OS X ] Getting screen resolution (faster): screenresolution +# +# Created by Dylan Araps +# https://github.com/dylanaraps/ + +version="${BASH_VERSION/.*}" +SYS_LOCALE="${LANG:-C}" +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-${HOME}/.config}" + +# Speed up script by not using unicode +export LC_ALL=C +export LANG=C + + +# Config Options {{{ + + +# Info Options {{{ + + +# Info +# See this wiki page for more info: +# https://github.com/dylanaraps/neofetch/wiki/Customizing-Info +printinfo () { + info title + info underline + + info "OS" distro + info "Kernel" kernel + info "Uptime" uptime + info "Packages" packages + info "Shell" shell + info "Resolution" resolution + info "DE" de + info "WM" wm + info "WM Theme" wmtheme + info "Theme" theme + info "Icons" icons + info "Font" font + info "CPU" cpu + info "GPU" gpu + info "Memory" memory + + # info "Disk" disk + # info "Battery" battery + # info "Song" song + # info "Local IP" localip + # info "Public IP" publicip + # info "Users" users + # info "Birthday" birthday + + info linebreak + info cols + info linebreak + info linebreak +} + + +# Kernel + +# Show more kernel info +# --kernel_shorthand on/off +kernel_shorthand="on" + + +# Distro + +# Mac OS X hide/show build version +# --osx_buildversion on/off +osx_buildversion="on" + +# Mac OS X hide/show codename +# --osx_codename on/off +osx_codename="on" + +# Show 'x86_64' and 'x86' in 'Distro:' output. +# --os_arch on/off +os_arch="on" + + +# Uptime + +# Shorten the output of the uptime function +# --uptime_shorthand tiny, on, off +uptime_shorthand="off" + + +# Shell + +# Show the path to $SHELL +# --shell_path on/off +shell_path="on" + +# Show $SHELL's version +# --shell_version on/off +shell_version="off" + + +# CPU + +# CPU speed type +# Only works on Linux with cpufreq. +# --speed_type current, min, max, bios, +# scaling_current, scaling_min, scaling_max +speed_type="max" + +# CPU Display +# Set shorthand setting and progress bar setting +# --cpu_display (name, speed, tiny, on, off) (bar, infobar, barinfo, off) +cpu_shorthand="off" +cpu_display="off" + +# CPU Cores +# Display CPU cores in output +# --cpu_cores on/off +cpu_cores="on" + +# GPU + +# Shorten output of the getgpu funcion +# --gpu_shorthand on/off/tiny +gpu_shorthand="on" + +# Resolution + +# Display refresh rate next to each monitor +# Unsupported on Windows +# --refresh_rate on/off +refresh_rate="off" + +# Gtk Theme / Icons + +# Shorten output (Hide [GTK2] etc) +# --gtk_shorthand on/off +gtk_shorthand="off" + + +# Enable/Disable gtk2 theme/icons output +# --gtk2 on/off +gtk2="on" + +# Enable/Disable gtk3 theme/icons output +# --gtk3 on/off +gtk3="on" + + +# Battery + +# Which battery to display. +# By default we display all batteries. +# NOTE: Only works on Linux. +# --battery_num all, 0, 1, 2, etc +battery_num="all" + +# Whether or not to print each battery on the same line. +# By default each battery gets its own line and title. +# NOTE: Only works on Linux. +# --battery_shorthand on/off +battery_shorthand="off" + + +# IP Address + +# Website to ping for the public IP +# --ip_host url +public_ip_host="http://ident.me" + + +# Song + +# Print the Artist and Title on seperate lines +# --song_shorthand on/off +song_shorthand="off" + + +# Birthday + +# Whether to show a long pretty output +# or a shortened one +# NOTE: Long pretty output doesn't work on OpenBSD or NetBSD. +# --birthday_shorthand on/off +birthday_shorthand="off" + +# Whether to show the time in the output +# --birthday_time on/off +birthday_time="on" + +# Date format to use when printing birthday +# --birthday_format "format" +birthday_format="%a %d %b %Y %l:%M %p" + + +# Color Blocks + +# Color block range +# --block_range start end +start=0 +end=7 + +# Toggle color blocks +# --color_blocks on/off +color_blocks="on" + +# Color block width +# --color_block_width num +block_width=3 + + +# }}} + +# Text Colors {{{ + + +# Text Colors +# Each number represents a different part of +# the text in this order: +# title, @, underline, subtitle, colon, info +# colors=(4 6 1 8 8 6) +# You can also specify: +# fg (foreground color) +colors=(distro) + + +# }}} + +# Text Options {{{ + + +# Toggle line wrapping +# --line_wrap on/off +line_wrap="off" + +# Toggle bold text +# --bold on/off +bold="on" + +# Enable/Disable Underline +# --underline on/off +underline_enabled="on" + +# Underline character +# --underline_char char +underline_char="-" + +# Prompt height +# You should only have to change this if your +# prompt is greater than 2 lines high. +# --prompt_height num +prompt_height=1 + + +# }}} + +# Progress Bars {{{ + + +# Progress bar character +# --progress_char elapsed_char total_char +progress_char_elapsed="=" +progress_char_total="-" + +# Progress vorder +# --progress_border on/off +progress_border="on" + +# Progress bar length in spaces +# Number of chars long to make the progress bars. +# --progress_length num +progress_length="15" + +# Progress bar colors +# When set to distro, uses your distro's logo colors +# Takes: num, "distro" +# --progress_colors col col +progress_color_elapsed="distro" +progress_color_total="distro" + +# Customize how the info is displayed. +# bar: Only the progress bar is displayed. +# infobar: The bar is displayed after the info. +# barinfo: The bar is displayed before the info. +# off: Only the info is displayed. +# +# --memory_display bar/infobar/barinfo/off +# --battery_display bar/infobar/barinfo/off +# --disk_display bar/infobar/barinfo/off +memory_display="off" +battery_display="off" +disk_display="off" + + +# }}} + +# Image Options {{{ + + +# Image Source +# --image wall, ascii, /path/to/img, /path/to/dir/, off +image="wall" + +# Thumbnail directory +thumbnail_dir="$HOME/.cache/thumbnails/neofetch" + +# W3m-img path +# This is automatically detected, this variable +# should only be set to w3m-img's location if the +# builtin detection doesn't work. +w3m_img_path="/usr/lib/w3m/w3mimgdisplay" + +# Image position +# Only works with the w3m backend +# --image_position left/right +image_position="left" + +# Crop mode +# --crop_mode normal/fit/fill +crop_mode="normal" + +# Crop offset +# Only affects normal mode. +# --crop_offset northwest/north/northeast/west/center +# east/southwest/south/southeast +crop_offset="center" + +# Image size +# The image is half the terminal width by default. +# --size auto, 00px, 00% +image_size="auto" + +# Right gap between image and text +# --gap num +gap=2 + +# Image offsets +# --xoffset px +# --yoffset px +yoffset=0 +xoffset=0 + + +# }}} + +# Ascii Options {{{ + + +# Default ascii image to use +# When this is set to distro it will use your +# distro's logo as the ascii. +# --ascii 'distro', path/to/ascii +ascii="distro" + +# Ascii colors +# When this is set to distro it will use your +# ditro's colors to color the ascii. +# NOTE: You can also set this to a range of colors +# which will allow you to custom color distro logos +# --ascii_colors distro +# --ascii_colors 2 4 5 6 +ascii_colors=(distro) + +# Logo size +# Arch, Crux and Gentoo have a smaller logo +# variant. Changing the value below to 'small' +# will make neofetch use the small logo. +# --ascii_logo_size small, normal +ascii_logo_size="normal" + + +# }}} + +# Scrot Options {{{ + + +# Whether or not to always take a screenshot +# You can manually take a screenshot with "--scrot" or "-s" +scrot="off" + +# Screenshot program to launch +# --scrot_cmd +scrot_cmd="scrot -c -d 3" + +# Scrot dir +# Where to save the screenshots +# --scrot_dir /path/to/screenshot/folder +scrot_dir="$HOME/Pictures/" + +# Scrot filename +# What to name the screenshots +# --scrot_name str +scrot_name="neofetch-$(date +%F-%T).png" + + +# }}} + +# Stdout options {{{ + +# Separator for stdout mode +# --stdout_separator string +stdout_separator=" " + +# }}} + +# Config Options {{{ + + +# Enable/Disable config file +# --config off, none +config="on" + +# Path to custom config file location +# --config path/to/config +config_file="${XDG_CONFIG_HOME:-${HOME}/.config}/neofetch/config" + + +# }}} + + +# }}} + + +# Gather Info {{{ + + +# Set no case match and extended globbing. +shopt -s nocasematch extglob + + +# Operating System {{{ + +case "$(uname)" in + "Linux") os="Linux" ;; + "Darwin") os="$(sw_vers -productName)" ;; + "OpenBSD") os="OpenBSD" ;; + *"BSD") os="BSD" ;; + "CYGWIN"*) os="Windows" ;; + *) printf "%s\n" "Unknown OS detected: $(uname)"; exit 1 ;; +esac + +# }}} + +# Distro {{{ + +getdistro () { + [ ! -z "$distro" ] && return + + case "$os" in + "Linux" ) + if type -p lsb_release >/dev/null 2>&1; then + distro="$(lsb_release -d 2>/dev/null | awk -F ':' '/Description/ {printf $2}')" + distro=${distro/[[:space:]]} + + elif type -p crux >/dev/null 2>&1; then + distro="$(crux)" + + else + distro="$(awk -F 'NAME=' '/^NAME=/ {printf $2}' /etc/*ease)" + distro=${distro//\"} + + # Workaround for distros that store the value differently. + [ -z "$distro" ] && distro="$(awk -F 'TAILS_PRODUCT_NAME="|"' '/^TAILS_PRODUCT_NAME=/ {printf $2}' /etc/*ease)" + [ -z "$distro" ] && distro="$(awk '/BLAG/ {print $1; exit}' /etc/*ease)" + fi + ;; + + "Mac OS X") + osx_version=$(sw_vers -productVersion) + osx_build=$(sw_vers -buildVersion) + + case "${osx_version%.*}" in + "10.4") codename="Mac OS X Tiger" ;; + "10.5") codename="Mac OS X Leopard" ;; + "10.6") codename="Mac OS X Snow Leopard" ;; + "10.7") codename="Mac OS X Lion" ;; + "10.8") codename="OS X Mountain Lion" ;; + "10.9") codename="OS X Mavericks" ;; + "10.10") codename="OS X Yosemite" ;; + "10.11") codename="OS X El Capitan" ;; + *) codename="Mac OS X" ;; + esac + distro="$codename $osx_version $osx_build" + ;; + + "iPhone OS") + distro="iOS $(sw_vers -productVersion)" + + # "uname -m" doesn't print architecture on iOS so we force it off. + os_arch="off" + ;; + + "OpenBSD") + distro="OpenBSD" + ;; + + "BSD") + distro="$(uname -sr)" + ;; + + "Windows") + distro="$(wmic os get Caption /value)" + + # Strip crap from the output of wmic + distro=${distro/Caption'='} + distro=${distro//[[:space:]]/ } + distro=${distro// } + distro=${distro/Microsoft } + ;; + esac + distro=${distro//+( )/ } + + # Get architecture + [ "$os_arch" == "on" ] && \ + distro+=" $(uname -m)" + + [ "$osx_codename" == "off" ] && \ + distro=${distro/${codename}/Mac OS X} + + [ "$osx_buildversion" == "off" ] && \ + distro=${distro/ ${osx_build}} +} + + +# }}} + +# Title {{{ + +gettitle () { + title="${USER:-$(whoami)}@${HOSTNAME:-$(hostname)}" +} + +# }}} + +# Kernel {{{ + +getkernel() { + case "$kernel_shorthand" in + "on") kernel="$(uname -r)" ;; + "off") kernel="$(uname -srm)" ;; + esac +} + +# }}} + +# Uptime {{{ + +getuptime () { + case "$os" in + "Linux" | "Windows") + case "$distro" in + *"Puppy"* | "Quirky Werewolf"* | "Alpine Linux"* | "Windows"*) + uptime=$(uptime | awk -F ':[0-9]{2}+ |(, ){1}+' '{printf $2}') + ;; + + "openSUSE"*) + uptime=$(uptime | awk -F ':[0-9]{2}+[a-z][a-z] |(, ){1}+' '{printf $2}') + ;; + + *) + uptime="$(uptime -p)" + [ "$uptime" == "up " ] && uptime="up $(awk -F'.' '{print $1}' /proc/uptime) seconds" + ;; + esac + ;; + + "Mac OS X" | "iPhone OS" | *"BSD") + # Get boot time in seconds + boot="$(sysctl -n kern.boottime)" + boot="${boot/'{ sec = '}" + boot=${boot/,*} + + # Get current date in seconds + now=$(date +%s) + uptime=$((now - boot)) + + # Convert uptime to days/hours/mins + minutes=$((uptime / 60%60)) + hours=$((uptime / 3600%24)) + days=$((uptime / 86400)) + + case "$minutes" in + 1) minutes="1 minute" ;; + 0) unset minutes ;; + *) minutes="$minutes minutes" ;; + esac + + case "$hours" in + 1) hours="1 hour" ;; + 0) unset hours ;; + *) hours="$hours hours" ;; + esac + + case "$days" in + 1) days="1 day" ;; + 0) unset days ;; + *) days="$days days" ;; + esac + + [ ! -z "$hours" ] && \ + [ ! -z "$minutes" ] && \ + hours+="," + + [ ! -z "$days" ] && \ + [ ! -z "$hours" ] && \ + days+="," + + uptime="up $days $hours $minutes" + ;; + esac + + # Make the output of uptime smaller. + case "$uptime_shorthand" in + "on") + uptime=${uptime/up } + uptime=${uptime/minutes/mins} + uptime=${uptime/minute/min} + uptime=${uptime/seconds/secs} + uptime=${uptime# } + ;; + + "tiny") + uptime=${uptime/up } + uptime=${uptime/ days/d} + uptime=${uptime/ day/d} + uptime=${uptime/ hours/h} + uptime=${uptime/ hour/h} + uptime=${uptime/ minutes/m} + uptime=${uptime/ minute/m} + uptime=${uptime/ seconds/s} + uptime=${uptime/,} + uptime=${uptime# } + ;; + esac + uptime=${uptime//+( )/ } +} + +# }}} + +# Package Count {{{ + +getpackages () { + case "$os" in + "Linux" | "iPhone OS") + type -p pacman >/dev/null 2>&1 && \ + packages="$(pacman -Qq --color never | wc -l)" + + type -p dpkg >/dev/null 2>&1 && \ + packages=$((packages+=$(dpkg --get-selections | grep -cv deinstall$))) + + type -p /sbin/pkgtool >/dev/null 2>&1 && \ + packages=$((packages+=$(ls -1 /var/log/packages | wc -l))) + + type -p rpm >/dev/null 2>&1 && \ + packages=$((packages+=$(rpm -qa | wc -l))) + + type -p xbps-query >/dev/null 2>&1 && \ + packages=$((packages+=$(xbps-query -l | wc -l))) + + type -p pkginfo >/dev/null 2>&1 && \ + packages=$((packages+=$(pkginfo -i | wc -l))) + + type -p pisi >/dev/null 2>&1 && \ + packages=$((packages+=$(pisi list-installed | wc -l))) + + type -p pkg >/dev/null 2>&1 && \ + packages=$((packages+=$(ls -1 /var/db/pkg | wc -l))) + + type -p emerge >/dev/null 2>&1 && \ + packages=$((packages+=$(ls -d /var/db/pkg/*/* | wc -l))) + + type -p nix-env >/dev/null 2>&1 && \ + packages=$((packages+=$(ls -d -1 /nix/store/*/ | wc -l))) + + type -p apk >/dev/null 2>&1 && \ + packages=$((packages+=$(apk info | wc -l))) + + type -p pacman-g2 >/dev/null 2>&1 && \ + packages=$((packages+=$(pacman-g2 -Q | wc -l))) + + type -p cave >/dev/null 2>&1 && \ + packages=$((packages+=$(ls -d -1 /var/db/paludis/repositories/cross-installed/*/data/* /var/db/paludis/repositories/installed/data/* | wc -l))) + ;; + + "Mac OS X") + [ -d "/usr/local/bin" ] && \ + packages=$(($(ls -l /usr/local/bin/ | grep -v "\(../Cellar/\|brew\)" | wc -l) - 1)) + + type -p port >/dev/null 2>&1 && \ + packages=$((packages + $(port installed 2>/dev/null | wc -l) - 1)) + + type -p brew >/dev/null 2>&1 && \ + packages=$((packages + $(find /usr/local/Cellar -maxdepth 1 2>/dev/null | wc -l) - 1)) + + type -p pkgin >/dev/null 2>&1 && \ + packages=$((packages + $(pkgin list 2>/dev/null | wc -l))) + ;; + + *"BSD") + if type -p pkg_info >/dev/null 2>&1; then + packages=$(pkg_info | wc -l) + + elif type -p pkg >/dev/null 2>&1; then + packages=$(pkg info | wc -l) + fi + ;; + + "Windows") + packages=$(cygcheck -cd | wc -l) + + # Count chocolatey packages + [ -d "/cygdrive/c/ProgramData/chocolatey/lib" ] && \ + packages=$((packages+=$(ls -1 /cygdrive/c/ProgramData/chocolatey/lib | wc -l))) + ;; + esac + packages=${packages// } +} + +# }}} + +# Shell {{{ + +getshell () { + case "$shell_path" in + "on") shell="$SHELL" ;; + "off") shell="${SHELL##*/}" ;; + esac + + if [ "$shell_version" == "on" ]; then + shell+=" " + case "$shell" in + *"bash"*) + shell+="$(bash --version | head -n 1)" + shell=${shell/ *, version} + ;; + + *"zsh"*) + shell+="$(zsh --version)" + shell=${shell/ zsh} + ;; + + *"mksh"* | *"ksh") + shell+="$("$SHELL" -c 'printf "%s" "$KSH_VERSION"')" + shell=${shell/ * KSH} + ;; + + *"tcsh"* | *"csh"*) + shell+="$("$SHELL" --version)" + shell=${shell/tcsh} + shell=${shell/\(*} + ;; + esac + + shell="${shell/\(*\)}" + fi +} + +# }}} + +# Desktop Environment {{{ +getde () { + case "$os" in + "Mac OS X") de="Aqua" ;; + *) + de="${XDG_CURRENT_DESKTOP/i3}" + de=${de/'X-'} + ;; + esac + + if [ -n "$DISPLAY" ] && [ -z "$de" ]; then + de="$(xprop -root | awk '/KDE_SESSION_VERSION|^_MUFFIN|xfce4|xfce5/' 2>/dev/null)" + + case "$de" in + "KDE_SESSION_VERSION"*) de="KDE${de/* = }" ;; + *"TDE_FULL_SESSION"*) de="Trinity" ;; + *"MUFFIN"*) de="Cinnamon" ;; + *"xfce4"*) de="XFCE4" ;; + *"xfce5"*) de="XFCE5" ;; + esac + fi +} + +# }}} + +# Window Manager {{{ + +getwm () { + if [ -n "$DISPLAY" ] && [ "$os" != "Mac OS X" ]; then + id="$(xprop -root -notype | awk '$1=="_NET_SUPPORTING_WM_CHECK:"{print $5}')" + wm="$(xprop -id "$id" -notype -f _NET_WM_NAME 8t)" + wm=${wm/*_NET_WM_NAME = } + wm=${wm/\"} + wm=${wm/\"*} + + # Fallback for Wayland wms + case "$wm" in + "xwlc") + wm="$(ps -e | grep -m 1 -oE "sway|orbment|velox|orbital")" + [ "$version" -ge 4 ] && wm=${wm^} + ;; + esac + + else + case "$os" in + "Mac OS X") wm="Quartz Compositor" ;; + "Windows") wm="Explorer" ;; + esac + fi +} + +# }}} + +# Window Manager Theme {{{ + +getwmtheme () { + [ -z "$wm" ] && getwm + [ -z "$de" ] && getde + + case "$wm" in + 'BudgieWM') wmtheme="$(gsettings get org.gnome.desktop.wm.preferences theme)" ;; + 'E16') wmtheme="$(awk -F "= " '/theme.name/ {print $2}' "$HOME/.e16/e_config--0.0.cfg")";; + 'Sawfish') wmtheme="$(awk -F ")" '/\(quote default-frame-style/ {print $2}' "$HOME/.sawfish/custom")" ;; + + 'Cinnamon' | 'Muffin' | 'Mutter (Muffin)') + detheme="$(gsettings get org.cinnamon.theme name)" + wmtheme="$(gsettings get org.cinnamon.desktop.wm.preferences theme)" + wmtheme="$detheme (${wmtheme})" + ;; + + 'Compiz' | 'Mutter'* | 'GNOME Shell' | 'Gala') + if type -p gsettings >/dev/null 2>&1; then + wmtheme="$(gsettings get org.gnome.desktop.wm.preferences theme)" + + elif type -p gconftool-2 >/dev/null 2>&1; then + wmtheme="$(gconftool-2 -g /apps/metacity/general/theme)" + fi + ;; + + 'Metacity'*) + if [ "$de" == "Deepin" ]; then + wmtheme="$(gsettings get com.deepin.wrap.gnome.desktop.wm.preferences theme 2>/dev/null)" + + else + wmtheme="$(gconftool-2 -g /apps/metacity/general/theme 2>/dev/null)" + fi + ;; + + 'E17' | 'Enlightenment') + if type -p eet >/dev/null 2>&1; then + wmtheme="$(eet -d $HOME/.e/e/config/standard/e.cfg config | awk '/value \"file\" string.*.edj/ {print $4}')" + wmtheme=${wmtheme##*/} + wmtheme=${wmtheme%.*} + fi + ;; + + 'Fluxbox') + [ -f $HOME/.fluxbox/init ] && \ + wmtheme="$(awk -F "/" '/styleFile/ {print $NF}' "$HOME/.fluxbox/init")" + ;; + + 'IceWM'*) + [ -f $HOME/.icewm/theme ] && \ + wmtheme="$(awk -F "[\",/]" '!/#/ {print $2}' "$HOME/.icewm/theme")" + ;; + + 'Openbox') + if [ "$de" == "LXDE" ] && [ -f "${HOME}/.config/openbox/lxde-rc.xml" ]; then + ob_file="lxde-rc" + + elif [ -f "${HOME}/.config/openbox/rc.xml" ]; then + ob_file="rc" + fi + + wmtheme="$(awk -F "[<,>]" '//dev/null)" + wmtheme="${wmtheme##*\\}" + wmtheme="${wmtheme%.*}" + wmtheme="${wmtheme^}" + ;; + + esac + + wmtheme="${wmtheme//\'}" + [ "$version" -ge 4 ] && wmtheme=${wmtheme^} +} + +# }}} + +# CPU {{{ + +getcpu () { + case "$os" in + "Mac OS X") + cpu="$(sysctl -n machdep.cpu.brand_string)" + cores=$(sysctl -n hw.ncpu) + ;; + + "iPhone OS") + ios_model=${ios_model:-$(uname -m)} + case "$ios_model" in + "iPhone1,1" | "iPhone1,2" | "iPod1,1") + cpu="Samsung S5L8900 @ 412MHz" + cores="1" + ;; + + "iPhone2,1") + cpu="Samsung S5PC100 @ 600MHz" + cores="1" + ;; + + "iPhone3,1" | "iPhone3,2" | "iPhone3,3" | "iPod4,1") + cpu="Apple A4 @ 800MHz" + cores="1" + ;; + + "iPhone4,1" | "iPod5,1") + cpu="Apple A5 @ 800MHz" + cores="2" + ;; + + "iPhone5,1" | "iPhone5,2" | "iPhone5,3" | "iPhone5,4") + cpu="Apple A6 @ 1.3GHz" + cores="2" + ;; + + "iPhone6,1" | "iPhone6,2") + cpu="Apple A7 @ 1.3GHz" + cores="2" + ;; + + "iPhone7,1" | "iPhone7,2") + cpu="Apple A8 @ 1.4GHz" + cores="2" + ;; + + "iPhone8,1" | "iPhone8,2" | "iPhone8,4") + cpu="Apple A9 @ 1.85GHz" + cores="2" + ;; + + "iPod2,1") + cpu="Samsung S5L8720 @ 533MHz" + cores="1" + ;; + + "iPod3,1") + cpu="Samsung S5L8922 @ 600MHz" + cores="1" + ;; + + "iPod7,1") + cpu="Apple A8 @ 1.1GHz" + cores="2" + ;; + + "iPad1,1") + cpu="Apple A4 @ 1GHz" + cores="1" + ;; + + "iPad2,1" | "iPad2,2" | "iPad2,3" | "iPad2,4" | "iPad2,5" | "iPad2,6" | "iPad2,7") + cpu="Apple A5 @ 1GHz" + cores="2" + ;; + + "iPad3,1" | "iPad3,2" | "iPad3,3") + cpu="Apple A5X @ 1GHz" + cores="2" + ;; + + "iPad3,4" | "iPad3,5" | "iPad3,6") + cpu="Apple A6X @ 1.4GHz" + cores="2" + ;; + + "iPad4,1" | "iPad4,2" | "iPad4,3") + cpu="Apple A7 @ 1.4GHz" + cores="2" + ;; + + "iPad4,4" | "iPad4,5" | "iPad4,6" | "iPad4,7" | "iPad4,8" | "iPad4,9") + cpu="Apple A7 @ 1.4GHz" + cores="2" + ;; + + "iPad5,1" | "iPad5,2") + cpu="Apple A8 @ 1.5GHz" + cores="2" + ;; + + "iPad5,3" | "iPad5,4") + cpu="Apple A8X @ 1.5GHz" + cores="3" + ;; + + "iPad6,3" | "iPad6,4") + cpu="Apple A9X @ 2.16GHz" + cores="2" + ;; + + "iPad6,7" | "iPad6,8") + cpu="Apple A9X @ 2.26GHz" + cores="2" + ;; + esac + ;; + + *) + case "$distro" in + "OpenBSD"* | "FreeBSD"*) + # Get cpu name + cpu="$(sysctl -n hw.model)" + cpu=${cpu/[0-9]\.*} + cpu=${cpu/ @*} + + # Get cpu speed + case "$distro" in + "OpenBSD"*) speed=$(sysctl -n hw.cpuspeed) ;; + "FreeBSD"*) speed=$(sysctl -n hw.clockrate) ;; + esac + speed=$((speed / 100)) + cores=$(sysctl -n hw.ncpu) + ;; + + *) + # Get cpu name + cpu="$(awk -F ': | @' '/model name/ {printf $2; exit}' /proc/cpuinfo)" + + # Get cpu speed + if [ -d "/sys/devices/system/cpu/cpu0/cpufreq" ]; then + case "$speed_type" in + current) speed_type="scaling_cur_freq" ;; + min) speed_type="scaling_min_freq" ;; + max) speed_type="scaling_max_freq" ;; + bios) speed_type="bios_limit" ;; + scaling_current) speed_type="scaling_cur_freq" ;; + scaling_min) speed_type="scaling_min_freq" ;; + scaling_max) speed_type="scaling_max_freq" ;; + esac + + read -t 1 -r speed < \ + /sys/devices/system/cpu/cpu0/cpufreq/${speed_type} + + speed=$((speed / 100000)) + else + speed=$(awk -F ': |\\.' '/cpu MHz/ {printf $2; exit}' /proc/cpuinfo) + speed=$((speed / 100)) + fi + + cores=$(awk -F ': ' '/siblings/ {printf $2; exit}' /proc/cpuinfo) + ;; + esac + + # Fix for speeds under 1ghz + if [ -z "${speed:1}" ]; then + speed="0.${speed}" + else + speed=${speed:0:1}.${speed:1} + fi + + cpu="$cpu @ ${speed}GHz" + ;; + esac + + # Remove uneeded patterns from cpu output + # This is faster than sed/gsub + cpu=${cpu//(tm)} + cpu=${cpu//(TM)} + cpu=${cpu//(r)} + cpu=${cpu//(R)} + cpu=${cpu//CPU} + cpu=${cpu//Processor} + cpu=${cpu//Six-Core} + cpu=${cpu//Eight-Core} + cpu=${cpu/Dual-Core} + cpu=${cpu/Quad-Core} + cpu=${cpu//with Radeon HD Graphics} + + # Add cpu cores to output + [ "$cpu_cores" == "on" ] && [ ! -z "$cores" ] && \ + cpu=${cpu/@/\(${cores}\) @} + + # Make the output of cpu shorter + case "$cpu_shorthand" in + "name") + cpu=${cpu/@*} + ;; + + "speed") + cpu=${cpu#*@ } + ;; + + "on" | "tiny") + cpu=${cpu/Intel } + cpu=${cpu/Core } + cpu=${cpu/Core? Duo } + cpu=${cpu/AMD } + + case "$cpu_shorthand" in + "tiny") cpu=${cpu/@*} ;; + esac + ;; + esac + + # Trim whitespace + cpu=${cpu//+( )/ } + + [ ! -z "$cpu" ] && prin "$subtitle" "$cpu" + + if [ "$cpu_display" != "off" ]; then + cpu_usage="$(ps aux | awk 'BEGIN { sum = 0 } { sum += $3 }; END { print sum }')" + cpu_usage="${cpu_usage/\.*}%" + + case "$cpu_display" in + "info") prin "$subtitle Usage" "$cpu_usage" ;; + "bar") prin "$subtitle Usage" "$(bar "${cpu_usage/'%'}" $(( 100 * cores )))" ;; + "infobar") prin "$subtitle Usage" "${cpu_usage} $(bar "${cpu_usage/'%'}" $(( 100 * cores )))" ;; + "barinfo") prin "$subtitle Usage" "$(bar "${cpu_usage/'%'}" $(( 100 * cores ))) $cpu_usage" ;; + esac + fi + [ "$stdout_mode" != "on" ] && unset cpu +} + +# }}} + +# GPU {{{ + +getgpu () { + case "$os" in + "Linux") + gpu="$(PATH="/sbin:$PATH" lspci | grep -F "3D")" + + # If a GPU with a prefix of '3D' doesn't exist + # fallback to looking for a prefix of 'VGA' + [ -z "$gpu" ] && \ + gpu="$(PATH="/sbin:$PATH" lspci | grep -F "VGA")" + + gpu=${gpu//??':'??'.'?} + + # Count the number of GPUs + count="$(printf "%s" "$gpu" | uniq -c)" + count=${count/ VGA*} + count=${count/ 3D*} + count=${count//[[:space:]]} + + # If there's more than one gpu + # Display the count. + if [ "$count" -gt 1 ]; then + count=" x $count" + else + unset count + fi + + # Format the output + gpu=${gpu/* VGA compatible controller: } + gpu=${gpu/* 3D controller: } + gpu=${gpu/(rev*)} + + case "$gpu" in + intel*) + gpu="Intel Integrated Graphics" + ;; + + advanced*) + gpu=${gpu/Advanced Micro Devices, Inc\. } + gpu=${gpu/'[AMD/ATI]' } + gpu=${gpu/Tahiti PRO} + gpu=${gpu/Seymour} + gpu=${gpu/Cayman} + gpu=${gpu/Richland} + gpu=${gpu/Pitcairn} + gpu=${gpu/Broadway} + gpu=${gpu/XTMobility} + gpu=${gpu/Mobility} + gpu=${gpu/Hawaii} + gpu=${gpu/Tobago} + gpu=${gpu/Thames} + gpu=${gpu/Kabini} + gpu=${gpu/Bonaire} + gpu=${gpu/XTX} + gpu=${gpu/ OEM} + gpu=${gpu/ Cape Verde} + gpu=${gpu/ \[} + gpu=${gpu/\]} + + brand="AMD " + ;; + + nvidia*) + gpu=${gpu/NVIDIA Corporation } + gpu=${gpu/G????M } + gpu=${gpu/G???? } + gpu=${gpu/\[} + gpu=${gpu/\] } + + brand="NVIDIA " + ;; + + *virtualbox*) + gpu="VirtualBox Graphics Adapter" + ;; + esac + + gpu="${brand}${gpu}" + ;; + + "Mac OS X") + # Use cache if it exists + if [ -f "/Library/Caches/neofetch/gpu" ]; then + source "/Library/Caches/neofetch/gpu" + else + gpu=$(system_profiler SPDisplaysDataType | awk -F': ' '/^\ *Chipset Model:/ {printf $2 ", "}') + gpu=${gpu//'/ $'} + gpu=${gpu%,*} + cache "gpu" "$gpu" "/Library/Caches/" + fi + ;; + + "iPhone OS") + ios_model=${ios_model:-$(uname -m)} + case "$ios_model" in + "iPhone1,1" | "iPhone1,2") + gpu="PowerVR MBX Lite 3D" + ;; + + "iPhone2,1" | "iPhone3,1" | "iPhone3,2" | "iPhone3,3" | "iPod3,1" | "iPod4,1" | "iPad1,1") + gpu="PowerVR SGX535" + ;; + + "iPhone4,1" | "iPad2,1" | "iPad2,2" | "iPad2,3" | "iPad2,4" | "iPad2,5" | "iPad2,6" | "iPad2,7" | "iPod5,1") + gpu="PowerVR SGX543MP2" + ;; + + "iPhone5,1" | "iPhone5,2" | "iPhone5,3" | "iPhone5,4") + gpu="PowerVR SGX543MP3" + ;; + + "iPhone6,1" | "iPhone6,2" | "iPad4,1" | "iPad4,2" | "iPad4,3" | "iPad4,4" | "iPad4,5" | "iPad4,6" | "iPad4,7" | "iPad4,8" | "iPad4,9") + gpu="PowerVR G6430" + ;; + + "iPhone7,1" | "iPhone7,2" | "iPod7,1" | "iPad5,1" | "iPad5,2") + gpu="PowerVR GX6450" + ;; + + "iPhone8,1" | "iPhone8,2" | "iPhone8,4") + gpu="PowerVR GT7600" + ;; + + "iPod1,1" | "iPod2,1") + gpu="PowerVR MBX Lite" + ;; + + "iPad3,1" | "iPad3,2" | "iPad3,3") + gpu="PowerVR SGX534MP4" + ;; + + "iPad3,4" | "iPad3,5" | "iPad3,6") + gpu="PowerVR SGX554MP4" + ;; + + "iPad5,3" | "iPad5,4") + gpu="PowerVR GXA6850" + ;; + + "iPad6,3" | "iPad6,4" | "iPad6,7" | "iPad6,8") + gpu="PowerVR 7XT" + ;; + esac + ;; + + *"BSD") + case "$distro" in + "FreeBSD"*) + gpu=$(pciconf -lv 2>/dev/null | grep -B 4 "VGA" | grep "device") + gpu=${gpu/device*= } + gpu=${gpu//\'} + ;; + + *) + gpu=$(glxinfo | grep -F 'OpenGL renderer string') + gpu=${gpu/'OpenGL renderer string: '} + ;; + esac + ;; + + + "Windows") + gpu=$(wmic path Win32_VideoController get caption /value) + gpu=${gpu/Caption'='} + gpu=${gpu//[[:space:]]/ } + gpu=${gpu// } + ;; + esac + + case "$gpu_shorthand" in + "on" | "tiny") + gpu=${gpu// Rev\. ?} + gpu=${gpu//AMD*\/ATI\]/AMD} + gpu=${gpu// Tahiti} + gpu=${gpu// PRO} + gpu=${gpu// OEM} + gpu=${gpu// Mars} + gpu=${gpu// Series} + gpu=${gpu// Controller} + gpu=${gpu/\/*} + + case "$gpu_shorthand" in + "tiny") + gpu=${gpu/Graphics } + gpu=${gpu/GeForce } + gpu=${gpu/Radeon } + ;; + esac + ;; + esac + + gpu=${gpu//+( )/ } + gpu="${gpu}${count}" +} + +# }}} + +# Memory {{{ + +getmemory () { + case "$os" in + "Linux" | "Windows") + if [ ! -z "$(grep -F "MemAvail" /proc/meminfo)" ]; then + mem=($(awk -F ':| kB' '/MemTotal|MemAvail/ {printf $2}' /proc/meminfo)) + memused=$((mem[0] - mem[1])) + else + mem=($(awk -F ':| kB' '/MemTotal|MemFree|Buffers|Cached/ {printf $2}' /proc/meminfo) 0 0) + memused=$((mem[0] - mem[1] - mem[2] - mem[3])) + fi + + memused=$((memused / 1024)) + memtotal=$((mem[0] / 1024)) + ;; + + "Mac OS X" | "iPhone OS") + memtotal=$(printf "%s\n" "$(sysctl -n hw.memsize)"/1024^2 | bc) + memwired=$(vm_stat | awk '/wired/ { print $4 }') + memactive=$(vm_stat | awk '/active / { printf $3 }') + memcompressed=$(vm_stat | awk '/occupied/ { printf $5 }') + memused=$(((${memwired//.} + ${memactive//.} + ${memcompressed//.}) * 4 / 1024)) + ;; + + "OpenBSD" | "BSD") + case "$distro" in + "OpenBSD"*) + mem=($(top -d 1 | awk -F ': |/| |M' '/Memory:/ {printf $4 " " $6 " " $11 "\n"}')) + memtotal=$((${mem[1]} + ${mem[2]})) + memused=$((memtotal - ${mem[0]})) + ;; + + "FreeBSD"*) + memtotal=$(dmesg | awk '/real mem/ {printf $5}') + memtotal=${memtotal/\(} + memtotal=${memtotal/MB\)} + memfree=$(top -d 1 | awk '/Mem:/ {printf $10}') + memfree=${memfree/M} + memused=$((memtotal - memfree)) + ;; + + "NetBSD"*) + memfree=$(($(vmstat | awk 'END{printf $4}') / 1000)) + memused=$(($(vmstat | awk 'END{printf $3}') / 1000)) + memtotal=$((memused + memfree)) + memused=$((memtotal - memfree)) + ;; + esac + + ;; + esac + memory="${memused}MB / ${memtotal}MB" + + # Progress bars + case "$memory_display" in + "bar") memory="$(bar "${memused}" "${memtotal}")" ;; + "infobar") memory="${memory} $(bar "${memused}" "${memtotal}")" ;; + "barinfo") memory="$(bar "${memused}" "${memtotal}") ${memory}" ;; + esac +} + +# }}} + +# Song {{{ + +getsong () { + if mpc version >/dev/null 2>&1; then + song="$(mpc current 2>/dev/null)" + state=$(mpc | awk -F '\\[|\\]' '/\[/ {printf $2}' 2>/dev/null) + + elif [ -n "$(ps x | awk '!(/awk/) && /cmus/')" ]; then + song="$(cmus-remote -Q | grep "tag artist\|title" 2>/dev/null)" + song=${song/tag artist } + song=${song/tag title/-} + song=${song//[[:space:]]/ } + state=$(cmus-remote -Q | awk -F ' ' '/status/ {printf $2}' 2>/dev/null) + + elif pgrep "mocp" >/dev/null 2>&1; then + song="$(mocp -Q "%artist - %song" 2>/dev/null)" + state="$(mocp -Q "%state" 2>/dev/null)" + + elif [ -n "$(ps x | awk '!(/awk/) && /spotify/')" ]; then + case "$os" in + "Linux") + # This command is way too long + song="$(\ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 \ + org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata' |\ + awk -F 'string "' '/string|array/ {printf "%s",$2; next}{print ""}' |\ + awk -F '"' '/artist|title/ {printf $2 " - "}' + )" + song=${song% - } + song=${song/'('*} + song=${song//'['*} + ;; + + "Mac OS X") + song="$(osascript -e 'tell application "Spotify" to artist of current track as string & " - " & name of current track as string')" + state="$(osascript -e 'tell application "Spotify" to player state as string')" + ;; + esac + + elif [ -n "$(ps x | awk '!(/awk/ || /Helper/) && /Google Play Music Desktop Player/')" ] && type -p gpmdp >/dev/null 2>&1; then + song="$(gpmdp current)" + state="$(gpmdp status)" + + elif [ -n "$(ps x | awk '!(/awk/ || /Helper/) && /iTunes/')" ]; then + song="$(osascript -e 'tell application "iTunes" to artist of current track as string & " - " name of current track as string')" + state="$(osascript -e 'tell application "iTunes" to player state as string')" + + else + song="Not Playing" + fi + + case "$state" in + "paused" | "PAUSE") + song="Paused" + ;; + + "stopped" | "STOP") + song="Stopped" + ;; + esac + + # Display Artist and Title on seperate lines. + if [ "$song_shorthand" == "on" ] && [ "$stdout_mode" != "on" ]; then + artist="${song/ -*}" + song=${song/$artist - } + + if [ "$song" != "$artist" ]; then + prin "Artist" "$artist" + prin "Song" "$song" + else + prin "$subtitle" "$song" + fi + unset song + fi +} + +# }}} + +# Resolution {{{ + +getresolution () { + case "$os" in + "Linux" | *"BSD") + if type -p xrandr >/dev/null 2>&1; then + case "$refresh_rate" in + "on") resolution=$(xrandr --nograb --current | awk 'match($0,/[0-9]{2,3}.[0-9]{2}\*/) {printf $1 " @ " substr($0,RSTART,RLENGTH) "Hz, "}') ;; + "off") resolution=$(xrandr --nograb --current | awk '/*/ {printf $1 ", "}') ;; + esac + resolution=${resolution//\*} + + elif type -p xdpyinfo >/dev/null 2>&1; then + resolution=$(xdpyinfo 2>/dev/null | awk '/dimensions:/ {printf $2}') + fi + ;; + + "Mac OS X") + if type -p screenresolution >/dev/null 2>&1; then + resolution=$(screenresolution get 2>&1 | awk '/Display/ {printf $6 "Hz, "}') + resolution=${resolution//x??@/ @ } + + else + resolution=$(system_profiler SPDisplaysDataType |\ + awk '/Resolution:/ {printf $2"x"$4" @ "$6"Hz, "}') + fi + + [[ "$refresh_rate" == "off" ]] && \ + resolution=${resolution// @ *([0-9])Hz} + ;; + + "Windows") + width=$(wmic desktopmonitor get screenwidth /value 2>/dev/null) + width=${width/ScreenWidth'='/} + width=${width//[[:space:]]} + + height=$(wmic desktopmonitor get screenheight /value 2>/dev/null) + height=${height/ScreenHeight'='/} + height=${height//[[:space:]]} + + [ ! -z "$width" ] && \ + resolution="${width}x${height}" + ;; + esac + + resolution=${resolution%,*} +} + +# }}} + +# Theme/Icons/Font {{{ + +getstyle () { + # Fix weird output when the function + # is run multiple times. + unset gtk2theme gtk3theme theme path + + case "$1" in + theme) + name="gtk-theme-name" + gsettings="gtk-theme" + gconf="gtk_theme" + xfconf="ThemeName" + kde="widgetStyle" + ;; + + icons) + name="gtk-icon-theme-name" + gsettings="icon-theme" + gconf="icon_theme" + xfconf="IconThemeName" + kde="Theme" + ;; + + font) + name="gtk-font-name" + gsettings="font-name" + gconf="font_theme" + xfconf="FontName" + kde="font" + ;; + esac + + if [ -n "$DISPLAY" ] && [ "$os" != "Mac OS X" ]; then + # Get DE if user has disabled the function. + [ -z "$de" ] && getde + + case "$de" in + "KDE"*) + kdeconfigdir + + if [ -f "${kde_config_dir}/share/config/kdeglobals" ]; then + kde_config_file="${kde_config_dir}/share/config/kdeglobals" + + theme=$(grep "^[^#]*$kde" "$kde_config_file") + theme=${theme/${kde}*=} + [ "$version" -ge 4 ] && theme=${theme^} + + gtk_shorthand="on" + return + fi + ;; + + *"Cinnamon") + if type -p gsettings >/dev/null 2>&1; then + gtk3theme=$(gsettings get org.cinnamon.desktop.interface $gsettings) + gtk3theme=${gtk3theme//"'"} + gtk2theme=${gtk3theme} + fi + ;; + + "Gnome"* | "Unity"* | "Budgie") + if type -p gsettings >/dev/null 2>&1; then + gtk3theme=$(gsettings get org.gnome.desktop.interface $gsettings) + gtk3theme=${gtk3theme//"'"} + gtk2theme=${gtk3theme} + + elif type -p gconftool-2 >/dev/null 2>&1; then + gtk2theme=$(gconftool-2 -g /desktop/gnome/interface/$gconf) + fi + ;; + + "Mate"*) + gtk3theme=$(gsettings get org.mate.interface $gsettings) + gtk2theme=${gtk3theme} + ;; + + "Xfce"*) + type -p xfconf-query >/dev/null 2>&1 && \ + gtk2theme=$(xfconf-query -c xsettings -p /Net/$xfconf) + ;; + esac + + # Check for gtk2 theme + if [ -z "$gtk2theme" ]; then + if [ -f "${GTK2_RC_FILES:-$HOME/.gtkrc-2.0}" ]; then + gtk2theme=$(grep "^[^#]*$name" "${GTK2_RC_FILES:-$HOME/.gtkrc-2.0}") + + elif [ -f "/usr/share/gtk-2.0/gtkrc" ]; then + gtk2theme=$(grep "^[^#]*$name" /usr/share/gtk-2.0/gtkrc) + + elif [ -f "/etc/gtk-2.0/gtkrc" ]; then + gtk2theme=$(grep "^[^#]*$name" /etc/gtk-2.0/gtkrc) + fi + + gtk2theme=${gtk2theme/${name}*=} + gtk2theme=${gtk2theme//\"} + fi + + # Check for gtk3 theme + if [ -z "$gtk3theme" ]; then + if [ -f "$XDG_CONFIG_HOME/gtk-3.0/settings.ini" ]; then + gtk3theme=$(grep "^[^#]*$name" "$XDG_CONFIG_HOME/gtk-3.0/settings.ini") + + elif type -p gsettings >/dev/null 2>&1; then + gtk3theme="$(gsettings get org.gnome.desktop.interface $gsettings)" + gtk3theme=${gtk3theme//\'} + + elif [ -f "/usr/share/gtk-3.0/settings.ini" ]; then + gtk3theme=$(grep "^[^#]*$name" /usr/share/gtk-3.0/settings.ini) + + elif [ -f "/etc/gtk-3.0/settings.ini" ]; then + gtk3theme=$(grep "^[^#]*$name" /etc/gtk-3.0/settings.ini) + fi + + gtk3theme=${gtk3theme/${name}*=} + gtk3theme=${gtk3theme//\"} + gtk3theme=${gtk3theme/[[:space:]]/ } + fi + + # Uppercase the first letter of each gtk theme + if [ "$version" -ge 4 ]; then + gtk2theme=${gtk2theme^} + gtk3theme=${gtk3theme^} + fi + + # Toggle visibility of gtk themes. + [ "$gtk2" == "off" ] && unset gtk2theme + [ "$gtk3" == "off" ] && unset gtk3theme + + # Format the string based on which themes exist + if [ "$gtk2theme" ] && [ "$gtk2theme" == "$gtk3theme" ]; then + gtk3theme+=" [GTK2/3]" + unset gtk2theme + + elif [ "$gtk2theme" ] && [ "$gtk3theme" ]; then + gtk2theme+=" [GTK2], " + gtk3theme+=" [GTK3] " + else + [ "$gtk2theme" ] && gtk2theme+=" [GTK2] " + [ "$gtk3theme" ] && gtk3theme+=" [GTK3] " + fi + + # Final string + theme="${gtk2theme}${gtk3theme}" + theme=${theme//\"} + theme=${theme//\'} + + # Make the output shorter by removing "[GTKX]" from the string + if [ "$gtk_shorthand" == "on" ]; then + theme=${theme/ '[GTK2]'} + theme=${theme/ '[GTK3]'} + theme=${theme/ '[GTK2/3]'} + fi + fi +} + +gettheme () { + getstyle theme +} + +geticons () { + getstyle icons + icons="$theme" +} + +getfont () { + getstyle font + font="$theme" +} + +# }}} + +# Disk Usage {{{ + +getdisk () { + # df flags + case "$os" in + "Linux" | "iPhone OS" | "Windows") df_flags="-h -l --total" ;; + "Mac OS X") df_flags="-H / -l" ;; + + *"BSD") + case "$distro" in + "FreeBSD"*) df_flags="-h -c -l" ;; + *) return ;; + esac + ;; + esac + + # Get the disk info + disk=$(df $df_flags 2>/dev/null | awk 'END{print $2 ":" $3 ":" $5}') + + # Format the output + disk_used=${disk#*:} + disk_used=${disk_used%%:*} + disk_total=${disk%%:*} + disk_total_per=${disk#*:*:} + + # Put it all together + disk="${disk_used} / ${disk_total} (${disk_total_per})" + + # Add info bar + disk_used=${disk_used/G} + disk_total=${disk_total/G} + + [[ "$disk_used" == *"T" ]] && \ + disk_used=$(printf "%s\n" "${disk_used/T} * 1000" | bc) + + [[ "$disk_total" == *"T" ]] && \ + disk_total=$(printf "%s\n" "${disk_total/T} * 1000" | bc) + + case "$disk_display" in + "bar") disk="$(bar "${disk_used/'.'*}" "${disk_total/'.'*}")" ;; + "infobar") disk+=" $(bar "${disk_used/'.'*}" "${disk_total/'.'*}")" ;; + "barinfo") disk="$(bar "${disk_used/'.'*}" "${disk_total/'.'*}") $disk" ;; + "perc") disk="$disk_total_per $(bar "${disk_used/'.'*}" "${disk_total/'.'*}")" ;; + esac +} + +# }}} + +# Battery Usage {{{ + +getbattery () { + case "$os" in + "Linux") + if [ "$(ls /sys/class/power_supply/)" ]; then + # Set the index to the battery number. + case "$battery_num" in + "all") battery_num="*" index=0 ;; + *) index="$battery_num" ;; + esac + + batteries=($(cat /sys/class/power_supply/BAT${battery_num}/capacity)) + battery_state=($(cat /sys/class/power_supply/BAT${battery_num}/status)) + + # Get the subtitle and reassign it so it doesn't change. + title="$subtitle" + + # If shorthand is on, print each value on the same line + if [ "$battery_shorthand" == "on" ] || [ "$stdout_mode" == "on" ]; then + battery=${batteries[*]} + battery=${battery// /%, } + battery="${battery}%" + + else + if [ "${#batteries[@]}" -gt 1 ]; then + unset battery + + # Print each battery on a separate line. + index=0 + for bat in "${batteries[@]}"; do + case "$battery_display" in + "bar") prin "${title}${index}" "$(bar ${bat/'%'} 100)" ;; + "infobar") prin "${title}${index}" "${bat}% $(bar "${bat/'%'}" 100)" ;; + "barinfo") prin "${title}${index}" "$(bar "${bat/'%'}" 100) ${bat}%" ;; + *) prin "${title}${index}" "${bat}%" ;; + esac + index=$((index + 1)) + done + return + fi + battery="${batteries[0]}%" + fi + fi + ;; + + "BSD") + case "$distro" in + "FreeBSD"*) + battery=$(acpiconf -i 0 | awk -F ':\t' '/Remaining capacity/ {print $2}') + battery_state=$(acpiconf -i 0 | awk -F ':\t\t\t' '/State/ {print $2}') + ;; + + "NetBSD"*) + battery=$(envstat | awk '\\(|\\)' '/charge:/ {print $2}') + battery="${battery/\.*}%" + ;; + esac + ;; + + "OpenBSD") + battery0full=$(sysctl -n hw.sensors.acpibat0.watthour0) + battery0full=${battery0full/ Wh*} + + battery0now=$(sysctl -n hw.sensors.acpibat0.watthour3) + battery0now="${battery0now/ Wh*}" + + [ ! -z "$battery0full" ] && \ + battery="$(printf "%s\n" "100 * $battery0now / $battery0full" | bc)%" + ;; + + "Mac OS X") + battery="$(pmset -g batt | grep -o '[0-9]*%')" + battery_state="$(pmset -g batt | awk 'NR==2 {print $3}')" + ;; + + "Windows") + battery="$(wmic Path Win32_Battery get EstimatedChargeRemaining /value)" + battery=${battery/EstimatedChargeRemaining'='} + battery=${battery//[[:space:]]/ } + battery=${battery// } + [ ! -z "$battery" ] && \ + battery+="%" + ;; + esac + + case "$battery_state" in + "charging"*) battery+=" Charging" ;; + esac + + case "$battery_display" in + "bar") battery="$(bar ${battery/'%'*} 100)" ;; + "infobar") battery="${battery} $(bar "${battery/'%'*}" 100)" ;; + "barinfo") battery="$(bar "${battery/'%'*}" 100) ${battery}" ;; + esac +} + +# }}} + +# IP Address {{{ + +getlocalip () { + case "$os" in + "Linux") + localip="$(ip route get 1 | awk '{print $NF;exit}')" + ;; + + "Mac OS X" | "iPhone OS") + localip="$(ipconfig getifaddr en0)" + [ -z "$localip" ] && localip="$(ipconfig getifaddr en1)" + ;; + + *"BSD") + localip="$(ifconfig | awk '/broadcast/ {print $2}')" + ;; + + "Windows") + localip="$(ipconfig | awk -F ': ' '/IPv4 Address/ {printf $2}')" + ;; + esac +} + +getpublicip () { + if type -p dig >/dev/null 2>&1; then + publicip="$(dig +time=1 +tries=1 +short myip.opendns.com @resolver1.opendns.com 2>/dev/null)" + fi + + if [ -z "$publicip" ] && type -p curl >/dev/null 2>&1; then + publicip="$(curl --max-time 10 -w '\n' "$public_ip_host" 2>/dev/null)" + fi + + if [ -z "$publicip" ] && type -p wget >/dev/null 2>&1; then + publicip="$(wget -T 10 -qO- "$public_ip_host" 2>/dev/null; printf "%s")" + fi +} + +# }}} + +# Logged In Users {{{ + +getusers () { + users="$(who | awk '!seen[$1]++ {printf $1 ", "}')" + users=${users%\,*} +} + +# }}} + +# Birthday {{{ + +getbirthday () { + case "$os" in + "linux" | "iPhone OS") + birthday="$(ls -alct --full-time / | awk '/lost\+found|private/ {printf $6 " " $7}')" + date_cmd="$(date -d"$birthday" "$birthday_format")" + ;; + + "Mac OS X") + birthday="$(ls -lUT /var/log/install.log | awk '{printf $6 " " $7 " " $9 " " $8}')" + + # Split the string into Date + time + time=${birthday/*???? } + birthday=${birthday/$time} + + case "${time/:*}" in + 0? | 10 | 11) time+=" AM" ;; + *) time+=" PM" ;; + esac + birthday+="$time" + birthday_shorthand="on" + ;; + + *"BSD") + case "$distro" in + "OpenBSD"*) + birthday="$(ls -alctT / | awk '/lost\+found/ {printf $6 " " $7 " " $9 " " $8}')" + birthday_shorthand="on" + ;; + + "FreeBSD"*) + birthday="$(ls -alctT /etc/hostid | awk '{printf $6 " " $7 " " $9 " " $8}')" + date_cmd="$(date -j -f "%b %d %Y" "$birthday" "$birthday_format")" + ;; + + "NetBSD"*) + birthday="$(ls -alctT /etc/defaults/rc.conf | awk '{printf $6 " " $7 " " $9 " " $8}')" + birthday_shorthand="on" + ;; + esac + ;; + + "Windows") + birthday="$(ls -alct --full-time /cygdrive/c/Windows/explorer.exe | awk '{printf $8 " " $9}')" + date_cmd="$(date -d"$birthday" "$birthday_format")" + ;; + esac + + # Strip seconds from time output + birthday=${birthday/:?? / } + + # Pretty output + [ "$birthday_shorthand" == "off" ] && \ + birthday=${date_cmd//+( )/ } + + # Toggle showing the time + [ "$birthday_time" == "off" ] && \ + birthday=${birthday/??:??*} +} + +# }}} + +# Terminal colors {{{ + +getcols () { + if [ "$color_blocks" == "on" ]; then + printf "${padding}%s" + while [ $start -le $end ]; do + case "$start" in + [0-6]) printf "\033[4${start}m%${block_width}s" ;; + 7) printf "\033[4${start}m%${block_width}s${clear}\n${padding}" ;; + *) printf "\033[48;5;${start}m%${block_width}s" ;; + esac + start=$((start + 1)) + done + + # Clear formatting + printf "%b%s" "$clear" + fi +} + +# }}} + +# }}} + + +# Images {{{ + + +# Wallpaper {{{ + +getwallpaper () { + case "$os" in + "Linux" | *"BSD") + if type -p feh >/dev/null 2>&1 && [ -f "$HOME/.fehbg" ]; then + img="$(awk -F\' '/feh/ {printf $2}' "$HOME/.fehbg")" + + elif type -p nitrogen >/dev/null 2>&1; then + img="$(awk -F'=' '/file/ {printf $2;exit;}' "$XDG_CONFIG_HOME/nitrogen/bg-saved.cfg")" + + elif type -p gsettings >/dev/null 2>&1; then + # Get DE if user has disabled the function. + [ -z "$de" ] && getde + + case "$de" in + "MATE"*) img="$(gsettings get org.mate.background picture-filename 2>/dev/null)" ;; + *) img="$(gsettings get org.gnome.desktop.background picture-uri 2>/dev/null)" ;; + esac + + # Strip quotes etc from the path. + img=${img/'file://'} + img=${img//\'} + fi + ;; + + "Mac OS X") + img="$(osascript -e 'tell application "System Events" to picture of current desktop')" + ;; + + "Windows") + case "$distro" in + "Windows XP") + img="/cygdrive/c/Documents and Settings/${USER}" + img+="/Local Settings/Application Data/Microsoft" + img+="/Wallpaper1.bmp" + ;; + + "Windows"*) + img="$APPDATA/Microsoft/Windows/Themes" + img+="/TranscodedWallpaper.jpg" + ;; + esac + ;; + esac + + # If img is an xml file don't use it. + [ "${img/*\./}" == "xml" ] && img="" + + # Error msg + [ -z "$img" ] && err "Wallpaper detection failed, falling back to ascii mode." +} + +# }}} + +# Ascii {{{ + +getascii () { + if [ ! -f "$ascii" ] || [ "$ascii" == "distro" ]; then + # Error message + [ "$ascii" != "distro" ] && \ + [ ! -f "$ascii" ] && err "Ascii file not found, using distro ascii" + + # Lowercase the distro name + if [ "$version" -le 3 ]; then + ascii=$(tr '[:upper:]' '[:lower:]' <<< "$ascii_distro") + else + ascii=${ascii_distro,,} + fi + + [ "$ascii_logo_size" == "small" ] && \ + ascii="${ascii/ *}_small" + + if [ -f "/usr/share/neofetch/ascii/distro/${ascii/ *}" ]; then + ascii="/usr/share/neofetch/ascii/distro/${ascii/ *}" + + elif [ -f "/usr/local/share/neofetch/ascii/distro/${ascii/ *}" ]; then + ascii="/usr/local/share/neofetch/ascii/distro/${ascii/ *}" + + else + getscriptdir + + # If the ascii file doesn't exist fallback to text mode. + if [ ! -f "$script_dir/ascii/distro/${ascii/ *}" ]; then + padding="\033[0C" + image="off" + err "Ascii file not found, falling back to text mode." + return + fi + + ascii="$script_dir/ascii/distro/${ascii/ *}" + fi + + # We only use eval in the distro ascii files. + print="$(eval printf "$(<"$ascii")")" + else + case "${ascii_colors[0]}" in + "distro") ascii_color="$c1" ;; + *) ascii_color="\033[38;5;${ascii_colors[0]}m" ;; + esac + + print="${ascii_color}$(<"$ascii")" + fi + + # Set locale to get correct padding + export LC_ALL="$SYS_LOCALE" + + # Turn the file into a variable and strip escape codes. + ascii_strip=$(<"$ascii") + ascii_strip=${ascii_strip//\$\{??\}} + ascii_strip=${ascii_strip//\\} + + # Get length of longest line + ascii_size=($(awk 'END {print NR}length>max{max=length}END{print max}' <<< "$ascii_strip")) + lines=$((ascii_size[0] + 1)) + ascii_length=${ascii_size[1]} + + padding="\033[$((ascii_length + gap))C" + printf "%b%s" "$print" + + export LC_ALL=C +} + + +# }}} + +# Image {{{ + +getimage () { + # Fallback to ascii mode if imagemagick isn't installed. + type -p convert >/dev/null 2>&1 || image="ascii" + + # Get terminal lines + lines=$(tput lines) + + case "$image" in + "wall") getwallpaper ;; + "ascii") getascii; return ;; + *) + if [ "${image: -1}" == "/" ]; then + files=("$image"*.png "$image"*.jpg) + img="$(printf "%s" "${files[RANDOM % ${#files[@]}]}")" + else + img="$image" + fi + ;; + esac + + # Get terminal width and height + stty -echo + if [ -n "$TMUX" ]; then + printf "%b%s" "\033Ptmux;\033\033[14t\033\033[c\033\\" + else + printf "%b%s" "\033[14t\033[c" + fi + + # The ascape code above prints the output AFTER the prompt so this + # loop below reads it as input. wtf xterm + read -t 1 -d c -s -r term_size; stty echo + + # Split the string + term_size=${term_size//'['} + term_size=${term_size/';'} + term_size=${term_size/$'\E4'} + term_size=${term_size/t*} + term_height=${term_size/';'*} + term_width=${term_size/*';'} + + + # If $img isn't a file or the terminal doesn't support xterm escape sequences, + # fallback to ascii mode. + if [ ! -f "$img" ] || [ ${#term_size} -le 5 ]; then + image="ascii" + getascii + + # Error messages + [ ! -f "$img" ] && err "\$img, isn't a file, falling back to ascii mode." + [ ${#term_size} -le 5 ] && err "Your terminal doesn't support \\\033[14t, falling back to ascii mode." + + return + fi + + # Get terminal columns + columns=$(tput cols) + + # Calculate font size + font_width=$((term_width / columns)) + + # Image size is half of the terminal + case "$image_size" in + "auto") + image_size=$((columns * font_width / 2)) + term_height=$((term_height - term_height / 4)) + + [ "$term_height" -lt "$image_size" ] && \ + image_size="$term_height" + ;; + + *"%") + percent=${image_size/\%} + image_size=$((percent * term_width / 100)) + + [ "$((percent * term_height / 50))" -lt "$image_size" ] && \ + image_size=$((percent * term_height / 100)) + ;; + + *) image_size=${image_size/px} ;; + esac + + # Where to draw the image + case "$image_position" in + "left") + # Padding is half the terminal width + gap + padding="\033[$((image_size / font_width + gap + xoffset/font_width))C" + ;; + + "right") + padding="\033[0C" + xoffset=$((columns * font_width / 2 - gap)) + ;; + esac + + # Make the directory if it doesn't exist + mkdir -p "$thumbnail_dir" + + # Check to see if the image has a file extension, if it doesn't + # then add one. + case "${img##*/}" in + *"."*) imgname="$crop_mode-$crop_offset-$image_size-${img##*/}" ;; + *) imgname="$crop_mode-$crop_offset-$image_size-${img##*/}.jpg" ;; + esac + + # Check to see if the thumbnail exists before we do any cropping. + if [ ! -f "$thumbnail_dir/$imgname" ]; then + # Get image size so that we can do a better crop + size=$(identify -format "%w %h" "$img") + width=${size%% *} + height=${size##* } + + # This checks to see if height is geater than width + # so we can do a better crop of portrait images. + size=$height + [ "$height" -gt "$width" ] && size=$width + + case "$crop_mode" in + fit) + c=$(convert "$img" \ + -colorspace srgb \ + -format "%[pixel:p{0,0}]" info:) + + convert \ + "$img" \ + -trim +repage \ + -gravity south \ + -background "$c" \ + -extent "$size"x"$size" \ + -scale "$image_size"x"$image_size" \ + "$thumbnail_dir/$imgname" + ;; + + fill) + convert \ + "$img" \ + -trim +repage \ + -scale "$image_size"x"$image_size"^ \ + -extent "$image_size"x"$image_size" \ + "$thumbnail_dir/$imgname" + ;; + + *) + convert \ + "$img" \ + -gravity $crop_offset \ + -crop "$size"x"$size"+0+0 \ + -quality 95 \ + -scale "$image_size"x"$image_size" \ + "$thumbnail_dir/$imgname" + ;; + esac + fi + + # The final image + img="$thumbnail_dir/$imgname" +} + +takescrot () { + $scrot_cmd "${scrot_dir}${scrot_name}" +} + +# }}} + +# Find w3m-img {{{ + +# Find w3mimgdisplay automatically +getw3m_img_path () { + if [ -x "$w3m_img_path" ]; then + return + + elif [ -x "/usr/lib/w3m/w3mimgdisplay" ]; then + w3m_img_path="/usr/lib/w3m/w3mimgdisplay" + + elif [ -x "/usr/libexec/w3m/w3mimgdisplay" ]; then + w3m_img_path="/usr/libexec/w3m/w3mimgdisplay" + + elif [ -x "/usr/lib64/w3m/w3mimgdisplay" ]; then + w3m_img_path="/usr/lib64/w3m/w3mimgdisplay" + + elif [ -x "/usr/libexec64/w3m/w3mimgdisplay" ]; then + w3m_img_path="/usr/libexec64/w3m/w3mimgdisplay" + + else + image="ascii" + err "w3m-img wasn't found on your system, falling back to ascii mode." + fi +} + +# }}} + + +# }}} + + +# Text Formatting {{{ + + +# Info {{{ + +info () { + # $1 is the subtitle + subtitle="$1" + + # Call the function and update variable + if [ -z "$2" ]; then + "get$1" 2>/dev/null + eval output="\$${1}" + + else + "get$2" 2>/dev/null + eval output="\$${2}" + fi + + # If the output is empty, don't print anything + [ -z "$output" ] && return + + case "$1" in + title) + string="${bold}${title_color}${output}" + string="${string/@/${at_color}@${title_color}}" + length=${#output} + ;; + + underline) + string="${underline_color}${output}" + ;; + + *) + string="${bold}${subtitle_color}${subtitle}${clear}" + string+="${colon_color}: ${info_color}${output}" + length=$((${#subtitle} + ${#output} + 2)) + ;; + esac + + # If there's no subtitle don't print one + [ -z "$2" ] && string=${string/*: } + + # Print the string + printf "%b%s\n" "${padding}${string}${clear}" +} + +# }}} + +# Prin {{{ + +prin () { + if [ -z "$2" ]; then + string="${info_color}${1}" + length=${#1} + + else + string="${bold}${subtitle_color}${1}${clear}" + string+="${colon_color}: ${info_color}${2}" + length=$((${#subtitle} + ${#2} + 1)) + fi + + # Print the info + printf "%b%s\n" "${padding}${string}${clear}" +} + +# }}} + +# Stdout {{{ + +stdout () { + # Read args early for the separator + stdout_separator_flag="$(awk -F '--stdout_separator ' '{printf $2}' <<< "${args[@]}")" + stdout_separator_flag=${stdout_separator_flag/ '--'*} + + [ ! -z "$stdout_separator_flag" ] && \ + stdout_separator="$stdout_separator_flag" + + for func in "${args[@]}"; do + case "$func" in + "--"*) break ;; + *) + "get$func" 2>/dev/null + eval output="\$$func" + stdout+="${output}${stdout_separator}" + ;; + esac + done + + printf "%s" "${stdout%%${stdout_separator}}" + exit +} + +# }}} + +# Underline {{{ + +getunderline () { + case "$underline_enabled" in + "on") + underline=$(printf %"$length"s) + underline=${underline// /$underline_char} + ;; + "off") underline="" ;; + esac +} + +# }}} + +# Colors {{{ + +colors () { + # Change color of logo based on distro + case "$ascii_distro" in + "Arch"* | "Antergos"*) + setcolors 6 4 + ;; + + "CentOS"*) + setcolors 3 2 4 5 7 + ;; + + "CRUX"* | "Chakra"* | "gNewSense"* | "SailfishOS"* | "Alpine"* | "Ubuntu-GNOME"* | "Qubes"*) + setcolors 4 5 7 + ;; + + "Chrom"*) + setcolors 2 1 3 4 7 + ascii_distro="chrome" + ;; + + "Debian"* | "FreeBSD"* | "Elementary"* | "CrunchBang"* | "Ubuntu"*) + setcolors 7 1 3 + ;; + + "Red"*) + setcolors 7 1 3 + ascii_distro="redhat" + ;; + + "Kogaion"*) + setcolors 4 7 + ;; + + "Fedora"* | "Sabayon"* | "Frugalware"* | "Exherbo"*) + setcolors 7 4 1 + ;; + + "Gentoo"* | "Funtoo"* | "SteamOS"*) + setcolors 7 5 + ;; + + "KDE"*) + setcolors 2 7 + ascii_distro="kde" + ;; + + "Kali"*) + setcolors 4 8 + ;; + + *"OS X"* | *"iOS"*) + setcolors 2 3 1 1 5 4 + ascii_distro="mac" + ;; + + "OpenMandriva"*) + setcolors 4 3 + ;; + + "Mageia"*) + setcolors 7 6 + ;; + + "Peppermint"*) + setcolors 7 1 + ;; + + *"Mint"*) + setcolors 7 2 + ascii_distro="mint" + ;; + + "LMDE"* | "Chapeau"*) + setcolors 7 2 + ;; + + "NetBSD"* | "Parabola"* | "Tails"* | "BLAG"*) + setcolors 5 7 + ;; + + "OpenBSD"*) + setcolors 3 7 6 1 8 + ;; + + "OpenSuse"* | "Manjaro"* | "Deepin"*) + setcolors 2 7 + ;; + + "PCLinuxOS"* | "Slackware"* | "KaOS"* | "Kubuntu"* | "Lubuntu"* | "Xubuntu"*) + setcolors 4 7 1 + ;; + + "Puppy"* | "Quirky Werewolf"* | "Precise Puppy"*) + setcolors 4 + ascii_distro="puppy" + ;; + + "Scientific"*) + setcolors 4 1 7 + ;; + + "Solus"*) + setcolors 7 8 + ;; + + "Trisquel"* | "NixOS"* | "Zorin"*) + setcolors 4 6 + ;; + + "Travis") + setcolors 3 1 0 7 4 + ;; + + "void"*) + setcolors 2 8 + ;; + + "Windows 8"* | "Windows 10"*) + setcolors 6 + ascii_distro="windows10" + ;; + + "Windows"*) + setcolors 1 2 4 3 + ;; + + "Raspbian"* | *) + setcolors 2 1 + ;; + esac + + # Overwrite distro colors if '$ascii_colors' doesn't + # equal 'distro'. + [ "${ascii_colors[0]}" != "distro" ] && \ + setcolors ${ascii_colors[@]} +} + +setcolors () { + c1="$(color $1)" + c2="$(color $2)" + c3="$(color $3)" + c4="$(color $4)" + c5="$(color $5)" + c6="$(color $6)" + + if [ "${colors[0]}" == "distro" ]; then + title_color="$c1" + at_color="\033[0m" + underline_color="\033[0m" + subtitle_color="$c2" + colon_color="\033[0m" + info_color="\033[0m" + + # If the second color is white use the first for the subtitle + [ "$2" == 7 ] && subtitle_color="\033[0m\033[3${1}m" + else + title_color="$(color ${colors[0]})" + at_color="$(color ${colors[1]})" + underline_color="$(color ${colors[2]})" + subtitle_color="$(color ${colors[3]})" + colon_color="$(color ${colors[4]})" + info_color="$(color ${colors[5]})" + fi + + if [ "$progress_color_elapsed" == "distro" ]; then + progress_color_elapsed="$(color fg)" + else + progress_color_elapsed="$(color $progress_color_elapsed)" + fi + + case "$progress_color_total $1" in + distro\ [736]) progress_color_total="$c2" ;; + distro\ [0-9]) progress_color_total="$c1" ;; + *) progress_color_total="$(color $progress_color_total)" ;; + esac +} + +color () { + case "$1" in + [0-7]) printf "%b%s" "\033[0m\033[3${1}m" ;; + "fg") printf "%b%s" "\033[0m" ;; + *) printf "%b%s" "\033[38;5;${1}m" ;; + esac +} + + +# }}} + +# Bold {{{ + +bold () { + case "$bold" in + "on") bold="\033[1m" ;; + "off") bold="" ;; + esac +} + +# }}} + +# Linebreak {{{ + +getlinebreak () { + linebreak=" " +} + +# }}} + +clear="\033[0m" + + +# }}} + + +# Other {{{ + + +# Get script directory {{{ + +getscriptdir () { + # Use $0 to get the script's physical path. + cd "${0%/*}" || exit + script_dir=${0##*/} + + # Iterate down a (possible) chain of symlinks. + while [ -L "$script_dir" ]; do + script_dir="$(readlink "$script_dir")" + cd "${script_dir%/*}" || exit + script_dir="${script_dir##*/}" + done + + # Final directory + script_dir="$(pwd -P)" +} + +# }}} + +# Source Config {{{ + +# Check for $config_file first +getconfig () { + # Check $config_file + if [ -f "$config_file" ]; then + source "$config_file" + return + fi + mkdir -p "$XDG_CONFIG_HOME/neofetch/" + + # Check $XDG_CONFIG_HOME/neofetch and create the + # dir/files if they don't exist. + if [ -f "$XDG_CONFIG_HOME/neofetch/config" ]; then + source "$XDG_CONFIG_HOME/neofetch/config" + + elif [ -f "/usr/share/neofetch/config" ]; then + cp "/usr/share/neofetch/config" "$XDG_CONFIG_HOME/neofetch" + source "$XDG_CONFIG_HOME/neofetch/config" + + elif [ -f "/usr/local/share/neofetch/config" ]; then + cp "/usr/local/share/neofetch/config" "$XDG_CONFIG_HOME/neofetch" + source "$XDG_CONFIG_HOME/neofetch/config" + + else + getscriptdir + + cp "$script_dir/config/config" "$XDG_CONFIG_HOME/neofetch" + source "$XDG_CONFIG_HOME/neofetch/config" + fi +} + +# Check the commandline flags early for '--config none/off' +case "$@" in + *"--config off"* | *'--config "off"'* | *"--config 'off'"* | \ + *"--config none"* | *'--config "none"'* | *"--config 'none'"* | *"--stdout"*) + config="off" + ;; +esac +[ "$config" == "on" ] && getconfig + +# }}} + +# Progress Bars {{{ + +bar() { + # Get the values + elapsed=$(($1 * progress_length / $2)) + + # Create the bar with spaces + prog=$(printf %"$elapsed"s) + total=$(printf %"$((progress_length - elapsed))"s) + + # Set the colors and swap the spaces for $progress_char + bar+="${progress_color_elapsed}${prog// /$progress_char_elapsed}" + bar+="${progress_color_total}${total// /$progress_char_total}" + + # Borders + if [ "$progress_border" == "on" ]; then + bar+="$(color fg)]" + bar="$(color fg)[$bar" + fi + + printf "%b%s\n" "${bar}${clear}" +} + +# }}} + +# Cache {{{ + +cache () { + mkdir -p "$3/neofetch" + echo "${1/*-}=\"$2\"" > "$3/neofetch/${1/*-}" +} + +# }}} + +# KDE Config directory {{{ + +kdeconfigdir () { + if [ -n "$KDE_CONFIG_DIR" ]; then + kde_config_dir="$KDE_CONFIG_DIR" + + elif type -p kde5-config >/dev/null 2>&1; then + kde_config_dir=$(kde5-config --localprefix) + + elif type -p kde4-config >/dev/null 2>&1; then + kde_config_dir=$(kde4-config --localprefix) + + elif type -p kde-config >/dev/null 2>&1; then + kde_config_dir=$(kde-config --localprefix) + fi +} + +# }}} + +err () { + err+="$(color 1)[!]$(color fg) $1 \n" +} + +# }}} + + +# Usage {{{ + + +usage () { cat << EOF + + usage: neofetch --option "value" --option "value" + + NOTE: There's also a config option for each flag below. + + Info: + --disable infoname Allows you to disable an info line from appearing + in the output. + NOTE: You can supply multiple args. eg. + 'neofetch --disable cpu gpu disk shell' + --osx_buildversion on/off Hide/Show Mac OS X build version. + --osx_codename on/off Hide/Show Mac OS X codename. + --os_arch on/off Hide/Show Windows architecture. + --speed_type type Change the type of cpu speed to display. + Possible values: current, min, max, bios, + scaling_current, scaling_min, scaling_max + NOTE: This only support Linux with cpufreq. + --cpu_shorthand type Shorten the output of CPU + Possible values: name, speed, tiny, on, off + --cpu_cores on/off Whether or not to display the number of CPU cores + --kernel_shorthand on/off Shorten the output of kernel + --uptime_shorthand on/off Shorten the output of uptime (tiny, on, off) + --refresh_rate on/off Whether to display the refresh rate of each monitor + Unsupported on Windows + --gpu_shorthand on/off Shorten the output of GPU (tiny, on, off) + --gtk_shorthand on/off Shorten output of gtk theme/icons + --gtk2 on/off Enable/Disable gtk2 theme/icons output + --gtk3 on/off Enable/Disable gtk3 theme/icons output + --shell_path on/off Enable/Disable showing \$SHELL path + --shell_version on/off Enable/Disable showing \$SHELL version + --battery_num num Which battery to display, default value is 'all' + --battery_shorthand on/off Whether or not each battery gets its own line/title + --ip_host url Url to ping for public IP + --song_shorthand on/off Print the Artist/Title on seperate lines + --birthday_shorthand on/off Shorten the output of birthday + --birthday_time on/off Enable/Disable showing the time in birthday output + --birthday_format format Format the birthday output. (Uses 'date' cmd format) + + + Text Formatting: + --colors x x x x x x Changes the text colors in this order: + title, @, underline, subtitle, colon, info + --underline on/off enable/disable the underline. + --underline_char char Character to use when underlining title + --line_wrap on/off Enable/Disable line wrapping + --bold on/off Enable/Disable bold text + --prompt_height num Set this to your prompt height to fix issues with + the text going off screen at the top + + + Color Blocks: + --color_blocks on/off Enable/Disable the color blocks + --block_width num Width of color blocks + --block_range start end Range of colors to print as blocks + + + Progress Bars: + --progress_char 'elapsed char' 'total char' + Characters to use when drawing progress bars. + --progress_border on/off Whether or not to surround the bar with '[]' + --progress_length num Length in spaces to make the progress bars. + --progress_colors num num Colors to make the progress bar. + Set in this order: elapsed, total + --cpu_display mode1 mode2 Which shorthand to use and how CPU usage should be printed + mode1 takes: name, speed, tiny, on, off + mode2 takes: info, bar, infobar, barinfo + --memory_display mode Which way should the memory progress bar be added + Takes bar, infobar, barinfo + --battery_display mode Which way should the battery progress bar be added + Takes bar, infobar, barinfo + --disk_display mode Which way should the disk progress bar be added + Takes bar, infobar, barinfo, perc + + + Image: + --image type Image source. Where and what image we display. + Possible values: wall, ascii, + /path/to/img, /path/to/dir/, off + --size 20px | --size 20% Size to make the image, takes pixels or a percentage. + --image_position left/right Where to display the image: (Left/Right) + --crop_mode mode Which crop mode to use + Takes the values: normal, fit, fill + --crop_offset value Change the crop offset for normal mode. + Possible values: northwest, north, northeast, + west, center, east, southwest, south, southeast + + --xoffset px How close the image will be to the left edge of the + window. This only works with w3m. + --yoffset px How close the image will be to the top edge of the + window. This only works with w3m. + --gap num Gap between image and text. + NOTE: --gap can take a negative value which will + move the text closer to the left side. + --clean Remove all cropped images + + + Ascii: + --ascii value Where to get the ascii from, Possible values: + distro, /path/to/ascii + --ascii_colors x x x x x x Colors to print the ascii art + --ascii_distro distro Which Distro's ascii art to print + --ascii_logo_size Size of ascii logo. + Supported distros: Arch, Gentoo, Crux, OpenBSD. + + + Stdout: + --stdout info info Launch neofetch in stdout mode which prints the info + in a plain-text format that you can use with + lemonbar etc. + --stdout_separator string String to use as a separator in stdout mode. + + + Screenshot: + --scrot /path/to/img Take a screenshot, if path is left empty the screen- + shot function will use \$scrot_dir and \$scrot_name. + --scrot_cmd cmd Screenshot program to launch + + + Other: + --config /path/to/config Specify a path to a custom config file + --config none Launch the script without a config file + --help Print this text and exit + --test Launch the script with all functions / options enabled. + This should only be used for testing purposes, ie Travis.CI. + -v Display error messages. + -vv Display a verbose log for error reporting. + +EOF +exit 1 +} + + +# }}} + + +# Args {{{ + + +while [ "$1" ]; do + case $1 in + # Info + --os_arch) os_arch="$2" ;; + --osx_buildversion) osx_buildversion="$2" ;; + --osx_codename) osx_codename="$2" ;; + --cpu_cores) cpu_cores="$2" ;; + --speed_type) speed_type="$2" ;; + --kernel_shorthand) kernel_shorthand="$2" ;; + --uptime_shorthand) uptime_shorthand="$2" ;; + --cpu_shorthand) cpu_shorthand="$2" ;; + --gpu_shorthand) gpu_shorthand="$2" ;; + --refresh_rate) refresh_rate="$2" ;; + --gtk_shorthand) gtk_shorthand="$2" ;; + --gtk2) gtk2="$2" ;; + --gtk3) gtk3="$2" ;; + --shell_path) shell_path="$2" ;; + --shell_version) shell_version="$2" ;; + --battery_num) battery_num="$2" ;; + --battery_shorthand) battery_shorthand="$2" ;; + --ip_host) public_ip_host="$2" ;; + --song_shorthand) song_shorthand="$2" ;; + --birthday_shorthand) birthday_shorthand="$2" ;; + --birthday_time) birthday_time="$2" ;; + --birthday_format) birthday_format="$2" ;; + --disable) + for func in "$@"; do + case "$func" in + "--disable") continue ;; + "--"*) return ;; + *) unset -f "get$func" ;; + esac + done + ;; + + # Text Colors + --colors) + unset colors + for arg in "$2" "$3" "$4" "$5" "$6" "$7"; do + case "$arg" in + "--"*) break ;; + *) colors+=($arg) + esac + done + colors+=(7 7 7 7 7 7) + ;; + + # Text Formatting + --underline) underline_enabled="$2" ;; + --underline_char) underline_char="$2" ;; + --line_wrap) line_wrap="$2" ;; + --bold) bold="$2" ;; + --prompt_height) prompt_height="$2" ;; + + # Color Blocks + --color_blocks) color_blocks="$2" ;; + --block_range) start=$2; end=$3 ;; + --block_width) block_width="$2" ;; + + # Progress Bars + --progress_char) + progress_char_elapsed="$2" + progress_char_total="$3" + ;; + --progress_border) progress_border="$2" ;; + --progress_length) progress_length="$2" ;; + --progress_colors) + progress_color_elapsed="$2" + progress_color_total="$3" + ;; + --cpu_display) + cpu_shorthand="$2" + cpu_display="$3" + ;; + --memory_display) memory_display="$2" ;; + --battery_display) battery_display="$2" ;; + --disk_display) disk_display="$2" ;; + + # Image + --image) + image="$2" + case "$2" in "--"* | "") image="ascii" ;; esac + ;; + + --size) image_size="$2" ;; + --image_position) image_position="$2" ;; + --crop_mode) crop_mode="$2" ;; + --crop_offset) crop_offset="$2" ;; + --xoffset) xoffset="$2" ;; + --yoffset) yoffset="$2" ;; + --gap) gap="$2" ;; + --clean) + rm -rf "$thumbnail_dir" + rm -rf "/Library/Caches/neofetch/" + exit + ;; + + # Ascii + --ascii) + image="ascii" + ascii="$2" + case "$2" in "--"* | "") ascii="distro" ;; esac + ;; + + --ascii_colors) + unset ascii_colors + for arg in "$2" "$3" "$4" "$5" "$6" "$7"; do + case "$arg" in + "--"*) break ;; + *) ascii_colors+=($arg) + esac + done + ascii_colors+=(7 7 7 7 7 7) + ;; + + --ascii_distro) + ascii_distro="$2" + case "$2" in "--"* | "") ascii_distro="$distro" ;; esac + ;; + + --ascii_logo_size) ascii_logo_size="$2" ;; + + # Screenshot + --scrot | -s) + scrot="on" + if [ "$2" ]; then + scrot_name="${2##*/}" + scrot_dir="${2/$scrot_name}" + fi + ;; + --scrot_cmd) scrot_cmd="$2" ;; + + # Stdout + --stdout) + unset info_color prin clear bar + stdout_mode="on" + config="off" + case "$2" in + "--"* | "") printf "%s\n" "--stdout requires at least one argument"; exit ;; + *) shift; args=("$@"); stdout ;; + esac + ;; + + # Other + --config) + case "$2" in + "none" | "off") config="off" ;; + *) config_file="$2"; config="on"; getconfig ;; + esac + ;; + --test) + info=(title underline distro kernel uptime packages shell resolution de wm wmtheme theme icons cpu gpu memory font disk battery song localip publicip users birthday) + + refresh_rate="on" + shell_version="on" + cpu_display="infobar" + memory_display="infobar" + disk_display="infobar" + + printinfo () { + if [ ! -z "$TRAVIS_OS_NAME" ]; then + info linebreak + info linebreak + fi + + for func in "${info[@]}"; do + info "$(tr '[:lower:]' '[:upper:]' <<< "$func")" $func + done + + info linebreak + info cols + info linebreak + printf "%b%s" "\033[$(tput lines)H" + } + ;; + + -v) verbose="on" ;; + -vv) set -x; verbose="on" ;; + --help) usage ;; + esac + + shift +done + + +# }}} + + +# Call Functions and Finish Up {{{ + + +# Restore cursor and clear screen on ctrl+c +trap 'printf "\033[?25h"; clear; exit' 2 + +# Distro detection +getdistro +[ -z "$ascii_distro" ] && ascii_distro="$distro" + +# Text formatting +colors +bold + +if [ "$image" != "off" ]; then + # If the script exits for any reason, unhide the cursor. + trap 'printf "\033[?25h"' EXIT + + # Clear the scren + clear + + # Hide the cursor + printf "\033[?25l" + + # If iterm2 is detected use iterm2 backend. + if [ -n "$ITERM_PROFILE" ]; then + image_backend="iterm2" + else + image_backend="w3m" + fi + + # Find w3mimgdisplay + [ "$image_backend" == "w3m" ] && \ + [ "$image" != "ascii" ] && \ + getw3m_img_path + + # Get the image + getimage +fi + +# Display the image if enabled +if [ "$image" != "off" ] && [ "$image" != "ascii" ]; then + case "$image_backend" in + "w3m") + printf "%b%s\n" "0;1;$xoffset;$yoffset;$image_size;$image_size;;;;;$img\n4;\n3;" |\ + $w3m_img_path 2>/dev/null || padding="\033[0C" + ;; + + "iterm2") + printf "%b%s\a\n" "\033]1337;File=width=${image_size}px;height=${image_size}px;inline=1:$(base64 < "$img")" + ;; + esac +fi + +# Disable line wrap +[ "$line_wrap" == "off" ] && printf "\033[?7l" + +# Move cursor to the top +[ "$image" != "off" ] && printf "\033[0H" + +# Print the info +printinfo + +if [ "$image" != "off" ]; then + # Get cursor position + info_height="$(stty -echo; IFS=';' read -rdR -t 1 -d c -p $'\033[6n\033[c' ROW COL; printf "%s" "${ROW#*[}"; stty echo)" + + # Set cursor position dynamically based on height of ascii/text. + [ "${lines:-0}" -lt "${info_height:-0}" ] && lines="$info_height" + + printf "%b%s" "\033[${lines}H\033[${prompt_height}A" +fi + +# Re-enable line wrap +[ "$line_wrap" == "off" ] && printf "%b%s" "\033[?7h" + +# If enabled take a screenshot +if [ "$scrot" == "on" ]; then + takescrot +fi + +# Show error messages +if [ "$verbose" == "on" ]; then + printf "$err" +fi + +# }}} diff --git a/neofetch b/neofetch index 8b648dfc..d9ef7afc 100755 --- a/neofetch +++ b/neofetch @@ -450,8 +450,7 @@ shopt -s nocasematch extglob case "$(uname)" in "Linux") os="Linux" ;; "Darwin") os="$(sw_vers -productName)" ;; - "OpenBSD") os="OpenBSD" ;; - *"BSD") os="BSD" ;; + *"BSD" | "DragonFly") os="BSD" ;; "CYGWIN"*) os="Windows" ;; *) printf "%s\n" "Unknown OS detected: $(uname)"; exit 1 ;; esac @@ -507,13 +506,8 @@ getdistro () { os_arch="off" ;; - "OpenBSD") - distro="OpenBSD" - ;; - "BSD") - distro="$(uname -v)" - distro=${distro%% *} + distro="$(uname -sr)" ;; "Windows") @@ -582,7 +576,7 @@ getuptime () { esac ;; - "Mac OS X" | "iPhone OS" | *"BSD") + "Mac OS X" | "iPhone OS" | "BSD") # Get boot time in seconds boot="$(sysctl -n kern.boottime)" boot="${boot/'{ sec = '}" @@ -714,7 +708,7 @@ getpackages () { packages=$((packages + $(pkgin list 2>/dev/null | wc -l))) ;; - *"BSD") + "BSD") if type -p pkg_info >/dev/null 2>&1; then packages=$(pkg_info | wc -l) @@ -945,6 +939,43 @@ getwmtheme () { getcpu () { case "$os" in + "Linux" | "Windows") + # Get cpu name + cpu="$(awk -F ': | @' '/model name/ {printf $2; exit}' /proc/cpuinfo)" + + # Get cpu speed + if [ -d "/sys/devices/system/cpu/cpu0/cpufreq" ]; then + case "$speed_type" in + current) speed_type="scaling_cur_freq" ;; + min) speed_type="scaling_min_freq" ;; + max) speed_type="scaling_max_freq" ;; + bios) speed_type="bios_limit" ;; + scaling_current) speed_type="scaling_cur_freq" ;; + scaling_min) speed_type="scaling_min_freq" ;; + scaling_max) speed_type="scaling_max_freq" ;; + esac + + read -t 1 -r speed < \ + /sys/devices/system/cpu/cpu0/cpufreq/${speed_type} + + speed=$((speed / 100000)) + else + speed=$(awk -F ': |\\.' '/cpu MHz/ {printf $2; exit}' /proc/cpuinfo) + speed=$((speed / 100)) + fi + + cores=$(awk -F ': ' '/siblings/ {printf $2; exit}' /proc/cpuinfo) + + # Fix for speeds under 1ghz + if [ -z "${speed:1}" ]; then + speed="0.${speed}" + else + speed=${speed:0:1}.${speed:1} + fi + + cpu="$cpu @ ${speed}GHz" + ;; + "Mac OS X") cpu="$(sysctl -n machdep.cpu.brand_string)" cores=$(sysctl -n hw.ncpu) @@ -1060,60 +1091,18 @@ getcpu () { esac ;; - *) - case "$distro" in - "OpenBSD"* | "FreeBSD"*) - # Get cpu name - cpu="$(sysctl -n hw.model)" - cpu=${cpu/[0-9]\.*} - cpu=${cpu/ @*} + "BSD") + # Get cpu name + cpu="$(sysctl -n hw.model)" + cpu=${cpu/[0-9]\.*} + cpu=${cpu/ @*} - # Get cpu speed - case "$distro" in - "OpenBSD"*) speed=$(sysctl -n hw.cpuspeed) ;; - "FreeBSD"*) speed=$(sysctl -n hw.clockrate) ;; - esac - speed=$((speed / 100)) - cores=$(sysctl -n hw.ncpu) - ;; + # Get cpu speed + speed=$(sysctl -n hw.cpuspeed hw.clockrate 2>/dev/null) + speed=$((speed / 100)) - *) - # Get cpu name - cpu="$(awk -F ': | @' '/model name/ {printf $2; exit}' /proc/cpuinfo)" - - # Get cpu speed - if [ -d "/sys/devices/system/cpu/cpu0/cpufreq" ]; then - case "$speed_type" in - current) speed_type="scaling_cur_freq" ;; - min) speed_type="scaling_min_freq" ;; - max) speed_type="scaling_max_freq" ;; - bios) speed_type="bios_limit" ;; - scaling_current) speed_type="scaling_cur_freq" ;; - scaling_min) speed_type="scaling_min_freq" ;; - scaling_max) speed_type="scaling_max_freq" ;; - esac - - read -t 1 -r speed < \ - /sys/devices/system/cpu/cpu0/cpufreq/${speed_type} - - speed=$((speed / 100000)) - else - speed=$(awk -F ': |\\.' '/cpu MHz/ {printf $2; exit}' /proc/cpuinfo) - speed=$((speed / 100)) - fi - - cores=$(awk -F ': ' '/siblings/ {printf $2; exit}' /proc/cpuinfo) - ;; - esac - - # Fix for speeds under 1ghz - if [ -z "${speed:1}" ]; then - speed="0.${speed}" - else - speed=${speed:0:1}.${speed:1} - fi - - cpu="$cpu @ ${speed}GHz" + # Get cpu cores + cores=$(sysctl -n hw.ncpu) ;; esac @@ -1324,7 +1313,7 @@ getgpu () { esac ;; - *"BSD") + "BSD") case "$distro" in "FreeBSD"*) gpu=$(pciconf -lv 2>/dev/null | grep -B 4 "VGA" | grep "device") @@ -1401,7 +1390,7 @@ getmemory () { memused=$(((${memwired//.} + ${memactive//.} + ${memcompressed//.}) * 4 / 1024)) ;; - "OpenBSD" | "BSD") + "BSD") case "$distro" in "OpenBSD"*) mem=($(top -d 1 | awk -F ': |/| |M' '/Memory:/ {printf $4 " " $6 " " $11 "\n"}')) @@ -1522,7 +1511,7 @@ getsong () { getresolution () { case "$os" in - "Linux" | *"BSD") + "Linux" | "BSD") if type -p xrandr >/dev/null 2>&1; then case "$refresh_rate" in "on") resolution=$(xrandr --nograb --current | awk 'match($0,/[0-9]{2,3}.[0-9]{2}\*/) {printf $1 " @ " substr($0,RSTART,RLENGTH) "Hz, "}') ;; @@ -1747,12 +1736,11 @@ getdisk () { # df flags case "$os" in "Linux" | "iPhone OS" | "Windows") df_flags="-h -l --total" ;; - "Mac OS X") df_flags="-H / -l" ;; - - *"BSD") + "Mac OS X" | "BSD") case "$distro" in - "FreeBSD"*) df_flags="-h -c -l" ;; - *) return ;; + "OpenBSD"*) return ;; + "FreeBSD"* | *"OS X"* ) df_flags="-H / -l" ;; + *) df_flags="-h -c -l" ;; esac ;; esac @@ -1837,7 +1825,7 @@ getbattery () { "BSD") case "$distro" in - "FreeBSD"*) + "FreeBSD"* | "DragonFly"*) battery=$(acpiconf -i 0 | awk -F ':\t' '/Remaining capacity/ {print $2}') battery_state=$(acpiconf -i 0 | awk -F ':\t\t\t' '/State/ {print $2}') ;; @@ -1901,7 +1889,7 @@ getlocalip () { [ -z "$localip" ] && localip="$(ipconfig getifaddr en1)" ;; - *"BSD") + "BSD") localip="$(ifconfig | awk '/broadcast/ {print $2}')" ;; @@ -1960,7 +1948,7 @@ getbirthday () { birthday_shorthand="on" ;; - *"BSD") + "BSD") case "$distro" in "OpenBSD"*) birthday="$(ls -alctT / | awk '/lost\+found/ {printf $6 " " $7 " " $9 " " $8}')" @@ -1972,7 +1960,7 @@ getbirthday () { date_cmd="$(date -j -f "%b %d %Y" "$birthday" "$birthday_format")" ;; - "NetBSD"*) + "NetBSD"* | "DragonFly"*) birthday="$(ls -alctT /etc/defaults/rc.conf | awk '{printf $6 " " $7 " " $9 " " $8}')" birthday_shorthand="on" ;; @@ -2030,7 +2018,7 @@ getcols () { getwallpaper () { case "$os" in - "Linux" | *"BSD") + "Linux" | "BSD") if type -p feh >/dev/null 2>&1 && [ -f "$HOME/.fehbg" ]; then img="$(awk -F\' '/feh/ {printf $2}' "$HOME/.fehbg")"