Fork me on GitHub

Hi. Is it possible to have a single lsp-server for multiple projects? So that lsp-find-references works across all projects? Can you give me a hint how to configure this in (Doom) Emacs?

Erick G. Islas Osuna13:05:31

As far as I know, currently is not possible but if I am right, @UKFSJSM38 was working on this feature


It's possible and quite easy for deps.edn projects, for lein project it depends on the project arch, the 2 things required to make it work are: • Configure classpaths correctly where all deps for all subproject would be returned In a single classpath • Configure source-paths in a way all sub-projects are available The clojure-lsp project for example is a single repo with multiple projects inside. If you share your project arch + project.clj/deps.edn I can help, if it's a public project, it will be easier to understand it


Polylith is another example that works with clojure-lsp importing a single project root as well


you could also write a little shell script to collect all the classpaths and use project-specs


yeah, I'd avise customizing project specs as last resources, source-aliases and source-paths are meant for that


well, depends on what multiple projects means. It's important to show that we have escape hatches.

👍 1

I thkink my problem is Emacs. All projects are it's own git repos (with deps.edn). And Emacs starts a new lsp-server for every project. Any ideas how to prevent this?


yes, you need to configure the project root properly on lsp-mode, try lsp-workspace-folders-remove and then lsp and choose the correct project root


@UKFSJSM38 What do you mean by "correct project root"? I have at least two clojure projects, wich are it's own git repos. Both side by side: /p/my-app and /p/mylib. I have configured a deps alias in myapp with :extra-deps :local/root to mylib. When opening myapp , Emacs starts a lsp server. It recognizes the reference and I can even jump to mylib. But then Emacs starts another lsp server. And this one has no reference to myapp. Do you know if it is possible to configure Emacs so that it uses only one lsp server for both (or for all) projects?


Yes, this happens because lsp-mode thinks mylib is another project, you should remove it from lsp-mode, and when lsp-mode asks it again, you choose to not import that project


But if you intend to work on mylib and not my app, that's not possible AFAIK


Ok, Emacs does not start another lsp-server for /p/mylib which is fine. But then buffers in mylib have no lsp-server at all and the lsp commands do not work. 😞


Is there a command to connect the current project with a running lsp-server?


hum, yes, I think that is expected unfortunately, not sure there is a good workaround for that :/ > Is there a command to connect the current project with a running lsp-server? no


maybe you could move both projects to a /p/foo/myapp and /p/foo/mylib , have a deps.edn on /p/foo and import it as the root

👆 1

then you would have all you want for both projects in a single process


otherwise, I think having 2 process for each one is the way


I tried this already. But Emacs (projectile) stands in the way. It treats each git repo as it's own project. And when "forcing" both repos into the parent project using .dir-locals.el, commands like projectile-find-file don't work, since these internally use git ls-files.


Where do you think is the missing feature? In lsp-mode? In clojure-lsp?


I would imagine to have somethink like a lsp-server-reuse-id configured in my projects. And if two projects have the same id they would use the same lsp-server.


hum, for that one sounds like some misconfiguration on projectile, does it work if you projectile-remove-known-project ?


yeah, but there is no id feature for lsp at all, it'd need to be something custom not following spec I think


you can fall back to project-spec


But lsp supports multi-root, doesn't it?


@U0BUV7XSA I think the issue is more on client side than server


I have tried this in VSCode. I added the "folders" /p/mylib and then /p/myapp. And it seams they use only one lsp-server. I can jump from myapp to mylib and back via "references. So clojure-lsp is very capable of serving multiple directories without a common parent directory. So there must be a part which ignores the ability to set the directories for the lsp "workspace" and instead automatically creates a "workspace" whith only the the root dir of the project which is provided by projectile. Do you think, I am on the right path? Is it lsp-mode?


I have found a way to add buffers from anywhere to the same lsp-session. When opening a new buffer, Emacs prompts with xyz.clj is not part of any project. Select action: By answering this with I=>Import project by selecting root directory interactively and providing always the same dummy project /p/all-clojure , Emacs starts a single lsp-server / single lsp-session. Then I can open a different buffer from a different project and "bind" it to the same session. Then I can navigate them all using lsp-find-definition and lsp-find-references. The big issue: Emacs prompts for every new buffer with this question and I have to provide always the same answer. Is there a way to automatically add all new buffers to the p/all-clojure project?


I have discovered a hack that works: (defun lsp-find-session-folder (session file-name) "/p/all-clojure")


yeah, besides that hack I don't think it's possible, glad you found a workaround :)


Thank you very much for your help! I think it would require only a small change in lsp-mode so that it supports a behavior more like VSCode for multiple "folders". I have filed a feature request:

👍 1