Fork me on GitHub
#lsp
<
2023-03-16
>
borkdude15:03:15

I'm trying to run clojure-lsp with clj-kondo enabled (which I usually run separately, so I disable it in lsp normally). I have the same problem as before, that warnings stay there until I save the file.

borkdude15:03:25

Also warnings don't seem to appear until I save the file

2
borkdude15:03:53

If this is the standard behavior, I don't understand how people put up with this

borkdude16:03:24

@U0BUV7XSA does the + mean you have the same behavior?

borkdude16:03:09

I'll switch back to running clj-kondo separately because I can't work like that ;)

ericdallo16:03:31

It's not standard behavior and don't know any config to behave like that

ericdallo16:03:49

If you share your config I can take a look in the weekend

snoe16:03:17

I do have the same, it's been like this for at least a year

lassemaatta16:03:46

is this something related to flycheck-check-syntax-automatically? I know I've fiddled with it to fine tune how/when the errors are refreshed

ericdallo16:03:47

Server logs will tell if it's server not publishing diagnostics or editor not updating the UI

borkdude16:03:50

FWIW with clj-kondo I also use flycheck, but on the buffer, not on the saved file

borkdude16:03:19

flycheck-check-syntax-automatically is a variable defined in 'flycheck.el'.

Its value is (save idle-change new-line mode-enabled)

borkdude16:03:12

all packages are in the elpa dir already

borkdude16:03:25

you just have to move your config aside and load mine

borkdude16:03:51

oh lol, it seems it just takes a ridiculous long time before stuff updates

snoe16:03:43

that's weird because I can force open with :e in nvim and the updates appear at once

borkdude16:03:55

maybe it has to do with

company-idle-delay 2
      lsp-idle-delay 2
      
?

borkdude16:03:14

I'll try without

borkdude16:03:52

still slow as hell

borkdude16:03:59

could it be that this is slowing down?

(setq garbage-collection-messages t)

borkdude16:03:54

I guess I'll just have to wait a little before stuff updates...

borkdude16:03:02

"raw" clj-kondo is much snappier

ericdallo19:03:05

