Fork me on GitHub
#lsp
<
2023-03-30
>
witek09:03:04

I would like to use the analysis data produced by clj-kondo. Is there a way to get this data from clojure-lsp which is already started from Emacs? Perhaps configure clojure-lsp so that it writes it into a file and keeps it updated? Or can I somehow connect to the clojure-lsp process? Or should I run my own clj-kondo` process with a file watcher separately?

borkdude09:03:57

That is all the data that lsp itself uses, but lsp also does some processing on that and can export its own format using clojure-lsp dump (WARNING: it's a lot of data)

witek09:03:59

I know, I can run clj-kondo and get the data I need. But my project is big and it takes a while. And since Emacs already has started clojure-lsp , I hoped I can reuse this instance so I don`t have to run it twice.

witek09:03:19

... clojure-lsp already has the data in memory - Is there a way to access it?

witek09:03:07

I don't really understand the internals of LSP protocol, but could it be used to get the analysis data in raw (EDN)?

borkdude09:03:37

I'll defer to @UKFSJSM38 but these details, but I don't think so at the moment

ericdallo11:03:25

It's possible and easy to access that data via editor but clojure-lsp doesn't support dump via editor yet, but would be easy to add, would you mind creating a issue for that @U2ERGD6UD? We could offer a function to return that info via a custom request, but I'd like to understand how you want to use the info, if via a Elisp function(if using Emacs) or something else

borkdude12:03:58

wouldn't opening that data in your editor crash your editor? ;)

ericdallo12:03:48

Yeah, exactly, that's why I'd like to understand what you would do with that data, probably saving to a file would be a best option

witek12:03:59

Well, going through the editor seams not right. I want the data in Clojure. To generate charts/graphs in a Clerk notebook. So I have a running REPL where I would like to access the data.

ericdallo12:03:35

So maybe using clojure-lsp.api that already exists?

ericdallo12:03:19

You can't really link to the running clojure-lsp as if it's a graal image, a repl won't work

ericdallo12:03:55

But for a running jvm clojure-lsp it's already possible via lsp-clojure-connect-nrepl-server that I use for debugging purposes

ericdallo12:03:49

I think for your case may be a good idea use clojure-lsp JVM in your editor so you could do that

witek12:03:17

Ok, say I use jvm lsp. How do I access the kondo analysis data?

ericdallo12:03:39

Do you use Emacs?

witek12:03:07

I mean, is there an atom holding it?

ericdallo12:03:29

lsp-clojure-nrepl-connect (or something, can recall the exact name right now), will connect cider to the nrepl running in clojure-lsp of your editor

馃憤 2
ericdallo12:03:54

Then you can use the clojure-lsp.api to access functions that provide kondo analysis

馃憤 2
witek12:03:37

Thank you! Again!

borkdude12:03:43

@U2ERGD6UD check clj-kondo channel for LSP docs on how to running the most recent LSP + kondo + nREPL (typed this on phone)

ericdallo12:03:29

It works too, but it doesn't need to be the most recent master to do that, https://clojure-lsp.io/installation/#embedded-jar-legacy-executable from lastest release is already enough

witek12:03:26

I could include lsp-clojure as a dependency to my existing REPL with Clerk. And then start the lsp/kondo analysis via API. Correct?

witek12:03:03

No, then my editor will not connect.

ericdallo12:03:40

the process running your editor is separated from your REPL with Clerk

witek12:03:05

Yo have to include a (http) server in clojure-lsp 馃槈

ericdallo12:03:36

I think it's best to avoid that:joy:

borkdude12:03:32

@U2ERGD6UD Here is how you can start lsp along with any other deps in an nREPL server:

馃檹 2
witek13:03:16

It looks like the functions in clojure-lsp.api print the analysis data. Can I get to the data directly?

ericdallo13:03:57

Yes, just pass the :raw option

ericdallo13:03:52

What function are you calling?

witek13:03:05

