How do I retrieve the client <-> server log?
check the lsp-log-io
section: https://emacs-lsp.github.io/lsp-mode/page/troubleshooting/
Thanks. Filed here: https://github.com/clojure-lsp/clojure-lsp/issues/332
Thank you!
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.Yes, you can (setq lsp-headerline-breadcrumb-enable nil)
For more details, check https://emacs-lsp.github.io/lsp-mode/tutorials/how-to-turn-off/
Oh, I saw that variable but I thought it kept the mode enabled with the breadcrumbs invisible. Ill try it.
thanks
works great
๐
Does clojure-lsp
conflict in any way with clj-refactor
?
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/
Yeah, I noticed similar functions. I might just replace clj-refactor with LSP.
Thanks again ๐
Thank you for the sponsor @nicdaoraf โค๏ธ
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
No problem, that support already helps a lot ๐
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 :(
There are a lot of things that may cause that: https://emacs-lsp.github.io/lsp-mode/page/performance/
Like, emacs version, lsp-doctor
, and other missing tweaks
I'll try
It's a big file though, 2000 lines almost.
Yeah, I'm trying here but it works for me well There is something that we could improve though related to file changes
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
BTW, i use Emacs Gcc, which is very fast compared with other emacs versions
I have emacs 27.1 with native json support and checked most of these things, still very slow
Chech the /tmp/clojure-lsp.out log, we print the ms
of each lsp function
otherwise is a lsp-mode issue
I mean, so slow that my CPU fans are making noise and I can't do anything
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?this looks a old session log
check lsp-clojure-server-info
it should has a log-path
{: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"}
tail log-file
and reproduce the slowness
https://gist.github.com/borkdude/9162c9bed4fca8722f7ca964244d82ea :didChange 14 seconds?
yeah, that's the issue
for me takes 1s though
it was a recent feature
When you change a function arity, it re scan all the references of that file
I tested with your analyze-children
function and it took 1s
This slowness happens only when changing function arity? otherwise it could be a performance issue on clojure-lsp
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 upIt's a performance issue indeed, we should not re analyze anything in this case
I'll add a feature flag for that disabled by default and focus on improve it soon
that should fix for your case for now
Can't linting / analyzing be async? It should never slow down my typing imo.
In clojure-lsp yes, it could
this could be another improvement indeed
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
(this is for all of the source dir even)
We lint all the reference files
this way if user go to a referenced file and the function arity was changed it will have the most updated lint
Why is this? They didn't change?
imagine this case:
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 nowif 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
yes, of course, clj-kondo already takes care of this itself.
imo you should only lint/analyze the current file
but if analyze only the current file, clj-kondo will not return findings of the other files
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
if I lint with text
let me test it so
But this is a old clojure-lsp issue
why should clj-kondo returning warnings for other files? you will see those warnings when you visit the other file
not really, because the diagnostics are not updated when visiting a file
only when changing it
what we would need to do is: when changing a.clj
publish diagnostics for b.clj
also
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
yeah, that should be considered too, I'll disable that as default, we may need to think more about that as a improvement
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
You could add a log here: https://github.com/clojure-lsp/clojure-lsp/blob/master/src/clojure_lsp/feature/file_management.clj#L62
I was going to look into the arglist issue for you, but this is now taking up my time instead ;)
I'm adding a flag to that right now, disabled as default
I'lll work on the arglist issue first
hahaha,sorry about that
can you also add the analyzed files to the log output perhaps?
I'll then try that from a branch which I will compile locally
Yes, I can add a debug log
Oh, somehow I could reproduce the 14s issue
that's incredible not usable hahaha
the issue is waiting sync for analyzing each reference indeed
well, will commit the log with the flag turned off
I noticed a bug on that, we are analysing the same uri multiple times ๐
Maybe you can also apply some debouncing, e.g. when the user types again, the previous requests get cancelled?
lsp-mode should already handles that
ok
Also I found that the didChange on clojure-lsp could be complete async (confirming with lsp-mode folks)
@ericdallo This was added by snoe: https://github.com/clojure-lsp/clojure-lsp/issues/324#issuecomment-782887656 Isn't this what you need here?
@borkdude yes, I use that, but is not the same
that return all the available signatures for a function
we'd need each arg of a signature
to know if user is hovering over a
or b
ins a (foo 1 2)
function
from a (defn foo [a b])
var-definition
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?
hum, I think parsing would solve, not sure it'd solve for all cases (`& rest`)
user=> (edn/read-string "[a b {:keys [:foo]}]")
[a b {:keys [:foo]}]
user=> (edn/read-string "[a b & xs]")
[a b & xs]
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 onebut we could also change :arglist-strs
to [["x" "y"]]
instead of [["x y"]]
, would that make sense?
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
yeah, I think you should just skip the &
as this is a special case
(foo 1 2)
=> 2 children
then I could (nth paramters (-> children dec))
so just parse to EDN and filter on &
should work for 99% of cases
I think so
I'll give a try
Edamame also works here btw, you can resolve aliases to a dummy namespace
edamame already comes with clj-kondo as a dependency
user=> (e/parse-string "{::str/keys [:a]}" {:auto-resolve (fn [ns] (symbol ns))})
#:str{:keys [:a]}
or even:
user=> (e/parse-string "{::str/keys [:a]}" {:auto-resolve (fn [ns] (symbol (str ":" ns)))})
#::str{:keys [:a]}
to fake it more ;)nice, this should work
I''ll merge the performance fix, made some tests and it really improved the performance for analyzer/impl.clj file ๐
๐
That works like a charm https://github.com/clojure-lsp/clojure-lsp/issues/324#issuecomment-782889893 โจ
Thank you!
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?
Yeah, I don't get it that commit too ๐ it seems @dharrigan made a rebase with his branch and because of the
Fixes clojure-lsp#324
comment it linked it somehowbut that was done before our conversation of today @borkdude
ah ok
: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 ๐
Hmm, I don't seem to have the signature help.
Even despite stealing this from your dotfiles @ericdallo (setq lsp-signature-function 'lsp-signature-posframe)
Also, how do I remove the file paths? (You don't have them)
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
Ah! It works I see. I had the expectation that it would come up automatically without having to invoke anything.
yeah, that's what I would expect too, like in cider
Is there a way to edit the faces so that the current arg is colored more obviously?
Tรด come automatically we d need to pass to client a character that it'll know that should show the signature
Like ( for java constructors
> yeah, that's what I would expect too, like in cider Oh, I didnt know cider does this ๐ฎ
But in clojure there isn't a character common for that
Maybe check in cider.el how they are doing this?
Cider is specific for clojure, they are probably checking if it's a function arg
Lsp must be generic :/
Sรณ client doesn't know that, it can only pass the character that user is inputting
ah yes, I see, you are not controlling the client
Ah, I see. Performance-aside, it can be "every char" being typed?
Exactly, the lap client is generic for multiple languages, so it can only do things that follow the lsp spec
Yes @nicdaoraf, but that would show the signature everytime, even on non sense places
nonsense places like fns without overloads?
Like, show the signature in every keystroke
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)
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
Yeah, I agree that would perfect for clojure, but I could not find a character that makes sense
( probably is another trigger char for ts
Actually, can't (
be the trigger for Clojure too?
No, because the function comes after it not before
Sรณ we wouldn't know the function name when typed (
Ah, I see. I guess they didnt have Lisps in mind when they designed the protocol (I mean MS)
I can re check the spec but I could not find anything to work that with clojure
Is this it?
Hum, maybe we could use (
as trigger and space as retrigger?
Yes
yeah :)
Also not sure the context field can help us
> 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 (
?
setup at (, trigger at space, is this possible?
I think if server return nil ( when don't know the function) a retrigger will no twork
But I can test it
maybe the server can remember some kind of state, the user typed '(` and then the next space will return something?
sounds brittle
As a retrigger probably works only when user close the window but the signature is valid
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
TLDR for context field?
Is a field containing the information about the current signature, maybe can help us Check the spec for more info
@ericdallo 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)?
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
@ericdallo 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?
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.
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
I have already gone through this
I'll check the logs
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
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
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
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.
I will try to reproduce it, this is not normal
notify-references-on-change is already off by default
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?
I'm trying to force lsp to work with .cljc files
unsuccessfully
; (
What is your issue @huxley ?
Yes, by default it uses emacs lv
to show in the bottoom similar to eldoc
in files other than .cljc works like gold
don't really see anything :/
I think you need to configure lsp-mode
doom-emacs/spaceemacs already do that
how you are configuring lsp-mode? use-package
?
should I install anything else beyond lsp-mode?
you need to trigger it manually with lsp-signature-activate
or set lsp-signature-auto-activate
to :after-completion
to show after completion
I use doom emacs
(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))
wow, cool, thanks
I don't have anything else
try adding :hook ((clojure-mode . lsp)
or :hook ((clojurec-mode . lsp)
BTW the performance adding 1
looks normal to me, but not sure realted to emacsGcc good performance
Press 1 and hold the key
that's what I did
works, thanks!
I thought there was nothing but lsp-mode
, but there is also lsp
itself
Actually it looks the same performance if LSP is disabled
probably this is missing from doom config
btw, writing in clojure was awesome, but with lsp it's even better ; )
thanks ๐
Not sure what we could do to improve that, the logs looks ok to me
I'd suggest asking help on lsp-mode discord ๐
@yyoncho knows better ways to trace those performance issues on Emacs
you are inside the clj-kondo project in analyzer.clj (about 2000 lines long)?
Yep, on the comment section
you're welcome
ok, I'll try on discord later this week, thanks
clojure-lsp
is on Github trending repos of Clojure ๐ ๐ :clojure-lsp: Thanks all!
https://github.com/trending/clojure?since=monthly
I donโt think thatโs missing from Doom. @huxley, did you add (clojure +lsp)
to init.el
in addition to lsp
?