lsp

grzm 2025-01-30T20:54:32.421519Z

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?

ericdallo 2025-01-30T20:56:37.887519Z

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

ericdallo 2025-01-30T20:57:25.290969Z

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

grzm 2025-01-30T21:04:52.024299Z

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.

grzm 2025-01-30T21:05:22.942519Z

When I opened a file in src it asked me to start a new project.

grzm 2025-01-30T21:05:49.921709Z

How can I now also have a (separate) lsp workspace in lib ?

ericdallo 2025-01-30T21:09:51.157059Z

Only importing lib folder, but I suggest you don't do that, clojure-lsp won't find things outside there

grzm 2025-01-30T21:12:26.151779Z

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?

ericdallo 2025-01-30T21:13:48.914369Z

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

grzm 2025-01-30T21:14:29.839939Z

Ah.

grzm 2025-01-30T21:15:58.696969Z

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 ?

grzm 2025-01-30T21:16:50.770749Z

I guess it's a mini mono repo at that point.

ericdallo 2025-01-30T21:17:52.884419Z

Definitely, it's like https://github.com/clojure-lsp/clojure-lsp works with lib and cli subprojects where cli depends on lib

ericdallo 2025-01-30T21:18:08.145799Z

And I just import the root because it's easier and things just work

grzm 2025-01-30T21:19:24.927009Z

Cool. What's the top-level deps.edn file do for you in clojure-lsp?

ericdallo 2025-01-30T21:31:16.653979Z

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

grzm 2025-01-30T21:35:25.853929Z

Ah. Cheers. (For some reason my eyes missed the cli references in the top-level deps.)

grzm 2025-01-30T21:35:43.364379Z

Cool. I'll give that a shot. Thanks for letting me pick your brain.

👍 1
2025-01-30T21:19:39.090999Z

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.

ericdallo 2025-01-30T21:33:43.070519Z

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)

2025-01-30T21:37:52.625299Z

oh cool, that does what i wanted. i didn’t realize there was a porcelain/plumbing distinction there — thanks!

👍 1
Drew Verlee 2025-01-30T00:44:31.725639Z

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?

ericdallo 2025-01-30T12:20:55.841139Z

Makes sense to me, but looks like more like a clj-kondo improvement? C/c @borkdude

borkdude 2025-01-30T15:46:23.795379Z

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?

ericdallo 2025-01-30T15:56:06.574899Z

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

👀 1
Drew Verlee 2025-01-31T23:54:40.902829Z

Thanks bork and eric, thats some good initial feedback on the idea.