Ответ 1
[Редактировать с помощью неавтор: это с 2010 года, и процесс с момента его создания значительно упрощен с мая 2011 года. Я добавлю сообщение в этот ответ с моими установками с февраля 2012 года.]
Вам нужно собрать несколько частей: Emacs, SLIME (отлично работает с Clojure - см. swank- clojure), swank- clojure (реализация > сервера SLIME аналог), clojure -мод, Paredit и, конечно, банку Clojure для начала, а затем, возможно, некоторые дополнительные функции, среди которых Leiningen, возможно, был бы самым заметным. После того, как вы все настроите, у вас будет - внутри Emacs - все функции рабочего процесса/редактирования, которые вы указываете в вопросе.
Основная настройка:
Ниже приводятся подробные руководства, в которых описывается, как установить все это; там больше в Сети, но некоторые из них довольно устарели, в то время как эти два, похоже, сейчас в порядке:
-
в котором найдены трюки торговли, касающиеся публикации Clojure authorhip на блоге Фила Хагельберга; Фил поддерживает swank- clojure и clojure -mode, а также пакет под названием Emacs Starter Kit, который, как ни странно, должен знать любой новичок в мире Emacs. Кажется, что эти инструкции были обновлены с недавними изменениями в инфраструктуре; в случае сомнений, найдите дополнительную информацию о группе Clojure Google.
-
Настройка Clojure, Incanter, Emacs, Slime, Swank и Paredit в блоге проекта Incanter. Incanter - увлекательный пакет, предоставляющий R-подобный DSL для статистических вычислений, встроенных прямо в Clojure. Этот пост будет полезен, даже если вы не планируете использовать или даже устанавливать - Incanter.
Положив все на работу:
Как только вы настроите все это, вы можете попробовать и сразу начать использовать его, но я настоятельно рекомендую вам сделать следующее:
-
Взгляните на руководство SLIME - оно включено в источники и на самом деле очень читаемо. Кроме того, нет абсолютно никакой причины, по которой вы должны прочитать все 50-страничное руководство монстра; просто посмотрите, какие функции доступны.
Примечание: функция автодока SLIME, найденная в последних источниках восходящего потока, несовместима с swank- clojure - эта проблема не возникнет, если вы последуете за рекомендацией Фила Хагельберга по использованию Версия ELPA (см. Его вышеупомянутое сообщение в блоге для объяснения) или просто оставить autodoc off (это состояние по умолчанию). У последнего варианта есть еще одна привлекательность, поскольку вы все равно можете использовать последний SLIME с Common Lisp, если вы это используете.
-
Посмотрите на документы для paredit. Есть два способа сделать это: (1) взглянуть на источник - там огромное количество комментариев в верхней части файла, которые содержат всю информацию, которая вам может понадобиться; (2) введите C-h m в Emacs, в то время как режим paredit активен - появится буфер с информацией о текущем основном режиме, за которым следует информация обо всех активных второстепенных режимах (paredit является одним из них).
Обновление: Я только что нашел этот классный набор заметок на Paredit от Фила Хагельберга... Это ссылку на текстовый файл, я помню, что видел где-то хороший набор слайдов с этой информацией, но теперь, похоже, не могу найти его. Во всяком случае, это хорошее резюме того, как это работает. Определенно взгляните на это, я не могу жить без Paredit, и этот файл должен очень легко начать использовать его, я полагаю.: -)
-
В самом деле, комбинация C-h m расскажет вам обо всех связках клавиш, активных в SLIME REPL, в clojure -mode (вы хотите запомнить C-c C-k для отправки текущего буфера для компиляции ) и действительно в любом Emacs-буфере.
Как для загрузки кода из файла, а затем для его экспериментирования в REPL: используйте вышеупомянутую комбинацию C-c C-k для компиляции текущего буфера, затем use
или require
его пространство имен в REPL. Затем экспериментируйте.
Заключительные примечания:
Будьте готовы к тому, чтобы настроить какое-то время, прежде чем все клики. Там задействовано множество инструментов и их взаимодействие в основном довольно плавное, но не до такой степени, что было бы безопасно предположить, что вам не придется вносить некоторые корректировки изначально.
Наконец, здесь немного кода, который я храню в .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))