Fork me on GitHub
#lsp
<
2021-02-21
>
nmkip01:02:20

Hi!! Is there to turn off lsp-headerline-breadcrumb-mode? I copied this from the docs and the breadcrumb mode is enabled by default in my clojure buffers.

(use-package lsp-mode
    :ensure t
    :hook ((clojure-mode . lsp)
           (clojurec-mode . lsp)
           (clojurescript-mode . lsp))
    :config
    ;; add paths to your local installation of project mgmt tools, like lein
    (setenv "PATH" (concat
                    "/usr/local/bin" path-separator
                    (getenv "PATH")))
    (dolist (m '(clojure-mode
                 clojurec-mode
                 clojurescript-mode
                 clojurex-mode))
      (add-to-list 'lsp-language-id-configuration `(,m . "clojure")))
    (setq lsp-clojure-server-command '("bash" "-c" "clojure-lsp"))
    (lsp-headerline-breadcrumb-mode nil)) 
I guess I can add a hook and toggle it.

ericdallo01:02:45

Yes, you can (setq lsp-headerline-breadcrumb-enable nil)

nmkip01:02:05

Oh, I saw that variable but I thought it kept the mode enabled with the breadcrumbs invisible. Ill try it.

nmkip01:02:47

works great

nmkip03:02:34

Does clojure-lsp conflict in any way with clj-refactor?

ericdallo03:02:30

LSP replace most clj-refactor features, and AFAIK only conflicts with creating a new ns which can be solved like this tutorial explains: https://emacs-lsp.github.io/lsp-mode/tutorials/clojure-guide/

nmkip03:02:41

Yeah, I noticed similar functions. I might just replace clj-refactor with LSP.

nmkip03:02:37

Thanks again 😄

👍 3
ericdallo13:02:03

Thank you for the sponsor @nicdaoraf ❤️

anonimitoraf14:02:37

No worries 🙂 I appreciate all your efforts I'd contribute with code if I could but currently have a full-time job and a startup-ish with a friend

ericdallo14:02:13

No problem, that support already helps a lot 😉

catjam 3
borkdude15:02:15

lsp-mode becomes unbearably slow for me when developing clj-kondo itself (e.g. in clj_kondo/impl/analyzer.clj). So slow that I have to turn it off unfortunately, because I can't even type anymore :(

ericdallo15:02:58

Like, emacs version, lsp-doctor, and other missing tweaks

borkdude15:02:10

It's a big file though, 2000 lines almost.

ericdallo15:02:54

Yeah, I'm trying here but it works for me well There is something that we could improve though related to file changes

ericdallo15:02:48

but it's a corner case only when changing a function arity (that will trigger other scans in references), it should not make the experience that bad

ericdallo15:02:51

BTW, i use Emacs Gcc, which is very fast compared with other emacs versions

borkdude15:02:56

I have emacs 27.1 with native json support and checked most of these things, still very slow

ericdallo15:02:26

Chech the /tmp/clojure-lsp.out log, we print the ms of each lsp function

ericdallo15:02:39

otherwise is a lsp-mode issue

borkdude15:02:40

I mean, so slow that my CPU fans are making noise and I can't do anything

borkdude15:02:48

I am watching this:

$ tail -f /tmp/clojure-lsp.out
2021-02-20T11:32:36.922Z MBP2019.local INFO [clojure-lsp.main:350] - Shutting down
2021-02-20T11:32:37.213Z MBP2019.local INFO [clojure-lsp.main:355] - Exit
Nothing to see here?

ericdallo15:02:46

this looks a old session log

ericdallo15:02:53

check lsp-clojure-server-info

ericdallo15:02:02

it should has a log-path

borkdude15:02:40

{:project-root "file:///Users/borkdude/Dropbox/dev/clojure/clj-kondo",
 :project-settings {:auto-add-ns-to-new-files? false},
 :client-settings
 {:dependency-scheme "jar",
  :source-paths #{"src" "test"},
  :macro-defs {},
  :project-specs nil,
  :cljfmt {:indents {}},
  :document-formatting? true,
  :document-range-formatting? true},
 :port "NREPL only available on :debug profile compiled binary",
 :version "2021.02.19-00.19.27",
 :log-file
 "/var/folders/2m/h3cvrr1x4296p315vbk7m32c0000gp/T/clojure-lsp.3323505275673554799.out"}

ericdallo15:02:07

tail log-file and reproduce the slowness

ericdallo15:02:59

yeah, that's the issue

ericdallo15:02:05

for me takes 1s though

ericdallo15:02:16

it was a recent feature

ericdallo15:02:49

When you change a function arity, it re scan all the references of that file

ericdallo15:02:08

I tested with your analyze-children function and it took 1s

ericdallo15:02:45

This slowness happens only when changing function arity? otherwise it could be a performance issue on clojure-lsp

borkdude15:02:57

For example I'm just editing the comment form at the bottom of the file and I tried typing (+ 1 2 3):

(comment
  (+    )
  (parse-string "#js [1 2 3]"))
It takes 14 seconds before the space shows up

ericdallo15:02:34

It's a performance issue indeed, we should not re analyze anything in this case

ericdallo15:02:56

I'll add a feature flag for that disabled by default and focus on improve it soon

ericdallo15:02:01

that should fix for your case for now

borkdude15:02:50

Can't linting / analyzing be async? It should never slow down my typing imo.

ericdallo15:02:17

In clojure-lsp yes, it could

ericdallo15:02:24

this could be another improvement indeed

borkdude16:02:45

The question is also, why does it take 14 seconds ....

:didChange 14192ms
If I lint this file using clj-kondo only it takes 1 second:
$ time clj-kondo --config '{:output {:analysis {:locals true :keywords true} :format :edn}}' --lint src > /dev/null
clj-kondo --config  --lint src > /dev/null   1.08s  user 0.12s system 99% cpu 1.212 total

borkdude16:02:52

(this is for all of the source dir even)

ericdallo16:02:34

We lint all the reference files

ericdallo16:02:52

this way if user go to a referenced file and the function arity was changed it will have the most updated lint

borkdude16:02:53

Why is this? They didn't change?

ericdallo16:02:01

imagine this case:

ericdallo16:02:12

I have a.clj:

(defn foo [a b])
b.clj
(foo 1 2)
If I change the arity of foo, I want clj-kondo warn that (foo 1 2) has another arity now

ericdallo16:02:38

if we don't do that, user will notice that only if enter on b.clj change the buffer, and clj-kondo relint b.clj and notice that the arity changed

borkdude16:02:38

yes, of course, clj-kondo already takes care of this itself.

borkdude16:02:11

imo you should only lint/analyze the current file

ericdallo16:02:35

but if analyze only the current file, clj-kondo will not return findings of the other files

borkdude16:02:38

this is what clj-kondo itself has been doing, and lint warnings you will get when you visit the other files, because it persists through the cache

ericdallo16:02:39

if I lint with text

ericdallo16:02:55

let me test it so

ericdallo16:02:14

But this is a old clojure-lsp issue

borkdude16:02:17

why should clj-kondo returning warnings for other files? you will see those warnings when you visit the other file

ericdallo16:02:42

not really, because the diagnostics are not updated when visiting a file

ericdallo16:02:57

only when changing it

ericdallo16:02:19

what we would need to do is: when changing a.clj publish diagnostics for b.clj also

borkdude16:02:37

I am not interested in seeing lint warnings for other files than the current one. Supporting that is way too unperformant, this is why clj-kondo doesn't do that. If I opt out of linting via lsp-mode I also want to opt out of this slow behavior

ericdallo16:02:38

yeah, that should be considered too, I'll disable that as default, we may need to think more about that as a improvement

borkdude16:02:50

For now I'll have to disable lsp-mode for this project, as it's not workable unfortunately. Maybe I can see what clojure-lps is analyzing? Maybe it tries to analyze all my deps as well, by accident? This takes about 5-10 seconds on my machine

borkdude16:02:19

I was going to look into the arglist issue for you, but this is now taking up my time instead ;)

ericdallo16:02:27

I'm adding a flag to that right now, disabled as default

borkdude16:02:33

I'lll work on the arglist issue first

ericdallo16:02:37

hahaha,sorry about that

borkdude16:02:08

can you also add the analyzed files to the log output perhaps?

borkdude16:02:43

I'll then try that from a branch which I will compile locally

ericdallo16:02:48

Yes, I can add a debug log

ericdallo16:02:35

Oh, somehow I could reproduce the 14s issue

ericdallo16:02:48

that's incredible not usable hahaha

ericdallo16:02:02

the issue is waiting sync for analyzing each reference indeed

ericdallo16:02:14

well, will commit the log with the flag turned off

ericdallo16:02:32

I noticed a bug on that, we are analysing the same uri multiple times 🙂

borkdude16:02:38

Maybe you can also apply some debouncing, e.g. when the user types again, the previous requests get cancelled?

ericdallo16:02:09

lsp-mode should already handles that

ericdallo16:02:36

Also I found that the didChange on clojure-lsp could be complete async (confirming with lsp-mode folks)

ericdallo16:02:58

@U04V15CAJ yes, I use that, but is not the same

ericdallo16:02:09

that return all the available signatures for a function

ericdallo16:02:17

we'd need each arg of a signature

ericdallo16:02:49

to know if user is hovering over a or b ins a (foo 1 2)function

ericdallo16:02:24

from a (defn foo [a b]) var-definition

borkdude16:02:48

so you need the locations, or only the list? if you need only the list, I think you can parse the arglist-strs as edn?

ericdallo16:02:43

hum, I think parsing would solve, not sure it'd solve for all cases (`& rest`)

borkdude16:02:31

user=> (edn/read-string "[a b {:keys [:foo]}]")
[a b {:keys [:foo]}]
user=> (edn/read-string "[a b & xs]")
[a b & xs]

borkdude16:02:01

I think it could maybe fail on this:

user=> (edn/read-string "[{::str/keys [:x]}]")
Execution error at user/eval14 (REPL:1).
Invalid token: ::str/keys
but this is such a niche use case that you could maybe not support this one

borkdude16:02:00

but we could also change :arglist-strs to [["x" "y"]] instead of [["x y"]], would that make sense?

ericdallo16:02:16

what we would need is a list of the args like ["a" "b" "& rest"] this way I can count the children of the function usage with rewrite-clj and get the arg name via the index

borkdude16:02:57

yeah, I think you should just skip the & as this is a special case

ericdallo17:02:01

(foo 1 2) => 2 children then I could (nth paramters (-> children dec))

borkdude17:02:08

so just parse to EDN and filter on & should work for 99% of cases

ericdallo17:02:31

I'll give a try

borkdude17:02:21

Edamame also works here btw, you can resolve aliases to a dummy namespace

borkdude17:02:13

edamame already comes with clj-kondo as a dependency

borkdude17:02:34

user=> (e/parse-string "{::str/keys [:a]}" {:auto-resolve (fn [ns] (symbol ns))})
#:str{:keys [:a]}

borkdude17:02:19

or even:

user=> (e/parse-string "{::str/keys [:a]}" {:auto-resolve (fn [ns] (symbol (str ":" ns)))})
#::str{:keys [:a]}
to fake it more ;)

