There seems to be a semi-meme going around on some of the planets I read.
My concern is long directory paths and I wanted a dymanic solution for it. Surely, I cannot be the first person to think of it, but I haven’t seen it in use anywhere else.
jolexa @ helios :: ~ %%andjolexa @ helios :: ~ %% cd projects/prefix-tinderbox/really_long_dirname_so_that_binpkgs_can_be_shortened/a/b/ jolexa @ helios :: .../a/b %%
(the colors and wrapping are representitive only)
and the code that produces that:
_chomp_path() {
local path=${1/${HOME}/\~}
local last=${path} sedout= count=0 count2=0
sedout=$(echo ${path} | sed -e 's:/: :g')
for i in ${sedout}; do
(( count++ ))
done
if ((count > 2)); then
last="..."
for i in ${sedout}; do
(( count2++ ))
if (( count2 >= count - 1 )); then
last+="/$i"
fi
done
fi
echo ${last}
}
PS1='\[\033[1;34m\]\u \[\033[1;32m\]@\[\033[1;34m\] \h \[\033[1;30m\]::\[\033[1;37m\] $(_chomp_path $(pwd)) \[\033[1;30m\]%%\[\033[0m\] '
If anyone wants to improve that function, let me know. It “fails” on directories with spaces in it.




Nice idea
I still prefer my two line solution though, that way I always know where to look for my prompt :p
A nice one. I want to keep my prompt short so now it shows only last directory in path. Sometimes one dir is too little so when I’ll have some time I’ll try showing two like you do
As I told you on IRC, bash4 as a builtin setting for that: PROMPT_DIRTRIM.
Yea, that makes life alot simpler. So,
PROMPT_DIRTRIM=2
PS1='\[\033[1;34m\]\u \[\033[1;32m\]@\[\033[1;34m\] \h \[\033[1;30m\]::\[\033[1;37m\] \w \[\033[1;30m\]%%\[\033[0m\] '
will deprecate my _chomp_path() function. I’ll check for bash version and keep the function for bash-3 boxes but that will become useless over time too. Anyway, thx!
How about an ruby path shortener?
ruby -e’a=”‘$(pwd)’”;b,a=a,a.gsub(%r{/([^/])[^/]+(/.*)},”/\\1\\2″)while(a.length>20)&&(b!=a);puts a’
Arrgh, the comment engine destroyed my quote signs… Just replace accordingly. Or does this work?
ruby -e'a="'$(pwd)'";b,a=a,a.gsub(%r{/([^/])[^/]+(/.*)},"/\\1\\2")while(a.length>20)&&(b!=a);puts a'And more improved:
ruby -e'a="'$(pwd)'".gsub(%r{^'$HOME'},"~");b,a=a,a.gsub(%r{/([^/])[^/]+(/.*)},"/\\1\\2")while(a.length>15)&&(b!=a);puts a'I think I’ll go with that.
Boils down to having:
_dir_chomp() {
ruby -e'a="'$1'".gsub(%r{^'$HOME'},"~");b,a=a,a.gsub(%r{/(\.?[^/.])[^/]+(/.*)},"/\\1\\2")while(a.length>'$2')&&(b!=a);print a'
}
From prompt (PS1) call with:
$(_dir_chomp "$(pwd)" 20)
for a max length of 20.
Not sure if bash has something similar or not, but in zsh you can do PS1=”%2c” and it would print the last two directories. Just change the number to display the amount of trailing directories you want printed.
Heres a bash 3 friendly (i think) space friendly version
_chomp_path() {local path=${1/${HOME}/\~}
local last=${path} sedout= count=0 path2=
#bash is dumb, "${#path//[^'/']/}" fails.
sedout="${path//[^'/']/}"
count=${#sedout}
if ((count > 2)); then
last="..."
path2=${path%/*}
path2=${path2%/*}
last+=${path//${path2}}
fi
echo ${last}
}
Fish has a similar prompt. it shows only the first letter of every directory but the last one, which is displayed entirely.
This is actually what my ruby path shortener above does…
The zsh prompt knows %<string< and similar commands to trim strings within the prompt and print dots for the omitted parts (BTW: zsh is much more convenient for interactive shell: All such interactive functions like prompts, completion, … are much more powerful – once properly configured).
Another possibility is to use plain sh substitution which will make it work in a few lines.
You might want to have a look at my bash and zsh prompt buried in the German forums which uses path shortening with changing colors for the omitted part (which is not directly possible with zsh) by means of sh substitution:
http://forums.gentoo.org/viewtopic-p-4223650.html#4223650
(to use it with zsh you must source the code using the lines at the end of the posting and set the option prompt_subst). The path cutting sequence is added into the PS1 code near the end of the function (after "if ${CUT}").
The following awk code will work for arbitrary directory names. The number of directories to show has been parametrized.
_chomp_path() {
local path=${1/${HOME}/\~}
awk -v path=”$path” -v limit=2 ‘BEGIN {
dirparts = split(path,split_path,”/”)
if ( dirparts-1 > limit ) {
printf(“%s”,”…”)
for (i=dirparts-limit+1;i<=dirparts;i++) {
printf("/%s",split_path[i])
}
}
else {
printf("%",path)
}
}' /dev/null
}
Mhm, whenever I’m trying to use pwd instead of \w in my PS1 it’s never changing after a cd command.
Also with a plain $(pwd) instead of $(_chomp_path $(pwd)).
Any ideas?
Of course it won’t, it needs to be expanded, see PROMPT_COMMAND section in man bash.
Tips : grep -i prompt_command ~/.bashrc should show: PROMPT_COMMAND=do_my_ps1 # where do_my_ps1 is a function of your own that can use pwd et al.