views:

1660

answers:

4

Hi all.

I've been Googling for a while looking for a simple way to do this, and I can't find one.

I have a custom terminal environment set up (zsh) with various aliases and functions to make things easier. One thing I keep running into is that I will quickly APPLE-t to create a new tab and then type a command relative to the path of the terminal window I was just in. This invariably fails because the path of the new tab is ~/ instead of whatever I was just using! Any ideas for a script to set the directory path of the new terminal tabs to the directory path of the opening tab?

Any help most appreciated.

Ian

+1  A: 

In my answer here, I provided a function and an alias:

function cd () { command cd "$@"; echo "$PWD" > /tmp/CWD; }
export cd

alias cdp='cd $(cat /tmp/CWD)'

You should be able to put a (possibly conditional) statement at the end of your ~/.bashrc or ~/.zshrc to execute that alias.

Dennis Williamson
Not quite perfect, though. Suppose you have two tabs open, your last `cd` was done in tab 1, but you're currently working in tab 2. Now you spawn a new tab -- it goes to the CWD of tab 1, not the CWD of tab 2.
ephemient
This breaks the cd command in my terminal. Not sure why, but I thought I'd better mention it for others benefit. Everything returns to normal upon removal. Thanks for your efforts though!
i0n
@ephemient: The `$PROMPT_COMMAND` variable could be set to `'echo "$PWD" > /tmp/CWD'` so it's written every time a prompt is issued. @i0n: What exactly does "breaks" mean. Error message? Specific behavior?
Dennis Williamson
Yes could have been more descriptive couldn't I! The cd command stops doing anything at all. No error message of any kind. cd .. cd DIR_NAME cd ~ everything to do with cd stops working. A complete and up to date copy of all of my terminal related files is on GitHub here: http://github.com/i0n/dotfiles
i0n
You might try adding `export cd`
Dennis Williamson
You might instead try (in Bash in any case) `PROMPT_COMMAND='echo "$PWD" > /tmp/CWD'`
Dennis Williamson
For `zsh`: PROMPT="$PROMPT\$(pwd>/tmp/ZWD)"
Dennis Williamson
+1  A: 

You can get what you want by modifying the BASH script found at http://www.entropy.ch/blog/Mac+OS+X/2008/06/27/Terminal-Tricks-“term”-revisited-with-tabs. Here is the script, taken from Marc Linyage's site www.entropy.ch/blog.

#!/bin/sh
#
# Open a new Mac OS X terminal window or tab in the current or another
# directory and optionally run a command in the new window or tab.
#
# - Without any arguments, the new terminal window opens in
#   the current directory, i.e. the executed command is "cd $PWD".
# - If the first argument is a directory, the new terminal will "cd" into
#   that directory before executing the remaining arguments as command.
# - The optional "-t" flag executes the command in a new tab 
#   instead of a new window.
# - The optional "-x" flag closes the new window or tab
#   after the executed command finishes.
# - The optional "-p" flag takes an argument of the form x,y (e.g. 40,50) and
#   positions the terminal window to the indicated location on the screen
# - The optional "-s" flag takes an argument of the form w,h (e.g. 800,400) and
#   resizes the terminal window to the indicated width and height in pixels.
#
# Written by Marc Liyanage <http://www.entropy.ch&gt;
#
# Version 2.1
#

set -e

while getopts xtp:s: OPTION; do
    [ $OPTION = "x" ] && { EXIT='; exit'; }
    [ $OPTION = "t" ] && { TAB=1; }
    [ $OPTION = "p" ] && { POSITION="set position of window 1 to {$OPTARG}"; }
    [ $OPTION = "s" ] && { SIZE="set size of window 1 to {$OPTARG}"; }
done

for (( $OPTIND; $OPTIND-1; OPTIND=$OPTIND-1 )); do shift; done

if [[ -d "$1" ]]; then WD=$(cd "$1"; pwd); shift; else WD=$PWD; fi


COMMAND="cd '$WD' && echo -n \$'\\\\ec';"
for i in "$@"; do
COMMAND="$COMMAND '$i'"
done

if [ $TAB ]; then

osascript 2>/dev/null <<EOF
tell application "System Events"
 tell process "Terminal" to keystroke "t" using command down
end
tell application "Terminal"
 activate
 do script with command "$COMMAND $EXIT" in window 1
 $POSITION
 $SIZE
end tell
EOF

else

osascript <<EOF
tell application "Terminal"
 activate
 do script with command "$COMMAND $EXIT"
 $POSITION
 $SIZE
end tell
EOF

fi
Pinochle
Huh. I wonder what that silly `for (( ... ))` loop is for; `shift $OPTIND` would be much better. Also, `COMMAND=...` should definitely be more like `COMMAND="cd $(printf '%q' "$WD") ..."` for safety. Ah well, it seems reasonably clever regardless.
ephemient
+2  A: 

OK, so as is my way I am answering my own question again (well at least getting close to answering it anyway)

I have found a less verbose script to the one above (courtesy of Dan Benjamin) that seems to do the trick, although both scripts output a similar error before successfully completing. I have dealt with that by adding clear to the end of the script so that's no big problem.

I say that I have nearly solved my own problem because my objective was to find a way to accomplish this with the Apple-t key command that has been burnt into my muscle memory as the shortcut for a new tab in anything, thanks to countless hours in various web browsers. The best I can manage with a script such as Dan's is t-return which isn't the biggest difference, but big enough that I will be slightly irked every time I issue said command. I know, I should let it go..... But I can't, which is probably how I got into this mess in the first place, endlessly fiddling with computers. I digress, here is the script I am using:

#!/bin/sh

# Make a new OS X Terminal tab with the current working directory.

if [ $# -ne 1 ]; then
    PATHDIR=`pwd`
else
    PATHDIR=$1
fi

/usr/bin/osascript <<EOF
activate application "Terminal"
tell application "System Events"
    keystroke "t" using {command down}
end tell
tell application "Terminal"
    repeat with win in windows
        try
            if get frontmost of win is true then
                do script "cd $PATHDIR; clear" in (selected tab of win)
            end if
        end try
    end repeat
end tell
EOF
clear

For completeness here is the error that gets spat out on the soliciting window if the trailing clear is omitted:

2009-10-20 01:30:38.714 osascript[20862:903] Error loading /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types:  dlopen(/Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types, 262): no suitable image found.  Did find:
    /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: no matching architecture in universal wrapper
osascript: OpenScripting.framework - scripting addition "/Library/ScriptingAdditions/Adobe Unit Types.osax" declares no loadable handlers.
tab 2 of window id 13942
i0n