Fork me on GitHub
#lsp
<
2022-03-28
>
dharrigan08:03:31

Just watching the latest stuff go into clojure-lsp for the java integration. Would you consider an option to provide, in the config.edn a path to the source, in addition to download or not download? For example, on Arch, I already have the sources downloaded, which are installed at /usr/lib/jvm/java-17-openjdk/lib/src.zip, so would be nice to simply point the config to there.

☝️ 1
dharrigan08:03:29

A key benefit of this, is that I don't have to worry about ensuring the sources are up-to-date. It's someone else's problem 🙂

dharrigan12:03:42

I've done a PR for this (https://github.com/clojure-lsp/clojure-lsp/pull/882). Happy to change based upon feedback.

ericdallo12:03:16

@dharrigan that feature is pretty new, so I didn't have time to improve docs that much, but it should be already possible to point to existing java docs

ericdallo12:03:25

I named URI exactly because of that

ericdallo12:03:59

It should work under the existing setting, if not, we should fix and not create a new setting for that

dharrigan12:03:40

sure, although one would have to remember to prefix it with file:/// etc...

dharrigan12:03:45

for uri to work.

ericdallo12:03:59

I'll rename from :jdk-souce-download-uri to jdk-source-uri

ericdallo12:03:02

Sound agood to me

ericdallo12:03:16

We can check if it's a path and concert to URI as well

ericdallo12:03:37

There is a shared/filename->uri function

dharrigan12:03:56

awesome, even simpler 🙂

dharrigan12:03:12

Shall I close down the PR?

ericdallo12:03:01

Feel free to change it to use same URI but checking if it's a filename and renaming it to :jdk-source-uri

dharrigan12:03:26

have to take pooch for a walk first, then when I come back I'll have a look see

dharrigan13:03:18

So question 'tho, what to do with download-jdk-source If false, or true

dharrigan13:03:58

if false, but uri is still file:/// do analyse? if false and uri is http:// do nothing?

ericdallo13:03:12

yes, I think we should analyze still

dharrigan13:03:35

kk, and if false and uri == http do nothing, like it is atm.

ericdallo13:03:37

check if URI is file:// or a path, otherwise check download-jdk-source

ericdallo13:03:51

I'd not suggest check for http, since there is https and variations

ericdallo13:03:49

I'll work on automatically finding the source on user's java home if available as mentioned https://clojurians.slack.com/archives/C17JYSA3H/p1648473913261469?thread_ts=1648384269.951629&amp;cid=C17JYSA3H

ericdallo13:03:11

and fallback to check the URI if not found or not set

genmeblog08:03:32

How to globally turn off unused-public-var linter in lsp? I have config.edn containing {:linters {:clojure-lsp/unused-public-var {:level :off}}} in ~/.clj-kondo/ and ~/.lsp folders and this still shows the warning

borkdude08:03:45

@tsulej ~/.config/clj-kondo/config.edn is the global clj-kondo config

genmeblog08:03:04

Oh... Why I didn't know that? Thanks!

borkdude08:03:39

It's in the docs, but I won't be that guy who tells you to RTFM because I enjoy helping people on Slack and I'm "guilty" of this myself too many times as well ;)

😄 1
genmeblog08:03:27

What confused me was the existence of ~/.clj-kondo folder with jar inside. But yeah, I skimmed the docs long time ago and have to do it again.

borkdude08:03:34

I don't know how that folder got there :)

genmeblog09:03:23

$ ls -l ~/.clj-kondo/
total 16968
-rw-r--r-- 1 tsl tsl 17374672 Mar  8 12:51 clj-kondo-lsp-server-2022.03.09-standalone.jar

genmeblog09:03:56

seems like a lsp download

borkdude09:03:00

have you been using Cursive maybe? that lsp server can be used with Cursive or any other editor, but typically it's used with Cursive

borkdude09:03:26

I don't remember any tool that's automatically downloading it, could it be that you have made a script which does so?

genmeblog09:03:42

Nope, emacs only. Maybe I messed something with the setup. I was trying many things at the beginning of the month. No, rather not downloaded manually. "Rather"...

borkdude09:03:06

you can probably throw it away

borkdude09:03:20

also I don't recommend having a .clj-kondo dir in your home directory

borkdude09:03:26

since it may incorrectly be picked up as a project root

borkdude10:03:53

Example of java navigation in a project that uses lsp4j :-) So it should also work in clojure-lsp itself :) Requires #clojure-lsp-builds

nice 3
😍 4
simonkatz18:03:34

I’m working on a project where all code is in a code subdirectory of the root of a Git repo — so project.clj, src dir, test dir etc are all in the code directory. Some clojure-lsp functionality isn’t working. For example, I don’t see any clj-kondo messages and the number of references to a function is not split into separate counts for tests and other code. If I move all the contents of the code directory up a level, all is OK. Is there some setting I can change to make this project work nicely with clojure-lsp?

