为Elocs/Swank/Paredit提供Clojure的温和教程

use*_*855 87 emacs clojure

我正在转向Emacs来处理Clojure/Lisp.为了能够执行以下操作,我需要在Emacs上设置的所有信息是什么?

  1. 自动匹配/生成相应的关闭括号
  2. autoindent Lisp/Clojure风格,而不是C++/Java风格
  3. 语法突出显示
  4. 调用REPL
  5. 能够将文件中的一部分代码加载到REPL中并进行评估.

如果我在Emacs上进行设置之后还可以获得命令列表来获取这些内容,那将是很棒的.

Mic*_*zyk 89

[来自非作者的编辑:这是从2010年开始,自2011年5月以来,该过程已经大大简化.我将在2012年2月的设置说明中为此答案添加帖子.]

你需要整理几件:Emacs,SLIME(与Clojure完美配合 - 见swank-clojure),swank-clojure(SLIME服务器对应的Clojure实现),clojure-mode,Paredit和当然,Clojure罐子一开始,然后也许是一些额外的,其中Leiningen可能是最值得注意的.一旦你完成所有设置,你将在Emacs中拥有你在问题中提到的所有工作流程/编辑功能.

基本设置:

以下是很好的教程,描述了如何设置所有这些; 网络上有更多,但其他一些已经过时了,而这两个似乎现在还可以:

  1. Phil Hagelberg的博客中发现有关clojure作者职位的交易技巧 ; Phil保持了swank-clojure和clojure模式,以及一个名为Emacs Starter Kit的软件包,这对Emacs世界的任何新手来说都是明智的建议.这些说明似乎已经与最近基础设施的变化有关; 如有疑问,请查看有关Clojure Google小组的其他信息.

  2. 在Incanter项目的博客上设置Clojure,Incanter,Emacs,Slime,Swank和Paredit.Incanter是一个迷人的软件包,为嵌入Clojure的统计计算提供类似R的DSL.即使您不打算使用 - 甚至安装 - 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组合来编译当前的缓冲区,然后use或者require其在REPL命名空间.接下来,试验一下.

最后的说明:

准备好在所有点击之前调整一段时间.涉及到很多工具,它们之间的相互作用大多相当平稳,但是并不是可以安全地假设您最初不需要进行一些调整.

最后,这里有一些我在.emacs其他地方找不到的代码(尽管它基于Phil Hagelberg的一个很酷的功能).我在启动我的swank实例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))
Run Code Online (Sandbox Code Playgroud)

  • 别客气.希望它能让你顺利进入Clojure.快乐的黑客!:-) (3认同)
  • 非常感谢你的精彩写作! (2认同)
  • ł:非常好写.谢谢. (2认同)

Pio*_*ski 10

还有一个非常好的教程:

在30到45分钟内,您可以从头开始设置所有内容.

本教程不假设任何先前的Emacs知识(以及Clojure也是如此 - 在之前的帖子中有一个很好的介绍Clojure).


Art*_*ldt 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)
Run Code Online (Sandbox Code Playgroud)

然后运行:

lein swank
Run Code Online (Sandbox Code Playgroud)

来自Emacs:

 alt-x slime-connect
Run Code Online (Sandbox Code Playgroud)