Emacs / Swank / Paredit Clojure的一个温和的教程
我正在转向Emacs,致力于Clojure / Lisp。 我需要在Emacs上设置的所有信息能够执行以下操作?
- 自动匹配/生成相应的右括号
- autoindent Lisp / Clojure风格,而不是C ++ / Java风格
- 语法突出显示
- 调用REPL
- 为了能够从文件中加载一部分代码到REPL中并对其进行评估。
如果我能在Emacs上设置一些命令的列表来获得这些东西,那将是非常好的。
[从非作者编辑:这是从2010年,这个过程已经被大大简化,自2011年5月以来。我将添加一个post到我的设置备注截至2012年2月。
你需要把几个部分放在一起:Emacs,SLIME(与Clojure完美兼容 – 参见swank-clojure),swank-clojure(SLIME服务器对应的Clojure实现),clojure模式,Paredit和当然,Clojure的瓶子是一个开始,那么也许Leiningen可能是最值得注意的一些额外的。 一旦完成了设置,您将会在Emacs中获得您在问题中提到的所有工作stream程/编辑function。
基本设置:
以下是描述如何设置所有这些的很好的教程; networking上还有更多,但是其他一些已经过时了,而现在这两种似乎是可以的:
-
在菲尔·哈格尔伯格的博客中发现了关于clojure作者身份的行业技巧 ; Phil维护了swank-clojure和clojure-mode,还有一个名为Emacs Starter Kit的包,这是Emacs世界的任何新手都应该看看的东西。 这些说明似乎已经被提出来,最近基础设施的变化已经被提出来了。 如有疑问,请查看Clojure的Google小组的其他信息。
-
在Incanter项目的博客上设置Clojure,Incanter,Emacs,Slime,Swank和Paredit文章。 Incanter是一个迷人的软件包,它提供了一个embedded到Clojure中的用于统计计算的R-like DSL。 即使您不打算使用甚至安装Incanter,这篇文章也会很有用。
把这一切工作:
一旦你设置了所有这些东西,你可以尝试立即开始使用它,但我强烈build议你做以下事情:
-
看看SLIME的手册 – 它包含在源代码中,实际上非常可读。 另外,你完全没有理由读完整本50页的怪物手册。 只是看看有什么function可用。
注意: 在最新的上游源代码中find的SLIME的autodocfunction与swank-clojure不兼容 – 如果您按照Phil Hagelberg的build议使用ELPA版本,则不会出现此问题(请参阅他的上述博客文章以获得解释)或者直接closuresautodoc(这是事情的默认状态)。 后面的选项有一些额外的吸引力,因为你仍然可以使用最新的SLIME和Common Lisp,以防你使用它。
-
看一下文档中的paredit。 有两种方法可以解决这个问题:(1)查看源代码 – 文件顶部有大量的注释,其中包含您可能需要的所有信息; (2)在Emacs中inputCh m ,而paredit-mode处于活动状态 – 将popup一个缓冲区,其中包含当前主要模式的信息,后面跟随所有活动次要模式的信息(paredit就是其中之一)。
更新:我刚刚在Phil Hagelberg的Paredit上发现了这套很酷的笔记 …这是一个文本文件的链接,我记得在某处看到一组很好的幻灯片,但似乎无法find它。 无论如何,它是如何工作的一个很好的总结。 肯定看一下,我现在不能没有Paredit的生活,这个文件应该很容易开始使用它,我相信。 🙂
-
实际上, Ch m组合会告诉你所有在SLIME REPL处于活动状态的键绑定,在clojure模式下(你需要记住Cc Ck发送当前缓冲区进行编译),甚至在任何Emacs缓冲区中。
至于从文件加载代码,然后在REPL上进行试验:使用前面提到的Cc Ck组合来编译当前缓冲区,然后在REPL中use
或require
它的名称空间。 接下来,试验一下。
最后说明:
在所有点击之前准备好调整一下。 涉及到很多工具,它们之间的相互作用大都相当顺利,但是到最后假设你不需要做出一些调整是安全的。
最后,这里有一些我保存在.emacs
的代码,你不会在其他地方find它(尽pipe它是基于Phil Hagelberg的一个很酷的function)。 我在用lein swank
(Leiningen的一个更酷的特性)开始我的lein swank
实例和使用下面find的clojure-project
函数来从Emacs内部开始整个事情之间交替。 我已经尽力使后者产生一个与lein swank
提供的环境非常匹配的环境。 呵呵,如果你只是想在Emacs上做一个REPL来进行一个快速而肮脏的实验,那么使用正确的设置你就可以直接使用Mx 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 dt)) 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 eg clojure or clojure-contrib as a project ;; (both lack "deps/") ; (mapcar (lambda (d) (mkdir dt)) '("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))
还有一个更好的教程:
- http://www.braveclojure.com/basic-emacs/ (第一部分)
- http://www.braveclojure.com/using-emacs-with-clojure/ (第二部分)
在30到45分钟内,人们可以从头开始设置一切。
本教程不假设任何Emacs的知识(也是Clojure) – 在之前的文章中,Clojure有一个很好的介绍。
Emacs入门套件已经得到了Clojure 入门的好评:
要回答你的问题只是你的问题的一部分:
Leiningen是一个非常简单的方法,用正确的类pathbuild立swank并连接到Emacs。
一个伟大的video在这里: 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
在Clojure上使用Emacs进行Clojure文档也是有用的。