Giter Site home page Giter Site logo

hgrep's Introduction

hgrep: Human-friendly GREP

CI crate Coverage

hgrep is a grep tool to search files with a given pattern and print the matched code snippets with human-friendly syntax highlighting. This tool brings search results like the code search on GitHub to your local machine. In short, it's something like searching files with ripgrep and showing results with bat.

This is similar to -C option of grep command. hgrep is useful to survey the matches with contexts around them. When some matches are near enough, hgrep prints the lines within one code snippet. Unlike grep -C, hgrep adopts some heuristics around blank lines to determine an efficient number of context lines.

screenshot

Example:

# Use built-in subset of ripgrep (optional)
hgrep pattern ./dir

# Read results of grep command via stdin
grep -nH pattern -R ./dir | hgrep
rg -nH pattern ./dir | hgrep

hgrep provides two printers to print match results for your use case. Please see 'bat printer v.s. syntect printer' section for the comparison.

  • syntect printer (default): Our own implementation of printer using syntect library. Performance, output layout, and color themes are more optimized
  • bat printer: Printer built on top of bat's pretty printer implementation, which is battle-tested and provides some unique features

Please see the usage section for more details.

Installation

Binary releases

Visit the releases page and download the zip file for your platform. Unarchive the file and put the executable file in some $PATH directory. Currently, the following targets are supported. If you want a binary for some other platform, feel free to make an issue to request it.

  • Linux (x86_64-gnu, x86_64-musl, aarch64-gnu)
  • macOS (x86_64, aarch64)
  • Windows (x86_64-msvc)

By adding hgrep repository as Homebrew tap, hgrep command can be installed and managed via Homebrew. The formula supports x86_64/aarch64 macOS and x86_64 Linux.

brew tap "rhysd/hgrep" "https://github.com/rhysd/hgrep"
brew install hgrep

Note: If you installed Homebrew to a non-default location (e.g. ~/homebrew), you might see some errors. In the case, please try to install hgrep via cargo instead. See #6 for more details.

On macOS, you can install hgrep with the following commands through MacPorts:

sudo port selfupdate
sudo port install hgrep

For NetBSD

To install pre-built binaries using the package manager, simply run:

pkgin install hgrep

Or, if you prefer to build from source,

cd /usr/pkgsrc/textproc/hgrep
make install

Via APT package manager on Debian or Ubuntu

Visit the releases page and download .deb package file. It can be installed via dpkg command:

sudo dpkg -i hgrep_v0.3.6-1_amd64.deb

The manual (for man command) and Bash completion is automatically installed. If you're using some other shell, setup the shell completion by yourself. See 'Generate completion scripts' section for more details.

Via cargo package manager

cargo install hgrep

Since cargo builds hgrep command from sources, you can choose your favorite features and drop others by feature flags. For example, if you always use hgrep with reading grep output from stdin and don't use bat printer, only enabling syntect-printer dramatically reduces the number of dependencies, installation time, and binary size.

cargo install hgrep --no-default-features --features syntect-printer

Feature flags

All features are optional and enabled by default. At least bat-printer or syntect-printer needs to be enabled.

Feature Description
ripgrep Built-in grep implementation built on top of ripgrep as a library. Performance is better than piping rg in some cases.
syntect-printer Our own printer implementation built with syntect library. Performance and output layout are optimized for our use cases.
bat-printer Printer implementation built on top of bat's pretty printer, which is battle-tested and provides some unique features.

For the differences of bat-printer and syntect-printer, see 'bat printer v.s. syntect printer' section.

Usage

Built-in ripgrep

Optionally hgrep provides built-in grep implementation thanks to ripgrep as a library. It is a subset of rg command.

Built-in ripgrep is a recommended way to use hgrep because it is optimized for the use case.

When a pattern is given, hgrep command search files in given paths with it. When a directory is included in paths, hgrep searches it recursively. When no path is given, hgrep searches the current directory.

hgrep [options...] pattern [paths...]

By default, hgrep shows at least 3 lines and at most 6 lines as context of a match. How many context lines is determined by some heuristics around blank lines for space efficiency. Minimum context lines can be specified by -c and maximum context lines can be specified by -C. If you don't want the heuristics, give the same value to the options like -c 6 -C 6.

# At least 10 context lines and at most 20 context lines
hgrep -c 10 -C 20 pattern paths...

Like ripgrep, the built-in grep filters files by default. It looks at ignore files such as .gitignore and ignores hidden files. To disable the filters, --no-ignore and --hidden are available respectively. -u is a useful shortcut for them.

# Same as `hgrep --no-ignore pattern paths...`
hgrep -u pattern paths...

# Same as `hgrep --no-ignore --hidden pattern paths...`
hgrep -uu pattern paths...

Regarding to the performance compared to receiveing inputs from grep or rg via pipe, it's fast to handle so many matches in the same process. In combination with syntect-printer feature, matched regions can be highlighted in a searched text color. The built-in grep feature is enabled by default and can be omitted by feature flags.

