#语法高亮 #grep #命令行 #ripgrep #命令输出 #bat #命令行工具

bin+lib hgrep

hgrep 是一个具有人性化的搜索输出的 grep 工具。这与 -C 选项的 grep 命令类似,但其输出增强了语法高亮,专注于可读性。

23 个版本

0.3.7 2024年4月21日
0.3.4 2024年1月6日
0.3.1 2023年1月31日
0.2.6 2022年5月27日
0.2.1 2021年11月13日

#69文本处理

Download history 22/week @ 2024-04-26 6/week @ 2024-05-03 7/week @ 2024-05-17 3/week @ 2024-05-24 5/week @ 2024-05-31 4/week @ 2024-06-07 2/week @ 2024-06-14 4/week @ 2024-06-21 78/week @ 2024-07-26 8/week @ 2024-08-02

每月下载量 86

MIT 和可能 LGPL-3.0-or-later

1MB
5K SLoC

hgrep:人性化的 GREP

CI crate Coverage

hgrep 是一个 grep 工具,用于使用给定模式搜索文件,并以人性化的语法高亮显示匹配的代码片段。此工具将 GitHub 上的代码搜索结果带到您的本地计算机。简而言之,它类似于使用 ripgrep 搜索文件,并使用 bat 显示结果。

这与 -C 选项的 grep 命令类似。hgrep 适用于查看匹配及其周围上下文。当某些匹配项足够接近时,hgrep 会打印一个代码片段内的行。与 grep -C 不同,hgrep 采用了关于空白行的某些启发式方法来确定高效的上下文行数。

screenshot

示例

# 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 提供了两个打印机来打印匹配结果以供您使用。请参阅'bat 打印机 v.s. syntect 打印机'部分进行比较。

  • syntect 打印机(默认):我们使用 syntect 库实现的打印机。性能、输出布局和颜色主题都进行了优化
  • bat 打印机:建立在 bat 的美观打印实现之上的打印机,经过实战检验并提供了某些独特功能

请参阅使用部分以获取更多详细信息。

安装

二进制发布版本

访问发布页面并下载适用于您平台的zip文件。解压文件,并将可执行文件放入某个$PATH目录。目前支持以下目标。如果您需要其他平台的二进制文件,请随意创建一个问题来请求它。

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

通过Homebrew

通过将hgrep仓库添加为Homebrew tap,可以使用Homebrew安装和管理hgrep命令。该公式支持x86_64/aarch64 macOS和x86_64 Linux。公式

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

注意:如果您将Homebrew安装到了非默认位置(例如,~/homebrew),您可能会看到一些错误。在这种情况下,请尝试通过cargo安装hgrep。有关更多详细信息,请参阅#6

通过MacPorts

在macOS上,您可以通过以下命令使用MacPorts安装hgrep

sudo port selfupdate
sudo port install hgrep

对于NetBSD

要使用包管理器安装预构建的二进制文件,只需运行

pkgin install hgrep

或者,如果您更喜欢从源代码构建

cd /usr/pkgsrc/textproc/hgrep
make install

通过Debian或Ubuntu上的APT包管理器

访问发布页面并下载.deb包文件。它可以通过dpkg命令安装

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

手册(对于man命令)和Bash自动完成是自动安装的。如果您使用的是其他shell,请自行设置shell完成。有关更多详细信息,请参阅'生成完成脚本'部分

通过cargo包管理器

cargo install hgrep

由于cargo从源代码构建hgrep命令,您可以选择您喜欢的功能并禁用其他功能。例如,如果您总是使用hgrep从stdin读取grep输出,并且不使用bat打印机,只启用syntect-printer可以显著减少依赖项的数量、安装时间和二进制文件大小。

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

功能标志

所有功能都是可选的,默认启用。至少需要启用bat-printersyntect-printer

功能 描述
ripgrep 基于ripgrep库构建的内置grep实现。在某些情况下性能优于将rg命令管道。
syntect-printer 使用syntect库构建的我们自己的打印机实现。性能和输出布局针对我们的用例进行了优化。
bat-printer 基于bat的漂亮打印机构建的打印机实现,它经过实战检验并提供了某些独特功能。

有关bat-printersyntect-printer之间的差异,请参阅'bat打印机 v.s. syntect打印机'部分。

用法

内置ripgrep

hgrep可以提供内置grep实现,归功于ripgrep库。它是rg命令的一个子集。

内置的ripgrep是推荐使用hgrep的方式,因为它针对此用例进行了优化。

当给出一个模式时,hgrep命令将使用该模式搜索给定路径下的文件。当路径中包含目录时,hgrep将递归搜索该目录。如果没有给出路径,hgrep将搜索当前目录。

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

