変態キーバインドに挑戦

おさかなラボさんの「禁断の快楽・変態キーバインドのお誘い」という記事に激しく衝撃を受けました。これ、Gentoo Linux でもできないかなあ、とやってみた記録です。長文なので最初に書いておくと‥あんまりうまくいかなかったです。('A`)

やりたいこと

  1. セミコロンを Enter に。Ctrl + セミコロンで本物のセミコロン。
  2. Ctrl + HJKL でカーソルの左下上右移動。

あんまりコテコテに変えてしまうと他の端末が使えなくなってしまいそうなので、とりあえずこれだけにしておきました。職場の Windows マシンに「窓使いの憂鬱」をインストールして、このキーバインドをしばらく実践してみたのですが‥‥実にすばらしい!
セミコロンが Enter になると、たとえば

  カタカタカタ ぱしっ
  カタカタカタカタカタカタ ぱしっ

と普通に打つとこうだったのが、

  カタカタカタにゅる
  カタカタカタカタカタカタにゅる

みたいな感じです。タイプが速くなるかと言われると微妙ですが、この感触は慣れるともうやみつき。Ctrl + セミコロンも、そんなに違和感なく使えました。SQL*Plus とかはちょっとつらかったけど、それを補って余りあるものがあります。

あと最近すっかり Vim 派なので、いつでもどこでも HJKL というのもかなりいいです。Firefox でも HJKL。Excel でも HJKL。これに慣れると Vim でもつい Ctrl を押しながら HJKL しちゃいますが、挿入モードでもカーソル移動できるのでかえって便利だったりします。

コンソールでの設定

うちのマシンは日本語106キーボードです。ほかのキーボードだといろいろと違うところがあるかと思いますので、参考にされる場合は適宜読みかえてください。

それではまずはコンソールから設定していきます。追加のキーマップを作ってそれを読みこむようにします。

file: /usr/share/keymaps/i386/include/hentai.map
keycode 39 = Return  plus
control keycode 39 = semicolon

control keycode 37 = Up
control keycode 35 = Left
control keycode 38 = Right
control keycode 36 = Down

plus というのは Shift + セミコロンでプラス記号になるように、ということです。これを読みこむには loadkeys というコマンドを使うようですが、Gentoo では init スクリプトになっているので、それを使います。/etc/conf.d/keymaps で追加したキーマップを指定して‥

file: /etc/conf.d/keymaps
EXTENDED_KEYMAPS="hentai"

keymaps を再起動します。

# /etc/init.d/keymaps restart

これで完了。コンソールってあんまり使わないかもしれないけど、くせになってると手が勝手にセミコロン打っちゃうんですね。コマンドの履歴を JK で行ったりきたりできるのも何げに便利です。

X での設定(1) xmodmap

この設定が X でも引き継がれるのならもう何もしなくていいのですが、残念ながら別々のものみたいです。~/.Xmodmap というファイルに設定を書いて、起動時に xmodmap というコマンドで読みこむとのこと。

ではさっそく、とやってみたのですが‥‥‥。

どうやら Ctrl を押しながら、という設定は書けないようです。xmodmap でできるのは、Shift を押しながらの場合と、Mode_switch というのに指定したキーを押しながらの場合だけみたい。早くも行きづまりです。('A`)

しかたがないので、Caps Lock を Ctrl に、左の Ctrl キーを Mode_switch に割り当てて、これでしのぐような設定にしてみます。もともと Caps Lock は Ctrl にしてたので、そんなに支障はない、かな?

file: ~/.Xmodmap
clear lock
clear control
keycode  66 = Control_L
keycode  37 = Mode_switch
keycode  43 = h H Left
keycode  44 = j J Down
keycode  45 = k K Up
keycode  46 = l L Right
keycode  47 = Return plus semicolon plus
add control = Control_L
add control = Control_R

キーコードもコンソールとは違うんですね。この方法だと、Ctrl + HJKL がショートカットになっているアプリとキーがバッティングしない、というメリットはありますが、さすがにイマイチですね‥。左の Ctrl と Caps Lock を無意識のうちに使い分けられるようになるには、相当な訓練が必要そうです。

X での設定(2) gtkrc

Xfce4 ではこんな感じにキーボードマップを選ぶことができます。次はこれを試してみましょう。

Xfce4 キーボードの設定

ここで選んでいるのは GTK+ のキーバインド設定みたいなので、適当に作ってみます。ファイル名と置き場所はこんなふうにしてやると、設定画面が認識してくれます。

file: ~/.themes/Vim/gtk-2.0-key/gtkrc
binding "gtk-vim-text-entry"
{
  bind "<ctrl>j" { "move-cursor" (display-lines,  1, 0) }
  bind "<ctrl>k" { "move-cursor" (display-lines, -1, 0) }
  bind "<ctrl>l" { "move-cursor" (logical-positions,  1, 0) }
  bind "<ctrl>h" { "move-cursor" (logical-positions, -1, 0) }

  bind "<ctrl>semicolon" { "insert-at-cursor" (";") }   # ←ダメ
  bind "<ctrl>Return" { "insert-at-cursor" (";") }      # ←ダメ
}
class "GtkEntry" binding "gtk-vim-text-entry"
class "GtkTextView" binding "gtk-vim-text-entry"

中に「ダメ」と書いてしまいましたが、Ctrl + セミコロンがどうがんばってもセミコロンになってくれませんでした。それに、ここでの設定よりも、各アプリでのもともとのキー設定のほうが優先されるみたいです。たとえば Leafpad で Ctrl + H すると、カーソルが左に動くのではなくて置換のダイアログが開くといった具合。アプリごとに設定を書けばいけそうな気もしますが、そこまではちょっと、ねえ。

また、当然ながら xterm のような GTK+ でないアプリには効きません。うーん。

X での設定(3) xbindkeys + xvkbd

だんだんムキになってきました。(w

xbindkeys はキー入力に対して実行するコマンドを設定できるというツールです。本来の意図はランチャーみたいですね。xvkbd はソフトウェアキーボードですが、指定したキーコードを送るだけ、という動作もできます。このふたつを組み合わせて、キーの入力と出力をすり替えてやる、という技があるそうなので、試してみることにします。

まずはこれらをインストールしないといけません。

# emerge -pvt xbindkeys xvkbd
[ebuild  N    ] x11-misc/xvkbd-2.8
[ebuild  N    ]  x11-libs/Xaw3d-1.5-r1
[ebuild  N    ]   x11-misc/imake-1.0.2  USE="-debug"
[ebuild  N    ]    x11-misc/xorg-cf-files-1.0.2  USE="-debug"
[ebuild  N    ]  app-text/rman-3.2
[ebuild  N    ]  x11-misc/gccmakedep-1.0.2  USE="-debug"
[ebuild  N    ] x11-misc/xbindkeys-1.8.0  USE="-guile -tk"

いろいろ入ってきてしまいますが、しかたありません。そしたら xbindkeys の設定ファイルに、xvkbd を実行する設定を書いていきます。

file: ~/.xbindkeysrc
"LC_ALL=C xvkbd -xsendevent -no-sync -text \[Left] >& /dev/null"
  control + h
"LC_ALL=C xvkbd -xsendevent -no-sync -text \[Down] >& /dev/null"
  control + j
"LC_ALL=C xvkbd -xsendevent -no-sync -text \[Up] >& /dev/null"
  control + k
"LC_ALL=C xvkbd -xsendevent -no-sync -text \[Right] >& /dev/null"
  control + l
"LC_ALL=C xvkbd -xsendevent -no-sync -text \[semicolon] >& /dev/null"
  m:0x4 + c:47

なかなか試行錯誤の跡がうかがえます。('A`)

普通に実行するとしばらく黙りこんでしまったので、LC_ALL をつけてます。なんかフォントを探しにいってるみたい。-xsendevent はつけないと動いてくれませんでした。-no-sync はなんとなく。-text がかんじんのキーコードを送るだけ、というオプションです。で、実行するたびにメッセージを吐くので捨ててる、といった感じです。
Ctrl + セミコロンはこうやって直接キーコードを指定してやると、うまくひろってくれました。キーコードは xbindkeys -k と実行すると調べられます。

xbindkeys を起動してやると‥

$ xbindkeys

やりました!ちゃんと Ctrl + HJKL で上下左右に動きます!すばらしい!

‥‥のですが。
キー入力のたびにプロセスを起動することになるので、やはりそれなりのオーバーヘッドがあるんですね。それが気になるかどうかはマシンスペックにもよるのかもしれないけど、「裏で何か違うことやってるな」感はひしひしと伝わってきて、常用するにはちょっと抵抗があるかなあ、とそんな感じでした。

それに、なぜか Firefox にだけはまったく効きませんでした。原因はさっぱりわかりませんが、JK でスクロールできないのは残念ですね‥。

まとめ

とまあいろいろがんばってみたものの、しっくりくる方法にはたどりつけませんでした。で、結局いまはどうしてるかというと、

  1. セミコロンを Enter にするのは xmodmap で。
  2. カーソル移動は Mode_switch + HJKL で妥協。
  3. gtkrc はいちおう設定しておく。(Firefox のテキストエリアでだけはこれが効くので)
  4. Ctrl + セミコロンは xbindkeys + xvkbd で。
    (Mode_switch + セミコロンだけだとさすがにつらそうなので)

という快適なのかどうなのかよくわからない状態になってます。
それにしても、こんなに手こずるとは思いませんでしたねえ。もっといいやり方があるんでしょうか。。。

「犬使いの憂鬱」とかないのかな、とぐぐってみたところ、「そういうのが欲しい」という何年も前の 2ch のスレが引っかかっただけでした。('A`)

いただいたコメント

  1. From: tottsan さん - 2008/9/10 5:30

    (1)
    XKBエクステンションを使用しなければ、コンソールの設定が
    引き継がれます。

    (2)
    逆にXKBエクステンションの設定ファイルをいじれば、かなり
    複雑なカスタマイズができます。
    http://www.m17n.org/ntakahas/npx/aggressive/aggressive2.ja.html
    にその例があります。

よろしければコメントをどうぞ...

(お持ちでしたら)