Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

feat(editors/vscode): Add requiresConfiguration option #4023

Merged
merged 4 commits into from
Dec 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 2 additions & 8 deletions crates/rome_lsp/src/capabilities.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use tower_lsp::lsp_types::{
CodeActionProviderCapability, DocumentOnTypeFormattingOptions, OneOf, ServerCapabilities,
TextDocumentSyncCapability, TextDocumentSyncKind,
CodeActionProviderCapability, ServerCapabilities, TextDocumentSyncCapability,
TextDocumentSyncKind,
};

/// The capabilities to send from server as part of [`InitializeResult`]
Expand All @@ -12,12 +12,6 @@ pub(crate) fn server_capabilities() -> ServerCapabilities {
TextDocumentSyncKind::INCREMENTAL,
)),
code_action_provider: Some(CodeActionProviderCapability::Simple(true)),
document_formatting_provider: Some(OneOf::Left(true)),
document_range_formatting_provider: Some(OneOf::Left(true)),
document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
first_trigger_character: String::from("}"),
more_trigger_character: Some(vec![String::from("]"), String::from(")")]),
}),
rename_provider: None,
..Default::default()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ pub struct WorkspaceSettings {

/// Enable rename capability
pub rename: Option<bool>,

/// Only run Rome if a `rome.json` configuration file exists.
pub require_configuration: Option<bool>,
}

