Re: vimclojure bug

31 views
Skip to first unread message

Meikel Brandmeyer

unread,
Sep 5, 2009, 2:25:55 AM9/5/09
to Mark Swanson, vimcl...@googlegroups.com
Hi Mark,

Am 05.09.2009 um 05:59 schrieb Mark Swanson:

> I really enjoy using vimclojure. I'm having some trouble with one
> thing:
> vimclojure doesn't seem to be able to be able to grok working with
> filenames that contain a directory component in front of the file
> name.
>
> F.E.
> $ vi test/hello.clj
>
> ERROR -> Couldn't execute Nail! java.io.FileNotFoundException: Could
> not
> locate hello__in
> it.class or hello.clj on classpath:
>
> Note that vimclojure is looking in the wrong place: it should be
> looking
> in text/hello.clj

No. This message stems from the Clojure side of VimClojure. It is
important to understand how VimClojure works to understand this error:

The Vim side is not interested in filenames, namespaces and such. It
just does highlighting, editing, indenting, ...

The Clojure side does the actual work. At the moment this works as
follows:
- VC reads the file (The content is actually copied into a temporary
file, so the filename is not of interest) and tries to find out the
namespace of the file. This namespace is reported and stored in the
Vim buffer. You can check that with doing a ":echo
b:vimclojure_namespace" in a Vim buffer with a clojure file. It should
tell you the namespace.
- Then VC "require"s the namespace. This is necessary because we use
Clojure introspection facilities. (And this is step that actually
fails in your case!) Again, the filename in Vim is not of interest
since this goes all through the Clojure require machinery and the
classpath.
- VC extracts highlighting information from the "use"d and "require"d
namespaces.
- VC extracts completion data, eg. from all-ns, ns-publics, etc....

The advantages of this approach are:
- It works now! (I want to get this done. Otherwise I must implement a
parser, understand the logic, break things if I miss an update to the
Clojure machinery, ....)
- 100% agreement with what happens really, since Clojure is used
directly.
- Relatively easy to set up remote connections.

The disadvantages are:
- A little bit annoying setup, but trivial in the end. (Just put
everything in src and add src to your classpath...)
- Don't execute things on the toplevel of your file. (Eg. starting a
server or so)
- Don't have syntax errors in your file. Or it will blow up because it
is loaded.

For me the advantages greatly outweigh the disadvantages. Don't write
"scripts". Put everything in an entry point and call that from/use
that as a main of a class. This makes the functionality of your
program also available as a library. Don't have syntax errors. Leaving
a file in a half-edited state isn't a good idea anyway.

Ok. Back to your original question: my suspicion is, that you declared
a namespace via "(ns hello)" in your file. That means Clojure looks in
hello.clj (or the hello__init.class) on the classpath. If now src is
on the classpath and you put the file in src/test/hello.clj, this
won't work, since it violates clojures naming conventions for the
source files. If you put the file into src/hello.clj it will work,
because now evertything is in the right place. Similar renaming the
namespace into test.hello should also fix the issue.

Hope this helps.

Sincerely
Meikel

MarkSwanson

unread,
Sep 5, 2009, 1:19:06 PM9/5/09
to vimclojure
<snip>
> For me the advantages greatly outweigh the disadvantages. Don't write  
> "scripts". Put everything in an entry point and call that from/use  
> that as a main of a class. This makes the functionality of your  
> program also available as a library. Don't have syntax errors. Leaving  
> a file in a half-edited state isn't a good idea anyway.

Thanks for explaining all of this.
Also, thanks for the hint on how to structure a clojure project.

> Ok. Back to your original question: my suspicion is, that you declared  
> a namespace via "(ns hello)" in your file. That means Clojure looks in  
> hello.clj (or the hello__init.class) on the classpath. If now src is  
> on the classpath and you put the file in src/test/hello.clj, this  
> won't work, since it violates clojures naming conventions for the  
> source files. If you put the file into src/hello.clj it will work,  
> because now evertything is in the right place. Similar renaming the  
> namespace into test.hello should also fix the issue.

Got it. You're correct about (ns hello). I'm really thankful that you
took the time to help this Clojure newb.

Cheers.

Meikel Brandmeyer

unread,
Sep 26, 2009, 1:25:27 PM9/26/09
to vimcl...@googlegroups.com
Hi,

Am 05.09.2009 um 19:19 schrieb MarkSwanson:

