Feature: use heading-style output for `rtk grep`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 81.1k
- Forks
- 5.1k
- Avg merge
- 4d 21h
- Merged PRs (30d)
- 35
Description
rg uses heading-style output by default when printing to a TTY:
$ rg -n "FilterLevel" src
src/core/filter.rs
8:pub enum FilterLevel {
14:impl FromStr for FilterLevel {
19: "none" => Ok(FilterLevel::None),
20: "minimal" => Ok(FilterLevel::Minimal),
21: "aggressive" => Ok(FilterLevel::Aggressive),
27:impl std::fmt::Display for FilterLevel {
30: FilterLevel::None => write!(f, "none"),
31: FilterLevel::Minimal => write!(f, "minimal"),
32: FilterLevel::Aggressive => write!(f, "aggressive"),
315:pub fn get_filter(level: FilterLevel) -> Box<dyn FilterStrategy> {
317: FilterLevel::None => Box::new(NoFilter),
318: FilterLevel::Minimal => Box::new(MinimalFilter),
319: FilterLevel::Aggressive => Box::new(AggressiveFilter),
370: assert_eq!(FilterLevel::from_str("none").unwrap(), FilterLevel::None);
372: FilterLevel::from_str("minimal").unwrap(),
373: FilterLevel::Minimal
376: FilterLevel::from_str("aggressive").unwrap(),
377: FilterLevel::Aggressive
src/main.rs
101: level: core::filter::FilterLevel,
src/cmds/system/read.rs
3:use crate::core::filter::{self, FilterLevel, Language};
11: level: FilterLevel,
84: level: FilterLevel,
197: run(file.path(), FilterLevel::Minimal, None, None, false, 0)?;
src/cmds/system/README.md
7:- `read.rs` uses `core/filter` for language-aware code stripping (FilterLevel: none/minimal/aggressive)
But in agent cli, commands are usually captured through non-TTY stdout. In that case, rg defaults to grep-like output instead:
$ rg -n "FilterLevel" src > output.txt
$ cat output.txt
src/main.rs:101: level: core::filter::FilterLevel,
src/core/filter.rs:8:pub enum FilterLevel {
src/core/filter.rs:14:impl FromStr for FilterLevel {
src/core/filter.rs:19: "none" => Ok(FilterLevel::None),
src/core/filter.rs:20: "minimal" => Ok(FilterLevel::Minimal),
src/core/filter.rs:21: "aggressive" => Ok(FilterLevel::Aggressive),
src/core/filter.rs:27:impl std::fmt::Display for FilterLevel {
src/core/filter.rs:30: FilterLevel::None => write!(f, "none"),
src/core/filter.rs:31: FilterLevel::Minimal => write!(f, "minimal"),
src/core/filter.rs:32: FilterLevel::Aggressive => write!(f, "aggressive"),
src/core/filter.rs:315:pub fn get_filter(level: FilterLevel) -> Box<dyn FilterStrategy> {
src/core/filter.rs:317: FilterLevel::None => Box::new(NoFilter),
src/core/filter.rs:318: FilterLevel::Minimal => Box::new(MinimalFilter),
src/core/filter.rs:319: FilterLevel::Aggressive => Box::new(AggressiveFilter),
src/core/filter.rs:370: assert_eq!(FilterLevel::from_str("none").unwrap(), FilterLevel::None);
src/core/filter.rs:372: FilterLevel::from_str("minimal").unwrap(),
src/core/filter.rs:373: FilterLevel::Minimal
src/core/filter.rs:376: FilterLevel::from_str("aggressive").unwrap(),
src/core/filter.rs:377: FilterLevel::Aggressive
src/cmds/system/README.md:7:- `read.rs` uses `core/filter` for language-aware code stripping (FilterLevel: none/minimal/aggressive)
src/cmds/system/read.rs:3:use crate::core::filter::{self, FilterLevel, Language};
src/cmds/system/read.rs:11: level: FilterLevel,
src/cmds/system/read.rs:84: level: FilterLevel,
src/cmds/system/read.rs:197: run(file.path(), FilterLevel::Minimal, None, None, false, 0)?;
Because of this, rtk grep ends up producing output similar to the non-TTY rg format:
$ rtk grep -n "FilterLevel" src
24 matches in 4 files:
src/cmds/system/README.md:7:...filter` for language-aware code stripping (FilterLevel: none/minimal/aggressive)
src/cmds/system/read.rs:3:use crate::core::filter::{self, FilterLevel, Language};
src/cmds/system/read.rs:11:level: FilterLevel,
src/cmds/system/read.rs:84:level: FilterLevel,
src/cmds/system/read.rs:197:run(file.path(), FilterLevel::Minimal, None, None, false, 0)?;
src/core/filter.rs:8:pub enum FilterLevel {
src/core/filter.rs:14:impl FromStr for FilterLevel {
src/core/filter.rs:19:"none" => Ok(FilterLevel::None),
src/core/filter.rs:20:"minimal" => Ok(FilterLevel::Minimal),
src/core/filter.rs:21:"aggressive" => Ok(FilterLevel::Aggressive),
src/core/filter.rs:27:impl std::fmt::Display for FilterLevel {
src/core/filter.rs:30:FilterLevel::None => write!(f, "none"),
src/core/filter.rs:31:FilterLevel::Minimal => write!(f, "minimal"),
src/core/filter.rs:32:FilterLevel::Aggressive => write!(f, "aggressive"),
src/core/filter.rs:315:pub fn get_filter(level: FilterLevel) -> Box<dyn FilterStrategy> {
src/core/filter.rs:317:FilterLevel::None => Box::new(NoFilter),
src/core/filter.rs:318:FilterLevel::Minimal => Box::new(MinimalFilter),
src/core/filter.rs:319:FilterLevel::Aggressive => Box::new(AggressiveFilter),
src/core/filter.rs:370:assert_eq!(FilterLevel::from_str("none").unwrap(), FilterLevel::None);
src/core/filter.rs:372:FilterLevel::from_str("minimal").unwrap(),
src/core/filter.rs:373:FilterLevel::Minimal
src/core/filter.rs:376:FilterLevel::from_str("aggressive").unwrap(),
src/core/filter.rs:377:FilterLevel::Aggressive
src/main.rs:101:level: core::filter::FilterLevel,
This repeats the file path for every match, even when many matches come from the same file. For agent output, this is
noticeably more verbose than rg's default TTY heading style.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the rtk grep command entry point and trace how matches are formatted when stdout is captured rather than attached to a TTY. Compare the current repeated-path output with the heading-style example in the issue, then add coverage for grouped file headings and verify that the requested output is produced.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100