Emacs for Clojure - Part 2

This is the second in a two part post about a Clojure programmer workflow entirely within Emacs.

Editing Clojure

Some useful navigation key bindings in Clojure-mode, actually any Lisp code editing mode in Emacs, are as follows:

Keybinding Command
C-M-f forward-sexp
C-M-b backward-sexp
C-M-a beginning-of-defun
C-M-e end-of-defun
C-M-x slime-compile-defun
C-x C-e slime-eval-last-expression

Some of these key bindings get redefined when a buffer is in slime-mode to SLIME enhanced equivalents, but mostly they behave the same.

And, don't forget the exponential effect of the C-u prefix key.

Some other key bindings that are also useful are:

Keybinding Command Doc
C-M-q indent-sexp A lot of times when copying and pasting or otherwise modifying large blocks of s-expressions, the indentation of the code can get out of whack. indent-sexp can help restore the balance.
C-M-h mark-defun  
C-M-k kill-sexp  

Also worth knowing, the magic of dynamic abbrevs bound to the M-/ key binding. Dynamic abbrevs are a quick way to complete a long function or var name from a minimal prefix. It's very brute force (i.e, just searches for a match in all the open buffers), but since it's very fast, it comes in handy when you're working with partially evaluated Clojure code.

Clojure REPL

Everything begins with a Clojure instance which has SWANK loaded. Again, there are lots of ways of starting one of these, and the most common use case is with a Leiningen project setup. Setting up Leiningen is beyond the scope of this post, but the docs on Leiningen's github page are quite helpful in getting you started.

Once Leiningen is setup and you have a project.clj file for your project, you can invoke clojure-jack-in.

Once SLIME is connected, it's helpful to know the following commands:

Keybinding Command Doc
  slime-repl This is a quick way to jump to the *slime-repl clojure* buffer.
  slime-reset When your SLIME connection goes out of whack.
C-M-i slime-complete-symbol  
C-x e slime-eval-last-expression Makes every Clojure buffer into a REPL. Plus, it is very handy when iterating on tests.
C-c C-c, C-M-x slime-compile-defun This is convenient for compiling a defn or other top-level form, without having to put the cursor at the end of the expression.
  slime-list-connections If you find yourself having to connect to multiple SWANK servers this command is helpful in switching between them.
  slime-list-threads Show the list of scheduled JVM threads, and can provides an interactive way to kill running threads. Use with caution.

Emacs for Clojure - Part 1

This is a brief overview of the way I work in Clojure using Emacs - almost exclusively. Obviously, Emacs is not the only way to interact with Clojure, but it can be a pretty seamless and efficient environment for Clojure, once you become familiar with the powerful extensibility and "mouse-free" efficiency of Emacs.

Also, since Emacs uses Lisp as its extension language, there's a lot of value for a Clojure/Lisp developer in learning and mastering the Emacs' ecosystem. I hope this series of posts will be helpful in that endeavour.

There are lots of "getting started with Emacs" docs available online and on the web. The easiest one is the built-in Tutorial, which you can also bring up within Emacs with C-h t or M-x help-with-tutorial. Other online references:

  1. A Guided Tour of Emacs
  2. A Tutorial Introduction to GNU Emacs

For the most part, I'm going to assume you're using Emacs default key bindings, but the following customizations don't really depend on that.

Process

My typical work-flow involves the following steps (but not necessarily in the same order always):

(loop []
  ;; Edit code/tests
  ;; Interactive development with REPL and tests
  ;; Look up documentation
  ;; Search and Navigate a code tree
  ;; Run batch tests
  ;; Merge commits and resolve conflicts in Git
  (recur))

I'll try to cover each of these steps in detail over the course of the next few posts.

Clojure Mode Setup

Like snowflakes and Sting albums, there are myriad ways of setting up the Clojure environment in Emacs, but essentially all of them should be doing something similar to the following:

