mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
fix(vscode): don't lint files in .gitignore and .eslintignore (#1765)
Closed https://github.com/oxc-project/oxc/issues/1752
This commit is contained in:
parent
2e707bc1c7
commit
fc7c857f80
3 changed files with 59 additions and 4 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1987,6 +1987,7 @@ dependencies = [
|
|||
"dashmap",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"globset",
|
||||
"ignore",
|
||||
"log",
|
||||
"miette",
|
||||
|
|
|
|||
|
|
@ -39,3 +39,4 @@ tower-lsp = { workspace = true, features = ["proposed"] }
|
|||
log = "0.4.20"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
globset = "0.4.14"
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@ mod options;
|
|||
mod walk;
|
||||
|
||||
use crate::linter::{DiagnosticReport, ServerLinter};
|
||||
use globset::Glob;
|
||||
use ignore::gitignore::Gitignore;
|
||||
use log::{debug, error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use dashmap::DashMap;
|
||||
|
|
@ -33,6 +35,7 @@ struct Backend {
|
|||
server_linter: ServerLinter,
|
||||
diagnostics_report_map: DashMap<String, Vec<DiagnosticReport>>,
|
||||
options: Mutex<Options>,
|
||||
gitignore_glob: Mutex<Option<Gitignore>>,
|
||||
}
|
||||
#[derive(Debug, Serialize, Deserialize, Default, PartialEq, PartialOrd, Clone, Copy)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
@ -71,6 +74,7 @@ enum SyntheticRunLevel {
|
|||
impl LanguageServer for Backend {
|
||||
async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult> {
|
||||
self.init(params.root_uri)?;
|
||||
self.init_ignore_glob().await;
|
||||
let options = params.initialization_options.and_then(|mut value| {
|
||||
let settings = value.get_mut("settings")?.take();
|
||||
serde_json::from_value::<Options>(settings).ok()
|
||||
|
|
@ -166,6 +170,9 @@ impl LanguageServer for Backend {
|
|||
if run_level < SyntheticRunLevel::OnSave {
|
||||
return;
|
||||
}
|
||||
if self.is_ignored(¶ms.text_document.uri).await {
|
||||
return;
|
||||
}
|
||||
self.handle_file_update(params.text_document.uri, None).await;
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +183,10 @@ impl LanguageServer for Backend {
|
|||
if run_level < SyntheticRunLevel::OnType {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.is_ignored(¶ms.text_document.uri).await {
|
||||
return;
|
||||
}
|
||||
let content = params.content_changes.first().map(|c| c.text.clone());
|
||||
self.handle_file_update(params.text_document.uri, content).await;
|
||||
}
|
||||
|
|
@ -185,6 +196,9 @@ impl LanguageServer for Backend {
|
|||
if run_level < SyntheticRunLevel::OnType {
|
||||
return;
|
||||
}
|
||||
if self.is_ignored(¶ms.text_document.uri).await {
|
||||
return;
|
||||
}
|
||||
self.handle_file_update(params.text_document.uri, None).await;
|
||||
}
|
||||
|
||||
|
|
@ -244,12 +258,42 @@ impl Backend {
|
|||
};
|
||||
|
||||
Error { code: ErrorCode::ParseError, message, data: None }
|
||||
})
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn init_ignore_glob(&self) {
|
||||
let uri = self
|
||||
.root_uri
|
||||
.get()
|
||||
.expect("The root uri should be initialized already")
|
||||
.as_ref()
|
||||
.expect("should get uri");
|
||||
let mut builder = globset::GlobSetBuilder::new();
|
||||
// Collecting all ignore files
|
||||
builder.add(Glob::new("**/.eslintignore").unwrap());
|
||||
builder.add(Glob::new("**/.gitignore").unwrap());
|
||||
|
||||
let ignore_file_glob_set = builder.build().unwrap();
|
||||
|
||||
let mut gitignore_builder = ignore::gitignore::GitignoreBuilder::new(uri.path());
|
||||
let walk = ignore::WalkBuilder::new(uri.path())
|
||||
.ignore(true)
|
||||
.hidden(false)
|
||||
.git_global(false)
|
||||
.build();
|
||||
for entry in walk.flatten() {
|
||||
if ignore_file_glob_set.is_match(entry.path()) {
|
||||
gitignore_builder.add(entry.path());
|
||||
}
|
||||
}
|
||||
|
||||
*self.gitignore_glob.lock().await = gitignore_builder.build().ok();
|
||||
}
|
||||
|
||||
#[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(),
|
||||
|
|
@ -276,6 +320,14 @@ impl Backend {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn is_ignored(&self, uri: &Url) -> bool {
|
||||
let Some(ref gitignore_globs) = *self.gitignore_glob.lock().await else {
|
||||
return false;
|
||||
};
|
||||
let path = PathBuf::from(uri.path());
|
||||
gitignore_globs.matched_path_or_any_parents(&path, path.is_dir()).is_ignore()
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
@ -293,7 +345,8 @@ async fn main() {
|
|||
root_uri: OnceCell::new(),
|
||||
server_linter,
|
||||
diagnostics_report_map,
|
||||
options: tokio::sync::Mutex::new(Options::default()),
|
||||
options: Mutex::new(Options::default()),
|
||||
gitignore_glob: Mutex::new(None),
|
||||
})
|
||||
.finish();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue