Windows Terminalは、Microsoftがオープンソースとして開発を進めるコンソールプログラム。従来Windowsには、Conhost.exeと呼ばれる組み込みのコンソールプログラムがあった。これは、標準ではコマンドプロンプト ウィンドウで使われている。Windows 11では、いよいよ標準のConhost.exeをWindows Terminalで置き換えることが可能になる。この記事では、こうした将来を見込み、Windows Terminalのキーボード割り当てとそのカスタマイズ方法を解説する。

Windows Terminalとは?

Windows Terminalは、Windows 11からは、標準的なコンソールとしても利用できるようになり、今後、コンソールプログラムの主流になることが予想される。いまのところWindowsに標準で搭載されているわけではないが、Microsoftストアから簡単にインストールが可能だ。このWindows Terminalには、一般ユーザーの利用を想定した「安定版」と、開発者や導入評価のための「プレビュー版」がある。プレビュー版もMicrosoftストアからのインストールが可能だが、Insider登録が必要。なお、安定版、プレビュー版とも、Githubからファイルを直接ダウンロードしてのインストールも可能である。

(つい先日、プレビュー版のVer.1.12.2931.0が公開されたりもしたが)原稿執筆時点では、Windows Terminalプレビュー版がVer.1.11.2421.0(以下このバージョンをプレビュー版と表記する)、Windows Terminal安定版がVer.1.10.2383.0(同安定版と表記)である。

Windows Terminalや多くのソフトウェアのバージョン番号には、複数のルールがあるが、多くの場合、ピリオドで区切った数値をそれぞれ整数として扱い、ゼロを先頭に付けない。つまり「Ver.1.11」は、メジャーバージョンが1、マイナーバージョンが11であり、小数の1.11ではないことに注意されたい。こうしたバージョン表記では、1.10のほうが1.9よりも後のバージョンになる。3つ目の数字は、Windows Terminalの場合、上位2つの数字同士が同じバージョンのときだけ大小関係が比較できることに注意されたい。

プレビュー版と安定版は、ほぼ同時に公開され、プレビュー版のほうがマイナーバージョンで一回分バージョンが先行している。これでフィードバックを集め、バグなどを修正したものが安定版だが、機能によっては、プレビュー版にあったものが安定版では削除されることもある。実際、安定版には、1つ前のプレビュー版(Ver.1.10.1933.0)では利用できたGUI設定のキー編集機能が搭載されていない。

標準のキー割り当て

表01は、プレビュー版、安定版の標準のキー割り当てである。Windows Terminalは、内部でcmd.exe、PowerShell、bashといった「シェル」(コマンドラインインタプタ)を動かすため、それらが利用するキーボードショートカットを避けて割り当てが行われている。原則、Ctrlキーと英数字の同時押しは割り当てを避けている。多くのシェルでは、「Alt」キーを使うことがないため、Altキー単独、Alt+Shift、Ctrl+Altキーと英数字、あるいは、PCの機能キー(Home、End、PageUp、PageDown、Insert)などを使うキーボードショートカットを使う。後述するように、このキー割り当てはすべてユーザーが変更が可能で、シェルやその上で動くコンソールアプリケーションなどとの衝突がある場合には、自由に変更が可能だ。キー割り当てがわかりやすいように、キーで分類ソートしたものを表02に示す。

  • ■表01

    ■表01

  • ■表02

    ■表02

Windows Terminalにはオンラインヘルプ機能はないが、実行中にキー割り当てを調べるには、GUI設定やコマンドパレットを使うことができる。GUI設定は、メニューアイコン(+アイコン)から「設定」を選ぶことで表示できる。左側から「操作」タブを選ぶと、キー割り当てが表示される。また、コマンドパレット(Ctrl+Shft+P)で機能に関するキーワードを入れると、そのキーワードを含む「Action」(Windows Terminalの機能)と、キー割り当て(もしあれば)が表示される。ただし、現在の安定版では、GUI設定からは、すべてのActionをキーに割り当てることができない(プレビュー版は可能)。ただし、安定版、プレビュー版ともに、すべての機能を割り当てるためには、Settings.jsonというファイルを編集して行う。こうしたJSONファイル編集による設定は、Windows Terminalが当初から持っていた機能で、GUI設定が装備されたのは、つい最近のことだ。GUI設定は簡単なので、特に説明は不要と思われ、ここでは、JSONファイルによるキー割り当て方法だけを解説する。

キーボードの割り当て方法

Windows Terminalのキー割り当ては、Setting.jsonと呼ばれるJSON形式のファイルを編集することで行う。JSON形式とは、JavaScriptからオブジェクトをテキスト形式で保存、読み込みを行うために作られた形式だが、インターネット関連のサービスやローカルアプリケーションでも広く使われる形式だ。構造としては簡単だが、本来、人間が読み書きすることを想定していないため、ソフトウェアによっては、エディタなどで扱いにくい形式(たとえば、改行なしで数メガバイトなど)を出力することがある。Windows Terminalでは、巨大なファイルは出力しないが、できる限り編集などを容易にするため、「JSON Schema」、「jsonc」といった仕様に対応している。JSON Schemaに対応したエディタ(JSONエディタ)を利用することで、Settings.jsonの編集中に補完機能などを利用することができる。こうしたJSONエディタには、MicrosoftのVisual Studio Codeなどがある。

jsoncは、Microsoftが自社製品向けに定義したJSONにコメントを付けるための公開仕様。このjsoncには対応していないJSONエディタやアプリケーションがあるので、settings.jsonをプログラムで処理、編集する場合には注意されたい。たとえば、Microsoftの製品でも、Windows PowerShell(Windowsに標準搭載されているPowerShell)は、JSONの処理機能を持つがjsoncには対応していない。これに対して、オープンソース版でWindows PowerShellの後継とされるPowerShellは、jsoncに対応している。

Windows TerminalでGUI設定を開き、設定ページ左下にある「JSONファイルを開く」を使うことで、Settings.jsonファイルが標準のJSONエディタで開く。Windows側でなにも設定されていなければ、アプリケーションを尋ねる画面が表示される。何もプログラムがインストールされていないなら、Windows標準のメモ帳を使うことが可能だ。また、Visual Studio CodeなどJSONファイル(拡張子が.json)と関連付けされているプログラムがあれば、それが開くようになる。前述のようにJSON Schemaに対応したエディタを使うほうが便利なので、キーボードのカスタマイズを行うなら、JSONエディタとなるテキストエディタを入れておくべきだろう。

JSONでは、基本的な値(データ型)としては文字列、または数値、真偽値(true、falseのどちらか)、ヌル値(null)のみを扱い、構造としてはプロパティとオブジェクト、配列がある。プロパティは、名前と値(オブジェクトや配列のこともある)をコロンでつなげたもの。名前は必ず文字列になる。オブジェクトは波括弧で括られた部分。配列は、同種の値をカンマで区切って角括弧でくくったもの。

もともとプログラムから読み込むことを想定しているため、改行やダブルクオートの外のスペース、タブなどは無視される。

Settings.jsonは、(図01)のような構造をしており、キー割り当てを変更するには、Actionsプロパティの配列中にあるキー割り当てオブジェクトを編集する。Actionsプロパティは「"actions": [……」と「……]」の間に記述される。JSONでは、“[”と“]”で囲まれた部分は、「配列」と呼ばれ要素をカンマで区切る。ただし、最後の要素の後ろ、“]”の直前にはカンマをつけない。また、JSONでは、キーワードの途中でなければ、改行文字やタブ文字、スペースは自由に入れてかまわない。

  • Windows Terminalのキーボードカスタマイズ導入編

    図01: settings.jsonは、波カッコ「{ }」と角カッコ「[ ]」で構造を示す。このカッコは1つのjsonファイル中で必ず対になって使われる。また、この2つのカッコの中の要素はカンマで区切るが最後の要素(閉じる波カッコや角カッコの直前)はカンマが不要なので、編集による要素の削除、追加の際には注意が必要だ。キーボードを定義するにはjson中の「"action":」で始まる部分を編集する

基本的なキー割り当ては、


{"command":【コマンド名またはアクション】,"keys":"【キー割り当て文字列】"}

となっている。これを編集、追加することでキー割り当てを変更、追加できる。なお、Windows Terminalのデフォルトのキー割り当ては、defaults.jsonというファイルで見ることができる。これは、「Alt+Ctrl+カンマ」キーまたは、Altキーを押しながらメニューの「設定」をクリックすることで開くことができる。注意するのは、このdefaults.jsonは、Windows Terminalがファイルを作成するものの、絶対に読み込まないため、編集しても設定は変わらない点に注意する。変更は、すべてSettings.jsonで行う。なお前記のキー割り当ての表は、このdefualt.jsonから作成されている。

プロパティ名「command」につづく【コマンド名またはアクション】には、単純なコマンド名と引数を持つアクションがある。単純なコマンド名の場合には、


 { "command": "newTab", "keys": "ctrl+shift+t" }

のような表記になる。ここでnewTabが単純なコマンド名である。この指定は、新しいタブを開くnewTabコマンドにCtrl+Shft+Tを割り当てるものだ(割り当て可能なキーについては後述)。これに対して引数を使うアクションの場合には、


 { "command": { "action": "switchToTab", "index": 0 }, "keys": "ctrl+alt+1" }

のような構造になる。コマンドとしてタブを切り替えるswitchToTabとその引数である"index"に0を指定して、「最初のタブへの切り替え」という動作を「Ctrl+Alt+1」に割り当てている。なお、引数はコマンド名により決まる。また、一部のコマンドは、引数なしで利用することもできる。このときには引数にコマンドにより定義されたデフォルト値が使われる。引数がある場合には、"command"キーワードに続く波括弧の中に"action"やパラメーターなどの指定があることに注意願いたい。なお、キー割り当て部分("keys")の指定は、どちらの場合も同じ形式である。

commandプロパティや、その中のactionプロパティで指定可能なWindows Terminalの機能を「アクション」と呼ぶ。アクションを指定したcommandプロパティを「コマンド」という。コマンドは、キー割り当てして実行する以外に、コマンドパレットで直接指定して実行することができる。前述の「Actions」セクションには、キー割り当て以外にコマンドパレットで実行するための「コマンド」定義も含まれている。

利用できるアクションには、表03のようなものがある。これは、Windows Terminalのソースコードから作成したものだ。この表で「引数」欄が「丸印」になっているものは、引数の指定ができる。引数には、必須のもの(省略できない)とオプション(省略可能)がある。アクションと引数の定義を表04示す。

  • ■表03

    ■表03

  • ■表04

    ■表04

割り当てることが可能なキー

割り当てるキーボードは、keysプロパティでテキストを使って指定する。キーは、大きく「モデファイアキー」(Modifier keys。修飾キー)とそうでないキー(修飾キーに対してファイナルキーと呼ばれることがある)を「+」文字でつないで指定する。Windows Terminalでは、修飾キーに表05のものが利用できる。簡単にいうと修飾キーを押しながらファイナルキーを押すことで指定したキーコードがWindows Terminalにおくられ、これを処理してWindows Terminalはコマンドを実行する。

  • ■表05

    ■表05

