[Редактировать от неавтора: это с 2010 года, и этот процесс значительно упростился с мая 2011 года. Я добавлю к этому ответу пост с моими замечаниями по настройке на февраль 2012 года.]
Вам нужно собрать несколько частей: Emacs, SLIME (который прекрасно работает с Clojure - см. Swank-clojure), swank-clojure (реализация Clojure серверного аналога SLIME), clojure-mode, Paredit и, конечно же, банку Clojure для начала, а затем, возможно, некоторые дополнения, среди которых Лайнинген, возможно, будет самым заметным. Как только вы все настроите, в Emacs вы получите все функции рабочего процесса / редактирования, которые вы упомянули в вопросе.
Базовая настройка:
Ниже приведены отличные учебники, в которых описывается, как все это настроить; в Интернете есть еще что-то, но некоторые другие устарели, в то время как эти два, кажется, в порядке:
, в котором можно найти хитрости, касающиеся авторства Clojure сообщение в блоге Фила Хагельберга; Фил поддерживает режим swank-clojure и clojure-mode, а также пакет под названием Emacs Starter Kit, на который любой новичок в мире Emacs должен посоветовать взглянуть. Эти инструкции, похоже, были обновлены с учетом последних изменений в инфраструктуре; в случае сомнений поищите дополнительную информацию о группе Google Clojure.
Настройка сообщений Clojure, Incanter, Emacs, Slime, Swank и Paredit в блоге проекта Incanter. Incanter - это увлекательный пакет, предоставляющий R-подобный DSL для статистических вычислений, встроенных прямо в Clojure. Этот пост будет полезен, даже если вы не планируете использовать или даже устанавливать Incanter.
Положить все это на работу:
После того, как вы настроите все это, вы можете сразу же начать его использовать, но я настоятельно рекомендую вам сделать следующее:
Взгляните на руководство SLIME - оно включено в источники и на самом деле очень читабельно. Кроме того, нет абсолютно никаких причин, по которым вам следует прочитать все 50-страничное руководство для монстров; просто посмотрите вокруг, чтобы увидеть, какие функции доступны.
Примечание: Функция автодока SLIME, обнаруженная в последних исходных источниках, несовместима с swank-clojure - эта проблема не возникнет, если вы будете следовать рекомендации Фила Хагельберга по использованию версии ELPA см. его вышеупомянутый пост в блоге для объяснения) или просто отключите autodoc (это состояние по умолчанию). Последний вариант имеет дополнительную привлекательность в том смысле, что вы все еще можете использовать последнюю версию SLIME с Common Lisp, если вы используете ее также.
Посмотрите документы для paredit. Есть два способа сделать это: (1) посмотреть на источник - в верхней части файла находится огромное количество комментариев, которые содержат всю информацию, которая вам, вероятно, понадобится; (2) введите Ch m в Emacs, когда активен режим paredit - появится всплывающий буфер с информацией о текущем основном режиме, за которым следует информация обо всех активных второстепенных режимах (paredit - один из них).
Обновление: Я только что нашел этот классный набор заметок на Paredit от Phil Hagelberg ... Это ссылка на текстовый файл, я помню, видел хороший набор скользит с этой информацией где-то, но не может найти ее сейчас. В любом случае, это хорошее резюме того, как это работает. Определенно посмотрите на это, я не могу жить без Paredit сейчас, и этот файл должен облегчить его использование, я полагаю. : -)
На самом деле комбинация Ch m расскажет вам обо всех сочетаниях клавиш, активных на SLIME REPL, в режиме clojure (вы должны запомнить Cc Ck для отправки текущего буфера для компиляции) и действительно в любом буфере Emacs.
Что касается загрузки кода из файла и последующего эксперимента с ним в REPL: используйте вышеупомянутую комбинацию Cc Ck для компиляции текущего буфера, затем use
или require
его пространство имен в РЕПЛ. Далее, экспериментируйте.
Заключительные ноты:
Будьте готовы немного подправить вещи, прежде чем все это щелкнет. Здесь задействовано много инструментов, и их взаимодействие в основном довольно плавное, но не до такой степени, что было бы безопасно предположить, что вам не придется вносить какие-то корректировки на начальном этапе.
Наконец, вот небольшой код, который я храню в .emacs
, который вы не найдете в другом месте (хотя он основан на классной функции Фила Хейгельберга). Я чередую запускать экземпляры swank с lein swank
(одна из кулеров Leiningen) и использовать функцию clojure-project
, как показано ниже, для запуска всего этого из Emacs. Я приложил все усилия, чтобы последние создали среду, точно соответствующую той, которая предусмотрена lein swank
. Да, и если вы просто хотите использовать REPL в Emacs для быстрого и грязного эксперимента, то при правильной настройке вы сможете напрямую использовать M-x slime .
(setq clojure-project-extra-classpaths
'(
; "deps/"
"src/"
"classes/"
"test/"
))
(setq clojure-project-jar-classpaths
'(
; "deps/"
"lib/"
))
(defun find-clojure-project-jars (path)
(apply #'append
(mapcar (lambda (d)
(loop for jar in (remove-if (lambda (f) (member f '("." "..")))
(directory-files d t))
collect jar into jars
finally return jars))
(remove-if-not #'file-exists-p
clojure-project-jar-classpaths))))
(defun find-clojure-jar (jars)
(let ((candidates
(remove-if-not
(lambda (jar)
(string-match-p "clojure\\([0-9.-]+\\(SNAPSHOT|MASTER\\)?\\)?\\.jar$" jar))
jars)))
(if candidates
(car candidates)
(expand-file-name "~/.clojure/clojure.jar"))))
(defun find-clojure-contrib-jar (jars)
(let ((candidates
(remove-if-not
(lambda (jar)
(string-match-p "clojure-contrib\\([0-9.-]+\\(SNAPSHOT|MASTER\\)?\\)?\\.jar$" jar))
jars)))
(if candidates
(car candidates)
(expand-file-name "~/.clojure/clojure-contrib.jar"))))
;;; original due to Phil Hagelberg
;;; (see `Best practices for Slime with Clojure' thread on Clojure Google Group)
(defun clojure-project (path)
"Sets up classpaths for a clojure project and starts a new SLIME session.
Kills existing SLIME session, if any."
(interactive (list (ido-read-directory-name
"Project root:"
(locate-dominating-file default-directory "pom.xml"))))
(when (get-buffer "*inferior-lisp*")
(kill-buffer "*inferior-lisp*"))
(cd path)
;; I'm not sure if I want to mkdir; doing that would be a problem
;; if I wanted to open e.g. clojure or clojure-contrib as a project
;; (both lack "deps/")
; (mapcar (lambda (d) (mkdir d t)) '("deps" "src" "classes" "test"))
(let* ((jars (find-clojure-project-jars path))
(clojure-jar (find-clojure-jar jars))
(clojure-contrib-jar (find-clojure-contrib-jar jars)))
(setq swank-clojure-binary nil
;; swank-clojure-jar-path (expand-file-name "~/.clojure/clojure.jar")
swank-clojure-jar-path clojure-jar
swank-clojure-extra-classpaths
(cons clojure-contrib-jar
(append (mapcar (lambda (d) (expand-file-name d path))
clojure-project-extra-classpaths)
(find-clojure-project-jars path)))
swank-clojure-extra-vm-args
(list (format "-Dclojure.compile.path=%s"
(expand-file-name "classes/" path)))
slime-lisp-implementations
(cons `(clojure ,(swank-clojure-cmd) :init swank-clojure-init)
(remove-if #'(lambda (x) (eq (car x) 'clojure))
slime-lisp-implementations))))
(slime))