Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions crates/oxc_language_server/src/capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ use tower_lsp_server::lsp_types::{

use crate::{code_actions::CODE_ACTION_KIND_SOURCE_FIX_ALL_OXC, commands::LSP_COMMANDS};

#[derive(Clone)]
#[derive(Clone, Default)]
pub struct Capabilities {
pub code_action_provider: bool,
pub workspace_apply_edit: bool,
pub workspace_execute_command: bool,
pub workspace_configuration: bool,
}

impl From<ClientCapabilities> for Capabilities {
Expand All @@ -28,8 +29,17 @@ impl From<ClientCapabilities> for Capabilities {
value.workspace.as_ref().is_some_and(|workspace| workspace.apply_edit.is_some());
let workspace_execute_command =
value.workspace.as_ref().is_some_and(|workspace| workspace.execute_command.is_some());
let workspace_configuration = value
.workspace
.as_ref()
.is_some_and(|workspace| workspace.configuration.is_some_and(|config| config));

Self { code_action_provider, workspace_apply_edit, workspace_execute_command }
Self {
code_action_provider,
workspace_apply_edit,
workspace_execute_command,
workspace_configuration,
}
}
}

Expand Down
26 changes: 24 additions & 2 deletions crates/oxc_language_server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const OXC_CONFIG_FILE: &str = ".oxlintrc.json";
struct Backend {
client: Client,
root_uri: OnceCell<Option<Uri>>,
capabilities: OnceCell<Capabilities>,
server_linter: RwLock<ServerLinter>,
diagnostics_report_map: ConcurrentHashMap<String, Vec<DiagnosticReport>>,
options: Mutex<Options>,
Expand Down Expand Up @@ -102,21 +103,37 @@ impl LanguageServer for Backend {
*self.options.lock().await = value;
}

let capabilities = Capabilities::from(params.capabilities);
self.capabilities.set(capabilities.clone()).map_err(|err| {
let message = match err {
SetError::AlreadyInitializedError(_) => {
"capabilities are already initialized".into()
}
SetError::InitializingError(_) => "initializing error".into(),
};

Error { code: ErrorCode::ParseError, message, data: None }
})?;

self.init_nested_configs().await;
let oxlintrc = self.init_linter_config().await;
self.init_ignore_glob(oxlintrc).await;
Ok(InitializeResult {
server_info: Some(ServerInfo { name: "oxc".into(), version: None }),
offset_encoding: None,
capabilities: Capabilities::from(params.capabilities).into(),
capabilities: capabilities.into(),
})
}

async fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
let changed_options =
if let Ok(options) = serde_json::from_value::<Options>(params.settings) {
options
} else {
} else if self
.capabilities
.get()
.is_some_and(|capabilities| capabilities.workspace_configuration)
{
// Fallback if some client didn't took changed configuration in params of `workspace/configuration`
let Some(options) = self
.client
Expand All @@ -133,6 +150,10 @@ impl LanguageServer for Backend {
return;
};
options
} else {
// the client did not give os changes to the configuration and he is not able to respond to `workspace/configuration`
// so we fallback to the current configuration
self.options.lock().await.clone()
};

let current_option = &self.options.lock().await.clone();
Expand Down Expand Up @@ -565,6 +586,7 @@ async fn main() {
let (service, socket) = LspService::build(|client| Backend {
client,
root_uri: OnceCell::new(),
capabilities: OnceCell::new(),
server_linter: RwLock::new(server_linter),
diagnostics_report_map,
options: Mutex::new(Options::default()),
Expand Down
Loading