Emacs / Swank / Paredit的Clojure入门教程


87

我将移至Emacs从事Clojure / Lisp的工作。为了执行以下操作,我需要在Emacs上设置的所有信息是什么?

  1. 自动匹配/生成相应的括号
  2. 自动缩进Lisp / Clojure样式,而不是C ++ / Java样式
  3. 语法高亮
  4. 调用REPL
  5. 为了能够将一部分代码从文件加载到REPL中并进行评估。

如果在Emacs上进行设置之后,我还能够获得命令列表来获取这些信息,那将是很棒的。

Answers:


89

[由非作者编辑:这是2010年的内容,自2011年5月以来,此过程已得到显着简化。我将在2012年2月之前在此答案中添加设置笔记,并发帖。

您需要将以下几部分放在一起:Emacs,SLIME(与Clojure完美配合-参见swank-clojure),swank-clojure(SLIME服务器副本的Clojure实现),clojure-mode,Paredit和当然,首先是Clojure罐子,然后也许还有一些额外的东西,其中Leiningen也许是最著名的。完成所有设置后,您将在Emacs中拥有问题中提到的所有工作流程/编辑功能。

基本设置:

以下是一些很棒的教程,它们描述了如何进行所有这些设置。Web上还有更多功能,但是其他一些功能已经过时,而目前看来这两个还可以:

  1. 菲尔·黑格尔伯格(Phil Hagelberg)的博客中发现了有关Clojure作者身份的交易技巧;Phil维护着swank-clojure和clojure-mode以及称为Emacs Starter Kit的软件包,这是Emacs领域的任何新手都值得推荐的东西。这些说明似乎已随着基础结构的最新更改而更新。如有疑问,请在Clojure的Google组中查找其他信息。

  2. 在Incanter项目的博客上设置Clojure,Incanter,Emacs,Slime,Swank和Paredit帖子。Incanter是一个引人入胜的软件包,提供了类似R的DSL,用于嵌入到Clojure中的统计计算。即使您不打算使用-甚至不安装-Incanter,此帖子也将很有用。

全部使用:

设置完所有这些内容之后,您可以尝试立即开始使用它,但是我强烈建议您执行以下操作:

  1. 看看SLIME的手册-它包含在源代码中,并且非常易读。另外,绝对没有理由要阅读整本50页的怪物手册。请环顾四周,看看有哪些可用功能。

    注意:最新上游资源中发现的SLIME的autodoc功能与swank-clojure不兼容-如果您按照Phil Hagelberg的建议使用ELPA版本,则不会出现此问题(有关解释,请参见他前面提到的博客文章)或直接关闭autodoc(这是事物的默认状态)。后一种选择具有更多吸引力,因为您仍然可以将最新的SLIME与Common Lisp一起使用。

  2. 看看paredit的文档。有两种方法可以解决此问题:(1)查看源代码-文件顶部有大量注释,其中包含您可能需要的所有信息;(2)C-h m在paredit-mode处于活动状态时键入Emacs-会弹出一个缓冲区,其中包含有关当前主要模式的信息,然后是有关所有活动的次要模式的信息(paredit是其中之一)。

    更新:我刚刚在Phil Hagelberg的Paredit上找到了这些很酷的笔记集...这是一个文本文件的链接,我记得在某处看到了一组包含此信息的幻灯片,但是现在似乎找不到它。无论如何,这是一个很好的工作总结。一定要看看它,我相信我现在离不开Paredit,并且相信这个文件应该使开始使用它非常容易。:-)

  3. 实际上,该C-h m组合将告诉您在SLIME REPL上处于活动状态的所有键绑定,处于clojure模式(您要记住C-c C-k将当前缓冲区发送出去进行编译),实际上是任何Emacs缓冲区中。

至于从文件中加载代码,然后在REPL上对其进行实验,请使用上述C-c C-k组合来编译当前缓冲区,然后在REPL处编译其缓冲区userequire命名空间。接下来,尝试一下。

最后说明:

准备好在所有单击之前调整一些时间。这里涉及到很多工具,它们之间的交互通常相当流畅,但并不是可以安全地假设您一开始就不必进行一些调整。

最后,这是我保留的一些代码.emacs,您在其他地方看不到(尽管它基于Phil Hagelberg的出色功能)。我交替使用lein swank(Leiningen的一些更酷的功能)启动我的呆萌实例,然后使用clojure-project如下所示的功能从Emacs中启动整个过程。我已尽力使后者产生与所提供的环境紧密匹配的环境lein swank。哦,如果您只是想要Emacs中的REPL进行快速而肮脏的实验,那么使用正确的设置,您应该可以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
非常感谢您的美好写作!
user855'2

3
别客气。希望它能帮助您使用Clojure。骇客骇客!:-)
米哈尔Marczyk

2
:非常好写。谢谢。
拉尔夫(Ralph)2010年

确实,这是一个非常不错的教程。我刚刚发现,即使我不太喜欢,最好的选择是Emacs。IDEA,Eclipse和netbeans根本不适合您。
亚当·阿罗德


8

Emacs的入门套件已经入门使用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


1

这里必须提到CIDER(Clojure交互式开发环境)。

它涵盖了您所需要的大部分内容。这包括:

  • 交互式REPL
  • 调试
  • 试运行
  • 代码导航
  • 文档查找
  • 还有更多

除CIDER之外,还有其他一些重要的插件,用于Clojure开发,我将分别(主观地)对它们进行分组:

必需品

尼斯

一般基础知识(适用于任何语言)

  • magit – Emacs内部的git瓷器

  • 弹丸–用于查找文件,搜索等的mgmt项目

  • 掌舵–增量完成和选择范围缩小框架(或 swiper

其他资源

如果您正在寻找已经为您完成大部分/所有工作的设置,则有两个选项:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.