Skip to content

Instantly share code, notes, and snippets.

@kugland
Last active January 31, 2023 21:32
Show Gist options
  • Save kugland/38a80e2ad5dab4da1e806256d0912014 to your computer and use it in GitHub Desktop.
Save kugland/38a80e2ad5dab4da1e806256d0912014 to your computer and use it in GitHub Desktop.
Ellipsize path: function for Zsh (used in https://github.com/kugland/my-zshrc)
# Ellipsizes a path to display it in a limited space.
function ellipsize() {
(( ${#1} <= 40 )) && { print -r -- $1; return } # If the path is short enough, just return it.
local array=(${(s:/:)1}) # Split the path into an array.
local head=() tail=() # The head and tail of the path.
local prefix='' # '/' if the path is absolute, '' otherwise.
[[ ${1[1]} == '/' ]] && prefix='/' # If the path is absolute, set the prefix.
local next=tail # The next part of the path to be added.
local result # The result.
local elm # The current element being processed.
for (( i=1; $i <= ${#array}; i++ )) { # Ellipsize elements bigger than 23 characters.
(( ${#array[$i]} > 23 )) && array[$i]=${array[$i]:0:20}…
}
while (( ${#:-${prefix}${(j:/:)head}/…/${(j:/:)tail}} < 40 && ${#array} )) {
# While the path is too long and there are still elements to process:
case $next { # Select the next part of the path to be added and remove it from the array.
head) elm=$array[1]; shift array ;;
tail) elm=$array[-1]; shift -p array ;;
}
if (( ${#:-${prefix}${(j:/:)head}/${elm}/${(j:/:)tail}} > 40 && ${#elm} > 3 )) {
elm='…' # If it would be too long, replace it with '…'.
}
case $next { # Add the element to the path.
head) head+=($elm); next=tail ;;
tail) tail=($elm $tail); next=head ;;
}
[[ ${elm} == '…' ]] && break # If we had to ellipsize the path, stop.
}
if (( ${#array} == 1 && ${#${array[1]}} <= 3 )) { # If a single elm is left with len<=3, add it.
head+=($array[1])
} elif (( ${#array} )) { # If there are still elements left, add '…'.
head+=('…')
}
result=${prefix}${(j:/:)head}/${(j:/:)tail} # Join everything together.
result=${result//\/…\/…/\/…} # Remove any '…/…' sequences.
result=${result//\/…\/…/\/…} # Remove any '…/…' sequences.
result=${result//\/…\/…/\/…} # Remove any '…/…' sequences.
result=${result//[[:blank:]]…/…} # Remove any spaces before ellipses.
print -r -- $result
}
max_length=40
find ~ -type d 2>/dev/null| while read line; do
result="$(ellipsize $line | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g')"
if [[ "${result}" = "${line}" ]]; then
continue
fi
# Transform the result into a Perl regex.
regex='\Q'$result'\E'
regex=$(echo $regex | sed 's,/,\\/,g; s,/…/,/\\E[^/]+\\Q/,g; s/…/\\E.*\\Q/g;')
print -r -- "
\$line = \"$line\";
\$result = \"$result\";
if (\$line =~ /$regex/) {
print \"OK: \$result <- \$line\\n\";
} else {
print \"FAIL: \$result <- \$line\\n\";
}
"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment