abo-abo / lispy

Short and sweet LISP editing
http://oremacs.com/lispy/
1.21k stars 132 forks source link

Company completion breaks when using cider with Clojure 1.9.0 #418

Open Grobwiefein opened 6 years ago

Grobwiefein commented 6 years ago

If lispy-mode is enabled in a Clojure 1.9.0 project (Cider/Leiningen), Company completion doesn’t work in the source coder buffer as well as in the REPL. The following error is shown:

Company: backend company-capf error "Symbol’s function definition is void: CompilerException" with args (candidates )

After a little bit of debugging, it turns out that if lispy-clojure-complete-at-point is in completion-at-point-functions, the error occurs. When removing it, completion works as expected. Also, in Clojure 1.8 projects completion works fine.

Update: After further debugging it turns out the CompilerException appears when evaluating https://github.com/abo-abo/lispy/blob/6dc413baadb0e1ae55e05de061199de22237868c/le-clojure.el#L482-L485 The evaluation results in

#("CompilerException java.lang.RuntimeException: No such namespace: lispy-clojure, compiling:(*cider-repl clj-forceps-cbr*:1:5) \n" 0 126 (help-echo cider--help-echo cider-locals nil))
abo-abo commented 6 years ago

Thanks for the report, I'll have to investigate more to find the root cause.

For now, lispy-clojure-complete-at-point will not throw any errors. So for 1.9.0 it will simply return nothing. Please check that it works.

WebsterWing commented 6 years ago

Was having the same issue until I upgraded recently. Should be verified with Clojure 1.9.0 but I think that this one can be closed.

Edit: The completion backend is still broken, it just doesn't break company for me any more. Can someone explain why lispy even creates a backend?

abo-abo commented 6 years ago

why lispy even creates a backend

Extended completion for Java interop.

abo-abo commented 6 years ago

@Grobwiefein @WebsterWing Could you please try to load lispy-clojure.clj using your Clojure 1.9 setup? And report the error message here.

Grobwiefein commented 6 years ago

Executing the following code in a Cider REPL with Clojure 1.9 runs without errors:

(load-file "/home/user/.emacs.d/elpa/lispy-20180516.826/lispy-clojure.clj")

After loading the file, completion works as expected.

abo-abo commented 6 years ago

@Grobwiefein You mean cider-load-file? We already use that.

Can you restart the REPL and eval this:

(cider-load-file (expand-file-name "lispy-clojure.clj" lispy-site-directory))
WebsterWing commented 6 years ago

When I ran the file, the following text appeared in my repl

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Andre0991 commented 6 years ago

Both load-file (in the Clojure repl as suggested by Grobwiefein) and cider-load-file make the completion work in my setup.

Andre0991 commented 6 years ago

Actually, I get the same error that @WebsterWing reported when I use cider-jack-in in a Clojure file that is not associated with any project - and completion does work after that.

Edit: Strangely, I'm not getting the error anymore. Probably due to some package upgrade. But still, it seems that lispy-clojure.clj is not loaded properly. F results in an error, for example.

Grobwiefein commented 6 years ago

@abo-abo No, I used the ordinary load-file function. I evaluated your snipped after doing a cider-jack-in and get the same result: completion works as expected.

drorbemet commented 6 years ago

In my case this error hasn't gone yet. As a first step after many hours of searching and trying different versions of the clojure-packages involved I collected all versions which could be relevant to debug this.

Symptom CompilerException with completion called using company or with

(special-lispy-follow) on a region on a clojure symbol

Versions

(emacs-version)
"GNU Emacs 25.3.1 (x86_64-redhat-linux-gnu, GTK+ Version 3.22.19)
 of 2017-09-15"
(shell-command-to-string "java -version")
"openjdk version \"1.8.0_171\"
OpenJDK Runtime Environment (build 1.8.0_171-b10)
OpenJDK 64-Bit Server VM (build 25.171-b10, mixed mode)
"
(shell-command-to-string "javac -version")
"javac 1.8.0_171
"
(shell-command-to-string "lein --version")
"Warning: refactor-nrepl needs to run in the context of a project.
Warning: refactor-nrepl middleware won't be activated.
Leiningen 2.8.1 on Java 1.8.0_171 OpenJDK 64-Bit Server VM
"

(prin1 cider-jack-in-dependencies)
(("com.cemerick/pomegranate" "1.0.0")
 ("org.tcrawley/dynapath" "0.2.5")
 ("org.clojure/tools.nrepl" "0.2.13"))

(prin1 cider-jack-in-lein-plugins)
(("refactor-nrepl" "2.4.0-SNAPSHOT" :predicate cljr--inject-middleware-p)
 ("cider/cider-nrepl" "0.18.0-SNAPSHOT"))

(prin1 cider-jack-in-nrepl-middlewares)
(("refactor-nrepl.middleware/wrap-refactor" :predicate cljr--inject-middleware-p)
 "cider.nrepl/cider-middleware")

(prin1 cljr-inject-dependencies-at-jack-in)
t

