Skip to content

Clojure mit Emacs hacken

Ich habe einige Zeit versucht, die verschiedenen Modes für die Unterstützung von Clojure in Emacs manuell auf dem aktuellen Stand zu halten.

Dafür habe ich verschiedene git-Repositories verwendet. Angefangen habe ich mit etwas analog zu Exploring Clojure (Lisp on the JVM) – Part 2 – Setup – schlußendlich bin ich auf die Repositories von Phil Hagelberg gegangen:

Zunächst konnte man das swank-clojure-Projekt mit Maven bauen. Dann wurde der Build-Prozess auf Leiningen umgestellt, das bei mir nicht reibungslos zum Laufen zu bekommen war.

Zusätzlich bestand ein Problem darin, dass die verschiedenen Teile nicht immer vollständig zusammenarbeiten wollten – z.B. machte eine Änderung in SLIME den swank-clojure-Server unbrauchbar. Es war ziemlich zeitaufwendig die Abhängigkeiten (auch Leiningen) zwischen den Projekten so sauber hinzukriegen, dass alles tatsächlich lief.

Stand der Dinge

Inzwischen verwende ich einen viel einfacheren Installationsmechanismus: ELPA (Emacs Lisp Package Archive). Damit bin ich zwar nicht immer auf dem aktuellen Stand, aber wenigstens funktioniert das Zusammenspiel.

Und so wird’s gemacht:

  1. Zunächst ELPA installieren.
  2. Dann mit M-x package-list-packages ELPA starten.
  3. swank-clojure in der Liste der zur Verfügung stehenden Packages auswählen – mit i für die Installation markieren und mit x die Installation durchführen.
  4. Emacs neu starten
  5. Mit M-x slime werden die Abhängigkeiten von swank-clojure heruntergeladen und installiert:
    • clojure-mode, slime, slime- und swank-clojure werden in ein Unterverzeichnis elpa geladen.
    • der Java-Teil von swank-clojure, clojure und clojure-contrib werden in ein Unterverzeichnis .swank-clojure geladen.

Danach hat man eine tolle Entwicklungsumgebung für Clojure mit Tab-Vervollständigung, Syntaxhervorhebung, versch. Codenavigierungsmöglichkeiten und eine das Hackerherze verwöhnende REPL mit warmen Worten des Zuspruchs:

[codesyntax lang=“lisp“] (defvar slime-words-of-encouragement `(„Let the hacking commence!“ „Hacks and glory await!“ „Hack and be merry!“ „Your hacking starts… NOW!“ „May the source be with you!“ „Take this REPL, brother, and may it serve you well.“ „Lemonodor-fame is but a hack away!“ ,(format „%s, this could be the start of a beautiful program.“ (slime-user-first-name))) „Scientifically-proven optimal words of hackerish encouragement.“) [/codesyntax]

Weitere, ausführlichere Infos zum Setup gibt’s dort:

Außerdem gibt’s eine Seite im DenkzeitWiki, auf der ich weitere Erkenntnisse zusammentrage: Hacking Clojure With Emacs.

Nachfolgend noch der Clojure-relevante Teil meiner .emacs: [codesyntax lang=“lisp“] (require ‚paredit) ;; http://www.emacswiki.org/emacs/ParEdit (mapc (lambda (mode) (let ((hook (intern (concat (symbol-name mode) „-mode-hook“)))) (add-hook hook (lambda () (paredit-mode 1))))) ‚(emacs-lisp lisp inferior-lisp clojure slime slime-repl)) ; http://lispservice.posterous.com/paredit-in-the-slime-repl (add-to-list ‚load-path „~/.emacs.d/plugins/clojure“) ;; currently hosting: slime-fuzzy from http://elder-gods.org/~larry/repos/slime-tracker/contrib/slime-fuzzy.el (setq slime-repl-history-file „~/.emacs.d/persistent/.slime-history.eld“) ; from http://nflath.com/2009/09/slime-clojure-setup/ – default is ~/.slime-history.eld ;; slime (eval-after-load „slime“ ‚(progn ;;; http://groups.google.com/group/clojure/msg/419eb38c229269e5 (require ’slime-fuzzy) (setq slime-complete-symbol*-fancy t) (setq slime-complete-symbol-function ’slime-fuzzy-complete-symbol) (setq slime-use-autodoc-mode nil) ;; http://groups.google.com/group/clojure/msg/337057edae5dcdc3 (slime-setup ‚(slime-repl)))) ;;slime-banner slime-fancy do not work with ELPA/swank-clojure (currently: 20100108) (setq swank-clojure-binary „clj.bat“) ;; ~~~ http://www.skamphausen.de/cgi-bin/ska/My_Clojure_Setup (require ’slime) (require ‚clojure-mode) (require ’swank-clojure) (setq auto-mode-alist (cons ‚(„\\.clj$“ . clojure-mode) auto-mode-alist)) (def-slime-selector-method ?j „most recently visited clojure-mode buffer.“ (slime-recently-visited-buffer ‚clojure-mode)) (add-hook ‚clojure-mode-hook (lambda () (setq fill-column 80) (setq indent-tabs-mode nil) )) ;; ~~ (defun slimer () „Starts a two-window (current window at top, REPL at bottom) hacking session.“ (interactive) (when (get-buffer „*inferior-lisp*“) (kill-buffer „*inferior-lisp*“)) (save-window-excursion (slime))) [/codesyntax]

clj.bat sieht so aus:

[codesyntax lang=“dos“] @echo off rem http://bc.tech.coop/blog/081023.html REM set-up customized local environment call clj-local-env.bat set clj_jv_debug=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8889 set clj_jv_params=-Xms64m -Xmx1024m %clj_jv_server% -XX:+UseConcMarkSweepGC -XX:+DoEscapeAnalysis -Xbootclasspath/a:“%clj%“;“%clj%\clojure.jar“;“%clj%\clojure-contrib.jar“ REM -XX:+UseCompressedOops set clj_emacs_swank=“%HOME%\.swank-clojure\swank-clojure-1.1.0.jar“ set clj_cp_libs=“%clj_scratch%\src“;“%clj_scratch%\target\classes“;“%clj_scratch%\lib\wax_1.0.1.jar“;“%clj_scratch%\lib\vtd-xml.jar“;“%clj_scratch%\lib\miglayout-3.7.2.jar“ set clj_cp=%clj_cp_libs%;%clj_emacs_swank% REM http://www.robvanderwoude.com/parameters.php if [%1] == [] goto repl REM echo java %clj_jv_params% -cp %clj_cp% clojure.main %* java %clj_jv_params% -cp %clj_cp% clojure.main %* goto END :repl REM echo java %clj_jv_params% -cp %clj_cp% clojure.main java %clj_jv_params% -cp %clj_cp% clojure.main REM this does not work – „no ‚clj_jv_server‘ JVM at…“ REM javaw %debug% -cp %clj_cp% clojure.main :end [/codesyntax]

Und clj-local-env.bat so:

[codesyntax lang=“dos“] @echo off set clj=c:\Users\Steffen\hacking\clojure set clj_scratch=%clj%\scripts set clj_jv_server=-server [/codesyntax]

clj-local-env.bat verwende ich um Variablen so zu setzen, dass ich dieselbe clj.bat auf verschiedenen Rechnern verwenden kann.
clj.bat ist mit der Dateiendung clj verknüpft – wird also z.B. beim Doppelklick auf clj-Dateien verwendet.

Post a Comment

Your email is never published nor shared. Required fields are marked *