You are not logged in.
Hey there. I recently got a little bored with my prompt and so decided to see if I could conjure up a new one.
A considerable amount of time later, I had a PROMPT_COMMAND configured... only issue is that it's, well, a bit slow. It takes 60 microseconds to generate the prompt string because of all the fun stuff I'm doing, and while you might be like "whoa... 60 microseconds", if you compare that with my last prompt, which didn't use PROMPT_COMMAND at all - just PS1 - and so used so little resources it'd be unmeasurable unless I used a timer that could handle nanoseconds, you might be able to get what I mean when I say there's a difference. Oh, then there's also the part where I have really fast vision...
So, I was wondering if this prompt (which really does look messier than the longest regex in the world) could be sped up at all.
For reference, this is my old prompt (the \016 and \017 only affects the '+' when at a text console, at which point it turns into a right-facing arrow - I developed the prompt while X was broken):
export PS1='\[\e]0;${PWD%/}/\007\e[1;30m\]${PWD%/}/ \[\e[32m\016\]+ \[\017\e[0m\]'
Now for my new prompt...
As one long, utterly unmanageable line:
export PROMPT_COMMAND='cwd=${PWD%/}; thisdir="$(echo $cwd | sed '\''s/.*\///'\'')"; dirparts="${cwd:0:$((${#cwd} - ${#thisdir}))}"; dirparts="$(echo ${dirparts%/} | sed '\''s/\//\\[\\e[0;33m\\]\/\\[\\e[32m\\]/g'\'')"; rc=${PWD%/}; rc=${rc:0:1}; PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] "'
Spaced out, for easy copying (can still be pasted into a terminal and will "run", note the quote characters at the beginning and end):
export PROMPT_COMMAND='
cwd=${PWD%/};
thisdir="$(echo $cwd | sed '\''s/.*\///'\'')";
dirparts="${cwd:0:$((${#cwd} - ${#thisdir}))}";
dirparts="$(echo ${dirparts%/} | sed '\''s/\//\\[\\e[0;33m\\]\/\\[\\e[32m\\]/g'\'')";
rc=${PWD%/};
rc=${rc:0:1};
PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] "
'
I'm sure you'd understand if I told you that it took me a good half an hour to work out where to put all the \[s and \]s!
It looks nice-ish, but it isn't that cool with my not-so-speedy computer (it's 2.66GHz) which can be slow at some things - like this
Prompt requirements, in case you want to rewrite it from scratch (and I don't mind if you do, I sometimes do that sort of thing myself when dealing with other people's code, especially unmaintainable code):
- That the prompt is fast!
- Slash characters are colored dark brown (0;33m)
- All directory components of the path except the current directory are colored dark green (0;32m)
- The current directory is colored bright blue (1;34m)
- A slash (/) is added before and after the path string, but methods are used to prevent "duplicate slash syndrome" if I'm in the root folder (ie "//"), and additionally these extra slashes are colored the dark brown (0;33m)
- There is a space, a '%' character, and a further space after the directory
Also, will zsh render a prompt like this one quickly? I just may switch over if it is. And as you can see, designing impossibly complex prompts isn't beyond me, so figuring out how zsh handles prompts shouldn't be too hard
-dav7
Last edited by dav7 (2008-09-25 03:18:09)
Windows was made for looking at success from a distance through a wall of oversimplicity. Linux removes the wall, so you can just walk up to success and make it your own.
--
Reinventing the wheel is fun. You get to redefine pi.
Offline
Those seds are what's slowing you down.
Why can't you replace the thisdir line with:
thisdir="${cwd##*/}"
and the second dirparts line with:
dirparts="${dirparts%/}"; dirparts="${dirparts//\//your_colored_replacement_stuff}"
Then bash can do everything inside bash, without starting any extra processes (except date, in the last line).
Offline
Spaced out, for easy copying (can still be pasted into a terminal and will "run", note the quote characters at the beginning and end):
export PROMPT_COMMAND=' cwd=${PWD%/}; thisdir="$(echo $cwd | sed '\''s/.*\///'\'')"; dirparts="${cwd:0:$((${#cwd} - ${#thisdir}))}"; dirparts="$(echo ${dirparts%/} | sed '\''s/\//\\[\\e[0;33m\\]\/\\[\\e[32m\\]/g'\'')"; rc=${PWD%/}; rc=${rc:0:1}; PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] " '
Also, I think you might be able to replace the first dirparts line with:
dirparts="${cwd%$thisdir}"
Don't know whether that's going to make any perceptible speed difference though. Doubt it.
Offline
Don't know whether that's going to make any perceptible speed difference though. Doubt it.
Well, you might be surprised, but your changes have actually sped it up - on my system anyway.
My new PROMPT_COMMAND:
PROMPT_COMMAND='cwd=${PWD%/}; thisdir="${cwd##*/}"; dirparts="${cwd%$thisdir}"; dirparts="${dirparts%/}"; dirparts="${dirparts//\//\[\e[0;33m\]/\[\e[32m\]}"; rc=${PWD%/}; rc=${rc:0:1}; PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] "'
And spaced out, for easy {read,paste}ability:
PROMPT_COMMAND='
cwd=${PWD%/};
thisdir="${cwd##*/}";
dirparts="${cwd%$thisdir}";
dirparts="${dirparts%/}";
dirparts="${dirparts//\//\[\e[0;33m\]/\[\e[32m\]}";
rc=${PWD%/};
rc=${rc:0:1};
PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] "'
'
Some benchmarks; each measures the commands executed individually, then on one line.
Old prompt:
/Users/dav7/ + time cwd=${PWD%/};
real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time thisdir="$(echo $cwd | sed 's/.*\///')";real 0m0.028s
user 0m0.010s
sys 0m0.000s
/Users/dav7/ + time dirparts="${cwd:0:$((${#cwd} - ${#thisdir}))}";real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time dirparts="$(echo ${dirparts%/} | sed 's/\//\\[\\e[0;33m\\]\/\\[\\e[32m\\]/g')";real 0m0.027s
user 0m0.007s
sys 0m0.007s
/Users/dav7/ + time rc=${PWD%/};real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time rc=${rc:0:1};real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] "real 0m0.014s
user 0m0.000s
sys 0m0.003s
[01:02:45 PM] /Users/dav7/ %
[01:02:45 PM] /Users/dav7/ % time (cwd=${PWD%/}; thisdir="$(echo $cwd | sed 's/.*\///')"; dirparts="${cwd:0:$((${#cwd} - ${#thisdir}))}"; dirparts="$(echo ${dirparts%/} | sed 's/\//\\[\\e[0;33m\\]\/\\[\\e[32m\\]/g')"; rc=${PWD%/}; rc=${rc:0:1}; PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] ")real 0m0.025s
user 0m0.007s
sys 0m0.017s
[01:02:45 PM] /Users/dav7/ %
New prompt:
/Users/dav7/ + time cwd=${PWD%/};
real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time thisdir="${cwd##*/}";real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time dirparts="${cwd%$thisdir}";real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time dirparts="${dirparts%/}";real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time dirparts="${dirparts//\//\[\e[0;33m\]/\[\e[32m\]}";real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time rc=${PWD%/};real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time rc=${rc:0:1};real 0m0.000s
user 0m0.000s
sys 0m0.000s
/Users/dav7/ + time PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] "real 0m0.014s
user 0m0.000s
sys 0m0.003s
[01:04:47 PM] /Users/dav7/ %
[01:04:47 PM] /Users/dav7/ % time (cwd=${PWD%/}; thisdir="${cwd##*/}"; dirparts="${cwd%$thisdir}"; dirparts="${dirparts%/}"; dirparts="${dirparts//\//\[\e[0;33m\]/\[\e[32m\]}"; rc=${PWD%/}; rc=${rc:0:1}; PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] ")real 0m0.007s
user 0m0.000s
sys 0m0.007s
[01:04:47 PM] /Users/dav7/ %
A bit of trivia: when creating the new prompt, on the first try I didn't edit the appropriate changes in properly, and until I found myself examining it, I didn't realize this because it was so fast!
/Users/dav7/ + time (cwd=${PWD%/}; thisdir="${cwd##*/}"; dirparts="${cwd:0:$((${#cwd} - ${#thisdir}))}"; dirparts="${cwd%$thisdir}"; dirparts="${dirparts%/}"; dirparts="${dirparts//\//\[\e[0;33m\]/\[\e[32m\]}"; rc=${PWD%/}; rc=${rc:0:1}; PS1="\[\e]0;${cwd}/\007\e[1;36m\][\[\e[0;36m\]$(date "+%I:%M:%S %p")\[\e[1m\]] ${dirparts}\[\e[0;33m\]${rc}\[\e[1;34m\]${thisdir}\[\e[0;33m\]/\[\e[1;33m\] %\[\e[0m\] ")
real 0m0.004s
user 0m0.007s
sys 0m0.000s
/Users/dav7/ +
So, Profjim, thanks a heap!
-dav7
Last edited by dav7 (2008-09-25 03:18:44)
Windows was made for looking at success from a distance through a wall of oversimplicity. Linux removes the wall, so you can just walk up to success and make it your own.
--
Reinventing the wheel is fun. You get to redefine pi.
Offline
Glad it helped.
Offline