this is a example of how it behaves on my emacs (I'm not saving the buffer any time)

ericdallo19:03:41

I can take a look and try your config, but only on the weekend, I'm a little bit busy this week

borkdude20:03:27

I think it works now, but it's much slower than when I use clj-kondo directly via flycheck. I wonder if it's my setup of if clojure-lsp is just showing the diagnostics slower, which imo slows me down

borkdude20:03:52

but we'll see

ericdallo20:03:11

lsp-idle controls that, I have mine lower than default, I suggest trying with lower values (check my config)

ericdallo13:03:29

@U04V15CAJ I gave it a try with your config and here are my points: • I disabled the flycheck-clj-kondo prelude module and removed require, set lsp-idle-delay to 0.2 • Removed the line lsp-diagnostics-provider :none Besides that, your config looks Ok (some overrides of variables that already have that default value in the package, but not a problem though) That made the feedback better, but not as good as my gif (I'd say it's taking 300ms for yours while mine takes 200ms), not sure why, but your emacs looks slower overall than mine (opening, files, loading stuff etc), maybe related to doom optimizations. Also, I found flycheck-pos-tip that differently than lsp-ui only show the message if you hover over the errors, not only the lines, but that may be a desired behavior of yours. The syntax highlight from hover also seems to take 1 or 2 seconds to appear, pretty odd to me, it should take 0.2 seconds as well

borkdude13:03:06

@UKFSJSM38 I pointed you to a branch where I already had done those two bullet points

👍 2
borkdude13:03:58

thanks for looking into it

ericdallo13:03:45

also, we have now a M-x lsp-start-plain which may help testing those kind of configs issues easier

borkdude13:03:14

what is that?

ericdallo13:03:55

it will start a new emacs session with base config (you can add more configs to that), so you can check if it's a package conflict or some other emacs config you have configured

borkdude10:03:10

Running clj-kondo via flycheck (emacs) separately from clojure-lsp / lsp-mode is so much snappier, I'll continue doing so. Maybe I'll find the reason one day why it's so laggy with lsp-mode / clojure-lsp but even with lsp-start-plain it's laggy. Also, I didn't get any linting outside of projects, a feature which I use quite often for quickly debugging things (e.g. in /tmp/foo.clj) And the squiggles sometimes spanned entire expressions whereas with flycheck + clj-kondo they are just at the first character of an expression. In summary, I see the following benefits with running flycheck-clj-kondo (emacs) separately: • more instant, less laggy • linting for individual clojure files, even outside of projects • less overwhelming squiggles • you can use a newer version of clj-kondo than what is bundled with clojure-lsp

borkdude10:03:35

Maybe I should also try eglot

otfrom10:03:59

And flymake in newer emacs potentially

borkdude10:03:19

does lsp-mode use flymake? if not, how would it help?

borkdude10:03:13

(lsp-mode says flycheck is recommended in their README)

borkdude10:03:57

I have no problems with flycheck btw, flycheck-clj-kondo is using it and the feedback is instant. When I type an unresolved symbol, the feedback is there almost instantly, whereas via lsp-mode it takes like half a second or so before I see it (and before it disappears)

👍 2
borkdude11:03:37

Trying eglot now. It has the same lagginess.

borkdude11:03:28

I found that there were no docs mentioning clojure-lsp at all in clj-kondo but I updated them with my own findings: https://github.com/clj-kondo/clj-kondo/blob/master/doc/editor-integration.md#clojure-lsp

lassemaatta11:03:32

If one takes the (setq lsp-diagnostics-provider :none) route, does one also lose the :clojure-lsp/unused-public-var linting (which I find quite useful) provided through clojure-lsp?

borkdude11:03:59

yes, but I enable lens-mode which already tells me how many references there are to that var. Also there is https://github.com/borkdude/carve which you can use for this. And you can still run clojure-lsp as a command line tool to lint your project too.

borkdude11:03:07

Perhaps there is a way to get this linter into clj-kondo proper, but this requires the concept of "I've seen all the code that is relevant to deciding if this var is used anywhere", which e.g. carve does

borkdude11:03:56

updated the docs with that consideration

👍 2
ericdallo15:03:45

I still think there is something wrong with your config, even with with lsp-start-pain you still need to set lsp-idle-time to make sp-mode work faster. I would like to avoid recommend not using clojure-lsp diagnostics for some reasons: • you lose any extra linters like unused-public-var, I know you can rely on lens but a squiggle showing that in problems area is better than you don't noticing it and leaving the functions there and only when seeing the lens count of the function you would notice • There are more linters than clj-kondo like clj-dependency, there are few usages but at least for companies that have standards on projects related to namespace dependency that helps a lot. • I can see issues happening because people are using a third tool kondo externally (like conflicts between flyckeck and LSP and etc that we already had in the past) • Performance: we will call kondo twice, clojure-lsp still calls kondo for analysis, and even disabling findings, there will still have code being called twice that could be avoid, may worth mentioning in the docs I know you have your reasons to use clj-kondo, that's ok, but we could try focus on the root cause, lsp-mode is used by lots of other langs and the diagnostics feedback is on of it's core features that work well on most lsps

borkdude15:03:15

I have documented the losing of the extra linters, so people can decide for themselves. Performance: getting feedback quicker is what matters to me. That lsp is going stuff in the background is fine.

borkdude15:03:45

I want people to have the best clj-kondo experience, the lag that I have with it via clojure-lsp is less than optimal, so I'm going to recommend what works best for clj-kondo

ericdallo15:03:21

Maybe we could even improve kondo integration like calling it for findings and doing analysis stuff later, since we pass a lot of analysis configs that may affect performance for that call

ericdallo15:03:55

Could you record your lag? How many Ms approximately it is?

borkdude15:03:15

I have posted two gifs that show the lag vs raw clj-kondo, even with eglot

ericdallo15:03:17

that may be related to the debounce we do on server side https://github.com/clojure-lsp/clojure-lsp/blob/master/cli/src/clojure_lsp/server.clj#L36 of 100ms, we could try to decrease it and check how well behaves, we had it higher in the past and improved to 100ms, but I don't record trying even lower values

ericdallo15:03:32

changes debounce ms as well, as it's the time we will wait after user input to trigger kondo call. that may be offender c/c @U07M2C8TT in case any suggestions, we touched that code and made some refactors a year a go

borkdude15:03:56

@UKFSJSM38 another thing that bugged me was the overwhelming squiggles under the whole expression. with vanilla clj-kondo + flycheck I see this: This is how I always intentioned it. When I wrote an lsp server for clj-kondo in visual studio I noticed it would underline the whole expression, which I corrected here: https://github.com/clj-kondo/clj-kondo.lsp/blob/9db9ec3be0d5aeca8b76097010eeee4b2c4e2fe3/server/src/clj_kondo/lsp_server/impl/server.clj#L82-L88 I think clojure-lsp should do the same

ericdallo15:03:16

one another thing we can test to check how much time we are losing in clj-kondo communication is to call clj-kondo asking only findings (the way flyckeck-clj-kondo does) and compare with passing all analysis options clojure-lsp pass, if we find a considerable time spent, we could try to improve both to support a async analysis vs findings calls. > another thing that bugged me was the overwhelming That was a intentional change in the past because of performance issues using rewrite-clj there IIRC, we could try to change it again and check, https://github.com/clojure-lsp/clojure-lsp/blob/master/lib/src/clojure_lsp/feature/diagnostics.clj#L78-L81

borkdude15:03:15

performance issues with rewrite-clj? the clj-kondo server isn't using rewrite-clj

borkdude15:03:28

it's just a lookup in a string, 1 character, blazing fast

ericdallo15:03:29

will create a issue for that one, i think the performance was related to another thing

ericdallo15:03:01

yeah, I think we are really trying to use the whole expression, but I can see how convenient it is to have only in the start of the expr

snoe15:03:02

squiggles like that should be an option, i think as default it's a poorer experience, too easy to miss.

ericdallo15:03:21

yep, that was the reason ☝️

ericdallo15:03:39

a option with different default makes sense

borkdude15:03:14

I could live with that

borkdude15:03:47

if I knew that people were going to see this, I'd much rather moved the warning on the def symbol instead

borkdude16:03:36

the reason it's like this is that joker did a similar thing for invalid arities and I just borrowed that idea and it looked good to me in vanilla flycheck

👍 2
ericdallo16:03:37

@U04V15CAJ I made some tests with the debounce of diagnostics and changes ms, tested with 25ms for diagnostics and 50 for changes in clojure-lsp project. The improvevement is considerable (behaving equal to flycheck-clj-kondo AFAICS) on smaller buffers like call_hierarchy.clj and a little bit in bigger buffers leaving the bottleneck to clj-kondo call. For bigger buffers the call takes ~260ms while small buffers 60ms, so probably there's room for the findings async support where we could call clj-kondo twice, one for findings and another for analysis, we could pass info from the first call to the second one, but would require extra work on that

borkdude16:03:37

@UKFSJSM38 I can test a branch at some point, with my local clojure-lsp-dev script

borkdude16:03:33

I don't see much difference

ericdallo16:03:48

Even on smaller buffers?

borkdude16:03:23

this buffer is 200 lines

borkdude16:03:46

it also takes time before errors that should not be errors anymore disappear

borkdude16:03:28

let me also record again with vanilla clj-kondo

ericdallo16:03:32

From your gif it seems it's taking way more time than mine, maybe check server logs and see how much time the new log I added says

borkdude16:03:08

ok, I'll switch back

ericdallo16:03:40

Are you sure you a re using the branch? I don't see the new log

borkdude16:03:36

good call, I was having this commented out facepalm

lsp-clojure-custom-server-command '("/Users/borkdude/bin/clojure-lsp-dev")

😅 2
borkdude16:03:43

I'll restart

borkdude16:03:51

gist updated

borkdude16:03:57

I'll also try lsp-plain

ericdallo16:03:23

So, it's taking 50ms, which is pretty fast, but you also need to decrease lsp-idle-time to 0.05, which was what I used

ericdallo16:03:12

We may or not face other performance issues, but it's a good test

borkdude16:03:34

lsp-plain is just as slow here

borkdude16:03:52

I'll decrease lsp-idle-time now

👍 2
borkdude16:03:25

do you mean idle-delay?

borkdude16:03:11

I can confirm that with the idle-delay it's much better

ericdallo16:03:24

TBH I never did heavy tests decreasing that variable that low and there are LSP servers that may face performance issues, but maybe works well with clojure-lsp :)

