「ファイルを読み直す・開きなおす」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
(更新版をアップロード)
 
926行目: 926行目:
 
: また、include 版では「フォルダにコピー」コマンドでのターゲットフォルダのデフォルト設定を変更できます(初期値は <q>デスクトップ</q>)。
 
: また、include 版では「フォルダにコピー」コマンドでのターゲットフォルダのデフォルト設定を変更できます(初期値は <q>デスクトップ</q>)。
 
: ※ ソースコードのデフォルト状態では、外部の実行ファイルは使用せず、[https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/copyfile-method WSH の機能]でファイルをコピーするようにしてあります。 同名ファイルがあるばあいは上書き確認のダイアログを表示しますが、書き込み先のファイル/フォルダの状態によっては上書きコピーできないことがあります。
 
: ※ ソースコードのデフォルト状態では、外部の実行ファイルは使用せず、[https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/copyfile-method WSH の機能]でファイルをコピーするようにしてあります。 同名ファイルがあるばあいは上書き確認のダイアログを表示しますが、書き込み先のファイル/フォルダの状態によっては上書きコピーできないことがあります。
 
+
<br>
 +
* ソースコード内の「'''外部リソース設定'''」の項目を変更してからマクロを実行して「JSON ファイルを開く」コマンドで設定状態を確認しても、設定ファイルの内容は変更前の状態のままになります。 [[#SS3|確認ダイアログ]] で設定状態をチェックしたい場合は、一度「無題」のタブをアクティブにして「設定を初期化する」コマンドを実行してください。
 +
: ※「無題」以外のタブで「設定を初期化」すると <source lang="javascript" inline>"toolCopyOptions"</source> のコマンドライン引数部分にアクティブタブのファイルパスが書き込まれます (じっさいに「フォルダにコピー」を実行したときには JSON ファイルに書き込まれたパスではなく、アクティブタブの実体ファイルがコピーされますので、支障をきたすことはありません)。
 +
<br><br>
  
 
=== ソースコード ===
 
=== ソースコード ===
2,502行目: 2,505行目:
  
 
機能を盛りすぎてマクロの処理速度が遅くなってしまいましたが、2回目以降は 0.1 秒程度でポップアップメニューが表示されるようなので、許容範囲内として様子見…。
 
機能を盛りすぎてマクロの処理速度が遅くなってしまいましたが、2回目以降は 0.1 秒程度でポップアップメニューが表示されるようなので、許容範囲内として様子見…。
<br>
+
<br><br>
 
+
<b id="SS3">JSON ファイルを確認ダイアログのスクリーンショット</b>
----
 
*
 
*
 
  
 +
[[ファイル:ファイルを読み直す・開きなおす JSON.png|link=]]
 
<br><br>
 
<br><br>
 
<div id="END"> [[#include版|>> include版 の先頭へ]] </div>
 
<div id="END"> [[#include版|>> include版 の先頭へ]] </div>
 
[[#TOP|>> ページの先頭へ]]
 
[[#TOP|>> ページの先頭へ]]
 +
<br><br>
 +
 +
----
 +
* 
 +
* 
 +
  
 
<!--  
 
<!--  
 
[[ファイル:ファイルを読み直す・開きなおす.png]]
 
[[ファイル:ファイルを読み直す・開きなおす.png]]
 
[[ファイル:ファイルを読み直す・開きなおす【自家用版】.png]]
 
[[ファイル:ファイルを読み直す・開きなおす【自家用版】.png]]
 +
[[ファイル:ファイルを読み直す・開きなおす JSON.png]]
 
[[ファイル:ファイルを読み直す・開きなおす.zip]]
 
[[ファイル:ファイルを読み直す・開きなおす.zip]]
 
  -->
 
  -->

2019年11月30日 (土) 17:32時点における最新版


「読みなおす・開きなおす」ポップアップメニュー[編集]

標準ツールバーの「読み直し」アイコン(ファイル メニューの「読み直し」コマンド)のポップアップメニューを再現します。
Mery 本体のメニュー項目にはない ファイル操作に関する色々な機能 を追加してあります。


エンコード指定 の選択肢のほかに以下の機能を追加してあります。

  • Mery の 書き換え禁止 フラグ ON/OFF の変更
  • 読み取り専用属性 ON/OFF の変更(ファイルを開きなおす)
  • ファイルを 閉じて開きなおす
  • 編集モードの設定」パネルを開く
  • 編集モード」を変更するサブメニュー (不要な編集モードは非表示に)
  • ファイルの「プロパティ」を開く
  • さいごに閉じたファイル (最近 閉じたファイル)」を開く
  • 自動保存フォルダバックアップフォルダを開く(Mery ver 2.6.9 以上)
  • 親フォルダ、Mery フォルダ、データフォルダ等を開く
  • エンコード変更の読みなおし後に元のテキストを貼り付け (追加オプション)
  • 「編集モード」の状態を Mery.ini から読みこみ (追加オプション)
  • 「さいごに閉じたファイル」から自動保存・バックアップファイルを除外する設定を追加
  • アクティブタブのファイルや親フォルダのパス、Mery.exe、Mery フォルダ等の「パスをコピー
  • 実体ファイルを「デスクトップにコピー」または「任意のフォルダにコピー
  • 新規タブで開く」「メモ帳で開く
  • Mery.ini を開く」「Mery.txt を開く


ポップアップメニューのスクリーンショット (2019/11/30)

ファイルを読み直す・開きなおす.png


仕様上の制限[編集]

  • Mery ver 2.6.15 まででは、「読みなおし」や「書き換え禁止にする」を実行すると、ブックマークが消えてしまいます(Mery 本体側の仕様なので、ファイルメニューや編集メニューの標準コマンドでも同様にブックマークが消えます)。
  • ファイルを「開きなおす」場合は、タブの並び順のさいごの位置に開きます。
    また、開きなおしたファイルは、拡張子ごとの既定の「編集モード」になります。
  • 「無題」ドキュメントでは読み直しやエンコード指定ができないので、「編集モード サブメニュー」と「さいごに閉じたファイル」だけを表示します。
  • 「編集モード サブメニュー」は、「編集モードの設定」にあるアイテムと並び順を Mery.ini から取得することもできますが、ソースコードの編集(並び替え・添削)により自分に必要なアイテムだけを表示させることができます。
※ アクセラレータの重複でトグル移動してしまうときは、Enter キーで確定するか、ソースコード内でアクセラレータ( & 記号の位置や (&X) のアルファベット部分)を変更してください。
  • documenteditor.ActiveDocument にしたので、ツールバーやメニューから実行する場合は、アウトプットバーにフォーカスがあるときでも動作するはず?(ショートカットキーでの実行は無理かも)
  • エディタの設定で タブが無効 または タブの「閉じるボタン」を表示していない 場合は、閉じたときに Mery (のウインドウ)が終了してしまい、マクロが中断されてしまうので開きなおしができません。
    また、「読み取り専用属性」の変更もできません。
→ エディタの状態をチェックして、実行できないコマンドは適宜グレーアウトまたは非表示にします。
  • さいごに閉じたファイル」メニューを表示できるのは、Mery 本体の [ オプション ] 設定 >> 履歴 カテゴリ >> 「カーソル位置とブックマークを保存する」が有効で、本マクロの設定項目「ファイル・フォルダ サブメニュー」が有効の場合のみです。
※ Mery 本体(エディタエンジン)の仕様上、「キャレット位置が文書の先頭」×「ブックマークなし」×「横書き表示」で閉じたファイルは、Mery を終了したときに Mery.his から記録が削除されます。履歴に残したいファイルを閉じるさいは、キャレットの位置を文頭からズラすか、任意の行にブックマークをつけておくようにしてください。
  • 「自動保存/バックアップフォルダ」の設定を Mery.ini から読みとるため、Mery の「オプション」設定の「自動保存」でフォルダパスが指定されていて、フォルダの実在確認ができるなら、「自動保存/バックアップ」の有効/無効によらずポップアップメニュー内にコマンドを表示します。
→ 「自動保存/バックアップ」の 有効/無効 の設定状態により非表示またはグレーアウトするように変更しました。


ダウンロード[編集]

ファイルを読み直す・開きなおす.zip」(アイコン入り)
最終更新: 2019/11/30


ソースコード[編集]

#title = "ファイルを読み直す・開きなおす..."
#tooltip = "エンコード指定/読み取り専用属性/編集モードの変更"
#icon = "reload.ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",262

var start = new Date();	// 所要時間計測(開始)

/**
 * ---------------------------------------------------------
 * ファイルを読み直す・開きなおす
 * sukemaru (2019/03/29 - 2019/11/30)
 * ---------------------------------------------------------
 */

// ---------- ▼ 設定項目 ▼ ---------- //

// ■「編集モード」を Mery.ini から自動で取得する
var viewModeAutoSerchEnable = false;

// ■諸外国語用(UTF-** とシフトJIS 以外)の文字コードを表示する
var variousLanguageEnable = true;

// ■エンコードを変更して読みなおししたとき変更前のテキストを貼り付けする
var pasteAfterReload = false;

// ■「さいごに閉じたファイル」の件数
var numLatestClosed = 5;

// ■「さいごに閉じたファイル」に自動保存・バックアップフォルダのファイルを含めない
var woAutoSaved = false;

// ■ ポップアップメニューを表示する位置
var menuPosMouse = true;

// ---------- ▲ 設定項目 ▲ ---------- //


var Fso			= new ActiveXObject( "Scripting.FileSystemObject" );
var WshShell	= new ActiveXObject( "WScript.Shell" );
var d			= editor.ActiveDocument;
var fullPath	= Fso.FileExists( d.FullName ) ? d.FullName : "";
var desktopDir	= WshShell.SpecialFolders( "Desktop" );
var currentDir	= WshShell.CurrentDirectory;

// Mery フォルダとデータフォルダ
var meryPath	= editor.FullName;
var mery		= Fso.GetBaseName( meryPath );
var meryDir		= Fso.GetParentFolderName( meryPath ) + "\\";
var profileDir	= meryDir;
var iniPath		= meryDir + mery + ".ini";
var hisPath		= meryDir + mery + ".his";
if ( ! Fso.FileExists( iniPath ) ) {
  profileDir	= WshShell.SpecialFolders( "APPDATA" ) + "\\Mery\\";
  iniPath		= profileDir + mery + ".ini";
  hisPath		= profileDir + mery + ".his";
}
var profileDirExist = ( profileDir != meryDir );
var meryVer	 = + ( editor.Version.replace( /[0-9]+/g , function( digit ) {
                     return digit.length < 2 ? "0" + digit : digit
                 } ).replace( /\./g, "" ).slice( 0, 6 ) );

// エンコード と 編集モード
var dEnc  = d.Encoding;
var dMode = d.Mode;

// Mery.ini から情報収集
var iniKey = [ "AutoSaveEnabled", "AutoSaveToFolder", "AutoSaveFolder"
             , "BackupSaveToFolder", "BackupFolder"
             , "TabCloseButton" , "SaveHistory" ];

/* 配列 iniValue には編集モード名の配列もふくまれる */
// GetIniOption 関数は「読みなおし」マクロ用に改造
var iniValue = GetIniOptionRL( iniPath, iniKey, viewModeAutoSerchEnable );

// メニューに付けるチェックマークとグレーアウト設定

// 書き換え禁止フラグ
var dReadOnly	= d.ReadOnly;
var rCheckFlags	= dReadOnly ? meMenuChecked : 0;
var rGrayFlags1	= dReadOnly ? meMenuGrayed : 0;
var rGrayFlags2	= dReadOnly ? 0 : meMenuGrayed;

// ウインドウの「タブを有効にする」と「閉じるボタン」の設定状態
var tabEnable = editor.EnableTab;

if ( fullPath ) {
  var tabCloseButton = iniValue[0][5];
  // 「読み取り専用属性 ON/OFF」と「閉じて開きなおす」の必要条件
  var reopenEnable = ( tabEnable
                    && ( editor.documents.Count > 1 || tabCloseButton ) );

  // 読み取り専用属性
  var f = Fso.GetFile( fullPath );
  var attributeReadOnly	= ( f.Attributes & 1 );
  var aCheckFlags		= attributeReadOnly ? meMenuChecked : 0;
  var aGrayFlags		= tabEnable ? 0 : meMenuGrayed;
  var aGrayFlags1		= attributeReadOnly ? meMenuGrayed : 0;
  var aGrayFlags2		= attributeReadOnly ? 0 : meMenuGrayed;

  // エンコード
  var utf8    = ( dEnc == 65001 || dEnc == 650011 || dEnc == 650010 )
              ? meMenuChecked : 0;
  var utf16le = ( dEnc == 65537 || dEnc == 655371 || dEnc == 655370 )
              ? meMenuChecked : 0;
  var utf16be = ( dEnc == 65538 || dEnc == 655381 || dEnc == 655380 )
              ? meMenuChecked : 0;
}

// 自動保存フォルダとバックアップフォルダ
var versionCheck20609 = ( meryVer >= 20609 );
if ( versionCheck20609 ) {
  // 相対パス解決のためにカレントディレクトリを設定
  WshShell.CurrentDirectory = meryDir;
  var autoSaveFolder = Fso.GetAbsolutePathName( iniValue[0][2] );
  var backupFolder   = Fso.GetAbsolutePathName( iniValue[0][4] );
  // パスが "" のときも FolderExists は True なのでグレーアウトの条件を追加
  var autoSaveFlags	= ( iniValue[0][1] && iniValue[0][2]
                     && Fso.FolderExists( autoSaveFolder ) )
                    ? 0 : meMenuGrayed;
  var backupFlags	= ( iniValue[0][3] && Fso.FolderExists( backupFolder ) )
                 	? 0 : meMenuGrayed;
}
else { woAutoSaved = false; }
var autoSaveBackup	= ( versionCheck20609
                  	 && ( autoSaveFlags == 0 || backupFlags == 0 ) );

// さいごに閉じたファイル
if ( numLatestClosed > 0 ) {
  var saveHistory      = iniValue[0][6];
  if ( saveHistory ) {
    var setting = [ numLatestClosed, woAutoSaved ];
    var folders = [ autoSaveFolder, backupFolder ];
    var latestClosedFile = LatestClosedFile( hisPath, setting, folders );
    numLatestClosed = latestClosedFile.length;
  }
}


// ポップアップメニュー項目
var m   = CreatePopupMenu();
var sm1 = CreatePopupMenu();	// ファイル・フォルダ サブメニュー
var sm2 = CreatePopupMenu();	// 編集モード サブメニュー

m.Add( "書き換え禁止 ON/OFF (&Y)", 2, rCheckFlags );
// 「無題」ドキュメントではファイル・フォルダ サブメニューを表示しない
if ( fullPath ) {
  if ( tabEnable ) {
    m.Add( "読み取り専用属性 ON/OFF (&W)", 3, aCheckFlags + aGrayFlags );
    m.Add( "閉じて開きなおす (&L)", 1 );
  }
  m.Add( "", 0, meMenuSeparator );
  m.Add( "親フォルダを開く (&F)", 10 );
  m.Add( "フルパスをコピー (&C)", 32 );
  m.Add( "プロパティ (&R)", 4 );

  // ファイル・フォルダ サブメニュー
  m.Add( "", 0, meMenuSeparator );
  m.AddPopup( "ファイル・フォルダ サブメニュー (&F)", sm1 );
    sm1.Add( "書き換え禁止にする (&Y)", 2, rGrayFlags1 );
    sm1.Add( "書き換え禁止を解除 (&Y)", 2, rGrayFlags2 );
    sm1.Add( "", 0, meMenuSeparator );
  if ( tabEnable ) {
    sm1.Add( "読み取り専用属性にして開きなおす (&W)", 3, aGrayFlags1 );
    sm1.Add( "読み取り専用属性を解除して開きなおす (&W)", 3, aGrayFlags2 );
    sm1.Add( "", 0, meMenuSeparator );
  }
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "フルパスをコピー (&C)", 32 );
    sm1.Add( "ファイル名をコピー (&N)", 33 );
  if ( tabEnable && d.Text ) {
    sm1.Add( "新規タブで開く (&G)", 64 );
  }
    sm1.Add( "メモ帳で開く (&V)", 62 );
    sm1.Add( "デスクトップにコピー (&X)", 60 );
    sm1.Add( "任意のフォルダにコピー (&Z) ...", 61 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "プロパティ (&R)", 4 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "親フォルダのパスをコピー (&F)", 34 );
    sm1.Add( "親フォルダを開く (&P)", 10 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( mery + ".exe のフルパスをコピー (&E)", 30 );
    sm1.Add( "Mery フォルダのパスをコピー (&D)", 31 );
    sm1.Add( "Mery フォルダを開く (&M)", 11 );
  if ( profileDirExist ) {
    sm1.Add( "ユーザーフォルダを開く (&U)", 12 );
  }
  if ( autoSaveBackup ) {
    sm1.Add( "自動保存フォルダを開く (&A)", 13, autoSaveFlags );
    sm1.Add( "バックアップフォルダを開く (&B)", 14, backupFlags );
  }
    sm1.Add( "デスクトップフォルダを開く (&H)", 15 );

  // 「さいごに閉じたファイル」
  if ( numLatestClosed > 0 ) {
    LatestClosedFileMenu( latestClosedFile, sm1, 300 );
  }

    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "Mery.txt を開く (&T)", 41 );
    sm1.Add( mery + ".ini を開く (&I)", 42 );
    sm1.Add( "「読み直し」マクロの JS ファイルを開く (&J)", 6 );
    sm1.Add( "オプション (&O) ...", 5 );
    sm1.Add( "", 0, meMenuSeparator );
    sm1.Add( "キャンセル & ", 0 );	// Esc キーまたは Space キーでキャンセル可
}

// 編集モード サブメニュー
m.Add( "", 0, meMenuSeparator );
m.AddPopup( "編集モード サブメニュー (&M)", sm2 );

  sm2.Add( "現在の編集モードのプロパティ (&P)...", 100 );
  sm2.Add( "", 0, meMenuSeparator );

// 編集モードサブメニューの項目を自動で生成する場合
if ( viewModeAutoSerchEnable ) {
  var len = iniValue[1].length,  mode;
  for ( var i = 0; i < len; i ++ ) {
    mode = iniValue[1][i].replace( /&/g, "&&" );
    sm2.Add( "&" + mode, i + 5120, ( dMode == mode ) *1 )
    // 下にセパレータを入れたい
    if ( mode == "XML" && i + 1 != len ) {
      sm2.Add( "", 0, meMenuSeparator );
    }
  }
  sm2.Add( "", 0, meMenuSeparator );
  sm2.Add( "編集モードの設定 (&C) ...", 200 );
}

// 編集モードサブメニューの項目を手動で取捨選択する場合
else {
  sm2.Add( "編集モードの設定 (&C)...", 200 );
  sm2.Add( "", 0, meMenuSeparator );
  /**
   * 以下、追加/削除したものがあれば任意で変更すること。
   * ※ 編集モード各アイテムは sm2.Add(); の行のコメントアウトで非表示にできる
   * ※ sm2 グループ内での並べ替え可。
   */ 
  // ▼ デフォルトの編集モード ▼
  sm2.Add( "&Bat", 101, + ( dMode == "Bat" ) );
  sm2.Add( "C&#", 102, + ( dMode == "C#" ) );
  sm2.Add( "C&++", 103, + ( dMode == "C++" ) );
  sm2.Add( "ColdFusion", 104, + ( dMode == "ColdFusion" ) );
  sm2.Add( "&CSS", 105, + ( dMode == "CSS" ) );
  sm2.Add( "&Delphi", 106, + ( dMode == "Delphi" ) );
  sm2.Add( "HSP", 107, + ( dMode == "HSP" ) );
  sm2.Add( "&HTML", 108, + ( dMode == "HTML" ) );
  sm2.Add( "&INI", 109, + ( dMode == "INI" ) );
  sm2.Add( "J&ava", 110, + ( dMode == "Java" ) );
  sm2.Add( "&JavaScript", 111, + ( dMode == "JavaScript" ) );
  sm2.Add( "JSP", 112, + ( dMode == "JSP" ) );
  sm2.Add( "Per&l", 113, + ( dMode == "Perl" ) );
  sm2.Add( "P&erlScript", 114, + ( dMode == "PerlScript" ) );
  sm2.Add( "&PHP", 115, + ( dMode == "PHP" ) );
  sm2.Add( "P&owerShell", 116, + ( dMode == "PowerShell" ) );
  sm2.Add( "P&ython", 117, + ( dMode == "Python" ) );
  sm2.Add( "RHT&ML", 118, + ( dMode == "RHTML" ) );
  sm2.Add( "&Ruby", 119, + ( dMode == "Ruby" ) );
  sm2.Add( "S&QL", 120, + ( dMode == "SQL" ) );
  sm2.Add( "TeX", 121, + ( dMode == "TeX" ) );
  sm2.Add( "&Text", 122, + ( dMode == "Text" ) );
  sm2.Add( "&UWSC", 123, + ( dMode == "UWSC" ) );
  sm2.Add( "VB&Script", 124, + ( dMode == "VBScript" ) );
  sm2.Add( "&VisualBasic", 125, + ( dMode == "VisualBasic" ) );
  sm2.Add( "&Windows Script", 126, + ( dMode == "Windows Script" ) );
  sm2.Add( "x86 Assembler", 127, + ( dMode == "x86 Assembler" ) );
  sm2.Add( "&XML", 128, + ( dMode == "XML" ) );
  // ▲ デフォルトの編集モード ▲
  sm2.Add( "", 0, meMenuSeparator );

  /* ▼ ココに追加の編集モードを列挙する ▼ */
  // 編集モード名は正確に!
  // ※大文字/小文字、全角/半角の区別、空白やアンダースコア、
  //   ハイフン、カッコの種類
  // ※アクセラレータの「&」または「(&A)」以外は付加しないこと

// sm2.Add( "Hoge (&G)", 129 );
// sm2.Add( "Fuga (&F)", 130 );
// sm2.Add( "Piyo", 131 );

// sm2.Add( "&Mery_Macro_JS", 132, ModeCheck( "Mery_Macro_JS" ) );
// sm2.Add( "Mery MS&Y", 133, ModeCheck( "Mery MSY" ) );
// sm2.Add( "&JaneStyle (正規表現用)", 135, ModeCheck( "JaneStyle (正規表現用)" ) );
  /* ▲ ココに追加の編集モードを列挙する ▲ */
}
  sm2.Add( "", 0, meMenuSeparator );
  sm2.Add( "キャンセル & ", 0 );	// Esc キーまたは Space キーでキャンセル可

// 「無題」ドキュメントではエンコードメニューを表示しない
if ( fullPath ) {
    // 2068 からの ID は ExecuteCommandByID() の定数
    m.Add( "", 0, meMenuSeparator );
    m.Add( "", 0, meMenuSeparator );
    m.Add( "自動選択 (&A)", 2068 );
    m.Add( "", 0, meMenuSeparator );
    m.Add( "UTF-1&6LE", 2069, utf16le );
    m.Add( "UTF-16&BE", 2070, utf16be );
    m.Add( "UTF-&8", 2071, utf8 );
    m.Add( "UTF-&7", 2072, ( dEnc == 65000 ) *1 );
    m.Add( "", 0, meMenuSeparator );
    m.Add( "日本語 (シフト JI&S)", 2083, ( dEnc == 932 ) *1 );
  if ( variousLanguageEnable ) {
    m.Add( "日本語 (&JIS)", 2082, ( dEnc == 50222 ) *1 );
    m.Add( "日本語 (&EUC)", 2081, ( dEnc == 51932 ) *1 );
    m.Add( "", 0, meMenuSeparator );
    m.Add( "西ヨーロッパ言語", 2088, ( dEnc == 1252 ) *1 );
    m.Add( "中央ヨーロッパ言語", 2075, ( dEnc == 1250 ) *1 );
    m.Add( "キリル言語", 2078, ( dEnc == 1251 ) *1 );
    m.Add( "バルト言語", 2074, ( dEnc == 1257 ) *1 );
    m.Add( "ギリシャ語", 2079, ( dEnc == 1253 ) *1 );
    m.Add( "ヘブライ語", 2080, ( dEnc == 1255 ) *1 );
    m.Add( "トルコ語", 2086, ( dEnc == 1254 ) *1 );
    m.Add( "アラビア語", 2073, ( dEnc == 1256 ) *1 );
    m.Add( "タイ語", 2085, ( dEnc == 874 ) *1 );
    m.Add( "ベトナム語", 2087, ( dEnc == 1258 ) *1 );
    m.Add( "簡体中国語 (GB2312)", 2076, ( dEnc == 936 ) *1 );
    m.Add( "繁体中国語 (Big5)", 2077, ( dEnc == 950 ) *1 );
    m.Add( "韓国語", 2084, ( dEnc == 949 ) *1 );
  }
}

// 「無題」ドキュメント用のメインメニュー項目
if ( ! fullPath ) {
  m.Add( "", 0, meMenuSeparator );
  m.Add( mery + ".exe のフルパスをコピー (&E)", 30 );
  m.Add( "Mery フォルダのパスをコピー (&D)", 31 );
  m.Add( "Mery フォルダを開く (&M)", 11 );
  if ( profileDirExist ) {
    m.Add( "ユーザーフォルダを開く (&U)", 12 );
  }
  if ( autoSaveBackup ) {
    m.Add( "自動保存フォルダを開く (&A)", 13, autoSaveFlags );
    m.Add( "バックアップフォルダを開く (&B)", 14, backupFlags );
  }
  m.Add( "デスクトップフォルダを開く (&H)", 15 );

  // 「さいごに閉じたファイル」
  if ( numLatestClosed > 0 ) {
    LatestClosedFileMenu( latestClosedFile, m, 300 );
  }

  m.Add( "", 0, meMenuSeparator );
  m.Add( "Mery.txt を開く (&T)", 41 );
  m.Add( mery + ".ini を開く (&I)", 42 );
  m.Add( "「読み直し」マクロの JS ファイルを開く (&J)", 6 );
  m.Add( "オプション (&O) ...", 5 );
}

m.Add( "", 0, meMenuSeparator );
m.Add( "キャンセル & ", 0 );	// Esc キーまたは Space キーでキャンセル可


// ポップアップメニューを表示
Status = " 「読みなおし」 マクロ  [ "
       + ( ( new Date() - start ) /1000 ).toFixed( 3 ).replace( /\./, ". " )
       +" 秒 ]";
var r = m.Track( menuPosMouse );


switch ( r ) {
  case 0:
  break;

  case 1:	// ファイルを閉じて開きなおす
  d.Close();
  ReopenFile( fullPath );
  break;

  // 書き換え禁止フラグ ON/OFF を変更する
  case 2:
  // 未保存のとき、変更内容破棄について確認ダイアログが出る( ~ ver 2.7.4)
  d.ReadOnly = ! dReadOnly;
  break;

  // 読み取り専用属性 ON/OFF を変更して開き直す
  case 3:
  // d.Save();	// コメントアウトすると未保存で閉じる前に確認ダイアログ
  d.Close();
  f.Attributes = attributeReadOnly
               ? attributeReadOnly - 1
               : attributeReadOnly + 1;
  ReopenFile( fullPath );
  break;

  case 4:	// ファイルのプロパティを開く
  var fileName = d.Name;
  var folderPath = d.Path.replace( /\\+$/g, "" );
  var shell = new ActiveXObject( "Shell.Application" );
  shell.NameSpace( folderPath )
       .ParseName( fileName )
       .InvokeVerb( "プロパティ(&R)" );
  break;

  case 5:	// オプション... (環境設定)
  editor.ExecuteCommandByID( MEID_TOOLS_OPTIONS = 2177 );
  break;

  case 6:	// このマクロの JS ファイルを開く
  Status = " " + ScriptFullName;
  ReopenFile( ScriptFullName );
  // OpenJumpJS( "▼ 設定項目 ▼" );
  break;

  // フォルダを開く
  case 10:  case 11:  case 12:
  var path = ( r == 10 ) ? fullPath		// 親フォルダ
           : ( r == 11 ) ? meryPath		// Mery フォルダ
           :/* r == 12 */  iniPath;		// ユーザーフォルダ
  Status = " " + Fso.GetParentFolderName( path );
  WshShell.Run( "explorer /select,\"" + path + "\"" );
  break;

  case 13:  case 14:  case 15:
  var path = ( r == 13 ) ? autoSaveFolder	// 自動保存フォルダ
           : ( r == 14 ) ? backupFolder		// バックアップフォルダ
           :/* r == 15 */  desktopDir;		// デスクトップフォルダ
  Status = " " + path;
  WshShell.Run( "\"" + path + "\"");
  break;

  // パスをコピー
  case 30:  case 31:  case 32:  case 33:  case 34:
  var path = ( r == 30 ) ? meryPath		// Mery.exe のフルパスをコピー
           : ( r == 31 ) ? meryDir		// Mery フォルダのパスをコピー
           : ( r == 32 ) ? fullPath		// フルパスをコピー
           : ( r == 33 ) ? d.Name		// ファイル名をコピー
           :/* r == 34 */  d.Path;		// 親フォルダのパスをコピー
  Status = " " + path;
  ClipboardData.SetData( path );
  break;

  // Mery の設定ファイルを開く
  case 41:  case 42:
  var path = ( r == 41 ) ? meryDir + "Mery.txt"	// Mery.txt を開く
           :/* r == 42 */  iniPath;				// Mery.ini を開く
  Status = " " + path;
  ReopenFile( path );
  break;

  case 60:  case 61:	// デスクトップ/任意のフォルダにコピー
  confirmStr = "未保存の編集内容はコピーされませんが "
             + "\nこのままファイルコピーを実行しますか?";
  var targetDir = desktopDir;
  if ( d.Saved || Confirm( confirmStr ) ) {
    // フォルダを選択
    if ( r == 61 ) {
      targetDir = FolderSelectDilaog();	// フォルダ選択ダイアログ
      if ( ! targetDir ) { break; }
    }
    // FileSystemObject でファイルコピー 
    targetDirName = ( targetDir.toLowerCase() != desktopDir.toLowerCase() )
                  ? Fso.GetBaseName( targetDir ) + " フォルダ"
                  : "デスクトップ"; 
    Status = " \"" + targetDir + "\" にコピー";
    CopyFileTo( fullPath, targetDir, targetDirName );
  }
  break;

  case 62:	// メモ帳で開く
  var command = "\"notepad.exe\" \"" + fullPath + "\"";
  Status = " " + command;
  WshShell.Run( command );
  break;

  case 64:	// 新規タブで開く
  var sx = ScrollX,  sy = ScrollY;
  if ( fullPath || d.Text ) { editor.NewFile(); }
  var ad = editor.ActiveDocument;
  ad.Mode = dMode;  ad.Encoding = dEnc;
  if ( meryVer >= 20610 ) { ad.LineEnding = d.LineEnding; }
  ad.Text = d.Text;  ad.Saved = true;
  ad.selection.SetActivePos( d.selection.GetAnchorPos() );
  ad.selection.SetActivePos( d.selection.GetActivePos(), true );
  ScrollX = sx;  ScrollY = sy;
  break;

  case 100:	// 現在の編集モードのプロパティ...
  Status = " \"" + dMode + "\" のプロパティ";
  WshShell.SendKeys( "%P" );
  editor.ExecuteCommandByID( MEID_VIEW_MODE_CUSTOMIZE = 2144 );
  break;

  case 200:	// 編集モードの設定...
  Status = " 編集モードの設定を行います。";
  editor.ExecuteCommandByID( MEID_VIEW_MODE_CUSTOMIZE = 2144 );
  break;

  default:
  if ( r >= 300 && r < 400 ) {	// さいごに閉じたファイル
    ReopenFile( latestClosedFile[ r - 300 ] );
  }

  else if ( r >= 2068 && r <= 2091 ) {	// エンコード指定で読みなおす
    if ( pasteAfterReload ) {
      // 貼り付けオプション
      PasteAfterReload( d, r );
    }
    else {
      editor.ExecuteCommandByID( r );
    }
  }

  else if ( r >= 5120 && r < 6144 ) {	// 編集モードを変更する
    editor.ExecuteCommandByID( r );
  }
  else {	// 編集モードを変更する( r = 100 番台)
    var label = m.GetText( r ).replace( /[ ]*\(&.\)[ ]*|&/g , "" );
    d.Mode = label;
  }
  break;
}

// プロセスのカレントディレクトリを復旧する
WshShell.CurrentDirectory = currentDir;


// ---------- ▼ 関数 ▼ ----------
// ※各関数は部分的にメインスコープの変数を参照する

/**
 * 組み込み関数 GetIniOptionRL( meryIniPath, keyArray, viewModeSerch )
 * 引数で指定した INI オプション項目の値と
 * 編集モード一覧を配列で返す
 */
function GetIniOptionRL( iniPath, keyArray, viewModeSerch ) {
  // Mery.ini を読みこむ
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText,  Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( iniPath );
  var iniText = Adodb.ReadText( adReadAll );
  Adodb.Close();

  // 引数の配列をループ処理して ini からオプションの値を取得する
  var reg, value, iniOption = [];
  for ( var i = 0, len = keyArray.length; i < len; i ++ ) {
    reg = new RegExp( "^" + keyArray[i] + "=(.*?)$" , "m" );
    if ( reg.test( iniText ) ) { 
      value = reg.exec( iniText )[1];
      if ( /^-?[1-9][0-9]*$/.test( value ) ) {
        value = Number( value );	// 10進数なら Number 型で返す
      }
    }
    else { value = ""; }			// エラーがあっても継続
    iniOption.push( value );
  }

  // 編集モード名を取得する
  var modeArray = [];
  if ( viewModeSerch ) {
    // \r\n [Modes\Mode##] \r\n Caption=ModeName を抽出
    var reg2 = /\r\n\[Modes\\Mode\d+\]\r\nCaption=[^\r\n]+/g;
    modeArray = iniText.match( reg2 );	// 抽出結果の配列
    // ModeName を抽出
    var reg3 = /Caption=([^\r\n]+)/;
    for ( var i = 0, len = modeArray.length; i < len; i ++ ) {
      modeArray[i] = reg3.exec( modeArray[i] )[1];
    }
  }
  return [ iniOption, modeArray ];
}

/**
 * 関数 LatestClosedFile( meryhisPath, setting, folders )
 * ※「読みなおし」マクロ用改造版
 * Mery.his を読み込んで「さいごに閉じたファイル」のフルパスの配列を返す
 * 
 * ※ Mery の「オプション」設定で「カーソル位置とブックマークを保存する」
 *   が無効(Mery.his がない)なら [] を返す
 */
function LatestClosedFile( hisPath, setting, folders ) {
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  if ( ! Fso.FileExists( hisPath ) ) { return []; }
  
  var num = setting[0] ? setting[0] : 1;
  var woAutoSaved = setting[1];
  var closedFile = "";
  var closedFileArray = [];
  // Mery.his を読みこむ
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText,  Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( hisPath );
  var hisText = Adodb.ReadText( adReadAll );
  Adodb.Close();
  // Mery.his からファイルパスを抽出する
  var hisArray = hisText.match( /^\[.+\]$/gm );
  if ( ! hisArray ) { return []; }
  // 現在タブに開かれていないものを「さいごに閉じたファイル」とする
  hisArray.reverse();
  var hCount = hisArray.length;
  var eCount = Editors.Count;
  var docus,  dCount,  filePath;
  if ( woAutoSaved ) {
    var autoSaveDir = folders[0].toLowerCase() + "\\";
    var backupDir   = folders[1].toLowerCase() + "\\";
    var CheckAutoSaveBackup = function( path, autoSaveDir, backupDir ) {
      return ( path.toLowerCase().indexOf( autoSaveDir ) != -1
            || path.toLowerCase().indexOf( backupDir ) != -1 );
    };
  }
  outerLoop:
  for ( var i = 0; i < hCount && closedFileArray.length < num; i ++ ) {
    closedFile = hisArray[i].slice( 1, -1 );
    if ( woAutoSaved
        && CheckAutoSaveBackup( closedFile, autoSaveDir, backupDir ) ) {
      continue outerLoop;
    }
    for ( var ee = 0; ee < eCount; ee ++ ) {
      docus  = Editors.Item( ee ).Documents;
      dCount = docus.Count;
      for ( var dd = 0; dd < dCount; dd ++ ) {
        filePath = docus.Item( dd ).FullName.toLowerCase();
        if ( closedFile.toLowerCase() == filePath ) {
          continue outerLoop;
        }
      }
    }
    if ( Fso.FileExists( closedFile ) ) {
      closedFileArray.push( closedFile );
    }
  }
  return closedFileArray;
}

/**
 * 関数 LatestClosedFileMenu( objArray, objMenu, id )
 * 「さいごに閉じたファイル」のメニューを返す
 */
function LatestClosedFileMenu( objArray, objMenu, id ) {
  var count = objArray.length;
  var width = String( count ).length;
  var label,  num;
  objMenu.Add( "", 0, meMenuSeparator );
  objMenu.Add( "  ▼ さいごに閉じたファイル " + count + " 件 ▼"
             , 0, meMenuGrayed );
  for ( var i = 0; i < count; i ++ ) {
    // 「通し番号: 親フォルダ名\ ファイル名」に切りつめる
    num = ( "   " + ( i + 1 ) ).slice( - width ).replace( /\d$/, "&$&:  " );
    label = objArray[i].replace( /(?:.+\\)*([^\\]+\\)([^\\]+)$/, "$1 $2" );
    objMenu.Add( num + label, i + id );
  }
}

/**
 * 関数 ReopenFile( strPath )
 * 「開きなおす」
 */
function ReopenFile( strPath ) {
  // if ( editor.ActiveDocument.FullName
  //      || editor.ActiveDocument.Text ) {
  //   editor.NewFile();
  // }
  // editor.OpenFile( strPath );
  var WshShell = new ActiveXObject( "WScript.Shell" );
  WshShell.Run( "\"" + editor.FullName + "\" \"" + strPath + "\"" );
}

/**
 * 関数 CopyFileTo( sourcePath, targetDir, targetDirName )
 * 「デスクトップにコピー」
 */
function CopyFileTo( sourcePath, targetDir, targetDirName ) {
  targetDir = targetDir.replace( /[\\]*$/, "\\" );
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  try {
    // 上書きなしでコピーを実行
    Fso.CopyFile( sourcePath, targetDir, false );
  } catch( e ) {
     var fileName = /[^\\]+$/.exec( sourcePath )[0];
    if ( e.number == -2146828230 ) {	// "既に同名のファイルが存在しています。"
      var targetPath = targetDir + fileName;
      var modified = DateTime( Fso.GetFile( targetPath ).DateLastModified );
      var msgStr = e.message + " \n\n "
                 + targetPath + " \n "
                 + "更新日時: " + modified
                 + " \n\n上書きしますか? \n\n\n"
                 + "「はい」:上書き、 "
                 + "「いいえ」:フォルダを開く、 "
                 + "「キャンセル」:中止 ";
      var nSecondsToWait = 0;
      var strTitle = "Mery: \"" + targetDirName + "にコピー\" - "
                   + "「読みなおし」マクロ";
      // ボタン 3:[はい][いいえ][キャンセル]、アイコン 32:[?]、標準ボタン 512:第3ボタン
      var nType = 3 + 32 + 512;
      var msgBox = WshShell.Popup( msgStr, nSecondsToWait, strTitle, nType );
      if ( msgBox == 6 ) {	// 6:[はい]
        // 上書きありでコピーを実行
        try { Fso.CopyFile( sourcePath, targetDir, true ); } 
        catch( e ) { Alert( e ); }	// e.g. "書き込みできません。" (-2146828218)
      }
      else if ( msgBox == 7 ) {	// 7:[いいえ]
        // 親フォルダを開く
        WshShell.Run( "explorer /select,\"" + sourcePath + "\"" );
        // コピー先フォルダを開く
        var sourceDir = Fso.GetParentFolderName( sourcePath ).toLowerCase();
        var targetDir = targetDir.toLowerCase().replace( /\\+$/, "" );
        if ( sourceDir != targetDir ) {
          var targetPath = targetDir + "\\" + fileName;
          WshShell.Run( "explorer /select,\"" + targetPath + "\"" );
        }
      }
    }
    // 重複以外のエラーのとき
    else { Alert( e ); }	// e.g. "書き込みできません。" (-2146828218)
  }
}

/**
 * 関数 DateTime( date )
 * 日時を  "YYYY年M月D日、h:mm:ss"  で返す
 */
function DateTime( date ) {
  var dd = new Date( date );
  return dd.getFullYear() + "年" + ( dd.getMonth() + 1 ) + "月"
       + dd.getDate() +"日、" + dd.toLocaleTimeString();
}

/**
 * 関数 FolderSelectDilaog()
 * フォルダ選択ダイアログ(手石氏, 2013/02/04)
 * https://www.haijin-boys.com/wiki/フォルダ選択ダイアログ
 */
function FolderSelectDilaog() {
  var sTitle	= "フォルダを選択してください";
  var iOptions	= 0x0040;	// 新しいフォルダの作成を許可する。
  var vRootDir	= 0;
  var ShellApp	= new ActiveXObject( "Shell.Application" );
  var folder	= ShellApp.BrowseForFolder( 0, sTitle, iOptions, vRootDir );

  return ( folder ) ? folder.Self.Path : "" ;
}

/**
 * 関数 PasteAfterReload( objDocu, encoding )
 * エンコードを変更して読み直しをしたあとに、元のテキストをコピペする
 * ※  2019/10/28: 改行形式(要 Mery 2.6.10 以上)と
 *                 キャレット位置の復元処理を追加
 */
function PasteAfterReload( objDocu, encoding ) {
  Redraw = false;
  var d = objDocu,  s = d.selection;
  var txt	= d.Text;
  var pos	= s.GetActivePos();
  var saved	= d.Saved; 
  var eol	= ( meryVer >= 20610 ) ? d.LineEnding : 3;
  d.ReadOnly = false;
  editor.ExecuteCommandByID( encoding );
  d.Text = txt;
  s.SetActivePos( pos );
  if ( eol < 3 ) { d.LineEnding = eol; }
  d.Saved = true;	// 変更行の強調(太字)を解除
  d.Saved = saved;	// 「未保存*」フラグを読みなおし前の状態に戻す
}

/**
 * 関数 OpenJumpJS( str )
 * ※「読みなおし」マクロ用改造版
 * このマクロを開いて設定項目の行にジャンプする
 */
function OpenJumpJS( str ) {
  var targetStr = str || "";
  var eCount = editors.Count;
  var docus,  dCount,  dd,  ee,  js;
  var isOpen = false;
  outerLoop:
  for ( var j = 0; j < eCount; j ++ ) {
    docus  = editors.Item( j ).documents;
    dCount = docus.Count;
    for ( var i = 0; i < dCount; i ++ ) {
      dd = docus.Item( i );
      if ( dd.FullName == ScriptFullName ) {
        js     = dd;
        isOpen = true;
        break outerLoop;
      }
    }
  }
  Redraw = false;
  if ( ! isOpen ) {
    editor.NewFile();
    ee = ( editor.EnableTab ) ? editor : editors.Item( eCount );
    ee.OpenFile( ScriptFullName, 0 );
    js = ee.ActiveDocument;
  }
  js.Activate();
  if ( targetStr ) {
    var settingPos = js.Text.indexOf( targetStr );
    js.selection.EndOfDocument();	// ScrollY よりも確実性が高い
    js.selection.SetActivePos( settingPos + targetStr.length );
    js.selection.WordRight( true );
  }
  Redraw = true;
}

>> 目次へ

include版[編集]

設定項目が多くなりますが、外部のマクロや実行ファイルと連携させることで、機能をより強化することができます。

『sukemaru 自家用 (include版)』のポップアップメニュー(2019/11/30)

ファイルを読み直す・開きなおす【自家用版】.png


変更箇所と追加機能[編集]

  • エンコード一覧と「さいごに閉じたファイル」の配置を入れ替え
  • 「ファイル・フォルダ サブメニュー」を追加 (2019/11/30: 通常版にも移植した)
  • 設定変更 サブメニュー」を追加(マクロの動作設定をサブメニュー内から変更可)
  • ポップアップメニューの表示位置を指定可(マウス位置/キャレット位置)
    → キャレット位置表示のときは設定変更後にメニューを再表示する
  • 文字カウント」「バイト数」「すべて閉じる」マクロを呼び出す
  • お気に入り」プラグインのポップアップメニューと「コピー」ツール(フォルダにコピー)を呼び出す


(2019/11/30 追加・変更)

  • 「パスをコピー」コマンドに GetKeyState.exe による拡張機能を追加 ( ¥¥¥ に置換する)
  • 「Mery.his を開く」「Workspace.ini を開く」コマンドを追加
  • 「作業フォルダ」関連コマンド(開く/確認/変更)を追加
  • 「ブラウザで開く」コマンドを追加(実行ファイルの変更可)
  • 「フォルダにコピー」でのコピー先フォルダの既定値を変更する設定項目を追加
  • 「『さいごに閉じたファイル』の表示件数をリセットする」コマンドを追加
  • さいごに閉じたファイルを開く」マクロを呼び出す


外部リソースのインポート[編集]

※ インポートする各マクロの保存形式は UTF-8 でなければなりません。
※ 各マクロを [ マクロのカスタマイズ ] から登録しないでも、ファイルパスを指定するだけで利用できます。
※ プラグインは、DLL ファイルを "Plugins" フォルダに配置してから [ プラグインの設定 ] ダイアログで並び順を確認し、本マクロのソースコード内で番号を指定する必要があります。
  • すべて閉じる」マクロの『include版』(2019/05/03) を擬似 include する場合は、「すべて閉じる」マクロのソースコードを改造する必要があります。
  • 58 行目の if ( typeof IO == "object" && settingEnable ) { の行を以下のとおりの 2 行に変更する
var macroCloseAllJS;
if ( typeof IO == "object" && settingEnable && macroCloseAllJS == undefined ) {
※ 上のとおり変更しても、「すべて閉じる」マクロ単体での実行にあたって支障をきたすことはありません。 『include版』以外の「すべて閉じる」マクロの場合は、ソースコードを変更する必要はありません。
※ これは include ライブラリ/ IO.js の「擬似 include 処理」 eval( IO.Include( macroPath, "utf-8" ) ); を利用するうえで必要な変更となります。



2018/08/04版 を擬似 include する場合は、マクロのソースコードを部分的に改変する必要があります。


  • マクロライブラリにある「バイト数」マクロの擬似 include にあたっては、いずれのバージョンにおいてもソースコードの改変の必要はありません(イベントマクロであっても呼び出すことができます)。 本マクロのソースコード内の設定項目で、実体ファイルのパスを指定すればそのまま利用できます。


  • さいごに閉じたファイルを開く」マクロを擬似 include した場合、ポップアップメニュー内の さいごに閉じたファイル ... の行をクリックすると、「さいごに閉じたファイル」マクロを呼び出すことができます。 より多くの履歴を表示させたい場合にご利用下さい。


  • 「お気に入り」プラグインは、公式 プラグイン 版と プラグインライブラリ 版のどちらでも利用できますが、「プラグインの設定」ダイアログに登録された順位( [ ツール ] >> [ プラグイン ] メニュー内で表示される通し番号)の指定が必要になります。


  • アクティブなタブの実体ファイルを「フォルダにコピー」する機能では、外部の実行ファイル(e.g. RoboCopy, TeraCopy, FireFileCopy など)を使用することができますので、コマンドライン引数を設定することによりタイムスタンプやファイル属性などを維持した状態でのコピー、上書きコピーの可否や上書き確認の有無などを指定することができます。 >> 設定例
また、include 版では「フォルダにコピー」コマンドでのターゲットフォルダのデフォルト設定を変更できます(初期値は デスクトップ)。
※ ソースコードのデフォルト状態では、外部の実行ファイルは使用せず、WSH の機能でファイルをコピーするようにしてあります。 同名ファイルがあるばあいは上書き確認のダイアログを表示しますが、書き込み先のファイル/フォルダの状態によっては上書きコピーできないことがあります。


  • ソースコード内の「外部リソース設定」の項目を変更してからマクロを実行して「JSON ファイルを開く」コマンドで設定状態を確認しても、設定ファイルの内容は変更前の状態のままになります。 確認ダイアログ で設定状態をチェックしたい場合は、一度「無題」のタブをアクティブにして「設定を初期化する」コマンドを実行してください。
※「無題」以外のタブで「設定を初期化」すると "toolCopyOptions" のコマンドライン引数部分にアクティブタブのファイルパスが書き込まれます (じっさいに「フォルダにコピー」を実行したときには JSON ファイルに書き込まれたパスではなく、アクティブタブの実体ファイルがコピーされますので、支障をきたすことはありません)。



ソースコード[編集]

#title = "ファイルを読み直す・開きなおす..."
#tooltip = "エンコード指定/読み取り専用属性/編集モードの変更"
#include "include/IO.js"
#icon = "reload.ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",262

/**
 * ---------------------------------------------------------
 * 【include版】 ファイルを読み直す・開きなおす
 * sukemaru (2019/03/29 - 2019/11/30)
 * ---------------------------------------------------------
 */

var start = new Date();

// ● 優先的に定義の必要な変数
var Fso			= new ActiveXObject( "Scripting.FileSystemObject" );
var WshShell	= new ActiveXObject( "WScript.Shell" );
var d			= editor.ActiveDocument;
var fullPath	= Fso.FileExists( d.FullName ) ? d.FullName : "";
var fileName	= fullPath ? d.Name : "";
var fileExt		= fileName ? /[^.]+$/.exec( fileName )[0] : ""
var folderPath	= fullPath ? d.Path : "";
var scriptPath	= ScriptFullName;
var meryPath	= editor.FullName;
var mery		= Fso.GetBaseName( meryPath );
var meryDir		= Fso.GetParentFolderName( meryPath ) + "\\";
var currentDir	= WshShell.CurrentDirectory;
WshShell.CurrentDirectory = meryDir;
// 「デスクトップにコピー」 「デスクトップフォルダを開く」 で使用
var desktopDir = WshShell.SpecialFolders( "Desktop" );


/* ---------- ▼ 【include版】 初期設定 ▼ ---------- */
// ◆ 印の設定項目を変更した場合は、設定変更サブメニューで「設定を初期化」すること

// ●「設定変更」サブメニューを表示するか?	// (true する / false しない)
var settingEnable = true;		// ( 初期値:true )

// ◆ JSON ファイルのベース名
var jsonName = Fso.GetBaseName( scriptPath );	// ( 初期値:Fso.GetBaseName( scriptPath ) )

	// ※ 任意の名前に変更する場合はアンコメントして書き換える
	// jsonName = "読みなおし";

// ◆「フォルダにコピー」「デスクトップフォルダを開く」のターゲットを指定
var targetDir = desktopDir;		// ( 初期値:desktopDir )

	// ※ 任意のフォルダに変更する場合	※末尾に \\ をつけない
	// targetDir = "C:\\hoge";

/* --------------- ▲ 【include版】 初期設定 ▲ --------------- */


	/* ※ targetDir が実在しない場合はデスクトップに置き換える */
	targetDir = ( targetDir && Fso.FolderExists( targetDir ) )
	          ? targetDir : desktopDir;


/* ---------- ▼ 外部リソース設定 ▼ ---------- */
  // ※ ◆ 印の項目を変更した場合は、設定変更サブメニューで
  // 「設定内容を初期化」しないと JSON に書き込まれない
  // (そもそも JSON に書き込む必要のない項目なので、気にする必要はないが…)

  // ※ 各マクロは、 "絶対パス" か "「読みなおし」 マクロからの相対パス"
  //   または "Mery フォルダからの相対パス" で指定する。

// ◆「文字カウント」マクロ		// https://www.haijin-boys.com/wiki/文字カウント
var macroCountJS = "";
// macroCountJS = "Macros\\文字カウント.js";

// ◆「バイト数」マクロ			// https://www.haijin-boys.com/wiki/バイト数
var macroBytesJS = "";
// macroBytesJS = "Macros\\バイト数.js";

// ◆「すべて閉じる」マクロ(※要 改造)	// https://www.haijin-boys.com/wiki/すべて閉じる
var macroCloseAllJS = "";
// macroCloseAllJS = "Macros\\すべて閉じる(モード選択).js";

// ◆「さいごに閉じたファイル」マクロ		// https://www.haijin-boys.com/wiki/さいごに閉じたファイルを開く
var macroLatestClosedJS = "";
// macroLatestClosedJS = "Macros\\さいごに閉じたファイル.js";


// ◆「お気に入り」プラグインの表示名	// https://www.haijin-boys.com/wiki/お気に入り2
var pluginFavorite = "";
// pluginFavorite = "お気に入り";

// ◆「お気に入り」プラグインの [プラグイン] メニュー内での通し番号( 1 ~ )
var pluginFavoriteAt;
// pluginFavoriteAt = 1;


// ◆ GetKeyState.exe のパスを指定 ( 既定値:Macros\\GetKeyState.exe )
var getKeyState = "";
// getKeyState = "Macros\\GetKeyState.exe";

	// ※ 任意で変更する場合はフルパスで指定すること
	// getKeyState = "C:\\Program Files\\Mery\\GetKeyState.exe";


// ◆「メモ帳で開く」で使用する実行ファイル ( 既定値:"notepad.exe" )
var notepadExe = "notepad.exe";

// ◆「メモ帳」の表示名 ( 既定値:"メモ帳" )
var notepadName = "メモ帳";

// ◆「ブラウザで開く」で使用する実行ファイル ( 既定値:"iexplore.exe" )
var browserExe = "iexplore.exe";

// ◆「ブラウザ」の表示名 ( 既定値:"WEB ブラウザ" )
var browserName = "WEB ブラウザ";

	// ※ 任意で変更する場合はフルパスで指定すること
	// notepadExe  = "C:\\Progrm Files\\notepadpp\\notepad++.exe";
	// notepadName = "Notepad++";
	// browserExe  = "C:\\Program Files\\Mozilla\\Firefox\\firefox.exe";
	// browserName = "Firefox";


// ◆「フォルダにコピー」で使用する実行ファイル
//    ※ toolCopy = ""; のままなら WSH でコピーを実行
var toolCopy = "";

// ◆「フォルダにコピー」で使用するコマンドライン引数(先頭にスペースを入れること)
var toolCopyOptions = "";

	/**
	 * ◆「フォルダにコピー」で使用する実行ファイルを指定する場合
	 * WshShell.Run( "\"" + toolCopy + "\"" + toolCopyOptions ); で実行
	 * ※ 実行ファイルのパスが通っていない場合はフルパスで指定すること
	 * ※ コマンドライン引数 toolCopyOptions の先頭にはスペース " " を入れること
	 * ※ パス指定で半角空白が許容される場合でも "\"" + targetDir + "\"" とすること
	 * (「任意のフォルダにコピー」コマンドでのコピー先パスの置換処理に必要)
	 */

// 【設定例】

// 	// FireFileCopy の場合(※ e.g. 上書き確認あり)
// 	toolCopy = "FFC.exe";
// 	toolCopyOptions = " \"" + fullPath + "\""		// from
// 	                + " /to:\"" + targetDir + "\""	// to
// 	                + " /copy /ft:3"	// options	強制上書きは " /a" を追加
// 	                + " /nq /bg /go!";	// options

/* ---------- ▲ 外部リソース設定 ▲ ---------- */

/* ----------- ▼ 基本設定 ▼ ------------ */
  // include版 において、以下の項目 は
  // 「設定を初期化する」のときに使用される「初期値」にすぎない。
  // → ポップアップメニュー内から変更可

var viewModeMenuEnable		= true;
var viewModeAutoSerchEnable	= true;
var reloadMenuEnable		= true;
var variousLanguageEnable	= true;
var pasteAfterReload		= false;
var latestClosedMenuEnable	= true;
var numLatestClosed			= 10;
var woAutoSaved				= false;
var menuPosMouse			= true;

/* --------------- ▲ 基本設定 ▲ --------------- */

	/* 「メモ帳で開く」の実行ファイルと表示名が未指定のとき */
	notepadExe = ( notepadExe && Fso.FileExists( notepadExe ) )
	  ? notepadExe : "notepad.exe";
	notepadName = ( notepadExe == "notepad.exe" )
	  ? "メモ帳"
	  : notepadName
	    ? notepadName + " "
	    : notepadExe.replace( /(?:[^\\]+[\\])*([^\\]+?)(?:\.exe)?$/i, "$1" ) + " ";

	/* 「ブラウザで開く」の実行ファイルと表示名が未指定のとき */
	browserExe = ( browserExe && Fso.FileExists( browserExe ) )
	  ? browserExe : "iexplore.exe";
	browserName = ( browserExe == "iexplore.exe" )
	  ? "WEB ブラウザ"
	  : browserName
	    ? browserName + " "
	    : browserExe.replace( /(?:[^\\]+[\\])*([^\\]+?)(?:\.exe)?$/i, "$1" ) + " ";


/* ---------- ▼ 【include版】の追加コード ▼ ---------- */ 

// ソースコードの「設定項目」内の初期値を保存する
var setting = {
  settingEnable :			settingEnable,
  viewModeMenuEnable :		viewModeMenuEnable,
  viewModeAutoSerchEnable :	viewModeAutoSerchEnable,
  reloadMenuEnable :		reloadMenuEnable,
  variousLanguageEnable :	variousLanguageEnable,
  pasteAfterReload :		pasteAfterReload,
  latestClosedMenuEnable :	latestClosedMenuEnable,
  numLatestClosed :			numLatestClosed,
  woAutoSaved :				woAutoSaved,
  menuPosMouse :			menuPosMouse,
  // 以下の項目は初期値を保存する必要がないが…
  targetDir :				targetDir,
  jsonName :				jsonName,
  macroCountJS :			macroCountJS,
  macroBytesJS :			macroBytesJS,
  macroLatestClosedJS :		macroLatestClosedJS,
  pluginFavorite :			pluginFavorite,
  pluginFavoriteAt :		pluginFavoriteAt,
  notepadExe :				notepadExe,
  notepadName :				notepadName,
  browserExe :				browserExe,
  browserName :				browserName,
  toolCopy :				toolCopy,
  toolCopyOptions :			toolCopyOptions,
  getKeyState :				getKeyState
};
var initialSettings = setting;
if ( initialSettings.settingEnable ) {
  // JSON ファイルから設定を読み込む
  jsonName = jsonName || ScriptName.replace( /\.js$/i, "" );
  setting = IO.Deserialize( setting, jsonName );
  // 通常版の設定変数に再代入
  settingEnable				= setting.settingEnable;
  viewModeMenuEnable		= setting.viewModeMenuEnable;
  viewModeAutoSerchEnable	= setting.viewModeAutoSerchEnable;
  reloadMenuEnable			= setting.reloadMenuEnable;
  variousLanguageEnable		= setting.variousLanguageEnable;
  pasteAfterReload			= setting.pasteAfterReload;
  latestClosedMenuEnable	= setting.latestClosedMenuEnable;
  numLatestClosed			= setting.numLatestClosed;
  woAutoSaved				= setting.woAutoSaved;
  menuPosMouse				= setting.menuPosMouse;
}

// 設定変更した場合はメニューを再表示する(キャレット位置表示のときのみ)
var r = 0;
menuLoop:
do {	// while ( ! menuPosMouse && r >= 10000000 && r < 10000010 )

  // ループで再表示したときはタイマーをリセット
  if ( r ) { start = new Date(); }

/* ---------- ▲ 【include版】の追加コード ▲ ---------- */ 


  // Mery のデータフォルダと設定ファイル
  WshShell.CurrentDirectory = meryDir;
  var profileDir	= meryDir;
  var meryIni		= mery + ".ini";
  var meryHis		= mery + ".his";
  var iniPath		= meryDir + meryIni;
  var hisPath		= meryDir + meryHis;
  var workspacePath	= meryDir + "Workspace.ini";
  if ( ! Fso.FileExists( iniPath ) ) {
    profileDir		= WshShell.SpecialFolders( "APPDATA" ) + "\\Mery\\";
    iniPath			= profileDir + meryIni;
    hisPath			= profileDir + meryHis;
    workspacePath	= profileDir + "Workspace.ini";
  }
  var profileDirExists = ( profileDir != meryDir );
  var meryVer	 = + ( editor.Version.replace( /[0-9]+/g , function( digit ) {
                       return digit.length < 2 ? "0" + digit : digit
                   } ).replace( /\./g, "" ).slice( 0, 6 ) );

  // エンコード と 編集モード
  var dEnc = d.Encoding;
  var dMode = d.Mode;
  if ( ! viewModeMenuEnable ) {
    viewModeAutoSerchEnable = false;
  }

  // Mery.ini から情報収集
  var iniKey = [ "AutoSaveEnabled", "AutoSaveToFolder", "AutoSaveFolder"
               , "BackupSaveToFolder", "BackupFolder"
               , "LineColumnView" , "TabCloseButton" , "SaveHistory" ];

  /* 配列 iniValue には編集モード名の配列もふくまれる */
  // GetIniOption 関数は「読みなおし」マクロ用に改造
  var iniValue = GetIniOptionRL( iniPath, iniKey, viewModeAutoSerchEnable );

  // ● 各種変数、メニューに付けるチェックマーク・グレーアウトフラグの設定

  // 書き換え禁止フラグ
  var dReadOnly		= d.ReadOnly;
  var rCheckFlags	= dReadOnly ? meMenuChecked : 0;
  var rGrayFlags1	= dReadOnly ? meMenuGrayed : 0;
  var rGrayFlags2	= dReadOnly ? 0 : meMenuGrayed;

  // ウインドウの「タブを有効にする」と「閉じるボタン」の設定状態
  var tabEnable = editor.EnableTab;

  if ( fullPath && reloadMenuEnable ) {
    var tabCloseButton = iniValue[0][6];
    // 「読み取り専用属性 ON/OFF」と「閉じて開きなおす」の必要条件
    var reopenEnable = ( tabEnable
                      && ( editor.documents.Count > 1 || tabCloseButton ) );

    // 読み取り専用属性
    var f = Fso.GetFile( fullPath );
    var attributeReadOnly	= ( f.Attributes & 1 );
    var aCheckFlags			= attributeReadOnly ? meMenuChecked : 0;
    var aGrayFlags			= tabEnable ? 0 : meMenuGrayed;
    var aGrayFlags1			= attributeReadOnly ? meMenuGrayed : 0;
    var aGrayFlags2			= attributeReadOnly ? 0 : meMenuGrayed;

    // エンコード
    var utf8    = ( dEnc == 65001 || dEnc == 650011 || dEnc == 650010 )
                ? meMenuChecked : 0;
    var utf16le = ( dEnc == 65537 || dEnc == 655371 || dEnc == 655370 )
                ? meMenuChecked : 0;
    var utf16be = ( dEnc == 65538 || dEnc == 655381 || dEnc == 655380 )
                ? meMenuChecked : 0;
  }

  // 自動保存フォルダとバックアップフォルダ(「行の表示方法」を追加)
  var versionCheck20609 = ( meryVer >= 20609 );
  if ( versionCheck20609 ) {
    var autoSaveFolder = Fso.GetAbsolutePathName( iniValue[0][2] );
    var backupFolder   = Fso.GetAbsolutePathName( iniValue[0][4] );
    // パスが "" のときも FolderExists は True なのでグレーアウトの条件を追加
    var autoSaveFlags = ( iniValue[0][1] && iniValue[0][2]	// iniValue[0][0] &&
                       && Fso.FolderExists( autoSaveFolder ) )
                      ? 0 : meMenuGrayed;
    var backupFlags   = ( iniValue[0][3] && Fso.FolderExists( backupFolder ) )
                      ? 0 : meMenuGrayed;
  }
  else { woAutoSaved = false; }
  var autoSaveBackup  = ( versionCheck20609
                       && ( autoSaveFlags == 0 || backupFlags == 0 ) );


  // 「疑似 include 処理」するマクロのチェック
  // マクロのパスを解決する
  var MacroPath = function( macro ) {
    WshShell.CurrentDirectory = meryDir;
    var macroPath = Fso.GetAbsolutePathName( macro );
    if ( Fso.FileExists( macro ) ) {
      return macro;
    }
    var macroDir = Fso.GetParentFolderName( scriptPath ) + "\\";
    if ( Fso.FileExists( macroDir + macro ) ) {
      macroPath = macroDir + macro;
      return macroPath;
    }
    WshShell.CurrentDirectory = macroDir;
    var macroPath = Fso.GetAbsolutePathName( macro );
    if ( Fso.FileExists( macroPath ) ) {
      return macroPath;
    }
    macroDir = meryDir + "Macros\\";
    WshShell.CurrentDirectory = macroDir;
    macroPath = Fso.GetAbsolutePathName( macro );
    if ( Fso.FileExists( macroPath ) ) {
      return macroPath;
    }
    return "";
  };
  // 実在確認の結果をポップアップメニューのグレーアウトフラグに
  var MacroExists = function( macro ) {
    return MacroPath( macro ) ? 0 : meMenuGrayed;
  };

  // さいごに閉じたファイル
  var saveHistory = iniValue[0][7];
  var latestClosedMenuCondition = ( latestClosedMenuEnable
                                 && numLatestClosed > 0 && saveHistory );
  if ( latestClosedMenuCondition ) {
    var folders = [ autoSaveFolder, backupFolder ];
    var latestClosedFile = LatestClosedFile( hisPath, setting, folders );
    numLatestClosed = latestClosedFile.length;
  }

  // 「デスクトップフォルダ」のフォルダ名
  var targetDirName = ( targetDir.toLowerCase() != desktopDir.toLowerCase() )
                    ? Fso.GetBaseName( targetDir ) + " フォルダ"
                    : "デスクトップ"; 

  // 作業フォルダ変更コマンド用
  var toCurrentDir = fullPath ? "親" : "Mery ";


  // ● ポップアップメニュー項目
  var m = CreatePopupMenu();

  // ファイル・フォルダ サブメニュー
  m.AddPopup( "  ファイル・フォルダ サブメニュー (&F)", sm3 = CreatePopupMenu() );
  if ( fullPath ) {
    sm3.Add( "フルパスをコピー (&C)", 32 );
    sm3.Add( "ファイル名をコピー (&N)", 33 );
  }
  if ( tabEnable && d.Text ) {
    sm3.Add( "新規タブで開く (&G)", 64 );
  }
  if ( fullPath ) {
    sm3.Add( notepadName.replace( /&/g, "&&" ) + "で開く (&V)", 62 );
  if ( /(?:s?html?|php|txt)$/.test( fileExt ) ) {
    sm3.Add( browserName.replace( /&/g, "&&" ) + "で開く (&X)", 63 );
  }
    sm3.Add( targetDirName.replace( /&/g, "&&" ) + "にコピー (&Y)", 60 );
    sm3.Add( "任意のフォルダにコピー (&Z) ...", 61 );
    sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( "プロパティ (&R) ...", 4 );
    sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( "親フォルダのパスをコピー (&F)", 34 );
    sm3.Add( "親フォルダを開く (&P)", 10 );
  }
    sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( mery + ".exe のフルパスをコピー (&E)", 30 );
    sm3.Add( "Mery フォルダのパスをコピー (&D)", 31 );
    sm3.Add( "Mery フォルダを開く (&M)", 11 );
  if ( profileDirExists ) {
    sm3.Add( "ユーザーフォルダを開く (&U)", 12 );
  }
  if ( autoSaveBackup ) {
    sm3.Add( "自動保存フォルダを開く (&A)", 13, autoSaveFlags );
    sm3.Add( "バックアップフォルダを開く (&B)", 14, backupFlags );
  }
    sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( targetDirName.replace( /&/g, "&&" ) + " フォルダを開く (&H)", 15 );
    sm3.Add( "作業フォルダを開く (&O)", 16 );
    sm3.Add( "作業フォルダを確認 (&K)", 39 );
    sm3.Add( toCurrentDir + "フォルダを作業フォルダに設定する (&L)", 40 );
    sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( "Mery.txt を開く (&T)", 41 );
    sm3.Add( mery + ".ini を開く (&I)", 42 );
    sm3.Add( mery + ".his を開く (&S)", 43 );
  if ( meryVer >= 20615 ) {
    sm3.Add( "Workspace.ini を開く (&W)", 44 );
  }
    sm3.Add( "", 0, meMenuSeparator );
  if ( pluginFavorite && pluginFavoriteAt ) {	// 「お気に入り」プラグイン
    sm3.Add( "&1. 「" + pluginFavorite + "」 プラグイン ...", 50 );
  }
  if ( macroCountJS ) {
    sm3.Add( "&2. 「文字カウント」 マクロ ...", 51, MacroExists( macroCountJS ) );
  }
  if ( macroBytesJS ) {
    sm3.Add( "&3. 「バイト数」 マクロ", 52, MacroExists( macroBytesJS ) );
  }
  if ( macroCloseAllJS ) {
    // sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( "&4. 「すべて閉じる」 マクロ ...", 53, MacroExists( macroCloseAllJS ) );
  }
    sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( "「読み直し」 マクロの JS ファイルを開く (&J)", 6 );
    sm3.Add( "", 0, meMenuSeparator );
    sm3.Add( "キャンセル\t& ", 0 );	// Esc キーまたは Space キーでキャンセル可


  // 読みなおし サブメニュー	※「無題」ドキュメントでは表示しない
  if ( fullPath && reloadMenuEnable ) {
    m.AddPopup( "  読みなおし サブメニュー (&L)", sm1 = CreatePopupMenu() );
      sm1.Add( "書き換え禁止 ON/OFF (&Y)", 2, rCheckFlags );
      // sm1.Add( "  書き換え禁止にする (&Y)", 2, rGrayFlags1 );
      // sm1.Add( "  書き換え禁止を解除 (&Y)", 2, rGrayFlags2 );
    if ( reopenEnable ) {
      // sm1.Add( "", 0, meMenuSeparator );
      sm1.Add( "読み取り専用属性 ON/OFF (&W)", 3, aCheckFlags + aGrayFlags );
      // sm1.Add( "  読み取り専用属性を設定して開きなおす (&R)", 3, aGrayFlags1 );
      // sm1.Add( "  読み取り専用属性を解除して開きなおす (&R)", 3, aGrayFlags2 );
      // sm1.Add( "", 0, meMenuSeparator );
      sm1.Add( "閉じて開きなおす (&O)", 1 );
    }
      sm1.Add( "", 0, meMenuSeparator );

      // エンコード指定読みなおしメニュー
      // 2068 からの ID は ExecuteCommandByID() の定数
      sm1.Add( "", 0, meMenuSeparator );
      sm1.Add( "自動選択 (&A)", 2068 );
      sm1.Add( "", 0, meMenuSeparator );
      sm1.Add( "UTF-1&6LE", 2069, utf16le );
      sm1.Add( "UTF-16&BE", 2070, utf16be );
      sm1.Add( "UTF-&8", 2071, utf8 );
      sm1.Add( "UTF-&7", 2072, ( dEnc == 65000 ) *1 );
      sm1.Add( "", 0, meMenuSeparator );
      sm1.Add( "日本語 (シフト JI&S)", 2083, ( dEnc == 932 ) *1 );

    if ( variousLanguageEnable ) {
      sm1.Add( "日本語 (&JIS)", 2082, ( dEnc == 50222 ) *1 );
      sm1.Add( "日本語 (&EUC)", 2081, ( dEnc == 51932 ) *1 );
      sm1.Add( "", 0, meMenuSeparator );
      sm1.Add( "西ヨーロッパ言語", 2088, ( dEnc == 1252 ) *1 );
      sm1.Add( "中央ヨーロッパ言語", 2075, ( dEnc == 1250 ) *1 );
      sm1.Add( "キリル言語", 2078, ( dEnc == 1251 ) *1 );
      sm1.Add( "バルト言語", 2074, ( dEnc == 1257 ) *1 );
      sm1.Add( "ギリシャ語", 2079, ( dEnc == 1253 ) *1 );
      sm1.Add( "ヘブライ語", 2080, ( dEnc == 1255 ) *1 );
      sm1.Add( "トルコ語", 2086, ( dEnc == 1254 ) *1 );
      sm1.Add( "アラビア語", 2073, ( dEnc == 1256 ) *1 );
      sm1.Add( "タイ語", 2085, ( dEnc == 874 ) *1 );
      sm1.Add( "ベトナム語", 2087, ( dEnc == 1258 ) *1 );
      sm1.Add( "簡体中国語 (GB2312)", 2076, ( dEnc == 936 ) *1 );
      sm1.Add( "繁体中国語 (Big5)", 2077, ( dEnc == 950 ) *1 );
      sm1.Add( "韓国語", 2084, ( dEnc == 949 ) *1 );
    }
      sm1.Add( "", 0, meMenuSeparator );
      sm1.Add( "キャンセル\t& ", 0 );
  }	// if ( fullPath && reloadMenuEnable )

  // 編集モード サブメニュー
  if ( viewModeMenuEnable ) {
    m.AddPopup( "  編集モード サブメニュー (&V)", sm2 = CreatePopupMenu() );
      sm2.Add( "現在の編集モードのプロパティ (&P) ...", 100 );
      sm2.Add( "", 0, meMenuSeparator );

    /* 編集モードサブメニューの項目を自動で生成する場合 */
    if ( viewModeAutoSerchEnable ) {
      for ( var i = 0, len = iniValue[1].length, mode; i < len; i ++ ) {
        mode = iniValue[1][i];
        sm2.Add( "&" + mode.replace( /&/g, "&&" ), i + 5120, ( dMode == mode ) *1 )
        // 下にセパレータを入れたい
        if ( mode == "XML" && i + 1 != len ) {
          sm2.Add( "", 0, meMenuSeparator );
        }
      }
      sm2.Add( "", 0, meMenuSeparator );
      sm2.Add( "編集モードの設定 (&C) ...", 200 );
    }

    // 編集モードサブメニューの項目を手動で取捨選択する場合
    else {
      sm2.Add( "編集モードの設定 (&C) ...", 200 );
      /**
       * 以下、追加/削除したものがあれば任意で変更すること。
       * ※ 編集モード各アイテムは sm2.Add(); の行のコメントアウトで非表示にできる
       * ※ sm2 グループ内での並べ替え可。
       */ 

    /* ▼ ココに追加の編集モードを列挙する(id の範囲は 129 - 199)▼ */
      sm2.Add( "", 0, meMenuSeparator );
      // 編集モード名は正確に!
      // ※大文字/小文字、全角/半角の区別、空白やアンダースコア、
      //   ハイフン、カッコの種類
      // ※アクセラレータの「&」または「(&A)」以外は付加しないこと

      // sm2.Add( "Hoge (&G)", 129 );
      // sm2.Add( "Fuga (&F)", 130 );
      // sm2.Add( "Piyo", 131 );

      // ※「MeryMacroJS」?  「Mery Macro JS」?  「Mery_Macro_JS」?
      // sm2.Add( "&Mery_Macro_JS", 132, ModeCheck( "Mery_Macro_JS" ) );
      // sm2.Add( "Mery MS&Y", 133, ModeCheck( "Mery MSY" ) );
      // sm2.Add( "&JaneStyle (正規表現用)", 134, ModeCheck( "JaneStyle (正規表現用)") );
    /* ▲ ココに追加の編集モードを列挙する ▲ */ 

      // ▼ デフォルトの編集モード ▼
      sm2.Add( "", 0, meMenuSeparator );
      sm2.Add( "&Bat", 101, + ( dMode == "Bat" ) );
      sm2.Add( "C&#", 102, + ( dMode == "C#" ) );
      sm2.Add( "C&++", 103, + ( dMode == "C++" ) );
      sm2.Add( "ColdFusion", 104, + ( dMode == "ColdFusion" ) );
      sm2.Add( "&CSS", 105, + ( dMode == "CSS" ) );
      sm2.Add( "&Delphi", 106, + ( dMode == "Delphi" ) );
      sm2.Add( "HSP", 107, + ( dMode == "HSP" ) );
      sm2.Add( "&HTML", 108, + ( dMode == "HTML" ) );
      sm2.Add( "&INI", 109, + ( dMode == "INI" ) );
      sm2.Add( "J&ava", 110, + ( dMode == "Java" ) );
      sm2.Add( "&JavaScript", 111, + ( dMode == "JavaScript" ) );
      sm2.Add( "JSP", 112, + ( dMode == "JSP" ) );
      sm2.Add( "Per&l", 113, + ( dMode == "Perl" ) );
      sm2.Add( "P&erlScript", 114, + ( dMode == "PerlScript" ) );
      sm2.Add( "&PHP", 115, + ( dMode == "PHP" ) );
      sm2.Add( "P&owerShell", 116, + ( dMode == "PowerShell" ) );
      sm2.Add( "P&ython", 117, + ( dMode == "Python" ) );
      sm2.Add( "RHT&ML", 118, + ( dMode == "RHTML" ) );
      sm2.Add( "&Ruby", 119, + ( dMode == "Ruby" ) );
      sm2.Add( "S&QL", 120, + ( dMode == "SQL" ) );
      sm2.Add( "TeX", 121, + ( dMode == "TeX" ) );
      sm2.Add( "&Text", 122, + ( dMode == "Text" ) );
      sm2.Add( "&UWSC", 123, + ( dMode == "UWSC" ) );
      sm2.Add( "VB&Script", 124, + ( dMode == "VBScript" ) );
      sm2.Add( "&VisualBasic", 125, + ( dMode == "VisualBasic" ) );
      sm2.Add( "&Windows Script", 126, + ( dMode == "Windows Script" ) );
      sm2.Add( "x86 Assembler", 127, + ( dMode == "x86 Assembler" ) );
      sm2.Add( "&XML", 128, + ( dMode == "XML" ) );
      // ▲ デフォルトの編集モード ▲
    }
    sm2.Add( "", 0, meMenuSeparator );
    sm2.Add( "キャンセル\t& ", 0 );
  }	// if ( viewModeMenuEnable )

  /* 【include版】の設定変更サブメニュー */ 
  if ( initialSettings.settingEnable  ) {
    m.Add( "", 0, meMenuSeparator );
    SettingsMenu( m, setting );
  }

  // メインメニュー項目
  if ( fullPath ) {
    m.Add( "", 0, meMenuSeparator );
    m.Add( "  親フォルダを開く (&P)", 10 );
    m.Add( "  フルパスをコピー (&C)", 32 );
    m.Add( "  プロパティ (&R) ...", 4 );
  }
  if ( ! fullPath ) {
    m.Add( "", 0, meMenuSeparator );
  }
    m.Add( "  書き換え禁止 ON/OFF (&Y)", 2, rCheckFlags );

  // 「さいごに閉じたファイル」
  if ( latestClosedMenuCondition ) {
    m.Add( "", 0, meMenuSeparator );
    LatestClosedFileMenu( latestClosedFile, m, 300
                        , MacroExists( macroLatestClosedJS ) );
  }
    m.Add( "", 0, meMenuSeparator );

  if ( macroCloseAllJS ) {
    m.Add( "「すべて閉じる」マクロ (&Q) ..."
         , 53, MacroExists( macroCloseAllJS ) );
  }

  if ( ! viewModeMenuEnable ) {
    m.Add( "  現在の編集モードのプロパティ (&M) ...", 100 );
  }

    m.Add( "  オプション (&O) ...", 5 );
    m.Add( "  Mery.ini を開く (&I)", 42 );
    m.Add( "", 0, meMenuSeparator );
    m.Add( "  キャンセル\t& ", 0 );	// Esc キーまたは Space キーでキャンセル可

  // プロセスのカレントディレクトリを復旧する
  WshShell.CurrentDirectory = currentDir;


  // ポップアップメニューを表示
  Status = " 「読みなおし」 マクロ  [ "
         + ( ( new Date() - start ) / 1000 ).toFixed( 3 ).replace( /\./, ". " )
         + " 秒 ]";
  r = m.Track( menuPosMouse );


  var confirmStr = "";
  switch ( r ) {
    case 0:
    break;

    case 1:	// ファイルを閉じて開きなおす
    // 未保存のとき、閉じる前に保存の確認ダイアログが出る
    d.Close();
    ReopenFile( fullPath );
    break;

    case 2:	// 書き換え禁止フラグ ON/OFF を変更する
    // 未保存のとき、変更内容破棄について確認ダイアログが出る( ~ ver 2.7.4)
    d.ReadOnly = ! dReadOnly;
    break;

    case 3:	// 読み取り専用属性 ON/OFF を変更して開き直す
    // d.Save();	// コメントアウトすると未保存で閉じる前に確認ダイアログが出る
    d.Close();
    f.Attributes = attributeReadOnly
                 ? attributeReadOnly - 1
                 : attributeReadOnly + 1;
    ReopenFile( fullPath );
    break;

    case 4:	// ファイルのプロパティを開く
    Status = " " + fullPath;
    var ShellApp = new ActiveXObject( "Shell.Application" );
    ShellApp.NameSpace( folderPath.replace( /\\+$/g, "" ) )
            .ParseName( fileName )
            .InvokeVerb( "プロパティ(&R)" );
    break;

    case 5:	// オプション (環境設定)
    Status = " 設定を変更します。";
    editor.ExecuteCommandByID( MEID_TOOLS_OPTIONS = 2177 );
    break;

    case 6:	// このマクロの JS ファイルを開く
    Status = " " + ScriptFullName;
    ReopenFile( ScriptFullName );
    // OpenJumpJS();
    break;

    // フォルダを開く
    case 10:  case 11:  case 12:
    var path = ( r == 10 ) ? fullPath	// 親フォルダ
             : ( r == 11 ) ? meryPath	// Mery フォルダ
             :/* r == 12 */  iniPath;	// ユーザーフォルダ
    Status = " " + Fso.GetParentFolderName( path );
    WshShell.Run( "explorer /select,\"" + path + "\"" );
    break;

    case 13:  case 14:  case 15:  case 16:
    var path = ( r == 13 ) ? autoSaveFolder	// 自動保存フォルダ
             : ( r == 14 ) ? backupFolder	// バックアップフォルダ
             : ( r == 15 ) ? targetDir		// デスクトップフォルダ
             :/* r == 16 */  currentDir;	// 作業フォルダ
    Status = " " + path;
    WshShell.Run( "\"" + path + "\"");
    break;

    // パスをコピー
    case 30:  case 31:  case 32:  case 33:  case 34:
    var path = ( r == 30 ) ? meryPath		// Mery.exe のフルパスをコピー
             : ( r == 31 ) ? meryDir		// Mery フォルダのパスをコピー
             : ( r == 32 ) ? fullPath		// フルパスをコピー
             : ( r == 33 ) ? fileName		// ファイル名をコピー
             :/* r == 34 */  folderPath;	// 親フォルダのパスをコピー
    var ctrl = 0;
    if ( MacroPath( getKeyState ) ) {
      ctrl = WshShell.Run( "\"" + getKeyState + "\" ctrl", 0, true );
      path = ( ctrl == 1 ) ? path.replace( /\\/g, "\\$&" ) : path;
    }
    Status = " " + path;
    ClipboardData.SetData( path );
    break;

    case 39:	// 作業フォルダを確認
    Status = " 作業フォルダ:  " + currentDir;
    WshShell.CurrentDirectory = currentDir;
    break;

    case 40:	// 作業フォルダに設定する(カレントディレクトリを変更)
    WshShell.CurrentDirectory = ( fullPath ) ? folderPath : meryDir;
    Status = " 作業フォルダ:  " + WshShell.CurrentDirectory;
    // Quit();
    break;

    // Mery の設定ファイルを開く
    case 41:  case 42:  case 43:  case 44:
    var path = ( r == 41 ) ? meryDir + "Mery.txt"	// Mery.txt を開く
             : ( r == 42 ) ? iniPath				// Mery.ini を開く
             : ( r == 43 ) ? hisPath				// Mery.his を開く
             :/* r == 44 */  workspacePath; 		// Workspace.ini を開く
    Status = " " + path;
    ReopenFile( path );
    break;

    case 50:	// 「お気に入り」プラグイン
    var meID = pluginFavoriteAt + 7167;	// MEID_PLUGINS = 7168 からの連番
    try {
      editor.ExecuteCommandByID( meID );
    } catch( e ) { Alert( e ); }
    break;

    // マクロを擬似インクルード
    case 51:  case 52:  case 53:  case 54:
    path = ( r == 51 ) ? MacroPath( macroCountJS )			// 文字カウント
         : ( r == 52 ) ? MacroPath( macroBytesJS )			// バイト数
         : ( r == 53 ) ? MacroPath( macroCloseAllJS )		// すべて閉じる
         :/* r == 54 */  MacroPath( macroLatestClosedJS );	// さいごに閉じたファイル
    try {
      eval( IO.Include( path, "utf-8" ) );
    } catch( e ) { Alert( e ); }
    break;

    case 60:  case 61:		// デスクトップ/任意のフォルダにコピー
    confirmStr = "未保存の編集内容はコピーされませんが "
               + "\nこのままファイルコピーを実行しますか?";
    if ( d.Saved || Confirm( confirmStr ) ) {
      // フォルダを選択
      if ( r == 61 ) {
        var folder = FolderSelectDilaog();	// フォルダ選択ダイアログ
        if ( ! folder ) { break; }
        // toolCopyOptions の targetDir を置換
        var reg = RegExp( "\"" + targetDir.replace( /\\*$/, "" )
                                 .replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" )
                        + "\"", i );
        toolCopyOptions = toolCopyOptions.replace( reg, "\"" + folder + "\"" );
        targetDir = folder;
      }
      // 外部実行ファイルでファイルコピー 
      if ( toolCopy && toolCopyOptions.charAt( 0 ) == " "
                    && toolCopyOptions.indexOf( targetDir ) > 0 ) {
        try {
          if ( toolCopy.indexOf( " " ) >= -1 && ! /^"[^"]+"$/.test( toolCopy ) ) {
            toolCopy = "\"" + toolCopy + "\"";
          }
          Status = " " + toolCopy + toolCopyOptions;
          WshShell.Run( toolCopy + toolCopyOptions );
        } catch( e ) { Alert( e ); }
      }
      // FileSystemObject でファイルコピー 
      else {
        targetDirName = ( targetDir.toLowerCase() != desktopDir.toLowerCase() )
                      ? Fso.GetBaseName( targetDir ) + " フォルダ"
                      : "デスクトップ"; 
        Status = " \"" + targetDir + "\" にコピー";
        CopyFileTo( fullPath, targetDir, targetDirName );
      }
    }
    break;

    case 62:	// メモ帳で開く
    var command = "\"" + notepadExe + "\" \"" + fullPath + "\"";
    Status = " " + command;
    WshShell.Run( command );
    break;

    case 63:	// ブラウザで開く
    var command = "\"" + browserExe + "\" \"" + fullPath + "\"";
    Status = " " + command;
    WshShell.Run( command );
    break;

    case 64:	// 新規タブで開く
    var sx = ScrollX,  sy = ScrollY;
    if ( fullPath || d.Text ) { editor.NewFile(); }
    var ad = editor.ActiveDocument;
    ad.Mode = dMode;  ad.Encoding = dEnc;
    if ( meryVer >= 20610 ) { ad.LineEnding = d.LineEnding; }
    ad.Text = d.Text;  ad.Saved = true;
    ad.selection.SetActivePos( d.selection.GetAnchorPos() );
    ad.selection.SetActivePos( d.selection.GetActivePos(), true );
    ScrollX = sx;  ScrollY = sy;
    break;

    case 100:	// 現在の編集モードのプロパティ...
      Status = " \"" + dMode + "\" のプロパティ";
      WshShell.SendKeys( "%P" );
      editor.ExecuteCommandByID( MEID_VIEW_MODE_CUSTOMIZE = 2144 );
      break;

    case 200:	// 編集モードの設定...
      Status = " 編集モードの設定を行います。";
      editor.ExecuteCommandByID( MEID_VIEW_MODE_CUSTOMIZE = 2144 );
      break;

    default:
      /* 【include版】の設定変更サブメニュー項目を選択した場合 */
      if ( r >= 10000000 && r <= 10000015 ) {
        SettingsChange( r );
      } else

      if ( r >= 300 && r < 400 ) {	// さいごに閉じたファイル
        ReopenFile( latestClosedFile[ r - 300 ] );
      }

      else if ( r >= 2068 && r <= 2091 ) {	// エンコード指定で読みなおす
        if ( pasteAfterReload ) {
          // 貼り付けオプション
          PasteAfterReload( d, r );
        }
        else {
          editor.ExecuteCommandByID( r );
        }
      }

      else if ( r >= 5120 && r < 6144 ) {	// 編集モードを変更する
        editor.ExecuteCommandByID( r );
      }
      else {	// 編集モードを変更する( r = 100 番台)
        var label = m.GetText( r )
                     .replace( /[ ]*\(&.\)[ ]*|&/g , "" );
        d.Mode = label;
      }
      break;
  }

// 設定変更した場合はメニューを再表示する(キャレット位置表示のときのみ)
}
while ( ! menuPosMouse && r >= 10000000 && r <= 10000011 );

// プロセスのカレントディレクトリを復旧する
if ( r != 40 ) { WshShell.CurrentDirectory = currentDir; }
// Quit();


// ---------- ▼ 関数 ▼ ----------
// ※各関数は部分的にメインスコープの変数を参照する

/**
 * 関数 GetIniOptionRL( meryIniPath, keyArray, viewModeSerch )
 * ※「読みなおし」マクロ用 魔改造版
 * 引数 keyArray で指定した INI オプション項目の値と
 * 編集モードの一覧をそれぞれ配列で返す
 */
function GetIniOptionRL( iniPath, keyArray, viewModeSerch ) {
  // Mery.ini を読みこむ
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText,  Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( iniPath );
  var iniText = Adodb.ReadText( adReadAll );
  Adodb.Close();

  // 引数の配列をループ処理して ini からオプションの値を取得する
  var reg, value, iniOption = [];
  for ( var i = 0, len = keyArray.length; i < len; i ++ ) {
    reg = new RegExp( "^" + keyArray[i] + "=(.*?)$" , "m" );
    if ( reg.test( iniText ) ) { 
      value = reg.exec( iniText )[1];
      if ( /^-?[1-9][0-9]*$/.test( value ) ) {
        value = Number( value );	// 10進数なら Number 型で返す
      }
    }
    else { value = 0; }				// エラーがあっても継続
    iniOption.push( value );
  }

  // 編集モード名を取得する
  var modeArray = [];
  if ( viewModeSerch ) {
    // \r\n [Modes\Mode##] \r\n Caption=ModeName を抽出
    var reg2 = /\r\n\[Modes\\Mode\d+\]\r\nCaption=[^\r\n]+/g;
    modeArray = iniText.match( reg2 );	// 抽出結果の配列
    // ModeName を抽出
    var reg3 = /Caption=([^\r\n]+)/;
    for ( var i = 0, len = modeArray.length; i < len; i ++ ) {
      modeArray[i] = reg3.exec( modeArray[i] )[1];
    }
  }
  return [ iniOption, modeArray ];
}

/**
 * 関数 LatestClosedFile( meryhisPath, setting, folders )
 * ※「読みなおし」マクロ用改造版
 * Mery.his を読み込んで「さいごに閉じたファイル」のフルパスの配列を返す
 * ※ Mery の「オプション」設定で「カーソル位置とブックマークを保存する」
 *   が無効(Mery.his がない)なら [] を返す
 */
function LatestClosedFile( hisPath, setting, folders ) {
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  if ( ! Fso.FileExists( hisPath ) ) { return []; }
  var num = setting.numLatestClosed
          ? setting.numLatestClosed : 1;
  var closedFile = "";
  var closedFileArray = [];
  // try {
    // Mery.his を読みこむ
    var Adodb = new ActiveXObject( "ADODB.Stream" );
    var adTypeText = 2,  adReadAll = -1;
    Adodb.Type = adTypeText,  Adodb.Charset = "UTF-8";
    Adodb.Open();
    Adodb.LoadFromFile( hisPath );
    var hisText = Adodb.ReadText( adReadAll );
    Adodb.Close();
    // Mery.his からファイルパスを抽出する
    var hisArray = hisText.match( /^\[.+\]$/gm );
    if ( ! hisArray ) { return []; }
    // 現在タブに開かれていないものを「さいごに閉じたファイル」とする
    hisArray.reverse();
    var hCount = hisArray.length;
    var eCount = Editors.Count;
    var docus,  dCount,  filePath;
    if ( woAutoSaved ) {
      var autoSaveDir = folders[0].toLowerCase() + "\\";
      var backupDir   = folders[1].toLowerCase() + "\\";
      var CheckAutoSaveBackup = function( path, autoSaveDir, backupDir ) {
        return ( path.toLowerCase().indexOf( autoSaveDir ) != -1
              || path.toLowerCase().indexOf( backupDir ) != -1 );
      };
    }
    outerLoop:
    for ( var i = 0; i < hCount && closedFileArray.length < num; i ++ ) {
      closedFile = hisArray[i].slice( 1, -1 );
      if ( setting.woAutoSaved
        && CheckAutoSaveBackup( closedFile, autoSaveDir, backupDir ) ) {
        continue outerLoop;
      }
      for ( var ee = 0; ee < eCount; ee ++ ) {
        docus  = Editors.Item( ee ).Documents;
        dCount = docus.Count;
        for ( var dd = 0; dd < dCount; dd ++ ) {
          filePath = docus.Item( dd ).FullName.toLowerCase();
          if ( closedFile.toLowerCase() == filePath ) {
            continue outerLoop;
          }
        }
      }
      if ( Fso.FileExists( closedFile ) ) {
        closedFileArray.push( closedFile );
      }
    }
  // } catch( e ) {  }	// Alert( e );  closedFileArray = [];
  return closedFileArray;
}

/**
 * 関数 LatestClosedFileMenu( objArray, objMenu, id, LatestClosedJSisExist )
 * 「さいごに閉じたファイル」のメニューを返す
 * ※「読みなおし」マクロ用 改造版
 */
function LatestClosedFileMenu( objArray, objMenu, id, jsCheck ) {
  var count = objArray.length;
  var numWidth = String( count ).length;
  var dirWidth = 20;	// ※ 親フォルダ名の文字数を切りつめて表示する閾値
  var label,  num,  dir,  fileName;

  objMenu.Add( "  ▼ さいごに閉じたファイル " + count + " 件 ▼"
               + ( jsCheck ? "" : " ..." )
             , 54, jsCheck );
  for ( var i = 0; i < count; i ++ ) {
    // try {
      // 「通し番号: 親フォルダ名\ ファイル名」に切りつめる
      num = ( "   " + ( i + 1 ) ).slice( - numWidth ).replace( /\d$/, "&$&:  " );
      dir = /([^\\]+)(?:\\[^\\]+)$/.exec( objArray[i] )[1];
      dir = ( dir.length > dirWidth )
          ? dir.slice( 0, dirWidth ) + " ... "
          : dir;
      fileName = /[^\\]+$/.exec( objArray[i] )[0];

      // 「¥」を「¥¥」で表示させるなら
      label = ( dir + "\\ " + fileName ).replace( /&/g, "&&" );
      // 「¥」を「/」で表示させるなら	// 「∖」(U+2216)
      // label = ( dir + "/ " + fileName ).replace( /&/g, "&&" );

      objMenu.Add( num + label, i + id );
    // } catch( err ) { continue; }
  }
}

/**
 * 関数 ReopenFile( strPath )
 * 「開きなおす」
 */
function ReopenFile( strPath ) {
  // if ( editor.ActiveDocument.FullName
  //      || editor.ActiveDocument.Text ) {
  //   editor.NewFile();
  // }
  // editor.OpenFile( strPath );
  var WshShell = new ActiveXObject( "WScript.Shell" );
  WshShell.Run( "\"" + editor.FullName + "\" \"" + strPath + "\"" );
}

/**
 * 関数 CopyFileTo( sourcePath, targetDir, targetDirName )
 * 「デスクトップにコピー」
 */
function CopyFileTo( sourcePath, targetDir, targetDirName ) {
  targetDir = targetDir.replace( /[\\]*$/, "\\" );
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  try {
    // 上書きなしでコピーを実行
    Fso.CopyFile( sourcePath, targetDir, false );
  } catch( e ) {
     var fileName = /[^\\]+$/.exec( sourcePath )[0];
    if ( e.number == -2146828230 ) {	// "既に同名のファイルが存在しています。"
      var targetPath = targetDir + fileName;
      var modified = DateTime( Fso.GetFile( targetPath ).DateLastModified );
      var msgStr = e.message + " \n\n "
                 + targetPath + " \n "
                 + "更新日時: " + modified
                 + " \n\n上書きしますか? \n\n\n"
                 + "「はい」:上書き、 "
                 + "「いいえ」:フォルダを開く、 "
                 + "「キャンセル」:中止 ";
      var nSecondsToWait = 0;
      var strTitle = "Mery: \"" + targetDirName + "にコピー\" - "
                   + "「読みなおし」マクロ";
      // ボタン 3:[はい][いいえ][キャンセル]、アイコン 32:[?]、標準ボタン 512:第3ボタン
      var nType = 3 + 32 + 512;
      var msgBox = WshShell.Popup( msgStr, nSecondsToWait, strTitle, nType );
      if ( msgBox == 6 ) {	// 6:[はい]
        // 上書きありでコピーを実行
        try { Fso.CopyFile( sourcePath, targetDir, true ); }
        catch( e ) { Alert( e ); }	// e.g. "書き込みできません。"
      }
      else if ( msgBox == 7 ) {	// 7:[いいえ]
        // 親フォルダを開く
        WshShell.Run( "explorer /select,\"" + sourcePath + "\"" );
        // コピー先フォルダを開く
        var sourceDir = Fso.GetParentFolderName( sourcePath ).toLowerCase();
        var targetDir = targetDir.toLowerCase().replace( /\\+$/, "" );
        if ( sourceDir != targetDir ) {
          var targetPath = targetDir + "\\" + fileName;
          WshShell.Run( "explorer /select,\"" + targetPath + "\"" );
        }
      }
    }
    // 重複以外のエラーのとき
    else { Alert( e ); }	// e.g. "書き込みできません。"
  }
}

/**
 * 関数 DateTime( date )
 * 日時を  "YYYY年M月D日、h:mm:ss"  で返す
 */
function DateTime( date ) {
  var dd = new Date( date );
  return dd.getFullYear() + "年" + ( dd.getMonth() + 1 ) + "月"
       + dd.getDate() +"日、" + dd.toLocaleTimeString();
}

/**
 * 関数 FolderSelectDilaog()
 * 
 * フォルダ選択ダイアログ(手石氏, 2013/02/04)
 * https://www.haijin-boys.com/wiki/フォルダ選択ダイアログ
 */
function FolderSelectDilaog() {
  var sTitle	= "フォルダを選択してください";
  var iOptions	= 0x0040;	// 新しいフォルダの作成を許可する。
  var vRootDir	= 0;
  var ShellApp	= new ActiveXObject( "Shell.Application" );
  var folder	= ShellApp.BrowseForFolder( 0, sTitle, iOptions, vRootDir );

  return ( folder ) ? folder.Self.Path : "" ;
}

/**
 * 関数 PasteAfterReload( objDocu, encoding )
 * エンコードを変更して読み直しをしたあとに、元のテキストをコピペする
 */
function PasteAfterReload( objDocu, encoding ) {
  Redraw = false;
  var d = objDocu,  s = d.selection;
  var txt	= d.Text;
  var pos	= s.GetActivePos();
  var saved	= d.Saved; 
  var eol	= ( meryVer >= 20610 ) ? d.LineEnding : 3;
  d.ReadOnly = false;
  editor.ExecuteCommandByID( encoding );
  d.Text = txt;
  s.SetActivePos( pos );
  if ( eol < 3 ) { d.LineEnding = eol; }
  d.Saved = true;	// 変更行の強調(太字)を解除
  d.Saved = saved;	// 「未保存*」フラグを読みなおし前の状態に戻す
}

/**
 * 関数 OpenJumpJS( str )
 * ※「読みなおし」マクロ用改造版
 * このマクロを開いて設定項目の行にジャンプする
 */
function OpenJumpJS( str ) {
  var targetStr = str || "";
  var eCount = editors.Count;
  var docus,  dCount,  dd,  ee,  js;
  var isOpen = false;
  outerLoop:
  for ( var j = 0; j < eCount; j ++ ) {
    docus  = editors.Item( j ).documents;
    dCount = docus.Count;
    for ( var i = 0; i < dCount; i ++ ) {
      dd = docus.Item( i );
      if ( dd.FullName == ScriptFullName ) {
        js     = dd;
        isOpen = true;
        break outerLoop;
      }
    }
  }
  Redraw = false;
  if ( ! isOpen ) {
    editor.NewFile();
    ee = ( editor.EnableTab ) ? editor : editors.Item( eCount );
    ee.OpenFile( ScriptFullName, 0 );
    js = ee.ActiveDocument;
  }
  js.Activate();
  if ( targetStr ) {
    var settingPos = js.Text.indexOf( targetStr );
    js.selection.EndOfDocument();	// ScrollY よりも確実性が高い
    js.selection.SetActivePos( settingPos + targetStr.length );
    js.selection.WordRight( true );
  }
  Redraw = true;
}


// ---------- ▼ 【include版】 関数 ▼ ---------- //

/**
 * 関数 SettingsMenu( objPopupMenu )
 * ポップアップメニューに「設定変更」サブメニューを表示する
 */
function SettingsMenu( objMenu, setting ) {
  var subMenu = CreatePopupMenu();
  // メニューのオプションフラグ
  var grayFlag = ! setting.settingEnable ? meMenuGrayed : 0;
  var grayFlag_1
        = ( ! setting.viewModeMenuEnable || ! setting.settingEnable )
        ? meMenuGrayed : 0;
  var grayFlag_2
        = ( ! setting.reloadMenuEnable || ! setting.settingEnable )
        ? meMenuGrayed : 0;
  var maxLatestClosedFlag
        = ( ! setting.latestClosedMenuEnable || setting.numLatestClosed > 29 )
        ? meMenuGrayed : 0;
  var minLatestClosedFlag
        = ( ! setting.latestClosedMenuEnable || setting.numLatestClosed < 1 )
        ? meMenuGrayed : 0;
  var initialNum = initialSettings.numLatestClosed;
  var numLatestClosedFlag
        = ( ! setting.latestClosedMenuEnable
           || setting.numLatestClosed == initialNum
           || setting.numLatestClosed + 2 == initialNum
           || setting.numLatestClosed - 2 == initialNum )
        ? meMenuGrayed : 0;
  var woAutosaveFlag
        = ( ! setting.latestClosedMenuEnable || ! setting.settingEnable )
        ? meMenuGrayed : 0;

  // 「設定変更」サブメニューのアイテム
  objMenu.AddPopup( "  設定を変更する (&S)", subMenu );
    subMenu.Add( "「編集モード サブメニュー」を表示する (&V)"
               , 10000001, setting.viewModeMenuEnable + grayFlag );
    subMenu.Add( "「編集モード」を自動で取得する (&A)"
               , 10000002, setting.viewModeAutoSerchEnable + grayFlag_1 );
    subMenu.Add( "----", 0, meMenuSeparator );
    subMenu.Add( "「読みなおし サブメニュー」を表示する (&R)"
               , 10000003, setting.reloadMenuEnable + grayFlag );
    subMenu.Add( "  諸外国語用の文字コードを表示する (&F)"
               , 10000004, setting.variousLanguageEnable + grayFlag_2 );
    subMenu.Add( "  読みなおし後に元のテキストを貼り付ける (&P)"
               , 10000005, setting.pasteAfterReload + grayFlag_2 );
    subMenu.Add( "----", 0, meMenuSeparator );
    subMenu.Add( "「さいごに閉じたファイル」を表示する (&L)"
               , 10000006, setting.latestClosedMenuEnable + grayFlag );
    subMenu.Add( "「さいごに閉じたファイル」の履歴を 2 件 増やす (&U)\t"
               + Math.max( setting.numLatestClosed, 0 )
               + ( setting.numLatestClosed > 29
                     ? "" : " → " + ( setting.numLatestClosed + 2 ) )
               , 10000007, maxLatestClosedFlag || grayFlag );
    subMenu.Add( "「さいごに閉じたファイル」の履歴を 2 件 減らす (&D)\t"
               + Math.max( setting.numLatestClosed, 0 )
               + ( setting.numLatestClosed < 1
                     ? ""
                     : " → " + Math.max( setting.numLatestClosed - 2, 0 ) )
               , 10000008, minLatestClosedFlag || grayFlag );
    subMenu.Add( "「さいごに閉じたファイル」の表示件数をリセットする (&H)\t"
               + Math.max( setting.numLatestClosed, 0 ) + " → " + initialNum
               , 10000009, numLatestClosedFlag || grayFlag );
    subMenu.Add( "  履歴に 自動保存・バックアップ ファイルを含めない (&E)"
               , 10000010, setting.woAutoSaved + woAutosaveFlag );
    subMenu.Add( "----", 0, meMenuSeparator );
    subMenu.Add( "  入力カーソル の位置 にメニューを表示する"
               + ( menuPosMouse ? " (&M)" : "" )
               , 10000011, ! setting.menuPosMouse + grayFlag );
    subMenu.Add( "  マウスポインタの位置 にメニューを表示する"
               + ( setting.menuPosMouse ? "" : " (&M)" )
               , 10000011, setting.menuPosMouse + grayFlag );
    subMenu.Add( "----", 0, meMenuSeparator );
    // subMenu.Add( "----", 0, meMenuSeparator );
    subMenu.Add( "  設定内容をロックする (&S)"
               , 10000000, ! setting.settingEnable *1 );
    subMenu.Add( "", 0, meMenuSeparator );
    subMenu.Add( "「読みなおし」マクロの JS ファイルを開く (&J)", 10000013 );
    subMenu.Add( "「読みなおし」マクロの JSON ファイルを開く (&O)", 10000014 );
    subMenu.Add( "----", 0, meMenuSeparator );
    subMenu.Add( "  設定を初期化する (&I)", 10000015, grayFlag );
    subMenu.Add( "----", 0, meMenuSeparator );
    subMenu.Add( "  キャンセル\t& ", 0 );
}

/**
 * 関数 SettingsChange( num )
 * ポップアップメニューで選択した項目の設定状態を変更する
 */
function SettingsChange( num ) {
  var settingsChanged = true;
  switch ( num ) {
    case 10000000:
      settingEnable = setting.settingEnable
                    = ! setting.settingEnable;
      break;
    case 10000001:
      viewModeMenuEnable = setting.viewModeMenuEnable
                         = ! setting.viewModeMenuEnable;
      break;
    case 10000002:
      viewModeAutoSerchEnable = setting.viewModeAutoSerchEnable
                              = ! setting.viewModeAutoSerchEnable;
      break;
    case 10000003:
      reloadMenuEnable = setting.reloadMenuEnable
                       = ! setting.reloadMenuEnable;
      break;
    case 10000004:
      variousLanguageEnable = setting.variousLanguageEnable
                            = ! setting.variousLanguageEnable;
      break;
    case 10000005:
      pasteAfterReload = setting.pasteAfterReload
                       = ! setting.pasteAfterReload;
      break;
    case 10000006:
      latestClosedMenuEnable = setting.latestClosedMenuEnable
                             = ! setting.latestClosedMenuEnable;
      break;
    case 10000007:
      numLatestClosed = setting.numLatestClosed
                      += 2;
      break;
    case 10000008:
      numLatestClosed = setting.numLatestClosed
                      -= 2;
      break;
    case 10000009:
      numLatestClosed = setting.numLatestClosed
                      = initialSettings.numLatestClosed;
      break;
    case 10000010:
      woAutoSaved = setting.woAutoSaved
                  = ! setting.woAutoSaved;
      break;
    case 10000011:
      menuPosMouse = setting.menuPosMouse
                   = ! setting.menuPosMouse;
      break;

    case 10000013:
      settingsChanged = false;
      Status = " " + ScriptFullName;
      OpenJumpJS( "var settingEnable = " );
      break;
    case 10000014:
      settingsChanged = false;
      Status = " " + JsonDir() + "\\" + jsonName + ".json";
      OpenJumpJson( jsonName, setting, true );
      break;
    case 10000015:
      settingsChanged = false;
      Status = " " + JsonDir() + "\\" + jsonName + ".json";
      CheckJsonFile( jsonName, setting, true );
      break;

    default:
      settingsChanged = false;
      break;
  }
  if ( settingsChanged ) {
    try {
      IO.Serialize( setting, jsonName );
      Status = " 設定の変更を保存しました。";
    }
    catch( e ) { Status = " " + e;  Alert( e ); }
  }
}

/**
 * 関数 OpenJumpJson( jsonName, setting, bool )
 * ※「読みなおし」マクロ用改造版
 * JSON ファイルを開く
 */
function OpenJumpJson( jsonName, setting, bool ) {
  // var jsonName = jsonName || ScriptName.replace( /\.js$/i, "" );
  bool = bool || false;
  var WshShell = new ActiveXObject( "WScript.Shell" );
  try {
    IO.Serialize( setting, jsonName );
  } catch( e ) { ; }
  Sleep( 500 );
  var jsonDir = JsonDir();
  var jsonPath = jsonDir + "\\" + jsonName + ".json";
  var jsonContents = JsonContents( jsonPath, bool );
  if ( ! e && IO.Path.IsExist( jsonPath ) && jsonContents.length ) {
    var confirmStr = "設定ファイルの内容:"
                   + ( bool ? " (※デコードして表示)" : "" ) + " \n\n"
                   + jsonContents
                   + "設定ファイルを開きますか? \n\n"
                   + "*** ソースコード内の外部リソース設定を変更した場合、"
                   + "「設定を初期化」しないと反映されません *** "
    var nSecondsToWait = 0;
    var strTitle = "Mery: JSON ファイルの確認 - 「読みなおし」マクロ";
    // ボタン 4:[はい][いいえ]、 アイコン 32:[?]、 標準ボタン 256:第2ボタン
    var nType = 4 + 32 + 256;
    var msgBox = WshShell.Popup( confirmStr, nSecondsToWait, strTitle, nType );
    if ( msgBox == 6 ) {	// 6:[はい]
      ReopenFile( jsonPath );
    }
  }
  else if ( e ) {
    Alert( e + " \n\n" + jsonPath + "  " );
  }
  else if ( ! e ) {
    Alert( "設定ファイルがありません \n\n" + jsonDir + "  " );
  }
}

/** 
 * 関数 CheckJsonFile( jsonName, setting, bool )
 * ※「読みなおし」マクロ用改造版
 * JSON ファイルの初期化/実在確認
 */
function CheckJsonFile( jsonName, setting, bool ) {
  var WshShell = new ActiveXObject( "WScript.Shell" );
  var jsonDir = JsonDir();
  var jsonPath = jsonDir + "\\" + jsonName + ".json";
  bool = bool || false;
  var isError = false;
  var msgStr = jsonPath + "  \n\n"
             + "設定ファイルを初期化しますか? "
  var nSecondsToWait = 0;
  var strTitle = "Mery: JSON ファイルの初期化 - 「読みなおし」マクロ";
  // ボタン 4:[はい][いいえ]、 アイコン 48:[!]、 標準ボタン 256:第2ボタン
  var nType = 4 + 48 + 256;
  var msgBox = WshShell.Popup( msgStr, nSecondsToWait, strTitle, nType );
  if ( msgBox == 6 ) {	// 6:[はい]
    try { IO.Serialize( initialSettings, jsonName ); }
    catch( e ) { isError = true; }
    Sleep( 500 );
    var jsonContents = JsonContents( jsonPath, bool );
    if ( ! isError && IO.Path.IsExist( jsonPath ) && jsonContents.length ) {
      msgStr = "設定ファイルを初期化しました。"
             + ( bool ? "(※デコードして表示)" : "" ) + " \n\n"
             + jsonContents;
      var nType = 64;	// ボタン 0:[OK]、 アイコン 64:[i]
      WshShell.Popup( msgStr, nSecondsToWait, strTitle, nType );
    }
    else if ( isError ) {
      Alert( e + " \n\n" + jsonPath + "  " );
    }
    else if ( ! isError ) {
      Alert( "設定ファイルを初期化できませんでした。 \n\n"
           + jsonDir + "  " );
    }
  }
}

/** 
 * 関数 JsonDir()
 * ※「読みなおし」マクロ用改造版
 * JSON ファイルの親フォルダのパス
 */
function JsonDir() {
  var jsonDir;
  var WshShell = new ActiveXObject( "WScript.Shell" );
  if ( IO.Path.IsExist( editor.FullName.replace( /\.exe$/i, ".ini" ) ) ) {
    jsonDir = editor.FullName.replace( /[^\\]+$/i, "" )
            + "Macros\\MacroSettings";
  }
  else {
    jsonDir = WshShell.SpecialFolders( "APPDATA" )
            + "\\Mery\\MacroSettings";
  }
  return jsonDir;
}

/** 
 * 関数 JsonContents( jsonPath [, bool] )
 * JSON ファイルの文字列をメッセージボックス用に整形する
 */
function JsonContents( jsonPath, bool ) {
  var contents = ( jsonPath + "  \n"
  + IO.LoadFromFile( jsonPath )
      .replace( /^\{/, "\n{\n  " )
      .replace( /\}$/g, "  \n}\n\n" )
      .replace( /,/g, " ,\n  " )
      .replace( /\":/g, "\": " )
  );
  if ( bool ) {
    // 「テキスト整形」マクロ(masme 氏)より >> 符号化/復号化 >> \uHHHH デコード
    var Decode_uHHHH = function( str ) {
      return str.replace( /\\u([0-9A-Fa-f]{4})/g, function( s, n ) {
        return String.fromCharCode( Number( "0x" + n ) )
      } )
    };
    contents = Decode_uHHHH( contents );
  }
  // 半角アルファベットの小文字を全角にする
  contents = contents.replace( /[a-z]/g, function( tmp ) {
    return String.fromCharCode( tmp.charCodeAt( 0 ) + 0xFEE0 )
  } );
  return contents;
}


外部実行ファイルで「フォルダにコピー」[編集]

/*
 * ◆ 「フォルダにコピー」 で使用する実行ファイルを指定する場合
 *    WshShell.Run( "\"" + toolCopy + "\"" + toolCopyOptions );
 *   で実行する
 * ※ 実行ファイルのパスが通っていない場合はフルパスで指定すること
 * ※ コマンドライン引数 toolCopyOptions の先頭にはスペース " " を入れること
 */


// RoboCopy の場合(※ e.g. 更新日時が新しければ上書き: /XO )
toolCopy = "RoboCopy.exe";
toolCopyOptions = " \"" + d.Path.slice( 0, -1 ) + "\""	// Source Dir
                + " \"" + desktopDir + "\""			 // Destination Dir
                + " \"" + d.Name + "\""				 // File
                + " /B /XO /COPY:DAT /R:1 /W:1";	// Options (Bacup, exclude older)


// TeraCopy の場合(※ e.g. 上書きなし >> 別名で保存: /RenameAll )
// ※ 最新上書き: /OverwriteOlder // 上書き: /OverwriteAll  // スキップ: /SkipAll
toolCopy = "C:\\Progrm Files\\TeraCopy\\TeraCopy.exe";
toolCopyOptions = " Copy"					// Operation
                + " \"" + d.Path + "\""		// Source
                + " \"" + desktopDir + "\""	// Target
                + " /RenameAll /Close";		// 別名で保存: /RenameAll


// Xcopy の場合(※ e.g. 上書き確認あり)
toolCopy = "xcopy.exe";
toolCopyOptions = " \"" + d.Path + "\""		// <source>
                + " \"" + desktopDir + "\""	// <Destination>
                + " /g /k /r /h /-y";		// options


// FastCopy の場合(※ e.g. サイズもしくは更新日時が違う場合のみ上書き)
// ※ 日付が新しければ上書き: /cmd=update  // つねに上書き: /cmd=force_copy
toolCopy = "C:\\Progrm Files\\FastCopy\\FastCopy.exe";
toolCopyOptions = " /cmd=deff"	// サイズか日付が違えば上書き:	/cmd=deff
                + " /auto_close /error_stop"
                + " \"" + d.Path + "\""				// file
                + " /to=\"" + desktopDir + "\"";	// dest_dir


// FireFileCopy の場合(※ e.g. 上書き確認あり)
toolCopy = "C:\\Progrm Files\\FFC\\FFC.exe";
toolCopyOptions = " \"" + fullPath + "\""		// from
                + " /to:\"" + desktopDir + "\""	// to
                + " /copy /ft:3"	// options	強制上書きは " /a" を追加
                + " /nq /bg /go!";	// options


更新履歴[編集]

2019/03/29:
・初版
2019/04/06 - 2019/04/08:
・「編集モードサブメニュー」を追加。
・Quit() メソッドを削除。
・「プロパティ」を追加。動作コードの記述を簡略化。
2019/04/28 - 2019/04/30:
・「さいごに閉じたファイル」を追加。
・「自動保存フォルダ/バックアップフォルダを開く」を追加。
・エラーの修正。
2019/05/13 - 2019/05/15:
・「親フォルダ/Mery フォルダ/データフォルダを開く」を追加。
・自動保存/バックアップフォルダが Mery のインストールフォルダと同じドライブがあるときに相対パスを検知できなかったミスを修正。
・「編集モード」の状態を Mery.ini から読みこみ。(追加オプション)
・その他の修正と少しだけ高速化(当社比 @ win XP)。
・『sukemaru 自家用』版を追加。
2019/05/19 - 2019/05/21:
・自動保存/バックアップの項目の表示に Mery 本体のバージョンチェックを適用。
・同梱の『sukemaru 自家用』版を『include版』に変更。
2019/05/28 - 2019/05/30:
・「さいごに閉じたファイル」から自動保存・バックアップファイルを除外する設定を追加。
・実体ファイルをデスクトップにコピーする。
・編集モードの手動設定で VBScript と VisualBasic のメニュー ID が重複していたのを修正(VisualBasic 以下の項目の ID を繰り下げ)。
2019/11/30:
通常版/include版 共通
・「Mery フォルダのパスをコピー」 「Mery.exe のフルパスをコピー」 コマンドを追加
・「Mery.ini を開く」 「Mery.txt を開く」 コマンドを追加
・実体ファイルを 「任意のフォルダ にコピー」 するコマンドを追加
・「メモ帳で開く」 「新規タブで開く」 コマンドを追加
・「さいごに閉じたファイル」 のパス中の 「&」 を補完
・「属性変更」 「閉じて開きなおす」 に条件を追加
・コマンドの追加・配置変更にともないアクセラレータを変更
・関数 VersionCheck(), 関数式 ModeCheck(), EncCheck() を削除
・その他、動作コードの変更・修正

include版
・「パスをコピー」コマンドに GetKeyState.exe による拡張機能を追加 ( ¥¥¥ に置換する)
・「Mery.his を開く」「Workspace.ini を開く」コマンドを追加
・「作業フォルダ」関連コマンド(開く/確認/変更)を追加
・「ブラウザで開く」コマンドを追加(実行ファイルの変更可)
・「フォルダにコピー」でのコピー先フォルダの既定値を変更する設定項目を追加
・「『さいごに閉じたファイル』の表示件数をリセットする」コマンドを追加
・「さいごに閉じたファイルを開く」マクロを呼び出す
・その他、動作コードの変更・修正


メモ[編集]

【include版】は、自家用で使っているソースコードから実験的要素を間引いたものにしてあります。当方ではバグのない状態で使用できていますが、公開用のソースコードでは「機能を間引いた」さいにミスをしてしまっている可能性がありますので、お気づきの点がありましたら、こちらのメモ欄の「編集」からお知らせください。

機能を盛りすぎてマクロの処理速度が遅くなってしまいましたが、2回目以降は 0.1 秒程度でポップアップメニューが表示されるようなので、許容範囲内として様子見…。

JSON ファイルを確認ダイアログのスクリーンショット

ファイルを読み直す・開きなおす JSON.png

>> ページの先頭へ


  •  
  •  


スポンサーリンク