Though almost all useful options are implemented, the built-in grep implementation is a subset of ripgrep. If you need full functionalities, use rg command and eat its output by hgrep via stdin. Currently there are the following restrictions.

  • Preprocessor is not supported (e.g. search zip files)
  • Pattern file (-f or --file of rg) is not supported
  • Sorting results (--sort and --sortr) is not supported because it significantly slows down printing the search output
  • Memory map is not used until --mmap flag is specified
  • Adding and removing file types are not supported. Only default file types are supported (see --type-list)
  • .ripgreprc config file is not supported
  • Searching binary files (--binary) is not supported

Eating grep -nH output

When no pattern and paths are given in command line arguments, hgrep can take grep results via stdin. Since hgrep expects file paths and line numbers in each line of the output, -nH is necessary at grep command.

grep -nH pattern -R paths... | hgrep [options...]

grep alternative tools like ripgrep, ag, pt, ... are also available because they can output results compatible with grep -nH.

rg -nH pattern paths... | hgrep [options...]

bat printer v.s. syntect printer

hgrep provides two printers to print match results; bat printer and syntect printer. bat printer is a printer implementation built on top of bat's pretty printer. And syntect printer is our own printer implementation built with syntect library. --printer (or -p) flag can specify the printer to print results.

At first, there was bat printer only. And then syntect printer was implemented for better performance and optimized layout.

Pros of each printers

  • syntect printer
    • Performance is much better. 2x to 4x faster (more match results get better performance).
    • Output layout is optimized for our use cases. Matched regions are highlighted in a searched text color. A line number at a match is highlighted in a different color.
    • Painting background color (--background) is supported. This is useful when your favorite theme does not fit to your terminal's background color.
    • Themes are optimized for showing matched results. And some new themes like ayu or predawn are available. See the output of --list-themes to know the list of all themes.
    • Compatibility for old terminals is better. It automatically changes the default theme to 'ansi' for 16-colors terminals. And it provides --ascii-lines flag to draw border lines with ascii characters instead of Unicode characters like '├', '┬', and so on.
  • bat printer
    • Implementation is battle-tested. It is already used by many users on many platforms and terminals.
    • The behavior is compatible with bat command. Its output layout is the same as bat command respecting BAT_THEME and BAT_STYLE environment variables. It can load bat's custom assets cache.

syntect is the default printer.

Themes only available with syntect printer

ayu-dark ayu-mirage ayu-light
ayu-dark ayu-mirage ayu-light
Cyanide predawn Material
cyanide predawn cyanide

(and more...)

Why performance of syntect printer is better?

Syntax highlighting is very CPU-heavy task. Many regular expression matchings happen at each line. For accurate syntax highlighting, a highlighter needs to parse the syntax from the beginning of file. It means that printing a match at the last line of a file is a much heavier task than printing a match at the first line of the file.

Since syntect printer is designed for calculating syntax highlights per file in parallel, its performance is much better. It's 2x~4x faster than bat printer in some experiments. More match results get better performance.

In contrast, bat is not designed for multi-threads. It's not possible to share bat::PrettyPrinter instance across threads. It means that printing match results including syntax highlighting must be done in a single thread.

syntect printer sequence bat printer sequence

Using pager

When you want a pager to see the output interactively, please pipe the output to external commands like less. $COLUMNS needs to be passed to --term-width option because the terminal width is fixed to 80 characters when stdout is not connected to TTY. If you frequently use a pager, it is a good option to define a wrapper shell function like below:

function hgrep() {
    command hgrep --term-width "$COLUMNS" "$@" | less -R
}

Change color theme and layout

The default color theme is Monokai Extended respecting bat command's default. Other theme can be specified via --theme option. To know names of themes, try --list-themes flag.

hgrep --theme Nord ...

The default layout is 'grid'. To reduce borderlines to use space more efficiently, --no-grid option is available.

hgrep --no-grid ...

When you use bat printer, hgrep respects BAT_THEME and BAT_STYLE environment variable. Theme set to BAT_THEME is used by default. And the grid layout is used when plain or header or numbers is set to BAT_STYLE. syntect printer does not look at these variables. To set default theme, please use a command alias in your shell (See 'Set default command options' for details).

export BAT_THEME=OneHalfDark
export BAT_STYLE=numbers
hgrep -p bat ...

When syntect printer is used, painting background colors is supported with --background flag.

hgrep --background ...

Set default command options

HGREP_DEFAULT_OPTS environment variable is available. Options set to the variable are prepended to the command line arguments when you run hgrep command.

Here are some examples:

# Set the `ayu-dark` color theme with background colors
export HGREP_DEFAULT_OPTS='--theme ayu-dark --background'
# Same as `hgrep --theme ayu-dark --background pattern paths`
hgrep pattern paths...

# Disable automatic filtering
export HGREP_DEFAULT_OPTS='--no-ignore --hidden'

# Use 'bat' printer by default
export HGREP_DEFAULT_OPTS='--printer bat'

The command line arguments in the environment variable are parsed with shlex. Use quotes for including spaces in some command line option arguments. For example:

$Env:HGREP_DEFAULT_OPTS = "--glob '!C:\Program Files'"

