aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/ssr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/ssr.rs')
-rw-r--r--crates/ra_ide/src/ssr.rs32
1 files changed, 26 insertions, 6 deletions
diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs
index 1873d1d0d..93e9aee1d 100644
--- a/crates/ra_ide/src/ssr.rs
+++ b/crates/ra_ide/src/ssr.rs
@@ -1,5 +1,3 @@
1//! structural search replace
2
3use std::{collections::HashMap, iter::once, str::FromStr}; 1use std::{collections::HashMap, iter::once, str::FromStr};
4 2
5use ra_db::{SourceDatabase, SourceDatabaseExt}; 3use ra_db::{SourceDatabase, SourceDatabaseExt};
@@ -25,6 +23,28 @@ impl std::fmt::Display for SsrError {
25 23
26impl std::error::Error for SsrError {} 24impl std::error::Error for SsrError {}
27 25
26// Feature: Structural Seach and Replace
27//
28// Search and replace with named wildcards that will match any expression.
29// The syntax for a structural search replace command is `<search_pattern> ==>> <replace_pattern>`.
30// A `$<name>:expr` placeholder in the search pattern will match any expression and `$<name>` will reference it in the replacement.
31// Available via the command `rust-analyzer.ssr`.
32//
33// ```rust
34// // Using structural search replace command [foo($a:expr, $b:expr) ==>> ($a).foo($b)]
35//
36// // BEFORE
37// String::from(foo(y + 5, z))
38//
39// // AFTER
40// String::from((y + 5).foo(z))
41// ```
42//
43// |===
44// | Editor | Action Name
45//
46// | VS Code | **Rust Analyzer: Structural Search Replace**
47// |===
28pub fn parse_search_replace( 48pub fn parse_search_replace(
29 query: &str, 49 query: &str,
30 parse_only: bool, 50 parse_only: bool,
@@ -196,10 +216,10 @@ fn find(pattern: &SsrPattern, code: &SyntaxNode) -> SsrMatches {
196 ) -> Option<Match> { 216 ) -> Option<Match> {
197 let match_ = check_opt_nodes(pattern.path(), code.path(), placeholders, match_)?; 217 let match_ = check_opt_nodes(pattern.path(), code.path(), placeholders, match_)?;
198 218
199 let mut pattern_fields = 219 let mut pattern_fields: Vec<RecordField> =
200 pattern.record_field_list().map(|x| x.fields().collect()).unwrap_or(vec![]); 220 pattern.record_field_list().map(|x| x.fields().collect()).unwrap_or_default();
201 let mut code_fields = 221 let mut code_fields: Vec<RecordField> =
202 code.record_field_list().map(|x| x.fields().collect()).unwrap_or(vec![]); 222 code.record_field_list().map(|x| x.fields().collect()).unwrap_or_default();
203 223
204 if pattern_fields.len() != code_fields.len() { 224 if pattern_fields.len() != code_fields.len() {
205 return None; 225 return None;