nvim-metals icon indicating copy to clipboard operation
nvim-metals copied to clipboard

How to handle switching "workspaces" in a single Neovim instance.

Open beem812 opened this issue 2 years ago • 6 comments

Describe the feature

Currently, when you open a scala file in one project and metals attaches and loads up, and then you switch to a file in a different scala project, metals maintains the project root from the first project it was loaded into. You can restart metals to pick up the correct project root, but it would be nice if nvim-metals noticed the change and recalculated the project root and picked up the correct scalafmt file and other config files. The example below is from the discord conversation about this topic.

├── mill-example
│  ├── build.sc
│  └── millexample
└── sbt-example
   ├── build.sbt
   ├── project
   └── src

Starting inside millexample and then switching to sbt-example leaves metals running off of the configuration files in mill-example.

Potential ways to implement

Per the discord comment, if nvim-metals recorded the current project root and was able to detect a new valid project root, the user could be prompted to restart metals, or perhaps have a config option to automatically restart metals upon detection of a new root. I'd prefer it to just take care of itself to match the workflow I'm coming from in emacs.

beem812 avatar Jan 01 '23 18:01 beem812

I'm wondering if there isn't some heavy lifting going on from the emacs "workspaces" in my other setup. I can flip between project and get correct type info from either project without restarting there which maybe suggests two running instances of metals? No idea if that's possible.

I may look into just working off terminal tabs for projects since that currently works out of the box and I just need to find a good interface for switching between them and opening new ones, something I think the vim community already has good options for.

beem812 avatar Jan 01 '23 19:01 beem812

Thanks for creating this @beem812!

I'm wondering if there isn't some heavy lifting going on from the emacs "workspaces" in my other setup.

I'm not incredibly familiar with how emacs handles this, but indeed in Neovim the idea of a workspace is pretty fluid seeing that it's just a bunch of buffers that are open and can be from all over the place. In nvim-metals we sort of artificially create a workspace since Metals itself needs this concept mainly to know where the root of the build is. Once it knows that, then everything is is good to go.

I can flip between project and get correct type info from either project without restarting there which maybe suggests two running instances of metals?

Yup exactly, in this scenario you have 2 different Metals processes running. You'd see the same behavior if you used something like tmux, opened a new pane, and opened another project. That's actually my current workflow, and one that seems to be pretty popular in the Neovim ecosystem.

With all that being said, we might be able to make this better in nvim-metals. Since it actually does calculate the root for every buffer and in theory if we detect that the root has changed, we could prompt the user to restart Metals. The tricky part then would be if you switch back and forth a bunch you'd be getting prompted all the time, and that's not idea. So it might just be that the current common flow of jumping between projects in different panes / tabs is the recommended one. I'll leave this open in case others have any ideas or input.

ckipp01 avatar Jan 02 '23 06:01 ckipp01

Yea it seems clear that if I'm getting the behavior from something other than the lsp in emacs then it's probably not the concern of the lsp here. If nvim-metals were to start prompting when a new root is seen I assume people already comfortable with how it works currently would want a toggle to prevent seeing it when they are just fliping to another project to reference some code. Kitty tabs are actually working pretty well given I can setup a command to open a new one directly to nvim.

beem812 avatar Jan 02 '23 23:01 beem812

I was just passing by, but I'll put my two cents in

I quite enjoy the possibility of developing multiple tightly coupled projects in a single Neovim instance (e.g. scala server and its React frontend) as sometimes they share the same environmental variables, launch scripts, etc. It feels that tmux panes/windows provide a larger switch latency than project.nvim with a telescope picker, which I use to wander among projects.

Here we might also look at behaviour of other language servers. For example, tsserver in its default lspconfig configuration is run in multiple parallel instances, one for each open project. It works well according to my observations. Thumbs up to the issue :)

susliko avatar Jan 27 '23 20:01 susliko

Could https://github.com/scalameta/metals/pull/5033 be used to implement the desired behavior described here??

caenrique avatar May 05 '23 12:05 caenrique

Could https://github.com/scalameta/metals/pull/5033 be used to implement the desired behavior described here??

Absolutely. I plan on documenting this better. I'll do it soon, but it's not in a stable release of Metals yet, but it will really help in situations like this.

ckipp01 avatar May 05 '23 12:05 ckipp01