Command options

  • Common options
    • --min-context NUM (-c): Minimum lines of leading and trailing context surrounding each match. Default value is 3
    • --max-context NUM (-C): Maximum lines of leading and trailing context surrounding each match. Default value is 6
    • --no-grid (-G): Remove borderlines for more compact output. --grid flag is an opposite of this flag
    • --tab NUM: Number of spaces for tab character. Set 0 to pass tabs through. Default value is 4
    • --theme THEME: Theme for syntax highlighting. Default value is the same as bat command
    • --list-themes: List all available theme names and their samples for --theme option
    • --printer: Printer to print the match results. 'bat' or 'syntect' is available. Default value is 'bat'
    • --term-width NUM: Width (number of characters) of terminal window
    • --wrap MODE: Text-wrapping mode. 'char' enables character-wise text-wrapping. 'never' disables text-wrapping. Default value is 'char'
    • --first-only (-f): Show only the first code snippet per file
    • --encoding (-E): Specify the text encoding that hgrep will use on all files printed like 'sjis'
  • Only for ripgrep feature
    • --no-ignore: Don't respect ignore files (.gitignore, .ignore, etc.)
    • --ignore-case (-i): When this flag is provided, the given pattern will be searched case insensitively
    • --smart-case (-S): Search case insensitively if the pattern is all lowercase. Search case sensitively otherwise
    • --hidden (-.): Search hidden files and directories. By default, hidden files and directories are skipped
    • --unrestricted (-u): Reduce the level of "smart" filtering by repeated uses (up to 2). A single flag -u is equivalent to --no-ignore. Two flags -uu are equivalent to --no-ignore --hidden. Unlike ripgrep, three flags -uuu are not supported since hgrep doesn't support --binary flag
    • --glob GLOB... (-g): Include or exclude files and directories for searching that match the given glob
    • --glob-case-insensitive: Process glob patterns given with the -g/--glob flag case insensitively
    • --fixed-strings (-F): Treat the pattern as a literal string instead of a regular expression
    • --word-regexp (-w): Only show matches surrounded by word boundaries
    • --follow (-L): When this flag is enabled, hgrep will follow symbolic links while traversing directories
    • --multiline (-U): Enable matching across multiple lines
    • --multiline-dotall: Enable "dot all" in your regex pattern, which causes '.' to match newlines when multiline searching is enabled
    • --crlf: When enabled, hgrep will treat CRLF (\r\n) as a line terminator instead of just \n. This flag is useful on Windows
    • --mmap: Search using memory maps when possible. mmap is disabled by default unlike hgrep
    • --max-count NUM (-m): Limit the number of matching lines per file searched to NUM
    • --max-depth NUM: Limit the depth of directory traversal to NUM levels beyond the paths given
    • --max-filesize NUM+SUFFIX?: Ignore files larger than NUM in size. This does not apply to directories.The input format accepts suffixes of K, M or G
    • --line-regexp (-x): Only show matches surrounded by line boundaries. This is equivalent to putting ^...$ around the search pattern
    • --invert-match (-v): Invert matching. Show lines that do not match the given pattern
    • --pcre2 (-P): When this flag is present, hgrep will use the PCRE2 regex engine instead of its default regex engine
    • --type TYPE (-t): Only search files matching TYPE. This option is repeatable
    • --type-not TYPE (-T): Do not search files matching TYPE. Inverse of --type. This option is repeatable
    • --type-list: Show all supported file types and their corresponding globs
    • --one-file-system: When enabled, the search will not cross file system boundaries relative to where it started from
    • --no-unicode: Disable unicode-aware regular expression matching
    • --regex-size-limit NUM+SUFFIX?: The upper size limit of the compiled regex. The default limit is 10M. For the size suffixes, see --max-filesize
    • --dfa-size-limit NUM+SUFFIX?: The upper size limit of the regex DFA. The default limit is 10M. For the size suffixes, see --max-filesize
  • Only for syntect-printer feature
    • --background: Paint background colors. This is useful when your favorite theme does not fit to your terminal's background color
    • --ascii-lines: Use ASCII characters for drawing border lines instead of Unicode characters
  • Only for bat-printer feature
    • --custom-assets: Load bat's custom assets from cache. Note that this flag may not work with some version of bat command

See --help for the full list of available options in your environment.

Text encoding

hgrep supports various encodings thanks to encoding_rs crate.

--encoding (-E) command line option can specify the file encoding explicitly. For example, the following command will assume matched files are encoded with Shift JIS.

hgrep --encoding sjis pattern

In addition, hgrep tries to detect file encodings from BOM. UTF-16LE, UTF-16BE, and UTF-8 can be detected automatically.

When no file encoding is detected from BOM, hgrep assumes files are encoded in UTF-8 as default encoding. If malformed UTF-8 sequences are contained, they are replaced with the replacement character U+FFFD.

Generate completion scripts

Shell completion script for hgrep command is available. --generate-completion-script option generates completion script and prints it to stdout. Bash, Zsh, Fish, PowerShell, Elvish, Nushell are supported. See --help for more details.

Here is an example of setup the completion script on Zsh.

# Let's say we set comps=~/.zsh/site-functions
hgrep --generate-completion-script zsh > ~/.zsh/site-functions/_hgrep
chmod +x ~/.zsh/site-functions/_hgrep

Generate man page

Manual page for hgrep command is available. --generate-man-page flag generates the man page and prints it to stdout.

This is an example to generate man page in /usr/local/share.

hgrep --generate-man-page > /usr/local/share/man/man1/hgrep.1

