Небольшое руководство по Emacs/Swank/Paredit для Clojure

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

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

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

4 ответа

Решение

[Редактировать от неавтора: это с 2010 года, и процесс был значительно упрощен с мая 2011 года. Я добавлю к этому ответу пост с моими замечаниями по настройке по состоянию на февраль 2012 года.]

Вам нужно собрать несколько частей: Emacs, SLIME (который прекрасно работает с Clojure - см. Swank-clojure), swank-clojure (реализация Clojure серверного аналога SLIME), clojure-mode, Paredit и, из Конечно, баночка Clojure для начала, а затем, возможно, некоторые дополнительные функции, среди которых, возможно, наиболее заметным будет Leiningen. После того, как вы все настроите, в Emacs появятся все функции рабочего процесса / редактирования, которые вы упомянули в вопросе.

Базовая настройка:

Ниже приведены отличные учебники, в которых описывается, как все это настроить; в Интернете есть еще что-то, но некоторые другие устарели, в то время как эти два, кажется, в порядке:

  1. в котором найдены уловки торговли относительно сообщения авторства clojure в блоге Фила Хэгелберга; Фил поддерживает режим swank-clojure и clojure-mode, а также пакет под названием Emacs Starter Kit, на который любой новичок в мире Emacs должен посоветовать взглянуть. Эти инструкции, кажется, были обновлены с учетом последних изменений в инфраструктуре; в случае сомнений поищите дополнительную информацию о группе Google Clojure.

  2. Настройка сообщений Clojure, Incanter, Emacs, Slime, Swank и Paredit в блоге проекта Incanter. Incanter - это увлекательный пакет, предоставляющий R-подобный DSL для статистических вычислений, встроенных прямо в Clojure. Этот пост будет полезен, даже если вы не планируете использовать или даже устанавливать Incanter.

Положить все это на работу:

После того, как вы настроите все это, вы можете сразу же начать использовать его, но я настоятельно рекомендую вам сделать следующее:

  1. Взгляните на руководство SLIME - оно включено в источники и на самом деле очень читабельно. Кроме того, нет абсолютно никакой причины, почему вы должны читать все 50-страничное руководство для монстров; просто посмотрите вокруг, чтобы увидеть, какие функции доступны.

    Note: the autodoc feature of SLIME as found in the latest upstream sources is incompatible with swank-clojure -- this problem won't come up if you follow Phil Hagelberg's recommendation to use the ELPA version (see his aforementioned blog post for an explanation) or simply leave autodoc off (which is the default state of things). The latter option has some added appeal in that you can still use the latest SLIME with Common Lisp, in case you use that as well.

  2. Have a look at the docs for paredit. There are two ways to go about this: (1) look at the source -- there's a huge amount of comments at the top of the file which contain all the information you're likely to need; (2) type Ch m in Emacs while paredit-mode is active -- a buffer will pop up with information on the current major mode followed by information on all active minor modes (paredit is one of those).

    Update: I've just found this cool set of notes on Paredit by Phil Hagelberg... That's a link to a text file, I remember seeing a nice set of slides with this information somewhere, but can't seem to find it now. Anyway, it is a nice summary of how it works. Definitely take a look at it, I can't live without Paredit now and this file should make it very easy to start using it, I believe.:-)

  3. In fact, the Ch m combination will tell you about all keybindings active at the SLIME REPL, in clojure-mode (you'll want to remember Cc Ck for sending the current buffer off for compilation) and indeed in any Emacs buffer.

As for loading the code from a file and then experimenting with it at the REPL: use the aforementioned Cc Ck combination to compile the current buffer, then use или же require its namespace at the REPL. Next, experiment away.

Финальные заметки:

Be prepared to have to tweak things for a while before it all clicks. There's a lot of tools involved and their interactions are mostly fairly smooth, but not to the point where it would be safe to assume you won't have to make some adjustments initially.

Finally, here's a bit of code I keep in .emacs which you won't find elsewhere (although it's based on a cool function by Phil Hagelberg). I alternate between starting my swank instances with lein swank (one of the cooler features of Leiningen) and using the clojure-project function as found below to start the whole thing from within Emacs. I've done my best to make the latter produce an environment closely matching that provided by lein swank, Oh, and if you just want a REPL in Emacs for a quick and dirty experiment, then with the correct setup you should be able to use Mx slime directly.

(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))

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

От 30 до 45 минут можно настроить все с нуля.

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

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

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

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

Отличное видео здесь: http://vimeo.com/channels/fulldisclojure Вот пример файла 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

Clojure с Emacs на Clojure Документация также может быть полезна.

Здесь необходимо упомянуть CIDER (интерактивную среду разработки Clojure).

Он покроет большую часть того, что вы ищете. Это включает в себя:

  • интерактивный REPL
  • отладка
  • тестовый запуск
  • код навигации
  • поиск документации
  • еще больше

Помимо CIDER, есть еще несколько важных и полезных надстроек для разработки Clojure, которые я попытаюсь сгруппировать соответственно (и субъективно):

Основы

  • smartparens - парные скобки, манипуляции, навигация (или parinfer, если хотите)

  • clj-refactor - имеет несколько удивительных функций, таких как автоматическое добавление / компиляция пространств имен (скоро он может быть включен в CIDER)

  • clojure-mode - блокировка шрифтов, отступы, навигация

  • компания - фреймворк автозаполнения (или выберите другой автозаполнитель)

  • разделители радуги - выделяет / раскрашивает разделители, такие как круглые, квадратные или фигурные скобки, в зависимости от их глубины

  • flycheck - расширение для оперативной проверки синтаксиса

  • flycheck-clj-kondo - интеграция для clj-kondo

Тонкости

  • clojure-snippets - расширяемые табуляцией ярлыки для более длинных фрагментов кода

  • dumb-jump - переход к определениям

  • which-key - отображает доступные сочетания клавиш во всплывающем окне

  • выделите круглые скобки - выделите окружающие скобки

  • crux - коллекция смехотворно полезных расширений для Emacs

  • comment-dwim-2 - замена встроенного Emacscomment-dwim

Общие основы (для любого языка)

  • magit - git porcelain внутри Emacs

  • снаряд - управление проектом для поиска файлов, поиска и т. д.

  • helm - структура постепенного завершения и сужения выбора (или swiper)

Другие источники

Если вы ищете установку, которая уже выполнила большую часть / всю эту работу за вас, есть несколько вариантов:

Другие вопросы по тегам