31 个版本
| 0.10.4 | 2023 年 3 月 2 日 |
|---|---|
| 0.10.2 | 2022 年 11 月 8 日 |
| 0.9.4 | 2021 年 2 月 15 日 |
| 0.9.3 | 2020 年 11 月 2 日 |
| 0.2.1-beta.2 | 2017 年 1 月 19 日 |
#28 in 命令行工具
16,643 个月下载量
用于 108 个包(81 个直接使用)
420KB
10K SLoC
生命短暂,使用 skim!
我们的一半生命花在导航上:文件、行、命令……你需要 skim!它是一个节省时间的通用模糊查找器。
skim 提供了一个单独的可执行文件:sk。基本上任何你想使用 grep 的地方,都尝试使用 sk。
目录
安装
skim 项目包含几个组件
sk可执行文件 -- 核心。sk-tmux-- 在 tmux 窗格中启动sk的脚本。- Vim/Nvim 插件 -- 在 Vim/Nvim 中调用
sk。有关更多 Vim 支持,请参阅 skim.vim。
包管理器
| 分发 | 包管理器 | 命令 |
|---|---|---|
| macOS | Homebrew | brew安装 sk |
| macOS | MacPorts | sudoport install skim |
| Fedora | dnf | dnf install skim |
| Alpine | apk | apk add skim |
| Arch | pacman | pacman -S skim |
查看 repology 以获取包可用性的全面概述。
作为 Vim 插件安装
通过 vim-plug(推荐)
Plug 'lotabout/skim', { 'dir': '~/.skim', 'do': './install' }
硬核
以下任何一项适用
- 使用 Git
$ git clone --depth 1 git@github.com:lotabout/skim.git ~/.skim $ ~/.skim/install - 使用二进制文件:直接 下载 sk 可执行文件。
- 从 crates.io 安装:
cargo install skim - 手动构建
$ git clone --depth 1 git@github.com:lotabout/skim.git ~/.skim $ cd ~/.skim $ cargo install $ cargo build --release $ # put the resulting `target/release/sk` executable on your PATH.
用法
skim 可以用作通用过滤器(类似于 grep)或作为调用命令的交互式界面。
作为过滤器
尝试以下命令
# directly invoke skim
sk
# or pipe some input to it: (press TAB key select multiple items with -m enabled)
vim $(find . -name "*.rs" | sk -m)
上述命令将允许您选择 ".rs" 扩展名的文件,并在 Vim 中打开您选择的文件。
作为交互式界面
skim 可以动态调用其他命令。通常您会希望将其与 grep、ack、ag 或 rg 集成,以在项目目录中搜索内容
# works with grep
sk --ansi -i -c 'grep -rI --color=always --line-number "{}" .'
# works with ack
sk --ansi -i -c 'ack --color "{}"'
# works with ag
sk --ansi -i -c 'ag --color "{}"'
# works with rg
sk --ansi -i -c 'rg --color=always --line-number "{}"'

