ReadP
「GHCのメジャーバージョンが知らぬ間に7に!」というくらいHaskell離れしてましたが,とあるスクリプトを作るために久しぶりに使ってみた。
とりあえず必要なのはParserCombinator。以前に作った自前のモノでもよいのだが,今回はReadPを使うことにした(Text.ParserCombinators.ReadP)。
何というか,関数型言語的な考え方を忘れてしまったので,まずは簡単なサンプルとして足し算の式を読み取ってその和を返すというものを作成。
import Text.ParserCombinators.ReadP import Char number :: ReadP Int number = (munch1 isDigit) >>= return . read add :: ReadP Int add = do { a <- number ; string "+" ; b <- number ; return (a + b) }
ghciで確認。
*Main> readP_to_S number "1" [(1,"")] *Main> readP_to_S add "1+2" [(3,"")]
どうやら狙ったものは作成できたらしい。returnの存在になかなか気付かなくって"ReadP Int"をどう作成すれば良いか悩んだ。ReadPはMonadのインスタンスだからreturnが使えるということを失念していた。
ReadPを使えそうな手応えを得たので本チャンの作業に取り掛かるか。
レイアウト(Mac OSX)
US配列のキーボードとJIS配列のキーボードでは記号類の配列にじゃっかん異なるところがあるが,ハードウェア的には同じものである。例えば,"p"のすぐ右のキーはJIS配列では"@"だがUS配列では"["となっている。しかし,送られて来るキーコードはどちらも0x2Fである。
キーボードから入力されたデータを解釈し,それに対応する文字に変換するのはOSの仕事となる。JIS配列キーボードが繋がっているときはキーコード0x2Fを"@"とし,US配列のときは"["とするわけだ。ソフトウェアでやっていることなのでこの変換の対応表は当然変更でき,JIS配列キーボードをUS配列として使うことは可能である。というか,意図せずそうなることもある。
Mac OSXではその辺のところがかなり細かく設定でき,自分好みの配列に変更することができる*1。ただし,その設定はXMLファイルで書く必要がある。設定ファイルを直接編集するのはかなり厳しいが,そこは安心,UkeleleというGUIでキーボードレイアウトを設定しXMLファイルを作成してくれるナイスなアプリがある。これがあれば変態的な配列にするのもかなり楽になる。
Ukeleleはすばらしいソフトだが,難点もある。ただし,それらはUkeleleの問題ではなく,OSXのキーボードドライバに起因する問題である。すなわち,以下の2点である。
- モディファイアキーを自由に再配置できない
- もともと割り当てられていないキーは再配置できない
*1:他のOSでも当然できるはずだが,良く知らない
キー間格差の問題点
Nキーロールオーバーについて書いたが,ゲーマーではないので実はどうでも良かったりする。気になったのはモディファイアキーとその他のキーがUSBキーボードでは区別されて送信されるという点である。
一般のUSBキーボードでホストとのやりとりで用いられるBoot Protocolではモディファイアキーは1byteのビットマップデータとして表現され,その他のキーは6bytes中の各1byteにキーコードが埋め込まれる。
モディファイアキーはCtrl,Alt,Shift,GUI*1の4種類でそれぞれ左右によって違いがあるので計8つ。つまり,1byteのビットマップならすべてのモディファイアキーの状態を表すことができる。
その他のキーは1byteのキーコードで送信されるので,6bytesだと最大で6つのキーが押されているという状態をホストに伝えることが可能となる。
これを読めば明らかなようにモディファイアキーとその他のキーは平等には扱われていない。USBキーボードはPS/2キーボードとは異なりただのスイッチの集まったデバイスにすぎないが,実はそのスイッチ間に格差があるのである。
で,その格差が問題になるかと言うと,当然なるし,現状の社会情勢ではその解消は難しい。
では,具体的にどのような時に問題になるのか。それは,ソフトウェアレベルでキーの配置替えをするときである。
ソフトウェアでのキーの配置替えとは,要は入力されたキーコードをソフトウェアで別のキーコードに変更にすることである。例えば,aのキーコードをbのキーコードに変更するようにすれば,キーボードのaのキーを押せばbと入力されるというイメージ。Windows XPなら窓使いの憂鬱というソフトでこれと同じことができる。ただし,窓使いの憂鬱ができることはこんなもんじゃない。
別にaをbに変更するだけなら特に問題にはならないが,aキーを左Ctrlキーとして使おうとするとちょっと問題が出てくる。というのも,aとCtrlはキーボードからの送られかたが違うからである。Boot Protocolではモディファイアキーは全てOn/Offの区別ができるようになっているが,aに左Ctrlを割り当てるとキー配置替えソフトより上位ではすべてのモディファイアキーを区別できるとは限らなくなってしまう。左Ctrlだけではなく,他のモディファイアキーも変更すれば,もしかしたら入力できないキーボードショートカットが出てくるかもしれない。まあ,よほど変態的な人でない限りは問題ない気はかなりするが。。ここまで書いておきながらだけど。
回避する方法としてはハードウェアレベルで変換という手があり,Kinesisのキーボードにあるキーのリマップ機能なんかはたぶんそうなっている。なお,キーコードを変換するような専用ハードウェアを軽く探してみたが,見当たらなかった。
まとめて書くより日々のログ
久しぶりにまとまった文章を書いたが,特に新たに調べたわけでもなく,ちょっと前に調べたことを資料を再度見て思い出しながら書いたので,それほど有益な時間の使い方ではなかったかもしれない。やはり調べたときに書いた方がその時に考えたことが文章にも反映されるのでログとしての価値は高い。
本来はもう少し書く予定だったが,正午から夜にかけてはPCを落として読書に時間を費やしたので,予定通りにはいかなかった。今どきの省エネPCの消費電力なんて微々たるもので,偽善や自己満に近いところはあるが,それでもやはり電気を使うことはためらわれた。