Persistent emacs server sessions

emacs

In my spare time, I’ve been working on two tools to make emacs more useful to me by leveraging two key features: the ability to save the desktop state and the ability to have emacs clients connect to an emacs server.

For the former, I wrote an emacs-lisp package called desktop-autosave. Once initiated, the package will periodically save the desktop under the name of your choice. The benefit of this is that you do not have to remember to save the desktop explictly yourself before you exit emacs or before you experience an emacs or system crash. Moreover, the next time you start desktop-autosave with that same name, the corresponding desktop is automatically loaded into your emacs workspace.

For the latter, I wrote a bash shell script called ee that will allow you to connect to a named emacs server (bringing up the server if it is not already running). The value of this package is that you can now invoke ee wherever you would normally have invoked emacs, and by just specifying the name of the desired server, you can easily set up as many emacs sessions as you have concurrent projects.

The real benefit comes when you use both packages together. In this case, you can use ee to bring up a named emacs server, and that server will save its desktop to disk periodically. As long as emacs stays running, you can keep connecting to the same server from as many clients as you wish. After your emacs server terminates (by exiting normally, by crashing, or by the machine being reset), you can use ee to once again bring up a server with the same name. In this case, emacs will load the automatically-saved desktop file from disk and you will have in memory all the files that you were working on previously on that particular emacs server. Nifty, no?

Feel fry to try these packages out. They are available on GitHub. If you find them useful or if you find bugs, let me know. Enjoy!

UPDATE 020120.02.11: desktop-autosave now saves shell-mode buffer contents, directory, and command history.

Execute-Notify

Multitasking in the right manner helps one be productive. Do it too much, and quality declines as you get more stressed. Do it too little, and, well, you get less done. I think the crucial element is minimizing significant context switches while allowing as many things to proceed on automatic pilot as possible.

In particular, when executing long commands on the computer (like, say, compiling a binary), it is better to switch to a different activity (preferably with lower intellectual demands, so as to keep the coding context in one’s working memory) than to sit idly twiddling your thumbs. My problem when I do this, especially since I have a different virtual desktop for each context, is that I may forget to go back and check whether my compilation succeeded and my tests passed.

I recently found out (on emacsfoo) about notify-send, a useful command-line interface to libnotify that lets alerts pop up on the desktop. As is the case for many others, I like the idea of using this tool to notify me that my long-running jobs are finished, so I can switch back to my main context. Thus, I wrote a simple command-line utility (en, for “execute-notify”) that you can use to wrap an arbitrary command and be notified when it exits. I strove to make it fairly general and customizable, and may add more features to it as needed.

The simplest invocation is simply to prefix your command with en:

en  gcc -o myprogram myprogram.cc

If the compilation failed, you would see a message like this:

A typical failure message conveyed by 'en' without any options

There are options to control the notification parameters, like so:

en --expiration 0 --title Compilation \
   --command_label "the usual gcc command" \
   --icon_success /usr/share/icons/gnome/32x32/status/info.png \
   gcc -o myprogram myprogram.cc

A customized 'en' notification when the underlying command succeeded

Here’s the help text for the command:

$ en --help
en Execute a command and notify when finished
Usage: en [FLAGS...] COMMAND [ARGS...]
   executes COMMAND ARGS... and sends a notification to the status
   panel upon completion, indicating the result of COMMAND. The
   exit code of COMMAND is the exit of en.

Each flag to en begins with "--"; flags take zero or one
arguments. The first argument to en that is not interpreted as
a flag or value is taken to be the command to execute.

Possible no-argument flags are:
  --help  Show this message
  --debug Print debugging information about en

Possible one-argument flags are:
  --title Prefix to the "Success" or "Failure" title of the
notification

  --command_label Description of the command to be used in the
notification text in place of the command itself. Useful for
succinctly describing a long command, or for use with --exit_code
flag

  --exit_code Simulated exit code from COMMAND to use when generating
the notification, Setting this flag causes COMMAND to not actually
execute, and is useful for testing that the notification is
formatted as desired without actually invoking COMMAND or of the
form

  --PROPERTY_OUTCOME where PROPERTY is one of "icon", "urgency", or
"expiration" and OUTCOME is one of "success" or "failure".
All the properties are used in creating and dispatching the
notification, but the outcome used depends on the exit code of the
command being run.
   icon: the icon to be used in the notification
   expiration: the duration of the notification (ms)
   urgency: the notification urgency, as defined by send-notify

Example:
  en --icon_success /usr/share/icons/gnome/32x32/emblems/emblem-default.png \
    --expiration 600000 --title "Directory listing" ls

Enjoy it and let me know what you think!