Hints and code snippets for a more sane OS X Terminal experience

posted in the early afternoon by Constantinos. Filed under Code, OS X

This post was originally published in 2006
The tips and techniques explained may be outdated.

Pretty long title, huh? Well, I’ve finally made the decision that there’s no way I’ll ever be able to keep a journal. So instead, I’ll start posting code snippets and general hints that I mostly harvested online (and try to cite wherever I can – remember that is -), but also modified to suit my purposes… First up is seamless integration of X11 in OS X with the Terminal application.. Read on for the code

First off, the reason I got started in this: I HATE xterm. Really dislike it, to the point where I would actively avoid any xwindow apps. That’s until I came across this hint at macosxhints.com. Really nice hint, but to get the best possible approach you have to shift through all the comments, and merge some bash with some csh scripts in order to get the most seamless approach. So this is my solution, for the bash shell, derived from that hint on macosxhints, and explicitly avoiding any modifications of master files (which might get overwritten with an OS X upgrade).

First step, is to prevent X11 from opening up an xterm window. That’s fairly easy. Simply create a file called .xinitrc under your home (~/) directory with your favorite editor (like TextMate 😉 ), and paste this code in it (lifted straight off the aforementioned hint):

PATH=/usr/X11R6/bin:$PATH
 
# surpress starting of an initial xterm
xterm()
{
    return 0
}
 
# remember the display name
echo "$DISPLAY" > $HOME/.tmp/X11-display-`hostname -s`
 
# run system-defined xinitrc (doesn't return)
source /etc/X11/xinit/xinitrc

Now what this does, is redefine the function that calls up the xterm window, and make it do nothing. Then the master file is sourced, so no harm no foul. This modification will survive across upgrades too.

Now to the more tricky part. In your .bash_profile file, insert this little gem of a code:

if [ !$DISPLAY ] && [ !$SSH_TTY ] && [ !$REMOTEHOST ]
then
    export DISPLAY=`ps xw -o command | sed -n '/^\/.*X11.*\:/s/.*:/:/p'`
fi
 
if [ $DISPLAY ]
then
    if xwininfo -display "$DISPLAY" -root >/dev/null 2>&1
    then
        echo Using X11 display $DISPLAY
        export DISPLAY
    else
        unset DISPLAY
    fi
fi


This piece of code simply tries to capture the $DISPLAY given by X11, so it can be used in the Terminal. This is usually :0, but not if you’re running it over ssh. This should catch either.

So far so good. Whenever I need xwindows, I can start X11, then open a new terminal window and voila. But wait a minute. Why would I have to manually start X11? When that app is idle, it’s using up almost zero resources. I could very easily place it in my startup items. That’s a good solution, with the problem being that I rarely need X11, and I don’t want to have it in my dock all the time.

This is where the magic happens (btw this same method can be used to hide the dock and menu-bar of pretty much ANY app). Find the X11 app in the finder under /Applications/Utilities/. Ctrl-click on it, and “Show Package Contents”. Then navigate to Contents/Info.plist, open it up in the Property List Editor, and add a new sibling under Root called LSUIElement, set it to boolean, and give it the value ‘Yes’ (or set it to string and give it the value 1). Save the plist file, and close it.

Almost there. Now in the terminal, give the command touch /Applications/Utilities/X11.app/, and you’re all set. Double click on the X11 app to start it, and… nothing! The only way you can know it’s running, is if you look for it in the Activity Monitor! This won’t survive across upgrades of X11, and in fact if X11 gets upgraded you will have to open Activity Monitor to kill it before the upgrade, but I feel it’s an easy change to make, and a change that’s almost a second nature to me.

So that’s my solution for this. Right now I have X11 running in the background at all times, and terminal simply captures the display and uses it whenever it needs it. And since all the modified files are in the user’s home directory, this solution will survive across OS upgrades. As a final note, I do have the capture script for tcsh, but it’s the same as the script listed in a comment of the previously mentioned macosxhints hint, so I won’t enter it here again. Just look for it there.

Comments are closed.