> Also, thanks for the hint on how to structure a clojure project.

Of course: YMMV. But anything dynamic really needs loading the
namespace. Consider the following scenario: You start editing a file.
You modify some function. You send the function to the Clojure side.
What should happen now? We actually need to load the namespace the
first time code is sent. Otherwise the namespace and (eventually
required) Vars are not in place for the function. We could also fail,
but that doesn't really help.

So if you want to "hot" load functions, the namespace should load
without side-effects (besides defining Vars).

> Got it. You're correct about (ns hello). I'm really thankful that you
> took the time to help this Clojure newb.

No problem. :) I think one has to understand the inner workings and
connections of the Classpath and the Clojure namespaces to correctly
use it. Also one has to understand the limitations of the system.
Otherwise one is fighting it instead of using it. Consider the mass of
add-classpath threads in the Clojure group. People just don't want to
understand, that the JVM was not designed that way. Instead of
accepting this, they try to find hacks around this limitation - each
and every causes more trouble than it helps...

So just giving in, is most of the times the easiest way to avoid
trouble. One can still do it differently and disable the dynamic part
of VC. One still does get a lot: syntax highlighting, indenting, <C-n>
completion.... It is just a trade-off.

Sincerely
Meikel

Joe Holloway

unread,
Oct 21, 2009, 12:08:33 PM10/21/09
to vimclojure
On Sep 5, 1:25 am, Meikel Brandmeyer <m...@kotka.de> wrote:
> The disadvantages are:
>
> <snip>
>
> - Don't have syntax errors in your file. Or it will blow up because it  
> is loaded.
>
> For me the advantages greatly outweigh the disadvantages. Don't write  
> "scripts". Put everything in an entry point and call that from/use  
> that as a main of a class. This makes the functionality of your  
> program also available as a library. Don't have syntax errors. Leaving  
> a file in a half-edited state isn't a good idea anyway.

Hi,

I actually logged a ticket on bitbucket [1] about this very thing
yesterday before I realized that this group existed and that you had
already explained this behavior here. In general, I agree with your
assertion that leaving files in a half-edited state is not a good
idea. My problem is that when I'm learning a new language on the side
or prototyping some code that I may end up scrapping, I tend to do all
sorts of silly, anti-idiomatic, noobtastic things. I may come back to
something that I was working on a couple weeks prior and not remember
what state it's in.

That said, I would never expect a plugin to fully workaround those
kinds of personal shortcomings especially in the face of such
technical obstacles as you've described. However, what I am
wondering: is there a way the plugin could be a bit more helpful when
the programmer has done something silly like walk away from a file
that contains a syntax error?

The way it works right now, the key bindings are skipped over when the
b:vimclojure_namespace is undefined. Could it instead map them all to
a function that emits the status of the plugin to the Vim status line
(:messages)? For example, "VimClojure not fully loaded, namespace of
file could not be determined, check syntax".

I am just trying to think of a way that this sort of error can be
distinguished from NailGun classpath issues or other installation
issues so the programmer doesn't get lost troubleshooting down the
wrong path.

Maybe I'm the only one that has done this more than once, but I
suspect that's not the case?

Thanks,
Joe

[1] http://bitbucket.org/kotarak/vimclojure/issue/7/syntax-errors-in-clojure-source-result-in-initbuffer-exception-that-suppress-plugin

Meikel Brandmeyer

unread,
Oct 21, 2009, 3:07:12 PM10/21/09
to vimcl...@googlegroups.com
Hi,

Am 21.10.2009 um 18:08 schrieb Joe Holloway:

> However, what I am wondering: is there a way the plugin could be a
> bit more helpful when the programmer has done something silly like
> walk away from a file that contains a syntax error?

Yes. This should be the case. At the moment I just ignore whatever
happens on initialisation. The ng command fails...Ok. Just go one
without. The behaviour should be more differentiated. Then also some
warning messages is possible.

> I am just trying to think of a way that this sort of error can be
> distinguished from NailGun classpath issues or other installation
> issues so the programmer doesn't get lost troubleshooting down the
> wrong path.

It can also be made easy to reset.

1. :e file (with syntax error)
2. *BOOM*, but contained, error message "interactive features disabled"
3. fixfixfix
4. :w
5. :e %
6. VC works as normal

> Maybe I'm the only one that has done this more than once, but I
> suspect that's not the case?

