@@ -18,7 +18,8 @@ defmodule Expert.State do
1818 defstruct configuration: nil ,
1919 initialized?: false ,
2020 shutdown_received?: false ,
21- in_flight_requests: % { }
21+ in_flight_requests: % { } ,
22+ workspace_folders: [ ]
2223
2324 @ supported_code_actions [
2425 Enumerations.CodeActionKind . quick_fix ( ) ,
@@ -55,11 +56,15 @@ defmodule Expert.State do
5556 |> Forge.Workspace . new ( )
5657 |> Forge.Workspace . set_workspace ( )
5758
58- config = Configuration . new ( event . root_uri , event . capabilities , client_name )
59+ config = Configuration . new ( event . workspace_folders , event . capabilities , client_name )
5960 new_state = % __MODULE__ { state | configuration: config , initialized?: true }
6061
6162 response = initialize_result ( )
6263
64+ for project <- config . projects do
65+ ensure_project_node_started ( project )
66+ end
67+
6368 { :ok , response , new_state }
6469 end
6570
@@ -100,6 +105,39 @@ defmodule Expert.State do
100105 { :ok , state }
101106 end
102107
108+ def apply ( % __MODULE__ { } = state , % Notifications.WorkspaceDidChangeWorkspaceFolders {
109+ params:
110+ % Structures.DidChangeWorkspaceFoldersParams {
111+ event: % Structures.WorkspaceFoldersChangeEvent { added: added , removed: removed }
112+ } = params
113+ } ) do
114+ workspace_folders = [ added | state . workspace_folders ] -- removed
115+
116+ removed_projects =
117+ for % { uri: uri } <- removed do
118+ project = Project . new ( uri )
119+ Logger . info ( "Stopping project at uri #{ uri } " )
120+ Expert.Project.Supervisor . stop ( project )
121+ project
122+ end
123+
124+ added_projects =
125+ for % { uri: uri } <- added do
126+ project = Project . new ( uri )
127+ ensure_project_node_started ( project )
128+ project
129+ end
130+
131+ config =
132+ state . configuration
133+ |> Configuration . add_projects ( added_projects )
134+ |> Configuration . remove_projects ( removed_projects )
135+
136+ state = % __MODULE__ { state | configuration: config , workspace_folders: workspace_folders }
137+
138+ { :ok , state }
139+ end
140+
103141 def apply ( % __MODULE__ { } = state , % GenLSP.Notifications.TextDocumentDidChange { params: params } ) do
104142 uri = params . text_document . uri
105143 version = params . text_document . version
@@ -136,18 +174,6 @@ defmodule Expert.State do
136174 language_id: language_id
137175 } = did_open . params . text_document
138176
139- project = Project . find_project ( uri )
140- config = state . configuration
141-
142- state =
143- if is_nil ( project ) do
144- state
145- else
146- maybe_start_project ( project , config )
147- config = Configuration . add_project ( config , project )
148- % __MODULE__ { state | configuration: config }
149- end
150-
151177 case Document.Store . open ( uri , text , version , language_id ) do
152178 :ok ->
153179 Logger . info ( "################### opened #{ uri } " )
@@ -216,19 +242,18 @@ defmodule Expert.State do
216242 { :ok , state }
217243 end
218244
219- defp maybe_start_project ( project , config ) do
220- already_started? =
221- Enum . any? ( config . projects , fn p ->
222- p . root_uri == project . root_uri
223- end )
224-
225- if already_started? do
226- :ok
227- else
228- Logger . info ( "Starting project at uri #{ project . root_uri } " )
229- result = Expert.Project.Supervisor . start ( project )
230- Logger . info ( "result: #{ inspect ( result ) } " )
231- :ok
245+ defp ensure_project_node_started ( project ) do
246+ case Expert.Project.Supervisor . start ( project ) do
247+ { :ok , _pid } ->
248+ Logger . info ( "Project node started for #{ project . name } " )
249+
250+ { :error , { reason , pid } } when reason in [ :alread_started , :already_present ] ->
251+ { :ok , pid }
252+
253+ { :error , reason } ->
254+ Logger . error (
255+ "Failed to start project node for #{ project . name } : #{ inspect ( reason , pretty: true ) } "
256+ )
232257 end
233258 end
234259
@@ -269,7 +294,13 @@ defmodule Expert.State do
269294 hover_provider: true ,
270295 references_provider: true ,
271296 text_document_sync: sync_options ,
272- workspace_symbol_provider: true
297+ workspace_symbol_provider: true ,
298+ workspace: % {
299+ workspace_folders: % Structures.WorkspaceFoldersServerCapabilities {
300+ supported: true ,
301+ change_notifications: true
302+ }
303+ }
273304 }
274305
275306 % GenLSP.Structures.InitializeResult {
0 commit comments