ericdallo17:02:43

nice, this should work

ericdallo17:02:03

I''ll merge the performance fix, made some tests and it really improved the performance for analyzer/impl.clj file 🙂

borkdude17:02:52

I'm not sure what the referenced commit below that comment here does: https://github.com/dharrigan/clojure-lsp/commit/581263159654838a7a0d5c6b8f1ec65977aba907 It seems like you're parsing the arglists yourself?

ericdallo17:02:01

Yeah, I don't get it that commit too 😅 it seems @U11EL3P9U made a rebase with his branch and because of the

Fixes clojure-lsp#324
comment it linked it somehow

ericdallo17:02:28

but that was done before our conversation of today @U04V15CAJ

ericdallo21:02:00

clojure-lsp Released https://github.com/clojure-lsp/clojure-lsp/releases/tag/2021.02.21-21.02.51 of clojure-lsp adding support for signatureHelp 🎉

clojure-lsp 9
borkdude21:02:29

@UKFSJSM38 I am trying it now. Performance seems better now in the big analyzer.clj file in clj-kondo. But when I type 1111 and keep typing ones in the comment block at the bottom, it's still lagging, i.e. it slows down my typing. Is there something that can be done about this?

borkdude21:02:38

It's as if I'm connected to a remote terminal with half a second of network lag. I think an editor tool should never slow the user down while typing.

