Skip to content

Commit 84a76a2

Browse files
committed
progress
1 parent d161f18 commit 84a76a2

4 files changed

Lines changed: 94 additions & 2 deletions

File tree

crates/pgt_cli/src/commands/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use pgt_console::Console;
1111
use pgt_fs::FileSystem;
1212
use pgt_workspace::PartialConfigurationExt;
1313
use pgt_workspace::configuration::{LoadedConfiguration, load_configuration};
14-
use pgt_workspace::workspace::UpdateSettingsParams;
14+
use pgt_workspace::workspace::{RegisterProjectFolderParams, UpdateSettingsParams};
1515
use pgt_workspace::{DynRef, Workspace, WorkspaceError};
1616
use std::ffi::OsString;
1717
use std::path::PathBuf;
@@ -301,6 +301,10 @@ pub(crate) trait CommandRunner: Sized {
301301
let (vcs_base_path, gitignore_matches) =
302302
configuration.retrieve_gitignore_matches(fs, vcs_base_path.as_deref())?;
303303
let paths = self.get_files_to_process(fs, &configuration)?;
304+
workspace.register_project_folder(RegisterProjectFolderParams {
305+
path: fs.working_directory(),
306+
set_as_current_workspace: true,
307+
})?;
304308

305309
workspace.update_settings(UpdateSettingsParams {
306310
workspace_directory: fs.working_directory(),

crates/pgt_lsp/src/server.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::utils::{into_lsp_error, panic_to_lsp_error};
55
use futures::FutureExt;
66
use futures::future::ready;
77
use pgt_fs::{ConfigName, FileSystem, OsFileSystem};
8+
use pgt_workspace::workspace::{RegisterProjectFolderParams, UnregisterProjectFolderParams};
89
use pgt_workspace::{DynRef, Workspace, workspace};
910
use rustc_hash::FxHashMap;
1011
use serde_json::json;
@@ -107,6 +108,10 @@ impl LanguageServer for LSPServer {
107108

108109
self.session.initialize(
109110
params.capabilities,
111+
params.client_info.map(|client_info| ClientInformation {
112+
name: client_info.name,
113+
version: client_info.version,
114+
}),
110115
params.root_uri,
111116
params.workspace_folders,
112117
);
@@ -217,6 +222,47 @@ impl LanguageServer for LSPServer {
217222
.ok();
218223
}
219224

225+
async fn did_change_workspace_folders(&self, params: DidChangeWorkspaceFoldersParams) {
226+
for removed in &params.event.removed {
227+
if let Ok(project_path) = self.session.file_path(&removed.uri) {
228+
let result = self
229+
.session
230+
.workspace
231+
.unregister_project_folder(UnregisterProjectFolderParams { path: project_path })
232+
.map_err(into_lsp_error);
233+
234+
if let Err(err) = result {
235+
error!("Failed to remove project from the workspace: {}", err);
236+
self.session
237+
.client
238+
.log_message(MessageType::ERROR, err)
239+
.await;
240+
}
241+
}
242+
}
243+
244+
for added in &params.event.added {
245+
if let Ok(project_path) = self.session.file_path(&added.uri) {
246+
let result = self
247+
.session
248+
.workspace
249+
.register_project_folder(RegisterProjectFolderParams {
250+
path: Some(project_path.to_path_buf()),
251+
set_as_current_workspace: true,
252+
})
253+
.map_err(into_lsp_error);
254+
255+
if let Err(err) = result {
256+
error!("Failed to add project to the workspace: {}", err);
257+
self.session
258+
.client
259+
.log_message(MessageType::ERROR, err)
260+
.await;
261+
}
262+
}
263+
}
264+
}
265+
220266
#[tracing::instrument(level = "trace", skip_all)]
221267
async fn completion(&self, params: CompletionParams) -> LspResult<Option<CompletionResponse>> {
222268
match handlers::completions::get_completions(&self.session, params) {

crates/pgt_lsp/src/session.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use pgt_workspace::PartialConfigurationExt;
1414
use pgt_workspace::Workspace;
1515
use pgt_workspace::configuration::{LoadedConfiguration, load_configuration};
1616
use pgt_workspace::features;
17-
use pgt_workspace::workspace::UpdateSettingsParams;
17+
use pgt_workspace::workspace::{RegisterProjectFolderParams, UpdateSettingsParams};
1818
use pgt_workspace::{DynRef, WorkspaceError};
1919
use rustc_hash::FxHashMap;
2020
use serde_json::Value;
@@ -31,6 +31,14 @@ use tower_lsp::lsp_types::{MessageType, Registration};
3131
use tower_lsp::lsp_types::{Unregistration, WorkspaceFolder};
3232
use tracing::{error, info};
3333

34+
pub(crate) struct ClientInformation {
35+
/// The name of the client
36+
pub(crate) name: String,
37+
38+
/// The version of the client
39+
pub(crate) version: Option<String>,
40+
}
41+
3442
/// Key, uniquely identifying a LSP session.
3543
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
3644
pub(crate) struct SessionKey(pub u64);
@@ -68,6 +76,7 @@ pub(crate) struct Session {
6876
struct InitializeParams {
6977
/// The capabilities provided by the client as part of [`lsp_types::InitializeParams`]
7078
client_capabilities: lsp_types::ClientCapabilities,
79+
client_information: Option<ClientInformation>,
7180
root_uri: Option<Url>,
7281
#[allow(unused)]
7382
workspace_folders: Option<Vec<WorkspaceFolder>>,
@@ -164,11 +173,13 @@ impl Session {
164173
pub(crate) fn initialize(
165174
&self,
166175
client_capabilities: lsp_types::ClientCapabilities,
176+
client_information: Option<ClientInformation>,
167177
root_uri: Option<Url>,
168178
workspace_folders: Option<Vec<WorkspaceFolder>>,
169179
) {
170180
let result = self.initialize_params.set(InitializeParams {
171181
client_capabilities,
182+
client_information,
172183
root_uri,
173184
workspace_folders,
174185
});
@@ -446,6 +457,8 @@ impl Session {
446457
info!("Configuration loaded successfully from disk.");
447458
info!("Update workspace settings.");
448459

460+
let fs = &self.fs;
461+
449462
if let Some(ws_configuration) = extra_config {
450463
fs_configuration.merge_with(ws_configuration);
451464
}
@@ -455,6 +468,31 @@ impl Session {
455468

456469
match result {
457470
Ok((vcs_base_path, gitignore_matches)) => {
471+
let register_result =
472+
if let ConfigurationPathHint::FromWorkspace(path) = &base_path {
473+
// We don't need the key
474+
self.workspace
475+
.register_project_folder(RegisterProjectFolderParams {
476+
path: Some(path.clone()),
477+
// This is naive, but we don't know if the user has a file already open or not, so we register every project as the current one.
478+
// The correct one is actually set when the LSP calls `textDocument/didOpen`
479+
set_as_current_workspace: true,
480+
})
481+
.err()
482+
} else {
483+
self.workspace
484+
.register_project_folder(RegisterProjectFolderParams {
485+
path: fs.working_directory(),
486+
set_as_current_workspace: true,
487+
})
488+
.err()
489+
};
490+
if let Some(error) = register_result {
491+
error!("Failed to register the project folder: {}", error);
492+
self.client.log_message(MessageType::ERROR, &error).await;
493+
return ConfigurationStatus::Error;
494+
}
495+
458496
let result = self.workspace.update_settings(UpdateSettingsParams {
459497
workspace_directory: self.fs.working_directory(),
460498
configuration: fs_configuration,

crates/pgt_workspace/src/workspace/server.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ impl Workspace for WorkspaceServer {
269269
ParsedDocument::new(params.path.clone(), params.content, params.version)
270270
});
271271

272+
if let Some(project_key) = self.path_belongs_to_current_workspace(&params.path) {
273+
self.set_current_project(project_key);
274+
}
275+
272276
Ok(())
273277
}
274278

0 commit comments

Comments
 (0)