Press "Enter" to skip to content

Current working directory restoration in Mavericks Terminal with tcsh

In John Siracusa’s excellent review of OS X Mavericks, he (originally) mentioned that the Terminal application is able to restore the current working directory of open shells across launches.

However, this section has subsequently disappeared from the online version, perhaps for the reasons given below (update: see below). Try looking here for a cached version of the original; scroll down to page/slide number 94. Sorry, John. Please purchase the full review on the iBooks store or the Amazon Kindle store to support John’s work.

Of course I was excited to try this out as, in the course of my work as a software developer, I often have several shell windows open in specific directories. So I tried it, and it didn’t work. It turns out the built-in support supplied by Apple assumes that you’re using the bash shell, but as an old-timer I’m stuck on tcsh instead:

Well, that’s no good, I thought. So I looked in the supporting code’s implementation (/etc/bashrc), and figured out how to do the same thing in tcsh. Simply place the following in your .tcshrc file:

if ("$?TERM_PROGRAM") then
 if ("$TERM_PROGRAM" == "Apple_Terminal") then
  alias precmd 'printf "33]7;%sa" "file://$host$cwd:ags/ /%20/"'
 endif
endif

This uses the appropriate escape sequence to send the URL of the current working directory to the terminal before each command; Terminal detects this information and uses it to update the state of the window (including a proxy icon in the window’s title bar for the corresponding folder). It turns out that the key is doing it using precmd (tcsh’s equivalent of PROMPT_COMMAND), and not sending the sequence in the prompt string itself as one might think. (The outer if statement is necessary to avoid an error when remotely logging in, as with ssh. It has to be a separate statement because of the variable expansion rules in tcsh.)

I’ve notified John via Twitter, so perhaps he add restore this information back to his review. In any case, it’s documented here for future generations. Drop me a note below if you have any issues with it.

Update: It turns out John removed it because he discovered it was a feature in Mountain Lion as well, which had happened not to work on his machine:

If you listen to John’s podcasts, you’ll realize that makes sense: he wouldn’t let something not new in Mavericks stand in the Mavericks review. Regardless, I wasn’t aware of the feature before and it still wouldn’t have worked in tcsh, so this post is presumably still useful. (Note that I haven’t tried it on Mountain Lion, and I’ve already upgraded my working machines to Mavericks; I don’t know why this technique wouldn’t work on Mountain Lion, but use it at your own risk.)

Update 2: OK, so it turns out the feature was first implemented in Lion, and other people have already figured out how to port it to other shells; see here for an implementation in zsh, for example. How did I manage to not learn about this for the last two years? Oh, well…

5 Comments

  1. Khoo Yit Phang
    Khoo Yit Phang December 19, 2013

    Here’s another version that only runs when changing directories, and does not call any external programs:

    alias cwdcmd '( set echo_style=both; echo -n "33]7;file://${HOST}${cwd:ags/ /%20/}a" )'

    • Khoo Yit Phang
      Khoo Yit Phang December 19, 2013

      Hmm, the first escape disappeared; let’s try that again:

      alias cwdcmd '( set echo_style=both; echo -n "33]7;file://${HOST}${cwd:ags/ /%20/}a" )'

      • Khoo Yit Phang
        Khoo Yit Phang December 19, 2013

        Okay, now there’s a missing “0” between the first slash and “3”.

    • Russell Finn
      Russell Finn December 19, 2013

      Hey, welcome. Don’t get many visitors round here.

      Somehow I never found out about cwdcmd either. The more you know…

      So you’re recommending the following:

      if ("$?TERM_PROGRAM") then
       if ("$TERM_PROGRAM" == "Apple_Terminal") then
        alias cwdcmd '( set echo_style=both ; echo -n "33]7;file://${host}${cwd:ags/ /%20/}a" )'
       endif
      endif

      I’ll try that.

Comments are closed.