Hi! I'm using clojure-lsp with lsp-mode in emacs. I have a clojure project with with the following directory structure:
λ tree -L2
├── .git
├── deps.edn
├── lib
│ ├── deps.edn
│ ├── src
│ └── test
├── src
└── test
In short: the main "service" code is based in the project root with the root deps.edn having
{:paths ["src"],
:deps {my-project/lib {:local/root "lib"}}}
So the service code references the lib code via the deps.edn file.
When I open a file in lib/src, an lsp workspace starts up and for the most part works as I would expect it to. However, the xrefs only point to references in lib/src, src, or test. Usages in lib/test are ignored. My naïve understanding of what's going on is that the lsp workspace sees the root of the project as the top level, makes an assumption that the paths of the project are src and test, and maybe also sees that the deps.edn has a dep for lib , and picks that up, too. lib/test gets skipped. This happens even if the very first file I open in the project is in lib/src , so lsp hasn't even started up yet.
Is there a way for me to convince lsp that lib is it's own project/workspace?Yes, clojure-lsp project itself is a deps.edn mono repo like that. First thing is make sure lsp-mode imported only the project root as a workspace and not the inner as well, you can confirm that with lsp-workspaces-folders-remove
Then, make sure that clojure-lsp is considering the class path correctly, by default it spawns a clj -A:dev:test -Spath command to get the classpath
Cool. After running lsp-workspaces-folders-remove, I then had to re-identify the project as a project for lsp-mode. That seems to have done the trick.
When I opened a file in src it asked me to start a new project.
How can I now also have a (separate) lsp workspace in lib ?
Only importing lib folder, but I suggest you don't do that, clojure-lsp won't find things outside there
Well, when I'm in the context of the lib folder, that's really what I want. When I'm in the "outer" context, I should be able to jump to references in lib because it's a dependency. When I'm in lib, I really only want to be concerned about lib/src and lib/test. (That's the reason I have the inner lib directory. Does that make sense? Or am I missing something?
Yes makes sense, it's just that I don't think that would work perfectly, too many variables, lsp-mode clojure-lsp classpath, projectile etc Only testing and understanding what is not working
Ah.
Do you think it would be "easier" to have, say
λ tree -L2
├── .git
├── lib
│ ├── deps.edn
│ ├── src
│ └── test
└── service
├── deps.edn
├── src
└── test
where service/deps.edn references ../lib ?I guess it's a mini mono repo at that point.
Definitely, it's like https://github.com/clojure-lsp/clojure-lsp works with lib and cli subprojects where cli depends on lib
And I just import the root because it's easier and things just work
Cool. What's the top-level deps.edn file do for you in clojure-lsp?
It's the one that aggregates all subprojects and provide all dev paths in the dev alias, this is the one clojure-lsp read in the root when running the classpath command
Ah. Cheers. (For some reason my eyes missed the cli references in the top-level deps.)
Cool. I'll give that a shot. Thanks for letting me pick your brain.
is it possible to insert arbitrary namespaces into whatever body of namespace mappings lsp-clojure-add-missing-libspec references?
e.g., if i’ve typed (anomalies/anomaly? …) and i tell LSP to add the missing lib for that var, LSP will require cognitect.anomalies instead of myapp.anomalies — i’d prefer LSP required the latter instead.
It's recommended to not use the add-missing-libspec directly (or any refactor unless you know what you are doing), the best way is to use the code actions which suggest multiple found namespaces for an alias (In doom emacs it's SPC c a , lsp-execute-code-actions)
oh cool, that does what i wanted. i didn’t realize there was a porcelain/plumbing distinction there — thanks!
would it be possible to make the https://shadow-cljs.github.io/docs/UsersGuide.html#infer-externs into a lsp warning? Is this is a silly thing to want?
Makes sense to me, but looks like more like a clj-kondo improvement? C/c @borkdude
I think what drew is asking is if the shadow warnings could be picked up by the editor and lsp or flycheck or whatever could be that mechanism, right?
Hum got it, not sure when/where this check happen, but if there was a programatic way to get them would make it easier to integrate I suppose
Thanks bork and eric, thats some good initial feedback on the idea.