# See the manual page
man hgrep

Exit status

hgrep command returns the exit status as follows.

Status Description
0 One or more matches were found
1 No match was found
2 Some error happened (e.g. IO error)

Terminal color support detection

hgrep automatically detects 24-bit or 256 or 16 colors support of your terminal application by the following logic.

COLORTERM

At first, hgrep checks COLORTERM environment variable. When truecolor or 24bit is set to the variable, 24-bit colors are enabled.

On Linux or macOS or FreeBSD or NetBSD, hgrep tries to detect your terminal's color support from terminfo.

On Windows, hgrep enables 24-bit colors if the Windows version is 10.0.15063 or later becuase OS version 10.0.15063 (Windows 10 1703) started to support 24-bit colors. Otherwise it enables only 16-colors.

TERM

When COLORTERM is not set, hgrep checks TERM environment variable which the terminal name is set.

  • When it ends with -truecolor or -24bit, 24-bit colors are enabled.
  • When it ends with -256color or -square, 256 colors are enabled.

Fallback

When no color support was detected from COLORTERM nor TERM, htrep eventually falls back to 256 colors, which are most widely supported by popular terminals.

Versioning

At this point the major version is fixed to 0. The minor version is bumped when some breaking changes are added. The patch version is bumped when some new compatible changes are added and/or some bug fixes are added.

Alternatives

Some other alternatives instead of using hgrep.

Small ShellScript to combine ripgrep and bat

ripgrep and bat are well-designed tools so they can be used as building parts of a small script.

rg -nH ... | while IFS= read -r line; do
  # Parse $line and calculate the range of snippet and highlighted lines
  file=...
  lines=...
  range=...

  # Show matched snippet
  bat -H ${lines} -r ${range} ${file}
done

It works fine but hgrep is more optimized for this usage.

  • When the matches are near enough, the lines are printed in one snippet.
  • Performance is much better than running bat process per matched line.
  • hgrep computes efficient context lines based on some heuristics.
  • hgrep is available where ShellScript is unavailable (e.g. PowerShell).

Fuzzy finder like fzf with bat preview window

Fuzzy finder like fzf provides a preview window functionality and bat can print the match in the preview window.

grep -nH ... | \
    fzf --preview='bat --pager never --color always -H {2} -r {2}: -p {1}' --delimiter=:

This usage is great when you need the incremental search, but you need to check each preview of matches one by one.

hgrep focuses on surveying all the matches.

Bug reporting

Please create an issue on GitHub. Ensure to describe how to reproduce the bug.

License

hgrep is distributed under the MIT license.

hgrep's People

Contributors

dependabot[bot] avatar github-actions[bot] avatar herbygillot avatar kianmeng avatar rhysd avatar ryooooooga avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

hgrep's Issues

Indent guide

Consider to add indent guide to the result snippets. Since snippets usually include indents and sometimes the indent level is deep, it would be helpful to know the level.

    ┊   match self.regions.first().copied() {
    ┊   ┊   Some((s, e)) if o == s && o < e => RegionBoundary::Start,
    ┊   ┊   Some((_, e)) if o == e => {
    ┊   ┊   ┊   // When the next region is adjcent, skip changing highlight
    ┊   ┊   ┊   match self.regions.get(1) {
    ┊   ┊   ┊   ┊   Some((s, _)) if o == *s => RegionBoundary::NotFound,
    ┊   ┊   ┊   ┊   _ => RegionBoundary::End,
    ┊   ┊   ┊   }
    ┊   ┊   }
    ┊   ┊   _ => RegionBoundary::NotFound,
    ┊   }
  • Character: (U+250A)
  • Color: gutter
  • Option: --no-indent-guide (indent guide is enabled by default)

Note that this feature is automatically disabled by --ascii-lines.

Challenges:

  • How to calculate indent width?
    • Width would be calculated at making chunks from grep matches.
  • How to handle tab character?
  • How to propagate the calculated indent width to a printer?

I should to confirm that the guides are not so noisy in outputs before implementing this by crafting an example output.

Support UTF-16

Currently hgrep supports only UTF-8 texts. This means that hgrep tries to print UTF-16 texts as if they are encoded in UTF-8, resulting in a quite broken output.

ripgrep supports UTF-16 by --encoding option so technically hgrep can support it too. ripgrep transcodes UTF-16 to UTF-8 on memory removing BOM using encoding_rs_io::DecodeReaderBytesBuilder. It means that ripgrep reports byte offsets for matched regions in transcoded UTF-8 text.

https://github.com/BurntSushi/ripgrep/blob/d922b7ac114c24d6800ae5f79d2967481f380c83/crates/searcher/src/searcher/mod.rs#L720-L744

hgrep can read matched file transcoding UTF-16 to UTF-8 as well. Currently hgrep reads file contents as-is. --encoding (-E) option can be added by reading files through the encoding_rs encoders.

hgrep/src/chunk.rs

Lines 220 to 223 in 6f49cb0

let contents = match fs::read(&path) {
Ok(vec) => vec,
Err(err) => return self.error_item(err.into()),
};

  • When BOM exists at top, respect the encoding (UTF-8, UTF-16-LE, UTF-16-BE)
    • UTF-16: Detect encoding with Encoding::for_bom and transcode input to UTF-8
    • UTF-8: Remove BOM and pass through input
  • Add --encode option which accepts encoding labels

