[!NOTE] Update (2026-04-04) shun の大幅なバージョンアップ(v5.0.1)に伴い、履歴スキーマ(バージョン 2)の変更や、新しい設定項目、プレビューパネルの追加などを反映しました。

Alfred や Raycast が好きで、Windows でも同じような体験がしたくて、Claude Code と一緒にランチャーを作りました。

shun とは

shun (瞬) は、グローバルホットキーで呼び出せるキーボードドリブンのミニマルランチャーです。

  • バックエンド: Rust + Tauri v2
  • フロントエンド: Svelte 5
  • 検索エンジン: nucleo-matcher(Helix エディタと同じファジー検索エンジン)
shun demo

主な機能

ファジー / 完全一致 / migemo 検索

nucleo-matcher によるファジー検索と完全一致検索を設定で切り替えられます。インストール済みアプリ、設定したアプリ、スキャンしたディレクトリのファイルが瞬時に絞り込まれます。

search_mode には以下の5モードがあります。

モード 説明
fuzzy nucleo-matcher によるファジー検索(デフォルト)
exact 部分文字列による完全一致検索
migemo ローマ字入力で日本語にマッチ
fuzzy_migemo fuzzy と migemo の和集合(fuzzy 優先)
exact_migemo exact と migemo の和集合(exact 優先)

設定ファイルで固定するほか、Ctrl+Shift+m でその場でサイクル切り替えできます。ソート順(回数優先 / 最近優先)も Ctrl+Shift+o で切り替え可能です。切り替えた状態は /save コマンドで config.local.toml に永続化できます。

migemo 系モードでは、ローマ字で日本語のファイル名や候補を検索できます。たとえば hajime と入力すると 初めてのRustはじめに にマッチします。fuzzy_migemo は「ローマ字でも日本語でもどちらでも引っかかる」ので、混在した候補リストを扱う場合に特に便利です。

rustmigemojsmigemooguna 氏作)を使用。辞書(yet-another-migemo-dict、BSD-3-Clause)はアプリに同梱しているので別途インストール不要です。

起動履歴 & よく使う順 / 最近使った順ソート

起動したアプリを自動的に記録し、実行回数と最終使用日時の組み合わせでソートされます。設定の sort_order でどちらを優先するか切り替え可能です。

  • count_first: 実行回数を優先し、同じ回数なら新しい順に表示。
  • recent_first: 最終使用日時を優先し、同じ日時なら回数が多い順に表示。

Args モード(Tab キー)

Tab キーを押すと Args モードに入り、追加の引数を渡して起動できます。バージョンアップにより、「どのアプリを、どの引数で実行したか」 が個別に履歴として記憶されるようになりました。

text
1
2
edge   →  Tab  →  https://bing.com     →  Enter
chrome →  Tab  →  https://google.co.jp →  Enter

Edge で Bing を開く

Chrome で Google を開く

ブラウザごとに開く URL を使い分けるのが特に便利です。一度使った組み合わせは引数込みで履歴に残るので、次回からは edbi と入力するだけで「Edge で Bing を開く」が候補に出てきます。

以前使った引数の組み合わせが履歴として記憶されていて、次回はゴーストテキストとして表示されます。Ctrl+f で1単語、Ctrl+e で行全体を確定できます。History アイテムで Tab を押すと、その引数を引き継いで Args モードに入れます。

パス & URL を直接開く

  • ~/Documents/usr/bin のような絶対パスを入力 → エクスプローラーや Finder で開く
  • %APPDATA%$HOME, ${XDG_CONFIG_HOME} などの環境変数を含むパスを直接入力 → 展開して開く
  • shell:startup などの Windows 特殊フォルダを入力 → 直接開く
  • https://... を入力 → ブラウザで開く
  • Tab で補完候補がドロップダウン表示

プレビューパネル

Ctrl+Shift+p でプレビューパネルを表示できます。

  • Args モード: ファイルパス補完中に、選択しているファイルの中身を表示。
  • 検索結果: 実行ファイルやスクリプト、テキストファイルなどの内容を表示。

プレビューには Shiki による構文強調(シンタックスハイライト)が適用され、テーマに合わせた色で見やすく表示されます。Ctrl+j / Ctrl+k でパネル内のスクロールも可能です。

ウィンドウの移動

ウィンドウ上部の マーク(ドラッグハンドル)をマウスで掴んで、好きな位置にウィンドウを移動できます。移動した位置は /save position コマンドで config.local.toml に保存し、次回起動時にも維持することが可能です。

