Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ Bench / `sift-profile`: package + features in `crates/core/benches/README.md` an
- Prefer fixing lints over `#[allow(clippy::…)]` unless there is a rare, documented reason.
- Larger roadmap slices: **one branch per slice**, PR, merge, then start the next slice from an updated default branch — details in `plan.md` when present.

### Branch names

Use **short, descriptive kebab-case** names so history and open PRs stay readable. Prefer a **type prefix** when it fits:

| Prefix | Use for |
|--------|---------|
| `feat/` | New behavior, flags, or API |
| `fix/` | Bug fixes, regressions |
| `docs/` | Documentation only |
| `chore/` | Tooling, CI, refactors with no user-visible change |

**Good:** `feat/stats-elapsed`, `fix/ignore-git-without-repo`, `docs/rg-compat-matrix`
**Avoid:** opaque labels like `phase-4` or `wip` with no topic — they force readers to open the PR to learn what changed.

Rename a local branch before push: `git branch -m old-name new-name`, then `git push -u origin new-name` (and delete the old remote branch if it was already pushed).

## Core API (entry points)

`IndexBuilder::build`, `Index::open`, `CompiledSearch::new`, then indexed `run_index` or walk-based search as in `crates/core/README.md`.
1 change: 1 addition & 0 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,7 @@ fn build_search_filter_config(
fn write_search_stats(stats: &SearchStats) {
eprintln!("{} matches", stats.matches);
eprintln!("{} files searched", stats.files_searched);
eprintln!("{:.6}s elapsed", stats.elapsed.as_secs_f64());
}

fn run_search_with_index(
Expand Down
4 changes: 4 additions & 0 deletions crates/cli/tests/integration_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ fn stats_reports_matches_and_files_searched() {
stderr.contains("1 files searched"),
"expected files searched in stderr, got: {stderr:?}"
);
assert!(
stderr.contains("s elapsed"),
"expected elapsed line in stderr, got: {stderr:?}"
);
}
5 changes: 5 additions & 0 deletions crates/core/src/search/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::io::{self, IsTerminal, Write};
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::time::Instant;

use grep_matcher::Matcher;
use grep_regex::RegexMatcher;
Expand Down Expand Up @@ -128,6 +129,7 @@ impl CompiledSearch {
}

// Stage 4: Build matcher (once per `CompiledSearch`) and search
let search_start = Instant::now();
let matcher = self.matcher.get_or_try_init(|| self.build_matcher())?;
let parallel = candidates.len() >= threshold;

Expand Down Expand Up @@ -159,6 +161,7 @@ impl CompiledSearch {
| SearchMode::FilesWithMatches
| SearchMode::FilesWithoutMatch => summary_counter.load(Ordering::Relaxed),
};
s.elapsed = search_start.elapsed();
}

Ok(ok)
Expand Down Expand Up @@ -225,6 +228,7 @@ impl CompiledSearch {
return Ok(false);
}

let search_start = Instant::now();
let matcher = self.matcher.get_or_try_init(|| self.build_matcher())?;
let parallel = candidates.len() >= threshold;

Expand Down Expand Up @@ -256,6 +260,7 @@ impl CompiledSearch {
| SearchMode::FilesWithMatches
| SearchMode::FilesWithoutMatch => summary_counter.load(Ordering::Relaxed),
};
s.elapsed = search_start.elapsed();
}

Ok(ok)
Expand Down
6 changes: 6 additions & 0 deletions crates/core/src/search/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::path::PathBuf;
use std::sync::Mutex;
use std::time::Duration;

use grep_regex::RegexMatcher;
use grep_searcher::Searcher;
Expand Down Expand Up @@ -185,12 +186,17 @@ impl Default for SearchOutput {
///
/// `matches` is mode-dependent: line hits for standard / only-matching / count modes,
/// one per matching file for `-l`, and one per listed file for `--files-without-match`.
///
/// `elapsed` covers wall time for the search stage (matcher build + scanning candidates), not
/// index open or filter prep.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct SearchStats {
/// Files searched after filtering (same length as the candidate list).
pub files_searched: usize,
/// Mode-dependent match tally (see struct docs).
pub matches: usize,
/// Wall-clock time spent in the search phase after candidates are ready.
pub elapsed: Duration,
}

#[derive(Debug)]
Expand Down
2 changes: 1 addition & 1 deletion docs/rg-compat-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ back each implemented row with Rust tests that run `rg` and `sift` side by side.
| Ignore / git defaults | `ripgrep/crates/ignore`, `ripgrep/crates/core/flags/defs.rs` | Partial | Hidden and glob basics exist; no full `--no-ignore*` family yet. |
| Context output (`-A/-B/-C`) | `ripgrep/crates/core/flags/defs.rs`, `ripgrep/tests/misc.rs` (`after_context`) | Implemented | See `integration_context.rs`; rg golden tests still TODO. |
| Color / separators / null | `ripgrep/crates/printer/src/standard.rs`, `ripgrep/crates/printer/src/summary.rs` | Implemented | `--color`, `-0` / `--null`; see `integration_null_color.rs`. |
| `--stats` | `ripgrep/crates/printer/stats.rs` (approx.) | Partial | Two lines on stderr: match tally + files searched; no bytes/time yet. |
| `--stats` | `ripgrep/crates/printer/stats.rs` (approx.) | Partial | Match tally, files searched, elapsed seconds on stderr; bytes scanned not yet. |
| Encoding / multiline | `ripgrep/crates/core/flags/defs.rs`, `ripgrep/tests/json.rs`, `ripgrep/tests/multiline.rs` | Missing | In scope, but after basic output parity lands. |
| `--json`, `--vimgrep`, `--stats`, `--debug` | `ripgrep/tests/json.rs`, `ripgrep/tests/misc.rs` (`vimgrep`) | Missing | In scope for non-engine parity. |
| `-P` / PCRE2 | `ripgrep/crates/pcre2`, `ripgrep/crates/core/flags/defs.rs` | Deferred | Explicitly out of scope for the current parity phase. |
Loading