默认情况下,hgrep显示至少3行并且最多6行的匹配上下文。上下文行数由一些关于空白行的启发式算法确定,以节省空间。可以通过-c指定最小上下文行数,通过-C指定最大上下文行数。如果您不想使用启发式算法,可以将这两个选项设置为相同的值,例如-c 6 -C 6

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

与ripgrep一样,内置的grep默认会过滤文件。它会查看忽略文件,例如.gitignore,并忽略隐藏文件。要禁用过滤器,可以使用分别的--no-ignore--hidden选项。-u是它们的便捷快捷键。

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

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

与通过管道从greprg接收输入相比,在同一个进程中处理这么多匹配项的速度很快。结合syntect-printer功能,匹配区域可以以搜索文本的颜色突出显示。内置grep功能默认启用,可以通过功能标志省略。

尽管实现了几乎所有有用的选项,但内置grep的实现是ripgrep的一个子集。如果您需要完整的功能,请使用rg命令,并通过stdin将其输出传递给hgrep。目前有以下限制。

  • 不支持预处理器(例如搜索zip文件)
  • 不支持模式文件(-f--filerg
  • 不支持排序结果(--sort--sortr),因为它会显著减慢打印搜索输出的速度
  • 直到指定了--mmap标志,才使用内存映射
  • 不支持添加和删除文件类型。仅支持默认文件类型(请参阅--type-list
  • 不支持.ripgreprc配置文件
  • 不支持搜索二进制文件(--binary

不支持处理grep -nH输出

当命令行参数中没有给出模式和路径时,hgrep可以通过stdin接收grep结果。由于hgrep期望输出中的每行都包含文件路径和行号,因此在grep命令中必须使用-nH

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

还有其他如grep的替代工具,例如ripgrepagpt等,它们可以输出与grep -nH兼容的结果。

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

bat打印机与syntect打印机

hgrep提供了两种打印匹配结果的打印机;bat 打印机和 syntect 打印机。 bat 打印机是在bat的格式化打印机基础上构建的实现。而 syntect 打印机是我们使用syntect库构建的自定义打印机。使用 --printer(或 -p)标志可以指定用于打印结果的打印机。

最初,只有 bat 打印机。后来为了更好的性能和优化的布局,实现了 syntect 打印机。

每种打印机的优点

  • syntect 打印机
    • 性能大幅提升。2倍到4倍的速度(匹配结果越多,性能越好)。
    • 输出布局针对我们的使用场景进行了优化。匹配区域以搜索文本颜色突出显示。匹配行的行号以不同颜色突出显示。
    • 支持绘制背景颜色(--background)。当您的主题不适合终端的背景颜色时,这很有用。
    • 主题针对显示匹配结果进行了优化。并提供了一些新主题,如ayupredawn。查看--list-themes的输出以了解所有主题的列表。
    • 对旧终端的兼容性更好。它会自动将默认主题更改为'ansi',适用于16色终端。并且提供--ascii-lines标志,使用ASCII字符而不是像'├', '┬'这样的Unicode字符绘制边框线。
  • bat 打印机
    • 实现经过实战检验。它已经被许多平台和终端上的许多用户使用。
    • 其行为与 bat 命令兼容。其输出布局与 bat 命令相同,并尊重 BAT_THEMEBAT_STYLE 环境变量。它可以加载bat的自定义资源缓存。

syntect 是默认打印机。

仅适用于 syntect 打印机的主题

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

(等等...)

为什么 syntect 打印机的性能更好?

语法高亮是一个非常占用CPU的任务。每行都会发生许多正则表达式匹配。为了精确的语法高亮,高亮器需要从文件的开始解析语法。这意味着在文件的最后一行打印匹配项比在文件的第一行打印匹配项是一个更重的任务。

由于 syntect 打印机是为计算每个文件的语法高亮而设计的,因此其性能要高得多。在某些实验中,它比 bat 打印机快2倍到4倍。匹配结果越多,性能越好。

相比之下,bat 没有设计成多线程的。无法在多个线程之间共享 bat::PrettyPrinter 实例。这意味着必须在一个线程中完成包括语法高亮在内的匹配结果打印。

syntect 打印机序列 bat 打印机序列

使用分页器

当您希望分页器可以交互式查看输出时,请将输出重定向到外部命令,例如 less。因为当标准输出没有连接到 TTY 时,终端宽度固定为 80 个字符,所以需要将 $COLUMNS 传递给 --term-width 选项。如果您经常使用分页器,定义一个如下的包装 shell 函数是一个好选择

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

更改颜色主题和布局

默认颜色主题是 Monokai Extended,遵循 bat 命令的默认设置。其他主题可以通过 --theme 选项指定。要了解主题名称,请尝试 --list-themes 标志。

hgrep --theme Nord ...

默认布局是 'grid'。为了更有效地使用空间,减少边框线,提供了 --no-grid 选项。

hgrep --no-grid ...

当您使用 bat 打印机时,hgrep 会尊重 BAT_THEMEBAT_STYLE 环境变量。默认使用设置为 BAT_THEME 的主题。当 BAT_STYLE 设置为 plainheadernumbers 时,使用网格布局。 syntect 打印机不会查看这些变量。要设置默认主题,请使用 shell 中的命令别名(有关详细信息,请参阅'设置默认命令选项')。

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

当使用 syntect 打印机时,支持使用 --background 标志绘制背景颜色。

hgrep --background ...

设置默认命令选项

HGREP_DEFAULT_OPTS 环境变量可用于。当您运行 hgrep 命令时,将变量设置的选项添加到命令行参数之前。

以下是一些示例

# 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'

环境变量中的命令行参数使用 shlex 进行解析。在命令行选项参数中包含空格时使用引号。例如

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

命令选项

  • 常见选项
    • --min-context NUM (-c):围绕每个匹配项的起始和结束上下文的行数。默认值为 3
    • --max-context NUM (-C):围绕每个匹配项的起始和结束上下文的行数。默认值为 6
    • --no-grid (-G):移除边框线以使输出更紧凑。--grid 标志与此标志相反
    • --tab NUM:制表符字符的空格数。设置为 0 以通过制表符。默认值为 4
    • --theme THEME:语法高亮的主题。默认值与 bat 命令相同
    • --list-themes:列出所有可用的主题名称及其 --theme 选项的示例
    • --printer:打印匹配结果的打印机。'bat' 或 'syntect' 可用。默认值为 'bat'
    • --term-width NUM:终端窗口的宽度(字符数)
    • --wrap MODE:文本换行模式。'char' 启用按字符的文本换行。'never' 禁用文本换行。默认值为 'char'
    • --first-only (-f):仅显示每个文件的第一个代码片段
    • --encoding (-E):指定 hgrep 在打印所有文件时使用的文本编码,如 'sjis'
  • 仅针对 ripgrep 功能
    • --no-ignore:不尊重忽略文件(.gitignore、.ignore 等)
    • --ignore-case (-i): 当提供此标志时,将按不区分大小写的方式搜索给定模式
    • --smart-case (-S): 如果模式全部为小写,则不区分大小写搜索。否则区分大小写搜索
    • --hidden (-.): 搜索隐藏文件和目录。默认情况下,隐藏文件和目录将被跳过
    • --unrestricted (-u): 通过重复使用减少“智能”过滤级别(最多2级)。单个标志 -u 等同于 --no-ignore。两个标志 -uu 等同于 --no-ignore --hidden。与 ripgrep 不同,三个标志 -uuu 不受支持,因为 hgrep 不支持 --binary 标志
    • --glob GLOB... (-g): 包括或排除与给定 glob 匹配的文件和目录进行搜索
    • --glob-case-insensitive: 使用 -g/--glob 标志不区分大小写处理 glob 模式
    • --fixed-strings (-F): 将模式视为字面字符串而不是正则表达式
    • --word-regexp (-w): 仅显示由单词边界包围的匹配项
    • --follow (-L): 当此标志启用时,hgrep 将在遍历目录时跟随符号链接
    • --multiline (-U): 启用跨多行匹配
    • --multiline-dotall: 启用正则表达式中的“点所有”,当启用多行搜索时,点(.)将匹配换行符
    • --crlf: 当启用时,hgrep 将将 CRLF(《tt class="src-rs">\r\n》)视为行终止符,而不仅仅是 \n。此标志在 Windows 上非常有用
    • --mmap: 当可能时使用内存映射进行搜索。默认情况下,与 hgrep 不同,mmap 被禁用
    • --max-count NUM (-m): 限制每个文件中匹配行的数量为 NUM
    • --max-depth NUM: 限制目录遍历的深度为给定路径之外的 NUM 级
    • --max-filesize NUM+SUFFIX?: 忽略大于 NUM 大小的文件。这不适用于目录。输入格式接受后缀 K、M 或 G
    • --line-regexp (-x): 仅显示由行边界包围的匹配项。这相当于在搜索模式周围放置 ^...$
    • --invert-match (-v): 反转匹配。显示不匹配给定模式的行
    • --pcre2 (-P): 当此标志存在时,hgrep 将使用 PCRE2 正则表达式引擎而不是其默认引擎
    • --type TYPE (-t): 仅搜索匹配 TYPE 的文件。此选项可重复
    • --type-not TYPE (-T): 不要搜索匹配 TYPE 的文件。与 --type 相反。此选项可重复
    • --type-list: 显示所有支持的文件类型及其相应的 glob
    • --one-file-system: 当启用时,搜索将不会跨越相对于其开始位置的文件系统边界
    • --no-unicode:禁用对Unicode感知的正则表达式匹配
    • --regex-size-limit NUM+SUFFIX?:编译正则表达式的上限大小。默认限制为10M。关于大小后缀,请参阅--max-filesize
    • --dfa-size-limit NUM+SUFFIX?:正则表达式DFA的上限大小。默认限制为10M。关于大小后缀,请参阅--max-filesize
  • 仅适用于syntect-printer功能
    • --background:绘制背景颜色。当您喜欢的主题不适合您的终端背景颜色时,这很有用
    • --ascii-lines:使用ASCII字符绘制边框线而不是Unicode字符
  • 仅适用于bat-printer功能
    • --custom-assets:从缓存加载bat的自定义资源。请注意,此标志可能与某些版本的bat命令不兼容

有关您环境中可用的所有选项的完整列表,请参阅--help

文本编码

hgrep由于encoding_rs crate的支持,支持多种编码。

--encoding-E)命令行选项可以显式指定文件编码。例如,以下命令将假设匹配的文件使用Shift JIS编码。

hgrep --encoding sjis pattern

此外,hgrep会尝试从BOM检测文件编码。UTF-16LE、UTF-16BE和UTF-8可以自动检测。

如果没有从BOM检测到文件编码,hgrep默认将文件编码为UTF-8。如果包含格式错误的UTF-8序列,它们将被替换为替换字符U+FFFD

生成完成脚本

提供了hgrep命令的Shell完成脚本。--generate-completion-script选项生成完成脚本并将其打印到stdout。BashZshFishPowerShellElvishNushell都受支持。有关更多详细信息,请参阅--help

以下是在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

生成手册页

提供了hgrep命令的手册页。--generate-man-page标志生成手册页并将其打印到stdout。

以下是在/usr/local/share中生成手册页的一个示例。

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

# See the manual page
man hgrep

退出状态

hgrep命令按照以下方式返回退出状态。

状态 描述
0 找到一个或多个匹配项
1 未找到匹配项
2 发生某些错误(例如IO错误)

终端颜色支持检测

hgrep通过以下逻辑自动检测您的终端应用程序的24位、256或16色支持。

COLORTERM

首先,hgrep检查COLORTERM环境变量。当变量设置为truecolor24bit时,启用24位颜色。

在Linux、macOS、FreeBSD或NetBSD上,hgrep尝试通过terminfo检测您的终端的颜色支持。

在Windows上,如果Windows版本是10.0.15063或更高版本,hgrep启用24位颜色,因为操作系统版本10.0.15063(Windows 10 1703)开始支持24位颜色。否则,它只启用16种颜色。

TERM

当未设置COLORTERM时,hgrep会检查TERM环境变量,该变量设置了终端名称。

  • 如果它以-truecolor-24bit结尾,则启用24位颜色。
  • 如果它以-256color-square结尾,则启用256种颜色。

后备

如果没有从COLORTERMTERM检测到颜色支持,htrep最终会回退到256种颜色,这些颜色在流行的终端中得到了最广泛的支持。

版本

此时,主版本固定为0。当添加一些破坏性变化时,次版本号会增加。当添加一些新兼容性更改和/或一些错误修复时,补丁版本号会增加。

替代方案

一些其他替代方案,而不是使用hgrep。

用于组合ripgrepbat的小ShellScript

ripgrep和bat是设计良好的工具,因此可以作为小型脚本的一部分使用。

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

它工作得很好,但hgrep在这个用途上更优化。

  • 当匹配项足够接近时,行将在一个片段中打印。
  • 性能比为每行匹配项运行bat进程要好得多。
  • hgrep基于某些启发式算法计算高效的上下文行。
  • hgrep在ShellScript不可用的地方可用(例如PowerShell)。

类似于fzf的模糊搜索器,带有bat预览窗口

类似于fzf的模糊搜索器提供预览窗口功能,并且bat可以在预览窗口中打印匹配项。

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

当您需要增量搜索时,此用法非常出色,但您需要逐个检查匹配项的每个预览。

hgrep专注于查看所有匹配项。

错误报告

在GitHub上创建一个问题。确保描述如何重现错误。

许可证

hgrep在MIT许可证下分发。

依赖关系

~7–21MB
~366K SLoC