fix promblematic shorten path function

The previous implementation had shell specific paths which did not
produce the same result. It did not respect the maximum length which it
calculated. And for specific cases even repeated part of the path.

This implementation is portable across bash and zsh.
It respects maximum length strictly and only exceeds it when it has to
respect LP_PATH_KEEP leading dirs.
It adds support for only showing the current directory, without leading
ones. This fixes Issue #219.

(Rebased by Olivier Mengué on top of more recent changes in that
fucntion)
This commit is contained in:
polyphemus 2013-11-30 23:54:01 +01:00 committed by Olivier Mengué
parent e92a8e2630
commit 467490f20f

View File

@ -512,18 +512,11 @@ esac
unset _lp_connection unset _lp_connection
# BASH/ZSH function that shortens # Shorten the path of the current working directory
# a very long path for display by removing # * Show only the current directory
# the left most parts and replacing them # * Show as much of the cwd path as possible, if shortened display a
# with a leading ... # leading mark, such as ellipses, to indicate that part is missing
# # * show at least LP_PATH_KEEP leading dirs and current directory
# the first argument is the path
#
# the second argument is the maximum allowed
# length including the '/'s and ...
# http://hbfs.wordpress.com/2009/09/01/short-pwd-in-bash-prompts/
#
# + keep some left part of the path if asked
_lp_shorten_path() _lp_shorten_path()
{ {
@ -535,87 +528,53 @@ _lp_shorten_path()
return return
fi fi
local p local ret=""
p="${PWD/#$HOME/~}"
local -i len max_len
len=${#p}
(( max_len = ${COLUMNS:-80} * $LP_PATH_LENGTH / 100 ))
if $_LP_SHELL_bash; then local p="${PWD/#$HOME/~}"
if (( len > max_len )) local mask="${LP_MARK_SHORTEN_PATH}"
then local -i max_len=$(( ${COLUMNS:-80} * $LP_PATH_LENGTH / 100 ))
# index of the directory to keep from the root
# (starts at 0 whith bash, 1 with zsh)
local -i keep=LP_PATH_KEEP-1
# the character that will replace the part of the path that is
# masked
local mask="$LP_MARK_SHORTEN_PATH"
local -i mask_len=${#mask}
# finds all the '/' in
# the path and stores their
# positions
#
local pos=()
local -i slashes=0
for ((i=0;i<len;i++))
do
if [[ "${p:i:1}" == / ]]
then
pos=(${pos[@]} $i)
let slashes++
fi
done
pos=(${pos[@]} $len)
# we have the '/'s, let's find the if [[ ${LP_PATH_KEEP} == -1 ]]; then
# left-most that doesn't break the # only show the current directory, excluding any parent dirs
# length limit ret="${p##*/}" # discard everything upto and including the last slash
# [[ "${ret}" == "" ]] && ret="/" # if in root directory
local -i i=keep elif (( ${#p} <= ${max_len} )); then
if (( keep > slashes )) ; then ret="${p}"
i=slashes elif [[ ${LP_PATH_KEEP} == 0 ]]; then
fi # len is over max len, show as much of the tail as is allowed
while (( len-pos[i] > max_len-mask_len )) ret="${mask}${p:${#p} - ${max_len} + ${#mask}}"
do else
let i++ # len is over max len, show at least LP_PATH_KEEP leading dirs and
# current directory
local tmp=${p//\//}
local -i delims=$(( ${#p} - ${#tmp} ))
for (( dir=0; dir < ${LP_PATH_KEEP}; dir++ )); do
(( ${dir} == ${delims} )) && break
local left="${p#*/}"
local name="${p:0:${#p} - ${#left}}"
p="${left}"
ret="${ret}${name%/}/"
done done
# let us check if it's OK to if (( ${delims} <= ${LP_PATH_KEEP} )); then
# print the whole thing # no dirs between LP_PATH_KEEP leading dirs and current dir
# ret="${ret}${p##*/}"
if (( pos[i] == 0 )) else
then local base="${p##*/}"
# the path is shorter than
# the maximum allowed length,
# so no need for '…'
#
LP_PWD="$p"
elif (( pos[i] == len )) p="${p:0:${#p} - ${#base}}"
then
# constraints are broken because ret="${ret%/}" # strip trailing slash
# the maximum allowed size is smaller
# than the last part of the path, plus local -i len_left=$(( ${max_len} - ${#ret} - ${#base} - ${#mask} ))
# ' … '
# ret="${ret}${mask}${p:${#p} - ${len_left}}${base}"
LP_PWD="${p:0:pos[keep]+1}${mask}${p:len-max_len+mask_len}"
else
# constraints are satisfied, at least
# some parts of the path, plus ' … ', are
# shorter than the maximum allowed size
#
LP_PWD="${p:0:pos[keep]+1}${mask}${p:pos[i]}"
fi
else
LP_PWD="$p"
fi
else # zsh
if (( len > max_len )); then
LP_PWD="%-${LP_PATH_KEEP}~%${max_len}<${LP_MARK_SHORTEN_PATH}<%~%<<"
else
LP_PWD='%~'
fi fi
fi fi
echo "${ret}"
} }
# In bash shell, PROMPT_DIRTRIM is the number of directory to keep at the end # In bash shell, PROMPT_DIRTRIM is the number of directory to keep at the end