ChromeOS上のchromeでemacsキーバインドを実現するextensionかつIMEをつくりました。興味ある方いたら使ってみてください。使い方は結構ややこしいです。
私はDevチャンネルで使っているのでそれ以外の環境で使ってみてくれる人いたらうれしいです。
できること
ChromeOS上のChromeのテキスト入力可能なところでのEmacs Likeなキー操作
サポートしているキーバインド
- Ctrl+P (Up)
- Ctrl+N (Down)
- Ctrl+B (Left)
- Ctrl+F (Right)
- Ctrl+A (Home)
- Ctrl+E (End)
- Ctrl+D (Delete)
- Ctrl+H (Backspace)
- Ctrl+M (Enter)
- Ctrl+K (Kill line to end)
- Ctrl+W (Cut)
- Ctrl+Y (Paste)
Extensionのインストール
使い方
こちらを熟読ください。
主に以下のような手順が必要です。
(画像はdevチャンネルで作ったのでstableとは違います。)
- Extensionのインストール
- 手動でのshortcutの設定 (chrome://extensions/shortcuts)
- IMEの有効化
- IMEの選択
ここまでやって、Google Docsやgmailなどで試して見てください。
作るまでの顛末
Chromeとemacsキーバインドはけっこう相性が悪くて、ChromeのGoogle Docs上でemacs keybindを使えるのはMacOSくらい。
MacBookからPixelbookに乗り換えようと意気込んていたが、Emacsキーバインドが快適に使えるMacBookと比べると非常に使いづらい。
調べてみるといくつかツールがあるけど、Ctrl+PやCtrl+Nなど重要なバインドがChromeネイティブのショートカットとして拾われてしまいうまく動かない。
こういう記事も見つけたけど、私の環境ではうまく動かず。
私の目的としてはGoogle Docsが快適に操作できることが最優先。
Crostiniで動くLinuxアプリは大体Emacsキーバインド使えるので、Chromeさえなんとかなればよかった。
上記記事で紹介されている
をいじっているうちに、うまく行く方法を発見してゼロから作ることになった。chrome extensionもはじめて作った。
あと夏休みで時間があった。
実現方法
ChromeOSとChromeの制限をいかにかいくぐるか、という勝負。
chrome.commands
を使ってショートカットの上書き
Emacsキーバインドで重要なCtrl+P, Ctrl+N, Ctrl+FなどはChromeがショートカットを使っているため、普通のツールでは上書きできない。
私が発見したのはchrome.commands
というextensionのAPIを使って、それにショートカットを設定するとChromeのショートカットを上書きできることだった。
ただ、ひとつのextensionは4つまでしかデフォルトのショートカットを設定できない。この制限はchromeのソースコードにベタがきされており変更不可能。
また、先述のChromeが使っている、Ctrl+P, N, Fなどはデフォルトでは登録できない。そこで手動で設定してもらうことにした。
manifest.json
に以下のような感じで書いておくと、
{
"commands": {
"00-up": {
"description": "Go Up (Ctrl+P)"
},
"01-down": {
"description": "Go Down (Ctrl+N)"
}
}
以下のような感じでjsで処理できる。
chrome.commands.onCommand.addListener(function (c) {
switch (c) {
case "00-up":
sendEvent('ArrowUp');
break;
case "01-down":
sendEvent('ArrowDown');
break;
....
}
コマンド名に数字がついているのはショートカット設定ページで名前の順で勝手にソートされるので、任意の順位するため。
chrome.input.ime
による入力処理
よく調べていないが、Chromeでキー入力をするにはIMEのAPIを使うしかないようだ。なのでIMEとして作ることになった。IMEを作るというとすごく大変そうだが、実際にはコードを1行も書かなくてもIMEにすることができる。IMEにするとテキストボックスなど文字入力が可能な状態でキーコードを送ることができる。
コードは以下のような感じ。
chrome.input.ime.sendKeyEvents({ "contextID": contextId, "keyData": [keyData] });
私が作ったextensionではこのchrome.input.ime.sendKeyEvents
を使って仮想的にキーを入力することで各種ショートカットを実現している。
例えばCtrl+K
はShift + End
して、Ctrl+X
(切り取り)することで実現している。これをショートカットからのchrome.commands
という普通IMEで使わないようなところから呼び出すことでemacs keybindを実現している。
manifest.jsonとmain.jsで合わせても200行もなく実現出来た。
出来ないこと
- 今のところChrome上ででしか動かない。ChromeOS搭載の謎のテキストエディタなどでは動かない。
chrome.commands
にはglobalなショートカットのオプションがあるがChromeOSでは動かない。 -
Ctrl+Space
など単純なキー入力で実現出来ないものはサポートしていない。がんばればできるかもだけど、Ctrl+Space
は特にそもそもIME切り替えなので難しいだろう。 - また、潰してしまったCtrl+Fなどのショートカットが使えない。必死で潰したのにないと今度は困る。これはなんとかしたいところだがやり方がわからない。
- 日本語入力中に使えない。これはMozcを改造して自分でビルドすれば多分できる。Google Docsだと
Ctrl+Shift+K
で日本語入力できるので取り敢えずやらない。Qiitaを書くのに早速今困っているがなんとかなる。