borkdude16:03:41

The reason the spanning squiggles are also bothering me is that I'm spammed with messages while typing, which is not the case when the warning is concentrated on one character. It's just too much

ericdallo16:03:44

Yes, after working years with that setup I'm starting to feel the same @U04V15CAJ, new people kind of lost seeing lots of messages instead of focusing on only one

ericdallo16:03:14

I'll work on that setting support

borkdude16:03:27

cool! after that, the only thing left is:

Linting still works for files outside of projects
but I can probably figure a way around that, or would it be possible to also fix this with clojure-lsp?

ericdallo16:03:32

Could you elaborate that? If lsp-mode is enabled on a buffer, clojure-lsp should also lint that file

borkdude16:03:31

I have the (maybe bad) habit of writing files in /tmp/foo.clj to quickly try out things (both for kondo and babashka) and I like that I have linting there

borkdude16:03:43

but maybe I can just change my habit to ~/dev/scratch-project

ericdallo16:03:49

But linting should work for that as well, I do the same but usually add to a folder /tmp/my-test/foo.clj and if I like to test anything that needs a valid classpath I just add a deps.edn to there

borkdude16:03:25

yeah, if you add a directory in tmp, then yes

borkdude16:03:31

but this is just a minor issue I guess

ericdallo16:03:09