快捷键绑定
一些常用的快捷键
| 键 | 操作 |
|---|---|
| Enter | 接受(选择当前项并退出) |
| ESC/Ctrl-G | 中断 |
| Ctrl-P/Up | 向上移动光标 |
| Ctrl-N/Down | 向下移动光标 |
| TAB | 切换选择并向下移动(与 -m 结合使用) |
| Shift-TAB | 切换选择并向上移动(与 -m 结合使用) |
有关快捷键的完整列表,请参阅 man 页面(man sk)。
搜索语法
skim 借用了 fzf 的语法进行项目匹配
| 令牌 | 匹配类型 | 描述 |
|---|---|---|
text |
模糊匹配 | 匹配 text 的项目 |
^music |
前缀精确匹配 | 以 music 开头的项目 |
.mp3$ |
后缀精确匹配 | 以 .mp3 结尾的项目 |
'wild' |
精确匹配(引用) | 包含 wild 的项目 |
!fire |
否定精确匹配 | 不包含 fire 的项目 |
!.mp3$ |
否定后缀精确匹配 | 不以 .mp3 结尾的项目 |
skim 还支持令牌的组合。
- 空白符表示
AND。对于src main这个词,skim将搜索同时匹配src和main的项目。 |表示OR(注意|周围的空格)。对于.md$ | .markdown$这个词,skim将搜索以.md或.markdown结尾的项目。OR具有更高的优先级。因此,readme .md$ | .markdown$将分组为readme AND (.md$ OR .markdown$)。
如果您想使用正则表达式,skim 提供了 regex 模式
sk --regex
您可以通过按 Ctrl-R(旋转模式)动态切换到 regex 模式。
退出代码
| 退出代码 | 意义 |
|---|---|
| 0 | 正常退出 |
| 1 | 未找到匹配项 |
| 130 | 通过 Ctrl-C/Ctrl-G/ESC 等中断 |
自定义
此处文档仅是预览,请参阅 man 页面(man sk)以获取选项的完整列表。
快捷键映射
使用逗号分隔的键值对指定绑定(不允许有空格),例如
sk --bind 'alt-a:select-all,alt-d:deselect-all'
此外,使用 + 来连接操作,例如 execute-silent(echo {} | pbcopy)+abort。
有关详细信息,请参阅手册页中的 键盘绑定 部分。
排序标准
结果有五个排序键:score, index, begin, end, length,您可以通过指定 sk --tiebreak score,index,-begin 或任何其他您想要的顺序来指定记录的排序方式。
颜色方案
你很可能比我更有才华。幸运的是,你不会卡在默认颜色上,skim 支持自定义颜色方案。
--color=[BASE_SCHEME][,COLOR:ANSI]
颜色配置从基本颜色方案名称开始,后跟自定义颜色映射。例如
sk --color=current_bg:24
sk --color=light,fg:232,bg:255,current_bg:116,info:27
有关详细信息,请参阅手册页中的 --color 选项。
杂项
--ansi:解析数据源的 ANSI 颜色代码(例如,\e[32mABC)--regex:将查询用作正则表达式来匹配数据源
高级主题
交互模式
使用“交互模式”,您可以动态调用命令。试试看
sk --ansi -i -c 'rg --color=always --line-number "{}"'
它是如何工作的?

- Skim 可以接受两种类型的源:命令输出或管道输入
- Skim 有两种类型的提示:查询提示用于指定查询模式,命令提示用于指定命令的“参数”
-用于指定要执行的命令,默认为SKIM_DEFAULT_COMMAND-用于在启动时打开命令提示,默认显示c>。
如果您想进一步缩小命令返回的结果,请按 Ctrl-Q 切换到交互模式。
执行外部程序
您可以设置键盘绑定来启动外部进程而无需离开 skim(execute,execute-silent)。
# Press F1 to open the file with less without leaving skim
# Press CTRL-Y to copy the line to clipboard and aborts skim (requires pbcopy)
sk --bind 'f1:execute(less -f {}),ctrl-y:execute-silent(echo {} | pbcopy)+abort'
预览窗口
这是 fzf 的一个很棒的功能,skim 采用了这个功能。例如,我们使用 'ag' 来查找匹配的行,一旦我们缩小到目标行,我们最终想要通过检查行周围的上下文来决定选择哪些行。 grep 和 ag 有一个选项 --context,Skim 可以通过预览窗口做得更好。例如
sk --ansi -i -c 'ag --color "{}"' --preview "preview.sh {}"
(注意:preview.sh 是一个脚本,用于打印给定文件名:行:列的上下文)您会得到如下内容

它是如何工作的?
如果通过 --preview 选项提供了预览命令,Skim 将将 {} 替换为当前高亮的行,调用命令获取输出,并在预览窗口中打印输出。
有时您不需要整行来调用命令。在这种情况下,您可以使用{}、{1..}、{..3}或{1..5}来选择字段。语法在“字段支持”一节中解释。
最后,您可能想配置预览窗口的位置,使用--preview-window。
--preview-window up:30%将窗口置于上方,高度为skim总高度的30%。--preview-window left:10:wrap,指定wrap允许预览窗口包裹预览命令的输出。--preview-window wrap:hidden在启动时隐藏预览窗口,之后可以通过toggle-preview动作显示。
字段支持
通常只有插件用户需要理解这一点。
例如,您有如下格式的数据源
<filename>:<line number>:<column number>
然而,当在查询中输入时,您只想搜索<filename>。这意味着当您输入21时,您想找到一个包含<filename>且包含21的文件,而不是匹配行号或列号。
您可以使用sk --delimiter ':' --nth 1来实现这一点。
您还可以使用--with-nth来重新排列字段的顺序。
范围语法
<num>-- 指定第num个字段,从1开始。start..-- 从第start个字段开始,包括剩余的字段。..end-- 从第0个字段开始,一直到最后一个字段end,包括end。start..end-- 从第start个字段开始,一直到最后一个字段end,包括end。
作为库使用
Skim可以作为您的Rust包中的库使用。
首先,将skim添加到您的Cargo.toml
[dependencies]
skim = "*"
然后尝试运行这个简单的示例
extern crate skim;
use skim::prelude::*;
use std::io::Cursor;
pub fn main() {
let options = SkimOptionsBuilder::default()
.height(Some("50%"))
.multi(true)
.build()
.unwrap();
let input = "aaaaa\nbbbb\nccc".to_string();
// `SkimItemReader` is a helper to turn any `BufRead` into a stream of `SkimItem`
// `SkimItem` was implemented for `AsRef<str>` by default
let item_reader = SkimItemReader::default();
let items = item_reader.of_bufread(Cursor::new(input));
// `run_with` would read and show items from the stream
let selected_items = Skim::run_with(&options, Some(items))
.map(|out| out.selected_items)
.unwrap_or_else(|| Vec::new());
for item in selected_items.iter() {
print!("{}{}", item.output(), "\n");
}
}
给定一个 Option<SkimItemReceiver>,skim 将根据其读取项目,执行其任务,并返回用户选择,包括选定的项目、查询等。注意
SkimItemReceiver是crossbeam::channel::Receiver<Arc<dyn SkimItem>>- 如果没有,它将调用给定的命令并从命令输出中读取项目
- 否则,它将从(crossbeam)通道中读取项目。
特质 SkimItem 提供了自定义一行如何显示、比较和预览的方法。它默认实现了 AsRef<str>
此外,SkimItemReader 是一个将 BufRead 转换为 SkimItemReceiver 的辅助工具(我们可以轻松地将 File 转换为 BufRead)。这样你就可以轻松处理字符串或文件。
更多示例请查看 examples/ 目录。
常见问题解答
如何忽略文件?
Skim 调用 find . 获取用于过滤的文件列表。你可以通过设置环境变量 SKIM_DEFAULT_COMMAND 来覆盖它。例如
$ SKIM_DEFAULT_COMMAND="fd --type f || git ls-tree -r --name-only HEAD || rg --files || find ."
$ sk
如果你喜欢它作为默认值,可以将其放入你的 .bashrc 或 .zshrc
有些文件在 Vim 插件中不会显示
如果你使用 Vim 插件并执行 :SK 命令,你可能会发现一些文件没有显示。
如 #3 中所述,在 Vim 插件中,SKIM_DEFAULT_COMMAND 默认设置为命令
let $SKIM_DEFAULT_COMMAND = "git ls-tree -r --name-only HEAD || rg --files || ag -l -g \"\" || find ."
这意味着,git 识别不了的那些文件将不会显示。要么用 let $SKIM_DEFAULT_COMMAND = '' 覆盖默认值,要么自己查找缺失的文件。
与 fzf 的区别
fzf 是一个用 Go 编写的命令行模糊查找器,而 skim 尝试在 Rust 中实现一个新的版本!
该项目是从头开始的。一些实现决策与 fzf 不同。例如
skim是一个二进制文件以及库,而 fzf 只是一个二进制文件。skim有一个交互式模式。skim支持预选择- 模糊搜索算法不同。
显示匹配项的 UI。(fzf 现在有这个功能了)fzf将只显示匹配的范围,而skim将显示每个匹配的字符。:现在它与 fzf 相同。skim的范围语法是 Git 风格
如何贡献
如果您遇到任何错误或有任何想法,请创建新问题。拉取请求非常受欢迎。
依赖项
~9–19MB
~257K SLoC