Нежный учебник для Emacs/Swank/Paredit для Clojure

Я переезжаю в Emacs, чтобы работать над Clojure/Lisp. Какова вся информация, которую мне нужно настроить на Emacs, чтобы иметь возможность сделать следующее?

  • автоматическое совпадение/генерация соответствующих закрывающих скобок
  • autoindent Lisp/Clojure стиль, а не стиль С++/Java
  • Подсветка синтаксиса
  • Вызов REPL
  • Чтобы иметь возможность загружать часть кода из файла в REPL и оценивать его.

Было бы здорово, если бы я мог получить список команд, чтобы получить эти вещи после настройки вещей на Emacs.

Ответ 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))

Ответ 2

Есть еще один отличный учебник:

Через 30-45 минут все может быть настроено с нуля.

В учебном пособии не предполагается никаких предварительных знаний Emacs (и Clojure тоже - в более ранних сообщениях есть хорошее введение в Clojure).

Ответ 3

комплект Emacs Starter получил отличные отзывы для начала работы с Clojure:

Чтобы ответить только на чертовую часть вашего вопроса:

Leiningen - это действительно простой способ настроить swank с правильным классом классов и подключить его к Emacs.

Отличное видео здесь: http://vimeo.com/channels/fulldisclojure#8934942 Ниже приведен пример файла project.clj, который

(defproject project "0.1"
    :dependencies [[org.clojure/clojure
                      "1.1.0-master-SNAPSHOT"]
                   [org.clojure/clojure-contrib
                      "1.0-SNAPSHOT"]]
    :dev-dependencies [[leiningen/lein-swank "1.1.0"]]
    :main my.project.main)

затем выполните:

lein swank

и из Emacs:

 alt-x slime-connect