(defun clojure-mode-hook ()
  (setq indent-tabs-mode nil
        clojure-mode-use-backtracking-indent t)
  (setup-clojure-indentation-rules))
(require 'clojure-mode)
(require 'clojure-test-mode)
(require 'swank-clojure)
(add-hook 'clojure-mode-hook 'clojure-mode-hook)
(add-hook 'clojure-mode-hook 'clojure-test-mode)

If you are using Emacs 24 and have never setup Clojure-mode or SLIME before, check out the emacs-starter-kit.

Basic Editing

It's good to get familiar with the basic cursor movement keys such as:

Keybinding Command
C-n next-line
C-p previous-line
C-f forward-char
C-b backward-char
C-a move-beginning-of-line
C-e move-end-of-line

There's been a lot of cursing and teeth gnashing about Emacs' default key bindings, but here are some of the benefits that I've come to appreciate over time:

  1. Clustering – you can insert and move around with minimal physical movement from the home row of the keyboard.
  2. Easy to remember
  3. Work in bash and even on tty devices (never say never) - this is particularly useful if you're planning to do some remote pairing over tmux or screen

And, there is always C-h b describe-bindings which will list the key bindings in any given buffer.

Other useful basic key bindings:

Keybinding Command Doc
C-l recenter redraw buffer with the current line at the vertical center of the window; one useful variation is to C-u 0 C-l which will redraw the buffer with the current line at the top of the window
C-SPC set-mark-command set the beginning of a copy/cut region, and move the cursor to the end of the region
C-w kill-region cut the contents of the selected region
M-w kill-ring-save copy (not cut) the contents of the selected region
C-y yank paste the most recently copied/cut region at cursor point
M-y yank-pop when used after a yank, Emacs will replace the pasted region with older copied text cycling through the cut/copy history
C-x r k kill-rectangle mark a region as you would normally, but cut a rectangular sub-region. Useful when working with columns of data
C-x r y yank-rectangle paste the most recently killed rectangular region

Keyboard Macros

We've all been in situations where we've had to fix up some literal data structure or otherwise munge code by repeating a set of editing keystrokes, either deleting, inserting or otherwise splicing text. Keyboard macros can quickly help automate some of this work.

The basic principle is that you begin recording a macro C-x ( kmacro-start-macro, perform the keyboard actions, and then end recording with C-x ) kmacro-end-macro. You can then replay the macro using C-x e kmacro-end-and-call-macro. Also, check out C-x C-k n kmacro-name-last-macro for oft repeated macros.

Next post: REPL, SLIME and interactive programming.

ECL for iOS update for ECL-11.1.1, Xocde 4, and SDK 4.3

I've committed a new branch of ECL for iOS, which now requires ECL-11.1.1 (latest stable), and produces functioning device binaries for armv6 and armv7 architectures using Xcode 4 and SDK 4.3. This release has been tested on iPhone and iPad devices running iOS 4.3.1.

Please refer to the updated README for further details.

https://github.com/kriyative/ecl-iphone-builder/tree/elf

Please note that the earlier release branch `dragon' has also been updated to work with Xcode 4, and SDK 4.3. However, it continues to be based on ECL-10.4.1.

https://github.com/kriyative/ecl-iphone-builder/tree/dragon

Many thanks to Terje Norderhaug for his help with this update.

clojurejs -- a Clojure (subset) to Javascript translator

I'm releasing clojurejs – a Clojure library for translating a Clojure subset language to Javascript. The code is on github reachable at the following link:

http://github.com/kriyative/clojurejs

clojurejs is something I've been working on for a few weeks as part of a larger web app in Clojure. The code's a bit crufty (reflects my incremental discovery of the inconsistencies in Javascript), but functional and I wanted put something out there for people to check out. I welcome bug reports and feedback. It's been useful for my specific needs, and I'd be happy if it's even marginally useful to others.

I realize there are a number of other efforts to compile/translate Clojure (or other Lisp subset) to Javascript, but nothing quite fit my requirements, which prompted me to build clojurejs. Some useful aspects of clojurejs are:

  • Consistent scoping in let and loop/recur forms
  • Macros with defmacro
  • Implicit return from all forms
  • loop/recur translates to Javascript for loops
  • Translates Clojure vectors, strings, keywords, symbols and maps to Javascript equivalents
  • dot form access to methods and properties

Here's an example from the README:

(js
 (defn join [arr delim]
   (loop [str (get arr 0)
          i 1]
     (if (< i (length arr))
       (recur (+ str delim (get arr i))
              (+ i 1))
       str))))

translates to the following Javascript:

join = function(arr, delim) {
    return (function () {
        for (var str = arr[0],i = 1; true;) {
            if ((i < arr.length)) {
                str = (str + delim + arr[i]);
                i = (i + 1);
                continue;
            } else {
                return str;
            } break;
        }
    })();
}

Documentation is regrettably scarce, but there are more details in the README file, boot.cljs, and the unit tests. I hope to add more documentation and examples in the next few weeks. Stay tuned.

Lisp functions as UI callbacks in ECL/iOS

There's been a bit of recent interest in building "real" apps using ECL/iOS. While the `eclffi' sample code in the ecl-iphone-builder repo included examples of how to create/call Objective-C classes/methods from Lisp, it was missing the glue to go the other way, which was necessary to implement callbacks in Lisp. I've pushed an update to github which adds this functionality.

As an example I created a subclass of UIButton called UIButtonCB with one instance var called clickHandler, which can be set to a Lisp function pointer. The UIButtonCB class wires the UIControlEventTouchUpInside event to the specified handler function.

@implementation UIButtonCB

- (id) initWithFrame: (CGRect) aFrame
{
    [super initWithFrame: aFrame];
    clickHandler = Cnil;
    [self addTarget: self action: @selector(clicked:) forControlEvents: UIControlEventTouchUpInside];
    return self;
}

- (void) setClickHandler: (cl_object) fun
{
    register_cb(clickHandler, fun);
}

- (void) clicked: (id) sender
{
    if (Cnil != clickHandler) {
        cl_funcall(2, clickHandler, ecl_foreign_data_ref_elt(&sender,ECL_FFI_POINTER_VOID));
    }
}

- (void) dealloc
{
    remove_cb(clickHandler);
    clickHandler = Cnil;
    [super dealloc];
}

The call to register_cb() ensures that the callback function is protected from GC, and remove_cb() makes the function GC'able again. UIButtonCB can now be wrapped in Lisp with the following FFI glue:

(defun set-click-handler (view fun)
  (when fun
    (c-fficall ((view :pointer-void)
                ((make-callback-function fun) :object))
        :void
      "[#0 setClickHandler: #1];")))

(defun make-button (&rest init-view-args &key title title-color icon
                    on-click (enabled t) &allow-other-keys)
  (let ((view (make-view-instance "UIButtonCB" init-view-args)))
    (set-click-handler view on-click)
    (when icon (set-image view icon))
    (when title (set-title view title))
    (when title-color (set-title-color view title-color))
    (set-enabled view enabled)
    view))

Here's an example of the Lisp code to create a button with an on-click callback, which updates a label:

(let ((n 0)
      (label (make-label "" :frame '(10.0 50.0 300.0 35.0))))
  (add-subview (key-window) label)
  (add-subview (key-window)
               (make-button :frame '(140 230 40 20)
                            :title "click"
                            :background-color (color-argb 1 0.5 0.5 0.5)
                            :on-click (lambda (button)
                                        (declare (ignore button))
                                        (set-text label
                                                  (format nil
                                                          "~d click~:p"
                                                          (incf n)))))))

Obviously, this isn't a very sophisticated approach, but it's a start. It requires subclassing each UIControl or UIView to add the vars to store the Lisp callbacks. I'm sure there's ample room for abstracting or automating some of this boilerplate Objective C code.