2010/08/14

Putting the current directory in your terminal's titlebar: an optimization

Some time ago, I blogged about putting the current directory in your terminal's titlebar to improve your productivity. In the interest of dogfooding I used this myself for some time and I got annoyed by how much my terminal got slower.

The old (slow) code:

PROMPT_COMMAND="echo -ne \"\033]0;\$(pwd | sed "s#^$HOME#~#g")\007\""
Notice how the $(pwd | sed "s#^$HOME#~#g") part has to spawn at least two processes? One for pwd and another one for sed. Suffice it to say that spawning processes on Cygwin (Windows) isn't something you should take lightly.

Therefore, I propose to you the new and improved (fast) code:

PROMPT_COMMAND="echo -ne \"\033]0;\${PWD/\$HOME/~}\007\""
We replaced $(pwd | sed "s#^$HOME#~#g") with ${PWD/$HOME/~}. Instead of spawning 2 different process, this new command uses only bash built ins to accomplish the same thing. The bash syntax I'm using is quite obscure so let me quote the bash man pages (under Parameter Expansion):

${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in pathname expansion. Parameter is expanded and the longest match of pat- tern against its value is replaced with string. If Ipattern begins with /, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with #, it must match at the beginning of the expanded value of parameter. If pattern begins with %, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the / following pattern may be omit- ted. If parameter is @ or *, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable sub- scripted with @ or *, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.

Usage of this new syntax sped everything up a lot.

No comments:

Post a Comment