(pkg-info-version-info 'cider)
"0.18.0snapshot (package: 20180526.8)"

(pkg-info-version-info 'lispy)
"0.26.0 (package: 20180516.826)"

(pkg-info-version-info 'clj-refactor)
"2.4.0snapshot (package: 20180420.223)"

(cljr--middleware-version)
"2.4.0-SNAPSHOT"
(cljr-version)

(prin1 (read (f-read "nrpltest/project.clj")))

(defproject nrpltest 
  "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.9.0"]])
abo-abo commented 6 years ago

("com.cemerick/pomegranate" "1.0.0")

There's your problem. Change it to:

(com.cemerick/pomegranate "0.4.0")

and it will work. This is a known regression in pomegranate that makes the package almost useless. See https://github.com/cemerick/pomegranate/issues/94.

NightMachinery commented 6 years ago

@abo-abo My setup, too, works after calling (cider-load-file (expand-file-name "lispy-clojure.clj" lispy-site-directory)). Should I just add it to my Clojure hook? UPDATE: I see that you already do this in the added middleware. so why is it not taking effect?

abo-abo commented 6 years ago

I see that you already do this in the added middleware. so why is it not taking effect?

No idea. I would appreciate some pointers on why it's not happening in your config.

bennyandresen commented 6 years ago

I'm having the same issue as @NightMachinary. After a connected cider repl I have to eval (cider-load-file (expand-file-name "lispy-clojure.clj" lispy-site-directory)) to get completion or C-1 and C-2 to work. (C2 results in "no such namespace" message exactly as the top post.)

abo-abo commented 6 years ago

@bandresen

After a connected cider repl I have to eval

Did you connect with cider-jack-in or by pressing e?

bennyandresen commented 6 years ago

@abo-abo Using cider-jack-in to launch the repl from a clj-file. I eval forms in that file using C-c C-c or C-x C-e

What I can do to easily reproduce this: Open clj-file M-x cider-jack-in RET

After waiting 30 seconds or whatever depending on the project.

Starting nREPL server via lein update-in :dependencies conj \[com.cemerick/pomegranate\ \"0.4.0\"\] -- update-in :dependencies conj \[org.tcrawley/dynapath\ \"0.2.5\"\] -- update-in :dependencies conj \[org.clojure/tools.nrepl\ \"0.2.13\"\ \:exclusions\ \[org.clojure/clojure\]\] -- update-in :plugins conj \[refactor-nrepl\ \"2.4.0-SNAPSHOT\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.18.0-SNAPSHOT\"\] -- repl :headless :host ::...
nREPL server started on 35005
[nREPL] Establishing direct connection to localhost:35005 ...
[nREPL] Direct connection to localhost:35005 established
Connected.  This REPL is yours to command!

Now after I see the REPL pop up I go to a function and press C-2 and this appears in the *Messages* buffer and minibuffer: user-error: CompilerException java.lang.RuntimeException: No such namespace: lispy-clojure, compiling:(/tmp/form-init93109509822981571.clj:1:5)

Manual eval of (cider-load-file (expand-file-name "lispy-clojure.clj" lispy-site-directory)) Now I can use C-1 and C-2 without errors.


While reproducing I found the following behavior that may help with finding that here appears to be some timing or a wrong hook used place where lispy-clojure is attempted to be loaded:

This is pressing C-1 after a fresh Emacs session started up, no CIDER running:

Starting nREPL server via lein update-in :dependencies conj \[com.cemerick/pomegranate\ \"0.4.0\"\] -- update-in :dependencies conj \[org.tcrawley/dynapath\ \"0.2.5\"\] -- update-in :dependencies conj \[org.clojure/tools.nrepl\ \"0.2.13\"\ \:exclusions\ \[org.clojure/clojure\]\] -- update-in :plugins conj \[refactor-nrepl\ \"2.4.0-SNAPSHOT\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.18.0-SNAPSHOT\"\] -- repl :headless :host ::... [2 times]
nREPL server started on 38557
[nREPL] Establishing direct connection to localhost:38557 ...
[nREPL] Direct connection to localhost:38557 established
Loading /home/benny/.emacs.d/.local/packages/elpa/lispy-20180608.958/lispy-clojure.clj...
nREPL server started on 44009
[nREPL] Establishing direct connection to localhost:44009 ...
[nREPL] Direct connection to localhost:44009 established
Connected.  Hacks and glory await!
nil
=> nil
Connected.  Simplicity is the ultimate sophistication. -Leonardo da Vinci

Note that it launched two CIDERS (bug), but maybe more important it shows that lispy-clojure is loading before we get either REPLs connected event output.

abo-abo commented 6 years ago

@bandresen

Using cider-jack-in to launch the repl from a clj-file.

Thanks, I was able to reproduce the scenario. For me it never happened since I always use e to perform cider-jack-in for me, and that one would load the middleware.

Anyways, your scenario should be fixed now, please test.

bennyandresen commented 6 years ago

@abo-abo The changes you make work.

It appears to only load the actual clojure code when I initiate an action.

The REPL can sit for a minute but it only loads the lispy-clojure when I try to tab complete or C-1 C-2

Unrelated to this but my testing: I will open another issue because current melpa lispy is not compatible with current cider.

skrat commented 6 years ago

I have the same issue here, even with the latest version, it still complains about compliment not being in class path. It essentially break the autocompletion every time I enable lispy-mode. Can I just turn off the whole Clojure integration part? It obviously doesn't work, it's messing with dependencies, does stuff like hard codes cider-nrepl version

https://github.com/abo-abo/lispy/blob/master/lispy-clojure.clj#L47

This is not what I want during development. If CIDER can do without, why can't lispy just re-use that?

skrat commented 6 years ago

I'm trying to understand why does lispy add some (pomegranate) dependencies here:

https://github.com/abo-abo/lispy/blob/0d40a3619ca5739ec0b2864ec40f754847da6e2e/le-clojure.el#L96

Only to use that, to add more dependencies here:

https://github.com/abo-abo/lispy/blob/0d40a3619ca5739ec0b2864ec40f754847da6e2e/lispy-clojure.clj#L39

Can't you just add all dependencies you need in le-clojure.el and skip using pomegranate? Also what's the point of adding cider-nrepl if you already depend on CIDER, it's reasonable to assume it's already there and loaded.

abo-abo commented 6 years ago

@skrat

I have the same issue here, even with the latest version, it still complains about compliment not being in class path.

Please add a repro scenario.

It essentially break the autocompletion every time I enable lispy-mode.

This should not happen: lispy-clojure-complete-at-point catches all errors and returns nil if something fails. This can't break completion.

Can I just turn off the whole Clojure integration part?

(setq completion-at-point-functions
      (delq 'lispy-clojure-complete-at-point completion-at-point-functions))

It obviously doesn't work, it's messing with dependencies, does stuff like hard codes cider-nrepl version

What's wrong with that? cider/cider-nrepl "0.16.0" is the library that I want to use. Is there any problem to have it loaded alongside whatever version you're using? This should not be an issue in Clojure.

If CIDER can do without, why can't lispy just re-use that?

I don't want to do without. I want to have features that I want to have. Of course, the intention is to provide these features for free, they should not break the existing features.

abo-abo commented 6 years ago

I'm trying to understand why does lispy add some (pomegranate) dependencies here:

I thought this is obvious: I want a use-package-like behavior in Clojure, i.e. dynamically loading whatever libraries I need without having to declare them in project.clj. In order to set it up, I need "org.tcrawley/dynapath" "0.2.5" and "com.cemerick/pomegranate" "0.4.0". Afterwards, lispy-clojure.clj can use whatever package it needs via use-package.

skrat commented 6 years ago

Afterwards, lispy-clojure.clj can use whatever package it needs via use-package

Sure, but why are you not using the (cider-add-to-alist 'cider-jack-in-dependencies ? This would remove 2 dependencies (pomegranate, dynapath).

What's wrong with that? cider/cider-nrepl "0.16.0" is the library that I want to use

It's wrong since you can't load the same library twice, with different versions, into the same JVM process. Well of course you can, but depending on the order of loading, only one will be there. So if you load cider/cider-nrepl "0.16.0" with your smartypants pomegranate method, you're most likely overwriting whatever CIDER (currently at 0.18.0) loaded, and of course it breaks things for CIDER. Correct me if I'm wrong.

skrat commented 6 years ago

It's pretty hard to get something reproducible, but here you go https://github.com/skrat/lispy-buggy Steps:

abo-abo commented 6 years ago

Sure, but why are you not using the (cider-add-to-alist 'cider-jack-in-dependencies ? This would remove 2 dependencies (pomegranate, dynapath).

This is already used.

Correct me if I'm wrong.

Here's a session from today:

;; Connected to nREPL server - nrepl://localhost:32909
;; CIDER 0.18.0snapshot, nREPL 0.2.13
;; Clojure 1.8.0, Java 1.8.0_171

After cider-jack-in this gets loaded automatically:

Testing lispy-clojure-test

Ran 11 tests containing 43 assertions.
0 failures, 0 errors.

Then:

user> (lispy-clojure/location 'cider.nrepl.middleware.util.java.parser/source-info)
("file:/home/krehel/.m2/repository/cider/cider-nrepl/0.16.0/cider-nrepl-0.16.0.jar!/cider/nrepl/middleware/util/java/parser.clj" 248)

user> (lispy-clojure/location 'cider.nrepl.middleware.pprint/fipp-pprint)
("file:/home/krehel/.m2/repository/cider/cider-nrepl/0.18.0-SNAPSHOT/cider-nrepl-0.18.0-SNAPSHOT.jar!/cider/nrepl/middleware/pprint.clj" 25)

It's pretty hard to get something reproducible

Then there's no point of me getting into it. A docker image with spacemacs inside isn't a reproducible recipe for me. I don't want to debug spacemacs issues. Please post a recipe with emacs -Q.