スラッシュコマンド

コマンド 動作
/exit アプリ終了
/config 設定ファイルを開く(Tab で config.local.toml など他のファイルを選択可)
/history 履歴ファイルを開く
/reload 設定を再読み込み(グローバルショートカット、アプリスキャン、各種設定を反映)
/update アップデート確認・実行
/version バージョン表示
/theme テーマを即時切り替え(Tab でプリセットを選択可)
/save <item> 現在の search_mode / sort_order / theme / monitor / position / size を config.local.toml に保存(Tab で選択可)
/reset <item> config.local.toml に保存した上記設定をリセット(Tab で選択可)
/help キーバインドと現在のステータスを確認できるヘルプパネルを表示

/save/config などのコマンドは、Tab キーを押すことで引数の候補(設定項目やファイル名)がドロップダウン表示されます。

その他の便利な操作

  • Shift + Enter: 履歴の候補を無視して、現在入力しているクエリを直接コマンドとして実行します。
  • Ctrl + w / Ctrl + u: カーソル前の 1 単語削除、または行頭までの削除。
  • Ctrl + d: 選択した履歴アイテム(特定の引数セットを含む)を削除。

アップデート検知

バックグラウンドで定期的に新バージョンをチェックします(デフォルト1時間ごと、設定変更可能)。新バージョンが見つかると、検索欄のプレースホルダーが Update available: vX.X.X — /update に変わって通知してくれます。

実際のアップデートは手動で、/update を実行すると起動します。ダウンロードの進捗がリアルタイムで表示され、完了後に自動再起動します。

Scoop や Homebrew でインストールした場合は、それぞれ scoop update shun / brew upgrade --cask shun を代わりに実行してくれます。

インストール

ワンライナー

Windows (PowerShell、管理者権限不要):

powershell
1
irm https://yukimemi.github.io/shun/install.ps1 | iex

macOS / Linux:

bash
1
curl -fsSL https://yukimemi.github.io/shun/install.sh | sh

パッケージマネージャー

WinGet (Windows):

powershell
1
winget install yukimemi.shun

Scoop (Windows):

powershell
1
2
scoop bucket add yukimemi https://github.com/yukimemi/scoop-bucket
scoop install yukimemi/shun

Homebrew (macOS):

bash
1
2
brew tap yukimemi/tap
brew install --cask yukimemi/tap/shun

設定

初回起動時に自動生成されます。

OS パス
Windows %APPDATA%\shun\config.toml
macOS ~/Library/Application Support/shun/config.toml
Linux ~/.config/shun/config.toml

設定できる項目は多岐にわたります。詳細は README を参照してください。ここでは代表的な例を紹介します。

toml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# 検索モードとソート順
search_mode = "fuzzy_migemo"  # "fuzzy" | "exact" | "migemo" | "fuzzy_migemo" | "exact_migemo"
sort_order  = "count_first"   # "count_first" | "recent_first"
history_max_items = 1000      # 保持する履歴の最大数

# ウィンドウ・表示設定
max_items    = 8              # 候補の最大表示数
hide_on_blur = true           # フォーカスが外れたら自動的に閉じる
monitor      = "cursor"       # 起動モニター ("cursor" | "primary" | インデックス番号)
font_size    = 14             # フォントサイズ
opacity      = 1.0            # ウィンドウの不透明度 (0.0 - 1.0)
icon_style   = "unicode"      # ステータスバッジのスタイル ("unicode" | "svg")

# プレビュー・その他
preview_args   = true         # 引数モードでのプレビュー (デフォルト: true)
preview_search = true         # 検索結果のプレビュー (デフォルト: true)
auto_start     = true         # ログイン時に自動起動 (デフォルト: true)

[keybindings]
launch      = "Ctrl+Space"    # グローバルホットキー
next        = "Ctrl+n"
prev        = "Ctrl+p"
confirm     = "Enter"
arg_mode    = "Tab"
accept_line = "Ctrl+e"        # ゴーストテキストを全確定
accept_word = "Ctrl+f"        # ゴーストテキストを 1 単語確定
delete_word = "Ctrl+w"        # カーソル前の 1 単語削除
delete_line = "Ctrl+u"        # 行頭まで削除
run_query   = "Shift+Enter"   # 履歴を無視して直接実行
delete_item       = "Ctrl+d"        # 選択した履歴アイテムを削除
cycle_search_mode = "Ctrl+Shift+m"  # 検索モードをサイクル切り替え
cycle_sort_order  = "Ctrl+Shift+o"  # ソート順をトグル
toggle_preview    = "Ctrl+Shift+p"  # プレビューパネルの表示/非表示
preview_scroll_down = "Ctrl+j"      # プレビューパネルをスクロール
preview_scroll_up   = "Ctrl+k"      # プレビューパネルをスクロール
close             = "Escape"