ericdallo21:02:57

in clojure-lsp logs is there any method taking to much time? It turns out didChange is a notification and don't block user input, I suggest you follow performance section on lsp-mode as well

borkdude21:02:59

I have already gone through this

borkdude21:02:12

I'll check the logs

borkdude21:02:00

but since you could reproduce my previous issue, I suspect you will be able to reproduce this one too. it's the same, only less slow

borkdude21:02:28

2021-02-21T21:56:05.528Z MBP2019.local DEBUG [clojure-lsp.main:?] - :completion 329ms
2021-02-21T21:56:05.528Z MBP2019.local DEBUG [clojure-lsp.main:?] - :completion 330ms
2021-02-21T21:56:05.671Z MBP2019.local DEBUG [clojure-lsp.main:?] - :didChange 472ms

borkdude21:02:52

I tried finding the notify-references-on-change flag to see if I could turn this off but I can't find it anywhere in the code

borkdude22:02:33

Don't get me wrong, I think clojure-lsp is awesome but I will turn it off in clj-kondo again now, just can't work like this in this project.

ericdallo22:02:39

I will try to reproduce it, this is not normal

ericdallo22:02:17

notify-references-on-change is already off by default

borkdude22:02:41

Thanks a lot in advance. About the signatureHelp: does this also work without lsp-ui? E.g. show it in the mini-buffer, like cider does?

