home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2002 April
/
VPR0204A.ISO
/
OLS
/
LF-SUPPLEMENT101
/
lf-supplement101.lzh
/
LF-Supplement.mac
< prev
next >
Wrap
Text File
|
2001-12-09
|
14KB
|
545 lines
// LF-Supplement.mac,tab = 4
//=============================================================================
// Name : 文字列補完マクロ LF-Supplement
// Version : 1.0
// Author : Yusuke KOMORI
// Date : 2000.08.14(Mon) Version 0.0
// 2000.10.28(Sat) Version 0.1
// 2000.11.15(Wed) Version 0.1a 置換候補が正常に置換されない問題を
// を修正
// 2001.02.03(Sat) Version 0.2 複数辞書ファイルをサポート
// ピリオドを含む単語の検索をサポート
// 2001.11.22(Thu) Version 1.0 正式公開版
// 拡張子毎に辞書を切り換えられるよう
// にした
// 学習機能を追加
// 2001.12.09(Sun) Version 1.01 大文字小文字を区別しないで検索する
// オプションを追加した
// 学習辞書の保存先を指定可能にした
//-----------------------------------------------------------------------------
// Copyright: Original code by Yusuke Komori.
// Copyright (c) 2000-2001. Yusuke Komori, All rights reserved.
//=============================================================================
$VERSION = "LF-Supplement ver1.01";
$COPY_RIGHT = "Copyright (c) 2000-2001. Yusuke Komori, All rights reserved.";
//----------------------------------------------
// 初期設定
//----------------------------------------------
#MAX_CAN = 30; // 最大候補数
#learningMode = true; // 学習モード
#learnLimit = -1; // 学習単語の最大数(-1 で制限なし)
#DicNum = 0; // 読み込んだ補完辞書ファイルの数
$DicName[0] = ""; // 補完辞書ファイル名の配列
$UserDicPrefix = "userdic_"; // ユーザ辞書名のプレフィックス
// 設定ファイル名
$IniFileName = currentmacrodirectory + "\\LF-Supplement.ini";
//-------------------------------------------------------------
// 正規表現のメタキャラクタ(この文字は単語の区切りと見なさない)
//-------------------------------------------------------------
$meta[0] = "\\";
$meta[1] = "[";
$meta[2] = "]";
$meta[3] = "^";
$meta[4] = "$";
$meta[5] = "*";
$meta[6] = "+";
$meta[7] = "?";
$meta[8] = "|";
$meta[9] = ".";
#metasize = 10;
call InitDengakuDLL; // 田楽DLLの準備
call ReadConfig $IniFileName; // 設定の読み込み
// ユーザ辞書名の設定
$UserDicName = $learnDicDir + "\\" + $UserDicPrefix + filetype;
disabledraw;
// カーソル位置保存
#now_x = x;
#now_y = y;
//マクロを起動した秀丸のウィンドウハンドルを記憶しておく
#myhandle = hidemaruhandle(0);
// 補完対象単語の取得
call GetWord;
$word = $$return;
if (#IgnoreCase)
{
// 大文字小文字を区別しない場合の正規表現を生成
call CreateIgnoreCaseRegexp $word;
$word = $$return;
}
// 置換用辞書の作成
call ReadDic;
#dichandle = ##return;
// 補完候補の検索
call SearchWord $word;
##num = ##return;
if (##num == 0)
{
//補完候補が存在しなければ何もしない
goto EndProcess;
}
// 候補をメニュー表示して結果をする
if (!dllfunc("NEWMENU", "main")) goto ErrorProcess;
##i = 0;
while (##i < ##num)
{
if (!dllfunc("ADDMENUITEM", "main", $candidate[##i], "")) goto ErrorProcess;
##i = ##i + 1;
}
$$s = dllfuncstr("MENU", "main", #myhandle);
if ($$s == "0" || $$s == "!")
{
// キャンセル又はエラーの場合は終了
goto EndProcess;
}
else
{
// 選択結果からインデックス番号を取得
##sel = val(rightstr($$s, strlen($$s) - 5));
}
$$replaceWord = $candidate[##sel-1];
// 選択された単語を学習
if (#learningMode)
{
call LearnWord $$replaceWord;
}
// 選択された候補に置換する
call PutWord $$replaceWord;
goto EndProcess;
//-----------------------------------------------------------------------------
// ■ 補完候補を検索する
// ※辞書ウィンドウに制御が移っていることが前提。
//
// ●引数
// $$1 検索対象
// #MAX_CAN 補完候補の最大数
//
// ●戻り値
// $candidateName 補完候補表示名称を格納した配列
// $candidate 補完候補を格納した配列
// ##return 見つかった候補の数
//-----------------------------------------------------------------------------
SearchWord:
##index = 0;
// 検索バッファの設定
gofiletop;
// 検索パターンは ^(\t|文字列)
$$findRegexp = "^(\\t|" + $$1 + ")";
while(1)
{
// 検索対象にマッチする文字列を検索
searchdown $$findRegexp, regular;
if (!result)
{
break; // 見つからなかった場合は終了
}
// 見つかった文字列を取得
golinetop;
beginsel;
golineend;
$$str = gettext(seltopx, seltopy, selendx, selendy);
if ($$str == "\t")
{
if ((##index == 0) || ($candidate[##index - 1] == ""))
{
// 最初の候補がタブか、前の後方がタブの場合は無視
continue;
}
// タブにマッチした場合は辞書の区切りなのでセパレータとする
$$str = "";
}
else if (#learningMode)
{
// 学習モードの場合は重複してマッチしないかチェック
##pre_y = y; // 現在位置を保存
up;
searchup "^" + $$str + "\n", regular;
if (result)
{
// すでにマッチしている場合は候補に入れない
moveto x, ##pre_y; // カーソル位置復帰
continue;
}
down;
}
$candidate[##index] = $$str;
##index = ##index + 1;
if (##index >= #MAX_CAN)
{
// 補完候補が最大候補数を超えたら終了
message "補完候補が多すぎるので検索を中止しました.";
break;
}
}
if (##index > 0)
{
// 最後がセパレータになるのを防ぐ
while($candidate[##index - 1] == "")
{
##index = ##index - 1;
}
}
// 起動ウインドウへ制御を戻す
setactivehidemaru #myhandle;
return ##index;
//-----------------------------------------------------------------------------
// ■ 補完用辞書を読み込む
// ※読み込み後は、辞書ウィンドウに制御が移っている。
//
// ●引数
// #DicNum 読み込む補完用辞書の数
// $DicName 読み込む補完用辞書ファイル名の配列
//
// ●戻り値
// #DicIndex 各辞書ファイルの開始行数配列
// ##return 補完用辞書のウィンドウハンドル
//-----------------------------------------------------------------------------
ReadDic:
// 新規ファイルをステルスで開く
openfile "/h";
// 辞書ファイルのウインドウハンドルを取得
##dichandle = hidemaruhandle(0);
insertline; // 空行挿入(最初の1行は検索できないため)
// 学習辞書の読み込み
if (#learningMode && existfile($UserDicName))
{
// 学習モードON で 学習ファイルが存在すれば読み込む
gofileend;
insertfile $UserDicName;
insert "\t\n"; // ファイルの境界を判断するための識別子
}
// 置換用辞書の作成(定義されたファイルを連続して読み込む)
##i = 0;
while (##i < #DicNum)
{
gofileend;
$$dic = $DicName[##i];
if (!existfile($$dic))
{
message "辞書ファイルが存在しません\n" + $$dic;
setactivehidemaru ##myhandle; // 起動ウインドウへ制御を戻す
closehidemaruforced ##dichandle;
goto ErrorProcess;
}
insertfile $$dic;
insert "\t\n"; // ファイルの境界を判断するための識別子
##i = ##i + 1;
}
// 最後の1行を削除
up;
deleteline;
return ##dichandle;
//-----------------------------------------------------------------------------
// ■ ユーザ辞書に学習結果を書き込む
//
// ●引数
// $$1 書き込む単語
//-----------------------------------------------------------------------------
LearnWord:
openfile "/h " +$UserDicName; // ユーザ辞書ファイルをオープン
##userHandle = hidemaruhandle(0); // ユーザ辞書のハンドルを記憶
if(!readonly)
{
gofiletop; // 学習結果の書き込み
insertline;
insert $$1;
// 単語が既にユーザ辞書に登録されている場合は削除する
while(1)
{
searchdown "^" + $$1 + "\n", regular;
if (!result)
{
break;
}
deleteline;
}
if ((#learnLimit > 0) && (linecount2 > #learnLimit))
{
// リミットを超えた単語は削除する
movetolineno 1, #learnLimit;
down;
beginsel;
gofileend;
delete;
}
save;
setactivehidemaru #myhandle; // 元の秀丸に戻る
closehidemaruforced ##userHandle; // ユーザ辞書のクローズ
}
else
{
// ファイルが読み込み専用の場合
setactivehidemaru #myhandle; // 元の秀丸に戻る
closehidemaruforced ##userHandle; // ユーザ辞書のクローズ
message ("ユーザ辞書ファイルに書き込めません.\n" + $UserDicName);
}
return;
//-----------------------------------------------------------------------------
// ■ カーソル位置の単語を取得するサブルーチン
//
// ●戻り値
// $$return カーソル位置の単語
//-----------------------------------------------------------------------------
GetWord:
// 現在のカーソル位置を保存
##pre_x = x;
##pre_y = y;
// 単語の区切りと見なす文字を検索
searchup "([\"'(){} ]|\\t)", regular;
if (result)
{
// 見つかった場合
if (y == ##pre_y)
{
// 同一行である場合
right;
#start_x = x;
$$text = gettext(x, y, ##pre_x, ##pre_y);
}
else
{
// 同一行でない場合は論理行頭まで取得
#start_x = 0;
}
}
else
{
// 見つからなかった場合は論理行頭まで取得
#start_x = 0;
}
$$text = gettext(#start_x, ##pre_y, ##pre_x, ##pre_y);
//カーソル位置復帰
moveto ##pre_x, ##pre_y;
call ReplaceMetaStr $$text; // 正規表現のメタキャラクタをエスケープしておく
return $$return;
//-----------------------------------------------------------------------------
// ■ カーソル位置の単語を置換するサブルーチン
//-----------------------------------------------------------------------------
PutWord:
// 念のためカーソル位置復帰
moveto #now_x, #now_y;
disableinvert;
beginsel; // 選択開始
moveto #start_x, #now_y; // 検索対象の先頭へ
insert $$1;
enableinvert;
return;
//-----------------------------------------------------------------------------
// ■ 大文字小文字を区別しない正規表現を生成する
// 文字列中の全ての半角アルファベットを [aA] のような正規表現に置換する
//
// ●引数
// $$1 検索文字列
//
// ●戻り値
// $$return 生成した正規表現
//-----------------------------------------------------------------------------
CreateIgnoreCaseRegexp:
$$1 = dllfuncstr("TOLOWER", $$1); // あらかじめ全て小文字に変換しておく
// 全角文字も1文字とカウントして文字数をカウント
##strlength = dllfunc("STRLEN2", $$1);
$$retstr = "";
##i = 0;
while (##i < ##strlength)
{
$$tempStr = dllfuncstr("MIDSTR2", $$1, ##i ,1); // 1文字取り出し
##asciiCode = ascii($$tempStr);
if ((0x61 <= ##asciiCode) && (##asciiCode <= 0x7a))
{
// 文字がa~zの範囲であれば正規表現生成
$$retstr = $$retstr +
"[" + $$tempStr + char(##asciiCode - 0x20) + "]";
}
else
{
// それ以外の場合はそのまま
$$retstr = $$retstr + $$tempStr;
}
##i = ##i + 1;
}
return $$retstr;
//-----------------------------------------------------------------------------
// ■ 正規表現のメタキャラクタをエスケープする
// 田楽DLLを利用して、正規表現のメタキャラクタをエスケープしておく
//
// ●引数
// $$1 対象文字列
//
// ●戻り値
// $$return 置換結果
//-----------------------------------------------------------------------------
ReplaceMetaStr:
$$str = $$1;
##i = 0;
while(##i < #metasize)
{
$$str = dllfuncstr("GSUB", $$str, $meta[##i], "\\" + $meta[##i], -1);
##i = ##i + 1;
}
return $$str;
//-----------------------------------------------------------------------------
//■ コンフィグレーションのロード
// 現在開いているファイルの拡張子を判断して設定を読み込む。
//
// ●引数
// $$1 iniファイル名称
//
// ●戻り値
// #DicNum 読み込んだ辞書の総数
// $DicName 読み込んだ辞書ファイル名の配列
//-----------------------------------------------------------------------------
ReadConfig:
// iniファイル存在チェック
if (!existfile($$1))
{
message "iniファイルが存在しません.\n" + $$1;
return "";
}
// 学習モード関連設定の読み込み
#learningMode = getininum($$1, "LearningSetting", "Mode");
##isLimit = getininum($$1, "LearningSetting", "Limit");
if (##isLimit)
{
// 学習制限を行う場合
#learnLimit = getininum($$1, "LearningSetting", "LimitNum");
}
else
{
// 学習制限を行わない場合
#learnLimit = -1;
}
$learnDicDir = getinistr($$1, "LearningSetting", "LearnDicDir");
// 検索時に大文字小文字を無視するかどうかを読み込み
#IgnoreCase = getininum($$1, "LearningSetting", "IgnoreCase");
// 補完辞書ファイル名を取得
##i = 0;
while (1)
{
$$name = getinistr($$1, filetype, str(##i));
if ($$name == "")
{
// これ以上存在しなければ終了
#DicNum = ##i;
break;
}
$DicName[##i] = $$name;
##i = ##i + 1;
}
return;
//-----------------------------------------------------------------------------
// ■ 田楽DLLの利用準備
//-----------------------------------------------------------------------------
InitDengakuDLL:
if (1/2 == 0 && version < 309)
{
message "このマクロには秀丸の Ver.3.09 以降が必要です。";
endmacro;
}
$$dllFileName = hidemarudir + "\\dengakudll.dll";
// 田楽DLLのロード(すでにロードされている場合はロードしない)
if (loaddllfile != $$dllFileName)
{
loaddll($$dllFileName);
if (!result)
{
message "田楽DLL をロードできませんでした。";
endmacro;
}
}
return;
//-----------------------------------------------------------------------------
// ■ マクロ終了処理ルーチン
//-----------------------------------------------------------------------------
ErrorProcess:
message "処理中にエラーが発生しました.";
freedll; // 念のため、DLLを破棄
EndProcess:
// 辞書ウインドウを閉じる
closehidemaruforced #dichandle;
enabledraw;
endmacro;
//===================================================== End of LF-Supplemnt.mac