# 自動で見つかったアイテム(scan_dirs やシステムアプリ)の挙動を上書き
[[overrides]]
name       = "scoop"          # アプリ名(ファイル名)でマッチ
completion = "list"           # スキャンで見つかったコマンドに補完を追加できる
completion_list = ["install", "update", "search", "list", "status", "info"]

[[overrides]]
ext        = "xlsx"           # 拡張子でマッチ
path       = "C:/Program Files/Microsoft Office/root/Office16/EXCEL.EXE"
args       = ["{{ file_path }}"] # 本来のパス(Excel ファイル自体のパス)を引数で渡す

# ファイルパス補完付きでエディタを開く
[[apps]]
name       = "Neovide"
path       = "neovide"
completion = "path"

# docker exec の補完をコマンド出力から生成
[[apps]]
name               = "docker exec"
path               = "docker"
args               = ["exec", "-it"]
completion         = "command"
completion_command = "docker ps --format '{{.Names}}'"

# git checkout のブランチ補完
[[apps]]
name               = "git checkout"
path               = "git"
args               = ["checkout"]
completion         = "command"
completion_command = "git branch --format='%(refname:short)'"
workdir            = "~/src/myproject"

# ディレクトリをまとめてスキャン
[[scan_dirs]]
path       = "~/.local/bin"
recursive  = false
extensions = ["sh", "py", "ps1"]

テンプレートプレースホルダー

pathargs には Tera テンプレート構文が使えます。Tab で Args モードに入って入力した内容が {{ args }}(文字列全体)や {{ args_list }}(スペース区切りの配列)に展開されます。

利用可能な変数・関数:

  • {{ args }}: 入力内容全体(文字列)
  • {{ args_list.0 }}: スペース区切りの第1引数(0番目)
  • {{ env.VAR_NAME }}: 環境変数
  • {{ vars.my_var }}: [vars] セクションで定義した変数
  • {{ file_path }}: overrides で差し替えられた元のファイルパス(フルパス)
  • {{ now() | date(format="%Y%m%d") }}: 現在の日時
  • {{ args | urlencode }}: URL エンコードフィルタ

Web 検索をランチャーから

| urlencode フィルタを使うと日本語もそのまま検索できます。

toml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Google 検索
[[apps]]
name = "Google"
path = "https://www.google.com/search?q={{ args | urlencode }}"

# 第1引数、第2引数を個別に使いたい場合
[[apps]]
name = "Multi Search"
path = "https://example.com/search?q1={{ args_list.0 }}&q2={{ args_list.1 }}"

[[apps]]
name = "Perplexity"
path = "https://www.perplexity.ai/search?q={{ args | urlencode }}"

[[apps]]
name = "GitHub Search"
path = "https://github.com/search?q={{ args | urlencode }}"

使い方: perp → Tab → rust の所有権とは → Enter で Perplexity が開きます。一度使った検索クエリは履歴に残るので、次回は候補として出てきます。

環境変数

{{ env.VAR_NAME }} または Tera 標準の {{ get_env(name="VAR") }} で環境変数を参照できます。

toml
1
2
3
4
5
6
7
8
9
10
11
# プロジェクトを引数で指定してエディタで開く(src/ 以下の相対パスで補完される)
[[apps]]
name = "Open Project"
path = "neovide"
args = ["{{ env.USERPROFILE }}/src/{{ args }}"]
completion = "path"

# default 指定(Tera 標準関数)
[[apps]]
name = "Work Dir"
path = '{{ get_env(name="WORK_DIR", default="~/work") }}/{{ args }}'

日付プレフィックス付きメモ

now() 関数と date フィルターで今日の日付を埋め込めます(Tera 標準機能)。

toml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# MemoNew: Tab → タイトル入力 → Enter で "20260321-タイトル.md" を作成して開く
[[apps]]
name       = "MemoNew"
path       = "nvim"
args       = ['~/memo/{{ now() | date(format="%Y%m%d") }}-{{ args }}.md']
completion = "none"