Homebrew not working

❯ brew tap "rhysd/hgrep" "https://github.com/rhysd/hgrep"
brew install hgrep
==> Downloading https://github.com/rhysd/hgrep/releases/download/v0.2.1/hgrep-v0.2.1-x86_64-apple-darwin.zip
Already downloaded: /Users/$USER/Library/Caches/Homebrew/downloads/712103ea480f4147dde712234225835a35bc2a2213180120913b81329051bd47--hgrep-v0.2.1-x86_64-apple-darwin.zip
==> Installing hgrep from rhysd/hgrep
Error: Failure while executing; `/Users/$USER/homebrew/Cellar/hgrep/0.2.1/bin/hgrep --generate-completion-script zsh` was terminated by uncaught signal ABRT. Here's the output:
❯ /Users/$USER/homebrew/Cellar/hgrep/0.2.1/bin/hgrep --generate-completion-script zsh
zsh: no such file or directory: /Users/$USER/homebrew/Cellar/hgrep/0.2.1/bin/hgrep

Don't think it is related to OS, but if you need I will share.

Can't compile problem

OS: Arch Linux on Windows 10 x86_64
Kernel: 5.10.16.3-microsoft-standard-WSL2
Log:

❯ cargo install --git=https://github.com/rhysd/hgrep
    Updating git repository `https://github.com/rhysd/hgrep`
  Installing hgrep v0.1.3 (https://github.com/rhysd/hgrep#37082f52)
    Updating `sjtu` index
   Compiling libc v0.2.104
   Compiling autocfg v1.0.1
   Compiling cfg-if v1.0.0
   Compiling memchr v2.4.1
   Compiling proc-macro2 v1.0.30
   Compiling lazy_static v1.4.0
   Compiling unicode-xid v0.2.2
   Compiling syn v1.0.80
   Compiling pkg-config v0.3.20
   Compiling serde_derive v1.0.130
   Compiling log v0.4.14
   Compiling regex-syntax v0.6.25
   Compiling serde v1.0.130
   Compiling crossbeam-utils v0.8.5
   Compiling encoding_index_tests v0.1.4
   Compiling regex-automata v0.1.10
   Compiling hashbrown v0.11.2
   Compiling proc-macro-hack v0.5.19
   Compiling once_cell v1.8.0
   Compiling same-file v1.0.6
   Compiling crc32fast v1.2.1
   Compiling crossbeam-epoch v0.9.5
   Compiling fnv v1.0.7
   Compiling ryu v1.0.5
   Compiling bitflags v1.3.2
   Compiling termcolor v1.1.2
   Compiling ucd-trie v0.1.3
   Compiling safemem v0.3.3
   Compiling encoding_rs v0.8.29
   Compiling adler v1.0.2
   Compiling linked-hash-map v0.5.4
   Compiling rayon-core v1.9.1
   Compiling scopeguard v1.1.0
   Compiling serde_json v1.0.68
   Compiling version_check v0.9.3
   Compiling xml-rs v0.8.4
   Compiling bugreport v0.4.1
   Compiling base64 v0.13.0
   Compiling unicode-width v0.1.9
   Compiling itoa v0.4.8
   Compiling dtoa v0.4.8
   Compiling strsim v0.10.0
   Compiling std_prelude v0.2.12
   Compiling anyhow v1.0.44
   Compiling lazycell v1.3.0
   Compiling textwrap v0.14.2
   Compiling shell-escape v0.1.5
   Compiling bat v0.18.3
   Compiling bytecount v0.6.2
   Compiling either v1.6.1
   Compiling ansi_term v0.12.1
   Compiling indexmap v1.7.0
   Compiling num-traits v0.2.14
   Compiling memoffset v0.6.4
   Compiling num-integer v0.1.44
   Compiling miniz_oxide v0.4.4
   Compiling rayon v1.5.1
   Compiling encoding-index-simpchinese v1.20141219.5
   Compiling encoding-index-korean v1.20141219.5
   Compiling encoding-index-singlebyte v1.20141219.5
   Compiling encoding-index-japanese v1.20141219.5
   Compiling encoding-index-tradchinese v1.20141219.5
   Compiling thread_local v1.1.3
   Compiling walkdir v2.3.2
   Compiling pest v2.1.3
   Compiling line-wrap v0.1.1
   Compiling yaml-rust v0.4.5
   Compiling error-chain v0.12.4
   Compiling path_abs v0.5.1
   Compiling encoding v0.2.33
   Compiling semver-parser v0.10.2
   Compiling aho-corasick v0.7.18
   Compiling bstr v0.2.17
   Compiling grep-matcher v0.1.5
   Compiling os_str_bytes v4.2.0
   Compiling content_inspector v0.2.4
   Compiling atty v0.2.14
   Compiling terminal_size v0.1.17
   Compiling num_cpus v1.13.0
   Compiling memmap2 v0.3.1
   Compiling quote v1.0.10
   Compiling jobserver v0.1.24
   Compiling crossbeam-channel v0.5.1
   Compiling semver v0.11.0
   Compiling encoding_rs_io v0.1.7
   Compiling flate2 v1.0.22
   Compiling regex v1.5.4
   Compiling clap v3.0.0-beta.5
   Compiling cc v1.0.71
   Compiling grep-searcher v0.1.8
   Compiling crossbeam-deque v0.8.1
   Compiling chrono v0.4.19
   Compiling globset v0.4.8
   Compiling console v0.14.1
   Compiling grep-regex v0.1.9
   Compiling console v0.15.0
   Compiling clap_generate v3.0.0-beta.5
   Compiling sys-info v0.9.0
   Compiling onig_sys v69.7.1
   Compiling pcre2-sys v0.2.5
   Compiling ansi_colours v1.0.4
   Compiling git-version-macro v0.3.5
   Compiling grep-cli v0.1.6
   Compiling ignore v0.4.18
   Compiling git-version v0.3.5
   Compiling pcre2 v0.2.3
   Compiling grep-pcre2 v0.1.5
   Compiling bincode v1.3.3
   Compiling plist v1.2.1
   Compiling serde_yaml v0.8.21
   Compiling clircle v0.3.0
   Compiling onig v6.3.0
   Compiling syntect v4.6.0
   Compiling hgrep v0.1.3 (/home/young/.cargo/git/checkouts/hgrep-76d18114b713642b/37082f5)
error[E0599]: no variant or associated item named `ColoredHelp` found for enum `AppSettings` in the current scope
  --> src/main.rs:22:38
   |
22 |         .global_setting(AppSettings::ColoredHelp)
   |                                      ^^^^^^^^^^^ variant or associated item not found in `AppSettings`

error[E0061]: this function takes 4 arguments but 3 arguments were supplied
   --> src/main.rs:242:19
    |
242 |         "bash" => generate::<Bash, _>(&mut app, "hgrep", &mut stdout),
    |                   ^^^^^^^^^^^^^^^^^^^ --------  -------  ----------- supplied 3 arguments
    |                   |
    |                   expected 4 arguments
    |
note: function defined here
   --> /home/young/.cargo/registry/src/mirrors.sjtug.sjtu.edu.cn-7a04d2510079875b/clap_generate-3.0.0-beta.5/src/lib.rs:239:8
    |
239 | pub fn generate<G, S>(gen: G, app: &mut clap::App, bin_name: S, buf: &mut dyn Write)
    |        ^^^^^^^^

error[E0061]: this function takes 4 arguments but 3 arguments were supplied
   --> src/main.rs:243:18
    |
243 |         "zsh" => generate::<Zsh, _>(&mut app, "hgrep", &mut stdout),
    |                  ^^^^^^^^^^^^^^^^^^ --------  -------  ----------- supplied 3 arguments
    |                  |
    |                  expected 4 arguments
    |
note: function defined here
   --> /home/young/.cargo/registry/src/mirrors.sjtug.sjtu.edu.cn-7a04d2510079875b/clap_generate-3.0.0-beta.5/src/lib.rs:239:8
    |
239 | pub fn generate<G, S>(gen: G, app: &mut clap::App, bin_name: S, buf: &mut dyn Write)
    |        ^^^^^^^^

error[E0061]: this function takes 4 arguments but 3 arguments were supplied
   --> src/main.rs:244:25
    |
244 |         "powershell" => generate::<PowerShell, _>(&mut app, "hgrep", &mut stdout),
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ --------  -------  ----------- supplied 3 arguments
    |                         |
    |                         expected 4 arguments
    |
note: function defined here
   --> /home/young/.cargo/registry/src/mirrors.sjtug.sjtu.edu.cn-7a04d2510079875b/clap_generate-3.0.0-beta.5/src/lib.rs:239:8
    |
239 | pub fn generate<G, S>(gen: G, app: &mut clap::App, bin_name: S, buf: &mut dyn Write)
    |        ^^^^^^^^

error[E0061]: this function takes 4 arguments but 3 arguments were supplied
   --> src/main.rs:245:19
    |
245 |         "fish" => generate::<Fish, _>(&mut app, "hgrep", &mut stdout),
    |                   ^^^^^^^^^^^^^^^^^^^ --------  -------  ----------- supplied 3 arguments
    |                   |
    |                   expected 4 arguments
    |
note: function defined here
   --> /home/young/.cargo/registry/src/mirrors.sjtug.sjtu.edu.cn-7a04d2510079875b/clap_generate-3.0.0-beta.5/src/lib.rs:239:8
    |
239 | pub fn generate<G, S>(gen: G, app: &mut clap::App, bin_name: S, buf: &mut dyn Write)
    |        ^^^^^^^^

error[E0061]: this function takes 4 arguments but 3 arguments were supplied
   --> src/main.rs:246:21
    |
246 |         "elvish" => generate::<Elvish, _>(&mut app, "hgrep", &mut stdout),
    |                     ^^^^^^^^^^^^^^^^^^^^^ --------  -------  ----------- supplied 3 arguments
    |                     |
    |                     expected 4 arguments
    |
note: function defined here
   --> /home/young/.cargo/registry/src/mirrors.sjtug.sjtu.edu.cn-7a04d2510079875b/clap_generate-3.0.0-beta.5/src/lib.rs:239:8
    |
239 | pub fn generate<G, S>(gen: G, app: &mut clap::App, bin_name: S, buf: &mut dyn Write)
    |        ^^^^^^^^

Some errors have detailed explanations: E0061, E0599.
For more information about an error, try `rustc --explain E0061`.
error: failed to compile `hgrep v0.1.3 (https://github.com/rhysd/hgrep#37082f52)`, intermediate artifacts can be found at `/tmp/cargo-installWmUcTi`

Caused by:
  could not compile `hgrep` due to 6 previous errors

Panic when eating input from `rg --vimgrep` and max context=0

This happens especially when running with rg --vimgrep which can result in a line with more than one match will be printed more than once.
When running hgrep -C0 this will result in a panic on the duplicate line.
(Theoretically this could be considered invalid input, but I guess hgrep should handle it more gracefully than panicking)

I can reproduce this using the 0.2.6 build on github release and also compiling latest from main branch.

  1. Create a file:
abc
def
  1. Then run rg --vimgrep . file | hgrep -c0 -C0
  2. Resulting in the following panic message:
thread '<unnamed>' panicked at 'line 2 > chunk 1', /home/runner/work/hgrep/hgrep/src/chunk.rs:162:13
stack backtrace:
   0:     0x5623558a1d34 - std::backtrace_rs::backtrace::libunwind::trace::h22893a5306c091b4
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x5623558a1d34 - std::backtrace_rs::backtrace::trace_unsynchronized::h29c3bc6f9e91819d
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x5623558a1d34 - std::sys_common::backtrace::_print_fmt::he497d8a0ec903793
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x5623558a1d34 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h9c2a9d2774d81873
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x562355725d1c - core::fmt::write::hba4337c43d992f49
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/fmt/mod.rs:1194:17
   5:     0x56235589f295 - std::io::Write::write_fmt::heb73de6e02cfabed
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/io/mod.rs:1655:15
   6:     0x5623558a37ae - std::sys_common::backtrace::_print::h63c8b24acdd8e8ce
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x5623558a37ae - std::sys_common::backtrace::print::h426700d6240cdcc2
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x5623558a37ae - std::panicking::default_hook::{{closure}}::hc9a76eed0b18f82b
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:295:22
   9:     0x5623558a34dd - std::panicking::default_hook::h2e88d02087fae196
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:314:9
  10:     0x5623558a3d55 - std::panicking::rust_panic_with_hook::habfdcc2e90f9fd4c
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:698:17
  11:     0x5623558a3c64 - std::panicking::begin_panic_handler::{{closure}}::he054b2a83a51d2cd
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:588:13
  12:     0x5623558a2264 - std::sys_common::backtrace::__rust_end_short_backtrace::ha48b94ab49b30915
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x5623558a39cd - rust_begin_unwind
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:584:5
  14:     0x562355664d83 - core::panicking::panic_fmt::h366d3a309ae17c94
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/panicking.rs:143:14
  15:     0x5623557c3a9a - <hgrep::chunk::Files<I> as core::iter::traits::iterator::Iterator>::next::h5ee4291e70bebdc3
  16:     0x56235579be59 - <rayon::iter::par_bridge::IterParallelProducer<Iter> as rayon::iter::plumbing::UnindexedProducer>::fold_with::h0dca500009f9e028
  17:     0x5623557955a2 - rayon::iter::plumbing::bridge_unindexed_producer_consumer::h223e4423a9933835
  18:     0x5623557a2ca7 - std::panicking::try::hf0836b1c957853cc
  19:     0x5623557cb66d - rayon_core::registry::in_worker::he45b25a872d14469
  20:     0x562355795507 - rayon::iter::plumbing::bridge_unindexed_producer_consumer::h223e4423a9933835
  21:     0x5623557a2ca7 - std::panicking::try::hf0836b1c957853cc
  22:     0x5623557cb66d - rayon_core::registry::in_worker::he45b25a872d14469
  23:     0x562355795507 - rayon::iter::plumbing::bridge_unindexed_producer_consumer::h223e4423a9933835
  24:     0x5623557a2ca7 - std::panicking::try::hf0836b1c957853cc
  25:     0x5623557cb66d - rayon_core::registry::in_worker::he45b25a872d14469
  26:     0x562355795507 - rayon::iter::plumbing::bridge_unindexed_producer_consumer::h223e4423a9933835
  27:     0x5623557a2ca7 - std::panicking::try::hf0836b1c957853cc
  28:     0x5623557b5895 - <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h0b572bc3ae82dd95
  29:     0x5623557a260f - std::panicking::try::h5cef0bae059587cf
  30:     0x5623557b8ff3 - <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::h5b2d03e421fd52dd
  31:     0x56235566e2e5 - rayon_core::registry::WorkerThread::wait_until_cold::h8e688ed76ab0d924
  32:     0x562355806d36 - rayon_core::registry::ThreadBuilder::run::h5b1fb0c08159930b
  33:     0x5623558092d1 - std::sys_common::backtrace::__rust_begin_short_backtrace::hff0e2583cc1c2414
  34:     0x562355804cad - core::ops::function::FnOnce::call_once{{vtable.shim}}::h0d99182cc1cda66c
  35:     0x5623558a7435 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::ha99802c2c52ada61
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/alloc/src/boxed.rs:1861:9
  36:     0x5623558a7435 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::ha39aea1c57e28a15
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/alloc/src/boxed.rs:1861:9
  37:     0x5623558a7435 - std::sys::unix::thread::Thread::new::thread_start::h9f8e3d72b1f7662f
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys/unix/thread.rs:108:17
  38:     0x7fec1b9f08fd - <unknown>
  39:     0x7fec1ba72a60 - <unknown>
  40:                0x0 - <unknown>

How to visually indicate matches when consuming grep -nH output?

I have installed via cargo install hgrep under MINGW64 (Windows 10).

Assuming an input file like myfile.c:

/*
 * foo has changed [...] and is now a 2-parameters function
 */
// foo(24)
int myvar = foo(42, 28);

... then if I run hgrep on the file directly (e.g. hgrep foo myfile.c) - then the matches are nicely indicated (in addition to corresponding line numbers):

image

... however if I try to Eat grep -nH output (e.g. grep -nH foo myfile.c | hgrep) - then the matches are NOT indicated anymore, only the corresponding line numbers are:

image

Can I somehow get the matched substrings to be indicated, also when consuming grep -nH output?

Support `--sort` option

rg provides --sort option. hgrep also can support it.

Note that using --sort option can slow hgrep because sorting the matches means all matches must be calculated before printing them. For example, when a pattern matches to very last of large file, calculating highlights generally requires long time (since highlight must be calculated from the start of file).

musl binary is not statically linked

I downloaded the latest musl binary from GitHub releases, but am unable to run it.

❯ /spare/ssd/szafar/apps/bin/hgrep
zsh: no such file or directory: /spare/ssd/szafar/apps/bin/hgrep

❯ ldd /spare/ssd/szafar/apps/bin/hgrep
        linux-vdso.so.1 (0x00007fff4bdf7000)
        libgtk3-nocsd.so.0 => /lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 (0x00007fad62b28000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fad62b0d000)
        libc.musl-x86_64.so.1 => not found
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fad62b07000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fad62ae4000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fad628f2000)
        /lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007fad633d2000)

❯ file /spare/ssd/szafar/apps/bin/hgrep
/spare/ssd/szafar/apps/bin/hgrep: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, with debug_info, not stripped

v0.1.6: compilation error with Rust 1.56.0

Compilation failed on macOS Catalina 10.15.7 when trying to compile hgrep v0.1.6 using Rust 1.56.0:

error: couldn't read src/../assets/bat/assets/syntaxes.bin: No such file or directory (os error 2)
  --> src/syntect.rs:27:31
   |
27 | const SYNTAX_SET_BIN: &[u8] = include_bytes!("../assets/bat/assets/syntaxes.bin");
   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)

error: couldn't read src/../assets/bat/assets/themes.bin: No such file or directory (os error 2)
  --> src/syntect.rs:28:30
   |
28 | const THEME_SET_BIN: &[u8] = include_bytes!("../assets/bat/assets/themes.bin");
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `hgrep` due to 2 previous errors

UTF BOM screws up language auto-detect

I noticed when doing a grep on a project some resx files had proper highlighting and some did not. Renaming them to XML fixed this (as it used extension detection for lang I assume) but after some troubleshooting I found the same file with and without BOM would result in the problem (with BOM preventing the auto detection).
image
image

Internal syntect renderer has problems on windows with csharp files that have lines starting with # and background painting

