mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
feat: add option to control enable/disable oxc linter (#1665)
1. Closed https://github.com/oxc-project/oxc/issues/1655
This commit is contained in:
parent
d719af473c
commit
e529b38e32
3 changed files with 122 additions and 15 deletions
|
|
@ -1,4 +1,13 @@
|
|||
import { ExtensionContext, window, commands, workspace } from "vscode";
|
||||
import {
|
||||
ExtensionContext,
|
||||
window,
|
||||
commands,
|
||||
workspace,
|
||||
StatusBarItem,
|
||||
StatusBarAlignment,
|
||||
ConfigurationTarget,
|
||||
ThemeColor,
|
||||
} from "vscode";
|
||||
|
||||
import {
|
||||
Executable,
|
||||
|
|
@ -19,10 +28,13 @@ const enum OxcCommands {
|
|||
ApplyAllFixes = "oxc.applyAllFixes",
|
||||
ShowOutputChannel = "oxc.showOutputChannel",
|
||||
ShowTraceOutputChannel = "oxc.showTraceOutputChannel",
|
||||
ToggleEnable = "oxc.toggleEnable",
|
||||
}
|
||||
|
||||
let client: LanguageClient;
|
||||
|
||||
let myStatusBarItem: StatusBarItem;
|
||||
|
||||
export async function activate(context: ExtensionContext) {
|
||||
const restartCommand = commands.registerCommand(
|
||||
OxcCommands.RestartServer,
|
||||
|
|
@ -60,10 +72,22 @@ export async function activate(context: ExtensionContext) {
|
|||
},
|
||||
);
|
||||
|
||||
const toggleEnable = commands.registerCommand(
|
||||
OxcCommands.ToggleEnable,
|
||||
() => {
|
||||
let enabled = workspace.getConfiguration("oxc-client").get("enable");
|
||||
let nextState = !enabled;
|
||||
workspace
|
||||
.getConfiguration("oxc-client")
|
||||
.update("enable", nextState, ConfigurationTarget.Global);
|
||||
},
|
||||
);
|
||||
|
||||
context.subscriptions.push(
|
||||
restartCommand,
|
||||
showOutputCommand,
|
||||
showTraceOutputCommand,
|
||||
toggleEnable,
|
||||
);
|
||||
|
||||
const outputChannel = window.createOutputChannel(outputChannelName);
|
||||
|
|
@ -101,7 +125,10 @@ export async function activate(context: ExtensionContext) {
|
|||
"javascript",
|
||||
"typescriptreact",
|
||||
"javascriptreact",
|
||||
].map((lang) => ({ language: lang, scheme: "file" })),
|
||||
].map((lang) => ({
|
||||
language: lang,
|
||||
scheme: "file",
|
||||
})),
|
||||
synchronize: {
|
||||
// Notify the server about file changes to '.clientrc files contained in the workspace
|
||||
fileEvents: workspace.createFileSystemWatcher("**/.clientrc"),
|
||||
|
|
@ -121,15 +148,34 @@ export async function activate(context: ExtensionContext) {
|
|||
clientOptions,
|
||||
);
|
||||
workspace.onDidChangeConfiguration((e) => {
|
||||
let settings: any = {};
|
||||
if (e.affectsConfiguration("oxc-client.run")) {
|
||||
settings.run = workspace.getConfiguration("oxc-client").get("run");
|
||||
}
|
||||
let settings: any = JSON.parse(
|
||||
JSON.stringify(workspace.getConfiguration("oxc-client")),
|
||||
);
|
||||
updateStatsBar(settings.enable);
|
||||
client.sendNotification("workspace/didChangeConfiguration", {
|
||||
settings,
|
||||
});
|
||||
});
|
||||
|
||||
function updateStatsBar(enable: boolean) {
|
||||
if (!myStatusBarItem) {
|
||||
myStatusBarItem = window.createStatusBarItem(
|
||||
StatusBarAlignment.Right,
|
||||
100,
|
||||
);
|
||||
myStatusBarItem.command = OxcCommands.ToggleEnable;
|
||||
context.subscriptions.push(myStatusBarItem);
|
||||
myStatusBarItem.show();
|
||||
}
|
||||
let bgColor = new ThemeColor(
|
||||
enable
|
||||
? "statusBarItem.activeBackground"
|
||||
: "statusBarItem.errorBackground",
|
||||
);
|
||||
myStatusBarItem.text = `oxc: ${enable ? "on" : "off"}`;
|
||||
myStatusBarItem.backgroundColor = bgColor;
|
||||
}
|
||||
updateStatsBar(clientConfig.enable);
|
||||
client.start();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@
|
|||
"title": "Restart Oxc Server",
|
||||
"category": "Oxc"
|
||||
},
|
||||
{
|
||||
"command": "oxc.toggleEnable",
|
||||
"title": "toggle enable",
|
||||
"category": "Oxc"
|
||||
},
|
||||
{
|
||||
"command": "oxc.showOutputChannel",
|
||||
"title": "Show Output Channel",
|
||||
|
|
@ -67,6 +72,11 @@
|
|||
"default": "onType",
|
||||
"description": "Run the linter on save (onSave) or on type (onType)"
|
||||
},
|
||||
"oxc-client.enable": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "enable oxc linter"
|
||||
},
|
||||
"oxc-client.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
|
|||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use futures::future::join_all;
|
||||
|
|
@ -17,11 +18,11 @@ use tower_lsp::jsonrpc::{Error, ErrorCode, Result};
|
|||
use tower_lsp::lsp_types::{
|
||||
CodeAction, CodeActionKind, CodeActionOptions, CodeActionOrCommand, CodeActionParams,
|
||||
CodeActionProviderCapability, CodeActionResponse, Diagnostic, DidChangeConfigurationParams,
|
||||
DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams,
|
||||
InitializeParams, InitializeResult, InitializedParams, MessageType, OneOf, Registration,
|
||||
ServerCapabilities, ServerInfo, TextDocumentSyncCapability, TextDocumentSyncKind, TextEdit,
|
||||
Url, WorkDoneProgressOptions, WorkspaceEdit, WorkspaceFoldersServerCapabilities,
|
||||
WorkspaceServerCapabilities,
|
||||
DidChangeTextDocumentParams, DidCloseTextDocumentParams, 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};
|
||||
|
||||
|
|
@ -43,6 +44,27 @@ enum Run {
|
|||
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||
struct Options {
|
||||
run: Run,
|
||||
enable: bool,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
fn get_lint_level(&self) -> SyntheticRunLevel {
|
||||
if self.enable {
|
||||
match self.run {
|
||||
Run::OnSave => SyntheticRunLevel::OnSave,
|
||||
Run::OnType => SyntheticRunLevel::OnType,
|
||||
}
|
||||
} else {
|
||||
SyntheticRunLevel::Disable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd, Clone, Copy)]
|
||||
enum SyntheticRunLevel {
|
||||
Disable,
|
||||
OnSave,
|
||||
OnType,
|
||||
}
|
||||
|
||||
#[tower_lsp::async_trait]
|
||||
|
|
@ -94,6 +116,25 @@ impl LanguageServer for Backend {
|
|||
return;
|
||||
}
|
||||
};
|
||||
debug!("{:?}", &changed_options.get_lint_level());
|
||||
if changed_options.get_lint_level() == SyntheticRunLevel::Disable {
|
||||
// clear all exists diagnostics when linter is disabled
|
||||
let opened_files = self.diagnostics_report_map.iter().map(|k| k.key().to_string());
|
||||
let cleared_diagnostics = opened_files
|
||||
.into_iter()
|
||||
.map(|uri| {
|
||||
(
|
||||
// should convert successfully, case the key is from `params.document.uri`
|
||||
Url::from_str(&uri)
|
||||
.ok()
|
||||
.and_then(|url| url.to_file_path().ok())
|
||||
.expect("should convert to path"),
|
||||
vec![],
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
self.publish_all_diagnostics(&cleared_diagnostics).await;
|
||||
}
|
||||
*self.options.lock().await = changed_options;
|
||||
}
|
||||
|
||||
|
|
@ -121,8 +162,8 @@ 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 {
|
||||
let run_level = { self.options.lock().await.get_lint_level() };
|
||||
if run_level < SyntheticRunLevel::OnSave {
|
||||
return;
|
||||
}
|
||||
self.handle_file_update(params.text_document.uri, None).await;
|
||||
|
|
@ -131,8 +172,8 @@ impl LanguageServer for Backend {
|
|||
/// 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 {
|
||||
let run_level = { self.options.lock().await.get_lint_level() };
|
||||
if run_level < SyntheticRunLevel::OnType {
|
||||
return;
|
||||
}
|
||||
let content = params.content_changes.first().map(|c| c.text.clone());
|
||||
|
|
@ -140,9 +181,18 @@ impl LanguageServer for Backend {
|
|||
}
|
||||
|
||||
async fn did_open(&self, params: DidOpenTextDocumentParams) {
|
||||
let run_level = { self.options.lock().await.get_lint_level() };
|
||||
if run_level < SyntheticRunLevel::OnType {
|
||||
return;
|
||||
}
|
||||
self.handle_file_update(params.text_document.uri, None).await;
|
||||
}
|
||||
|
||||
async fn did_close(&self, params: DidCloseTextDocumentParams) {
|
||||
let uri = params.text_document.uri.to_string();
|
||||
self.diagnostics_report_map.remove(&uri);
|
||||
}
|
||||
|
||||
async fn code_action(&self, params: CodeActionParams) -> Result<Option<CodeActionResponse>> {
|
||||
let uri = params.text_document.uri;
|
||||
|
||||
|
|
@ -199,6 +249,7 @@ impl Backend {
|
|||
|
||||
#[allow(clippy::ptr_arg)]
|
||||
async fn publish_all_diagnostics(&self, result: &Vec<(PathBuf, Vec<Diagnostic>)>) {
|
||||
debug!("{:?}", result);
|
||||
join_all(result.iter().map(|(path, diagnostics)| {
|
||||
self.client.publish_diagnostics(
|
||||
Url::from_file_path(path).unwrap(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue