So I upgraded to OS X Mountain Lion yesterday. The install was pretty smooth (though had a tough time with the redeem code for the upgrade, worked on the third code that Apple sent across).
Most of the software is working fine. However, I found that my existing Xcode installation needed an upgrade (via a Xcode install from the App Store).
The problem is that any new Xcode install seems to nuke the command line development tools (think make, autoconf, etc.). The solution is pretty simple though. Once Xcode has been installed, run Xcode and then open the preferences. There is a section on downloads, which lists installing the command line tools as an option.
Voila! Issue resolved.
The gnuplot graphing utility has always had excellent support for multiple terminal types. While the X11 terminal is a satisfactory GUI view for the graphs, I prefer to use the AquaTerm terminal on OSX as it is more ‘Mac-like’ and feels more natural.
Also, I do prefer to compile gnuplot by myself on OSX rather than downloading the pre-packaged binaries – as this gives me more control over the compilation (including getting around the stupid Apple readline bug – where Apple has essentially shipped a broken readline by using libedit to emulate the non-existent libreadline).
This local compile requires that AquaTerm be installed so that the library dependencies for aquaterm exists in:
and the corresponding headers are available at:
In addition, the AquaTerm.app itself resides in /Applications.
However, on OS X Snow Leopard, there is a catch – the version of AquaTerm is 32 bit, whereas the default compilation of gnuport results in a 64-bit version – which is not able to load the 32-bit libaquaterm dynamic libraries.
In such a case, the gnuplot compilation does succeed – however, the default terminal becomes the X11 version – which is back to square-one.
A darwinports port does exist for gnuplot – however, as mentioned in an earlier post, this port seems to depend on half of the port repository (i.e., a ton of stuff you do NOT want gets installed as well).
However, there is a easier way to get around this situation. Here’s how.
- First install the default binary for AquaTerm from SourceForge and install normally. This step is to basically setup the right folders and symlinks so that you do not have to muck with these later
- Now install AquaTerm again from Darwinports – this port has the correct patches needed – and more importantly – builds a 64 bit version by default. This will also install the application under /Applications/MacPorts/
- Now comes the fun part. We will replace two folders from the darwinports version to the previously installed AquaTerm.
- Step 1: Replace /Library/Frameworks/AquaTerm.framework with /opt/local/Library/Frameworks/AquaTerm.framework. This will ensure that the correct 64 bit AquaTerm libraries get referenced by the gnuplot compilation
- Step 2: Replace /Applications/AquaTerm.app with /Applications/MacPorts/AquaTerm.app. This will ensure that the correct 64-bit AquaTerm binary is in the correct location
- Step 3 (Optional): You can now uninstall the darwinports version by running sudo port uninstall aquaterm from a terminal window
- Download the source code for gnuplot and extract the same.
- Run ./configure (using a command line parameter to ignore the broken Apple readline) and then make and make install (install will happen in /usr/local)
That’s it! The compilation should now succeed and gnuplot will be linked with the correct 64-bit aquaterm dynamic library. Enjoy!
In an earlier post I had listed the server-mode mechanism to allow client/server editing using Emacs. However, this require some setup and also an active Emacs session.
With the latest version of Emacs (23.1), a new mechanism to invoke Emacs in a server mode has been introduced. Basically, emacs can be invoked with the –daemon option from the shell command line:
$ emacs --daemon
This will run emacs in the background as a daemon which will be listening in to emacsclient connections. To actually start a edit session, use emacsclient from the command line as before with the file name as a parameter.
A couple of new options have been added to the 23.1 emacsclient which allow the client to either
- Invoke a terminal editing session (via the -t option to emacsclient), or
- Create or reuse a GUI frame for the editing session (default behavior)
The advantage here is that Emacs can now truly act as a server (without any visible window or terminal session) and can be added to the logon/start up scripts.
Emacs is a great editor, but has one setback – it is slow to startup if you have loads of packages to load. On my G4 iBook, it takes around 45 seconds before Emacs becomes usable (OK – I use lots of packages).
However, Emacs is not meant to be restarted every so often. The canonical usage is to start Emacs once, invoke the server mode (see EmacsClient) and then use the emacsclient from the command line to invoke the editor instance when needed. I.e., the classic client/server model for editing!
Note that by default, this uses local sockets and hence the clients can connect only to the local machine’s server. However, there is an alternate mechanism to use standard TCP/IP sockets, which allows connections to remote Emacs servers. See the emacsclient info page for details.
(Note: With the latest 23.1 version of Emacs, there is an alternate mechanism to start Emacs in a server mode – will post this in a future article).
In order to enable this feature, server-mode needs to be run within an active Emacs session (V22 and above). This can be achieved by:
Alternatively, you can add the following line at end of your .emacs file:
Note that a running Emacs session needs to be present before the clients can connect.
The next step is to invoke emacsclient from the command line (or from a script) with the file name to edit.
$ emacsclient <file to edit>
This will cause a new file buffer with the requested file to be opened in the running Emacs session. The emacsclient that invoked the edit will block till the running Emacs returns control via ‘C-x #’ (server-edit)
You can use the -n option to the emacsclient invocation to prevent the blocking.
On my system, I have aliased the ‘emacsclient’ binary to be ‘ec’, which is much simpler to type.
I.e., in my `.bashrc’, I have
alias ec emacsclient
I have also defined $EDITOR to use ‘emacsclient’ when possible, and ‘vi’ otherwise. However, instead of directly assigning to the $EDITOR environment variable, I have a small shell-script to define the default editor I want to use. This script is then assigned to the $EDITOR variable.
The code for the default-editor shell-script (named ‘default-editor’) is:
#!/bin/bash # Set up a default editor for the shell # Use Emacs if already open, and vi in other cases (including fallback) # Note that this will set the default emacsclient, which may not be what you want # if multiple versions of emacs are available. In that case, you can put the absolute path # of the emacsclient that needs to be used. # E.g., the Cocoa 23.1 emacsclient on OSX is actually located at: # /Applications/Emacs.app/Contents/MacOS/bin/emacsclient EMACS_EDITOR=`which emacsclient` if [ -x "$EMACS_EDITOR" ]; then $EMACS_EDITOR -a vi "$@" else vi "$@" # Never fails! fi
And then, in the .bashrc file, I have:
if [ -x $HOME/bin/default_editor ]; then export EDITOR=$HOME/bin/default_editor else export EDITOR=`which vi` fi
BTW, the code above assumes that you use bash as the primary shell in your terminal. You can however trivially modify the scripts above for your specific shell.
A Small function to set the PATH variable from within Emacs. You can define the function and the path definitions in your .emacs file:
Very useful for OS X, where the default path is set by plists.
;; Define a function to setup additional path (defun my-add-path (path-element) "Add the specified path element to the Emacs PATH" (interactive "DEnter directory to be added to path: ") (if (file-directory-p path-element) (setenv "PATH" (concat (expand-file-name path-element) path-separator (getenv "PATH")))))
and use it as:
;;; Set localized PATH for OS X (if (fboundp 'my-add-path) (let ((my-paths (list "/opt/local/bin" "/usr/local/bin" "/usr/local/sbin" "/usr/local/mysql/bin" "~/bin"))) (dolist (path-to-add my-paths (getenv "PATH")) (my-add-path path-to-add))))