ericdallo22:02:03

Yes, by default it uses emacs lv to show in the bottoom similar to eldoc

borkdude22:02:25

don't really see anything :/

borkdude22:02:25

should I install anything else beyond lsp-mode?

ericdallo22:02:35

you need to trigger it manually with lsp-signature-activate

ericdallo22:02:49

or set lsp-signature-auto-activate to :after-completion to show after completion

borkdude22:02:06

wow, cool, thanks

ericdallo22:02:04

BTW the performance adding 1 looks normal to me, but not sure realted to emacsGcc good performance

borkdude22:02:24

Press 1 and hold the key

ericdallo22:02:04

that's what I did

ericdallo22:02:11

Actually it looks the same performance if LSP is disabled

ericdallo22:02:33

Not sure what we could do to improve that, the logs looks ok to me

ericdallo22:02:46

I'd suggest asking help on lsp-mode discord 😕

ericdallo22:02:23

@U5B6G208G knows better ways to trace those performance issues on Emacs

borkdude22:02:33

you are inside the clj-kondo project in analyzer.clj (about 2000 lines long)?

ericdallo22:02:44

Yep, on the comment section

borkdude22:02:24

ok, I'll try on discord later this week, thanks

👍 3
anonimitoraf08:02:33

Hmm, I don't seem to have the signature help. Even despite stealing this from your dotfiles @UKFSJSM38 (setq lsp-signature-function 'lsp-signature-posframe) Also, how do I remove the file paths? (You don't have them)

ericdallo10:02:07

That doesn't look signature help, but hover request. Try lsp-signature-activate and ame sure your have posframe installed with that config of mine

catjam 3
anonimitoraf11:02:31

Ah! It works I see. I had the expectation that it would come up automatically without having to invoke anything.

borkdude11:02:01

yeah, that's what I would expect too, like in cider

anonimitoraf11:02:05

Is there a way to edit the faces so that the current arg is colored more obviously?

ericdallo11:02:55

Tô come automatically we d need to pass to client a character that it'll know that should show the signature

ericdallo11:02:04

Like ( for java constructors

anonimitoraf11:02:18

> yeah, that's what I would expect too, like in cider Oh, I didnt know cider does this 😮

ericdallo11:02:29

But in clojure there isn't a character common for that

borkdude11:02:23

Maybe check in cider.el how they are doing this?

ericdallo11:02:57

Cider is specific for clojure, they are probably checking if it's a function arg

ericdallo11:02:06

Lsp must be generic :/

ericdallo11:02:40

Só client doesn't know that, it can only pass the character that user is inputting

borkdude11:02:44

ah yes, I see, you are not controlling the client

anonimitoraf11:02:20

Ah, I see. Performance-aside, it can be "every char" being typed?

ericdallo11:02:21

Exactly, the lap client is generic for multiple languages, so it can only do things that follow the lsp spec

ericdallo11:02:03

Yes @nicdaoraf, but that would show the signature everytime, even on non sense places

anonimitoraf11:02:35

nonsense places like fns without overloads?

ericdallo11:02:20

Like, show the signature in every keystroke

anonimitoraf11:02:14

Right. Actually, I write a lot of Typescript (usually via vscode) and signature help auto-pops up. But I've realized that the trigger char is probably , myFunc(arg1, arg2, arg3)

anonimitoraf11:02:39

Ok, anyways, workflow optimization that is probably not worth the effort* 🙂 C-S SPC isn't hard at all to press. So thanks for the explanation

ericdallo11:02:22

Yeah, I agree that would perfect for clojure, but I could not find a character that makes sense

ericdallo11:02:44

( probably is another trigger char for ts

anonimitoraf11:02:34

Actually, can't ( be the trigger for Clojure too?

ericdallo11:02:57

No, because the function comes after it not before

ericdallo11:02:14

Só we wouldn't know the function name when typed (

anonimitoraf11:02:53

Ah, I see. I guess they didnt have Lisps in mind when they designed the protocol (I mean MS)

ericdallo11:02:20

I can re check the spec but I could not find anything to work that with clojure

ericdallo11:02:59

Hum, maybe we could use ( as trigger and space as retrigger?

ericdallo11:02:12

Also not sure the context field can help us

anonimitoraf11:02:57

> Hum, maybe we could use `(` as trigger and space as retrigger? But as you said, you don't know the function name yet when you're only at (?

borkdude11:02:26

setup at (, trigger at space, is this possible?

ericdallo11:02:56

I think if server return nil ( when don't know the function) a retrigger will no twork

ericdallo11:02:01

But I can test it

borkdude11:02:17

maybe the server can remember some kind of state, the user typed '(` and then the next space will return something?

borkdude11:02:23

sounds brittle

ericdallo11:02:31

As a retrigger probably works only when user close the window but the signature is valid

ericdallo11:02:18

Yeah, that could leave to false positives, thats why we should use the client info, the context field maybe can be hacked to make that work

anonimitoraf11:02:08

TLDR for context field?

ericdallo11:02:49

Is a field containing the information about the current signature, maybe can help us Check the spec for more info

👍 3
borkdude11:02:32

@UKFSJSM38 clojure-lsp also has a rewrite-clj representation of the AST right? Can you use this to scan backwards to see which function call you are in (if any)?

thinking-face 3
ericdallo13:02:20

We already do that, we scan backward to get the function name, but when user type ( the function name doesn't exists yet, but when one type a space, it should exists

🎯 3
ribelo22:02:26

I'm trying to force lsp to work with .cljc files

ericdallo22:02:35

What is your issue @U0BBFDED7 ?

ribelo22:02:06

in files other than .cljc works like gold

ericdallo22:02:34

I think you need to configure lsp-mode

ericdallo22:02:42

doom-emacs/spaceemacs already do that

ericdallo22:02:53

how you are configuring lsp-mode? use-package?

ribelo22:02:27

I use doom emacs

ribelo22:02:58

(use-package! lsp-mode
  :defer t
  :config
  (setq! lsp-ui-sideline-enable t
         lsp-symbol-highlighting-skip-current nil
         lsp-vetur-language-features-code-actions nil
         lsp-ui-sideline-actions-icon nil
         lsp-ui-sideline-show-code-actions nil)
  (pushnew! lsp-file-watch-ignored-directories
            "[/\\\\]\\.cpcache\\'"
            "[/\\\\]\\.shadow-cljs\\'"
            "[/\\\\]\\resources\\'")
  (set-face-foreground 'lsp-face-highlight-read nil)
  (set-face-background 'lsp-face-highlight-read nil)
  (set-face-attribute 'lsp-face-highlight-read nil :weight 'extra-bold)
  (set-face-background 'markdown-code-face nil))

ribelo22:02:19

I don't have anything else

ericdallo22:02:04

try adding :hook ((clojure-mode . lsp)

ericdallo22:02:18

or :hook ((clojurec-mode . lsp)

ribelo22:02:25

works, thanks!

ribelo22:02:06

I thought there was nothing but lsp-mode, but there is also lsp itself

👍 3
ericdallo22:02:41

probably this is missing from doom config

ribelo22:02:41

btw, writing in clojure was awesome, but with lsp it's even better ; )

ribelo22:02:56

you're welcome

zane23:02:52

I don’t think that’s missing from Doom. @U0BBFDED7, did you add (clojure +lsp) to init.el in addition to lsp?

☝️ 3
ribelo00:02:15

like i said, lsp works for me in .clj and .cljs but not .cljc

ribelo22:02:35

unsuccessfully

ericdallo22:02:51

clojure-lsp is on Github trending repos of Clojure 😄 🎉 clojure-lsp Thanks all! https://github.com/trending/clojure?since=monthly

🎉 9
catjam 3
anonimitoraf03:02:18

lol, a bit weird that https://github.com/tonsky/FiraCode is in there too

😄 3