borkdude18:03:33

Which editor are you using?

ericdallo18:03:31

you should configure the lsp-mode project root properly to point to code directory

ericdallo18:03:50

try lsp-workspace-folders-remove , choose the git root, and then lsp again

ericdallo18:03:02

choose the code dir when lsp-mode prompts

borkdude18:03:32

indeed, what greg says

simonkatz18:03:21

Thanks! (You guys are both amazing.)

❤️ 2
ericdallo18:03:32

clojure-lsp About the Java interop support being developed:thread:

👏 2
ericdallo18:03:36

Me and @U04V15CAJ have been adding support for Java interop on clj-kondo and clojure-lsp, for now the only java interop we have so far is the find java classes definition from java class usages. With current nightly build from #clojure-lsp-builds , we support : • Find a java class if the source (`.java`) is available on classpath • Find and decompile a java class if no source is available, only .class, decompiling it to .lsp/.cache/java • Find a JDK class (e.g. java.util.UUID), this one was just added recently, and it has some waterfall decisions ◦ First clojure-lsp tries to find a existing JDK src.zip , this is pretty common on JRE installations, it checks java.home property, JAVA_HOME env var, and java command on PATH ◦ If above is not found, it uses the one specified on :java :jdk-source-uri (Falbacking to clojure-lsp/jdk-source https://github.com/clojure-lsp/jdk-source if not set manually) only if :java :download-jdk-source? is enabled (disabled by default) We are still improving, and we need to make some minor fixes on clj-kondo, with all of this set and working, all java classes should be found when trying to find a definition 🎉 We should keep this on master a little bit before next release, for those who want to test it, it's possible downloading a nightly build from #clojure-lsp-builds

🙌 6
🎉 10
rodolfo18:03:09

Wow, nice work!!

gratitude 1
borkdude18:03:10

I made a bb script for myself to download and install the latest nightly. Feel free to copy and adapt.

#!/usr/bin/env bb

(ns lsp-nightly
  (:require [babashka.curl :as curl]
            [babashka.fs :as fs]
            [ :as io]))

(def lsp-nightly "")
(io/copy (:body (curl/get lsp-nightly {:as :stream}))
         (io/file "/tmp/nightly.zip"))

(fs/unzip "/tmp/nightly.zip" "/tmp/lsp" {:replace-existing true})

;; :facepalm:, the downloaded zip file contains another zip file
(fs/unzip "/tmp/lsp/clojure-lsp-native-macos-amd64.zip" "/tmp/lsp" {:replace-existing true})

(def dest-dir (or (first *command-line-args*) "/Users/borkdude/Dropbox/bin"))

(fs/copy "/tmp/lsp/clojure-lsp" dest-dir {:replace-existing true})

(.setExecutable (io/file dest-dir "clojure-lsp") true)

👍 2
dharrigan19:03:36

Here's a crazy idea, perhaps for the looong future. In IDE's such as IntelliJ, if one is working with Java/Kotlin and has dependencies. You can opt-in to download source as well as the normal jar files. This is done if the artifact in question has also an accompanying -sources jar located at the same location as the jar, for example: . Wouldn't it be neato that if in the background and totally opt-in that clojure lsp could download the sources of dependencies if available for clj-kondo analysis...?

borkdude19:03:04

@dharrigan What I was thinking is this: you could generate an additional deps.edn with those -sources deps (through some script) and then add that deps.edn as an extra dep via :local/root or -Sdeps. This technique could be used with or without changes to lsp. lsp could also try to do this automatically.

🧵 1
dharrigan19:03:21

interesting!

ericdallo19:03:23

Yeah, To be honest, the decompiler seems to work pretty well, so I'd wait for more testing on that feature

borkdude19:03:29

There is also a project called enrich-classpath under the emacs-clojure org that could be used (partially or as inspiration)

borkdude19:03:59

Yes, the -sources trick can already done manually too using an alias with extra-deps and then add the alias to the lsp startup command

mkvlr20:03:29

having the JDK sources available probably goes a long way in the day of a Clojure dev?

ericdallo20:03:04

Probably, I already saw people saying that one of the reasons they stick to cursive is because clojure-lsp doesn't java interop

ericdallo20:03:10

not for so long :)

snoe20:03:43

Yeah, if you've ever used java.time, for instance, having completion is night and day difference to keeping 15 browser tabs open to each class.

💯 4
dharrigan20:03:44

having java jdk sources is a big boon indeed!

dharrigan20:03:05

I for one welcome our new interop overlords 🙂

catjam 1
ericdallo20:03:57

Yes, we would like to add support for docs/go-to method definition and eventually completion, baby steps :)

