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 >
Text File  |  2001-12-09  |  14KB  |  545 lines

  1. // LF-Supplement.mac,tab = 4
  2. //=============================================================================
  3. // Name     : 文字列補完マクロ LF-Supplement
  4. // Version  : 1.0
  5. // Author   : Yusuke KOMORI
  6. // Date     : 2000.08.14(Mon) Version 0.0
  7. //            2000.10.28(Sat) Version 0.1
  8. //            2000.11.15(Wed) Version 0.1a 置換候補が正常に置換されない問題を
  9. //                                         を修正
  10. //            2001.02.03(Sat) Version 0.2  複数辞書ファイルをサポート
  11. //                                         ピリオドを含む単語の検索をサポート
  12. //            2001.11.22(Thu) Version 1.0  正式公開版
  13. //                                         拡張子毎に辞書を切り換えられるよう
  14. //                                         にした
  15. //                                         学習機能を追加
  16. //            2001.12.09(Sun) Version 1.01 大文字小文字を区別しないで検索する
  17. //                                         オプションを追加した
  18. //                                         学習辞書の保存先を指定可能にした
  19. //-----------------------------------------------------------------------------
  20. // Copyright: Original code by Yusuke Komori.
  21. //                 Copyright (c) 2000-2001. Yusuke Komori, All rights reserved.
  22. //=============================================================================
  23. $VERSION    = "LF-Supplement ver1.01";
  24. $COPY_RIGHT = "Copyright (c) 2000-2001. Yusuke Komori, All rights reserved.";
  25.  
  26. //----------------------------------------------
  27. // 初期設定
  28. //----------------------------------------------
  29. #MAX_CAN = 30;                        // 最大候補数
  30. #learningMode = true;                // 学習モード
  31. #learnLimit = -1;                    // 学習単語の最大数(-1 で制限なし)
  32. #DicNum = 0;                        // 読み込んだ補完辞書ファイルの数
  33. $DicName[0] = "";                    // 補完辞書ファイル名の配列
  34. $UserDicPrefix = "userdic_";        // ユーザ辞書名のプレフィックス
  35.  
  36. // 設定ファイル名
  37. $IniFileName = currentmacrodirectory + "\\LF-Supplement.ini";
  38.  
  39. //-------------------------------------------------------------
  40. // 正規表現のメタキャラクタ(この文字は単語の区切りと見なさない)
  41. //-------------------------------------------------------------
  42. $meta[0]  = "\\";
  43. $meta[1]  = "[";
  44. $meta[2]  = "]";
  45. $meta[3]  = "^";
  46. $meta[4]  = "$";
  47. $meta[5]  = "*";
  48. $meta[6]  = "+";
  49. $meta[7]  = "?";
  50. $meta[8] = "|";
  51. $meta[9] = ".";
  52. #metasize = 10;
  53.  
  54. call InitDengakuDLL;                // 田楽DLLの準備
  55. call ReadConfig $IniFileName;        // 設定の読み込み
  56.  
  57. // ユーザ辞書名の設定
  58. $UserDicName = $learnDicDir + "\\" + $UserDicPrefix + filetype;
  59.  
  60. disabledraw;
  61.  
  62. // カーソル位置保存
  63. #now_x = x;
  64. #now_y = y;
  65.  
  66. //マクロを起動した秀丸のウィンドウハンドルを記憶しておく
  67. #myhandle = hidemaruhandle(0);
  68.  
  69. // 補完対象単語の取得
  70. call GetWord;
  71. $word = $$return;
  72.  
  73. if (#IgnoreCase)
  74. {
  75.     // 大文字小文字を区別しない場合の正規表現を生成
  76.     call CreateIgnoreCaseRegexp $word;
  77.     $word = $$return;
  78. }
  79.  
  80. // 置換用辞書の作成
  81. call ReadDic;
  82. #dichandle = ##return;
  83.  
  84. // 補完候補の検索
  85. call SearchWord $word;
  86. ##num = ##return;
  87.  
  88. if (##num == 0)
  89. {
  90.     //補完候補が存在しなければ何もしない
  91.     goto EndProcess;
  92. }
  93.  
  94. // 候補をメニュー表示して結果をする
  95. if (!dllfunc("NEWMENU", "main")) goto ErrorProcess;
  96. ##i = 0;
  97. while (##i < ##num)
  98. {
  99.     if (!dllfunc("ADDMENUITEM", "main", $candidate[##i], "")) goto ErrorProcess;
  100.     ##i = ##i + 1;
  101. }
  102. $$s = dllfuncstr("MENU", "main", #myhandle);
  103.  
  104. if ($$s == "0" || $$s == "!")
  105. {
  106.     // キャンセル又はエラーの場合は終了
  107.     goto EndProcess;
  108. }
  109. else
  110. {
  111.     // 選択結果からインデックス番号を取得
  112.     ##sel = val(rightstr($$s, strlen($$s) - 5));
  113. }
  114.  
  115. $$replaceWord = $candidate[##sel-1];
  116.  
  117. // 選択された単語を学習
  118. if (#learningMode)
  119. {
  120.     call LearnWord $$replaceWord;
  121. }
  122.  
  123. // 選択された候補に置換する
  124. call PutWord $$replaceWord;
  125.  
  126. goto EndProcess;
  127.  
  128.  
  129. //-----------------------------------------------------------------------------
  130. // ■ 補完候補を検索する
  131. //    ※辞書ウィンドウに制御が移っていることが前提。
  132. // 
  133. // ●引数
  134. //   $$1            検索対象
  135. //   #MAX_CAN       補完候補の最大数
  136. // 
  137. // ●戻り値
  138. //   $candidateName 補完候補表示名称を格納した配列
  139. //   $candidate     補完候補を格納した配列
  140. //   ##return       見つかった候補の数
  141. //-----------------------------------------------------------------------------
  142. SearchWord:
  143.     
  144.     ##index = 0;
  145.     
  146.     // 検索バッファの設定
  147.     gofiletop;
  148.     
  149.     // 検索パターンは  ^(\t|文字列)
  150.     $$findRegexp = "^(\\t|" + $$1 + ")";
  151.     
  152.     while(1)
  153.     {
  154.         // 検索対象にマッチする文字列を検索
  155.         searchdown $$findRegexp, regular;
  156.         if (!result)
  157.         {
  158.             break;                        // 見つからなかった場合は終了
  159.         }
  160.         
  161.         // 見つかった文字列を取得
  162.         golinetop;
  163.         beginsel;
  164.         golineend;
  165.         $$str = gettext(seltopx, seltopy, selendx, selendy);
  166.         if ($$str == "\t")
  167.         {
  168.             if ((##index == 0) || ($candidate[##index - 1] == ""))
  169.             {
  170.                 // 最初の候補がタブか、前の後方がタブの場合は無視
  171.                 continue;
  172.             }
  173.             
  174.             // タブにマッチした場合は辞書の区切りなのでセパレータとする
  175.             $$str = "";
  176.         }
  177.         else if (#learningMode)
  178.         {
  179.             // 学習モードの場合は重複してマッチしないかチェック
  180.             ##pre_y = y;            // 現在位置を保存
  181.             up;
  182.             searchup "^" + $$str + "\n", regular;
  183.             if (result)
  184.             {
  185.                 // すでにマッチしている場合は候補に入れない
  186.                 moveto x, ##pre_y;    // カーソル位置復帰
  187.                 continue;
  188.             }
  189.             down;
  190.         }
  191.         
  192.         $candidate[##index] = $$str;
  193.         
  194.         ##index = ##index + 1;
  195.         
  196.         if (##index >= #MAX_CAN)
  197.         {
  198.             // 補完候補が最大候補数を超えたら終了
  199.             message "補完候補が多すぎるので検索を中止しました.";
  200.             break;
  201.         }
  202.     }
  203.     
  204.     if (##index > 0)
  205.     {
  206.         // 最後がセパレータになるのを防ぐ
  207.         while($candidate[##index - 1] == "")
  208.         {
  209.             ##index = ##index - 1;
  210.         }
  211.     }
  212.     
  213.     // 起動ウインドウへ制御を戻す
  214.     setactivehidemaru #myhandle;
  215.     return ##index;
  216.  
  217.  
  218. //-----------------------------------------------------------------------------
  219. // ■ 補完用辞書を読み込む
  220. //    ※読み込み後は、辞書ウィンドウに制御が移っている。
  221. // 
  222. // ●引数
  223. //   #DicNum   読み込む補完用辞書の数
  224. //   $DicName  読み込む補完用辞書ファイル名の配列
  225. //
  226. // ●戻り値
  227. //   #DicIndex 各辞書ファイルの開始行数配列
  228. //   ##return  補完用辞書のウィンドウハンドル
  229. //-----------------------------------------------------------------------------
  230. ReadDic:
  231.     
  232.     // 新規ファイルをステルスで開く
  233.     openfile "/h";
  234.     
  235.     // 辞書ファイルのウインドウハンドルを取得
  236.     ##dichandle = hidemaruhandle(0);
  237.     
  238.     insertline;            // 空行挿入(最初の1行は検索できないため)
  239.     
  240.     // 学習辞書の読み込み
  241.     if (#learningMode && existfile($UserDicName))
  242.     {
  243.         // 学習モードON で 学習ファイルが存在すれば読み込む
  244.         gofileend;
  245.         insertfile $UserDicName;
  246.         insert "\t\n";        // ファイルの境界を判断するための識別子
  247.     }
  248.     
  249.     // 置換用辞書の作成(定義されたファイルを連続して読み込む)
  250.     ##i = 0;
  251.     while (##i < #DicNum)
  252.     {
  253.         gofileend;
  254.         
  255.         $$dic = $DicName[##i];
  256.         if (!existfile($$dic))
  257.         {
  258.             message "辞書ファイルが存在しません\n" + $$dic;
  259.             setactivehidemaru ##myhandle;    // 起動ウインドウへ制御を戻す
  260.             closehidemaruforced ##dichandle;
  261.             goto ErrorProcess;
  262.         }
  263.         insertfile $$dic;
  264.         insert "\t\n";        // ファイルの境界を判断するための識別子
  265.         ##i = ##i + 1;
  266.     }
  267.     
  268.     // 最後の1行を削除
  269.     up;
  270.     deleteline;
  271.     
  272.     return ##dichandle;
  273.  
  274.  
  275. //-----------------------------------------------------------------------------
  276. // ■ ユーザ辞書に学習結果を書き込む
  277. //
  278. // ●引数
  279. //   $$1      書き込む単語
  280. //-----------------------------------------------------------------------------
  281. LearnWord:
  282.     openfile "/h " +$UserDicName;            // ユーザ辞書ファイルをオープン
  283.     ##userHandle = hidemaruhandle(0);        // ユーザ辞書のハンドルを記憶
  284.     
  285.     if(!readonly)
  286.     {
  287.         gofiletop;                            // 学習結果の書き込み
  288.         insertline;
  289.         insert $$1;
  290.         
  291.         // 単語が既にユーザ辞書に登録されている場合は削除する
  292.         while(1)
  293.         {
  294.             searchdown "^" + $$1 + "\n", regular;
  295.             if (!result)
  296.             {
  297.                 break;
  298.             }
  299.             deleteline;
  300.         }
  301.         
  302.         if ((#learnLimit > 0) && (linecount2 > #learnLimit))
  303.         {
  304.             // リミットを超えた単語は削除する
  305.             movetolineno 1, #learnLimit;
  306.             down;
  307.             beginsel;
  308.             gofileend;
  309.             delete;
  310.         }
  311.         
  312.         save;
  313.         setactivehidemaru #myhandle;        // 元の秀丸に戻る
  314.         closehidemaruforced ##userHandle;    // ユーザ辞書のクローズ
  315.     }
  316.     else
  317.     {
  318.         // ファイルが読み込み専用の場合
  319.         setactivehidemaru #myhandle;        // 元の秀丸に戻る
  320.         closehidemaruforced ##userHandle;    // ユーザ辞書のクローズ
  321.         message ("ユーザ辞書ファイルに書き込めません.\n" + $UserDicName);
  322.     }
  323.     
  324.     return;
  325.  
  326. //-----------------------------------------------------------------------------
  327. // ■ カーソル位置の単語を取得するサブルーチン
  328. //
  329. // ●戻り値
  330. //   $$return カーソル位置の単語
  331. //-----------------------------------------------------------------------------
  332. GetWord:
  333.     
  334.     // 現在のカーソル位置を保存
  335.     ##pre_x = x;
  336.     ##pre_y = y;
  337.     
  338.     // 単語の区切りと見なす文字を検索
  339.     searchup "([\"'(){} ]|\\t)", regular;
  340.     if (result)
  341.     {
  342.         // 見つかった場合
  343.         if (y == ##pre_y)
  344.         {
  345.             // 同一行である場合
  346.             right;
  347.             #start_x = x;
  348.             $$text = gettext(x, y, ##pre_x, ##pre_y);
  349.         }
  350.         else
  351.         {
  352.             // 同一行でない場合は論理行頭まで取得
  353.             #start_x = 0;
  354.         }
  355.     }
  356.     else
  357.     {
  358.         // 見つからなかった場合は論理行頭まで取得
  359.         #start_x = 0;
  360.     }
  361.     $$text = gettext(#start_x, ##pre_y, ##pre_x, ##pre_y);
  362.     
  363.     //カーソル位置復帰
  364.     moveto ##pre_x, ##pre_y;
  365.     
  366.     call ReplaceMetaStr $$text;    // 正規表現のメタキャラクタをエスケープしておく
  367.     
  368.     return $$return;
  369.  
  370.  
  371. //-----------------------------------------------------------------------------
  372. // ■ カーソル位置の単語を置換するサブルーチン
  373. //-----------------------------------------------------------------------------
  374. PutWord:
  375.     // 念のためカーソル位置復帰
  376.     moveto #now_x, #now_y;
  377.     disableinvert;
  378.     beginsel;                        // 選択開始
  379.     moveto #start_x, #now_y;        // 検索対象の先頭へ
  380.     insert $$1;
  381.     enableinvert;
  382.     return;
  383.  
  384.  
  385.  
  386. //-----------------------------------------------------------------------------
  387. // ■ 大文字小文字を区別しない正規表現を生成する
  388. //    文字列中の全ての半角アルファベットを [aA] のような正規表現に置換する
  389. // 
  390. // ●引数
  391. //   $$1      検索文字列
  392. //
  393. // ●戻り値
  394. //   $$return 生成した正規表現
  395. //-----------------------------------------------------------------------------
  396. CreateIgnoreCaseRegexp:
  397.     
  398.     $$1 = dllfuncstr("TOLOWER", $$1);    // あらかじめ全て小文字に変換しておく
  399.     // 全角文字も1文字とカウントして文字数をカウント
  400.     ##strlength = dllfunc("STRLEN2", $$1);
  401.     
  402.     $$retstr = "";
  403.     ##i = 0;
  404.     while (##i < ##strlength)
  405.     {
  406.         $$tempStr = dllfuncstr("MIDSTR2", $$1, ##i ,1);    // 1文字取り出し
  407.         ##asciiCode = ascii($$tempStr);
  408.         if ((0x61 <= ##asciiCode) && (##asciiCode <= 0x7a))
  409.         {
  410.             // 文字がa~zの範囲であれば正規表現生成
  411.             $$retstr = $$retstr +
  412.                         "[" + $$tempStr + char(##asciiCode - 0x20) + "]";
  413.         }
  414.         else
  415.         {
  416.             // それ以外の場合はそのまま
  417.             $$retstr = $$retstr + $$tempStr;
  418.         }
  419.         ##i = ##i + 1;
  420.     }
  421.     return $$retstr;
  422.  
  423.  
  424. //-----------------------------------------------------------------------------
  425. // ■ 正規表現のメタキャラクタをエスケープする
  426. //    田楽DLLを利用して、正規表現のメタキャラクタをエスケープしておく
  427. //
  428. // ●引数
  429. //   $$1      対象文字列
  430. //
  431. // ●戻り値
  432. //   $$return 置換結果
  433. //-----------------------------------------------------------------------------
  434. ReplaceMetaStr:
  435.     $$str = $$1;
  436.     
  437.     ##i = 0;
  438.     while(##i < #metasize)
  439.     {
  440.         $$str = dllfuncstr("GSUB", $$str, $meta[##i], "\\" + $meta[##i], -1);
  441.         ##i = ##i + 1;
  442.     }
  443.     
  444.     return $$str;
  445.  
  446.  
  447. //-----------------------------------------------------------------------------
  448. //■ コンフィグレーションのロード
  449. //   現在開いているファイルの拡張子を判断して設定を読み込む。
  450. // 
  451. // ●引数
  452. //   $$1          iniファイル名称
  453. // 
  454. // ●戻り値
  455. //   #DicNum      読み込んだ辞書の総数
  456. //   $DicName     読み込んだ辞書ファイル名の配列
  457. //-----------------------------------------------------------------------------
  458. ReadConfig:
  459.     
  460.     // iniファイル存在チェック
  461.     if (!existfile($$1))
  462.     {
  463.         message "iniファイルが存在しません.\n" + $$1;
  464.         return "";
  465.     }
  466.     
  467.     // 学習モード関連設定の読み込み
  468.     #learningMode = getininum($$1, "LearningSetting", "Mode");
  469.     ##isLimit = getininum($$1, "LearningSetting", "Limit");
  470.     if (##isLimit)
  471.     {
  472.         // 学習制限を行う場合
  473.         #learnLimit = getininum($$1, "LearningSetting", "LimitNum");
  474.     }
  475.     else
  476.     {
  477.         // 学習制限を行わない場合
  478.         #learnLimit = -1;
  479.     }
  480.     $learnDicDir = getinistr($$1, "LearningSetting", "LearnDicDir");
  481.     
  482.     // 検索時に大文字小文字を無視するかどうかを読み込み
  483.     #IgnoreCase = getininum($$1, "LearningSetting", "IgnoreCase");
  484.     
  485.     // 補完辞書ファイル名を取得
  486.     ##i = 0;
  487.     while (1)
  488.     {
  489.         $$name = getinistr($$1, filetype, str(##i));
  490.         if ($$name == "")
  491.         {
  492.             // これ以上存在しなければ終了
  493.             #DicNum = ##i;
  494.             break;
  495.         }
  496.         
  497.         $DicName[##i] = $$name;
  498.         ##i = ##i + 1;
  499.     }
  500.     
  501.     return;
  502.  
  503.  
  504. //-----------------------------------------------------------------------------
  505. // ■ 田楽DLLの利用準備
  506. //-----------------------------------------------------------------------------
  507. InitDengakuDLL:
  508.     if (1/2 == 0 && version < 309)
  509.     {
  510.         message "このマクロには秀丸の Ver.3.09 以降が必要です。";
  511.         endmacro;
  512.     }
  513.     
  514.     $$dllFileName = hidemarudir + "\\dengakudll.dll";
  515.     
  516.     // 田楽DLLのロード(すでにロードされている場合はロードしない)
  517.     if (loaddllfile != $$dllFileName)
  518.     {
  519.         loaddll($$dllFileName);
  520.         if (!result)
  521.         {
  522.             message "田楽DLL をロードできませんでした。";
  523.             endmacro;
  524.         }
  525.         
  526.     }
  527.     
  528.     return;
  529.  
  530.  
  531. //-----------------------------------------------------------------------------
  532. // ■ マクロ終了処理ルーチン
  533. //-----------------------------------------------------------------------------
  534. ErrorProcess:
  535.     message "処理中にエラーが発生しました.";
  536.     freedll;        // 念のため、DLLを破棄
  537.     
  538. EndProcess:
  539.     // 辞書ウインドウを閉じる
  540.     closehidemaruforced #dichandle;
  541.     enabledraw;
  542.     endmacro;
  543.  
  544. //===================================================== End of LF-Supplemnt.mac
  545.