Emacs Protip: Other-window Commands

In order to get better at emacs I’m focusing on a few keyboard shortcuts at a time in order to really grok it and start using them effectively.

I’m starting out with the other-window family of commands. There are quite a few of them, but these are some of the more useful. They are pretty easy to memorize in that they are variations of other common commands and share the same keyboard shortcut except for that infix 4.

dired-other-window (C-x 4 d)

Runs dired in the other window. I don’t use dired that much, but I can see how this comes in handy.

find-file-other-window (C-x 4 f)

Open a new file in the other window. This is really useful, as I often open a new file, split the window in two, go back to the original window and switch back to the original file. This command does all that at once.

ido-switch-buffer-other-window (C-x 4 b)

Switch to another buffer in the other window. Again, this is something that I do a lot, and I’m happy there’s a shortcut for it.

If you have ido installed (and you should), the latter two will bind to ido-find-file-other-window and ido-switch-buffer-other-window respectively. They do more or less the same thing, only better.

Fire Emblem: Coping With Loss

The battle was drawing to a close. My heroes had dispatched of the Mad King Gangrel a few turns previous, and were now finishing off the last of the desperate loyalists. And then, on the second to last turn I made the mistake of putting Olivia, the talented young Dancer who had only just joined my forces, within range of an enemy warrior. Disaster.

The enemy was swift and ruthless. As I watched in horror, a silent scream on my lips, the warrior brought his axe down and Olivia would never dance again.

I’m playing [Fire Emblem: Awakening][game], a turn-based strategy where your team of knights, mages and archers fight hordes and hordes of enemies in a fantasy setting. You tend to grow attached to these tiny men made of stats and polygons. Your guys have names, relationships and as it turns out, hopes and dreams. You can hang out with them back at the base and eavesdrop on their interactions. Donnel wants the war to end, so he can return home and be a farmer. Miriel wants to study the world. And Kellam just want the others to see him.

However, if your guys are killed in battle they die permanently. Unlike other games, there is no respawn and no resurrection. When you’re gone, you’re gone. And you feel terrible. Partly because it’s your fault, partly because you won’t get to hang out with them anymore.

Sure, you have the option of playing your game in the baby mode, where there is no actual permadeath. And there is always the option of resetting and going back to a saved game if the situation is too unbearable (it happens). But, I’ve found that when you instead learn to let go and accept your loss it feels weirdly liberating. Starting over is a way of cheating death, but accepting fate is conquering it.

Something Cool (Pt. 2)

In an earlier post I wrote about a way to implement cons, car and cdr (also known as pair, first, and second) using only function definitions and if statements in javascript. That was pretty mindblowing for me, but it turns out there is an a way to do without even using branching logic.

pair
function pair(x, y) {
return function(s) {
return s(x, y);
};
};

The pair function take to arguments X and Y, and returns another function which takes a function argument S. It is essentially a promise to apply S to X and Y.

first and second
function first(p) {
return p(function(x, y) { return x; });
}
function second(p) {
return p(function(x, y) { return y; });
}

Implementing first and second becomes pretty straightforward; it’s just a matter of taking the output from a call to pair and applying it to a function taking two arguments X and Y and returns either X (first) or Y (second).

The CoffeeScript implementation is incredibly terse and elegant, reading almost like mathematical notation.

The CoffeeScript version
pair = (x, y) -> (s) -> s x, y
first = (p) -> p (x, y) -> x
second = (p) -> p (x, y) -> y

Maintainer Blues

I’ve been maintaining emacs-eclim for a couple of years now. I like it, since that means I can push my commits to the repo with minimal fuss. And for a long period of time, that was all that mattered, since there weren’t a lot of other users around.

But that has changed. Over the past few months, we’ve been getting a stead stream of Github issues and pull requests. There’s even been some traffic over at our google group. It seems that people are getting interested.

That’s good.

