Saturday, May 26, 2007

emacs user experience




I'm very interested in User Experience (UX) and I was thinking today: The program where I have the very best User Experience is Emacs.

A lot of UX today is lumping everyone all together in the same bag, a kind of semi-experienced, not very interested or passionate user. I wonder, is this the kind of User we should be developing for in every situation?

I think that we first really need to think about the user we are targetting our code for, is this a beginner user who just wants to find something out quickly? Perhaps an intermediate but non-tecnical user? Or a hardcore Emacs guru? Each of these will have a vastly different user experience when using the same website or piece of software.

I think this is one of the real powers of developing model-heavy, API based, Behaviour Driven Development (BDD) code. With code like this, we can deploy different versions of the application for different users. Some users will want all the blinking lights and rounded corners, with lots of tooltips and easily accessible help. Others will want to code some custom Emacs Lisp so that they can quickly interact with your application.

One big application that has really shown this to me is the new Blogger with the GData interface. I wasn't doing much blogging at all because when I wanted to create a blog post, I would have to go to my blogger Create Post screen. Then I'd have to type in the text into that tiny textarea, without all my great Emacs shortcuts, publish it, and then wait for it to refresh to see if there were any errors. It would take about 30 extra seconds to do all this other stuff, and not having access to my Emacs environment was just a killer.

Now with gblogger.el, I can type up multiple blog posts at once from right inside Emacs. If there is an error, it gives me an error message and I can just do "undo" to get the original post back. It speeds up my blogging experience tremendously.

I think This is all parts of UX, and is something that is usually neglected by UX experts, although they might be targeting their users as one kind of user, like a beginning blogger, there are a whole range of users, and we should be thinking about all these users when we design our websites and APIs. Luckily, often the hardcore people on the team are the programmers, and as programmers, we can decide to make an API for our web projects when we code them. This can make our programming easier and can open up the code to new and exciting developments later.



Tuesday, May 22, 2007

funky new keybindings




I've got some great new keybindings that are really helping my fingers. First, here are some to help you scroll up and down in a file by one line. Great for when you're looking at lots of code, but pgup and pgdown are moving too much:


;; scroll one line at a time
(defun scroll-one-line-up (&optional arg)
"Scroll the selected window up (forward in the text) one line (or N lines)."
(interactive "p")
(scroll-up (or arg 1)))
(defun scroll-one-line-down (&optional arg)
"Scroll the selected window down (backward in the text) one line (or N)."
(interactive "p")
(scroll-down (or arg 1)))
;; Bind these functions (substitute your favorite keys for mine)
(global-set-key "\M-v" 'scroll-one-line-up)
(global-set-key "\C-b" 'scroll-one-line-up)
(global-set-key "\C-v" 'scroll-one-line-down)
(global-set-key [S-down] 'scroll-one-line-up)
(global-set-key [S-up] 'scroll-one-line-down)
(global-set-key [(kp-subtract)] 'scroll-one-line-down)
(global-set-key [(kp-add)] 'scroll-one-line-up)


I've had these bound to C-b and C-v for quite some time, but find that the "shift up arrow" (S-up) and "shift down arrow" (S-down) are much easier on the hands.


(global-set-key [S-down] 'scroll-one-line-up)
(global-set-key [S-up] 'scroll-one-line-down)


And so that I don't have to move my fingers to the "Page Up" and "Page Down" keys, I've rebound these to "meta left" and "meta right":


(global-set-key [?\e down] 'scroll-up)
(global-set-key [?\e up] 'scroll-down)


I've also rebound the shift and meta left and right to move more effectively within paragraphs:


(global-set-key [S-right] 'forward-word)
(global-set-key [S-left] 'backward-word)
(global-set-key [?\e right] 'forward-sentence)
(global-set-key [?\e left] 'backward-sentence)


These work great with my Enlightenment keybindings to move to different virtual and multiple desktops:

I've got ctrl-arrows moving between different virtual desktops, and ctrl-alt-arrows to move to the first four multiple desktops. I find that the 2x2 virtual desktop works great, I used to do a 3x3 virtual desktop, but found that it took a bit too much mental effort to remember the 9 different areas. Now, instead, I have 9 multiple desktops, each with a 2x2=4 virtual desktops on each one. Each multiple desktop is for a different task, I have a Emacs utility 2x2 desktop, A web desktop, a coding desktop, a desktop to monitor the development webserver, a desktop for multimedia with mplayer (and monitoring my production webserver), a desktop with root shells on my local machines (and a firefox that's running on tarayai for Gmail), an Emacs desktop for blogging, web browing with w3m and .emacs, a Emacs and Evince desktop for documentation, and finally an Emacs desktop for my info browsers.

That might seem like a lot of desktops, but with each one being 2x2, and each having a real distinct purpose, I find it super easy to use and keep track of.

Oh, right, also I should mention that each of those virtual desktops has only one window, either a rxvt-unicode terminal or a web browser, that's my real trick, no fancy desktop nonsense like I used to have, no widgets to distract me, just a big window with a font that is easy on the eyes (Bitstream Vera Sans Mono 15).

Back in the day, I used to have tons of widgets, man, I had them all, CPU monitors, network monitors, time and date, phase of the moon, xscreensaver widgets, volume control, it was crazy. Nowadays, I like the zen simplicity thing.


Monday, May 21, 2007

autotest.el




autotest.el is a great little Emacs mode that let's you run your ZenTest autotests for Ruby on Rails right inside Emacs.



Sunday, May 20, 2007

rinari




If you use Ruby on Rails in Emacs, check out the excellent rinari.el mode. It's great, I use it all the time. I did comment out the abbrev mode, I don't like using abbrev, I prefer to write all the code myself.



emacs quickies




Some awesome quickies for Emacs.



Friday, May 18, 2007

occur



I'm amazed, after 12 years of using Emacs, I still discover new things every week. This week, I learned about M-x occur in a blog post entitled Can your editor do this?.

To use it, go:


M-x occur


And then give it a regexp. I had a buffer with instructions for setting up one of my Ruby on Rails projects, and I wanted to find all the lines that referred to piston, so for the regexp, I typed:


piston


I often use


M-x grep


which is great, it lets you run grep from inside Emacs, and gives you a lot of useful functions, for example, if you press C-c C-c on a line in the grep buffer, Emacs helpfully loads the file for you and jumps to the correct line in the file.


Thursday, May 17, 2007

multi-tty emacs




I'm a huge fan of multi-tty emacs. It allows you to run terminal based emacsclients, kind of like how XEmacs does. For years I used XEmacs because it had this feature, but last year I heard about the multi-tty project, and it was so nice to switch back into Emacs from XEmacs.

I have a great setup now where I have long running Emacs servers, one per project that I'm working on, which are mostly Ruby on Rails projects. Each of these servers runs for a long time in the background, so I can setup all the terminals and shells that I need, and get things organized just how I like them. Then, I can connect to these Emacs servers with a text based emacsclient.

I start my Emacs servers with screen, this allows me to disconnect the Emacs server from the tty, so that I can logoff of a machine and still leave the Emacs server running. This is fantastic for web development work, because I can have these Emacs servers running on my web servers, all across the planet, connect to them when I need to do work, and have everything setup just like I like it.

I found the following script somewhere on the net, and it works great for starting up the Emacs server with screen:


#!/bin/bash
# Usage: preload-emacs <name> [<waitp>]
#
# Preloads the Emacs instance called NAME in a detached screen
# session. Does nothing if the instance is already running. If WAITP
# is non-empty, the function waits until the server starts up and
# creates its socket; otherwise it returns immediately.

name="$1"
waitp="$2"
screendir="/var/run/screen/S-$USER"
serverdir="/tmp/emacs$UID"
emacs=/usr/sness/emacs/bin/emacs

if [ -z "$name" ]; then
echo "Usage: preload_emacs <name> [<waitp>]" <&2
exit 1
fi

if [ ! -e "$screendir"/*."$name" ]; then
if [ -e "$serverdir/$name" ]; then
# Delete leftover socket (for the wait option)
rm "$serverdir/$name"
fi
screen -dmS "$name" "$emacs" -nw --eval "(setq server-name \"$name\")" -f server-start
fi
if [ ! -z "$waitp" ]; then
while [ ! -e "$serverdir/$name" ]; do sleep 0.1; done
fi


I have this aliased to the letter "e":


alias e='/home/sness/bin/preload-emacs sness'


o when I want to start up a server I can just type "e snessnet" to start an Emacs server with a name of "snessnet". Mmmm, less keystrokes...

To connect to these Emacs servers, I use emacsclient, and alias it to "ec":


alias ec='/usr/sness/emacs/bin/emacsclient -s sness'


So that I can type "ec snessnet" to connect to the snessnet Emacs server.


I have a whole bunch of these Emacs servers running at once on my development box, right now I have 9 different Emacs servers running, each of them for a different project that I'm working on. To look at all the current servers that are running, I have an alias setup:


we='ps auwwx | grep emacs | grep SCREEN | cut -d "\"" -f 2'


Which allows me to just type "we" to find out the names of all the currently running Emacs servers. Really really sweet.

What is extra sweet is that multi-tty emacs is in the process of getting merged into the main Emacs codebase, so that by the time Emacs 23 is out, it should be in the mainline codebase.



Friday, May 11, 2007

meta-f5 in urxvt




I use urxvt with multi-tty emacs. I wanted to bind M-f5 to post a emacslife blogpost. I tried everything, and then finally found out about "?\e":


(global-set-key [?\e f5] 'gblogger-new-entry-emacslife)



emacs keybindings




A good resource for emacs keybindings is at tiny-tools keybindings. Lots of good stuff.



Recall the previous command




I just learned about


C-x ESC ESC


which recalls your last command. That's so neat!

You can also go


M-x describe-key


To tell you what a key does before you press it.

If you want to see what keys you've recently pressed, you can do:


C-h l
M-x view-lossage