diff options
author | Satya Rohith <me@satyarohith.com> | 2021-06-21 12:13:35 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-21 16:43:35 +1000 |
commit | 952caa79b32e6c249977281ed494d4b1f98ed451 (patch) | |
tree | 3f072fc64b571eca1b203fb07df3689ad4fc3a95 /cli/lsp/analysis.rs | |
parent | bbc2745350687f209c6af75958cc12bb43e64042 (diff) |
feat(lsp): quick fix actions to ignore lint errors (#10627)
Closes #10122
Diffstat (limited to 'cli/lsp/analysis.rs')
-rw-r--r-- | cli/lsp/analysis.rs | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index 2235a2c83..f3af5fc8d 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -5,6 +5,7 @@ use super::tsc; use crate::ast; use crate::import_map::ImportMap; +use crate::lsp::documents::DocumentData; use crate::media_type::MediaType; use crate::module_graph::parse_deno_types; use crate::module_graph::parse_ts_reference; @@ -619,6 +620,7 @@ pub struct DenoFixData { #[derive(Debug, Clone)] enum CodeActionKind { Deno(lsp::CodeAction), + DenoLint(lsp::CodeAction), Tsc(lsp::CodeAction, tsc::CodeFixAction), } @@ -665,6 +667,106 @@ impl CodeActionCollection { Ok(()) } + pub(crate) fn add_deno_lint_ignore_action( + &mut self, + specifier: &ModuleSpecifier, + document: Option<&DocumentData>, + diagnostic: &lsp::Diagnostic, + ) -> Result<(), AnyError> { + let code = diagnostic + .code + .as_ref() + .map(|v| match v { + lsp::NumberOrString::String(v) => v.to_owned(), + _ => "".to_string(), + }) + .unwrap(); + + let line_content = if let Some(doc) = document { + doc + .content_line(diagnostic.range.start.line as usize) + .ok() + .flatten() + } else { + None + }; + + let mut changes = HashMap::new(); + changes.insert( + specifier.clone(), + vec![lsp::TextEdit { + new_text: prepend_whitespace( + format!("// deno-lint-ignore {}\n", code), + line_content, + ), + range: lsp::Range { + start: lsp::Position { + line: diagnostic.range.start.line, + character: 0, + }, + end: lsp::Position { + line: diagnostic.range.start.line, + character: 0, + }, + }, + }], + ); + let ignore_error_action = lsp::CodeAction { + title: format!("Disable {} for this line", code), + kind: Some(lsp::CodeActionKind::QUICKFIX), + diagnostics: Some(vec![diagnostic.clone()]), + command: None, + is_preferred: None, + disabled: None, + data: None, + edit: Some(lsp::WorkspaceEdit { + changes: Some(changes), + change_annotations: None, + document_changes: None, + }), + }; + self + .actions + .push(CodeActionKind::DenoLint(ignore_error_action)); + + let mut changes = HashMap::new(); + changes.insert( + specifier.clone(), + vec![lsp::TextEdit { + new_text: "// deno-lint-ignore-file\n".to_string(), + range: lsp::Range { + start: lsp::Position { + line: 0, + character: 0, + }, + end: lsp::Position { + line: 0, + character: 0, + }, + }, + }], + ); + let ignore_file_action = lsp::CodeAction { + title: "Ignore lint errors for the entire file".to_string(), + kind: Some(lsp::CodeActionKind::QUICKFIX), + diagnostics: Some(vec![diagnostic.clone()]), + command: None, + is_preferred: None, + disabled: None, + data: None, + edit: Some(lsp::WorkspaceEdit { + changes: Some(changes), + change_annotations: None, + document_changes: None, + }), + }; + self + .actions + .push(CodeActionKind::DenoLint(ignore_file_action)); + + Ok(()) + } + /// Add a TypeScript code fix action to the code actions collection. pub(crate) async fn add_ts_fix_action( &mut self, @@ -779,6 +881,7 @@ impl CodeActionCollection { .map(|i| match i { CodeActionKind::Tsc(c, _) => lsp::CodeActionOrCommand::CodeAction(c), CodeActionKind::Deno(c) => lsp::CodeActionOrCommand::CodeAction(c), + CodeActionKind::DenoLint(c) => lsp::CodeActionOrCommand::CodeAction(c), }) .collect() } @@ -833,6 +936,18 @@ impl CodeActionCollection { } } +/// Prepend the whitespace characters found at the start of line_content to content. +fn prepend_whitespace(content: String, line_content: Option<String>) -> String { + if let Some(line) = line_content { + let whitespaces = + line.chars().position(|c| !c.is_whitespace()).unwrap_or(0); + let whitespace = &line[0..whitespaces]; + format!("{}{}", &whitespace, content) + } else { + content + } +} + #[cfg(test)] mod tests { use super::*; |