Last active
January 31, 2023 21:32
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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