very specific problem, but not that hard to run into. I noticed when (h)greping for a specific macro the matching line was just a gray line.

With some more troubleshooting it seems this happens (gray line/whatever highlight color I would guess) any time the background is painted on a line starting with a # even when it is not the highlighted result.

Changing the file extension to .c instead of .cs fixes it, running the same command in linux works fine. Just about any combo other than a .cs file, or without the line background painted, or without the line starting with a # or not on windows seems ok:)

Sadly I don't see an immediate way to actually turn of background painting for the matched line (other than just using the other printer which does solve this:)).

Windows samples:
image

linux samples:
image

Since 0.2.7, --hidden now requires a value.

# v0.2.6
$ ./hgrep-v0.2.6-x86_64-apple-darwin/hgrep --help | grep hidden
    -., --hidden
            Search hidden files and directories. By default, hidden files and directories are
$ ./hgrep-v0.2.6-x86_64-apple-darwin/hgrep --hidden </dev/null

# v0.2.7
$ ./hgrep-v0.2.7-x86_64-apple-darwin/hgrep --help | grep hidden
  -., --hidden <hidden>
          Search hidden files and directories. By default, hidden files and directories are skipped
$ ./hgrep-v0.2.7-x86_64-apple-darwin/hgrep --hidden </dev/null
error: The argument '--hidden <hidden>' requires a value but none was supplied

For more information try '--help'

Release for apt or any other popular Linux packaging system

Would be nice to get it available for any more popular Linux packaging system (or multiple of them), such as apt, yum or pacman. Currently there are only packages for more macOS-based managers, such as Homebrew and MacPorts, or the Rust cargo one. And bloating the system with lots of package managers just to install an app or two is not great.

Musl binary

Hi
Is it possible to provide a musl-binary (the way ripgrep does)?
(i use an old linux machine that i cannot upgrage)

Many thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.