ファイナルキーは、修飾キー以外のキーを指定できる。表06は、その表記方法を示したものだ。ただし、キーボードレイアウトによって、利用可能な組み合わせに違いがある。また、Windows Terminalプレビュー版からは、ファイナルキーにキーボードスキャンコードや仮想キーコードを指定できるようになった。ファイナルキーを表す文字の代わりに「sc(【スキャンコード】)」、「vk(【仮想キーコード】)」を指定する。スキャンコードは、キーボードハードウェアが送出するキーに対応したコードであり、これをWindowsが汎用的に変換したのが仮想キーコードである。スキャンコードは、キーボードレイアウトに関係なく、キー1つ1つに割り当てられたコードだ。Windows内部では、これを言語やキーボードレイアウトに応じて仮想キーコードに変換している。文字Lのとなりのキーには、0x27というスキャンコードが割り当てられている。たとえば米国英語キーボードレイアウトでは、このキーは、シフトキーを押すと「:」が出るためキートップには「; :」などと表記されている。しかし、JIS配列準拠キーボードでは、シフトキーを押すと「+」が出るため、キートップは「; +」となる。また、EU圏向けのキーボードでは、このキーにはダイアクリティカルマークのついた文字が配置されることがある。たとえばドイツ語キーボードレイアウトでは、「O」にウムラウト記号がついた文字のキーになっている。

  • ■表06

    ■表06

この0x27というスキャンコードは、WindowsでVK_OEM_1(16進数で0xBA、10進数では186という数値)という仮想キーコードに変換される。OEM_1などというへんな名前がついているのは、このキーがレイアウトや言語によりさまざまな変わる可能性があるキーだからだ。しかし、標準的なキーボードでは、このキーが「L」キーの隣という位置は変わらない。その後、アプリケーションが文字を入力したいのであれば、VK_OEM_1は、WindowsのAPIで「;」の文字コード(0x3BというASCIIコード)に変換される(USキーボード、JISキーボードの場合)。

スキャンコードによる指定と仮想キーコードによる指定が可能なのは、スキャンコードでは、レイアウトにかかわらず、特定のキートップ(物理キー)を指定できるのに対して、仮想キーコードは、キーボード上にないキーやブラウザキーなどを指定できるという違いがあるからだ。ブラウザキーは、キーボードだけでなく、マウスやゲーム用キーコントローラーなどに装備されているボタンでも発生が可能だ。

なお、sc(x)、vk(x)では、xを10進数で指定する。スキャンコード(抜粋)を表07にしめす。これは、後述のWord文書の16ページにある「Scan Code Table」で「scan 1 make」と表記されているコードである。仮想キーコードは、後述するMicrosoftのサイトにページがある。なお、sc(x)、vk(x)は、ファイナルキーでのみ指定可能で修飾キーには利用できない。

  • ■表07

    ■表07

settings.jsonでWindows Terminalにキーボードショートカットを割り当ててしまうと、内部で動作しているシェルには、そのキーの組み合わせは、シェル側には、送られることがないという点には注意が必要だ(図02)。同様にWindows Terminal側でキーボードショートカットを割り当てたとしても、WindowsやIME動作中のキーボードショートカットやホットキー(アプリケーションなどが常に取得するキーの組み合わせ。APIで登録を行う)は、Windows Terminalでは取得できないという点にも注意が必要だ。また、プレビュー版、安定版ともに、一部のキーは、ホットキーとして扱われ、Windows Terminalが動作していないときでも有効であり、ホットキーによりWindows Terminalを起動することもできる点も考慮する必要がある。

  • 図02: Windowsでは、キーはWindowsで処理されたのち、Windows Terminalに送られ、シェル(コマンドラインインタプリタ)を介して、Windows Terminal内のアプリケーションまで伝わる。しかし、WindowsのホットキーやWindows Terminalに対して割り当てたキーは、シェルには送られないので注意が必要だ。settings.jsonでWindowsのホットキーを定義しても動作しないし、シェルやアプリケーションで使うキーをWindows Terminalに割り当ててしまうと動作ができなくなることがある

ドキュメントまとめ

キー割り当てを行うには、Actionsに記述するコマンドの機能を知る必要がある。これに関しては、以下のようなドキュメントが用意されている。

・Windows Terminal Actions(英語)
https://docs.microsoft.com/ja-jp/windows/terminal/customize-settings/actions

また、Settings.jsonの設定については、以下のドキュメントがある。

・Windows Terminal Startup Settings
https://docs.microsoft.com/ja-jp/windows/terminal/customize-settings/startup

