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 [email protected]:lotabout/skim.git ~/.skim $ ~/.skim/install
- 使用二进制文件:直接 下载 sk 可执行文件。
- 从 crates.io 安装:
cargo install skim
- 手动构建
$ git clone --depth 1 [email protected]: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