A tip: When experimenting just don't put a namespace in the file. This
will make the file "belong" to user. That means: it is not loaded.
Experiment with as many half-coded and not finished functions. \et and
friends will work as usual. When you are finished and everything is
cleaned up, simply but a ns at the top and you are done.

However pay attention, that at least the toplevel expressions are
always correctly balanced. Otherwise \et will not work correctly.

Sincerely
Meikel

eyeris

unread,
Oct 21, 2009, 6:07:59 PM10/21/09
to vimclojure
On Oct 21, 2:07 pm, Meikel Brandmeyer <m...@kotka.de> wrote:
> Hi,
>
> Am 21.10.2009 um 18:08 schrieb Joe Holloway:
>
> > However, what I am wondering: is there a way the plugin could be a
> > bit more helpful when the programmer has done something silly like
> > walk away from a file that contains a syntax error?
>
> Yes. This should be the case. At the moment I just ignore whatever  
> happens on initialisation. The ng command fails...Ok. Just go one  
> without. The behaviour should be more differentiated. Then also some  
> warning messages is possible.

I just submitted a patch that introduces the warning you mention:

http://bitbucket.org/kotarak/vimclojure/issue/10/warn-the-user-if-the-nailgun-client-is-not

Joe Holloway

unread,
Oct 23, 2009, 5:53:52 PM10/23/09
to vimclojure
> http://bitbucket.org/kotarak/vimclojure/issue/10/warn-the-user-if-the...

I'm not sure if you were addressing the issue I confirmed above, but I
applied your patch and it has no effect on that.

The test case is pretty simple. Create a file that contains a syntax
error such as:

((+ 1 1)

Save it, close the buffer, then open the file in a new buffer. The
VimClojure key bindings won't be mapped and no errors are given.

I'll see if I can expand on your patch to cover this scenario too.

Drew Vogel

unread,
Oct 24, 2009, 1:32:50 AM10/24/09
to vimcl...@googlegroups.com
What is displayed by :messages?

Meikel Brandmeyer

unread,
Oct 24, 2009, 3:07:25 AM10/24/09
to vimcl...@googlegroups.com
Hi,

Am 23.10.2009 um 23:53 schrieb Joe Holloway:

> The test case is pretty simple. Create a file that contains a syntax
> error such as:
>
> ((+ 1 1)
>
> Save it, close the buffer, then open the file in a new buffer. The

Please slow down a little. I appreciate your efforts to also provide
patches to the problems! :D

But we have to understand what happens here first. This is actually a
not so simple test case. Consider the following file

(foo)
((+ 1 1)

Here everything should actually work as intended.

The reasons why there are no keymappings done are one of the following:

- The ng server isn't running. (This should be checkable I hope. Maybe
by return value of the client.)
- The ng client is not where it is supposed to or the variable is not
correctly configured. (Should be checkable)
- The client is not executable. (Maybe Unix only? Can be included in
previous case?)
- Something is wrong with the Classpath. (Can only be checked for
clojure, contrib and VC itself. Other things might be possible with
user interaction.)
- The file has syntax failures.

The first bullets are quiet different from the last one. They are
pretty straight forward, I think.

The last one is special, because here we already read the file. So it
can influence what's happening. So now we have to understand what
happens when you open the file.

- VC reads the first expression and check if it is a ns or in-ns form.
- If so, it returns the namespace found. Otherwise user.
- If something else than user is returned, it 'require's the namespace
(and hence all 'require'd or 'use'd namespace and used classes).
- If user is returned, nothing else happens.

So in your example the keymappings are not done, because the namespace
check fails. VCs heuristic is a the moment, that this means either
something is wrong with the client or the servers is not running. If
you add (foo) everything should be fine, because foo is neither ns nor
in-ns and so user is returned. Since user is a no-op for the require
step, everything should be fine.

Now if we have:

(ns foo)
((+ 1 1)

Then I'm not sure what everything happens. What exactly depends on the
inner workings of Vim, I'm not sure I always understand. The syntax
highlighting is tries to extract information about macros, functions,
variables etc... If this fails, because of the syntax error the
mappings might not be in place. The highlighting is messed and and...

Fixing the error(s) and doing a simple ':e' should be enough to get
things straight again.

I'm sorry that I haven't more time at the moment, but it is also good
to see, that other people care enough for VC to contribute patches. :)

Sincerely
Meikel

Reply all
Reply to author
Forward
0 new messages