diff --git a/harper-ls/src/diagnostics.rs b/harper-ls/src/diagnostics.rs index 780f1dea6..3aadb2718 100644 --- a/harper-ls/src/diagnostics.rs +++ b/harper-ls/src/diagnostics.rs @@ -25,6 +25,7 @@ pub fn lints_to_diagnostics( pub fn lint_to_code_actions<'a>( lint: &'a Lint, + others: &[&'a Lint], uri: &'a Uri, document: &Document, config: &CodeActionConfig, @@ -48,7 +49,27 @@ pub fn lint_to_code_actions<'a>( ), }; - Some(CodeAction { + let all_edits = if others.is_empty() { + None + } else { + Some( + Some(TextEdit { + range, + new_text: replace_string.clone(), + }) + .into_iter() + .chain(others.iter().map(|other| { + let range = span_to_range(source, other.span); + TextEdit { + range, + new_text: replace_string.clone(), + } + })) + .collect::>(), + ) + }; + + let this_edit_action = CodeAction { title: suggestion.to_string(), kind: Some(CodeActionKind::QUICKFIX), diagnostics: None, @@ -73,7 +94,18 @@ pub fn lint_to_code_actions<'a>( is_preferred: None, disabled: None, data: None, - }) + }; + + let all_edits = all_edits.map(|edits| { + let mut do_all = this_edit_action.clone(); + do_all.title = do_all.title.replace("Replace ", "Replace all in document "); + if let Some(e) = do_all.edit.as_mut() { + e.changes = Some(HashMap::from([(uri.clone(), edits)])); + } + do_all + }); + + all_edits.into_iter().chain(Some(this_edit_action)) }) .map(CodeActionOrCommand::CodeAction), ); diff --git a/harper-ls/src/document_state.rs b/harper-ls/src/document_state.rs index 548cee032..4899eccc4 100644 --- a/harper-ls/src/document_state.rs +++ b/harper-ls/src/document_state.rs @@ -61,10 +61,15 @@ impl DocumentState { let span = range_to_span(source_chars, range).with_len(1); let mut actions: Vec = lints - .into_iter() + .iter() .filter(|lint| lint.span.overlaps_with(span)) .flat_map(|lint| { - lint_to_code_actions(&lint, &self.uri, &self.document, code_action_config) + let others = lints + .iter() + .filter(|other| other.spanless_hash() == lint.spanless_hash()) + .filter(|other| *other != lint) + .collect::>(); + lint_to_code_actions(lint, &others, &self.uri, &self.document, code_action_config) }) .collect();