«前の日記(2006-01-31 [火]) 最新 次の日記(2006-05-01 [月])» 編集
RSS: href="http://endoh-namazu.tierra.ne.jp/diary/index.rdf"


半期 四半期 全カテゴリ

新・なまず日記


2006-02-03 [金]

_ [AHK][カスタマイズ]窓使いの憂鬱のプラグインをAutoHotkeyで利用する ー 実践編(migemo-isearchの利用)

(前回の続きです)

前回、TAGA nayutaさんの窓使いの憂鬱(以下、mayu)用のプラグインを、AutoHotkey(以下、AHK)で利用するためのやり方とライブラリを紹介させて頂きました。今回は、実際にmayu用プラグインの一つである、tamanegiさんのmigemo-isearchを、AHKから使ってみます。

前回もちょっとふれましたが、migemo-isearchは、大きく分けて、以下の2種類の機能を持っています。

  1. 検索開始を指示する関数。これらの関数をコールすると、IEやSleipnirのウインドウの一番下のステータスバーのところに、独自ウインドウを生成し、その中で、キー入力待ちを始める。
    migemoを使った日本語サーチの他に、migemoを使わない英字のみのサーチや、正規表現サーチなどの機能がある。
  2. 上記の1で生成したウインドウにメッセージをおくる(PostMessage)ことで、次の検索候補や、前の検索候補にジャンプする。migemoを使っているときでもそうでないときでも、メッセージは共通であり、現在のインクリメンタルサーチ状態がどの関数で開始されたかで、次の(前の)検索候補のサーチ方法も決まる。また、検索終了(上記のウインドウの消去)も、メッセージで行う。

関数やPostMessageなどがでてきてややこしいので、簡単に使えるように、皮ライブラリ(ラッパ=wrapper)を作成しました。以下の手順で、あなたのautohotkey.iniに、migemo-isearchを、組み込んでください。

  1. 以下のファイルをダウンロードして、解凍してでてきたファイルを、autohotkey.iniと同じフォルダに置きます。これが、なまずが作った、ラッパライブラリです。

    migemo_isearch_v10001.zip

    ※上記zipファイルには、前回公開した、"mayu_plugin.ahk"も、含まれています。これは、前回とまったく同じものです。
  2. ここから、migemoの「バイナリ(DLL) 1.2 リリース版 for Windows」(cmigemo-1.2-dll.tar.bz2)をダウンロードします。
  3. 上記の"cmigemo-1.2-dll.tar.bz2"を解凍します。その中の、dictフォルダの中身が、migemoの辞書ファイルです。任意の場所に置いてかまいませんが、その場合は、辞書ファイルの一つの"migemo-dict"のフルパスを環境変数"MIGEMO_DICT"に設定するか、あるいは、後述するように、MIS_IEMigemoISearchForward()等の引数で、"migemo-dict"のフルパスを設定する必要があります。これらの設定をしたくない場合は、autohotkey.iniが置かれたフォルダ(A_WorkingDir)に"dict"というフォルダを作り、その中に辞書ファイルを置きます。
  4. 上記の"cmigemo-1.2-dll.tar.bz2"の中の"migemo.dll"ファイルを、autohotkey.iniが置かれたフォルダ(A_WorkingDir)か、システムフォルダなどPATHが通っているフォルダに置きます。
  5. ここから、migemo-isearch Ver 0.1.5のバイナリ版(migemo-isearch-0.1.5.zip)をダウンロードします。解凍して、中の"migemo-isearch.dll"ファイルを、autohotkey.iniが置かれたフォルダ(A_WorkingDir)か、システムフォルダなどPATHが通っているフォルダに置きます。
  6. 以下を参照して、autohotkey.iniに、migemo_isearch.ahkを、組み込んでください。
    #Include, migemo_isearch.ahk
    
    $^s:: SetTitleMatchMode,2
    if(WinActive("Microsoft Internet Explorer")) MIS_IEMigemoISearchForward("d:\program\xyzzy\dict\migemo-dict") else if(WinExist("ahk_class migemo-isearch")) MIS_MigemoISearchNextForward() else Send, ^s return
    $^r:: SetTitleMatchMode,2
    if(WinActive("Microsoft Internet Explorer")) MIS_IEMigemoISearchBackward("d:\program\xyzzy\dict\migemo-dict") else if(WinExist("ahk_class migemo-isearch")) MIS_MigemoISearchNextBackward() else Send, ^r return
    $Esc:: if(WinExist("ahk_class migemo-isearch")) MIS_MigemoISearchClose() else Send, {Esc} return
    $Return:: if(WinExist("ahk_class migemo-isearch")) MIS_MigemoISearchSelectAction() else Send, {Return} return
    この例では、
    • Cntrl-sで、migemoによる前方インクリメンタルサーチの開始
    • Cntrl-rで、migemoによる後方インクリメンタルサーチの開始
    • インクリメンタルサーチ状態のとき、Cntrl-sで、次の検索候補にジャンプ
    • インクリメンタルサーチ状態のとき、Cntrl-rで、前の検索候補にジャンプ
    • インクリメンタルサーチ状態のとき、Returnキーで、検索候補(選択状態になっている)をクリックしたのと同じ動作をする。検索候補がリンクであった場合は、そのリンクをクリックしたことになり、リンク先のページが開く。
    • ESCで、インクリメンタルサーチ状態の解除
    という動作を行います。なお、上記の例では、ブラウザとしてIEを想定しておりますが、これはIEのブラウザ描画エンジンを使っていればなんでもよくて、例えばSleipnirでもちゃんと動きます。その場合、"if(WinActive("Microsoft Internet Explorer"))"を、"if(WinActive("Sleipnir"))"と書けばよろしい。
    また、上記の例では、migemo辞書ファイル"migemo-dict"のフルパスを、引数で、指定しています(なまずは、既に、xyzzyで、miegmoを使っていたので、xyzzyフォルダの下に置いた"migemo-dict"を指定しています)。前述した通り、環境変数"MIGEMO_ENV"に、"migemo-dict"のフルパスを指定すれば、この引数は省略できます。さらに、autohotkey.iniがあるフォルダの下にdictフォルダを作ってそこに辞書ファイルを置けば、引数も、環境変数"MIGEMO_ENV"も、省略できます。

