Skip to content

Adopt workspaceFolders #733

@baronfel

Description

@baronfel

Per ionide/ionide-vscode-fsharp#1204 we should move off of using rootPath/rootUri directly.

Updated thoughts

We should do this, but it's a large task so we will take it in stages:

Stage 1 - remove use of deprecated members, keep behavior the same as today

  • update FSAC to not use RootPath/RootUri directly, in favor of the workspacePaths[0].Uri - this should be functionally the same as today, but stop our use of the deprecated members
  • update Ionide to do the same

Stage 2 - allow FSAC to handle not being the first workspacePath

  • update FSAC to probe the N workspacePaths for the first workspacePath with F# code in it and then fixate on that one - this keeps us in the 'single workspace' mode but enables users with many other workspaces to start working with us
  • update Ionide to do the same

Stage 3 - update FSAC to support multiple workspaces, with AdaptiveServerStates per workspace

  • update FSAC to support multiple proper workspaces, managing a set of AdaptiveServerState instances per workspace root
  • update Ionide to do the same
First version of this description Here's some initial investigation:

I've been looking at handling workspaceFolders (omnisharp has a not-completely-terrible thing that helped me get an idea for how it could be done), but it's completely going to up-end the initialization assumptions we've made so far. A brief explanation is in order. Right now, there
are three primary initialization flows, all of which I call the single folder model:

manual-init

in this model, the call stack looks like:

  • initialize
  • workspacePeek
  • workspaceLoad

at this point the projects load, the user can do interactions as normal

automatic-init-single-interesting

in this model, the call stack looks like:

  • initialize (with the AutomaticWorkspaceInit flag set)
    • the initialize logic calls workspacePeek and workspace load and there's only one directory or solution file found
  • that one thing is loaded

at this point the projects load, the user can do interactions as normal

automatic-init-multiple-interesting

in this model, the call stack looks like:

  • initialize (with the AutomaticWorkspaceInit flag set)
    • the initialize logic calls workspacePeek and workspace load and there are multiple potential interesting directories/solutions
  • nothing is loaded, some workspace load notifications are fired and the user has to choose a workspace

In all of these cases, the intialize payload has a RootPath/RootUri, and there's a block of F#-specific settings under the FSharp property key. We set a rootpath in the Commands at this point, and we eventually set the workspaceRoot (some mutable state) in the LSP itself.

multi-workspace

In a multi-workspace situation, none of that holds. The callstack looks like the following:

  • initialize (with RootPath/RootUri set, workspaceFolders set, and no Fsharp settings)
  • workspaceDidChangeConfiguration with the new configuration now including FSharp settings

This means that we need to extract out the actual initialization code from the initialize call and conditionally apply it, as well as likely listen to workspaceChanged events to set the workspace root.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions