如何将clojure源文件连接到Emacs上正在运行的clojure repl?

时间:2010-08-12 18:56:08

标签: emacs clojure slime aquamacs

我目前正在为Tomcat容器中的现有J2EE webapp添加功能,我正在使用Clojure编写我的添加内容。我的设置很简单:我只是添加对clojure生成的静态方法的调用,并编写来自clojure方面的所有艰苦工作。构建过程包括编译clojure代码(lein uberjar),然后在类路径上使用该jar编译java代码。

在webapp init中,我调用了一个生成的类,该类启动了一个(swank/start-repl)的swank服务器。我希望能够将我的Aquamacs的粘液连接到该服务器,并从那里以交互方式工作(直到某一点,我不会尝试任何需要java端重新编译的东西)。但我有一种我不太明白的情况。如果我执行\M-x slime-connect,我会收到一个REPL提示(在收到通知后没有低级lisp进程,我认为没关系,因为劣质lisp进程在emacs控制之外运行)。我可以完美地评估表格,甚至可以检查my.own.namespace/my-var之类的内容。但是,如果我访问一个已经编译过的clojure代码的文件,我似乎无法让slime认出它作为它的来源。考虑一个简单的clojure文件:

(ns my.namespace
  (:gen-class
   :name my.namespace
   :methods [#^{:static true} [testFunc [] void]]))

(def *secret* "shhhh")

(defn -testFunc []
  (println (str "our secret is: " secret)))

假设这是编译并包含在webapp加载的uberjar中,我可以评估/检查my.namespace/*secret*。但是如果我尝试在代码缓冲区内进行评估,那么Slime认为我在user命名空间(甚至可以理解!)。但现在我只剩下一个工作选项 - 我必须逐一评估文件中的所有表格! \C-c \C-l(加载源文件)不会做任何事情 - 显然只返回nil而不输出任何其他内容。编译所有内容似乎就是这样 - 它编译,如果找到它们会显示错误,但不会更改我的命名空间。而最奇怪的是\C-~(同步包和目录),它使用Common Lisp它正是我想要的,但在这里它冻结了clojure REPL。

总是可以选择切换到REPL,键入(in-ns 'my.namespace),然后一切正常。但是当clojure文件数量不断增长时(因为代码缓冲区的命名空间不会自动更改),这根本不够实用!)

我的问题是,我是否缺乏基本的命令/配置 - 或者是否有明显的原因导致这种行为发生。

3 个答案:

答案 0 :(得分:5)

我可能误解了你的问题,但你不能(在emacs中访问这个假设的缓冲区时),点击C-c C-k来编译当前Clojure实例中的缓冲区(Slime连接到什么)?

然后,在Slime缓冲区中,使用(in-ns 'my.namespace)切换到此命名空间。然后,您应该可以访问在该命名空间中编译的内容。

答案 1 :(得分:2)

在编译时自动切换命名空间从来就不是swank-clojure的默认设置,尽管它可能是一个可选的粘液功能,恰好与Clojure一起使用。但C-c M-p将repl切换到当前缓冲区的命名空间一直对我有用,而且我从来没有听说过有人遇到过这个问题。

你是在运行最新稳定版本的clojure-mode和slime-repl吗?你有swank-clojure.el安装? (你不应该需要它。)听起来这可能是因为elisp库的版本不匹配。如果这不是问题,那可能是Aquamacs的错误; swank-clojure旨在与GNU Emacs一起使用。如果你从主干而不是最新的elpa版本运行,它也可能是粘液中的一个错误。

答案 2 :(得分:1)

我刚刚发现删除了这个问题的罪魁祸首:来自slime-repl.el的slime-redirect-inferior-output是从我设置的钩子中调用的。事实证明,如果没有劣质的lisp进程(读取,swank服务器从emacs内部启动),它就不能很好地发挥作用。

因此,快速解决方法是从this中删除该函数中的error表单。现在钩子继续进行,并自动计算命名空间。如预期。谢谢你的建议,但他们引导我找到了这个解决方案!