rsontech.net

Effective Emacs in Windows 7

There are many posts around the web about how to run Emacs in Windows. While many of these suggest building and running a native version of Emacs, many others suggest running the version available through Cygwin. I tried both approaches many times but always ran into problems with the packages that I use most often. On top of that I was plagued with slowness that just isn’t there on other platforms. The good news is I’ve found a happy medium that works quite well for me and this post documents that monster I’ve created.

What I wanted

My goals for this setup were to make Emacs run on a “remote” machine and display on my local Windows install. I also wanted this to be as seamless as possible so that it felt as if I was running a native application. To do this I needed quite a bit of supporting software.

An Emacs host

I used a Linux host, specifically a VirtualBox VM running a minimal Ubuntu server install. Your host is going to need to have an opensshd and X11 installed, with X11 forwarding enabled in sshd_config. Anyone reading this guide is probably already very familiar with these steps so I’ll leave out the details.

I wrote a couple of scripts help make running a VM more bearable. This is VirtualBox specific, but I’m sure it can be adapted to other virtualization solutions.

file: EmacsHost.bat

@echo off
"C:\Program Files\Oracle\VirtualBox\VBoxHeadless.exe" -s EmacsHost

This batch file launches the VM named “EmacsHost” in headless mode. This means the only access to the machine is through remote services like ssh or vnc. Unfortunately, because it’s batch, this leaves a command prompt hanging around. To get rid of that I used a bit of VBScript.

file: EmacsHost.vbs

Set WshShell = WScript.CreateObject("WScript.Shell")
obj = WshShell.Run("c:\path\to\EmacsHost.bat", 0)
set WshShell = Nothing

Running Emacs.vbs runs EmacsHost.bat in a subprocess and kills off the parent shell.

I finished off the VM setup by having EmacsHost.vbs run on boot so it is always running whenever I attempt to run Emacs. The VM is tiny so it starts up immediately and I don’t worry about powering it off as there isn’t much to lose on the machine itself.

PuTTY and friends

The PuTTY project is a set of Windows applications that allow you to connect to remote machines via a number of protocols. You can download the two specific applications you’ll need directly but I strongly suggest downloading the installer for simplicity’s sake. From this project I used PuTTYgen to set up the ssh certificates and plink to make the connection to launch Emacs.

Unfortunately PuTTY’s certificates are incompatible with openssh and there is some work that needs to be done to make a private/public key pair that will work between the machines. There are many resources on setting up these certificates so I won’t go into details here. Later I reference the private key on Windows as “EmacsHostKey.ppk”.

An X11 server

In order to have Emacs display on your Windows machine you will need to be running an X11 server. I chose Cygwin/X since I had Cygwin installed for other reasons already. I also chose to launch the X server on startup at the same time as my VM, for the same reasons.

Putting it all together

To wrap things up I wrote a couple of scripts to make launching Emacs convenient.

file: Emacs.bat

@echo off
plink -l user -X -i c:\path\to\EmacsHostKey.ppk localhost "emacsclient -c -a ''"

file: Emacs.vbs

Set WshShell = WScript.CreateObject("WScript.Shell")
obj = WshShell.Run("c:\path\to\Emacs.bat", 0)
set WshShell = Nothing

With a running X server and a running VM, double clicking on Emacs.vbs in an Explorer window will launch emacsclient on the VM and display it on the Windows machine..

What’s left?

One slight annoyance is that pinning Emacs to the taskbar doesn’t work as expected. With Cygwin/X, pinning it actually pins an Xwin instance to the taskbar and clicking this doesn’t launch Emacs. To fix this I found an odd workaround somewhere on the Emacs Wiki:

  1. Right click on the pinned XWin icon on the taskbar.
  2. Right click on the Xwin entry at the top of the popup menu.
  3. Select properties option.
  4. Modify the “Target” field to point to Emacs.vbs.
  5. Optional: Select the “Change Icon” button and select an Emacs icon file.
  6. Optional: Select the “General” tab.
  7. Optional: Modify the first field to be “Emacs” instead of “Xwin”.

After a reboot (or restart of explorer.exe) the pinned Emacs icon functions just as any other pinned application.

The result

After following these steps I’m left with is an Emacs that behaves as though it is a native Windows application without the slowness or incompatibilities I ran into with a native Emacs build.

Notes

If you have any questions or suggestions on how I could improve either this setup or the guide itself speak up.

Published on Comments

· · ·

Why Emacs?

After a couple of months of using emacs as my primary editor I’ve finally settled down. I am as comfortable now with emacs as I was with vim when I made the switch. With that in mind, I feel like I need to explain why I’m sticking with it. Hopefully I’ll be able to convey this in a way that a vim power user might appreciate.

I understand now that comparing vim and emacs is ridiculous. Vim is an editor. Emacs is a host for running elisp applications.

When I was a vim user I thought it was nonsense that so many emacs users claimed that they hardly ever left emacs. Now it’s perfectly clear to me why they’d make such a claim. When you start using applications within emacs (such as an irc client, news reader, or calendar) you suddenly have a single, unified set of keybinds across all of your tools. Switching between chat windows and switching between text files use the exact same mechanism. Even switching between applications works the same way. Chances are you will probably be editing some text in those applications. Since you’re already inside emacs you get a familiar set of editing bindings –including your personal configuration– for free, in every application. This is something I’ve fought for years to achieve.

Another reason I consider emacs to be more of an environment is that it was designed from the ground up to be extended. Emacs provides hooks (similar to autocmd events in vimscript) for almost anything you can think of. These allow you to run arbitrary elisp when specific events happen. On top of that, elisp allows you to modify literally any function to add functionality without having to rewrite the entire function. This is called “advising” the function. The power that this gives you is really hard to convey because there isn’t any concept of this in vim.

I’m not an advocate of pushing people into making the switch to emacs. That being said, Magnar Sveen summed up my thoughts pretty well in one of his talks on Emacs Rocks:

God damn it, you’re a programmer. Start using an editor you can damn well program.

· · ·

Migrated to Jekyll

If you’re reading this that means the site’s transition to Jekyll is complete. Over the past couple of days I’ve been working on migrating my old flask+flatpages implementation over to Jekyll and I will now be hosting everything on GitHub. Everything is pretty much the same with a few minor visual changes.

Comment threads will be broken until I get the time to remap them with Disqus but eventually I’ll have all four comments back to their respective articles.

As always, please let me know if you notice any residual issues.

· · ·