用 Hister 打造个人搜索引擎工作流:从全局快捷键到索引维护的完整实践
【免费下载链接】histerYour own search engine项目地址: https://gitcode.com/GitHub_Trending/hi/hister
本文是 Hister 作者对自己日常搜索工作流的完整梳理:如何用全局快捷键把 Hister 变成"随时可用"的个人搜索入口,如何用查询语言、搜索别名与键盘导航把一次检索压缩到几次按键,如何优雅地回退到外部搜索引擎,以及如何通过 skip 规则、定期清理与预索引让索引始终保持精准。读完本文,你将获得一套可直接复制的搜索效率方案,并理解其背后的配置项与源码实现。
本文基于作者的真实使用习惯展开,文中涉及的工具(如 i3、xdg-open、Chromium)都是可替换的——核心方法论适用于任何窗口管理器与操作系统。配套的配置细节、命令参数与源码依据,均来自当前仓库的 配置实现、命令实现 与官方文档。
三步式搜索工作流
作者的日常搜索工作流可以概括为三个步骤:
- 尽可能快地打开 Hister
- 用最少的按键确认结果是否已在索引中
- 没有相关内容时,无缝回退到传统搜索引擎
这三步分别对应三个优化方向:启动速度、查询精度与兜底路径。下面逐一展开。
1. 秒开 Hister:全局快捷键与窗口管理器集成
把 Hister 设为浏览器的默认搜索引擎是一个不错的起点,但它仍然要求你先切换到浏览器窗口、打开新标签页、敲下回车,结果才会出现。更快的方案是:在窗口管理器里绑定一个全局热键,直接跳转到浏览器并打开新的 Hister 标签页。这样,一个两键组合就能让一个全新的搜索框出现在你面前。
作者使用 i3 窗口管理器,相关配置行是:
bindsym Mod4+s exec xdg-open "http://127.0.0.1:4433/"其中xdg-open(freedesktop.orgxdg-utils包的一部分)会用注册了该 URL scheme 的应用打开参数:通常就是你的默认浏览器。
作者将xdg-open的默认 URL 打开程序设置成一个小小的 shell 脚本:
#!/bin/sh chromium --incognito "$1" i3-msg "workspace web"这段脚本会启动一个新的浏览器窗口(如果浏览器已经在运行,则新建标签页),然后通知 i3 切换到浏览器所在的工作区。如果你同时使用多个浏览器,可以用下面这条命令替换最后的i3-msg:
sleep 0.1 && i3-msg "[urgent=latest] focus"它先短暂等待新窗口出现,再通过紧急提示(urgency hint)聚焦它,从而保证无论哪个浏览器被打开,你都能落到正确的窗口上。
需要说明的是:xdg-open完全可选,你可以直接在热键里管理窗口聚焦与浏览器启动。作者偏好xdg-open,是为了让所有应用获得一致的行为。
即使你的环境完全不同,原则是相同的:绑定一个打开新 Hister 标签页并聚焦它的全局热键。
从源码看,Hister 服务默认监听http://127.0.0.1:4433/的假设并非空穴来风——仓库的 Dockerfile 与 compose.yml 等部署文件均围绕本机自托管设计,默认数据目录等细节可参考 config/config.go 中的默认值定义。
2. 让搜索更高效
在 Hister 内保持搜索速度,作者依赖三样东西:查询语言、搜索别名与键盘导航。
掌握查询语言
Hister 的查询语言可以快速收窄结果范围。作者日常使用字段过滤器(field filters)、排除项(exclusions)与同义词组合(alternations)来用更少的按键得到更精确的结果,例如:
domain:github.com -type:local indexer这条查询的含义是:查找关于 indexer 的 GitHub 页面,同时排除本地文件(-type:local)。
查询语言的常用要素包括:
- 字段过滤:
title:、text:、url:、domain:、label:、language:、type:、visits:、added:、updated:等字段,例如domain:github.com只搜索该域名的页面; - 精确短语:用双引号包裹,如
"privacy policy"; - 排除:用减号前缀,如
-facebook、-type:file; - 同义词/或条件:用括号与竖线,如
(security|privacy|encryption); - 通配符:
secur*匹配 security、secure 等; - 排序:
sort:date、sort:visits、sort:-date等指令控制结果顺序。
完整字段说明与示例可以阅读查询语言指南。
搜索别名
作者为反复出现的搜索模式定义别名,主要使用两种风格:
同义词(Synonyms):当一个主题有多个常见名称时,用一个词作为别名。例如,go解析为(go|golang),这样无论页面用的是哪种拼写,你都能搜到,不必每次思考写法。
定向过滤器(Targeted filters):针对特定场景的搜索,使用!前缀让别名与普通词区分开。作者最典型的例子是!hi("Hister issues"),它解析为:
url:https://github.com/asciimoo/hister/issues/*输入!hi indexer就能立即列出所有提到 indexer 的 Hister GitHub issue。
这类别名把多词过滤器表达式压缩成一个短 token,让重复性搜索快得多。
从实现上看,别名并非在搜索引擎内部展开,而是在查询执行前由配置层完成。config/config.go中定义了Aliases map[string]string(config/config.go),ResolveAliases方法将查询按空白分词,并把与别名键完全相等的 token 替换为对应的展开表达式(config/config.go)。这意味着别名只作用于完整的单词 token——它不会匹配子串,你可以放心用短词而不必担心误伤。
别名与 skip、priority、versioning 规则一起存放在rules配置中(config/config.go)。单用户模式下规则保存在数据目录的rules.json中,多用户模式下每个用户有一份存于数据库的私有副本,详见规则文档。一份典型的别名配置长这样:
{ "gh": "domain:github.com", "local": "type:file", "work": "domain:(internal.example.com|jira.example.com)" }键盘导航
Hister 的热键可以让你完全用键盘移动结果并打开阅读视图(默认alt+v)。阅读视图在 Hister 内部渲染页面的干净版本,很多时候你不需要离开搜索界面就能获取所需信息。
阅读视图在源码中对应 Web 界面的view_result_popup动作("打开选中结果的离线预览弹窗"),其渲染路径复用了 go-readability 库做正文提取与清理(参见 cmd/tui/render/preview.go),这正是"干净可读版本"的技术来源。
Web 界面的默认热键定义在 config/config.go:
| 热键 | 动作 |
|---|---|
alt+j/alt+k | 选择下一个 / 上一个结果 |
/ | 聚焦搜索输入框 |
enter | 打开结果 |
alt+enter | 在新标签页打开结果 |
alt+o | 在配置的外部搜索引擎中打开当前查询 |
alt+v | 打开结果的离线预览(阅读视图) |
tab | 接受自动补全建议 |
? | 显示快捷键帮助 |
alt+d | 删除选中结果 |
把这些热键按你的习惯配置即可——默认值是一个合理的起点(对 vim 用户尤其友好)。完整的可配置动作列表(focus_search_input、open_result、open_query_in_search_engine、view_result_popup、show_hotkeys等)见配置文档的 hotkeys.web 章节。TUI(终端客户端)的快捷键则在独立的tui.yaml中配置,首次运行hister search时自动生成默认文件,同样包含j/k上下移动、enter打开结果、v切换预览等键位。
3. 无缝回退到外部搜索引擎
当所需信息不在你的索引中时,Hister 会为搜索流程增加额外开销。作者的优化目标是让这个开销尽可能小。他区分了两种场景:
场景一:搜索前就知道结果不在 Hister 里
在查询开头或结尾输入!!并按回车。Hister 会立即用同一查询重定向到你配置的外部搜索引擎。这在 Hister 界面和浏览器地址栏(当 Hister 被设为默认搜索引擎时)都能生效,唯一的开销只是多打两个字符。
例如:
!! advanced kubernetes networking guide场景二:搜索中途发现结果不在这里
按下配置的热键(默认Alt+o)或点击搜索框下方的Web链接。这会把当前查询直接带到你配置的搜索引擎,无需手动重打一遍——省去了"切到搜索引擎页面、重新输入查询"两步操作。
这条链路背后的配置项是app.search_url(config/config.go)。官方配置文档给出的默认值是:
app: search_url: "https://google.com/search?q={query}"其中{query}是查询词占位符。你可以换成任何搜索引擎,例如 DuckDuckGo 或 Bing:
app: search_url: "https://duckduckgo.com/?q={query}"此外,配置文档还提到一个关联行为:当查询无结果时,Hister 可以重定向到配置的search_url,如需保持停留在 Hister 内部可以关闭该行为。
保持索引干净
除了优化搜索流程,一个维护良好的索引也能显著提升效率。不断增长的索引只有在持续相关时才有价值,作者依靠两个习惯来维持。
Skip 规则
并非每个访问过的页面都值得索引。例如社交媒体信息流只会增加噪音而不增加价值。作者使用 skip 规则让它们从一开始就不进入索引。
skip 规则匹配的是完整 URL(含 scheme、host、path 与 query string),使用 Go 正则表达式语法,且不支持 look-ahead / look-behind;锚定必须包含 scheme,例如^https?://(login|mail)\.是合法的,而^foo.com不行。URL 的 hash 会在匹配前被剥离,utm_*参数会被去掉(详见规则文档的 Pattern syntax 章节)。
在规则页(Rules 页面)新增或编辑 skip 规则时,勾选Delete matching documents already in the index可以把规则应用到已存在的文档上——页面会显示匹配数量并要求确认后再删除,取消则只保存规则、保留已有文档。
作者的建议是:平时多留意自己的索引,发现噪音模式就及时补上对应的 skip 规则。
清理过期条目
即使有良好的 skip 规则,索引中仍会积累一些变得无关的内容:误打开的页面、不再使用的库的文档、已经放弃的项目的页面。作者在每次发现索引中有无用内容时就用delete命令清理:
hister delete "domain:old-framework.io" hister delete "url:https://jobs.example.com/*"--dry参数可以在真正删除前预览将要删除的内容:
hister delete --dry "domain:old-framework.io"从命令实现看(cmd/root.go),delete命令还支持:
--dry:只显示会被删除的文档数量,不真正删除;--verbose/-v:列出所有将被删除的 URL,可与--dry组合使用;--yes/-y:跳过确认提示直接删除。
由于delete接受完整查询表达式,它完全可以和前面学到的查询语言组合出非常精准的清理语句,例如hister delete --dry "domain:old-framework.io updated:>90d"这类按域名加时间维度的复合清理。
预索引参考资料
浏览器扩展只在你访问页面时进行索引,这意味着你从未打开过的文档对 Hister 是不可见的。作者用爬虫(crawler)预索引自己预期会反复查阅的参考资料来弥补这个缺口:
hister index --recursive --allowed-pattern=pkg.go.dev/some/library https://pkg.go.dev/github.com/some/library这条命令会爬取该库的文档页面,并把所有内容加入索引。
从 cmd/index.go 的实现看,hister index在递归模式下创建的是一个持久化爬取任务(persistent crawl job),并通过验证器规则控制爬取边界(crawlValidatorRules,cmd/index.go)。常用参数包括:
| 参数 | 作用 |
|---|---|
--recursive/-r | 递归爬取链接页面 |
--allowed-pattern | 正则模式,URL 必须匹配才会被跟进(可重复) |
--exclude-pattern | 正则模式,匹配的 URL 被跳过(可重复) |
--allowed-domain | 允许爬取的域名(可重复) |
--exclude-domain | 排除的域名(可重复) |
--max-depth | 最大爬取深度(0 = 不限) |
--max-links | 最多访问的页面数(0 = 不限) |
--force | 即使 URL 已在索引中也重新索引 |
--label | 为所有索引的文档附加标签 |
--delay/--timeout | 请求间隔(秒)/ 超时(秒),覆盖配置文件 |
--no-robots | 禁用 robots.txt 合规检查 |
--job-id | 持久化任务的 ID,可配合--recursive启动新任务或单独使用恢复旧任务 |
--input | 从文件或标准输入读取 URL 列表(每行一个),创建持久化任务 |
两点值得注意的默认行为:
- 爬取默认遵守 robots.txt:
cmd/index.go会构造crawler.RobotsCache检查每个 URL 是否被允许(cmd/index.go),需要越过后才使用--no-robots; - 递归模式下,已索引过的 URL 默认会被跳过(通过
DocumentExists检查,可用--force覆盖),失败的 URL 会被记录,可通过--failed-urls输出到文件。
作者用这个能力覆盖三类典型场景:
- API 与库文档:日常使用的工具与依赖库;
- 项目 wiki 与内部文档:团队或个人项目的说明页面;
- 长文参考页:知道自己会反复回来查阅的页面。
小结
一点点前置配置——一个全局热键、若干搜索别名、几条 skip 规则,加上对查询语法的熟悉——就能让 Hister 作为日常工具的效率显著提升。而预索引参考资料、定期清理过期条目,则保证索引在增长过程中始终保持精准。
这套工作流的全部细节都建立在实际可配置、可验证的组件之上:全局热键与search_url见配置文档,查询语法见查询语言指南,skip 规则与别名存储见规则文档,index命令的参数体系见 cmd/index.go,热键默认值则定义在 config/config.go。无论是窗口管理器、浏览器还是搜索引擎的选择,方法论本身都可以直接迁移到你自己的环境。
【免费下载链接】histerYour own search engine项目地址: https://gitcode.com/GitHub_Trending/hi/hister
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考