internal: unify subcommand handling between ra and xtask
This commit is contained in:
@@ -1,72 +1,86 @@
|
||||
//! Applies structured search replace rules from the command line.
|
||||
|
||||
use ide_ssr::MatchFinder;
|
||||
use project_model::CargoConfig;
|
||||
|
||||
use crate::cli::{
|
||||
flags,
|
||||
load_cargo::{load_workspace_at, LoadCargoConfig},
|
||||
Result,
|
||||
};
|
||||
use ide_ssr::{MatchFinder, SsrPattern, SsrRule};
|
||||
use project_model::CargoConfig;
|
||||
|
||||
pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
let cargo_config = CargoConfig::default();
|
||||
let load_cargo_config = LoadCargoConfig {
|
||||
load_out_dirs_from_check: true,
|
||||
with_proc_macro: true,
|
||||
prefill_caches: false,
|
||||
};
|
||||
let (host, vfs, _proc_macro) =
|
||||
load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?;
|
||||
let db = host.raw_database();
|
||||
let mut match_finder = MatchFinder::at_first_file(db)?;
|
||||
for rule in rules {
|
||||
match_finder.add_rule(rule)?;
|
||||
}
|
||||
let edits = match_finder.edits();
|
||||
for (file_id, edit) in edits {
|
||||
if let Some(path) = vfs.file_path(file_id).as_path() {
|
||||
let mut contents = db.file_text(file_id).to_string();
|
||||
edit.apply(&mut contents);
|
||||
std::fs::write(path, contents)?;
|
||||
impl flags::Ssr {
|
||||
pub fn run(self) -> Result<()> {
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
let cargo_config = CargoConfig::default();
|
||||
let load_cargo_config = LoadCargoConfig {
|
||||
load_out_dirs_from_check: true,
|
||||
with_proc_macro: true,
|
||||
prefill_caches: false,
|
||||
};
|
||||
let (host, vfs, _proc_macro) = load_workspace_at(
|
||||
&std::env::current_dir()?,
|
||||
&cargo_config,
|
||||
&load_cargo_config,
|
||||
&|_| {},
|
||||
)?;
|
||||
let db = host.raw_database();
|
||||
let mut match_finder = MatchFinder::at_first_file(db)?;
|
||||
for rule in self.rule {
|
||||
match_finder.add_rule(rule)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Searches for `patterns`, printing debug information for any nodes whose text exactly matches
|
||||
/// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful
|
||||
/// for much else.
|
||||
pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> {
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
use ide_db::symbol_index::SymbolsDatabase;
|
||||
let cargo_config = CargoConfig::default();
|
||||
let load_cargo_config = LoadCargoConfig {
|
||||
load_out_dirs_from_check: true,
|
||||
with_proc_macro: true,
|
||||
prefill_caches: false,
|
||||
};
|
||||
let (host, _vfs, _proc_macro) =
|
||||
load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?;
|
||||
let db = host.raw_database();
|
||||
let mut match_finder = MatchFinder::at_first_file(db)?;
|
||||
for pattern in patterns {
|
||||
match_finder.add_search_pattern(pattern)?;
|
||||
}
|
||||
if let Some(debug_snippet) = &debug_snippet {
|
||||
for &root in db.local_roots().iter() {
|
||||
let sr = db.source_root(root);
|
||||
for file_id in sr.iter() {
|
||||
for debug_info in match_finder.debug_where_text_equal(file_id, debug_snippet) {
|
||||
println!("{:#?}", debug_info);
|
||||
}
|
||||
let edits = match_finder.edits();
|
||||
for (file_id, edit) in edits {
|
||||
if let Some(path) = vfs.file_path(file_id).as_path() {
|
||||
let mut contents = db.file_text(file_id).to_string();
|
||||
edit.apply(&mut contents);
|
||||
std::fs::write(path, contents)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for m in match_finder.matches().flattened().matches {
|
||||
// We could possibly at some point do something more useful than just printing
|
||||
// the matched text. For now though, that's the easiest thing to do.
|
||||
println!("{}", m.matched_text());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl flags::Search {
|
||||
/// Searches for `patterns`, printing debug information for any nodes whose text exactly matches
|
||||
/// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful
|
||||
/// for much else.
|
||||
pub fn run(self) -> Result<()> {
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
use ide_db::symbol_index::SymbolsDatabase;
|
||||
let cargo_config = CargoConfig::default();
|
||||
let load_cargo_config = LoadCargoConfig {
|
||||
load_out_dirs_from_check: true,
|
||||
with_proc_macro: true,
|
||||
prefill_caches: false,
|
||||
};
|
||||
let (host, _vfs, _proc_macro) = load_workspace_at(
|
||||
&std::env::current_dir()?,
|
||||
&cargo_config,
|
||||
&load_cargo_config,
|
||||
&|_| {},
|
||||
)?;
|
||||
let db = host.raw_database();
|
||||
let mut match_finder = MatchFinder::at_first_file(db)?;
|
||||
for pattern in self.pattern {
|
||||
match_finder.add_search_pattern(pattern)?;
|
||||
}
|
||||
if let Some(debug_snippet) = &self.debug {
|
||||
for &root in db.local_roots().iter() {
|
||||
let sr = db.source_root(root);
|
||||
for file_id in sr.iter() {
|
||||
for debug_info in match_finder.debug_where_text_equal(file_id, debug_snippet) {
|
||||
println!("{:#?}", debug_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for m in match_finder.matches().flattened().matches {
|
||||
// We could possibly at some point do something more useful than just printing
|
||||
// the matched text. For now though, that's the easiest thing to do.
|
||||
println!("{}", m.matched_text());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user