|
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"エディタで代入の反転処理"
Delphi のエディタでクリップボードを使用して代入の反転を行います。
Abc.Value := Efg; ---> Efg := Abc.Value;
上記のように左辺と右辺の入れ換えをします。
複数行の処理も一度に出来ます。代入以外のコードはそのままです。
Delphi5 での動作確認しか行っていませんので、以前のバージョンで試す場合
は Delphi が暴走する可能性を覚悟してやってください^^;
といっても、クリップボードを使用しているだけなんで動作すると思います。
なお、Delphi へのショートカット登録は nifty:FDELPHI/MES/08/10902
「Satobe さん」のご発言をそのまま利用させていただきましたm(__)m
ゴリゴリとコーディングしてしまったのであんまり奇麗じゃないですけど、似
たような機能のものが見当たらないのでアップしました。
気づいたことがありましたらレス頂ければと思います。
使用方法
以下のユニットを設計時パッケージのコンポーネントとして追加します。
Ctrl+C で元のソースをクリップボードにコピーして、Ctrl+D でクリップボー
ド内の代入を反転、貼り付けたい場所に移動して Ctrl+V すれば反転したソー
スがペーストされます。
Ctrl+D のショートカットを変更したい場合は、*1 を変更してください。
------------------------------------------ 以下 ソース
unit SbstTurn;
interface
procedure Register;
implementation
uses Windows, Classes, SysUtils, ToolsAPI, Menus, Clipbrd;
type
TSbstTurnModule = class(TNotifierObject, IUnknown, IOTANotifier,
IOTAKeyboardBinding)
procedure SbstTurn(const Context: IOTAKeyContext;
KeyCode: TShortCut; var BindingResult: TKeyBindingResult);
function GetBindingType: TBindingType;
function GetDisplayName: string;
function GetName: string;
procedure BindKeyboard(const BindingServices: IOTAKeyBindingServices);
end;
procedure Register;
begin
(BorlandIDEServices as IOTAKeyBoardServices).
AddKeyboardBinding(TSbstTurnModule.Create);
end;
{ TSbstTurnModule }
procedure TSbstTurnModule.BindKeyboard(
const BindingServices: IOTAKeyBindingServices);
begin
BindingServices.AddKeyBinding([ShortCut(Ord('D'), [ssCtrl])], // *1
SbstTurn, nil); // ↑ショートカットの変更はここを修正
end;
function TSbstTurnModule.GetBindingType: TBindingType;
begin
Result := btPartial;
end;
function TSbstTurnModule.GetDisplayName: string;
begin
Result := 'Ctrl+''D''で代入式を反転';
end;
function TSbstTurnModule.GetName: string;
begin
Result := 'QZF12401.SbstTurnModule';
end;
procedure TSbstTurnModule.SbstTurn(const Context: IOTAKeyContext;
KeyCode: TShortCut; var BindingResult: TKeyBindingResult);
var
BaseText, TurnText, LeftText, RightText: string;
i, j, LeftPos, LeftLen, RightPos, RightLen: Integer;
Eot, Notsp, QuoteFnd: Boolean;
function LeftWordFound(WordPos: Integer ; WordText: string): Boolean;
var
WordLen: Integer;
begin
WordLen := Length(WordText);
if (WordPos > WordLen - 1)
and (Copy(BaseText, WordPos - WordLen + 1, WordLen) = WordText) then
if (BaseText[WordPos + 1] in [#10, #13, ' '])
and ((WordPos = WordLen)
or (BaseText[WordPos - WordLen] in [#10, #13, ' '])) then
Result := True
else
Result := False
else
Result := False;
end;
function RightWordFound(WordPos: Integer ; WordText: string): Boolean;
var
WordLen: Integer;
begin
WordLen := Length(WordText);
if (WordPos < Length(BaseText) - WordLen + 2)
and (Copy(BaseText, WordPos, WordLen) = WordText) then
if ((WordPos + WordLen > Length(BaseText))
or (BaseText[WordPos + WordLen] in [#10, #13, ' ', ';', '.']))
and (BaseText[WordPos - 1] in [#10, #13, ' ']) then
Result := True
else
Result := False
else
Result := False;
end;
begin
TurnText := Clipboard.AsText;
BaseText := UpperCase(TurnText);
// 代入文の反転処理(Pascal)
i := 2;
while i < Length(BaseText) - 1 do
begin
if (BaseText[i] = ':') and (BaseText[i + 1] = '=') then
begin
// 左側の文字列を検出
j := i - 1;
Eot := False;
Notsp := False;
QuoteFnd := False;
LeftLen := 0;
while (j > 0) and (not Eot) do
begin
if BaseText[j] = '''' then QuoteFnd := not QuoteFnd;
if (not Notsp) and not (BaseText[j] in [#10, #13, ' ']) then
Notsp := True;
if Notsp then
begin
if not QuoteFnd then
case BaseText[j] of
':', ';' : Eot := True;
'O' :
if LeftWordFound(j, 'DO') then Eot := True;
'N' :
if LeftWordFound(j, 'THEN')
or LeftWordFound(j, 'BEGIN') then Eot := True;
'Y' :
if LeftWordFound(j, 'TRY')
or LeftWordFound(j, 'FINALLY') then Eot := True;
'T' :
if LeftWordFound(j, 'REPEAT')
or LeftWordFound(j, 'EXCEPT') then Eot := True;
end;
Inc(LeftLen);
end;
Inc(j, -1);
end;
if j = 0 then j := 1
else
begin
Inc(j, 2);
Inc(LeftLen, -1);
end;
Notsp := False;
while (j < i) and (not Notsp) do
begin
if not (BaseText[j] in [#10, #13, ' ']) then Notsp := True
else
begin
Inc(LeftLen, -1);
Inc(j);
end;
end;
LeftPos := j;
// 右側の文字列を検出
j := i + 2;
Eot := False;
Notsp := False;
QuoteFnd := False;
RightPos := j;
RightLen := 0;
while (j < Length(BaseText)) and (not Eot) do
begin
if BaseText[j] = '''' then QuoteFnd := not QuoteFnd;
if (not Notsp) and not (BaseText[j] in [#10, #13, ' ']) then
begin
RightPos := j;
Notsp := True;
end;
if Notsp then
begin
if not QuoteFnd then
case BaseText[j] of
';' : Eot := True;
'E' :
if RightWordFound(j, 'END')
or RightWordFound(j, 'EXCEPT') then
Eot := True;
'U' :
if RightWordFound(j, 'UNTIL') then
Eot := True;
'F' :
if RightWordFound(j, 'FINALLY') then
Eot := True;
end;
Inc(RightLen);
end;
Inc(j);
end;
Inc(j, -2);
Inc(RightLen, -1);
Notsp := False;
while (j > i + 2) and (not Notsp) do
begin
if not (BaseText[j] in [#10, #13, ' ']) then Notsp := True
else
begin
Inc(RightLen, -1);
Inc(j, -1);
end;
end;
// 左右文字列の入れ換え
if (LeftLen < 1) or (RightLen < 1) then Exit;
RightText := Copy(TurnText, RightPos, RightLen);
LeftText := Copy(TurnText, LeftPos, LeftLen);
Delete(TurnText, RightPos, RightLen);
Insert(LeftText, TurnText, RightPos);
Delete(TurnText, LeftPos, LeftLen);
Insert(RightText, TurnText, LeftPos);
i := RightPos + RightLen + 1;
end
else
Inc(i);
end;
// 加工後の string をクリップボードに書き込む
Clipboard.AsText := TurnText;
end;
end.
------------------------------------------------ ここまで
2000/01/07(金) 10:42am Ohtaka(QZF12401)
Original document by Ohtaka 氏 ID:(QZF12401)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|