さいごに閉じたファイル を参照する

2019年4月28日 (日) 11:01時点におけるSukemaru (トーク | 投稿記録)による版

ファイルメニュー では「最近開いたファイルの履歴」が表示されますが、現在開いているファイルばかりが表示されてしまいがちです。

このマクロ(組み込み関数)では、Mery.ini ファイルに記録されている「最近開いたファイルの履歴」ではなく、 Mery.his ファイルに記録されている履歴情報を読み込み、「現在開いているファイル」を除いて、後ろから順にファイルパスを取得します。

  • Mery の「オプション」設定の「履歴」グループで「カーソル位置とブックマークを保存する」が無効の場合は、Mery.his ファイルを参照できないので "" を返します。
  • 通常の操作でタブを閉じず、「すべて閉じる」マクロなどでタブを閉じた場合、Mery.his ファイルの並び順が「保存された順 または 閉じた順」にならないことがあるので、このマクロで取得できる履歴の順番の正確さについては保証できません。


組み込み関数 LatestClosedFile()

includeライブラリ を導入(#include "include/IO.js" #include "include/MryInfo.js")したマクロで利用する前提なら前半部分「Mery.his をさがす」「Mery.his を読み込む」のコードを圧縮することもできますが、あえて include なしで使えるようにしてあります(処理手続きはおなじなので、処理速度に差はないとおもいます)。

 
// #title = "さいごに閉じたファイル"
// #tooltip = "「さいごに閉じたファイル」のフルパスを返す"

/**
 * 関数 LatestClosedFile( num )
 * Mery.his を読み込んで「さいごに閉じたファイル」のフルパスを返す
 * 
 * 引数 num: 「さいごに閉じたファイル」の件数を指定
 *     1 を指定した場合または省略した場合は、1件のフルパスを文字列で返す
 *     2 以上の数値を指定した場合は、配列で返す
 *       
 * ※ Mery の「オプション」設定で「カーソル位置とブックマークを保存する」
 *   が無効(Mery.his がない)なら "" を返す
 * ※ Mery.his を下から順にチェックするだけなので
 *   マクロなどで閉じられたファイルは Mery.his の並び順に反映されていないことがあるかも
 */

function LatestClosedFile( num ) {
  var start = new Date();	// 所要時間計測(開始)
  var closedFile = "";
  var closedFileArray = [];
  var num = num ? num : 1;

  // Mery.his をさがす
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  var meryhis = editor.FullName.replace( /\.exe$/i , ".his" );
  if ( ! Fso.FileExists( meryhis ) ) {
    meryhis = new ActiveXObject( "WScript.Shell" )
              .ExpandEnvironmentStrings( "%APPDATA%" )
            + "\\Mery\\Mery.his";
  }
  if ( ! Fso.FileExists( meryhis ) ) {
    return closedFile;
  }

  // Mery.his を読みこむ
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText;
  Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( meryhis );
  var hisText = Adodb.ReadText( adReadAll ).replace( /\r\n?/g, "\n" );
  Adodb.Close();

  // Mery.his からファイルパスを抽出する
  var hisArray = hisText.match( /^\[.+\]$/gm );

  var hCount = hisArray.length;
  if ( ! hCount ) {
    return closedFile;
  }

  // 履歴のファイルパスをうしろから順にチェックして
  // 現在開いているファイルにないものを「さいごに閉じたファイル」とする

  hisArray.reverse();
  var eCount = Editors.Count, dCount, cCount;
  for ( var i = 0; i < hCount || cCount < num; i ++ ) {
    closedFile = hisArray[i].replace( /^\[|\]$/g, "" );
    for ( var ee = 0, hit; ee < eCount; ee ++ ) {
      dCount = Editors.Item( ee ).Documents.Count;
      for ( var dd = 0, hit = 0; dd < dCount; dd ++ ) {
        file = Editors.Item( ee ).Documents.Item( dd ).FullName;
        if ( closedFile == file ) {
          hit ++;
        }
      }
      cCount = closedFileArray.length;
      if ( ! hit && cCount < num
           && ( ! cCount || closedFile != closedFileArray[ cCount-1 ] )
           && Fso.FileExists( closedFile ) ) {
        closedFileArray.push( closedFile );
      }
    }
  }

  Status = "  [ " + ( ( new Date() - start ) / 1000 ).toFixed( 3 ) + " 秒 ]";;
  return num == 1 ? closedFileArray[0] : closedFileArray;
}


使い方

 
/* 例1. 「さいごに閉じたファイル」を3件 取得する */

var _latestClosed3 = LatestClosedFile( 3 );

OutputBar.Writeln( "さいごに閉じたファイル: \n" + latestClosed3 );

Alert( "さいごに閉じたファイル: \n\n" + latestClosed3.join( "\n" ) );
 
/* 例2. 「さいごに閉じたファイル」5件 をポップアップメニューに表示する */

var _latestClosed5 = LatestClosedFile( 5 );

var menu = CreatePopupMenu();
menu.Add( "▼ さいごに閉じたファイル ▼", 0, meMenuGrayed );

for ( var i = 0; i < _latestClosed5.length; i ++ ) {
  // 「親フォルダ名\ ファイル名」に切りつめる
  menu.Add( "&" + ( i + 1 ) + ":  " + _latestClosed5[i].replace( /(?:.+\\)*([^\\]+\\)([^\\]+)$/, "$1 $2" ), i + 1 )
}

// ※ LatestClosedFile() または LatestClosedFile( 1 ) であれば
// 戻り値は配列ではなくフルパスの文字列だけなので
// menu.Add( "&1:  " + LatestClosedFile().replace( /(?:.+\\)*([^\\]+\\)([^\\]+)$/, "$1 $2" ), 1 );

var r = menu.Track( mePosMouse );
if ( r > 0 ) {
  editor.NewFile();
  editor.OpenFile( _latestClosed5[ r - 1 ] );

  // ※ LatestClosedFile() または LatestClosedFile( 1 ) であれば
  // editor.OpenFile( LatestClosedFile() );
}
スポンサーリンク