use anyhow::Result;
use prism::{index::ProjectIndex, search::lexical_search};
pub fn handle(query: String, top_k: usize) -> Result<()> {
let root = std::env::current_dir()
.unwrap_or_else(|_| std::path::PathBuf::from("."))
.to_string_lossy()
.to_string();
let index_path = std::path::Path::new(&root).join(".bctx").join("index.json");
let index = if index_path.exists() {
let json = std::fs::read_to_string(&index_path).unwrap_or_default();
serde_json::from_str::<ProjectIndex>(&json).unwrap_or_else(|_| ProjectIndex::new(&root))
} else {
ProjectIndex::new(&root)
};
let results = lexical_search(&index, &query, top_k);
if results.is_empty() {
println!("No results for \"{query}\".");
println!("Tip: run `bctx index` first to build the project index.");
return Ok(());
}
println!("bctx search: \"{query}\" — {} result(s)\n", results.len());
for (i, r) in results.iter().enumerate() {
let sym = r.symbol.as_deref().unwrap_or("");
if sym.is_empty() {
println!(" {}. {} (score: {:.2})", i + 1, r.path, r.score);
} else {
println!(
" {}. {} ::{} (score: {:.2})",
i + 1,
r.path,
sym,
r.score
);
}
if !r.snippet.is_empty() {
for line in r.snippet.lines().take(3) {
println!(" {line}");
}
}
println!();
}
Ok(())
}