what happens if you don't add that directory? no squiggles at all?

borkdude16:03:38

then I won't start lsp since it will treat my whole /tmp folder as a project, which I've had problems with in the past

borkdude16:03:26

is it possible to set lsp-idle-delay 0.05 based on clojure-mode, and it will remain to be the default in other modes?

ericdallo16:03:27

hum, if you don't have a deps.edn or anything at /tmp clojure-lsp will start as single file mode

ericdallo16:03:44

I think so, with setq-local

borkdude16:03:45

> hum, if you don't have a deps.edn or anything at /tmp clojure-lsp will start as single file mode isn't working for me, but we can focus on this later

👍 2
ericdallo12:03:26

An update: I've been using that clojure-lsp branch with lsp-idle-delay at 0.05 and it's working great (even with lsp dart which I use from time to time), so those are good news :) I'll keep testing a little bit and should merge the changes in clojure-lsp then

borkdude12:03:48

also with the more minimal squiggles? 😃

ericdallo12:03:07

Yes, I'll work on that option!

💯 2
ericdallo23:03:04

Done on master

borkdude09:03:50

@UKFSJSM38 Thank you, I'll try it out!

borkdude15:03:58

@UKFSJSM38 I noticed it's not entirely according to what vanilla flycheck does: the smaller squiggles should only apply to a "container" like a list, vector or map (which can be detected with charAt equals (, [ or {))

borkdude15:03:01

not to a symbol

borkdude15:03:50

but it's not a major problem to me, I find this ok too

borkdude16:03:55

hm yeah, it bother me a tiny bit, this is how it looks :)

ericdallo17:03:38

Pushed a fix

borkdude17:03:39

$ git pull upstream master
lsp-workspace-restart
works!

🎉 1
borkdude12:03:48

@UKFSJSM38 I'm very happy with the latest changes, thanks again

ericdallo13:03:30

Awesome, glad it's better!

lassemaatta13:03:01

clojure-lsp - the finest and tiniest of squiggles

borkdude13:03:18

like clj-kondo intended ;)

borkdude10:03:10

Running clj-kondo via flycheck (emacs) separately from clojure-lsp / lsp-mode is so much snappier, I'll continue doing so. Maybe I'll find the reason one day why it's so laggy with lsp-mode / clojure-lsp but even with lsp-start-plain it's laggy. Also, I didn't get any linting outside of projects, a feature which I use quite often for quickly debugging things (e.g. in /tmp/foo.clj) And the squiggles sometimes spanned entire expressions whereas with flycheck + clj-kondo they are just at the first character of an expression. In summary, I see the following benefits with running flycheck-clj-kondo (emacs) separately: • more instant, less laggy • linting for individual clojure files, even outside of projects • less overwhelming squiggles • you can use a newer version of clj-kondo than what is bundled with clojure-lsp