But here’s the thing: emacs-eclim was always just a tool to me; something I kept hacking on to solve those particular problems I encountered in my day to day work. So a lot of these feature requests are things I cannot relate to. Support for PHP? Android development? Ant? I dunno. These are things I have absolutely no motivation to spend my free time on. They might be problems, but they’re not my problems.

That’s bad.

Sure I’d like to achieve feature parity with the main eclim project (right now there are a lot of commands we don’t support). It would be cool to have better Ruby and Python support. Running unit tests from inside emacs is probably a useful feature. But I probably won’t be the guy to implement this.

Back to Reality

The Kabukicho gate

We just got back from a two-week trip to Japan, which was simply amazing. I’ve seen more temples and Torii gates than I care to remember; I’ve seen the spring festival of Takayama and the Peace Museum of Hiroshima. We went on a pilgrimage to Akihabara, shopped at Super Potato, and had drinks at 8-bit Cafe.

As most of my Japan knowledge comes from exclusively from playing the Yakuza games, one of my personal highlights was visiting the real-life “Kamurocho” and seeing the iconic Kabukicho gate.

Side note: Tokyo is about just about the only city on earth where I’d feel comfortable walking around the red light district at night snapping pictures with my big touristy camera.

This Is Why We Fight

This is frankly the best damn session report I’ve read in my entire life. At 36 pages long, it is an superbly well-written essay about the psychology of gaming, friendship, and the sheer ridiculousness of a certain monster wargame.

“Troy,” I said, “the reason I want so much to play this game is because nobody wants me to play this game. There is virtually no person you could present this to without getting a stunned, pitying look in return, and that ticks me off. It ticks me off because what so freaks people out is the time involved in this endeavor, time. Everything in adult life is designed to steal it away from us, and my God, look how we go along with the scheme so willingly.

“‘I have no time for such things anymore,’ we say, and then we spend our afternoons making our lawns pretty and shopping for junky Ikea furniture and ferrying kids to soccer games and gawking at cable TV, and above all, working at jobs we never really wanted. ‘Sure,’ we say, ‘when I was young and didn’t have all these responsibilities, I could spend hours doing this kind of thing. But that was then, and this is now.’

“Well, Troy,” I went on, “I want to be the guy who suddenly, at age 42, does spend hours doing this kind of thing, if only to feel what it’s like to take back a little piece of the soul I’ve sold to the company I slave for, to the obligatory evenings with people I’m not sure I even like, to daily errands, the lines at the DMV, to tax forms, to tedious family visits. This game is a slap in the face to all thinking creatures who live in such dire fear of the sands sifting through the hourglass. Playing a monster war game on this scale is ridiculous, a waste of energy, a waste of time, and so I want to do it. Let spite rule the day, Troy. Let’s learn and play A World at War!”

Raspberry, Meet Elnode

So, I was curious about elnode. And I wanted to play more with my Raspberry Pi. It only seemed logical to combine the two.

You know, because I can.

(I promised @nicferrier a writeup on this project, so here goes.)

Installing Emacs 24

The Emacs that comes with the Raspian distribution is version 23.4. Unfortunately, elnode requires Emacs 24, so I had to compile my own. I dreaded doing this, but it actually turned out pretty straightforward.

You need to apt-get install some build dependencies like libncurses-dev (and probably build-essentials if you don’t already have them), then you’re ready to go:

> wget http://ftp.gnu.org/pub/gnu/emacs/emacs-24.2.tar.gz
> tar xvfz emacs-24.2.tar.gz
> cd emacs-24.2
> ./configure
> make
> sudo make install

This would be a good opportunity to make a sandwich, or learn some sanskrit, as building everything will take quite a while.

Running Emacs

By default the elnode webserver runs on Emacs startup, so the idea is to fire up emacs and just leave it. One way of doing that would be to ssh into the Pi and run emacs inside a tmux session (I tend to use tmux for all remote access anyway). This makes the emacs process persistent, and when I next log in I can just resume the session.

