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

feat(vscode): watch configuration file #3284

Merged
merged 9 commits into from
Nov 2, 2022
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
2 changes: 1 addition & 1 deletion crates/rome_fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod path;

pub use fs::{
ErrorEntry, FileSystem, FileSystemExt, MemoryFileSystem, OpenOptions, OsFileSystem,
TraversalContext, TraversalScope,
TraversalContext, TraversalScope, CONFIG_NAME,
};
pub use interner::{AtomicInterner, IndexSetInterner, PathInterner};
pub use path::RomePath;
6 changes: 3 additions & 3 deletions crates/rome_lsp/src/handlers/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use rome_service::{
RomeError,
};
use tower_lsp::lsp_types::*;
use tracing::trace;
use tracing::debug;

#[tracing::instrument(level = "trace", skip(session), err)]
#[tracing::instrument(level = "debug", skip(session), err)]
pub(crate) fn format(
session: &Session,
params: DocumentFormattingParams,
Expand All @@ -19,7 +19,7 @@ pub(crate) fn format(

let doc = session.document(&url)?;

trace!("Formatting...");
debug!("Formatting...");
let result = session
.workspace
.format_file(FormatFileParams { path: rome_path });
Expand Down
58 changes: 53 additions & 5 deletions crates/rome_lsp/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
use std::collections::HashMap;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};

use crate::capabilities::server_capabilities;
use crate::requests::syntax_tree::{SyntaxTreePayload, SYNTAX_TREE_REQUEST};
use crate::session::{ClientInformation, Session, SessionHandle, SessionKey};
Expand All @@ -10,8 +6,12 @@ use crate::{handlers, requests};
use futures::future::ready;
use futures::FutureExt;
use rome_console::markup;
use rome_fs::CONFIG_NAME;
use rome_service::workspace::{RageEntry, RageParams, RageResult};
use rome_service::{workspace, Workspace};
use std::collections::HashMap;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::sync::Notify;
use tokio::task::spawn_blocking;
Expand Down Expand Up @@ -133,6 +133,23 @@ impl LSPServer {
.await;
}

let base_path = self.session.base_path();

if let Some(base_path) = base_path {
let registration_options = DidChangeWatchedFilesRegistrationOptions {
watchers: vec![FileSystemWatcher {
glob_pattern: format!("{}/rome.json", base_path.display()),
kind: Some(WatchKind::all()),
}],
};
self.register_capability(Registration {
id: "workspace/didChangeWatchedFiles".to_string(),
method: "workspace/didChangeWatchedFiles".to_string(),
register_options: Some(serde_json::to_value(registration_options).unwrap()),
})
.await;
}

if rename {
self.register_capability(Registration {
id: "textDocument/rename".to_string(),
Expand Down Expand Up @@ -217,6 +234,37 @@ impl LanguageServer for LSPServer {
self.setup_capabilities().await;
}

#[tracing::instrument(level = "trace", skip(self))]
async fn did_change_watched_files(&self, params: DidChangeWatchedFilesParams) {
let file_paths = params
.changes
.iter()
.map(|change| change.uri.to_file_path());
for file_path in file_paths {
match file_path {
Ok(file_path) => {
let base_path = self.session.base_path();
if let Some(base_path) = base_path {
let possible_rome_json = file_path.strip_prefix(&base_path);
if let Ok(possible_rome_json) = possible_rome_json {
if possible_rome_json.display().to_string() == CONFIG_NAME {
self.session.update_configuration().await;
self.session.fetch_client_configuration().await;
// for now we are only interested to the configuration file,
// so it's OK to exist the loop
break;
}
}
}
}
Err(_) => {
error!("The Workspace root URI {file_path:?} could not be parsed as a filesystem path");
continue;
}
}
}
}

async fn did_open(&self, params: DidOpenTextDocumentParams) {
handlers::text_document::did_open(&self.session, params)
.await
Expand Down Expand Up @@ -367,7 +415,7 @@ impl ServerFactory {

// "shutdown" is not part of the Workspace API
builder = builder.custom_method("rome/shutdown", |server: &LSPServer, (): ()| {
tracing::info!("Sending shutdown signal");
info!("Sending shutdown signal");
server.session.broadcast_shutdown();
ready(Ok(Some(())))
});
Expand Down
56 changes: 34 additions & 22 deletions crates/rome_lsp/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rome_service::workspace::{RageEntry, RageParams, RageResult, UpdateSettingsP
use rome_service::{load_config, Workspace};
use rome_service::{DynRef, RomeError};
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::RwLock;
use std::sync::{Arc, Mutex};
use tokio::sync::Notify;
Expand Down Expand Up @@ -196,16 +197,20 @@ impl Session {
== Some(true)
}

/// This function attempts to read the configuration from the root URI
pub(crate) async fn update_configuration(&self) {
pub(crate) fn base_path(&self) -> Option<PathBuf> {
let root_uri = self.root_uri.read().unwrap();
let base_path = root_uri.as_ref().and_then(|root_uri| match root_uri.to_file_path() {
root_uri.as_ref().and_then(|root_uri| match root_uri.to_file_path() {
Ok(base_path) => Some(base_path),
Err(()) => {
error!("The Workspace root URI {root_uri:?} could not be parsed as a filesystem path");
None
}
});
})
}

/// This function attempts to read the configuration from the root URI
pub(crate) async fn update_configuration(&self) {
let base_path = self.base_path();

match load_config(&self.fs, base_path) {
Ok(Some(configuration)) => {
Expand Down Expand Up @@ -241,24 +246,7 @@ impl Session {
error!("Cannot set workspace settings: {}", err);
})
.ok()?;
let mut configuration = self.configuration.write().unwrap();

// This operation is intended, we want to consume the configuration because once it's read
// from the LSP, it's not needed anymore
if let Some(configuration) = configuration.take() {
trace!(
"The LSP will now use the following configuration: \n {:?}",
&configuration
);

let result = self
.workspace
.update_settings(UpdateSettingsParams { configuration });

if let Err(error) = result {
error!("{:?}", &error)
}
}
self.update_workspace_settings();

Some(())
});
Expand All @@ -267,6 +255,30 @@ impl Session {
}
}

/// If updates the [Workspace] settings with the new configuration that was
/// read from file.
#[tracing::instrument(level = "debug", skip(self))]
pub(crate) fn update_workspace_settings(&self) {
let mut configuration = self.configuration.write().unwrap();

// This operation is intended, we want to consume the configuration because once it's read
// from the LSP, it's not needed anymore
if let Some(configuration) = configuration.take() {
trace!(
"The LSP will now use the following configuration: \n {:?}",
&configuration
);

let result = self
.workspace
.update_settings(UpdateSettingsParams { configuration });

if let Err(error) = result {
error!("{:?}", &error)
}
}
}

/// Broadcast a shutdown signal to all active connections
pub(crate) fn broadcast_shutdown(&self) {
self.cancellation.notify_one();
Expand Down
2 changes: 1 addition & 1 deletion crates/rome_service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ rome_rowan = { path = "../rome_rowan", features = ["serde"] }
rome_text_edit = { path = "../rome_text_edit" }
indexmap = { workspace = true, features = ["serde"] }
schemars = { version = "0.8.10", features = ["indexmap1"], optional = true }
tracing = { workspace = true }
tracing = { workspace = true, features = ["attributes"] }

[features]
schemars = ["dep:schemars", "rome_formatter/serde", "rome_js_factory", "rome_text_edit/schemars"]
4 changes: 4 additions & 0 deletions crates/rome_service/src/file_handlers/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use rome_diagnostics::{v2, v2::Diagnostic};
use rome_js_analyze::utils::rename::{RenameError, RenameSymbolExtensions};
use std::borrow::Cow;
use std::fmt::Debug;
use tracing::debug;

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
Expand Down Expand Up @@ -425,13 +426,16 @@ fn fix_all(params: FixAllParams) -> Result<FixFileResult, RomeError> {
}
}

#[tracing::instrument(level = "debug", skip(parse))]
fn format(
rome_path: &RomePath,
parse: AnyParse,
settings: SettingsHandle,
) -> Result<Printed, RomeError> {
let options = settings.format_options::<JsLanguage>(rome_path);

debug!("Format with the following options: \n{}", options);

let tree = parse.syntax();
let formatted = format_node(options, &tree)?;

Expand Down
1 change: 1 addition & 0 deletions crates/rome_service/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl WorkspaceSettings {
}

/// The (configuration)[Configuration] is merged into the workspace
#[tracing::instrument(level = "debug", skip(self))]
pub fn merge_with_configuration(
&mut self,
configuration: Configuration,
Expand Down
1 change: 1 addition & 0 deletions crates/rome_service/src/workspace/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ impl Workspace for WorkspaceServer {
/// ## Panics
/// This function may panic if the internal settings mutex has been poisoned
/// by another thread having previously panicked while holding the lock
#[tracing::instrument(level = "debug", skip(self))]
fn update_settings(&self, params: UpdateSettingsParams) -> Result<(), RomeError> {
let mut settings = self.settings.write().unwrap();
settings.merge_with_configuration(params.configuration)?;
Expand Down
23 changes: 23 additions & 0 deletions editors/vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

Adds support for the Rome language server to provide formatting, diagnostics, and code actions.

## How the extension works

The extension acts as a language server, which means that you will get all the features
provided by the extension (formatting, diagnostics, etc.) for any file supported by Rome.

The extension automatically discovers the `rome.json` file in the workspace root directory.

## Known limitations

There are a few limitations that the team plans to remove in the following releases.

- the discovery of the `rome.json` is limited to the root of the workspace
- changes to the configuration `rome.json` won't be picked automatically; use the VSCode command
`Restart LSP Server` or use `rome stop` command;
- when updating `rome` inside you `package.json`, the rome server needs to be restarted;
you can use `rome stop` command or kill the process manually;
- if you don't want to see Rome's diagnostics in projects that don't use Rome, you need to disable
the extension;

## Supported languages

Check the [website](https://rome.tools/#language-support) for more information.

## Usage

This extension may be bundled with a prebuilt binary for `rome_lsp`, the Rome language server.
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载