ericdallo20:03:23

we already have the mechanism on clj-kondo (ASM), we just need to improve it to have those features available on clojure-lsp

vemv07:03:52

btw one thing that I think escaped the various threads we had on the topic was practicalli's aliases https://github.com/practicalli/clojure-deps-edn/blob/fc9f90c51113985938a5a7478d77554f477540f5/deps.edn#L462-L478 It's not drastically different from the various ideas that have been thrown around, but this one seems simple for users to understand and test out At scale it doesn't quite cut it since users will likely forget, misconfigure, etc or even after a correct configuration, switching JDKs would invalidate these aliases, possibly leaving very confusing errors.

vemv07:03:41

And also deps.edn is one big map i.e. no sequential semantics. For all "sources" stuff, if you don't place this stuff at the tail of the classpath, you can and will suffer :)

😅 1
dharrigan20:03:52

Pleased to say that with the latest on master, the goto definition using vim + coc is looking good!

🚀 2
dharrigan20:03:32

(baby steps) 😉

borkdude20:03:15

Is this with java navigation?

dharrigan20:03:21

Yes. I can goto definition on a java class and have it decompiled etc...

dharrigan20:03:59

Not quite 100% there, for exmaple, if I goto definition on a stringbuffer constructor, it plops me at the top of the decompiled file, rather than at the constructor.

dharrigan20:03:05

But I'm sure it'll all be good in the end.

dharrigan20:03:46

it's no biggie, I can always go to the method by a simple grep. Having the ability just to go to source is fantastic no-matter what!

borkdude20:03:53

Those are the little things that are going to be improved over the next couple of months

dharrigan20:03:01

yup 🙂 All wonderful stuff.

dharrigan20:03:35

thank you! and Eric 🙂

borkdude20:03:45

@UKFSJSM38 considering this example though: perhaps clj-kondo could add :constructor true :arg-count 0 or so and then maybe clojure-lsp could figure out where to go, into the decompiled file?

borkdude20:03:28

I think that would require running a library like java-parser over the decompiled file

borkdude20:03:37

and then go to the correct constructor

borkdude20:03:23

I'm not sure if people would be too unhappy if clj-kondo did this work and thus had an dependency on java-parser

borkdude20:03:32

it already has a dependency on ASM

borkdude20:03:55

then you could call clj-kondo with the decompiled Java file and get on the fly analysis

borkdude20:03:12

anyway, these are the things that we need to figure out :)

👍 1
ericdallo20:03:10

Yes, ATM clojure-lsp has no logic on how to parse clojure or java, it relies on analysis location, so I think having the location come from kondo would make things easy to implement on clojure-lsp side

ericdallo20:03:19

If we parse at clj-kondo, we would probably be able to add to analysis args, methods info and more

borkdude21:03:00

yeah, and completions etc

ericdallo21:03:30

If ASM support get row/col location, then we may not need java-parser, but I couldn't find that info

borkdude21:03:05

it doesn't

😔 1
borkdude21:03:33

I mean, this info isn't available in the .class files I think, it's compiled away

borkdude21:03:09

but perhaps other people will also happily use the java parsing info if clj-kondo has that dep

borkdude21:03:14

javaparser I mean

borkdude21:03:22

and we can make deps optional too

borkdude21:03:20

btw there's also java doclet stuff we could try to use. I think CIDER uses this and I've also used this but at build time, not in clj-kondo itself

ericdallo21:03:23

Got it, that's bad

ericdallo21:03:43

Yeah, I know it would be one more lib, but it would be great for downstreams I think if kondo know more about java

ericdallo21:03:08

what does doclet does? It brings doc about java?

ericdallo21:03:38

If we intend to add java-parser in the future, would be needed that doclet?

borkdude21:03:58

it can generate javadoc stuff but as it does that, it extracts info about constructors, methods etc. it's built into java

1
borkdude21:03:42

I don't know if (ToolProvider/getSystemDocumentationTool) works properly in graalvm and also not if it provides good locations

ericdallo21:03:22

I see, sounds good explore that

borkdude21:03:30

feel free to try this out a bit

👍 1
borkdude21:03:50

I'm pretty sure javadoc doesn't generate any line numbers

😔 1
borkdude21:03:57

Maybe we have to split clj-kondo into modules too.

borkdude21:03:22

and clojure-lsp can use all modules, but other users can choose to only use the core dependency for only clojure

borkdude21:03:43

but that can happen in the future too when people start asking for it

ericdallo21:03:53

yes, I like that

borkdude21:03:54

I noticed javaparser has two deps: javassist and guava

ericdallo21:03:04

we only started split clojure-lsp into modules after people asked

👍 1
ericdallo21:03:22

clojure-lsp cli module unfortunately already has guava because of lsp4j