/// The `rome.*` extension settings
#[derive(Debug)]
pub(crate) struct Config {
pub(crate) struct ExtensionSettings {
pub(crate) settings: WorkspaceSettings,
}

impl Config {
impl ExtensionSettings {
pub(crate) fn new() -> Self {
Self {
settings: WorkspaceSettings::default(),
Expand All @@ -37,4 +41,8 @@ impl Config {
);
Ok(())
}

pub(crate) fn requires_configuration(&self) -> bool {
self.settings.require_configuration.unwrap_or_default()
}
}
4 changes: 2 additions & 2 deletions crates/rome_lsp/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod capabilities;
mod config;
mod documents;
mod extension_settings;
mod handlers;
mod line_index;
mod requests;
Expand All @@ -9,5 +9,5 @@ mod session;
mod url_interner;
mod utils;

pub use crate::config::WorkspaceSettings;
pub use crate::extension_settings::WorkspaceSettings;
pub use crate::server::{LSPServer, ServerConnection, ServerFactory};
119 changes: 89 additions & 30 deletions crates/rome_lsp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rome_console::markup;
use rome_fs::CONFIG_NAME;
use rome_service::workspace::{RageEntry, RageParams, RageResult};
use rome_service::{workspace, Workspace};
use serde_json::json;
use std::collections::HashMap;
use std::panic::RefUnwindSafe;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
Expand Down Expand Up @@ -109,45 +110,50 @@ impl LSPServer {
Ok(RageResult { entries })
}

async fn register_capability(&self, registration: Registration) {
let method = registration.method.clone();
async fn register_capabilities(&self, registrations: Vec<Registration>) {
let methods = registrations
.iter()
.map(|reg| reg.method.clone())
.collect::<Vec<_>>()
.join(", ");

if let Err(e) = self
.session
.client
.register_capability(vec![registration])
.await
{
error!("Error registering {:?} capability: {}", method, e);
if let Err(e) = self.session.client.register_capability(registrations).await {
error!("Error registering {:?} capability: {}", methods, e);
}
}

async fn unregister_capability(&self, unregistration: Unregistration) {
let method = unregistration.method.clone();
async fn unregister_capabilities(&self, registrations: Vec<Unregistration>) {
let methods = registrations
.iter()
.map(|reg| reg.method.clone())
.collect::<Vec<_>>()
.join(", ");

if let Err(e) = self
.session
.client
.unregister_capability(vec![unregistration])
.unregister_capability(registrations)
.await
{
error!("Error unregistering {:?} capability: {}", method, e);
error!("Error unregistering {:?} capability: {}", methods, e);
}
}

async fn setup_capabilities(&self) {
let rename = {
let config = self.session.config.read().ok();
let config = self.session.extension_settings.read().ok();
config.and_then(|x| x.settings.rename).unwrap_or(false)
};

let mut register = Vec::new();
let mut unregister = Vec::new();

if self.session.can_register_did_change_configuration() {
self.register_capability(Registration {
register.push(Registration {
id: "workspace/didChangeConfiguration".to_string(),
method: "workspace/didChangeConfiguration".to_string(),
register_options: None,
})
.await;
});
}

let base_path = self.session.base_path();
Expand All @@ -159,27 +165,75 @@ impl LSPServer {
kind: Some(WatchKind::all()),
}],
};
self.register_capability(Registration {
register.push(Registration {
id: "workspace/didChangeWatchedFiles".to_string(),
method: "workspace/didChangeWatchedFiles".to_string(),
register_options: Some(serde_json::to_value(registration_options).unwrap()),
})
.await;
});
}

if self.session.is_linting_and_formatting_disabled() {
unregister.extend([
Unregistration {
id: "textDocument/formatting".to_string(),
method: "textDocument/formatting".to_string(),
},
Unregistration {
id: "textDocument/rangeFormatting".to_string(),
method: "textDocument/rangeFormatting".to_string(),
},
Unregistration {
id: "textDocument/onTypeFormatting".to_string(),
method: "textDocument/onTypeFormatting".to_string(),
},
]);
} else {
register.extend([
Registration {
id: "textDocument/formatting".to_string(),
method: "textDocument/formatting".to_string(),
register_options: Some(json!(TextDocumentRegistrationOptions {
document_selector: None
})),
},
Registration {
id: "textDocument/rangeFormatting".to_string(),
method: "textDocument/rangeFormatting".to_string(),
register_options: Some(json!(TextDocumentRegistrationOptions {
document_selector: None
})),
},
Registration {
id: "textDocument/onTypeFormatting".to_string(),
method: "textDocument/onTypeFormatting".to_string(),
register_options: Some(json!(DocumentOnTypeFormattingRegistrationOptions {
document_selector: None,
first_trigger_character: String::from("}"),
more_trigger_character: Some(vec![String::from("]"), String::from(")")]),
})),
},
]);
}

if rename {
self.register_capability(Registration {
register.push(Registration {
id: "textDocument/rename".to_string(),
method: "textDocument/rename".to_string(),
register_options: None,
})
.await;
});
} else {
self.unregister_capability(Unregistration {
unregister.push(Unregistration {
id: "textDocument/rename".to_string(),
method: "textDocument/rename".to_string(),
})
.await;
});
}

if !register.is_empty() {
self.register_capabilities(register).await;
}

if !unregister.is_empty() {
self.unregister_capabilities(unregister).await;
}
}
}
Expand Down Expand Up @@ -237,8 +291,10 @@ impl LanguageServer for LSPServer {

info!("Attempting to load the configuration from 'rome.json' file");

self.session.load_client_configuration().await;
self.session.load_workspace_settings().await;
futures::join!(
self.session.load_extension_settings(),
self.session.load_workspace_settings()
);

let msg = format!("Server initialized with PID: {}", std::process::id());
self.session
Expand All @@ -256,11 +312,13 @@ impl LanguageServer for LSPServer {
Ok(())
}

/// Called when the user changed the editor settings.
#[tracing::instrument(level = "debug", skip(self))]
async fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
let _ = params;
self.session.load_client_configuration().await;
self.session.load_extension_settings().await;
self.setup_capabilities().await;
self.session.update_all_diagnostics().await;
}

#[tracing::instrument(level = "debug", skip(self))]
Expand All @@ -278,6 +336,7 @@ impl LanguageServer for LSPServer {
if let Ok(possible_rome_json) = possible_rome_json {
if possible_rome_json.display().to_string() == CONFIG_NAME {
self.session.load_workspace_settings().await;
self.setup_capabilities().await;
self.session.update_all_diagnostics().await;
// for now we are only interested to the configuration file,
// so it's OK to exist the loop
Expand Down Expand Up @@ -353,7 +412,7 @@ impl LanguageServer for LSPServer {
rome_diagnostics::panic::catch_unwind(move || {
let rename_enabled = self
.session
.config
.extension_settings
.read()
.ok()
.and_then(|config| config.settings.rename)
Expand Down
Loading