如何将 clojure 源文件连接到 Emacs 上正在运行的 clojure repl?
我目前正在向 Tomcat 容器中的现有 J2EE Web 应用程序添加功能,并且我正在使用 Clojure 编写添加内容。我的设置很简单:我只需添加对 clojure 生成的静态方法的调用,并从 clojure 端编写所有艰苦的工作。构建过程包括编译 clojure 代码 (lein uberjar
),然后使用类路径上的该 jar 编译 java 代码。
在 webapp init 中,我调用了一个生成的类,该类使用 (swank/start-repl)
启动 swank 服务器。我希望能够将我的 Aquamacs 的 slime 连接到该服务器,并从那里交互式地工作(在某种程度上,我不会尝试任何需要 java 端重新编译的事情)。但我有一个不太明白的情况。如果我执行 \Mx 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)))
假设该文件已编译并包含在 web 应用程序加载的 uberjar 中,我可以评估/检查 my.namespace/*secret*
。但是如果我尝试在代码缓冲区内进行评估,Slime 会认为我位于 user
命名空间上(这甚至可以说得通!)。但现在我只剩下一个工作选项 - 我必须逐一评估文件中的所有表格! \Cc \Cl
(加载源文件)不会执行任何操作 - 显然只是返回 nil 并且不输出任何其他内容。编译所有内容似乎就是这样做的 - 它会编译,如果发现错误则显示错误,但不会更改我的名称空间。最奇怪的是 \C-~
(同步包和目录),它使用 Common Lisp 实现了我想要的功能,但在这里它永久冻结了 clojure REPL。
始终可以选择切换到 REPL,输入 (in-ns 'my.namespace)
,然后一切正常。但是,当 clojure 文件数量不断增长时,这根本不够实用(因为代码缓冲区的命名空间不会自动更改!)
我的问题是,我是否缺少基本命令/配置 - 或者如果这种行为的发生有一个明显的原因。
I'm currently in the process of adding functionality to an existing J2EE webapp, in a Tomcat container, and I'm writing my additions using Clojure. My setup is simple: I just add calls to static methods generated by clojure, and code all the hard work from the clojure side. The build process consists in compiling clojure code (lein uberjar
) and then compiling the java code with that jar on the classpath.
In the webapp init, I have a call to a generated class that fires up a swank server with a (swank/start-repl)
. I'd like to be able to connect my Aquamacs' slime to that server, and work interactively from there (up to a point, I won't try nothing that requires a java-side recompilation). But I have a situation that I don't quite understand. If I do a \M-x slime-connect
, I get a REPL prompt (after being notified that there's no inferior lisp process, which I think it's ok, since the inferior lisp process is running outside emacs control). I can evaluate forms perfectly, and I can even inspect things like my.own.namespace/my-var
. However, if I visit a file with an already compiled clojure code, I can't seem to make slime recognize it as its source. Consider a simple clojure file:
(ns my.namespace
(:gen-class
:name my.namespace
:methods [#^{:static true} [testFunc [] void]]))
(def *secret* "shhhh")
(defn -testFunc []
(println (str "our secret is: " secret)))
Assuming that this was compiled and included in the uberjar loaded by the webapp, I can eval/inspect my.namespace/*secret*
. But If I try to eval inside the code buffer, Slime thinks I'm on the user
namespace (which can even make sense!). But now I'm left with a single working option - I have to evaluate - one by one, all the forms in the file! \C-c \C-l
(loading the source file) won't do nothing - apparently just returns nil and outputs nothing else. Compiling everything seems to do just that - it compiles, shows errors if it finds them, but won't change my namespace. And the strangest is the \C-~
(sync package and directory), which using Common Lisp it does just what I want, but here it freezes the clojure REPL for good.
There's always the option of switching to the REPL, typing (in-ns 'my.namespace)
, and then all works properly. But that simply isn't practical enough when the clojure files are growing in number (as the namespace of the code buffer won't change automatically!)
My question is, then, whether I'm lacking a basic command/configuration - or if there's an obvious reason for this behavior to happen as such.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我可能误解了你的问题,但是你不能(在 emacs 中访问这个假设的缓冲区时)点击 Cc Ck 来编译当前 Clojure 实例中的缓冲区(Slime 连接到的是什么)吗?
然后,在 Slime 缓冲区中,使用
(in-ns 'my.namespace)
切换到此命名空间。然后您应该可以访问您在该名称空间中编译的内容。I may be misunderstanding your problem, but can't you (while visiting this hypothetical buffer in emacs), hit
C-c C-k
to compile the buffer in your current Clojure instance (what Slime is connected to)?Then, in the Slime buffer, switch to this namespace with a
(in-ns 'my.namespace)
. Then you should have access to what you compiled in that namespace.在编译时自动切换名称空间从来都不是 swank-clojure 的默认设置,尽管它可能是一个可选的 slime 功能,恰好与 Clojure 一起使用。但是 Cc Mp 将 repl 切换到当前缓冲区的命名空间一直对我有用,而且我从未听说过有人遇到麻烦。
您是否正在运行最新稳定版本的 clojure-mode 和 slime-repl?你安装了 swank-clojure.el 吗? (你不应该需要它。)听起来这可能是由于 elisp 库的版本不匹配造成的。如果这不是问题,则可能是 Aquamacs 错误; swank-clojure 设计用于与 GNU Emacs 配合使用。如果您从 trunk 而不是最新的 elpa 版本运行,它也可能是 slime 中的错误。
Switching namespaces automatically on compile has never been the default for swank-clojure, though it might be an optional slime feature that happened to work with Clojure. But C-c M-p to switch the repl to the current buffer's namespace has always worked for me, and I've never heard of anyone having trouble with it.
Are you running on the latest stable versions of clojure-mode and slime-repl? Do you have swank-clojure.el installed? (You shouldn't need it.) It sounds like this could be due to mismatched versions of the elisp libs. If that's not the problem it could be an Aquamacs bug; swank-clojure is designed to work with GNU Emacs. It could also be a bug in slime if you are running from trunk rather than the latest elpa release.
我刚刚发现,删除此问题的罪魁祸首:来自 slime-repl.el 的
slime-redirect-inferior-output
是从我设置的挂钩中调用的。事实证明,如果没有劣质 lisp 进程(请阅读,从 emacs 内部启动的 swank 服务器),它就无法正常运行。因此,一个快速的解决方法就是从该函数中删除
error
形式,例如 this< /a>.现在挂钩继续进行,并且名称空间将自动计算。正如预期的那样。尽管如此,还是感谢您的建议 - 他们引导我找到了这个解决方案!I've just found out that removing the culprit for this issue:
slime-redirect-inferior-output
, from slime-repl.el, was being called from a hook I had setup. It turns out that it doesn't play well without an inferior-lisp-process (read, a swank server started from within emacs).So a quick workaround hack is just to remove the
error
form from that function, like this. Now the hook proceeds, and the namespaces are automatically calculated. As intended. Thank you for the suggestions, nevertheless - they led me to this solution!