emacs on WSLでSuper/Hyperキーを使う方法
はじめに
この前の東京Emacs勉強会で雑談してたときに、Superキー、Hyperキーの話になり、Macは修飾キーが多くてうらやましかった。 キーバインド覚えやすいところうまっていて、追加で悩む状況でもあるし。
ということで自分もSuper/Hyperデビューすべく、WSLでのやりかたを調べてみた。
環境
- wsl
- wsl上で動くEmacs
- X410 (Xサーバ)
なので、emacs for windowsとか、mingwのemacsではないです。その場合は、また他の手段を取る必要があるはず 1。
なお、wslで使うXサーバといえば、xmingかvcxsrvが有名ですが、emacsとの相性がよくない(※)ので別の有償のXサーバを使ってる。 X410は、ストアアプリとして購入できるが、しょっちゅう80%Offセールしているので割引タイミングを狙いましょう。
(※) emacsとの相性がわるい問題については以下のスライドを
目指すゴール
無変換キーをSuperキーとして、変換キーをHyperキーとして使えるようにする。
一般的には、WindowsキーがSuperキーにあたると思うし、なんなら設定なしでもそう動いてしかるべきなのだけど、そもそもOS側にトラップされてアプリケーションまでうまく届かなかったのと、Windows10になってWin+○のショートカットキーが増えてそれを無効にするのも不便だったので、上記の設定をおこなうことにした。
前置きは以上。
Superキー/Hyperキーを設定する
手段その1 AutoHotKeyを使う
多分これが一番早いと思います。 サンプルも多いはず。
自分は、なんとなくWindowsのユーザランドでキーいじるやつが嫌だったので採用しなかった。 (CapsとCtrlの入れかえで、結局レジストリいじらないとうまくいかなかったりというのに以前ぶつかったりしたので)
手段その2 xmodmapを使う
xmodmapはlinuxというか、Xの世界でキーマップ変更するためのもの。調べてみると最近は別のがあるっぽいけど、xmodmapでうまく動いたので気にしない。
そうそうキーコードなんて変わらないと思うので、同じ設定で同じように動くはず。
手順1. キーコードを特定する
xev
というコマンドを使うと、Xのアプリが起動して、そこでもろもろのイベントを標準出力に出して確認することができる。
これを使うと、変換と無変換のキーコードは以下のとおり、変換が129、無変換が131であることがわかる。
KeyRelease event, serial 33, synthetic NO, window 0x800001, root 0xf4, subw 0x0, time 426541921, (67,97), root:(179,232), state 0x0, keycode 131 (keysym 0xff22, Muhenkan), same_screen YES, XLookupString gives 0 bytes: XFilterEvent returns: False KeyPress event, serial 33, synthetic NO, window 0x800001, root 0xf4, subw 0x0, time 426596187, (843,330), root:(955,465), state 0x0, keycode 129 (keysym 0xff23, Henkan_Mode), same_screen YES, XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False
手順2. xmodmapの動作確認する
キーコードがわかったら、xmodmap
コマンドで一時的にキーシムを書きかえて動作確認してみる。
# xmodmap -e "keycode 131 = Super_L Super_L" # xmodmap -e "keycode 129 = Hyper_L Hyper_L"
実行後、再度xevを使って期待通り変わっていることを確認する。
KeyPress event, serial 33, synthetic NO, window 0x800001, root 0xf4, subw 0x0, time 426819890, (125,123), root:(263,284), state 0x0, keycode 131 (keysym 0xffeb, Super_L), same_screen YES, XKeysymToKeycode returns keycode: 115 XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False
先程はキーコード131が無変換だったのが、Superに変わっていることがわかる。
手順3. xmodmapの設定を作成する
調べると、xmodmap -pke
を実行して、必要なところだけ書きかえましょう。というのが出てくるのだが、実際のところ必要な設定だけ書けばよかったので、いきなり .Xmodmap
ファイルを作成する。
WSLで手持ちのXサーバ使う分には別にファイル名は何でもいいと思うのだが、ここは慣例に従っておく。(startxコマンドでx起動するときは、雛形で.Xmodmapを詠み込むのでファイル名重要)
自分の設定は、こんなかんじ。
https://github.com/grugrut/dotfiles/blob/master/.Xmodmap
clear mod3 clear mod4 !<muhenkan> keycode 129 = Hyper_L Hyper_L Hyper_L Hyper_L !<henkan> keycode 131 = Super_L Super_L Super_L Super_L add mod3 = Hyper_L add mod4 = Super_L Super_R
デフォルトの状態だと、SuperキーとHyperキーが同じ修飾キーとしてあつかわれていて、Hyperキー単体でうまくうけとれないので使われていないmod3にHyperキーを割当ておいた。
手順4. 自動で適用されるようにする
xmodmap ~/.Xmodmap
とコマンド実行すればよいのだけど、注意点が一つ。
xmodmapはXサーバに対して設定をおこなうコマンドなので、Xサーバが起動していない状態ではうまく動かない。
LinuxやBSD使ってるときにもxmodmap使ってたけど、当時は常にxorg-serverが起動してたので今回はじめてそのこと知った。
ついでなので、OSログイン時にXサーバを起動すべく適当なbatを作成した。 https://github.com/grugrut/dotfiles/blob/master/_windows/startx.bat
start /b x410.exe ubuntu.exe run "DISPLAY=127.0.0.1:0.0 xmodmap ~/.Xmodmap"
x410.exeが使っているXサーバ。バックグラウンド実行させたいので、/b
オプションをつけてる。
そして、ubuntu.exe run
をすることでwslでコマンド実行できる。
これを Windowsの shell:startup
に配置することでスタートアップ時に自動実行することができる。
ただし、直接おくよりもショートカットを配置することをおすすめする。直接配置すると、実行時にコマンドプロンプトが一瞬表示されてうっとうしいが、ショートカットであれば最小化して実行することができるので気にならないからだ。
まとめ
xmodmapを使うことで、他のアプリには影響なくwslのX使うアプリだけにいろいろ手をいれられることが確認できた。他にもその手の機能で便利なのありそう。
-
たぶん
w32-lwindow-modifier
とかが使えるはず↩