mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(vscode): add a option to control oxc lint timing (#1659)
1. Closed https://github.com/oxc-project/oxc/issues/1653 2. Now you use `oxc-client.run` to control the lint timing. [录屏 2023年12月12日 23时39分16秒.webm](https://github.com/oxc-project/oxc/assets/17974631/123326dc-6110-4f2e-9d48-ef1a3b0a4536)
This commit is contained in:
parent
117d95f0ae
commit
e63576d03c
5 changed files with 85 additions and 8 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1956,6 +1956,8 @@ dependencies = [
|
|||
"oxc_span",
|
||||
"rayon",
|
||||
"ropey",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tower-lsp",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ export async function activate(context: ExtensionContext) {
|
|||
// If the extension is launched in debug mode then the debug server options are used
|
||||
// Otherwise the run options are used
|
||||
// Options to control the language client
|
||||
let clientConfig: any = JSON.parse(JSON.stringify(workspace.getConfiguration('oxc-client')));
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
// Register the server for plain text documents
|
||||
documentSelector: [
|
||||
|
|
@ -96,17 +97,28 @@ export async function activate(context: ExtensionContext) {
|
|||
"typescriptreact",
|
||||
"javascriptreact",
|
||||
].map(lang => ({ language: lang, scheme: "file" })),
|
||||
|
||||
synchronize: {
|
||||
// Notify the server about file changes to '.clientrc files contained in the workspace
|
||||
fileEvents: workspace.createFileSystemWatcher("**/.clientrc"),
|
||||
},
|
||||
initializationOptions: {
|
||||
settings: clientConfig
|
||||
},
|
||||
outputChannel,
|
||||
traceOutputChannel,
|
||||
};
|
||||
|
||||
// Create the language client and start the client.
|
||||
client = new LanguageClient(languageClientId, languageClientName, serverOptions, clientOptions);
|
||||
workspace.onDidChangeConfiguration((e) => {
|
||||
let settings: any = {};
|
||||
if (e.affectsConfiguration("oxc-client.run")) {
|
||||
settings.run = workspace.getConfiguration('oxc-client').get("run")
|
||||
}
|
||||
client.sendNotification("workspace/didChangeConfiguration", {
|
||||
settings
|
||||
})
|
||||
})
|
||||
|
||||
client.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,16 @@
|
|||
"type": "object",
|
||||
"title": "oxc",
|
||||
"properties": {
|
||||
"oxc-client.run": {
|
||||
"scope": "resource",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"onSave",
|
||||
"onType"
|
||||
],
|
||||
"default": "onType",
|
||||
"description": "Run the linter on save (onSave) or on type (onType)"
|
||||
},
|
||||
"oxc-client.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
|
|
|
|||
|
|
@ -37,3 +37,5 @@ ropey = { workspace = true }
|
|||
tokio = { workspace = true, features = ["full"] }
|
||||
tower-lsp = { workspace = true, features = ["proposed"] }
|
||||
log = "0.4.20"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -4,21 +4,24 @@ mod options;
|
|||
mod walk;
|
||||
|
||||
use crate::linter::{DiagnosticReport, ServerLinter};
|
||||
use log::debug;
|
||||
use log::{debug, error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use futures::future::join_all;
|
||||
use tokio::sync::{OnceCell, SetError};
|
||||
use tokio::sync::{Mutex, OnceCell, SetError};
|
||||
use tower_lsp::jsonrpc::{Error, ErrorCode, Result};
|
||||
use tower_lsp::lsp_types::{
|
||||
CodeAction, CodeActionKind, CodeActionOptions, CodeActionOrCommand, CodeActionParams,
|
||||
CodeActionProviderCapability, CodeActionResponse, Diagnostic, DidChangeTextDocumentParams,
|
||||
DidOpenTextDocumentParams, DidSaveTextDocumentParams, InitializeParams, InitializeResult,
|
||||
InitializedParams, MessageType, ServerCapabilities, ServerInfo, TextDocumentSyncCapability,
|
||||
TextDocumentSyncKind, TextEdit, Url, WorkDoneProgressOptions, WorkspaceEdit,
|
||||
CodeActionProviderCapability, CodeActionResponse, Diagnostic, DidChangeConfigurationParams,
|
||||
DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams,
|
||||
InitializeParams, InitializeResult, InitializedParams, MessageType, OneOf, Registration,
|
||||
ServerCapabilities, ServerInfo, TextDocumentSyncCapability, TextDocumentSyncKind, TextEdit,
|
||||
Url, WorkDoneProgressOptions, WorkspaceEdit, WorkspaceFoldersServerCapabilities,
|
||||
WorkspaceServerCapabilities,
|
||||
};
|
||||
use tower_lsp::{Client, LanguageServer, LspService, Server};
|
||||
|
||||
|
|
@ -28,13 +31,33 @@ struct Backend {
|
|||
root_uri: OnceCell<Option<Url>>,
|
||||
server_linter: ServerLinter,
|
||||
diagnostics_report_map: DashMap<String, Vec<DiagnosticReport>>,
|
||||
options: Mutex<Options>,
|
||||
}
|
||||
#[derive(Debug, Serialize, Deserialize, Default, PartialEq, PartialOrd, Clone, Copy)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum Run {
|
||||
OnSave,
|
||||
#[default]
|
||||
OnType,
|
||||
}
|
||||
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||
struct Options {
|
||||
run: Run,
|
||||
}
|
||||
|
||||
#[tower_lsp::async_trait]
|
||||
impl LanguageServer for Backend {
|
||||
async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult> {
|
||||
self.init(params.root_uri)?;
|
||||
let options = params.initialization_options.and_then(|mut value| {
|
||||
let settings = value.get_mut("settings")?.take();
|
||||
serde_json::from_value::<Options>(settings).ok()
|
||||
});
|
||||
|
||||
if let Some(value) = options {
|
||||
debug!("initialize: {:?}", value);
|
||||
*self.options.lock().await = value;
|
||||
}
|
||||
Ok(InitializeResult {
|
||||
server_info: Some(ServerInfo { name: "oxc".into(), version: None }),
|
||||
offset_encoding: None,
|
||||
|
|
@ -42,6 +65,13 @@ impl LanguageServer for Backend {
|
|||
text_document_sync: Some(TextDocumentSyncCapability::Kind(
|
||||
TextDocumentSyncKind::FULL,
|
||||
)),
|
||||
workspace: Some(WorkspaceServerCapabilities {
|
||||
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
|
||||
supported: Some(true),
|
||||
change_notifications: Some(OneOf::Left(true)),
|
||||
}),
|
||||
file_operations: None,
|
||||
}),
|
||||
code_action_provider: Some(CodeActionProviderCapability::Options(
|
||||
CodeActionOptions {
|
||||
code_action_kinds: Some(vec![CodeActionKind::QUICKFIX]),
|
||||
|
|
@ -56,7 +86,18 @@ impl LanguageServer for Backend {
|
|||
})
|
||||
}
|
||||
|
||||
async fn initialized(&self, _: InitializedParams) {
|
||||
async fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
|
||||
let changed_options = match serde_json::from_value::<Options>(params.settings) {
|
||||
Ok(option) => option,
|
||||
Err(err) => {
|
||||
error!("error parsing settings: {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
*self.options.lock().await = changed_options;
|
||||
}
|
||||
|
||||
async fn initialized(&self, params: InitializedParams) {
|
||||
debug!("oxc initialized.");
|
||||
|
||||
if let Some(Some(root_uri)) = self.root_uri.get() {
|
||||
|
|
@ -79,12 +120,21 @@ impl LanguageServer for Backend {
|
|||
|
||||
async fn did_save(&self, params: DidSaveTextDocumentParams) {
|
||||
debug!("oxc server did save");
|
||||
// drop as fast as possible
|
||||
let options = { self.options.lock().await.run };
|
||||
if options < Run::OnSave {
|
||||
return;
|
||||
}
|
||||
self.handle_file_update(params.text_document.uri, None).await;
|
||||
}
|
||||
|
||||
/// When the document changed, it may not be written to disk, so we should
|
||||
/// get the file context from the language client
|
||||
async fn did_change(&self, params: DidChangeTextDocumentParams) {
|
||||
let options = { self.options.lock().await.run };
|
||||
if options < Run::OnType {
|
||||
return;
|
||||
}
|
||||
let content = params.content_changes.first().map(|c| c.text.clone());
|
||||
self.handle_file_update(params.text_document.uri, content).await;
|
||||
}
|
||||
|
|
@ -192,6 +242,7 @@ async fn main() {
|
|||
root_uri: OnceCell::new(),
|
||||
server_linter,
|
||||
diagnostics_report_map,
|
||||
options: tokio::sync::Mutex::new(Options::default()),
|
||||
})
|
||||
.finish();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue