
前回は文字を入力する方法を解説しましたが、それだけでは「保存」や「終了」などのコマンド操作が不便です。 今回は、Ctrl + Q で終了、Ctrl + S で保存といった、複数のキーを組み合わせる「コンボ入力(修飾キー)」の実装方法を紹介します。
前回 入力受付の実装:【Ratatui】Rustで作るTUIツール:ユーザーからの文字入力を受け取る(Input Formの実装)
1. 主要部分の実装例:matchガードを活用する
Rustの match 文には、条件を追加できる「ガード(if文をそのまま使える)」という機能があります。これを使って、Ctrlキーが押されているかどうかを判定します。
// イベント処理セクションの書き換え例
if let Event::Key(key) = event::read()? {
if key.kind == KeyEventKind::Press {
match key.code {
// Ctrl + 'q' でプログラムを終了する
KeyCode::Char('q') if key.modifiers.contains(event::KeyModifiers::CONTROL) => {
break;
}
// 通常の文字入力(Ctrlが押されていないときだけ反応させる)
KeyCode::Char(c) if !key.modifiers.contains(event::KeyModifiers::CONTROL) => {
input.push(c);
}
// Backspaceなどは前回同様なので略
KeyCode::Backspace => { input.pop(); }
_ => {}
}
}
}2. 実装結果
このコードを適用すると、以下のような挙動になります。
qと打てば、画面に「q」と表示される。Ctrl + Qを押すと、即座にプログラムが終了する。
これによって、「入力モード」と「コマンドモード」を切り替えなくても、自然なショートカット操作が可能になります。

qは普通に打ち込むことができる
3. ちょこっと解説:modifiers(修飾キー)の仕組み
今回のコードのポイントを3つに絞って解説します。
① key.modifiers とは?
event::read() で受け取った KeyEvent 構造体の中には、code(どのキーか)の他に、modifiers(どの修飾キーが一緒に押されているか)という情報が含まれています。
CONTROL: CtrlキーSHIFT: ShiftキーALT: Altキー
② match ガード(if ...)
match の枝に if を添えることで、「キーが ‘q’ である」かつ「Ctrlが含まれている」という複合的な条件を一行でスマートに記述できます。Rustらしい、安全で読みやすい書き方ですね。
③ なぜ「通常の入力」にもガードが必要なのか?
ここが重要なのですが、machはif elseifのような分岐処理ではないため、もし通常の文字入力側に if !key.modifiers.contains(...) を入れないと、Ctrl + Q を押したときに「終了処理」が走ると同時に、文字としての ‘q’ も入力欄に追加されてしまいます。
4. machgurdの書き方の例
今回実装したコンボは ctrlとのコンボですが、他のキーともコンボ入力の設定が可能です。修飾キー(Modifiers)を変えることで、さまざまな組み合わせに対応できます。
| 実装したいコンボ | match ガードの書き方 |
| Ctrl + A | KeyCode::Char('a') if key.modifiers.contains(event::KeyModifiers::CONTROL) |
| Alt + Enter | KeyCode::Enter if key.modifiers.contains(event::KeyModifiers::ALT) |
| Shift + Tab | KeyCode::BackTab (※Tab + Shiftは専用のCodeが割り当てられることが多いです(環境に依る)) |
Tip: >
KeyCode::Char('A')のように大文字で書く必要はありません。基本は小文字の'a'を指定し、modifiersでCONTROLが押されているかを判定するのが一般的です。
2. 複数の修飾キーを組み合わせる(Ctrl + Altなど)
「Ctrl と Alt を両方押しているとき」という複雑な判定も、ビット演算のようにチェックできます。
// Ctrl + Alt + S で「特別保存」のような処理
KeyCode::Char('s') if key.modifiers.contains(event::KeyModifiers::CONTROL | event::KeyModifiers::ALT) => {
// 処理を書く
}3. 特殊キーと修飾キーの組み合わせ
文字キー以外(矢印キーなど)と修飾キーを組み合わせると、一気に「本格的なソフト」っぽくなります。
match key.code {
// Ctrl + 矢印右 で単語単位の移動
KeyCode::Right if key.modifiers.contains(event::KeyModifiers::CONTROL) => {
// カーソルを次の単語へ飛ばす処理など
}
// Shift + 矢印上 で範囲選択
KeyCode::Up if key.modifiers.contains(event::KeyModifiers::SHIFT) => {
// 選択範囲を広げる処理など
}
_ => {}
}最後に
コンボ入力ができるようになると、Ctrl + C の強制終了を自前でハンドルしたり、Enter キーで入力を確定させたりと、作れるツールの幅が爆発的に広がります。
次回は、画面を分割して「入力欄」と「ログ表示欄」を作る、Layoutの実践編に挑戦しましょう!
分割レイアウトを作ってみる: 【Ratatui】画面を分割して「ツール」らしくする(Layout編)
ここまで読んでいただきありがとうございます。
では、次の記事で。 lumenHero