summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--CHANGELOG.md31
-rw-r--r--README.md2
-rw-r--r--TESTS.md8
-rwxr-xr-xdebug/font-issues.zsh182
-rwxr-xr-xdebug/iterm.zsh86
-rw-r--r--functions/icons.zsh59
-rwxr-xr-xpowerlevel9k.zsh-theme26
-rw-r--r--test-bsd-vm/Vagrantfile87
-rw-r--r--test-bsd-vm/bootstrap-zero.sh3
-rw-r--r--test-bsd-vm/bootstrap.sh13
-rw-r--r--test-vm-providers/plain.sh9
-rwxr-xr-xtest-vm-providers/setup-environment.sh44
-rw-r--r--test-vm/Vagrantfile2
-rw-r--r--test-vm/antigen.sh3
-rw-r--r--test-vm/bootstrap.sh10
-rw-r--r--test-vm/omz.sh2
-rw-r--r--test-vm/plain.sh3
-rw-r--r--test-vm/prezto.sh3
-rwxr-xr-xtest/functions/icons.spec362
-rwxr-xr-xtest/segments/dir.spec106
21 files changed, 1011 insertions, 35 deletions
diff --git a/.travis.yml b/.travis.yml
index ad4eb8c6..134f31f1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,16 +14,17 @@ before_script:
install:
- "sudo apt-get update -qq"
- - "sudo apt-get install zsh"
+ - "sudo apt-get install -y zsh"
- "sudo chsh -s $(which zsh)"
+ - "sudo apt-get install -y git mercurial subversion jq node golang ruby python python-virtualenv"
script:
- test/powerlevel9k.spec
- test/functions/utilities.spec
- test/functions/colors.spec
+ - test/functions/icons.spec
- test/segments/command_execution_time.spec
- test/segments/dir.spec
- test/segments/rust_version.spec
- test/segments/go_version.spec
- test/segments/vcs.spec
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e991af28..cbb9d16b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+## next
+
+### Add debug script for iTerm2 issues
+
+A new script `debug/iterm.zsh` was added for easier spotting problems with your iTerm2 configuration.
+
+### Add debug script for font issues
+
+A new script `debug/font-issues.zsh` was added, so that problems with your font could be spotted easier.
+
+### `ram` changes
+
+The `ram` segment now shows the available ram instead of free.
+
## v0.6.0
- Fixed a bug where the tag display was broken on detached HEADs.
@@ -24,28 +38,33 @@ Added an option to configure the path separator. If you want something
else than an ordinary slash, you could set
`POWERLEVEL9K_DIR_PATH_SEPARATOR` to whatever you want.
-### New segment 'command_execution_time' added
+#### `truncate_with_package_name` now searches for `composer.json` as well
+
+Now `composer.json` files are searched as well. By default `package.json` still takes
+precedence. If you want to change that, set `POWERLEVEL9K_DIR_PACKAGE_FILES=(composer.json package.json)`.
+
+### New segment `command_execution_time` added
Shows the duration a command needed to run. By default only durations over 3 seconds
are shown (can be adjusted by setting POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD).
-### New segment 'dir_writable' added
+### New segment `dir_writable` added
This segment displays a lock icon if your user has no write permissions in the current folder.
-### New segment 'disk_usage' added
+### New segment `disk_usage` added
This segment will show the usage level of your current partition.
-### New segment 'public_ip' added
+### New segment `public_ip` added
Fetches your Public IP (using ident.me) and displays it in your prompt.
-### New segment 'swift_version' added
+### New segment `swift_version` added
This segment displays the version of Swift that is installed / in your path.
-### New segment 'detect_virt' added
+### New segment `detect_virt` added
Detects and reports if you are in a virtualized session using `systemd`.
diff --git a/README.md b/README.md
index 18f6716d..141b65c7 100644
--- a/README.md
+++ b/README.md
@@ -311,7 +311,7 @@ Customizations available are:
|Default|Truncate whole directories from left. How many is defined by `POWERLEVEL9K_SHORTEN_DIR_LENGTH`|
|`truncate_middle`|Truncates the middle part of a folder. E.g. you are in a folder named "~/MySuperProjects/AwesomeFiles/BoringOffice", then it will truncated to "~/MyS..cts/Awe..les/BoringOffice", if `POWERLEVEL9K_SHORTEN_DIR_LENGTH=3` is also set (controls the amount of characters to be left).|
|`truncate_from_right`|Just leaves the beginning of a folder name untouched. E.g. your folders will be truncated like so: "/ro../Pr../office". How many characters will be untouched is controlled by `POWERLEVEL9K_SHORTEN_DIR_LENGTH`.|
-|`truncate_with_package_name`|Use the `package.json` `name` field to abbreviate the directory path.|
+|`truncate_with_package_name`|Search for a `package.json` or `composer.json` and prints the `name` field to abbreviate the directory path. The precedence and/or files could be set by `POWERLEVEL9K_DIR_PACKAGE_FILES=(package.json composer.json)`. If you have [jq](https://stedolan.github.io/jq/) installed, it will dramatically improve the speed of this strategy.|
|`truncate_with_folder_marker`|Search for a file that is specified by `POWERLEVEL9K_SHORTEN_FOLDER_MARKER` and truncate everything before that (if found, otherwise stop on $HOME and ROOT).|
For example, if you wanted the truncation behavior of the `fish` shell, which
diff --git a/TESTS.md b/TESTS.md
index d4e663dc..d51051c5 100644
--- a/TESTS.md
+++ b/TESTS.md
@@ -12,3 +12,11 @@ Tests in separate files under `test/functions`.
These Tests tend to be more complex in setup than the basic tests. To avoid ending
up in a huge single file, there is one file per segment in `test/segments`.
+
+# Test-VMs
+
+If unit tests are not sufficient (e.g. you have an issue with your prompt that
+occurs only in a specific ZSH framework), then you could use our Test-VMs!
+Currently there are two test VMs. `test-vm` is an Ubuntu machine with several
+pre-installed ZSH frameworks. And there is `test-bsd-vm` which is a FreeBSD!
+For how to run the machines see [here](test-vm/README.md). \ No newline at end of file
diff --git a/debug/font-issues.zsh b/debug/font-issues.zsh
new file mode 100755
index 00000000..166a6ac5
--- /dev/null
+++ b/debug/font-issues.zsh
@@ -0,0 +1,182 @@
+#!/usr/bin/env zsh
+#vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8
+
+# Taken from NeoFetch (slightly modified)
+get_term() {
+ local term
+ # If function was run, stop here.
+ #((term_run == 1)) && return
+
+ # Workaround for macOS systems that
+ # don't support the block below.
+ case "$TERM_PROGRAM" in
+ "iTerm.app") term="iTerm2" ;;
+ "Terminal.app") term="Apple Terminal" ;;
+ "Hyper") term="HyperTerm" ;;
+ *) term="${TERM_PROGRAM/\.app}" ;;
+ esac
+
+ # Check $PPID for terminal emulator.
+ while [[ -z "$term" ]]; do
+ parent="$(get_ppid "$parent")"
+ name="$(get_process_name "$parent")"
+
+ case "${name// }" in
+ "${SHELL/*\/}" | *"sh" | "tmux"* | "screen" | "su"*) ;;
+ "login"* | *"Login"* | "init" | "(init)") term="$(tty)" ;;
+ "ruby" | "1" | "systemd" | "sshd"* | "python"* | "USER"*"PID"*) break ;;
+ "gnome-terminal-") term="gnome-terminal" ;;
+ *) term="${name##*/}" ;;
+ esac
+ done
+
+ # Log that the function was run.
+ #term_run=1
+
+ echo "${term}"
+}
+
+get_term_font() {
+ local term="${1}"
+ #((term_run != 1)) && get_term
+
+ case "$term" in
+ "alacritty"*)
+ term_font="$(awk -F ':|#' '/normal:/ {getline; print}' "${XDG_CONFIG_HOME}/alacritty/alacritty.yml")"
+ term_font="${term_font/*family:}"
+ term_font="${term_font/$'\n'*}"
+ term_font="${term_font/\#*}"
+ ;;
+
+ "Apple_Terminal")
+ term_font="$(osascript -e 'tell application "Terminal" to font name of window frontmost')"
+ ;;
+ "iTerm2")
+ # Unfortunately the profile name is not unique, but it seems to be the only thing
+ # that identifies an active profile. There is the "id of current session of current window"
+ # thou, but that does not match to a guid in the plist.
+ # So, be warned! Collisions may occur!
+ # See: https://groups.google.com/forum/#!topic/iterm2-discuss/0tO3xZ4Zlwg
+ # and: https://gitlab.com/gnachman/iterm2/issues/5586
+ local currentProfileName=$(osascript -e 'tell application "iTerm2" to profile name of current session of current window')
+
+ # Warning: Dynamic profiles are not taken into account here!
+ # https://www.iterm2.com/documentation-dynamic-profiles.html
+
+ local nonAsciiFont
+
+ # Count Guids in "New Bookmarks"; they should be unique
+ local profilesCount=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:" ~/Library/Preferences/com.googlecode.iterm2.plist 2>/dev/null | grep -c "Guid")
+ for idx in $(seq 0 "${profilesCount}"); do
+ local profileName=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Name:" ~/Library/Preferences/com.googlecode.iterm2.plist 2>/dev/null)
+ if [[ "${profileName}" == "${currentProfileName}" ]]; then
+ # "Normal Font"
+ term_font=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Normal\ Font:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+
+ # Font for non-ascii characters
+ # Only check for a different non-ascii font, if the user checked
+ # the "use a different font for non-ascii text" switch.
+ local useDifferentFont=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Use\ Non-ASCII\ Font:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ if [[ "$useDifferentFont" == "true" ]]; then
+ local nonAsciiFont=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Non\ Ascii\ Font:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ if [[ "$term_font" != "$nonAsciiFont" ]]; then
+ term_font="$term_font (normal) / $nonAsciiFont (non-ascii)"
+ fi
+ fi
+ fi
+ done
+ ;;
+
+ "deepin-terminal"*)
+ term_font="$(awk -F '=' '/font=/ {a=$2} /font_size/ {b=$2} END{print a " " b}' "${XDG_CONFIG_HOME}/deepin/deepin-terminal/config.conf")"
+ ;;
+
+ "Hyper"*)
+ term_font="$(awk -F "," '/fontFamily/ {a=$1} END{print a}' "${HOME}/.hyper.js" | awk -F "'" '{a=$2} END{print a}')"
+ ;;
+
+ "konsole"*)
+ # Get Process ID of current konsole window / tab
+ child="$(get_ppid "$$")"
+
+ konsole_instances=($(qdbus | grep 'org.kde.konsole'))
+
+ for i in "${konsole_instances[@]}"; do
+ konsole_sessions=($(qdbus "${i}" | grep '/Sessions/'))
+ for session in "${konsole_sessions[@]}"; do
+ if ((child == "$(qdbus "${i}" "${session}" processId)")); then
+ profile="$(qdbus "${i}" "${session}" environment | awk -F '=' '/KONSOLE_PROFILE_NAME/ {print $2}')"
+ break
+ fi
+ done
+ [[ "$profile" ]] && break
+ done
+
+ # We could have two profile files for the same profile name, take first match
+ profile_filename="$(grep -l "Name=${profile}" "${HOME}"/.local/share/konsole/*.profile)"
+ profile_filename="${profile_filename/$'\n'*}"
+ [[ "$profile_filename" ]] && term_font="$(awk -F '=|,' '/Font=/ {print $2 " " $3}' "$profile_filename")"
+ ;;
+
+ "mintty")
+ term_font="$(awk -F '=' '!/^($|#)/ && /Font/ {printf $2; exit}' "${HOME}/.minttyrc")"
+ ;;
+
+ "pantheon"*)
+ term_font="$(gsettings get org.pantheon.terminal.settings font)"
+ [[ -z "${term_font//\'}" ]] && term_font="$(gsettings get org.gnome.desktop.interface monospace-font-name)"
+ term_font="$(trim_quotes "$term_font")"
+ ;;
+
+ "sakura"*)
+ term_font="$(awk -F '=' '/^font=/ {a=$2} END{print a}' "${XDG_CONFIG_HOME}/sakura/sakura.conf")"
+ ;;
+
+ "terminology")
+ term_font="$(strings "${XDG_CONFIG_HOME}/terminology/config/standard/base.cfg" | awk '/^font\.name$/{print a}{a=$0}')"
+ term_font="${term_font/.pcf}"
+ term_font="${term_font/:*}"
+ ;;
+
+ "termite")
+ [[ -f "${XDG_CONFIG_HOME}/termite/config" ]] && termite_config="${XDG_CONFIG_HOME}/termite/config"
+ term_font="$(awk -F '= ' '/\[options\]/ {opt=1} /^font/ {if(opt==1) a=$2; opt=0} END{print a}' "/etc/xdg/termite/config" "$termite_config")"
+ ;;
+
+ "urxvt" | "urxvtd" | "rxvt-unicode" | "xterm")
+ term_font="$(grep -i -F "${term/d}*font" < <(xrdb -query))"
+ term_font="${term_font/*font:}"
+ term_font="$(trim "$term_font")"
+
+ # Xresources has two different font formats, this checks which
+ # one is in use and formats it accordingly.
+ case "$term_font" in
+ *"xft:"*)
+ term_font="${term_font/xft:}"
+ term_font="${term_font/:*}"
+ ;;
+
+ "-"*) term_font="$(awk -F '\\-' '{printf $3}' <<< "$term_font")" ;;
+ esac
+ ;;
+
+ "xfce4-terminal")
+ term_font="$(awk -F '=' '/^FontName/ {a=$2} END{print a}' "${XDG_CONFIG_HOME}/xfce4/terminal/terminalrc")"
+ ;;
+ esac
+
+ echo "${term_font}"
+}
+
+local currentTerminal=$(get_term)
+local currentFont=$(get_term_font "${currentTerminal}")
+print -P "===== Font debugging ====="
+print -P "You are using %F{blue}${currentTerminal}%f with Font %F{blue}${currentFont}%f\n"
+
+if [[ $(echo "${currentFont}" | grep -c -E "Powerline|Awesome|Nerd") -eq 0 ]]; then
+ print -P "%F{yellow}WARNING%f It does not seem like you use an Powerline-enabled or Awesome Terminal Font!"
+ print -P "Please make sure that your font settings are correct!"
+else
+ print -P "Your font settings seem to be all right. If you still have issues,"
+ print -P "it is more likely to be a font issue than a Powerlevel9k related one."
+fi
diff --git a/debug/iterm.zsh b/debug/iterm.zsh
new file mode 100755
index 00000000..702175ff
--- /dev/null
+++ b/debug/iterm.zsh
@@ -0,0 +1,86 @@
+#!/usr/bin/env zsh
+#vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8
+
+if [[ "$TERM_PROGRAM" != "iTerm.app" ]]; then
+ print "Your Terminal Emulator does not appear to be iTerm2!"
+ print "This debug script is intended only for iTerm2 terminals."
+ exit 1
+fi
+
+if [[ ! -x "/usr/libexec/PlistBuddy" ]]; then
+ print "To use this debug script, you need to install XCode!"
+ exit 2
+fi
+
+local normalFont
+local type
+local command
+local ambiguousDoubleWidth
+local minimumContrast
+local useDifferentFont
+
+# Unfortunately the profile name is not unique, but it seems to be the only
+# thing that identifies an active profile. There is the "ID of current session
+# of current window" though, but that does not match to a `guid` in the plist.
+# So, be warned - collisions may occur!
+# See: https://groups.google.com/forum/#!topic/iterm2-discuss/0tO3xZ4Zlwg
+local currentProfileName=$(osascript -e 'tell application "iTerm2" to profile name of current session of current window')
+
+# Warning: Dynamic profiles are not taken into account here!
+# https://www.iterm2.com/documentation-dynamic-profiles.html
+
+# Count `guids` in "New Bookmarks"; they should be unique
+local profilesCount=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:" ~/Library/Preferences/com.googlecode.iterm2.plist 2>/dev/null | grep -c "Guid")
+for idx in $(seq 0 "${profilesCount}"); do
+ local profileName=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Name:" ~/Library/Preferences/com.googlecode.iterm2.plist 2>/dev/null)
+ if [[ "${profileName}" == "${currentProfileName}" ]]; then
+ # "Normal Font"
+ normalFont=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Normal\ Font:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ type=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Terminal\ Type:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ command=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Command:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ ambiguousDoubleWidth=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Ambiguous\ Double\ Width:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ minimumContrast=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Minimum\ Contrast:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+
+ # Font for non-ascii characters
+ # Only check for a different non-ASCII font, if the user checked
+ # the "use a different font for non-ascii text" switch.
+ useDifferentFont=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Use\ Non-ASCII\ Font:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ if [[ "$useDifferentFont" == "true" ]]; then
+ nonAsciiFont=$(/usr/libexec/PlistBuddy -c "Print :New\ Bookmarks:${idx}:Non\ Ascii\ Font:" ~/Library/Preferences/com.googlecode.iterm2.plist)
+ if [[ "$normalFont" != "$nonAsciiFont" ]]; then
+ normalFont="$normalFont (normal) / $nonAsciiFont (non-ascii)"
+ fi
+ fi
+ break
+ fi
+done
+
+print -P "You use %F{blue}iTerm2%f with the following settings:"
+print -P " Font: ${normalFont}"
+print -P " Terminal-Type: ${type}"
+print -P " Command: ${command}"
+
+#############################
+# Analyse possible problems #
+#############################
+local problemsFound
+if [[ "${ambiguousDoubleWidth}" == "true" ]]; then
+ problemsFound="${problemsFound}\n * Please uncheck 'Treat ambiguous characters as double-width'."
+fi
+if (( minimumContrast > 0 )); then
+ problemsFound="${problemsFound}\n * Please set minimum contrast to zero."
+fi
+if [[ $(echo "${normalFont}" | grep -c -E "Powerline|Awesome|Nerd|Source Code Pro") -eq 0 ]]; then
+ problemsFound="${problemsFound}\n * It does not seem like you use an Powerline-enabled or Awesome Terminal Font!"
+fi
+
+#############################
+# Output problems #
+#############################
+if [[ -n "${problemsFound}" ]]; then
+ print -P "\n"
+ print -P "%F{yellow}Possible Problems found:%f"
+ print -P "${problemsFound}"
+else
+ print -P "%F{green}No Problems found%f. Yay!"
+fi
diff --git a/functions/icons.zsh b/functions/icons.zsh
index 26412543..413ea19b 100644
--- a/functions/icons.zsh
+++ b/functions/icons.zsh
@@ -86,6 +86,8 @@ case $POWERLEVEL9K_MODE in
'awesome-fontconfig')
# fontconfig with awesome-font required! See
# https://github.com/gabrielelana/awesome-terminal-fonts
+ # Set the right locale to protect special characters
+ local LC_ALL="" LC_CTYPE="en_US.UTF-8"
icons=(
LEFT_SEGMENT_SEPARATOR $'\uE0B0' # 
RIGHT_SEGMENT_SEPARATOR $'\uE0B2' # 
@@ -149,6 +151,8 @@ case $POWERLEVEL9K_MODE in
'nerdfont-fontconfig')
# nerd-font patched (complete) font required! See
# https://github.com/ryanoasis/nerd-fonts
+ # Set the right locale to protect special characters
+ local LC_ALL="" LC_CTYPE="en_US.UTF-8"
icons=(
LEFT_SEGMENT_SEPARATOR $'\uE0B0' # 
RIGHT_SEGMENT_SEPARATOR $'\uE0B2' # 
@@ -156,22 +160,23 @@ case $POWERLEVEL9K_MODE in
LEFT_SUBSEGMENT_SEPARATOR $'\uE0B1' # 
RIGHT_SUBSEGMENT_SEPARATOR $'\uE0B3' # 
CARRIAGE_RETURN_ICON $'\u21B5' # ↵
- ROOT_ICON $'\u26A1' # ⚡
+ ROOT_ICON $'\uE614 ' # 
RUBY_ICON $'\uF219 ' # 
AWS_ICON $'\uF270' # 
- AWS_EB_ICON $'\U1F331 ' # 🌱
+ AWS_EB_ICON $'\UF1BD ' # 
BACKGROUND_JOBS_ICON $'\uF013 ' # 
TEST_ICON $'\uF188' # 
- TODO_ICON $'\u2611' # ☑
- BATTERY_ICON $'\uF241 ' # 
- OK_ICON $'\u2713' # ✓
- FAIL_ICON $'\u2718' # ✘
+ TODO_ICON $'\uF133' # 
+ BATTERY_ICON $'\UF240 ' # 
+ DISK_ICON $'\uF0A0' # 
+ OK_ICON $'\uF00C' # 
+ FAIL_ICON $'\uF00D' # 
SYMFONY_ICON $'\uE757' # 
- NODE_ICON $'\u2B22' # ⬢
+ NODE_ICON $'\uE617 ' # 
MULTILINE_FIRST_PROMPT_PREFIX $'\u256D'$'\U2500' # ╭─
MULTILINE_SECOND_PROMPT_PREFIX $'\u2570'$'\U2500 ' # ╰─
APPLE_ICON $'\uF179' # 
- FREEBSD_ICON $'\U1F608 ' # 😈
+ FREEBSD_ICON $'\UF30E ' # 
LINUX_ICON $'\uF17C' # 
SUNOS_ICON $'\uF185 ' # 
HOME_ICON $'\uF015' # 
@@ -189,22 +194,30 @@ case $POWERLEVEL9K_MODE in
VCS_INCOMING_CHANGES_ICON $'\uF01A ' # 
VCS_OUTGOING_CHANGES_ICON $'\uF01B ' # 
VCS_TAG_ICON $'\uF02B ' # 
- VCS_BOOKMARK_ICON $'\uF462' # 
+ VCS_BOOKMARK_ICON $'\uF461 ' # 
VCS_COMMIT_ICON $'\uE729 ' # 
- VCS_BRANCH_ICON $'\uF126' # 
+ VCS_BRANCH_ICON $'\uF126 ' # 
VCS_REMOTE_BRANCH_ICON $'\uE728 ' # 
VCS_GIT_ICON $'\uF113 ' # 
+ VCS_GIT_GITHUB_ICON $'\uE709 ' # 
+ VCS_GIT_BITBUCKET_ICON $'\uE703 ' # 
+ VCS_GIT_GITLAB_ICON $'\uF296 ' # 
VCS_HG_ICON $'\uF0C3 ' # 
- VCS_SVN_ICON '(svn) '
- RUST_ICON $'\uE7A8' # 
- PYTHON_ICON $'\uE73C' # 
+ VCS_SVN_ICON $'\uE72D ' # 
+ RUST_ICON $'\uE7A8 ' # 
+ PYTHON_ICON $'\UE73C ' # 
SWIFT_ICON $'\uE755' # 
- PUBLIC_IP_ICON ''
+ PUBLIC_IP_ICON $'\UF0AC' # 
+ LOCK_ICON $'\UF023' # 
+ EXECUTION_TIME_ICON $'\uF252' # 
+ SSH_ICON $'\uF489' # 
)
;;
*)
# Powerline-Patched Font required!
# See https://github.com/Lokaltog/powerline-fonts
+ # Set the right locale to protect special characters
+ local LC_ALL="" LC_CTYPE="en_US.UTF-8"
icons=(
LEFT_SEGMENT_SEPARATOR $'\uE0B0' # 
RIGHT_SEGMENT_SEPARATOR $'\uE0B2' # 
@@ -270,6 +283,8 @@ esac
# Override the above icon settings with any user-defined variables.
case $POWERLEVEL9K_MODE in
'flat')
+ # Set the right locale to protect special characters
+ local LC_ALL="" LC_CTYPE="en_US.UTF-8"
icons[LEFT_SEGMENT_SEPARATOR]=''
icons[RIGHT_SEGMENT_SEPARATOR]=''
icons[LEFT_SUBSEGMENT_SEPARATOR]='|'
@@ -300,8 +315,20 @@ function print_icon() {
fi
}
+# Get a list of configured icons
+# * $1 string - If "original", then the original icons are printed,
+# otherwise "print_icon" is used, which takes the users
+# overrides into account.
get_icon_names() {
- for key in ${(@k)icons}; do
- echo "POWERLEVEL9K_$key: ${icons[$key]}"
+ # Iterate over a ordered list of keys of the icons array
+ for key in ${(@kon)icons}; do
+ echo -n "POWERLEVEL9K_$key: "
+ if [[ "${1}" == "original" ]]; then
+ # print the original icons as they are defined in the array above
+ echo "${icons[$key]}"
+ else
+ # print the icons as they are configured by the user
+ echo "$(print_icon "$key")"
+ fi
done
}
diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme
index 5fab0190..52b56f4e 100755
--- a/powerlevel9k.zsh-theme
+++ b/powerlevel9k.zsh-theme
@@ -655,12 +655,24 @@ prompt_dir() {
subdirectory_path=$(truncatePathFromRight "${current_dir:${#${(S%%)package_path//$~zero/}}}")
# Parse the 'name' from the package.json; if there are any problems, just
# print the file path
- if name=$( cat "$package_path/package.json" 2> /dev/null | grep -m 1 "\"name\""); then
- name=$(echo $name | awk -F ':' '{print $2}' | awk -F '"' '{print $2}')
+ defined POWERLEVEL9K_DIR_PACKAGE_FILES || POWERLEVEL9K_DIR_PACKAGE_FILES=(package.json composer.json)
+ local pkgFile="unknown"
+ for file in "${POWERLEVEL9K_DIR_PACKAGE_FILES[@]}"; do
+ if [[ -f "${package_path}/${file}" ]]; then
+ pkgFile="${package_path}/${file}"
+ break;
+ fi
+ done
+
+ local packageName=$(jq '.name' ${pkgFile} 2> /dev/null \
+ || node -e 'console.log(require(process.argv[1]).name);' ${pkgFile} 2>/dev/null \
+ || cat "${pkgFile}" 2> /dev/null | grep -m 1 "\"name\"" | awk -F ':' '{print $2}' | awk -F '"' '{print $2}' 2>/dev/null \
+ )
+ if [[ -n "${packageName}" ]]; then
# Instead of printing out the full path, print out the name of the package
# from the package.json and append the current subdirectory
- current_path="`echo $name | tr -d '"'`$subdirectory_path"
+ current_path="`echo $packageName | tr -d '"'`$subdirectory_path"
else
current_path=$(truncatePathFromRight "$(pwd | sed -e "s,^$HOME,~,")" )
fi
@@ -891,15 +903,17 @@ prompt_ram() {
local base=''
local ramfree=0
if [[ "$OS" == "OSX" ]]; then
+ # Available = Free + Inactive
+ # See https://support.apple.com/en-us/HT201538
ramfree=$(vm_stat | grep "Pages free" | grep -o -E '[0-9]+')
+ ramfree=$((ramfree + $(vm_stat | grep "Pages inactive" | grep -o -E '[0-9]+')))
# Convert pages into Bytes
ramfree=$(( ramfree * 4096 ))
else
if [[ "$OS" == "BSD" ]]; then
- ramfree=$(vmstat | grep -E '([0-9]+\w+)+' | awk '{print $5}')
- base='M'
+ ramfree=$(grep 'avail memory' /var/run/dmesg.boot | awk '{print $4}')
else
- ramfree=$(grep -o -E "MemFree:\s+[0-9]+" /proc/meminfo | grep -o "[0-9]*")
+ ramfree=$(grep -o -E "MemAvailable:\s+[0-9]+" /proc/meminfo | grep -o "[0-9]*")
base='K'
fi
fi
diff --git a/test-bsd-vm/Vagrantfile b/test-bsd-vm/Vagrantfile
new file mode 100644
index 00000000..7df512a3
--- /dev/null
+++ b/test-bsd-vm/Vagrantfile
@@ -0,0 +1,87 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# All Vagrant configuration is done below. The "2" in Vagrant.configure
+# configures the configuration version (we support older styles for
+# backwards compatibility). Please don't change it unless you know what
+# you're doing.
+Vagrant.configure("2") do |config|
+ # The most common configuration options are documented and commented below.
+ # For a complete reference, please see the online documentation at
+ # https://docs.vagrantup.com.
+
+ # Every Vagrant development environment requires a box. You can search for
+ # boxes at https://atlas.hashicorp.com/search.
+ config.vm.box = "freebsd/FreeBSD-11.0-STABLE"
+
+ # Bootstrap
+ config.vm.provision :shell, path: "bootstrap-zero.sh", privileged: true
+ config.vm.provision :shell, path: "bootstrap.sh", privileged: false
+ config.vm.provision :shell, path: "../test-vm-providers/plain.sh", privileged: false
+
+ # Disable automatic box update checking. If you disable this, then
+ # boxes will only be checked for updates when the user runs
+ # `vagrant box outdated`. This is not recommended.
+ # config.vm.box_check_update = false
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine. In the example below,
+ # accessing "localhost:8080" will access port 80 on the guest machine.
+ # config.vm.network "forwarded_port", guest: 80, host: 8080
+
+ # Create a private network, which allows host-only access to the machine
+ # using a specific IP.
+ config.vm.network "private_network", ip: "192.168.33.10"
+
+ # Create a public network, which generally matched to bridged network.
+ # Bridged networks make the machine appear as another physical device on
+ # your network.
+ #config.vm.network "public_network"
+
+ # The BSD base box does not define a MAC address. Whysoever.
+ config.vm.base_mac = "8AAB4975994A"
+
+ # There is no BASH for root on BSD. We need to set another shell.
+ # See https://www.freebsd.org/doc/en/articles/linux-users/shells.html
+ config.ssh.shell = "/bin/sh"
+
+ # Share an additional folder to the guest VM. The first argument is
+ # the path on the host to the actual folder. The second argument is
+ # the path on the guest to mount the folder. And the optional third
+ # argument is a set of non-required options.
+ config.vm.synced_folder "..", "/vagrant_data", type: "nfs"
+ config.vm.synced_folder ".", "/vagrant", type: "nfs"
+
+ # Provider-specific configuration so you can fine-tune various
+ # backing providers for Vagrant. These expose provider-specific options.
+ # Example for VirtualBox:
+ config.vm.provider "virtualbox" do |vb|
+
+ # Change name to "powerlevel9k-bsd"
+ vb.name = "powerlevel9k-bsd"
+
+ # Display the VirtualBox GUI when booting the machine
+ #vb.gui = true
+
+ # Customize the amount of memory on the VM:
+ vb.memory = "256"
+ end
+
+ # View the documentation for the provider you are using for more
+ # information on available options.
+
+ # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
+ # such as FTP and Heroku are also available. See the documentation at
+ # https://docs.vagrantup.com/v2/push/atlas.html for more information.
+ # config.push.define "atlas" do |push|
+ # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
+ # end
+
+ # Enable provisioning with a shell script. Additional provisioners such as
+ # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
+ # documentation for more information about their specific syntax and use.
+ # config.vm.provision "shell", inline: <<-SHELL
+ # apt-get update
+ # apt-get install -y apache2
+ # SHELL
+end
diff --git a/test-bsd-vm/bootstrap-zero.sh b/test-bsd-vm/bootstrap-zero.sh
new file mode 100644
index 00000000..35dcd7f3
--- /dev/null
+++ b/test-bsd-vm/bootstrap-zero.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+pkg install -y sudo \ No newline at end of file
diff --git a/test-bsd-vm/bootstrap.sh b/test-bsd-vm/bootstrap.sh
new file mode 100644
index 00000000..ba27ffb3
--- /dev/null
+++ b/test-bsd-vm/bootstrap.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# Install ZSH
+sudo pkg install -y zsh
+sudo chsh -s `which zsh` vagrant
+sudo ln -s /usr/local/bin/zsh /usr/bin/zsh
+
+# Install git
+sudo pkg install -y git
+# Install mercurial
+sudo pkg install -y mercurial
+# Install subversion
+sudo pkg install -y subversion \ No newline at end of file
diff --git a/test-vm-providers/plain.sh b/test-vm-providers/plain.sh
new file mode 100644
index 00000000..b827a0c4
--- /dev/null
+++ b/test-vm-providers/plain.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/zsh
+
+echo 'LANG=en_US.UTF-8' >! ~/.zshrc
+echo 'source /vagrant_data/powerlevel9k.zsh-theme' >> ~/.zshrc
+
+echo 'echo "Have a look at the ~/p9k folder for prepared test setups."' >> ~/.zshrc
+
+# setup environment
+/vagrant_data/test-vm-providers/setup-environment.sh \ No newline at end of file
diff --git a/test-vm-providers/setup-environment.sh b/test-vm-providers/setup-environment.sh
new file mode 100755
index 00000000..0e8beb6d
--- /dev/null
+++ b/test-vm-providers/setup-environment.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/zsh
+
+OLDPWD="$(pwd)"
+cd $HOME
+
+TESTFOLDER="${HOME}/p9k"
+mkdir -p $TESTFOLDER
+cd $TESTFOLDER
+
+# Make a deep test folder
+mkdir -p deep-folder/1/12/123/1234/12345/123456/1234567/123455678/123456789
+
+# Make a git repo
+mkdir git-repo
+cd git-repo
+git config --global user.email "test@powerlevel9k.theme"
+git config --global user.name "Testing Tester"
+git init
+echo "TEST" >> testfile
+git add testfile
+git commit -m "Initial commit"
+cd $TESTFOLDER
+
+# Make a Mercurial repo
+mkdir hg-repo
+cd hg-repo
+export HGUSER="Test bot <bot@example.com>"
+hg init
+echo "TEST" >> testfile
+hg add testfile
+hg ci -m "Initial commit"
+cd $TESTFOLDER
+
+# Setup a SVN folder
+svnadmin create ~/.svn-repo
+mkdir svn-repo
+svn checkout "file://${HOME}/.svn-repo" "svn-repo"
+cd svn-repo
+echo "TEST" >> testfile
+svn add testfile
+svn commit -m "Initial commit"
+cd $TESTFOLDER
+
+cd $OLDPWD \ No newline at end of file
diff --git a/test-vm/Vagrantfile b/test-vm/Vagrantfile
index ee53fcdf..a421c706 100644
--- a/test-vm/Vagrantfile
+++ b/test-vm/Vagrantfile
@@ -16,7 +16,7 @@ Vagrant.configure(2) do |config|
# Bootstrap
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
- config.vm.provision :shell, path: "plain.sh", privileged: false
+ config.vm.provision :shell, path: "../test-vm-providers/plain.sh", privileged: false
config.vm.provision :shell, path: "antigen.sh"
config.vm.provision :shell, path: "prezto.sh"
config.vm.provision :shell, path: "omz.sh"
diff --git a/test-vm/antigen.sh b/test-vm/antigen.sh
index 0f44c6ca..2c563322 100644
--- a/test-vm/antigen.sh
+++ b/test-vm/antigen.sh
@@ -24,4 +24,7 @@ antigen apply
mkdir ~/antigen
curl -qL https://raw.githubusercontent.com/zsh-users/antigen/master/antigen.zsh > ~/antigen/antigen.zsh
source ~/antigen/antigen.zsh
+
+ # setup environment
+ /vagrant_data/test-vm-providers/setup-environment.sh
)
diff --git a/test-vm/bootstrap.sh b/test-vm/bootstrap.sh
index 9651c4eb..f680d4b8 100644
--- a/test-vm/bootstrap.sh
+++ b/test-vm/bootstrap.sh
@@ -7,3 +7,13 @@ sudo apt-get install -y git
sudo apt-get install -y zsh
sudo chsh -s $(which zsh) vagrant
+
+# Install mercurial
+sudo apt-get install -y mercurial
+# Install Subversion
+sudo apt-get install -y subversion
+# install golang
+echo 'golang-go golang-go/dashboard boolean false' | sudo debconf-set-selections
+sudo apt-get install -y golang
+# Install dependencies for tests
+sudo apt-get install -y jq node ruby python python-virtualenv \ No newline at end of file
diff --git a/test-vm/omz.sh b/test-vm/omz.sh
index 953f5c8f..73b659f3 100644
--- a/test-vm/omz.sh
+++ b/test-vm/omz.sh
@@ -28,4 +28,6 @@ plugins=(git rake ruby)
source $ZSH/oh-my-zsh.sh
' > $HOME/.zshrc
+ # setup environment
+ /vagrant_data/test-vm-providers/setup-environment.sh
)
diff --git a/test-vm/plain.sh b/test-vm/plain.sh
deleted file mode 100644
index 9c8445f4..00000000
--- a/test-vm/plain.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/zsh
-
-echo 'source /vagrant_data/powerlevel9k.zsh-theme' > ~/.zshrc
diff --git a/test-vm/prezto.sh b/test-vm/prezto.sh
index af4e7454..3ac38503 100644
--- a/test-vm/prezto.sh
+++ b/test-vm/prezto.sh
@@ -23,4 +23,7 @@ chmod 440 /etc/sudoers.d/$NEW_USER
ln -s /vagrant_data/powerlevel9k.zsh-theme ~/.zprezto/modules/prompt/functions/prompt_powerlevel9k_setup
sed -i "s/theme\ 'sorin'/theme\ 'powerlevel9k'/g" ~/.zpreztorc
+
+ # setup environment
+ /vagrant_data/test-vm-providers/setup-environment.sh
)
diff --git a/test/functions/icons.spec b/test/functions/icons.spec
new file mode 100755
index 00000000..c8d88644
--- /dev/null
+++ b/test/functions/icons.spec
@@ -0,0 +1,362 @@
+#!/usr/bin/env zsh
+#vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8
+
+# Required for shunit2 to run correctly
+setopt shwordsplit
+SHUNIT_PARENT=$0
+
+function setUp() {
+ # Store old value for LC_CTYPE
+ _OLD_LC_CTYPE="${LC_CTYPE}"
+ # Reset actual LC_CTYPE
+ unset LC_CTYPE
+
+ # Store old P9K mode
+ _OLD_P9K_MODE="${POWERLEVEL9K_MODE}"
+}
+
+function tearDown() {
+ # Restore LC_CTYPE
+ LC_CTYPE="${_OLD_LC_CTYPE}"
+
+ # Restore old P9K mode
+ POWERLEVEL9K_MODE="${_OLD_P9K_MODE}"
+}
+
+function testLcCtypeIsSetCorrectlyInDefaultMode() {
+ POWERLEVEL9K_MODE="default"
+ # Load Powerlevel9k
+ source functions/icons.zsh
+
+ assertEquals 'en_US.UTF-8' "${LC_CTYPE}"
+}
+
+function testLcCtypeIsSetCorrectlyInAwesomePatchedMode() {
+ POWERLEVEL9K_MODE="awesome-patched"
+ # Load Powerlevel9k
+ source functions/icons.zsh
+
+ assertEquals 'en_US.UTF-8' "${LC_CTYPE}"
+}
+
+function testLcCtypeIsSetCorrectlyInAwesomeFontconfigMode() {
+ POWERLEVEL9K_MODE="awesome-fontconfig"
+ # Load Powerlevel9k
+ source functions/icons.zsh
+
+ assertEquals 'en_US.UTF-8' "${LC_CTYPE}"
+}
+
+function testLcCtypeIsSetCorrectlyInNerdfontFontconfigMode() {
+ POWERLEVEL9K_MODE="nerdfont-fontconfig"
+ # Load Powerlevel9k
+ source functions/icons.zsh
+
+ assertEquals 'en_US.UTF-8' "${LC_CTYPE}"
+}
+
+function testLcCtypeIsSetCorrectlyInFlatMode() {
+ POWERLEVEL9K_MODE="flat"
+ # Load Powerlevel9k
+ source functions/icons.zsh
+
+ assertEquals 'en_US.UTF-8' "${LC_CTYPE}"
+}
+
+function testLcCtypeIsSetCorrectlyInCompatibleMode() {
+ POWERLEVEL9K_MODE="compatible"
+ # Load Powerlevel9k
+ source functions/icons.zsh
+
+ assertEquals 'en_US.UTF-8' "${LC_CTYPE}"
+}
+
+# Go through all icons defined in default mode, and
+# check if all of them are defined in the other modes.
+function testAllIconsAreDefinedLikeInDefaultMode() {
+ # Always compare against this mode
+ local _P9K_TEST_MODE="default"
+ POWERLEVEL9K_MODE="${_P9K_TEST_MODE}"
+ source functions/icons.zsh
+ # _ICONS_UNDER_TEST is an array of just the keys of $icons.
+ # We later check via (r) "subscript" flag that our key
+ # is in the values of our flat array.
+ typeset -ah _ICONS_UNDER_TEST
+ _ICONS_UNDER_TEST=(${(k)icons[@]})
+
+ # Switch to "awesome-patched" mode
+ POWERLEVEL9K_MODE="awesome-patched"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ # Iterate over all keys found in the _ICONS_UNDER_TEST
+ # array and compare it with the icons array of the
+ # current POWERLEVEL9K_MODE.
+ # Use parameter expansion, to directly check if the
+ # key exists in the flat current array of keys. That
+ # is quite complicated, but there seems no easy way
+ # to check the mere existance of a key in an array.
+ # The usual way would always return the value, so that
+ # would do the wrong thing as we have some (on purpose)
+ # empty values.
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "awesome-fontconfig" mode
+ POWERLEVEL9K_MODE="awesome-fontconfig"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "nerdfont-fontconfig" mode
+ POWERLEVEL9K_MODE="nerdfont-fontconfig"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "flat" mode
+ POWERLEVEL9K_MODE="flat"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "compatible" mode
+ POWERLEVEL9K_MODE="compatible"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ unset current_icons
+ unset _ICONS_UNDER_TEST
+}
+
+# Go through all icons defined in awesome-patched mode, and
+# check if all of them are defined in the other modes.
+function testAllIconsAreDefinedLikeInAwesomePatchedMode() {
+ # Always compare against this mode
+ local _P9K_TEST_MODE="awesome-patched"
+ POWERLEVEL9K_MODE="$_P9K_TEST_MODE"
+ source functions/icons.zsh
+ # _ICONS_UNDER_TEST is an array of just the keys of $icons.
+ # We later check via (r) "subscript" flag that our key
+ # is in the values of our flat array.
+ typeset -ah _ICONS_UNDER_TEST
+ _ICONS_UNDER_TEST=(${(k)icons[@]})
+
+ # Switch to "default" mode
+ POWERLEVEL9K_MODE="default"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ # Iterate over all keys found in the _ICONS_UNDER_TEST
+ # array and compare it with the icons array of the
+ # current POWERLEVEL9K_MODE.
+ # Use parameter expansion, to directly check if the
+ # key exists in the flat current array of keys. That
+ # is quite complicated, but there seems no easy way
+ # to check the mere existance of a key in an array.
+ # The usual way would always return the value, so that
+ # would do the wrong thing as we have some (on purpose)
+ # empty values.
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "awesome-fontconfig" mode
+ POWERLEVEL9K_MODE="awesome-fontconfig"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "nerdfont-fontconfig" mode
+ POWERLEVEL9K_MODE="nerdfont-fontconfig"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "flat" mode
+ POWERLEVEL9K_MODE="flat"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "compatible" mode
+ POWERLEVEL9K_MODE="compatible"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ unset current_icons
+ unset _ICONS_UNDER_TEST
+}
+
+# Go through all icons defined in awesome-fontconfig mode, and
+# check if all of them are defined in the other modes.
+function testAllIconsAreDefinedLikeInAwesomeFontconfigMode() {
+ # Always compare against this mode
+ local _P9K_TEST_MODE="awesome-fontconfig"
+ POWERLEVEL9K_MODE="$_P9K_TEST_MODE"
+ source functions/icons.zsh
+ # _ICONS_UNDER_TEST is an array of just the keys of $icons.
+ # We later check via (r) "subscript" flag that our key
+ # is in the values of our flat array.
+ typeset -ah _ICONS_UNDER_TEST
+ _ICONS_UNDER_TEST=(${(k)icons[@]})
+
+ # Switch to "default" mode
+ POWERLEVEL9K_MODE="default"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ # Iterate over all keys found in the _ICONS_UNDER_TEST
+ # array and compare it with the icons array of the
+ # current POWERLEVEL9K_MODE.
+ # Use parameter expansion, to directly check if the
+ # key exists in the flat current array of keys. That
+ # is quite complicated, but there seems no easy way
+ # to check the mere existance of a key in an array.
+ # The usual way would always return the value, so that
+ # would do the wrong thing as we have some (on purpose)
+ # empty values.
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "awesome-patched" mode
+ POWERLEVEL9K_MODE="awesome-patched"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "nerdfont-fontconfig" mode
+ POWERLEVEL9K_MODE="nerdfont-fontconfig"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "flat" mode
+ POWERLEVEL9K_MODE="flat"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "compatible" mode
+ POWERLEVEL9K_MODE="compatible"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ unset current_icons
+ unset _ICONS_UNDER_TEST
+}
+
+# Go through all icons defined in nerdfont-fontconfig mode, and
+# check if all of them are defined in the other modes.
+function testAllIconsAreDefinedLikeInNerdfontFontconfigMode() {
+ # Always compare against this mode
+ local _P9K_TEST_MODE="nerdfont-fontconfig"
+ POWERLEVEL9K_MODE="$_P9K_TEST_MODE"
+ source functions/icons.zsh
+ # _ICONS_UNDER_TEST is an array of just the keys of $icons.
+ # We later check via (r) "subscript" flag that our key
+ # is in the values of our flat array.
+ typeset -ah _ICONS_UNDER_TEST
+ _ICONS_UNDER_TEST=(${(k)icons[@]})
+
+ # Switch to "default" mode
+ POWERLEVEL9K_MODE="default"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ # Iterate over all keys found in the _ICONS_UNDER_TEST
+ # array and compare it with the icons array of the
+ # current POWERLEVEL9K_MODE.
+ # Use parameter expansion, to directly check if the
+ # key exists in the flat current array of keys. That
+ # is quite complicated, but there seems no easy way
+ # to check the mere existance of a key in an array.
+ # The usual way would always return the value, so that
+ # would do the wrong thing as we have some (on purpose)
+ # empty values.
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "awesome-patched" mode
+ POWERLEVEL9K_MODE="awesome-patched"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "awesome-fontconfig" mode
+ POWERLEVEL9K_MODE="awesome-fontconfig"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "flat" mode
+ POWERLEVEL9K_MODE="flat"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ # Switch to "compatible" mode
+ POWERLEVEL9K_MODE="compatible"
+ source functions/icons.zsh
+ typeset -ah current_icons
+ current_icons=(${(k)icons[@]})
+ for key in ${_ICONS_UNDER_TEST}; do
+ assertTrue "The key ${key} does exist in ${_P9K_TEST_MODE} mode, but not in ${POWERLEVEL9K_MODE}!" "(( ${+current_icons[(r)$key]} ))"
+ done
+
+ unset current_icons
+ unset _ICONS_UNDER_TEST
+}
+
+source shunit2/source/2.1/src/shunit2 \ No newline at end of file
diff --git a/test/segments/dir.spec b/test/segments/dir.spec
index ce6869b7..b2991175 100755
--- a/test/segments/dir.spec
+++ b/test/segments/dir.spec
@@ -114,6 +114,112 @@ function testTruncateWithFolderMarkerWithChangedFolderMarker() {
unset POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
}
+function testTruncateWithPackageNameWorks() {
+ local p9kFolder=$(pwd)
+ local BASEFOLDER=/tmp/powerlevel9k-test
+ local FOLDER=$BASEFOLDER/1/12/123/1234/12345/123456/1234567/12345678/123456789
+ mkdir -p $FOLDER
+
+ cd /tmp/powerlevel9k-test
+ echo '
+{
+ "name": "My_Package"
+}
+' > package.json
+ # Unfortunately: The main folder must be a git repo..
+ git init &>/dev/null
+
+ # Go back to deeper folder
+ cd "${FOLDER}"
+
+ POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(dir)
+ POWERLEVEL9K_SHORTEN_DIR_LENGTH=2
+ POWERLEVEL9K_SHORTEN_STRATEGY='truncate_with_package_name'
+
+ assertEquals "%K{blue} %F{black}My_Package/1/12/123/12…/12…/12…/12…/12…/123456789 %k%F{blue}%f " "$(build_left_prompt)"
+
+ # Go back
+ cd $p9kFolder
+ rm -fr $BASEFOLDER
+ unset POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
+ unset POWERLEVEL9K_SHORTEN_STRATEGY
+ unset POWERLEVEL9K_SHORTEN_DIR_LENGTH
+}
+
+function testTruncateWithPackageNameIfRepoIsSymlinkedInsideDeepFolder() {
+ local p9kFolder=$(pwd)
+ local BASEFOLDER=/tmp/powerlevel9k-test
+ local FOLDER=$BASEFOLDER/1/12/123/1234/12345/123456/1234567/12345678/123456789
+ mkdir -p $FOLDER
+ cd $FOLDER
+
+ # Unfortunately: The main folder must be a git repo..
+ git init &>/dev/null
+
+ echo '
+{
+ "name": "My_Package"
+}
+' > package.json
+
+ # Create a subdir inside the repo
+ mkdir -p asdfasdf/qwerqwer
+
+ cd $BASEFOLDER
+ ln -s ${FOLDER} linked-repo
+
+ # Go to deep folder inside linked repo
+ cd linked-repo/asdfasdf/qwerqwer
+
+ POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(dir)
+ POWERLEVEL9K_SHORTEN_DIR_LENGTH=2
+ POWERLEVEL9K_SHORTEN_STRATEGY='truncate_with_package_name'
+
+ assertEquals "%K{blue} %F{black}My_Package/as…/qwerqwer %k%F{blue}%f " "$(build_left_prompt)"
+
+ # Go back
+ cd $p9kFolder
+ rm -fr $BASEFOLDER
+ unset POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
+ unset POWERLEVEL9K_SHORTEN_STRATEGY
+ unset POWERLEVEL9K_SHORTEN_DIR_LENGTH
+}
+
+function testTruncateWithPackageNameIfRepoIsSymlinkedInsideGitDir() {
+ local p9kFolder=$(pwd)
+ local BASEFOLDER=/tmp/powerlevel9k-test
+ local FOLDER=$BASEFOLDER/1/12/123/1234/12345/123456/1234567/12345678/123456789
+ mkdir -p $FOLDER
+ cd $FOLDER
+
+ # Unfortunately: The main folder must be a git repo..
+ git init &>/dev/null
+
+ echo '
+{
+ "name": "My_Package"
+}
+' > package.json
+
+ cd $BASEFOLDER
+ ln -s ${FOLDER} linked-repo
+
+ cd linked-repo/.git/refs/heads
+
+ POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(dir)
+ POWERLEVEL9K_SHORTEN_DIR_LENGTH=2
+ POWERLEVEL9K_SHORTEN_STRATEGY='truncate_with_package_name'
+
+ assertEquals "%K{blue} %F{black}My_Package/.g…/re…/heads %k%F{blue}%f " "$(build_left_prompt)"
+
+ # Go back
+ cd $p9kFolder
+ rm -fr $BASEFOLDER
+ unset POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
+ unset POWERLEVEL9K_SHORTEN_STRATEGY
+ unset POWERLEVEL9K_SHORTEN_DIR_LENGTH
+}
+
function testHomeFolderDetectionWorks() {
POWERLEVEL9K_HOME_ICON='home-icon'