Skip to content

Commit

Permalink
add --first-only to show only first snippet per file
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Oct 28, 2021
1 parent 693ea18 commit 416787e
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ function hgrep() {
- `--list-themes`: List all theme names available for --theme option
- `--printer`: Printer to print the match results. 'bat' or 'syntect' is available. Default value is 'bat'
- `--term-width`: Width (number of characters) of terminal window
- `--first-only` (`-f`): Show only the first code snippet per file
- Only for `ripgrep` feature
- `--no-ignore`: Don't respect ignore files (.gitignore, .ignore, etc.)
- `--ignore-case` (`-i`): When this flag is provided, the given patterns will be searched case insensitively
Expand Down
25 changes: 14 additions & 11 deletions src/bat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn get_cache_dir() -> Option<PathBuf> {
}

pub struct BatPrinter<'main> {
grid: bool,
opts: PrinterOptions<'main>,
config: Config<'main>,
assets: HighlightingAssets,
}
Expand Down Expand Up @@ -104,7 +104,7 @@ impl<'main> BatPrinter<'main> {
};

Self {
grid: opts.grid,
opts,
assets,
config,
}
Expand Down Expand Up @@ -148,17 +148,20 @@ impl<'main> BatPrinter<'main> {
let input =
Input::from_reader(Box::new(file.contents.as_ref())).with_name(Some(&file.path));

let ranges = file
.line_matches
.iter()
.map(|m| {
let n = m.line_number as usize;
LineRange::new(n, n)
})
.collect();
let ranges = file.line_matches.iter().map(|m| {
let n = m.line_number as usize;
LineRange::new(n, n)
});

let ranges = if self.opts.first_only {
ranges.take(1).collect()
} else {
ranges.collect()
};

config.highlighted_lines = HighlightedLineRanges(LineRanges::from(ranges));

if !self.grid {
if !self.opts.grid {
print!("\n\n"); // Empty lines as files separator
}

Expand Down
9 changes: 9 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ fn cli<'a>() -> App<'a> {
.possible_values(["char", "never"])
.case_insensitive(true)
.about("Text-wrapping mode. 'char' enables character-wise text-wrapping. 'never' disables text-wrapping")
).arg(
Arg::new("first-only")
.short('f')
.long("first-only")
.about("Show only the first code snippet per file")
)
.arg(
Arg::new("generate-completion-script")
Expand Down Expand Up @@ -419,6 +424,10 @@ fn app() -> Result<bool> {
printer_opts.text_wrap = TextWrapMode::Never;
}

if matches.is_present("first-only") {
printer_opts.first_only = true;
}

#[cfg(feature = "syntect-printer")]
if matches.is_present("background") {
printer_opts.background_color = true;
Expand Down
2 changes: 2 additions & 0 deletions src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub struct PrinterOptions<'main> {
pub term_width: u16,
pub custom_assets: bool,
pub text_wrap: TextWrapMode,
pub first_only: bool,
}

impl<'main> Default for PrinterOptions<'main> {
Expand All @@ -62,6 +63,7 @@ impl<'main> Default for PrinterOptions<'main> {
custom_assets: false,
term_width: terminal_size().map(|(Width(w), _)| w).unwrap_or(80), // Note: `tput` returns 80 when tty is not found
text_wrap: TextWrapMode::Char,
first_only: false,
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/syntect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ struct Drawer<'file, W: Write> {
term_width: u16,
lnum_width: u16,
background: bool,
first_only: bool,
gutter_color: Color,
canvas: Canvas<'file, W>,
}
Expand Down Expand Up @@ -594,6 +595,7 @@ impl<'file, W: Write> Drawer<'file, W> {
lnum_width,
background: opts.background_color,
gutter_color,
first_only: opts.first_only,
canvas,
}
}
Expand Down Expand Up @@ -754,6 +756,9 @@ impl<'file, W: Write> Drawer<'file, W> {
self.draw_line(hl.highlight(line.as_ref()), lnum, matched)?;

if lnum == end {
if self.first_only {
break;
}
if let Some(c) = chunks.next() {
self.draw_separator_line()?;
chunk = c;
Expand Down Expand Up @@ -1177,6 +1182,9 @@ mod tests {
test_wrap_region_line_start(|_| {}),
test_wrap_region_line_end(|_| {}),
test_wrap_3_lines_emoji(|_| {}),
test_first_only(|o| {
o.first_only = true;
}),
);
}

Expand Down
16 changes: 16 additions & 0 deletions testdata/syntect/first_only.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
────────────────────────────────────────────────────────────────────────────────
 ./testdata/syntect/first_only.rs
─────┬──────────────────────────────────────────────────────────────────────────
 1 │ fn main() {
 2 │  fn foo() {
 3 │  println!("*match to this line*"); 
 4 │  }
 5 │  fn bar() {
 6 │  println!("*match to this line*"); 
 7 │  }
 8 │ 
 9 │  foo();
 10 │  bar();
 11 │ 
 12 │ 
─────┴──────────────────────────────────────────────────────────────────────────
23 changes: 23 additions & 0 deletions testdata/syntect/first_only.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
fn main() {
fn foo() {
println!("*match to this line*");
}
fn bar() {
println!("*match to this line*");
}

foo();
bar();







foo();
bar();
println!("*match to this line*");
foo();
bar();
}
2 changes: 2 additions & 0 deletions testdata/update_syntect_uitest.bash
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ cargo run -- '\*match to .+ line\*' -c 6 -C 6 -p syntect --term-width 80
cargo run -- '\*match to .+ line\*' -c 6 -C 6 -p syntect --term-width 80 ./testdata/syntect/whole_line.rs > ./testdata/syntect/whole_line.out
cargo run -- '\*match to .+ line\*' -c 6 -C 6 -p syntect --term-width 80 ./testdata/syntect/wrap_whole_3_lines.rs > ./testdata/syntect/wrap_whole_3_lines.out
cargo run -- '\*match to .+ line\*' -c 6 -C 6 -p syntect --term-width 80 ./testdata/syntect/wrap_3_lines_emoji.rs > ./testdata/syntect/wrap_3_lines_emoji.out
cargo run -- '\*match to .+ line\*' -c 6 -C 6 -p syntect --term-width 80 --first-only ./testdata/syntect/first_only.rs > ./testdata/syntect/first_only.out

# Previews
cat ./testdata/syntect/ansi16_colors.out
Expand Down Expand Up @@ -129,3 +130,4 @@ cat ./testdata/syntect/wrap_region_line_end.out
cat ./testdata/syntect/whole_line.out
cat ./testdata/syntect/wrap_whole_3_lines.out
cat ./testdata/syntect/wrap_3_lines_emoji.out
cat ./testdata/syntect/first_only.out

0 comments on commit 416787e

Please sign in to comment.