Enlive Vs Clojure-mode
Last night I published a screencast and in response to a comment I uploaded the htmlized source-code used in the screencast. The highlighting wasn’t working for me, so I put Emacs and Enlive to work!
The Problem
Clojure-mode is great, but sadly lacking in number of built-in functions which are highlighted. To resolve that I put Emacs and Enlive to work in order to provide a quick and dirty solution. Why dirty? Because it rips everything and usually Clojure-mode wants to keep definitions, functions and control structs separate, but when you’re in a hurry, who cares?
I had a heated discussion with gtk-recordMyDesktop, mencoder and iMovie regarding the aspect ration of the movie but didn’t quite resolve it. Hopefully the next video will be perfect, but for now just use the fullscreen function and the text should be fully readable.
The Video
(double click for full-screen — if you’re not seeing it, try hitting F5 or using Firefox)
Emacs and Enlive enhance Clojure-mode from Lau Jensen on Vimeo.
Cleanup
Just to be sure the above code is a bit dirty because normally you’ll want to at least be able to tell control structs from regular functions. Unfortunately Clojure.org doesn’t provide this distinction, so if you want to preseve the old highlighting, I suggest you do something like this, swapping out filter with remove and viceversa:
(defn scrape [] (let [page (-> "http://richhickey.github.com/clojure/" java.net.URL. html-resource) hits (select page [:div#namespace-entry :span#var-link :a#var-tag]) banned-list ["when" "while" "if" "or" "and" ...] ; Fill to your hearts content clean-list (->> hits (mapcat #(:content %)) (filter (fn [w] (every? #(not= % w) banned-list))) distinct)] (doseq [row (partition 5 clean-list)] (prn row))))
This is doing the very same thing as what you saw in the screencast, but its cleaned up a little bit, like what you’d expect from a function and not just REPL play. The only thing which might be a little untuitive in terms of understanding how the data gets tossed around is -» and mapcat. -» threads the first argument into the remaining arguments as the last item, so the above is similar to (distinct (filter (mapcat … hits))) and mapcat is (map concat (map f …)). I threw in a call to distinct because there were actually 5 names which were repeated, it makes no difference but its nicer.
Conclusion
Having a REPL lets you fire up both engines and just get going. If I was still fiddling in C, I would have to write the program, save the file, compile and link it, then run. After a series of fine-tunings I’d be able to work my way into Emacs.
If you haven’t yet installed your own shiny new Emacs/SLIME IDE: Go here. If you need Enlive: Go here.
| | |
Comments are closed.

about 2 months ago
Nice solution! I like the way you mix Clojure and Emacs techniques, e.g. using partition to break the input up and a keyboard macro to format it just so.
The next level solution would be to have the mode query the running Clojure via SLIME for each type of font-lock-able, and set itself up dynamically for each REPL. The existing hard-coded definitions could be left in the file as defaults, and then these defaults could be overwritten where the SLIME API provides alternatives.
I take your point about a quick and dirty solution, but have you any comments about whether this would be possible? Perhaps a SLIME-side API would not be necessary, and there are just introspection functions which could be called to return the necessary data.
about 2 months ago
@Vincent: Thanks!
Following the release of this blogpost we had a discussion in #Clojure with Phil Hagelbert the maintainer of Clojure-mode, and he proposed a solution with dynamic highlighting of everything in the Clojure.core namespace and another community member started working on it immediately. Printing the functions in itself is not a problem, so now I assume they’re making a patch for Clojure-mode.
about 2 months ago
Here’s the update to clojure-mode.el:
http://github.com/technomancy/clojure-mode/commit/2f611adb3283cd287506880c792e3845e5a0d559