今回、なまずが用意した、migemo-isearchのラッパライブラリの仕様を以下に説明します。migemo-isearch.dllの仕様を調べなくても使えるように機能を説明しますが、なまずは一行のみの「皮」を用意したのみで、機能そのものは、tamanegiさんのmigemo-isearchで実現されていることは言うまでもありません。


  • IEエンジンにおけるmigemo前方インクリメンタルサーチの開始

    MIS_IEMigemoISearchForward( dict )

    引数:
    • dict
      migemo用の辞書ファイル"migemo-dict"のパス。省略すると、スクリプトを起動したフォルダ(A_WorkingDir)の下のdict\migemo-dictか、あるいは環境変数MIGEMO_ENVで指定したファイルが参照される。

    戻り値:
    • なし

    動作:
    • migemoを使った(日本語もローマ字で検索可能)前方インクリメンタルサーチを開始する。IEエンジンを持つウインドウがActiveでないときに本関数をコールしたときの動作は不定。


  • IEエンジンにおけるmigemo後方インクリメンタルサーチの開始

    MIS_IEMigemoISearchBackward( dict )

    引数:
    • dict
      migemo用の辞書ファイル"migemo-dict"のパス。省略すると、スクリプトを起動したフォルダ(A_WorkingDir)の下のdict\migemo-dictか、あるいは環境変数MIGEMO_ENVで指定したファイルが参照される。

    戻り値:
    • なし

    動作:
    • migemoを使った(日本語もローマ字で検索可能)後方インクリメンタルサーチを開始する。IEエンジンを持つウインドウがActiveでないときに本関数をコールしたときの動作は不定。


  • IEエンジンにおける英字のみの前方インクリメンタルサーチ(正規表現)の開始

    MIS_IERegexpISearchForward()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • 正規表現による前方インクリメンタルサーチを開始する。IEエンジンを持つウインドウがActiveでないとき、本関数をコールしたときの動作は不定。
      正規表現のスタイルはPerlなどとほぼ同じで、詳細な仕様はこちらを参照のこと。


  • IEエンジンにおける英字のみの後方インクリメンタルサーチ(正規表現)の開始

    MIS_IERegexpISearchBackward()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • 正規表現による後方インクリメンタルサーチを開始する。IEエンジンを持つウインドウがActiveでないとき、本関数をコールしたときの動作は不定。
      正規表現のスタイルはPerlなどとほぼ同じで、詳細な仕様はこちらを参照のこと。


  • IEエンジンにおける英字のみの前方インクリメンタルサーチの開始

    MIS_IEISearchForward()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • 英字のみの前方インクリメンタルサーチを開始する。IEエンジンを持つウインドウがActiveでないとき、本関数をコールしたときの動作は不定。


  • IEエンジンにおける英字のみの後方インクリメンタルサーチの開始

    MIS_IEISearchBackward()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • 英字のみの後方インクリメンタルサーチを開始する。IEエンジンを持つウインドウがActiveでないとき、本関数をコールしたときの動作は不定。


  • 次のワードを検索

    MIS_MigemoISearchNextForward()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • インクリメンタルサーチ中にコールすると、次のワードを検索する。例えば MIS_IEMigemoISearchForward()でインクリメンタルサーチを開始していたら、次のワードも、migemoを使った検索を行う。
      クラス名"migemo-isearch"のウインドウがないときは、なにもしない。


  • 前のワードを検索

    MIS_MigemoISearchNextBackward()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • インクリメンタルサーチ中にコールすると、前のワードを検索する。例えば MIS_IEMigemoISearchForward()でインクリメンタルサーチを開始していたら、前のワードも、migemoを使った検索を行う。
      クラス名"migemo-isearch"のウインドウがないときは、なにもしない。


  • 選択された文字のクリック(と同じ動作)

    MIS_MigemoISearchSelectAction()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • インクリメンタルサーチ中にコールすると、現在選択中の文字列をクリックしたのと同じ動作を行う。選択中の文字列がリンクであったら、そのリンク先のページを開く動作を行う。
      クラス名"migemo-isearch"のウインドウがないときは、なにもしない。


  • 検索の終了(検索ウインドウの消去)

    MIS_MigemoISearchClose()

    引数:
    • なし

    戻り値:
    • なし

    動作:
    • インクリメンタルサーチ中にコールすると、インクリメンタルサーチを終了する(検索ウインドウを消去する)。
      クラス名"migemo-isearch"のウインドウがないときは、なにもしない。


以下は、上記の関数の、"CaseSensitve"(英語の大文字小文字を区別する)版です。しかし、なまずには、これらの関数の使い方がイマイチ良くわかっていません。一応ラッパ関数は作りましたが、使い方が良くわかっていないので、ちゃんと動作確認はできていません。"CaseSensitve"なことをのぞけば仕様は上記と変わりませんので、説明は省略します。

  • IEエンジンにおけるmigemo前方インクリメンタルサーチ(大文字小文字を区別)の開始

    MIS_IEMigemoISearchForwardCaseSensitive( dict )

  • IEエンジンにおけるmigemo後方インクリメンタルサーチ(大文字小文字を区別)の開始

    MIS_IEMigemoISearchBackwardCaseSensitive( dict )

  • IEエンジンにおける英字のみの前方インクリメンタルサーチ(正規表現,大文字小文字を区別)の開始

    MIS_IERegexpISearchForwardCaseSensitive()

  • IEエンジンにおける英字のみの後方インクリメンタルサーチ(正規表現,大文字小文字を区別)の開始

    MIS_IERegexpISearchBackwardCaseSensitive()

  • IEエンジンにおける英字のみの前方インクリメンタルサーチ (大文字小文字を区別)の開始

    MIS_IEISearchForwardCaseSensitive()

  • IEエンジンにおける英字のみの後方インクリメンタルサーチ (大文字小文字を区別)の開始

    MIS_IEISearchBackwardCaseSensitive()

※既知の問題
以下の問題のほとんどは、恐らくmayuでも起こることではないかと思うのですが、一応書いておきます。

  • ブラウザで表示しているHTML文書によっては、"get_doc failed"というエラーが出て、インクリメンタルサーチが開始できないことがある。フレームを切っている文書の場合は、対象フレームにキーボードフォーカスを設定すると、上記の問題が解消されることもあります。しかし、どうやっても開始できないページもある。たとえばTECHSIDEさんとか。なまずはTECHSIDEさんが好きなので、ちょっと残念です。
  • ブラウザの中の入力フィールドにキーボードフォーカスがある状態で、インクリメンタルサーチを開始すると、最初の一文字を入力したところで、"ctx->range_move_point failed"というエラーが出て、検索できません。フォーカスを入力フィールドから出してインクリメンタルサーチを開始させれば、大丈夫です。
  • ちょっと動作が重いことがあります。すばやくキー入力をすると、入力キーをロストすることがあります。ちょっとゆっくり目に入力するといいです。
  • インクリメンタルサーチで入力した文字列は、バックスペースキーで消すこともできますが、そのバックスペースを、AHKで他のキーに割り当てていて、そのキーをキーリピートさせると、重くてAHKが処理できず、いろいろおかしなことが起こります(突然AHKのコンソールウインドウが出てきたりとか)。リピートさせずにポチポチやるか、生のバックスペースキーを使う分には、大丈夫です。
  • ※06/2/8追記
    migemo-isearch.dllが06/2/4にVer 0.1.4になり、上記の問題はほぼ解決しました。見違えるほど動作が軽くなり、キーロストはほとんどありません。ホントに素晴らしいです。しかし、0.1.4にすると、

    1. MIS_MigemoISearchSelectAction()で、ほぼすべての条件で、AHKがハングする。
    2. フレームを切っているHTMLのとき、MIS_MigemoISearchClose()で、ときどきAHKがハングする。

    という課題が出ることがわかりました。それで、それを調整したmigemo_isearch.ahk Ver1.00.01(migemo_isearch_v10001.zip)を、公開します。これで、なまずの環境では、上記の1はほぼ完全に解決、 2は、100回に1回くらい、ごくまれにハングするくらいに収まりました。 本当の解決になっているかわかりませんが、とりあえず、これで様子を見てみます。
  • ※06/2/10追記
    (以下のハングアップの記事は、migemo-isearch がVer0.1.4での話です。Ver0.1.5では起こりません(06/2/15))
    上記の1はともかく、2に関しては、なまずの調整はなんの意味もなかったことがわかりました。やっぱり、度々、AHKがハングしてしまいます。
    「AHKがハングする」と、AHK全体で、新たなスレッドが一切生成されなくなる、ということが起こるようです。そうなると、"$^f::"などで定義したホットキースレッドが起動しなくなり、しかしキーのフックはしているので、定義したキーが使用できなくなります。
    こうなると、"autohotkey.exe"のプロセスを殺すしか復帰の道はありません。しかし、なまずはマウスクリックもホットキー定義していたので、クリックさえもできなくなり、プロセスを殺すだけでもエラい苦労しなければならず、ホトホト困りました。
    このハングが、AHKのみで起こることなのか(つまりなまずのmayu_plugin.ahkに問題がある)、それともmayuでも起こることなのかは、よくわかりません。また、どのような条件でこのハングが起こるのかも、よくわかりません。しかし、何度もやっているうちに、かなりの高確率で、ハングを起すパターンがあることが分かってきました。
    なまずの環境(Windows2000SP4)では、以下のパターンで、大体ハングが起こります。

    1. まず、フレームを切ってあるページ(たとえばこことか)を表示します。
    2. migemo-isearch.dll Ver0.1.4を使用するアプリケーションを、再起動するなどして、まだ、migemo-isearchが動いていない状態にします。AHKなら、リロードが一番簡単です。
    3. マウスで、ページの中の適当な文字列を、選択状態にします。ちょっと長めの文字列の方が、よくハングする?
    4. MIS_MigemoISearchNextForward()などで、migemo-isearch.dllを動かします。そして、なにも検索動作をさせずに、MIS_MigemoISearchClose()で、サーチを終了します。
    5. これで大体ハングします。


    どうも、「migemo-isearch.dllの最初の起動のときの動作」が重要のようです。この最初の動作が、上記のようなものでなかったら、(だいたい?ほとんど?絶対?→まだわかりません)ハングしないようです。とりあえず、今は、migemo-isearch.dllの最初の起動の時は、下記のような「儀式」をすることで、様子を見ています。

    1. migemo-isearchを最初に動かすときは、まず、ブラウザで適当なページを表示し、選択状態のテキストが一つもないことを確認します。
    2. MIS_MigemoISearchNextForward()などで、migemo-isearch.dllを動かします。そして、なにも検索動作をさせずに(検索キーワードを入力せずに)、MIS_MigemoISearchClose()で、検索ウインドウを閉じます。
    3. もう一度、MIS_MigemoISearchNextForward()を実行。こんどは、適当なキーワードを入力して、検索動作をさせます。その後、MIS_MigemoISearchClose()で、サーチを終了します。
    4. これで、大丈夫、のような気がする。


    こんな「儀式」が解決になっているかどうかは、甚だ心もとないところです。ハングが気になる方は、migemo-isearch.dllのVer0.1.3に戻すのも利口なやり方だと思います。しかし、0.1.3と0.1.4では、全然使用感が違うので、0.1.3のモタモタした感じは耐えられないかも。0.1.4では、検索キーワード入力と、検索動作を、別スレッドで動かすようになっていて、それで、あの素晴らしい使用感が得られているようです。しかし、このスレッドの調停の部分で、上記のようなハングが引き起こされているのでは、なんて、なまずは勝手に思っているのですが。いずれにしても、もはやなまずはmigemo-isearchがなかったら暮らしていけないので、もう少し、調査を続けたいと思います。
  • ※06/2/15追記
    tamanegiさんが、バージョンアップをしてくれました!
    現在の最新のバージョン ver0.1.5で、上記のハングアップの問題は、完全に解決しました。もう、へんな「儀式」は必要ありません。tamanegiさん、本当にありがとうございました。

さてさて、これで、AHKファンの方も、migemo-isearchが使えるようになったと思います。もう、なまずは完全にmigemo-isearchのトリコです。これがなくちゃ、もうWebブラウズはする気もおきないゼ、なんて感じです。
こんな素晴らしいツールをつくって頂いたtamanegiさん、またオリジナルmigemoの作者の高林哲さん、C/Migemoの作者KoRoNさん、mayuの作者TAGA nayutaさん、そして、なまずにmigemoという素晴らしいツールを教えてくれたmimiradiさんに、篤く感謝いたします。本当にありがとう。
mimiradiさんは、「エディタ・ブラウザのmigemo対応」は手放せない、と書いておられましたが、その意味がようやくわかりました。あなたのおかげで、なまずも、エディタ(xyzzy)、ブラウザ(Sleipnir)共に、migemo対応いたしました。確かにおっしゃる通り、手放せません。

本日のツッコミ(全2件) [ツッコミを入れる]
_ げんた (2008-03-14 [金] 19:18)

「[MIGEMO] I-search:」ウィンドウが開いているときに、<br>ブラウザ内のどこかにフォーカスが移ると、検索ワードの<br>入力待ちから抜けられなくなってしまいます。<br>とりあえず今は、自分でフォーカスを変えた場合については<br>以下のようにして逃げていますが、いい方法があれば<br>教えていただけませんか。<br><br>#IfWinActive ahk_class IEFrame<br>^s::MIS_IEMigemoISearchForward()<br><br>#IfWinActive ahk_class migemo-isearch<br>^s::MIS_MigemoISearchNextForward()<br><br>Esc::<br>AppsKey::<br>+f10::<br>MIS_MigemoISearchClose()<br>return<br><br>*LButton::<br>MIS_MigemoISearchClose()<br>MouseClick, Left<br>return<br><br>*RButton::<br>MIS_MigemoISearchClose()<br>MouseClick, Right<br>return<br>#IfWinActive

_ げんた (2008-03-14 [金] 19:28)

「[MIGEMO] I-search:」ウィンドウが開いているときに、<br>ブラウザ内のどこかにフォーカスが移ると、検索ワードの<br>入力待ちから抜けられなくなってしまいます。<br>とりあえず今は、自分でフォーカスを変えた場合については<br>以下のようにして逃げていますが、いい方法があれば<br>教えていただけませんか。<br><br>#IfWinActive ahk_class IEFrame<br>^s::MIS_IEMigemoISearchForward()<br><br>#IfWinActive ahk_class migemo-isearch<br>^s::MIS_MigemoISearchNextForward()<br><br>Esc::<br>AppsKey::<br>+f10::<br>MIS_MigemoISearchClose()<br>return<br><br>*LButton::<br>MIS_MigemoISearchClose()<br>MouseClick, Left<br>return<br><br>*RButton::<br>MIS_MigemoISearchClose()<br>MouseClick, Right<br>return<br>#IfWinActive

[]