2014年1月25日土曜日

GExpertsのMove to Matching Delimiter 機能

数日前、@_fm2さんが、ツイッターで

"DelphiのIDEで  begin 対する end を検索する、ショートカットなんぞはありませんか?"

とのつぶやかれてまた。

これ、IDEの標準機能では、出来なさそうだけど、GExperts のEditor Exports機能で
できます。

GExperts自体は、有名なツールなので、ご存知の方も多いと思います。

先ずは、GExpertsのインストール。

XE4までは、GExperts のサイトにインストーラがあるので、インストラーを使って
セットアップできます。

XE5は、残念ながら、インストーラがないので手動インストールが必要です。
インストール方法は、以下のとおりです。(Delphi XE5が必要です。)

1) SourceForgeのリポジトリからソースを入手します。

2) XE5用のプロジェクトを開きビルドします。
    ビルドすると、GExpertsRSXE5.dllができます。

3) レジストリ登録を行います。
 レジストリエディターで、

 HKEY_CURRENT_USER\Software\Embarcadero\BDS\12.0\Experts\

 に、文字列キーGExpertsを作成し、値にGExpertsRSXE5.dllをフルパスで
 設定します。

インストールに成功すれば、Delphi ( RadStudio )を起動するとメニューに
GExpertsが表示されます。

この状態で、Delphiのソースコードを開き"begin"のところにカーソルをあてて
[CTRL] + [ALT] + [右矢印キー]を押すと、対応する"end"に移動します。
この位置で、もう一回[CTRL] + [ALT] + [右矢印キー]を押すと、"begin"に
戻ります。(このショートカットキーは変更可能です。)

GExpertsのメニューから、Configurationを選択し、設定用のダイアログを開き、
Editor Expertsタブを選択し、Move to Matching Delimiterのところにカーソルを
あてると、機能の説明が確認できます。
説明には、

"  This expert enables you to quickly move to a matching beginning/ending delimiter for the following Delphi tokens: begin, try, case, repeat, for, with, while, asm, do, if, then, else, class, record, array, interface, implementation, uses, private, protected, public, published, until, end, try, finally, except, (/), and [/], .
  It also supports the following C++ tokens: {/}, (/), and [/]
The following steps are taken to match delimiters:
 - Beginning at the current cursor position, the expert looks to the left on the current line for a delimiter token such as "begin".
 - If a delimiter token is found, the expert scans for the matching token, such as "end" in the above instance.
 - If no delimiter is found to the left, as in the case "if|(i=0)" (where '|' represents the cursor), the expert attempts to find a delimiter token to the right of the current cursor position. In the mentioned example, this will identify the opening parenthesis, and an attempt is made to locate the closing parenthesis. "

とありますので、指定したトークンとペアになるトークンがあれば、その位置に
移動するようです。

試しに、try 〜 finally 〜 end で試した場合、finallyの位置でこの機能を使用した
場合の移動先は状況に依存するようでした。
(tryからはfinallyに、endからはfinallyにそれぞれ移動します。)

ソースも公開されてますので、GX_eFindDelimiter.pas等を書き換えれば
動きのカスタマイズも可能かと思います。