-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fix #150] Replace clojure-complete with compliment #153
Conversation
Ah, right. REPLy has to also work in situations where the nREPL is a remote classloader/process and does not have clojure-complete on the classpath (e.g. The nice thing about clojure-complete here is that it's just 1 file to ship across. With a bunch of namespaces in compliment, in order to integrate it I guess we'd have to ship every namespace over the nREPL connection. Also, this bit of code wouldn't be necessary for compliment, since this |
I see. I had no idea why this was necessary.
Guess that extracting this: '~(try
(formify-file
(-> (Thread/currentThread)
(.getContextClassLoader)
(.getResource "complete/core.clj")))
(catch Exception e
'(throw (Exception. "Couldn't find complete/core.clj"))) And applying it all namespaces should be enough, right?
I'll remove it. |
Yep, that sounds right. It will probably be some kind of nasty expression-building because of the cross-process stuff, but should work. |
@trptcolin Have a look at the updated code. Seems to me everything is being loaded (by inspecting the expressing passed to |
//cc @alexander-yakushev |
The current issue looks like the files needing to be required in an order where the dependencies are satisfied when they try to load. (Locally I'm printing out the value of Bumping utils, context, & sources up to the top appears to get things working for me locally, but I'm going to want to do a lot more testing before merging. The remote-process/classloader stuff is hairy to deal with, as you're seeing 😄 |
Yeah, I imagined it might be a load order issue; should have pursued this train of thought. I'm glad you got things working and I guess I'll be leaving the PR in your more capable hands from here on. :-) Thanks for taking the time to walk me though some of the code. |
Is there a way to build the namespace dependency tree automatically? It doesn't sound like a good idea to hardcode the list of files from other project. Ideally some function should do that, or at least I can put a function into Compliment itself that would yield a list of Compliment's namespaces/files. |
Good point @alexander-yakushev |
OK, it seems that the way to go is for me to put this into (def all-files
"List of all Compliment files in the correct loading order. This is required
by REPLy."
(map (partial format "compliment/%s.clj")
["utils"
"context"
"sources"
"sources/class_members"
"sources/ns_mappings"
"sources/namespaces_and_classes"
"sources/keywords"
"sources/special_forms"
"core"])) Anyway it would make more sense for me to maintain this list than for Colin. Thoughts? |
That'd be awesome, though it makes me sad for you to have to do that. |
Well, any automatic solution is unreasonably complex. Besides new files aren't added that often. I'll do this first thing in the morning. |
So, done alexander-yakushev/compliment@401aa20. Also I pushed it to Clojars as compliment |
I've updated the PR accordingly. Finally, everything seems to be working. :-) Thanks, @alexander-yakushev! |
OK, I got a chance to try this out more thoroughly tonight, and so far there are a couple of things I've found that are holding me back from merging (see below). I can totally see myself getting addicted to the Java instance method completion - good stuff!
|
Sounds like a good idea. You're right that the current sorting is optimized for drop-down completion.
Sounds like a bug as classes are always usable if referred to by a FQN. @alexander-yakushev is this intentional? |
This is not hard to do.
|
As requested in trptcolin/reply#153.
@trptcolin Guess you should test this with the new compliment 0.2-SNAPSHOT. The features you requested are now present there. |
A little typo by @bbatsov, it is |
I've updated the PR. |
I would suggest to wait until solid |
@alexander-yakushev You'll also have to check what's wrong with compliment and reply now. 0.1.2 passed the test suite, but 0.2 is currently failing one test. |
@alexander-yakushev Guess you can release that 0.2 version. |
I assume the spot calling |
@alexander-yakushev Can you look into this? I'd love us to finally wrap this legendary change. |
I remember I already did, and something prevented me from fixing it. I have to look again. |
@bbatsov We have discussed it before, haven't we? All Compliment files together are too big to be loaded in one |
@alexander-yakushev Yeah, that's what I mean when I asked if you can look into this. :-) |
Well, there's not much I can do on the Compliment side, is there? |
It's zombie time! I was wondering what should we do with this PR. Just refreshing your memories so that you don't have to — we were stuck with the following problem.
So, what do we do, gents? Investigate possible solutions further, or call it a day and close for good? |
Yeah, 4 was the blocker. I obviously want to see the switch done, guess @trptcolin wouldn't mind it as well. |
I don't know the code but would it be so difficult to have one load per namespace? |
@jakubholynet Likely something like this would be possible. When I started working on this I just tried to emulate directly what was being done for |
As @trptcolin commented himself:
|
I wonder if this asks for a more generic solution. Say, client-side cider-nrepl that can force-feed the server process with all the necessary code, even if the server started with bare nREPL. Too much? |
But what do you do when you just what to use REPLy by without CIDER's middleware?
Maybe really the simplest way would be to load the namespaces sequentially. |
Do you mean without CIDER but still wanting a completion? Perhaps, cider-nrepl could be modular in what it can ship over network.
It probably would be. And it would be nice if cider-nrepl had a standardized way of doing that, so that any middleware could be uploaded like that. Or, perhaps, not - I'm just thinking aloud, no particular usecase in mind. |
That should probably an nREPL concern, though, right? It would certainly be nice to be able to easily "enrich" an already running nREPL server. AFAIK this the main selling point of |
Sorry to bump this thread. clojure-complete has a bug that crashes leiningen on JDK 9. It has been fixed upstream but not pushed to Clojars. I tried to port clojure-complete and luckily I found this PR. Couple of points.
I don't know if collaborators in clojure-complete (@trptcolin ) can push a release to clojars but it will be great if it can be done for the short term fix. Thanks |
As by now Clojure 1.4 is dead and buried I don't think that bumping this would be a big problem for everyone. These days few libs aim to support anything older than 1.7.
Well, I wouldn't call this that big of a change. End users probably won't even notice it. |
Btw, there's a hope we'll wrap this at some point. After a short convo with @cgrand he made the astute observation that all we need to do to not the hit the JVM class limit is to evaluate smaller forms. We can either evaluate the forms in all the files one by one, which will certainly work, or try to eval each file as a single form, which will probably work, as none of the files are big. Basically the only reason why the PR's failing right now is that we're concatenating all files together and trying to evaluate them all at once. I can't believe how we didn't figure this out back in the day, but better late than never. :-) |
It doesn't look there is a trivial way to do this right now. The completion initializer assumes everything can be done in a single call through nREPL. A fixed version should somehow perform multiple calls, one per each file. |
Yeah, that should certainly be changed. I don't see any particular reason for this having to be done in a single eval request. Alternatively we can wait for @cgrand to port the sideloading to nREPL and then REPL-y would be able to simply inject compliment in this manner. That will probably be the preferred way to load libs from the clients down the road, so I guess we should aim in this direction. |
I've looked a bit more into it and while the idea is still to avoid having a big constant (string or form it doesn't matter; chunked or not it doesn't matter; it's the overall pr-dupped size of all constants that matter for the class size limit) it's a little bit more involved than what I previously thought (I missed the fact that the code I was shown was in syntax-quoted etc.). But @bbatsov is right, in the end side loading is the answer. |
7 years later I've decided to take an alternative approach in the interest of doing the least invasive change that will benefit the end users - see https://metaredux.com/posts/2021/08/17/introducing-incomplete-a-simple-clojure-code-completion-library.html |
Good decision! |
Turned out to be even easier than I thought, but one of the integration tests is failing and I'll need your help to fix it.
I've played with the completion is REPLy and it's working just fine; I have no idea why the test misbehaves.