高效Clojure工作流程? [英] Efficient Clojure workflow?
问题描述
我目前的工作流程(Compojure)是:
我正在使用Clojure开发一个宠物项目, p>- 以
lein swank
开始Swank。 - 转到Emacs,连接
Mx slime-connect
。 - 逐个加载所有现有的源文件。这也启动了一个Jetty服务器和一个应用程序。
- 在REPL中编写一些代码。
- 我记住了。 Eval(
Cc Cc
)it。 - 将REPL切换到此结构所驻留的命名空间并进行测试。
- 切换到浏览器并重新载入受影响网页的浏览器标签。
- 调整代码,对其进行评估,检入浏览器。
- 重复上述任一操作。
有许多麻烦:
- 我必须在Emacs和浏览器之间切换(如果我使用多个浏览器来测试类似模板的浏览器)。有自动化这个常见的成语吗?我以前有一个JavaScript位,不断地重新加载页面,但它的实用性有限,显然,当我必须与页面交互超过几秒钟。
- 我的JVM实例变得脏,当我实验和写测试功能。基本上命名空间被污染,特别是如果我重构和移动函数之间的命名空间。这可能导致符号冲突,我需要重新启动Swank。我可以取消一个符号吗?
- 在重新启动Swank时,我逐个加载所有源文件(
C-c C-k
)。 - 在REPL和文件编辑器之间切换可能有点令人不安,特别是当我打开了很多Emacs标签时,浏览器旁边
-
使用
ns-unmap
函数命名空间中的Var。为了更方便,可以在其上面构建undef
宏。像这样:(defmacro undef [& syms]
`(do〜@ ]`(ns-unmap * ns *'〜s))syms)))
ns-unalias
也可能感兴趣。 -
没有理由通过文件do Cc Ck ;你可以只需
require
你需要在REPL的命名空间。
此外,如果你键入几个字符SLIME REPL然后使用 Mp / Mn 浏览历史记录,将只显示与手动输入的文本的初始位匹配的条目。这与Paredit兼容(尾随的括号不会是一个问题)。所以,如果你在开始建立一个巨大的require -
(require'[foo:as f]'[bar:as b]'[clojure.contrib.sql:as sql] ... )
- 然后重新启动Swank后,所有你需要做的就是输入类似(require'[f
并按 Mp 再次将该表单提交到REPL提示符。
诚然,这可以通过多种方式自动化(例如,使用Swank REPL搜索配置文件,或者一个简单的宏扩展到一个适当的
require
形式,可以在从项目中引入一个实用程序命名空间后使用 - 特别是后一个想法将很容易实现) -
您可以使用 Cc Cz 在SLIME启用的缓冲区中创建一个带有SLIME REPL的窗口。此外,您应该尝试使用
ido
(如果您还没有)。我倾向于使用一个代码缓冲区打开在窗口左侧的屏幕和右侧的REPL缓冲区;与windmove-left
和windmove-right
绑定一些方便的键,我往往很高兴。 -
顺便说一下,我不使用
lein swank
通常情况下,我更喜欢我的自定义clojure-project
函数(Phil Hagelberg的原始版本)。有时,我觉得需要改进它...也许我会处理每个项目import
/require
下一次发生的自动化。 ; - ) - Start Swank with
lein swank
. - Go to Emacs, connect with
M-x slime-connect
. - Load all existing source files one by one. This also starts a Jetty server and an application.
- Write some code in REPL.
- When satisfied with experiments, write a full version of a construct I had in mind. Eval (
C-c C-c
) it. - Switch REPL to namespace where this construct resides and test it.
- Switch to browser and reload browser tab with the affected page.
- Tweak the code, eval it, check in the browser.
- Repeat any of the above.
- I have to switch between Emacs and the browser (or browsers if I am testing things like templating with multiple browsers) all the time. Is there a common idiom to automate this? I used to have a JavaScript bit that reloads the page continuously, but it's of limited utility, obviously, when I have to interact with the page for more than a few seconds.
- My JVM instance becomes "dirty" when I experiment and write test functions. Basically namespaces become polluted, especially if I'm refactoring and moving the functions between namespaces. This can lead to symbol collisions and I need to restart Swank. Can I undef a symbol?
- I load all source files one by one (
C-c C-k
) upon restarting Swank. I suspect I'm doing it all wrong. - Switching between the REPL and the file editor can be a bit irritating, especially when I have a lot of Emacs tabs open, alongside the browser(s).
It is possible to remove a Var from a namespace with the
ns-unmap
function. For added convenience, anundef
macro can be built on top of it e.g. like so:(defmacro undef [& syms] `(do ~@(map (fn [s] `(ns-unmap *ns* '~s)) syms)))
ns-unalias
may also be of interest.There's no reason to go through the files holding the namespaces just to do C-c C-k in each of them; you can just
require
the namespaces you need at the REPL.Moreover, if you type a few characters at the SLIME REPL and then use M-p / M-n to browse history, only the entries matching the initial bit of text you entered by hand will be displayed. This is compatible with Paredit (the trailing closing bracket(s) will not be a problem). So, if you build up a huge require at the start --
(require '[foo :as f] '[bar :as b] '[clojure.contrib.sql :as sql] ...)
-- then after restarting Swank, all you need to do is to type something like(require '[f
and press M-p to bring that form to the REPL prompt again.Admittedly, this could be automated in a number of ways (e.g. having the Swank REPL search for a configuration file, or perhaps a simple macro expanding into an appropriate
require
form which could be used after bringing in just one utility namespace from the project -- especially the latter idea would be easy to implement), but I find it sufficiently low on the annoyance factor that I haven't so far bothered with any improvements.You can use C-c C-z to make a window with the SLIME REPL pop up while you are in a SLIME-enabled buffer. Also, you should try using
ido
if you haven't already. I tend to work with a code buffer open in a window on the left hand side of the screen and a REPL buffer on the right; withwindmove-left
andwindmove-right
bound to some convenient keys, I tend to be pretty happy. If I need to look at additional buffers often, I use extra Emacs frames.Incidentally, I don't use
lein swank
normally, I prefer my customclojure-project
function (a tweaked version of Phil Hagelberg's original). On occasion, I feel a desire to improve it... perhaps I'll deal with per-projectimport
/require
automation next time that happens. ;-)
我正在寻找方法来改善上述点和整个工作流程,所以我很感激如果你会分享你的。
P。 S。
我之前也使用过Vimclojure,所以基于Vimclojure的工作流程也是受欢迎的。
不是完整的工作流程说明,只是几个想法:
I am developing a pet project with Clojure, but wonder if I can speed up my workflow a bit.
My current workflow (with Compojure) is:
There are a number of annoyances with it:
I'm looking for ways to improve the above points and the entire workflow in general, so I'd appreciate if you'd share yours.
P. S.
I have also used Vimclojure before, so Vimclojure-based workflows are welcome too.
Not a complete workflow description, just a few ideas:
这篇关于高效Clojure工作流程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!