Not sure which one. Now trying `dump

witek13:03:43

You mean {:analysis {:type :raw}}?

witek13:03:41

{:output :raw} probably...

ericdallo13:03:35

actually, not really, that option doesn't exist

ericdallo13:03:55

check the docstring or cljdocs

witek13:03:55

ok, so the analysis data is in the resulting value. can I dispable printing the output?

ericdallo13:03:15

let me confirm

ericdallo13:03:58

the docs are missing mention, but you can just pass :raw? true and should not have any print, only the result

ericdallo13:03:04

I will improve the docs

witek14:03:55

{:output :none} or {:output nil} would be nice...

ericdallo14:03:48

yeah, not sure would be possible to support :output nil as some commands didn't have the output, would cause a breaking change

ericdallo14:03:14

and :output is already a map on some commands, so would be weird I think to support :output :none

witek14:03:26

ok. :raw? true works. thank you!

馃帀 2
ericdallo14:03:30

I thought about :output :raw? but I don't like that much the raw as well

borkdude14:03:02

I would prefer :raw true and :output :raw ;)

ericdallo14:03:26

you mean :output :raw true for the latter?

witek14:03:21

If shape of :output can not be changed, perhaps a new option :no-output true would be more clear.

ericdallo14:03:46

output is already a map for some functions but not for others (which I intend to fix now), but if we introduce a :output :raw as a keyword value, we would cause breaking changes for commands that didn't call :output (because didn't exist)

ericdallo14:03:26

@U2ERGD6UD would look weird for commands that already have :output right?

witek14:03:32

But why have the :raw there? The option does not change the output. It disables it. And the function result does not change. I find "raw" misleading. Should be "none" oder "disabled" or something...

ericdallo14:03:27

yep, a legacy from clojure-lsp.main which uses internal-api as well, clojure-lsp --raw , I agree we could have :output :something true

ericdallo14:03:42

also maybe output is not a good place to specify whether should print to stdout or not :) output means the output of the function, if will use edn, json, canonical-paths etc, but not the stdout print

plus_one 2
ericdallo14:03:52

naming is hard indeed 馃槀

ericdallo14:03:46

maybe :silent or something which is really what raw was intended for since the beginning

witek14:03:55

Another idea: {:output {:target :std-out}} as default with possibility of {:output {:target :none}}

ericdallo14:03:23

but isn't the function return a target of a output as well 馃槀 ? :output :quiet ? I'm out of ideas already..

witek14:03:31

Perhaps dump should not print at all and just return a value. And then have a new start with dump!

ericdallo14:03:32

yeah, I think that was accidentally, we could fix it only for dump

ericdallo11:03:53

The removal of the let is quite recent but beautiful indeed :)

genmeblog18:03:04

Probably it's not the same case but cider-eval-last-sexp-and-replace does the same magic.

ericdallo18:03:56

@U1EP3BZ3Q I think borkdude is sharing about the inline symbol feature which allows you to remove a local or var and replace with its real code

馃憤 4
ericdallo18:03:31

an eval would get only the result and not really the entire code being used considering other vars and locals

borkdude18:03:06

yes, so

(let [x 1 y 2] (+ x y)) would become `(+ 1 2)
`

馃憤 2
genmeblog18:03:13

definitely useful

ericdallo18:03:27

Also, No repl connected required :)

genmeblog18:03:46

actually, no repl no life :)

ericdallo18:03:37

yeah, repl is awesome, but if I can get some or most features without the need to connect and eval a huge project, I'm even happier

borkdude18:03:32

I always say that clj-kondo is there not to replace the REPL but to optimize the time you spend in the REPL, since you can spot issues early, you don't even have to bother to eval it

鈽濓笍 6
eval-on-point20:03:40

Using emacs, clojure-align seems to be pretty slow for my coworker and me when lsp is enabled. A small file like this seems to take around 3.5 seconds to format:

{:paths ["src"]
 :deps {dep1 {:local/root "path/to/dep1"}
        example/depdency2 {:local/root "example/path/to/dep2"}
        a/longer-dependency-name-for-format-example {:mvn/version "2.0.0"}}
 :aliases {:test {:extra-paths ["test"]}}}
Scanning the code, I think this is because clojure-align may make several recursive calls cljfmt. Before digging deeper, I am just hoping to confirm that others are experiencing this issue and that we don't have anything misconfigured on our ends

ericdallo20:03:58

yes, I think this is a performance issue in cljfmt + a lot of calls that probably should not happen in clojure-align. One thing that happens is that lsp-mode changes indent-region via a variable to use lsp for format regions in clojure buffers, you can disable that and rely on lsp-format-buffer or region manually which is what most people do

ericdallo20:03:12

(setq lsp-enable-indentation nil)

eval-on-point20:03:16

cool, that is what I noticed. There may be some low hanging fruit in the clojure-align function that may reduce the number of necessary calls to indent-region

ericdallo20:03:10

yeah, there are probably quick wins in cljfmt as well

eval-on-point20:03:42

thanks for confirming!

eval-on-point21:03:15

just FYI, looks like there may be a solution that would move this to a single cljfmt call: [align associative (Attempt to solve issue #36) by reutsharabani 路 Pull Request #299 路 weavejester/cljfmt](https://github.com/weavejester/cljfmt/pull/299)

ericdallo21:03:50

ah yea, I'm following that issue 馃槢 really looking forward to have align associative in cljfmt, it's the only big feature I miss from cljfmt

eval-on-point21:03:39

last thing would be column limit, which I think would probably end the split-braining between cljfmt and zprint

ericdallo21:03:23

oh, that'd be nice indeed

ericdallo21:03:01

I do have in my backlog add support for zprint as formatting provider because of those things cljfmt doesn't have

ericdallo21:03:23

but if cljfmt manages to fix at least the vertical align, would be really good