feat: introduce --compute-indices flag to codex-file-search (#1419)
This is a small quality-of-life feature, the addition of `--compute-indices` to the CLI, which, if enabled, will compute and set the `indices` field for each `FileMatch` returned by `run()`. Note we only bother to compute `indices` once we have the top N results because there could be a lot of intermediate "top N" results during the search that are ultimately discarded. When set, the indices are included in the JSON output when `--json` is specified and the matching indices are displayed in bold when `--json` is not specified.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
use std::io::IsTerminal;
|
||||
use std::path::Path;
|
||||
|
||||
use clap::Parser;
|
||||
use codex_file_search::Cli;
|
||||
use codex_file_search::FileMatch;
|
||||
use codex_file_search::Reporter;
|
||||
use codex_file_search::run_main;
|
||||
use serde_json::json;
|
||||
@@ -11,6 +13,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let cli = Cli::parse();
|
||||
let reporter = StdioReporter {
|
||||
write_output_as_json: cli.json,
|
||||
show_indices: cli.compute_indices && std::io::stdout().is_terminal(),
|
||||
};
|
||||
run_main(cli, reporter).await?;
|
||||
Ok(())
|
||||
@@ -18,15 +21,40 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
struct StdioReporter {
|
||||
write_output_as_json: bool,
|
||||
show_indices: bool,
|
||||
}
|
||||
|
||||
impl Reporter for StdioReporter {
|
||||
fn report_match(&self, file: &str, score: u32) {
|
||||
fn report_match(&self, file_match: &FileMatch) {
|
||||
if self.write_output_as_json {
|
||||
let value = json!({ "file": file, "score": score });
|
||||
println!("{}", serde_json::to_string(&value).unwrap());
|
||||
println!("{}", serde_json::to_string(&file_match).unwrap());
|
||||
} else if self.show_indices {
|
||||
let indices = file_match
|
||||
.indices
|
||||
.as_ref()
|
||||
.expect("--compute-indices was specified");
|
||||
// `indices` is guaranteed to be sorted in ascending order. Instead
|
||||
// of calling `contains` for every character (which would be O(N^2)
|
||||
// in the worst-case), walk through the `indices` vector once while
|
||||
// iterating over the characters.
|
||||
let mut indices_iter = indices.iter().peekable();
|
||||
|
||||
for (i, c) in file_match.path.chars().enumerate() {
|
||||
match indices_iter.peek() {
|
||||
Some(next) if **next == i as u32 => {
|
||||
// ANSI escape code for bold: \x1b[1m ... \x1b[0m
|
||||
print!("\x1b[1m{}\x1b[0m", c);
|
||||
// advance the iterator since we've consumed this index
|
||||
indices_iter.next();
|
||||
}
|
||||
_ => {
|
||||
print!("{}", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
println!();
|
||||
} else {
|
||||
println!("{file}");
|
||||
println!("{}", file_match.path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user