codespelunker (cs)
一个命令行搜索工具。允许您在当前目录下搜索代码或文本文件,可以通过控制台、TUI或HTTP服务器使用布尔查询或正则表达式进行搜索。
可以将其视为类似于使用ripgrep、silver searcher或grep结合fzf的方法,但集成在单个工具中。
采用MIT或UNLICENSE双重许可。
支持
商业使用cs
?如果您需要cs
的优先支持,可以购买一年的支持服务 https://boyter.gumroad.com/l/vvmyi ,这将使您有权获得开发者的优先直接电子邮件支持。
特点
为什么使用cs?
- 速度相当快
- 实时对结果进行排序,帮助您找到所需内容
- 可跨多行搜索
- 具有美观的TUI界面
- 跨平台(可能需要新的Windows终端)
cs
存在的原因是因为我在使用rg TERM | fzf
时遇到了限制,于是决定解决自己的问题。
安装
如果您想创建安装包,请尽管去做。告诉我,我会确保在这里添加相关信息。
Go Get
如果您安装了Go >= 1.20
go install github.com/boyter/cs@v1.3.0
Nixos
nix-shell -p codespelunker
https://github.com/NixOS/nixpkg/pull/236073
手动安装
Windows、GNU/Linux和macOS的二进制文件可从releases页面获取。
常见问题
这个工具速度是否和...一样快?
不是。
你没让我说完,我想问它是否和...一样快?
答案可能是否定的。它不能直接比较。据我所知,除了全文索引工具(如hound、searchcode、sourcegraph等)外,没有其他工具像这样工作。没有工具能像这样实时工作。
虽然cs
与ripgrep、grep、ack或silver searcher等工具有一些重叠,但实际上它的工作方式不同,所以任何比较都是毫无意义的。它比它们中的大多数都慢,但它也在做不同的事情。
如果你想进行一个有缺陷的比较,可以尝试将它们的输出通过管道传递给fzf。
在我的本地机器上(写作时是Macbook Air M1),它可以在约2.5秒内搜索最近checkout的Linux源代码。虽然绝对性能不是设计目标,但我也不希望这是一个缓慢的工具。因此,如果有任何明显的性能提升机会,我都会采纳。
它能在普通文档上工作吗?
只要是文本文件就可以。我写它是为了搜索代码,但它对全文文档也同样有效。例如,我在《傲慢与偏见》上测试了片段提取功能。如果你有大量PDF文件,你可以用shell脚本配合pdftotext来创建可搜索的内容。
请注意,它是为代码设计的,因此完全支持.ignore和.gitignore文件。
索引在哪里?
没有索引。所有计算都是实时暴力进行的。对于TUI模式,采用了一些结果缓存的快捷方式来提高速度。
那么排名是如何工作的?
标准BM25或TF/IDF,或者Lucene中修改的TF/IDF https://opensourceconnections.com/blog/2015/10/16/bm25-the-next-generation-of-lucene-relevation/ ,它减弱了词频的影响。
从技术上讲,它并不准确,因为它是根据匹配到的内容而不是所有内容来计算权重的,但在实践中效果足够好,而且是实时计算的。试试看,如果有什么不符合你预期的,请反馈!
你是如何获取片段的?
这不是一件容易的事... https://github.com/boyter/cs/blob/master/snippet.go 看看代码吧。
它的工作原理是传递要提取片段的文档内容和每个词的所有匹配位置。然后它遍历每个词的每个位置,检查两侧寻找附近的词。接着它根据我们正在检查的词的词频进行排名,并对更罕见的词给予奖励。它还奖励更多匹配、更近的匹配、精确大小写匹配和完整单词匹配。
更多信息请阅读这篇博文的"Snippet Extraction AKA I am PHP developer"部分 https://boyter.org/posts/abusing-aws-to-make-a-search-engine/
HTTP模式看起来是什么样的?
它有点简陋。
<img alt="scc" src=https://github.com/boyter/cs/raw/master/cs_http.png>
你可以使用--template-display
和--template-search
来改变它的外观和感觉。查看 https://github.com/boyter/cs/tree/master/asset/templates 获取可用于修改的示例模板。
cs -d --template-display ./asset/templates/display.tmpl --template-search ./asset/templates/search.tmpl
使用方法
cs
的命令行使用设计得尽可能简单。
完整详情可以在cs --help
或cs -h
中找到。请注意,以下内容反映的是master分支的状态,而不是发布版本,因此下面列出的功能可能在你的安装版本中缺失。
$ cs -h
代码探索器 (cs) 代码搜索。
版本 1.3.0
Ben Boyter <ben@boyter.org>
cs 使用一些布尔逻辑递归搜索当前目录,
可选择与正则表达式结合使用。
可通过命令行工作,将传入的参数作为搜索词,
或在无参数时以 TUI 模式运行。也可以使用
-d 或 --http-server 标志在 HTTP 模式下运行。
默认搜索对所有术语使用 AND 布尔语法
- 使用引号进行精确匹配 "查找这个"
- 在 1 或 2 的距离内进行模糊匹配 fuzzy~1 fuzzy~2
- 使用 NOT 进行否定,如 pride NOT prejudice
- 使用牙签语法进行正则表达式 /pr[e-i]de/
通过添加以下语法可以模糊匹配要搜索的文件
- test file:test
- stuff filename:.go
搜索的文件将限制为第一个示例中模糊匹配 test 的文件,
第二个示例中匹配 .go 的文件。
使用所有当前功能的示例搜索
- darcy NOT collins wickham~1 "ten thousand a year" /pr[e-i]de/ file:test
TUI 模式下的默认输入字段支持一些 nano 命令
- CTRL+a 移动到输入的开头
- CTRL+e 移动到输入的末尾
- CTRL+k 从光标位置向前清除
用法:
cs [标志]
标志:
--address string HTTP 模式下监听的地址和端口 (默认 ":8080")
--binary 设置以禁用二进制文件检测并搜索二进制文件
-c, --case-sensitive 使搜索区分大小写
--dir string 要搜索的目录,如果未设置则默认为当前工作目录
--exclude-dir strings 要排除的目录 (默认 [.git,.hg,.svn])
-x, --exclude-pattern strings 匹配区分大小写模式的文件和目录位置将被忽略 [逗号分隔列表:例如 vendor,_test.go]
-r, --find-root 尝试通过反向遍历查找 .git 或 .hg 来找到此存储库的根目录
-f, --format string 设置输出格式 [text, json, vimgrep] (默认 "text")
-h, --help cs 的帮助
--hidden 包括隐藏文件
-d, --http-server 启动搜索的 http 服务器
-i, --include-ext strings 限制文件扩展名(注意:区分大小写)[逗号分隔列表:例如 go,java,js,C,cpp]
--max-read-size-bytes int 读入文件的字节数,忽略剩余内容 (默认 1000000)
--min 包括压缩文件
--min-line-length int 文件被视为压缩文件的平均行字节数 (默认 255)
--no-gitignore 禁用 .gitignore 文件逻辑
--no-ignore 禁用 .ignore 文件逻辑
-o, --output string 输出文件名(默认标准输出)
--ranker string 设置排名算法 [simple, tfidf, tfidf2, bm25] (默认 "bm25")
-s, --snippet-count int 显示的片段数量 (默认 1)
-n, --snippet-length int 显示的片段大小 (默认 300)
--template-display string 自定义样式的显示模板路径
--template-search string 自定义样式的搜索模板路径
-v, --version cs 的版本
搜索可以在单个或多个词上进行,它们之间应用逻辑 AND。您可以在术语前使用 NOT 进行否定。 您可以使用引号进行精确匹配,并使用牙签进行正则表达式。
使用所有当前功能的示例搜索
cs t NOT something test~1 "ten thousand a year" "/pr[e-i]de/" file:test
如果您喜欢,可以在 TUI 模式下以类似于 fzf
的方式使用它,因为如果您按回车键,cs
将返回匹配的文档路径。
cat `cs`