Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
progress
  • Loading branch information
psteinroe committed May 28, 2025
commit 84a76a2ca385a16ba8d97b4f5e59981a689ca102
6 changes: 5 additions & 1 deletion crates/pgt_cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use pgt_console::Console;
use pgt_fs::FileSystem;
use pgt_workspace::PartialConfigurationExt;
use pgt_workspace::configuration::{LoadedConfiguration, load_configuration};
use pgt_workspace::workspace::UpdateSettingsParams;
use pgt_workspace::workspace::{RegisterProjectFolderParams, UpdateSettingsParams};
use pgt_workspace::{DynRef, Workspace, WorkspaceError};
use std::ffi::OsString;
use std::path::PathBuf;
Expand Down Expand Up @@ -301,6 +301,10 @@ pub(crate) trait CommandRunner: Sized {
let (vcs_base_path, gitignore_matches) =
configuration.retrieve_gitignore_matches(fs, vcs_base_path.as_deref())?;
let paths = self.get_files_to_process(fs, &configuration)?;
workspace.register_project_folder(RegisterProjectFolderParams {
path: fs.working_directory(),
set_as_current_workspace: true,
})?;

workspace.update_settings(UpdateSettingsParams {
workspace_directory: fs.working_directory(),
Expand Down
46 changes: 46 additions & 0 deletions crates/pgt_lsp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::utils::{into_lsp_error, panic_to_lsp_error};
use futures::FutureExt;
use futures::future::ready;
use pgt_fs::{ConfigName, FileSystem, OsFileSystem};
use pgt_workspace::workspace::{RegisterProjectFolderParams, UnregisterProjectFolderParams};
use pgt_workspace::{DynRef, Workspace, workspace};
use rustc_hash::FxHashMap;
use serde_json::json;
Expand Down Expand Up @@ -107,6 +108,10 @@ impl LanguageServer for LSPServer {

self.session.initialize(
params.capabilities,
params.client_info.map(|client_info| ClientInformation {
name: client_info.name,
version: client_info.version,
}),
params.root_uri,
params.workspace_folders,
);
Expand Down Expand Up @@ -217,6 +222,47 @@ impl LanguageServer for LSPServer {
.ok();
}

async fn did_change_workspace_folders(&self, params: DidChangeWorkspaceFoldersParams) {
for removed in &params.event.removed {
if let Ok(project_path) = self.session.file_path(&removed.uri) {
let result = self
.session
.workspace
.unregister_project_folder(UnregisterProjectFolderParams { path: project_path })
.map_err(into_lsp_error);

if let Err(err) = result {
error!("Failed to remove project from the workspace: {}", err);
self.session
.client
.log_message(MessageType::ERROR, err)
.await;
}
}
}

for added in &params.event.added {
if let Ok(project_path) = self.session.file_path(&added.uri) {
let result = self
.session
.workspace
.register_project_folder(RegisterProjectFolderParams {
path: Some(project_path.to_path_buf()),
set_as_current_workspace: true,
})
.map_err(into_lsp_error);

if let Err(err) = result {
error!("Failed to add project to the workspace: {}", err);
self.session
.client
.log_message(MessageType::ERROR, err)
.await;
}
}
}
}

#[tracing::instrument(level = "trace", skip_all)]
async fn completion(&self, params: CompletionParams) -> LspResult<Option<CompletionResponse>> {
match handlers::completions::get_completions(&self.session, params) {
Expand Down
40 changes: 39 additions & 1 deletion crates/pgt_lsp/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use pgt_workspace::PartialConfigurationExt;
use pgt_workspace::Workspace;
use pgt_workspace::configuration::{LoadedConfiguration, load_configuration};
use pgt_workspace::features;
use pgt_workspace::workspace::UpdateSettingsParams;
use pgt_workspace::workspace::{RegisterProjectFolderParams, UpdateSettingsParams};
use pgt_workspace::{DynRef, WorkspaceError};
use rustc_hash::FxHashMap;
use serde_json::Value;
Expand All @@ -31,6 +31,14 @@ use tower_lsp::lsp_types::{MessageType, Registration};
use tower_lsp::lsp_types::{Unregistration, WorkspaceFolder};
use tracing::{error, info};

pub(crate) struct ClientInformation {
/// The name of the client
pub(crate) name: String,

/// The version of the client
pub(crate) version: Option<String>,
}

/// Key, uniquely identifying a LSP session.
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub(crate) struct SessionKey(pub u64);
Expand Down Expand Up @@ -68,6 +76,7 @@ pub(crate) struct Session {
struct InitializeParams {
/// The capabilities provided by the client as part of [`lsp_types::InitializeParams`]
client_capabilities: lsp_types::ClientCapabilities,
client_information: Option<ClientInformation>,
root_uri: Option<Url>,
#[allow(unused)]
workspace_folders: Option<Vec<WorkspaceFolder>>,
Expand Down Expand Up @@ -164,11 +173,13 @@ impl Session {
pub(crate) fn initialize(
&self,
client_capabilities: lsp_types::ClientCapabilities,
client_information: Option<ClientInformation>,
root_uri: Option<Url>,
workspace_folders: Option<Vec<WorkspaceFolder>>,
) {
let result = self.initialize_params.set(InitializeParams {
client_capabilities,
client_information,
root_uri,
workspace_folders,
});
Expand Down Expand Up @@ -446,6 +457,8 @@ impl Session {
info!("Configuration loaded successfully from disk.");
info!("Update workspace settings.");

let fs = &self.fs;

if let Some(ws_configuration) = extra_config {
fs_configuration.merge_with(ws_configuration);
}
Expand All @@ -455,6 +468,31 @@ impl Session {

match result {
Ok((vcs_base_path, gitignore_matches)) => {
let register_result =
if let ConfigurationPathHint::FromWorkspace(path) = &base_path {
// We don't need the key
self.workspace
.register_project_folder(RegisterProjectFolderParams {
path: Some(path.clone()),
// 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.
// The correct one is actually set when the LSP calls `textDocument/didOpen`
set_as_current_workspace: true,
})
.err()
} else {
self.workspace
.register_project_folder(RegisterProjectFolderParams {
path: fs.working_directory(),
set_as_current_workspace: true,
})
.err()
};
if let Some(error) = register_result {
error!("Failed to register the project folder: {}", error);
self.client.log_message(MessageType::ERROR, &error).await;
return ConfigurationStatus::Error;
}

let result = self.workspace.update_settings(UpdateSettingsParams {
workspace_directory: self.fs.working_directory(),
configuration: fs_configuration,
Expand Down
4 changes: 4 additions & 0 deletions crates/pgt_workspace/src/workspace/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ impl Workspace for WorkspaceServer {
ParsedDocument::new(params.path.clone(), params.content, params.version)
});

if let Some(project_key) = self.path_belongs_to_current_workspace(&params.path) {
self.set_current_project(project_key);
}

Ok(())
}

Expand Down
Loading