なお、スキャンコード、仮想キーコードは、10進数で表記する。これについては、以下にドキュメントがある。

・Keyboard Scan Code Specification(Word文書ファイルのダウンロード)
https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc

・Virtual-Key コード
https://docs.microsoft.com/ja-jp/windows/win32/inputdev/virtual-key-codes

ドキュメントに記載されていないAction

前記のドキュメントには、記載されていないアクションがある。表03で赤字で示したアクションが、ドキュメントに記載されていないものだ。ここでは簡単にこれらについて解説する。

"commandPalette"アクションは、コマンドパレットを起動するアクションだ。このアクションを使うことでSetting.jsonで、コマンドパレット開くキーボードショートカットを変更できるようになる(デフォルトはCtrl+Shift+P)。

"wt"アクションは、新規にWindows Terminalを起動するものだ。このアクションは、引数としてWindows Terminalのアプリ実行エイリアス「wt.exe」の起動オプションと同じ文字列を受け付ける。起動オプションを表08に示す。

  • ■表08

    ■表08

focusPaneは、現在開いているタブにあるindexパラメーターで指定されたペインに制御を移す。ペインには作成順に番号が付く。似たようなアクションにmoveFocusはあるが、これは、現在選択中のペインを基準にして右側(right)や左側(left)などの方向、順番(nextInOrder、previousInOrder)などを指定してペインを選択するもの。

movePaneは、ペインを他のタブへと移動させるもので、パラメーターには、タブ番号を指定する。存在しないタブ番号を指定すると、新規にタブが作られるため、このコマンドを使ってペインをタブに変換することもできる。また、どのタブもペインを1つ持っているため、すでに存在しているタブ番号を使って、ペインのないタブでこのアクションを実行すると、タブをペインに変換することが可能だ。ただし、キーボードショートカットでこのアクションを使う場合、移動先のタブ番号が固定されてしまうため、行き先のタブ番号の数だけキーボードショートカットを指定しなければならない。どちらかというとコマンドパレットから実行したほうが便利なコマンドだ。

openTabColorPickerは、タブの色選択メニューを開くもの。やはり似たようなアクションとしてsetTabColorアクションがあるが、キーボードショートカットで使うと、色番号が固定されてしまうが、openTabColorPickerは、色をユーザーが選択できるため、どちらかというとキーボードショートカット向きのアクションだ。

toggleSpitOrientationは、「水平」、「垂直」のペインの分割方法をあとから切り替えるもの。ペイン作成のsplitPaneアクションでは、パラメーターとして「水平」、「垂直」、「自動」の3つが指定できる。自動は、現在のペインの縦横比から水平か垂直かを自動的に決めるもので、すべてのペインは、水平か垂直のどちらかで分割されていることになる。このtoggleSpitOrientationは、これをあとから切り替えるもの。ただし、このコマンドは、分割された2つのペインの位置関係を変えることになり結果を予測しづらい点に注意が必要だ。

「breakIntoDebugger」と「minimizeToTray」は特殊なアクションで、通常は利用しない。「breakIntoDebugger」は、プレビュー版Windows Terminalでのみ有効で、WindowsにインストールされたDebuggerを起動するもの。一般的にはDebuggerはVisual Studioなどの開発環境をインストールしないとインストールされないものなので、普通の環境で使うことはできない。「minimizeToTray」は、ソースコード上はアクションとして定義されていて、settings.jsonに記述することも可能だが、何も実行されないアクションだ。

Windows Terminalは、Windows 11では、従来のコンソールウィンドウ(conhost.exe)に代わるものとして利用することも可能になった。従来のコンソールウィンドウに比べて、タブ表示やペイン分割などさまざまな機能を持つ。その使い勝手を決めるのは、さまざまなカスタマイズだが、そのうちキーボード割り当てに関しては、一番効果が高く、使い勝手を決めるのはキーボードショートカットだといえる。簡単な割り当ては、GUI設定ページでも可能だが、完全に能力を引き出すためには、settings.jsonによるキー割り当てを行う必要がある。