Setting window and tab names in the Leopard Terminal
Since I'm a Unix person at heart, I spend a lot of time working in terminal windows. Most modern terminal applications (such as those provided by GNOME and KDE) support web-browser-like tabs, which allow you to have multiple interactive shell sessions running in a single window. However, prior to Mac OS X 10.5, Apple's Terminal application didn't have tabs, which rendered it essentially useless for a heavy terminal user like me. (Fortunately, iTerm provided a tab-enabled alternative.)
For the Leopard release, Apple upgraded Terminal to include support for tabs. This is a very welcome (and long overdue) enhancement that puts the stock Mac OS X terminal on par with the previously-superior iTerm … almost. Unfortunately, the support for tabs in Leopard's Terminal has one serious flaw: The title of a tab is always set to the name of the currently-running process, and there's no preference option for overriding it.
In order to keep track of the various tabs I have open, I want the title of each tab to always be the name of the current working directory (not the full path — just the last component). With iTerm, all I had to do to accomplish this was to add the following line to my .bash_profile:
PROMPT_COMMAND='echo -n -e "\e]0;${PWD##*/}\a"'
In brief, this causes bash to set the title of the terminal window to the name of the current directory every time it prints the shell prompt. (For a more detailed explanation, see "How to change the title of an xterm".) In iTerm, this also sets the tab title. Sadly, such is not the case in Terminal; the window title changes, but the tab title is still the name of the current process.
I googled around a bit, hoping someone had already solved this problem for me, but I didn't find anything (although a post by Mike Rodriquez suggested the trick of using hard links to change the tab title). So I was forced to put on my bash-hacker hat and come up with my own solution.
And here it is:
function set_window_and_tab_title
{
local title="$1"
if [[ -z "$title" ]]; then
title="root"
fi
local tmpdir=~/Library/Caches/${FUNCNAME}_temp
local cmdfile="$tmpdir/$title"
# Set window title
echo -n -e "\e]0;${title}\a"
# Set tab title
if [[ -n ${CURRENT_TAB_TITLE_PID:+1} ]]; then
kill $CURRENT_TAB_TITLE_PID
fi
mkdir -p $tmpdir
ln /bin/sleep "$cmdfile"
"$cmdfile" 10 &
CURRENT_TAB_TITLE_PID=$(jobs -x echo %+)
disown %+
kill -STOP $CURRENT_TAB_TITLE_PID
command rm -f "$cmdfile"
}
PROMPT_COMMAND='set_window_and_tab_title "${PWD##*/}"'
It's not pretty, but it does the job. To use it, just add the above code to your .bash_profile. Since the code works by creating a dummy process with the name of the current directory, you should also change Terminal's "Preferences … → Settings → Shell → Prompt before closing" setting to "Never". Otherwise, whenever you try to close a tab, Terminal will warn you about killing the dummy process, which gets old fast.
Hopefully, Apple will fix the issue with tab titles soon, making my little hack unnecessary. Until then, this will allow me to be as productive in the new Terminal as I was with iTerm.
(Note that iTerm supports a number of other features that aren't present in the new Terminal, so it's definitely worth a look if you use the command line frequently. Personally, the only iTerm feature I ever cared about was tabs, and now that Terminal supports them, I can simplify my life a little by relying on one less piece of third-party software.)
Update: The initial version of my code failed when the working directory was /. I've updated it to set the window and tab title to "root" in that case.
Tags: apple
Sat, 08 Dec 2007 00:42 UTC