Rust製Fuzzy Finderのskimを自作CLIツールに組み込んでみる
Rust で書かれたskim
では Go で書かれているfzf
のように曖昧検索ができます。cargo install skim
でインストールしsk
コマンドで利用できるようになります。
この skim
はライブラリとしても利用できます。今回は自作のブックマーク管理 CLI ツールに skim
を組み込んでみました。
作ったもの
こちらです。
自分がよく閲覧する Web の記事のリンクをローカルで管理できるCLIツールです。ブックマークは~/rbm-bookmarks.toml
というファイルに保存されます。
はてブとかブラウザのブックマークでも良いのですが、自分はVimを使って作業することが多いためいちいちブラウザに行かずにターミナルからさくっと開きたい一心で作りました。
crate.ioにも登録しているのでcargo install rbm
でインストールできます。
rbm add
コマンドで新規ブックマークを追加します。
$ rbm add
Title> Google
URL> https://google.com
Tag> Google,Search
rbm list
で登録したブックマークの一覧を表示し、曖昧検索で絞りこんで選択したブックマークをブラウザで開くことができます。ここでskim
をライブラリとして使用しています。
ライブラリとして利用している部分のコード
ブックマーク管理 CLI ツールでskim
を用いて曖昧検索をしている部分のコードは下記となります。
(CLI ツール自体の作りや toml ファイルに保存する部分については割愛します。詳細は GitHub をご確認ください。)
use crate::bookmark::Bookmark;
use skim::prelude::*;
use skim::{Skim, SkimItemReceiver, SkimItemSender};
use std::{process::Command, sync::Arc};
impl SkimItem for Bookmark {
// 曖昧検索に使われる値
fn text(&self) -> Cow<str> {
Cow::Borrowed(&self.inner)
}
// 絞り込んで選択した際に表示される値
fn output(&self) -> Cow<str> {
Cow::Borrowed(&self.url)
}
}
/// Search bookmark with fuzzy finder.
pub fn finder(bookmarks: Vec<Bookmark>) {
// 曖昧検索の起動時の画面高さを指定・Enterキーで選択する
let options = SkimOptionsBuilder::default()
.height(Some("50%"))
.multi(true)
.bind(vec!["Enter:accept"])
.build()
.unwrap();
let (tx_item, rx_item): (SkimItemSender, SkimItemReceiver) = unbounded();
for bookmark in bookmarks {
let _ = tx_item.send(Arc::new(bookmark));
}
drop(tx_item);
let selected_items = Skim::run_with(&options, Some(rx_item))
.map(|out| match out.final_key {
Key::Enter => out.selected_items,
_ => Vec::new(),
})
.unwrap_or_else(Vec::new);
for item in selected_items.iter() {
let url = item.output();
// 曖昧検索の結果出力されるurlをopenコマンドで開く
// Macだけで動く
Command::new("open")
.arg(url.as_ref())
.output()
.expect("Faild to execute process");
}
}
このコードはskim
のリポジトリのexamples
内にあるcustom_item.rsとcustom_keybinding_actions.rsのコードを参考にしています。
正直内部の仕組みを理解して使いこなせているわけではありませんが、割と簡単に自作 CLI ツールに曖昧検索を組み込むことができます。
ちなみに
今回作ったブックマーク管理アプリは Microsoft が公開している Rust の勉強教材(コマンドラインの to-do リスト プログラムを作成する)を改造して作りました。
この教材は私のような Rust 勉強中の者にとっては非常にためになります。
Discussion