However, with this approach I’d still need to login in and start manually every time the server restarts, so the setup is kind of fragile. Especially since I have builders running round the house cutting the main power every now and then.

So instead I use a simple init script to run emacs in daemon mode (using the aptly named --daemon switch). This way I can still connect to the running emacs process using emacsclient, but I don’t have to bother with starting it manually anymore.

The only caveat is that since I want start-stop-daemon to fork off a new process to run emacs as the pi user (running a web-connected emacs as root seems like a really bad idea), I can’t rely on it to generate a correct PID file for me. Instead, we’ll have to do that from inside emacs (see next section).

/etc/init.d/elnode
#!/bin/sh
set -e
# Must be a valid filename
NAME=elnode
PIDFILE=/home/pi/elnode/elnode.pid
UID=1000
#This is the command to be run, give the full pathname
DAEMON=/usr/local/bin/emacs
DAEMON_OPTS="--daemon --load /home/pi/.emacs.d/init.el --load /home/pi/elnode/web.el"
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
case "$1" in
start)
echo -n "Starting daemon: "$NAME
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $UID --exec $DAEMON -- $DAEMON_OPTS
echo "."
;;
stop)
echo -n "Stopping daemon: "$NAME
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
echo "."
;;
restart)
echo -n "Restarting daemon: "$NAME
start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $UID --exec $DAEMON -- $DAEMON_OPTS
echo "."
;;
*)
echo "Usage: "$1" {start|stop|restart}"
exit 1
esac
exit 0

When I start the deamon I get some weird error messages from elnode, but as far as I can tell it actually runs fine.

pi@raspberrypi ~ $ sudo /etc/init.d/elnode start
Restarting daemon: elnode("/usr/local/bin/emacs" "--load" "/home/pi/.emacs.d/init.el" "--load" "/home/pi/elnode/web.el")
Starting Emacs daemon.
deleting server process
elnode-error: elnode--sentinel 'deleted.' for process *elnode-webserver-proc* with buffer *elnode-webserver*
found the server process - NOT deleting
elnode-error: Elnode server stopped
.

Running elnode

Elnode is available from Marmalade, which makes it very easy to install from inside emacs. I also grapped the xmlgen library to help with HTML generation.

This is my little Hello World-script. There’s nothing remarkable about it, really. The first section generates a PID file to be used by the init script to check if the process is running. I stop the default server, as it binds to “localhost”, and I want to bind to the actual server name (raspberrypi.local in my case) in order to serve remote requests. You can see it in action here.

Did I say there was nothing remarkable about this script? Yeah, apart from the fact that it’s running a webserver inside a 25 year old text editor on a computer that’s about as large as a deck of cards.

/home/pi/elnode/web.el
;;; -*- lexical-binding: t -*-
;; write the pid file
(with-temp-file "/home/pi/elnode/elnode.pid" (insert (format "%d" (emacs-pid))))
(require 'cl)
;; stop the default server
(elnode-stop 8000)
(defvar request-count 0)
(defun hello-handler (httpconn)
"Hello, world"
(elnode-http-start httpconn 200 '("Content-Type" . "text/html"))
(elnode-http-return httpconn
(xmlgen
`(html
(head
(title "Hello, elnode!")
(style "body { margin:100px auto auto auto; width: 400px; }"))
(body
(p "Hello, I am a small "
(a :href "https://github.com/nicferrier/elnode" "webserver")
" running inside Emacs 24 on a "
(a :href "http://www.raspberrypi.org" "Raspberry Pi")
".")
(p "The local time is "
,(format-time-string "%H:%M")
" and I have served a total of "
,(incf request-count)
" requests."))))))
(defun root-handler (httpconn)
(elnode-hostpath-dispatcher httpconn '((".*/favicon.ico" . elnode-send-404)
(".*" . hello-handler))))
(elnode-start 'root-handler :port 8000 :host "raspberrypi.local")