It includes some functionality for interacting with subprocesses. This
is a small subset of the functionality of the functionality included in
SLIME, but it's simpler and easier to configure.
However, now that clojure-mode has the M-x clojure-install command that
sets up SLIME etc, I don't know if the built-in subprocess features are
worth keeping around any more. Personally I have never used them or
heard of anyone using them; I wonder if they are just legacy baggage.
Would anyone be opposed to their removal?
thanks,
Phil
> I'm working on cleaning up the code for clojure-mode.el, which provides
> Clojure support for Emacs.
Further things I am considering removing:
* support for Emacs 21 (which was released around 2001)
* the ability to turn off highlighting multi-line def forms
* the clojure-update command (simply runs a few git commands and recompiles)
If any of these features is dear to your heart, please let me know and
it may be spared. I'd like to streamline the code to ease maintenance,
and I will include a pointer in the comments to the last version that
supported Emacs 21.
-Phil
> However, now that clojure-mode has the M-x clojure-install command
> that
> sets up SLIME etc, I don't know if the built-in subprocess features
> are
> worth keeping around any more. Personally I have never used them or
> heard of anyone using them; I wonder if they are just legacy baggage.
>
> Would anyone be opposed to their removal?
What would the consequences be? Do I understand correctly that clojure-
mode would no longer support Lisp interaction, and that installing
SLIME would be required for every Emacs user?
Until now I have never even looked at SLIME, considering the number of
difficulties I see reported by lots of people. Life is too short to
waste on configuration problems... and in that category I am still
busy dealing with Clojure's move to github. I still use clojure-mode
with its basic interaction commands for all my Clojure hacking.
On the other hand, if SLIME installation is painless now, that would
be fine with me as well.
Konrad.
> On 8 Sep 2009, at 02:36, Phil Hagelberg wrote:
>> However, now that clojure-mode has the M-x clojure-install command
>> that sets up SLIME etc, I don't know if the built-in subprocess
>> features are worth keeping around any more. Personally I have never
>> used them or heard of anyone using them; I wonder if they are just
>> legacy baggage.
>>
>> Would anyone be opposed to their removal?
>
> Until now I have never even looked at SLIME, considering the number of
> difficulties I see reported by lots of people. Life is too short to
> waste on configuration problems... and in that category I am still
> busy dealing with Clojure's move to github. I still use clojure-mode
> with its basic interaction commands for all my Clojure hacking.
Most of these are caused by people manually installing SLIME rather than
using M-x clojure-install. I would rather focus on having one method of
subprocess interaction so we can make that work as smoothly as possible
than keep this vestigal functionality in here that only a handful of
people use.
> On the other hand, if SLIME installation is painless now, that would
> be fine with me as well.
Please give it a try and let me know if you have any problems. M-x
clojure-install should pull in everything you need, including its own
copy of Clojure 1.0.
> Clojure-update is a sensible complement to clojure-install, I'd
> strongly vote for keeping it.
I think the value-add here is pretty minimal. Before Clojure 1.0 if a
change in Clojure broke swank-clojure, we'd have to scramble to get it
fixed in swank-clojure, and everyone would update. But now that there's
a stable target, I haven't been tracking master closely, so staying
up-to-date is much less important.
Plus it's just a wrapper around a handful of shell commands. If more
people use it I may keep it around, otherwise I'd suggest switching over
to a shell script.
-Phil
> Also, one thing that I (and others) have noticed is that clojure mode
> chokes on the #^{} form metadata on namespaces. (See any of the files
> in clojure-contrib for an example.) I'm not able to reproduce the
> problem now, so if you don't already know what it is, I'll keep my eye
> out for it and send you a proper report when I have it happening.
Yeah, I've seen this. I don't use this style myself, but I want to
support it. I've opened a ticket for this, though it's for swank-clojure
rather than clojure-mode itself:
http://github.com/technomancy/swank-clojure/issues/#issue/1
Speaking of which, I've heard rumors that a nicer docstring syntax for
namespaces is planned. Has there been any work on this? I think it's a
great idea and may implement it myself if nobody else has.
-Phil
> One problem I do have with clojure-mode/clojure is managing the
> classpaths for clojure projects... It seems that the typical elisp
> config only has one variable (which is then shared across all clojure
> files) for specifying the classpath...
>
> Personally I'd like to maintain the required classpath with the
> project and outside of my .emacs files and was wondering if anyone had
> any elisp setups to work around this.... I was thinking maybe having
> clojure-mode search every directory up from the file your editing for
> a .classpath file to pass to a clj bash script for evaluation... How
> does everyone else do this?
The solution I've settled on is the clojure-project function:
(defun clojure-project (path)
"Setup 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 "src"))))
(require 'swank-clojure)
(when (get-buffer "*inferior-lisp*")
(kill-buffer "*inferior-lisp*"))
(add-to-list 'swank-clojure-extra-vm-args
(format "-Dclojure.compile.path=%s"
(expand-file-name "target/classes/" path)))
(setq swank-clojure-binary nil
swank-clojure-jar-path (expand-file-name "target/dependency/" path)
swank-clojure-extra-classpaths
(append (mapcar (lambda (d) (expand-file-name d path))
'("src/" "target/classes/" "test/"))
(let ((lib (expand-file-name "lib" path)))
(if (file-exists-p lib)
(directory-files lib t ".jar$"))))
slime-lisp-implementations
(cons `(clojure ,(swank-clojure-cmd) :init swank-clojure-init)
(remove-if #'(lambda (x) (eq (car x) 'clojure))
slime-lisp-implementations)))
(save-window-excursion
(slime)))
This just resets the classpath to include target/dependency/ as well as
any jars in the lib/ directory of your project. I've included this in
the Emacs Starter Kit but haven't included it in clojure-mode yet since
I haven't quite decided if it's suitable for everyone. But it seems
there's a demand for it; so I guess I'll include it.
Another option is to use directory-local variables using a
.dir-locals.el file in your project root, but that can only set values
for variables, it can't do things like add a value to an existing list,
so its utility is limited.
-Phil
>> On the other hand, if SLIME installation is painless now, that would
>> be fine with me as well.
>
> Please give it a try and let me know if you have any problems. M-x
> clojure-install should pull in everything you need, including its own
> copy of Clojure 1.0.
I work with the development branch regularly updated from github. Do I
conclude correctly that clojure-install is of no use for me?
> I think the value-add here is pretty minimal. Before Clojure 1.0 if a
> change in Clojure broke swank-clojure, we'd have to scramble to get it
> fixed in swank-clojure, and everyone would update. But now that
> there's
> a stable target, I haven't been tracking master closely, so staying
> up-to-date is much less important.
How stable is swank-clojure in practice with the changes that happened
since 1.0?
Konrad.
It really does seem like there's a certain demand for it, I stumbled
upon several blog posts and such where people have trouble setting up
their Clojure projects. I definitely think that this would be a
worthwhile addition to clojure-mode.
Regards,
Michael
Yes, that looks like just what I'm after (I haven't yet tried it out -
but will be sure to!)...
This issue has got me thinking that the real problem appears to be
that there isn't a standard or default way (script) to start up and
run java/clojure projects... i.e. though this solves the problem when
running clojure programs in emacs it doesn't do so for when you move
into a different environment (perhaps staging or production) and want
to run a REPL configured for your project or clojure program.
I think there will always be a need for people to craft the JVM args
for specific projects themselves, but it'd be nice if clojure could
provide a default mechanism for specifying the basic JVM args etc in
a way that meant it worked across environments, editors and
environments... Is such a thing possible or even desirable...
Personally I think finding a nice lightweight, default solution to
this problem that can be supported by all environments/editors/IDE's
would make clojure even more suited to rapid prototyping, experimental
development and bootstrapping projects in a painless manner.
Any thoughts?
R.
Glad I'm not the only one :-)
>> Personally I think finding a nice lightweight, default solution to
>> this problem that can be supported by all environments/editors/IDE's
>> would make clojure even more suited to rapid prototyping, experimental
>> development and bootstrapping projects in a painless manner.
>
> I know there's one included in contrib now, but it's not quite the
> same. I suppose in order to be portable there'd need to be a batch
> file
> for windows too; it's a shame there's no good cross-platform way to
> handle
> that.
>
> -Phil
As I'm sure you and many others know, this problem exists in the Java
community also... A few years ago I found a solution in Apache
Commons Launcher:
http://commons.apache.org/launcher/
It uses a lot of the infrastructure from ant and is pretty powerful,
providing a cross platform way of specifying jvm args, classpaths,
library paths etc... Sadly the project is largely moribund but other
than being poorly documented it worked pretty well... I could imagine
a pure clojure implementation of this (perhaps based on lancet?) that
would use a clojure DSL instead of ant xml to configure the VM in a
cross platform manner.
The only problem I ran into with commons launcher was to do with
System.in being passed through the VMs... It worked but its
implementation was inefficient and resulted in excessive CPU
consumption unless you switched it off... This was an easy work
around for me, as I didn't need to read from System.in, but I can
imagine it being a problem if you're running a REPL. I suspect
however that it was just a bug, rather than a larger design flaw.
R.
I've tried getting this to work but it keeps it failing after I call
the function and interactively tell it my project direcotory it seems
to repeatedly poll with the following message:
Polling "/var/folders/mY/mY1Jdd-YEAW-N77HgxpP6k+++TI/-Tmp-/slime.53923"..
(Abort with `M-x slime-abort-connection'.) [15 times]
Any ideas?
R.
> Also, one thing that I (and others) have noticed is that clojure mode
> chokes on the #^{} form metadata on namespaces. (See any of the files
> in clojure-contrib for an example.) I'm not able to reproduce the
> problem now, so if you don't already know what it is, I'll keep my eye
> out for it and send you a proper report when I have it happening.
So I just found out that you can add regular docstrings to namespaces as
per http://code.google.com/p/clojure/issues/detail?id=30, which was
actually news to me (I thought it was targeted for 1.1). Anyway, given
that you can do docstrings with nicer syntax now and git supports far
more detailed authorship data, is there any reason to still use the #^{}
syntax for namespaces? I must confess I've never liked the way it looks.
-Phil
> I do something similar to Brenton. I use clojure-mode, and vote for
> keeping it as-is, making SLIME integration optional or ancillary.
Could you guys give SLIME another shot via M-x clojure-install? If you
haven't been using it because you had a hard time installing SLIME/swank
months ago, things have changed pretty markedly since then. I'd say that
using SLIME now requires no more effort than using the built-in inf-lisp
functionality; possibly less.
If you try it and don't like it, that's fine; please let me know. I just
want to see if this can meet peoples' needs.
-Phil
Neat!! I like the simplicity of it too, however it's Unix only which
means that unlike commons launcher it wont work on Windows. Sadly I
can see this being a problem for some of my projects :-(
Still definitely looks like it's worth checking out!
R.
Sounds nice... Any chance of putting this script up somewhere?
Having something that works consistently across Emacs/Slime and the
command line without needless duplication is something I've been
looking for.
Thanks again,
R.
> I'm not so excited about deriving authorship data from git, though. It
> seems like there are a lot of reasons that could be "wrong" from the
> point of view of what we want for the documentation (how do you decide
> when a checkin represents a true "co--author?", etc.). Having the
> string there allows folks to use it with a little more nuance ("By
> Stuart Sierra with some critical bug fixes by Phil Hagelberg").
Well, everyone who's contributed to the library is an author in a
sense. Whoever's written the most lines of non-whitespace,
non-documentation code is the primary author. Why rely on
manually-curated data when you have a canonical source?
Anyway, I'm just not a fan of strong code ownership as I see that
sometimes it creates a "don't touch" mindset. But maybe that's just me.
> But even if it did #^{} is legitimate syntax and emacs probably
> shouldn't barf on it.
That's true. I'll let someone who uses it write the patch though. =)
-Phil
> The solution I've settled on is the clojure-project function:
Here's what I've added to the swank-clojure codebase. It supports the
somewhat standard src/ and classes/ project layout style as well as one
based on Maven conventions.
(defun swank-clojure-project (path)
"Setup classpath for a clojure project and starts a new SLIME session.
Kills existing SLIME session, if any."
(interactive (list
(ido-read-directory-name
"Project root: "
(if (functionp 'locate-dominating-file) ; Emacs 23 only
(locate-dominating-file default-directory "src")
default-directory))))
;; TODO: allow multiple SLIME sessions per Emacs instance
(when (get-buffer "*inferior-lisp*") (kill-buffer "*inferior-lisp*"))
(setq swank-clojure-binary nil
swank-clojure-classpath (let ((l (expand-file-name "lib" path)))
(if (file-exists-p l)
(directory-files l t ".jar$"))))
(add-to-list 'swank-clojure-classpath (expand-file-name "src/" path))
;; For Maven style project layouts
(when (or (file-exists-p (expand-file-name "pom.xml" path))
(file-exists-p (expand-file-name "project.clj" path)))
(dolist (d '("src/main/clojure/" "src/test/"
"target/classes/" "target/dependency/"))
(add-to-list 'swank-clojure-classpath (expand-file-name d path)))
(add-to-list 'swank-clojure-extra-vm-args
(format "-Dclojure.compile.path=%s"
(expand-file-name "target/classes/" path))))
(run-hooks 'swank-clojure-project-hook)
(setq slime-lisp-implementations
(cons `(clojure ,(swank-clojure-cmd) :init swank-clojure-init)
(remove-if #'(lambda (x) (eq (car x) 'clojure))
slime-lisp-implementations)))
(save-window-excursion
(slime)))
> Another option is to use directory-local variables using a
> .dir-locals.el file in your project root, but that can only set values
> for variables, it can't do things like add a value to an existing list,
> so its utility is limited.
This version has a hook, so you can customize your one-off project
settings using that.
Thoughts?
-Phil
I have not read all of this thread and am not sure completely what is
what with regards to the details of authorship of either method.
But, I do believe it is of great importance to maintain good
contributors records to the files and its modification history
regardless of code "ownership" but for good legal provenance.
It makes things cleaner and easier for licensing purposes and anything
concerning bureaucrats and lawyers.
Having watched another open source project go through diligent efforts
to trace down any and all potential contributors to do a relicensing
effort was a major pain and an incredible amount of work.
As I said, I don't know all the details in this situation and either
position might very well cover this issue just fine. Just wanted to
bring up a scenario for which good record keeping benefits the project
and community.
Jimmie
> But, I do believe it is of great importance to maintain good
> contributors records to the files and its modification history
> regardless of code "ownership" but for good legal provenance.
Two things: git maintains this record automatically and much more
thoroughly than a manually curated way could, and all contributors have
to sign a contributor agreement anyway that assigns copyright to
Rich.
So this issue is already taken care of.
-Phil
> A few comments and questions about the setup process:
>
> At the end of the process, the mini-buffer says, "You must specify
> either a `swank-clojure-binary' or a `swank-clojure-classpath'. What
> should those values be? I see the swank-clojure directory that has
> been installed, but I'm not sure what the binary is.
I forgot to commit my changes to clojure-mode; try pulling in the
latest revision from git://github.com/technomancy/clojure-mode.git
> I like using autoload to load modes, but in order to call
> clojure-slime-config I need to load clojure-mode.el explicitly,
> correct? I don't want to put the call to clojure-slime-config in my
> clojure-mode-hook because that gets called every time I open a clojure
> buffer, correct?
If you install via ELPA, the autoloads will be set up for you
automatically. There's a bit of trickery that allows clojure-mode to be
autoloaded like normal but still lets you use the clojure-slime-config
function at startup without triggering a full load. So this should not
be a problem unless you are manually handling your autoloads for some
reason. Using the built-in update-directory-autoloads function will also
work.
I've updated the install instructions; they no longer show how to
manually add autoloads.
> I noticed that clojure-install installed the 1.0 release, but I like
> running against the master branch. Crazy, I know.
Sure, just run M-x clojure-update.
-Phil
Done. After doing that and cleaning out some old SBCL cruft in my init
file, it seems to be working. Here's what I have in my init file:
(require 'clojure-mode)
(clojure-slime-config "~/src/clojure")
>> I like using autoload to load modes, but in order to call
>> clojure-slime-config I need to load clojure-mode.el explicitly,
>> correct? I don't want to put the call to clojure-slime-config in my
>> clojure-mode-hook because that gets called every time I open a clojure
>> buffer, correct?
>
> If you install via ELPA, the autoloads will be set up for you
> automatically. There's a bit of trickery that allows clojure-mode to be
> autoloaded like normal but still lets you use the clojure-slime-config
> function at startup without triggering a full load. So this should not
> be a problem unless you are manually handling your autoloads for some
> reason. Using the built-in update-directory-autoloads function will also
> work.
I don't use ELPA; I'm too old-school (26 years of Emacs and counting)
for such fancy hand-holding :-) I experimented with autoload, but
couldn't get it working (clojure-mode loaded, but it didn't find the
"slime" command when I tried M-x slime. In any case, require works.
It's unfortunate that I have to load it every time I start Emacs, but
that's not too often in any case.
> I've updated the install instructions; they no longer show how to
> manually add autoloads.
>
>> I noticed that clojure-install installed the 1.0 release, but I like
>> running against the master branch. Crazy, I know.
>
> Sure, just run M-x clojure-update.
Excellent. Thanks, and thank you for your help and clojure-mode.
> -Phil
Jim