Bash でローマ字による日本語ファイル名補完を行う

Bash のプログラマブル補完と Migemo を組み合わせて、ローマ字による日本語ファイル名補完が行えるようにするスクリプトです。

ニュース

このソフトウェアはもはやメンテナンスされていません。ごめんなさい。 元々2008年当時、私は bash-completion の開発に参加していたのですが、その過程で bash のプログラマブル補完周りのバグがいろいろと見つかりました。しかし残念な事に、bash の作者はプログラマブル補完について以前から否定的な考えを示しており、それらのバグに関しても修正されないままでした。

bash-completion では、bash のバグを回避するために様々なトリックを使っていましたが、それでもやはり限界があり、bash のバグに起因する bash-completion のバグの多くが修正不可の状態なっていました。 bash のプログラマブル補完周りのバグは、根本的には bash のプログラマブル補完機能の設計上の問題であるため、修正するにはプログラマブル補完のコードを一から書き直す必要がありました。そのため、使用シェルを zsh に切り替え、bash-completion 及び bash-completion-migemo からは手を引いてしまいました。

2008-08-25
Autotools化しました。手動での環境変数の設定やファイルのコピーをする必要は無くなり、./configure && make && make install でインストールして、bash-completion-migemo.sh を source するだけで使えるようになりました。

ダウンロード

必要なもの

単に私がこの環境で開発しているというだけで、もっと古いバージョンや新しいバージョンでも動くかもしれません。

インストール

$ ./configure && make && make install

でインストール出来ます。 この場合のインストール先は /usr/local/share/bash-completion-migemo になります。

$ ./configure --prefix ~

とすれば、~/share/bash-completion-migemo へインストールする事も出来ます。

そして、インストールした bash-completion-migemo.sh を source すれば、ローマ字による補完が使えるようになります。

$ source /usr/local/share/bash-completion-migemo/bash-completion-migemo.sh

適当なファイルを作って試してみましょう。

$ touch あいうえお
$ ls aiu[TAB]
 => あいうえお

ちゃんと動くことが確認できたら、~/.bashrc に上記 source 行を追加しておくと良いでしょう。

bash-completion と一緒に使う場合は、先に bash-completion スクリプトを source しておいて下さい。

制限事項

$ ls
123hati
123八
$ ls 123ha[TAB]

とすると、

$ ls 123

という風に ha が消えてしまいます。 これは、123ha で始まる補完候補として 123hati と 123八 という二つの候補が返されるけれど、Bash は補完候補の中で共通の部分を残すため(たぶん)、二つの文字列の間で共通の 123 のみが残され、異なっている ha の部分が消されてしまう。という事だと思います。

他にも、

$ ls
伊藤太郎
伊東太郎
$ ls ito[TAB]
$ ls 伊

という感じで to が消えます。

これは解決が非常に難しいかも・・・。本来は、ito[TAB] は 伊to になるべきだけど、でもそのためには「ito の i が 伊 に対応するから、to はそのまま残す。」という事をしなければならない。

正しく動くようにするには、Bash の変更が必要になりそう。

TODO

zsh でも使えるようにしたい。

user-dict の指定方法を決める。

gettext 化とか。

C/Migemo を使うとどうなるのかテスト。

sourceforge とかに移すとか。

man page を書いた方が良いかも。

名前付きパイプを使うのをやめて(デッドロックする事が多い)、XML-RPC とか D-Bus とかを使うようにする。

技術的な事柄

以下の説明は普通に使い分には必要の無い事柄ですが、興味のある方がいるかもしれないので説明しておきます。

付属の romkan.rb について

romkan.rb には、以下のように変換テーブルを実行時に生成している箇所がたくさんあります。

  KANROM = (kanaroma = Hash.new
          (KUNREITAB + HEPBURNTAB + MISC).split(/\s+/).pairs {|x|
            kana, roma = x
            kanaroma[kana] = roma
          }
          kanaroma)

生成されるテーブルは静的なので、全てリテラルに展開しました。これだけで以下のようにかなり早くなりました。

$ ruby -r profile -e "require 'romkan'"
%   cumulative   self              self     total
time   seconds   seconds    calls  ms/call  ms/call  name
[...]
0.00     0.91      0.00        1     0.00   910.00  #toplevel
$ ruby -r profile -e "require './romkan'"
%   cumulative   self              self     total
time   seconds   seconds    calls  ms/call  ms/call  name
[...]
0.00     0.01      0.00        1     0.00    10.00  #toplevel

もう一つ、romkan.rb はローマ字からひらがなへの変換を行うテーブルを持っていますが、これに "thi" から "てぃ" への変換がありません。 ローマ字入力 - Wikipedia によると、「JIS X 4063:2000」というので規程されているらしいので、それと比較すると以下の入力方式が足りません。

「必ず実装しなければいけない入力方式」で規程されているもののなかで romkan.rb に足りないものは:

「追加で実装したほうがよい入力方式」の方は、vavivuvevo う゛ぁう゛ぃう゛う゛ぇう゛ぉ 以外が全て足りません。

というわけで、足りないものを全て追加しました。ただ、ゕ と ゖ は EUC-JP で表現出来ないので除外しました。(Unicode か JIS X EUC-JIS-2004 じゃないと)

付属の migemo-dict について

Migemo の辞書にはこういう定義があります。

たんそ	炭素	炭疽	C	Carbon

これによって

t[TAB]

とすると、C で始まるファイル名にもマッチしてしまいます。他にもこういう「一文字の英単語」が結構あって、例えばこういう定義:

ほうそ	硼素	B	Boron
ふっそ	F	Flourine

これによって、h[TAB] が B で始まるファイル名と F で始まるファイル名にもマッチしてしまいます。これは非常に利便性が悪いと思うので、付属の migemo-dict では「アルファベットに変換される箇所」を除去しました。

辞書を再生成するために実行したコマンドについては migemo-dict/MEMO にメモしてあります。