# MemoList: Tab → ~/memo/ 以下のファイルを migemo パス補完で選択 → Enter
# "hajime" で "初めて.md" がヒット
[[apps]]
name                   = "MemoList"
path                   = "nvim"
args                   = ["~/memo/{{ args }}"]
completion             = "path"
completion_search_mode = "migemo"

date(format="%Y-%m-%d") のようにフォーマットを変えるのも自由です。設定だけで完結する、ちょっとしたメモ管理フローが作れます。

履歴ファイル

履歴は以下のパスにシンプルな JSON として保存されています。バージョン 2 以降、構造が配列形式になり、各エントリが keyargs(配列)を個別に持つようになりました。これにより、以前の形式(文字列結合)では失われがちだった「スペースを含む引数」なども正確(lossless)に保持・復元できるようになっています。

OS パス
Windows %APPDATA%\shun\history.json
macOS ~/Library/Application Support/shun/history.json
Linux ~/.config/shun/history.json
json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "version": 2,
  "entries": [
    {
      "key": "msedge.exe",
      "args": ["https://bing.com"],
      "count": 12,
      "last_used": 1742478231
    },
    {
      "key": "Google",
      "args": ["shun", "launcher"],
      "count": 5,
      "last_used": 1775302627
    }
  ]
}

普通の JSON なので、テキストエディタで直接編集できます。/history コマンドで即座に開けます。

不要な履歴アイテムを1件ずつ消したいだけなら、ランチャー上で候補を選んで Ctrl+d を押すだけで削除できます。

マシン固有の設定は config.local.toml に

config.toml と同じディレクトリに config.local.toml を置くと、その内容がマージされます。config.toml を dotfiles などで複数マシン共通に管理しつつ、マシンごとに異なるスキャン対象パスや追加アプリは config.local.toml に書く、という運用が便利です。

toml
1
2
3
4
5
# config.local.toml(このマシンだけのスキャン追加)
[[scan_dirs]]
path = "C:/work/projects"
recursive = true
extensions = ["exe", "bat", "ps1"]

ユーザー定義変数 [vars]

[vars] セクションに任意のキーを定義すると、pathargs の Tera テンプレートから {{ vars.キー名 }} で参照できます。config.tomlconfig.local.toml はマージしてから展開されるので、config.local.toml 側の [vars] に書いた値を config.toml[[apps]] で使うことができます。マシンごとに異なるパスなどを config.local.toml にだけ書いておく運用が便利です。

toml
1
2
3
4
5
6
7
8
9
10
# config.local.toml
[vars]
work_dir = "C:/work/myproject"
editor   = "neovide"

# config.toml(config.local.toml の vars を参照できる)
[[apps]]
name = "Open Work"
path = "{{ vars.editor }}"
args = ["{{ vars.work_dir }}"]

技術的なポイント

Rust + Tauri v2

ネイティブアプリとして軽量・高速。バックエンドは Rust で書かれており、グローバルショートカットの登録、アプリスキャン、検索、履歴管理などをすべて Rust で処理しています。

nucleo-matcher

Helix エディタが採用しているファジーマッチャーで、精度と速度のバランスが良いです。

rustmigemo / jsmigemo

oguna 氏による Pure Rust / Pure JS の migemo 実装。辞書(yet-another-migemo-dict、Mozc + UniDic ベースの BSD-3-Clause ライセンス)をバイナリに同梱し、インストール不要で日本語ローマ字検索を実現しています。

Svelte 5 (Runes)

フロントエンドは Svelte 5 の Runes ($state, $derived, $effect) で記述。シンプルな UI ながら補完ドロップダウンやゴーストテキストなど複数の状態を管理しています。

おわりに

このランチャーは Claude Code と一緒に開発しました。自分でアーキテクチャや機能の方向性を決めつつ、Rust の細かい実装や CI/CD の設定などは Claude Code に大きく助けてもらっています。「こういう動きにしたい」という意図を伝えるだけでコードに落としてくれるので、アイデアを素早く形にできました。

Tauri v2 を使っているので Windows / macOS / Linux すべてでビルド・リリースしていますが、動作確認は Windows のみで行っています。macOS・Linux で試してみた方がいれば、フィードバックいただけると嬉しいです!

ぜひ試してみてください!