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

Commit

Permalink
feat(rome_lsp): read configuration file (#2872)
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico committed Jul 15, 2022
1 parent cae86c5 commit 332130c
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 75 deletions.
2 changes: 1 addition & 1 deletion crates/rome_fs/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub use memory::MemoryFileSystem;
pub use os::OsFileSystem;
pub const CONFIG_NAME: &str = "rome.json";

pub trait FileSystem: Sync + RefUnwindSafe {
pub trait FileSystem: Send + Sync + RefUnwindSafe {
/// Open a handle to the file at `path`
///
/// Currently this locks down the file for both reading and writing
Expand Down
111 changes: 64 additions & 47 deletions crates/rome_lsp/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use rome_formatter::{IndentStyle, LineWidth};
use rome_js_formatter::context::QuoteStyle;
use rome_service::configuration::Configuration;
use rome_service::settings;
use rome_service::settings::FormatSettings;
use serde::{Deserialize, Serialize};
use serde_json::{Error, Value};
use tracing::{info, trace};
Expand Down Expand Up @@ -77,62 +79,77 @@ impl Config {
}

/// Convert the current configuration to an instance of [settings::WorkspaceSettings]
pub fn as_workspace_settings(&self) -> settings::WorkspaceSettings {
///
/// If the configuration file is found we use it with its defaults, otherwise
/// we use the settings coming from the client
pub fn as_workspace_settings(
&self,
configuration: Option<&Configuration>,
) -> settings::WorkspaceSettings {
let mut settings = settings::WorkspaceSettings::default();

// second, we apply the settings coming from the client
settings.format.format_with_errors = self.settings.formatter.format_with_syntax_errors;

let custom_ident_style: IndentStyle = self
.settings
.formatter
.indent_style
.parse()
.unwrap_or_default();

if custom_ident_style != IndentStyle::default() {
// merge settings with the ones provided by the editor
match custom_ident_style {
IndentStyle::Space(_) => {
settings.format.indent_style =
Some(IndentStyle::Space(self.settings.formatter.space_quantity));
if let Some(configuration) = configuration {
trace!("Applying configuration coming from the configuration file");
settings.format = FormatSettings::from(&configuration.formatter);
settings.languages.javascript.format.quote_style =
Some(configuration.javascript.formatter.quote_style)
} else {
trace!("Applying configuration coming from the client");
let custom_ident_style: IndentStyle = self
.settings
.formatter
.indent_style
.parse()
.unwrap_or_default();

if custom_ident_style != IndentStyle::default() {
// merge settings with the ones provided by the editor
match custom_ident_style {
IndentStyle::Space(_) => {
settings.format.indent_style =
Some(IndentStyle::Space(self.settings.formatter.space_quantity));
}
IndentStyle::Tab => {
settings.format.indent_style = Some(custom_ident_style);
}
}
IndentStyle::Tab => {
settings.format.indent_style = Some(custom_ident_style);
}
}

info!(
"Using user setting indent style: {:?}",
settings.format.indent_style
);
}
info!(
"Using user setting indent style: {:?}",
settings.format.indent_style
);
}

let custom_quote_style: QuoteStyle = self
.settings
.formatter
.quote_style
.parse()
.unwrap_or_default();
let custom_quote_style: QuoteStyle = self
.settings
.formatter
.quote_style
.parse()
.unwrap_or_default();

if custom_quote_style != QuoteStyle::default() {
settings.languages.javascript.format.quote_style = Some(custom_quote_style);
info!("Using user setting quote style: {}", custom_quote_style);
}
if custom_quote_style != QuoteStyle::default() {
settings.languages.javascript.format.quote_style = Some(custom_quote_style);
info!("Using user setting quote style: {}", custom_quote_style);
}

// apply the new line width only if they are different
let custom_line_width: LineWidth = self
.settings
.formatter
.line_width
.try_into()
.unwrap_or_default();

if custom_line_width != LineWidth::default() {
settings.format.line_width = Some(custom_line_width);
info!(
"Using user setting line width: {}",
custom_line_width.value()
);
// apply the new line width only if they are different
let custom_line_width: LineWidth = self
.settings
.formatter
.line_width
.try_into()
.unwrap_or_default();

if custom_line_width != LineWidth::default() {
settings.format.line_width = Some(custom_line_width);
info!(
"Using user settings line width: {}",
custom_line_width.value()
);
}
}

settings
Expand Down
15 changes: 15 additions & 0 deletions crates/rome_lsp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use crate::requests::syntax_tree::{SyntaxTreePayload, SYNTAX_TREE_REQUEST};
use crate::session::Session;
use crate::utils::into_lsp_error;
use crate::{handlers, requests};
use rome_service::load_config;
use rome_service::load_config::ConfigurationType;
use serde_json::Value;
use tokio::io::{Stdin, Stdout};
use tower_lsp::jsonrpc::Result as LspResult;
Expand Down Expand Up @@ -58,6 +60,19 @@ impl LanguageServer for LSPServer {
}

async fn initialized(&self, _: InitializedParams) {
info!("Attempting to load the configuration from 'rome.json' file");

match load_config(&self.session.fs, ConfigurationType::Root) {
Ok(Some(configuration)) => {
info!("Configuration found, and it is valid!");
self.session.configuration.write().replace(configuration);
}
Err(err) => {
error!("Couldn't load the configuration file, reason:\n {}", err);
}
_ => {}
};

self.session.fetch_client_configuration().await;

if self.session.config.read().get_workspace_settings().unstable {
Expand Down
65 changes: 42 additions & 23 deletions crates/rome_lsp/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ use futures::StreamExt;
use parking_lot::RwLock;
use rome_analyze::RuleCategories;
use rome_diagnostics::file::FileId;
use rome_fs::RomePath;
use rome_fs::{FileSystem, OsFileSystem, RomePath};
use rome_service::configuration::Configuration;
use rome_service::workspace;
use rome_service::workspace::PullDiagnosticsParams;
use rome_service::workspace::UpdateSettingsParams;
use rome_service::RomeError;
use rome_service::Workspace;
use rome_service::{DynRef, RomeError};
use std::collections::HashMap;
use tower_lsp::lsp_types;
use tracing::{error, trace};
Expand All @@ -30,6 +31,13 @@ pub(crate) struct Session {
pub(crate) config: RwLock<Config>,

pub(crate) workspace: Box<dyn Workspace>,

/// File system to read files inside the workspace
pub(crate) fs: DynRef<'static, dyn FileSystem>,

/// The configuration coming from `rome.json` file
pub(crate) configuration: RwLock<Option<Configuration>>,

documents: RwLock<HashMap<lsp_types::Url, Document>>,
url_interner: RwLock<UrlInterner>,
}
Expand All @@ -40,13 +48,16 @@ impl Session {
let documents = Default::default();
let url_interner = Default::default();
let config = RwLock::new(Config::new());
let configuration = RwLock::new(None);
Self {
client,
client_capabilities,
workspace: workspace::server(),
documents,
url_interner,
config,
fs: DynRef::Owned(Box::new(OsFileSystem)),
configuration,
}
}

Expand Down Expand Up @@ -158,27 +169,35 @@ impl Session {
section: Some(String::from(CONFIGURATION_SECTION)),
};
let items = vec![item];
let configurations = self.client.configuration(items).await;

if let Ok(configurations) = configurations {
configurations.into_iter().next().and_then(|configuration| {
let mut config = self.config.write();

config
.set_workspace_settings(configuration)
.map_err(|err| {
error!("Cannot set workspace settings: {}", err);
})
.ok()?;

self.workspace
.update_settings(UpdateSettingsParams {
settings: config.as_workspace_settings(),
})
.ok()?;

Some(())
});
let client_configurations = self.client.configuration(items).await;

if let Ok(client_configurations) = client_configurations {
client_configurations
.into_iter()
.next()
.and_then(|client_configuration| {
let mut config = self.config.write();

config
.set_workspace_settings(client_configuration)
.map_err(|err| {
error!("Cannot set workspace settings: {}", err);
})
.ok()?;
let configuration = self.configuration.read();
let settings = config.as_workspace_settings(configuration.as_ref());

trace!(
"The LSP will now use the following configuration: \n {:?}",
&settings
);

self.workspace
.update_settings(UpdateSettingsParams { settings })
.ok()?;

Some(())
});
} else {
trace!("Cannot read configuration from the client");
}
Expand Down
2 changes: 1 addition & 1 deletion crates/rome_service/src/file_handlers/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
use super::{ExtensionHandler, Mime};
use std::fmt::Debug;

#[derive(Clone, Copy, Default)]
#[derive(Debug, Clone, Copy, Default)]
pub struct JsFormatSettings {
pub indent_style: Option<IndentStyle>,
pub line_width: Option<LineWidth>,
Expand Down
8 changes: 5 additions & 3 deletions crates/rome_service/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rome_fs::RomePath;
use rome_js_syntax::JsLanguage;

/// Global settings for the entire workspace
#[derive(Default)]
#[derive(Debug, Default)]
pub struct WorkspaceSettings {
/// Formatter settings applied to all files in the workspaces
pub format: FormatSettings,
Expand All @@ -16,6 +16,7 @@ pub struct WorkspaceSettings {
}

/// Formatter settings for the entire workspace
#[derive(Debug)]
pub struct FormatSettings {
/// Enabled by default
pub enabled: bool,
Expand All @@ -38,6 +39,7 @@ impl Default for FormatSettings {
}

/// Formatter settings for the entire workspace
#[derive(Debug)]
pub struct LinterSettings {
/// Enabled by default
pub enabled: bool,
Expand All @@ -50,7 +52,7 @@ impl Default for LinterSettings {
}

/// Static map of language names to language-specific settings
#[derive(Default)]
#[derive(Debug, Default)]
pub struct LanguagesSettings {
pub javascript: LanguageSettings<JsLanguage>,
}
Expand All @@ -74,7 +76,7 @@ pub trait Language: rome_rowan::Language {
) -> Self::FormatContext;
}

#[derive(Default)]
#[derive(Debug, Default)]
pub struct LanguageSettings<L: Language> {
/// Formatter settings for this language
pub format: L::FormatSettings,
Expand Down

0 comments on commit 332130c

Please sign in to comment.