位置情報を保存してから「すべて選択/選択解除」(非スクロール)

提供: MeryWiki
ナビゲーションに移動 検索に移動

【include 版】すべて選択/選択解除 (非スクロール)[編集]

「すべて選択 (Ctrl+A)」を実行して全文コピーやステータスバーで文書全体の文字数・行数などを確認したときにキャレットやスクロール位置がスッ飛んでいってしまったり、選択範囲を解除したときにも同様のことが起こったりするので、状況によってはスクロール位置とキャレット位置を元に戻す手間が面倒です…。


以下のふたつのマクロを使って「すべて選択」/「選択範囲を解除」すると、無用なスクロールやキャレット移動がなくなります。
また、ふたつのマクロを交互に実行することで「任意の範囲選択状態」と「すべて選択状態」のトグル切り替えができます。


お好みでツールバー(マクロバー)アイコンに登録するか、キーボードショートカットに割りあててご利用下さい。
※ すでに キーアサイン集 の「すべて選択 (非スクロール)」「選択範囲を解除 (非スクロール)」マクロを導入している場合は、当マクロのソースコードで上書き保存するのがよいとおもいます。


【include版】 すべて選択 (非スクロール)
  • 「すべて選択」を実行する前のキャレット位置とスクロール位置を保存してから「すべて選択 (非スクロール)」を実行します。
    ※ 「すべて選択」前に選択範囲があった場合は、選択範囲の開始/終了位置を保存します。
  • 開いているタブごとに位置情報を保存し、すでに閉じられたタブの情報は逐次削除します。
  • 無題-<n>」タブの情報は ファイル名 = "無題" として保存します。
    ※ 「選択解除」するまえに別の「無題-<m>」タブでこのマクロを実行すると "無題" の位置情報は上書きされます。
【include版】 選択範囲を解除 (非スクロール)
  • 「すべて選択」の状態で実行したときのみ、「【include版】 すべて選択 (非スクロール)」マクロが保存した情報を利用して、キャレット位置とスクロール位置を復元します。
    ※ 保存されている当該タブの位置情報は、このマクロの実行時に削除されます。
    ※「すべて選択」状態を解除したときに復元された選択範囲は、このマクロをもう一度実行すると完全に解除されます。
  • 「【include版】 すべて選択 (非スクロール)」マクロが保存した位置情報がない場合は「選択範囲を解除 (非スクロール)」を実行します。
  • ホイールスクロールなどによりキャレットが表示領域内にない状態、かつ「選択範囲なし」の状態で実行したときは、キャレットのある行まで画面をスクロールします。


  • このページのマクロは、「includeライブラリ」を利用し、外部ファイル(JSON)に情報を保存/参照します。
    あらかじめ「includeライブラリ」を Macros フォルダに配置してください。
  • 外部ファイルの保存場所は Mery\Macros\MacroSettings\<位置情報を保存>.json
    または %AppData%\Mery\MacroSettings\<位置情報を保存>.json です。
  • 環境によっては、外部ファイルへの書き込みの 遅延 などによりエラーが発生することがあるかもしれません。
  • JSON ファイルには、アクティブなタブの 「ファイルパス」 「全文字数」 「選択範囲の開始/終了位置」 「スクロール位置」 「行番号」 を保存します。
    複数のタブで「すべて選択」を実行している場合は、それぞれのタブの情報が保存されます。
  • JSON ファイルへのファイルアクセスが最小限になる仕様にしてあります。
    また、「すべて選択」を実行したときに他のタブで開かれていないファイルの情報があれば、それらのファイル情報は逐次削除するので、JSON ファイルが肥大化することはありません。


選択範囲(キャレット位置)を保存/復帰するためのマクロ を追加しました。

  • 「任意の範囲選択状態」と「すべて選択状態」のトグル切り替えのさいに保存した位置情報を破棄せず、繰り返して「位置を復帰」の操作ができるようになります。


ダウンロード[編集]

>> 「ファイル:【include 版】すべて選択/選択解除.zip (アイコン入り)」

  • 2019/10/21: 【include 版】の第1版
  • 2019/10/27: 【include 版】の第2版(描画速度を微妙に改善)
  • 2019/11/13: 【include 版】の第3版
  • 位置を復帰/保存」マクロを追加
  • マクロ追加により既存マクロのコードを微修正
  • JSON ファイル名の既定値を変更 「すべて選択」 → 「位置情報を保存」


ソースコード[編集]

【include版】 すべて選択 (非スクロール)[編集]

#title = "すべて選択 (位置を保存・非スクロール)"
#tooltip = "位置情報を保存してから すべて選択 (スクロールしない)"
#include "include/IO.js"
// #icon = "select_all.ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",111

// 推奨割当:「Ctrl + A」

/**
 * sukemaru, 2019/10/21 - 2019/11/13 【include 版】
 * 要:include ライブラリ
 * 
 * ・「すべて選択」 前の選択範囲(キャレット位置)とスクロール位置などの
 *   情報を JSON ファイルに書き出す。
 *   → 「選択解除」 「位置を復帰」 マクロで、保存した位置情報に復元可。
 * ※ すべて選択状態から「選択解除」マクロを実行(位置を復帰)すると、
 *    当該ファイルの位置情報は JSON から削除される。
 * 
 * ・JSON にはファイルパスごとに位置情報を保存する。
 * ・JSON のリストに現在開かれていないファイルの情報があれば削除する。
 */

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

// 位置情報の保存用ファイルのベース名
var jsonName = "位置情報を保存";

  // ※ 「すべて選択」 「選択解除」 「位置を復帰」 マクロで同一の名前を指定すること
  // 保存先は…		(e.g. "位置情報を保存" の場合)
  // ・ポータブル版: Mery\Macros\MacroSettings\位置情報を保存.json
  // ・インストール版: %AppData%\Mery\MacroSettings\位置情報を保存.json
  
// ---------- ▲ 設定項目 ▲ ----------

var d = editor.ActiveDocument,  s = d.selection;
var dText = d.Text,  dLength = dText.length;

if ( s.Text.length != dLength ) {
  /**
   *  フルパス、文字数
   *  選択範囲の開始/終了位置(anc, act)
   *  スクロール位置(sx, sy)、アクティブ行(ay)
   */
  var dPath = d.FullName || "無題";
  var anc = s.GetAnchorPos(),  act = s.GetActivePos();
  var sx = ScrollX,  sy = ScrollY;
  var ay = s.GetActivePointY( mePosLogical );

  // すべて選択 (スクロールしない)
  Redraw = false;
  s.SelectAll();
  ScrollX = sx;  ScrollY = sy;
  Redraw = true;

  var setting = { fileList: [] };
  setting = IO.Deserialize( setting, jsonName );	// JSON 読み込み
  var list = setting.fileList;
  var infoExist = false;

  for ( var i = 0, path; i < list.length; i ++ ) {
    path = list[i][0];

    // リストにファイルの情報があれば書き換える
    if ( path == dPath ) {
      infoExist = true;
      list[i] = [ dPath, dLength, anc, act, sx, sy, ay ];
    }
    // リストに現在開かれていないファイルの情報があれば削除する
    else {
      var eCount = Editors.Count;
      var docus,  dCount,  filePath,  hit;
      for ( var ee = 0, hit = 0; ee < eCount; ee ++ ) {
        docus = Editors.Item( ee ).Documents;
        dCount = docus.Count;
        for ( var dd = 0; dd < dCount; dd ++ ) {
          filePath = docus.Item( dd ).FullName;
          if ( path == filePath ) { hit ++ }
        }
      }
      if ( ! hit ) { list.splice( i --, 1 ) }
    }
  }

  // リストにファイルの情報がなければ追加する
  if ( ! infoExist ) {
    list.push( [ dPath, dLength, anc, act, sx, sy, ay ] );
  }

  setting.fileList = list;
  IO.Serialize( setting, jsonName );	// JSON 書き込み
}


/*
 * JSON ファイルの初期値
 * {"fileList":[]}
 */


【include版】 選択範囲を解除 (非スクロール)[編集]

#title = "選択解除 (位置を復帰・非スクロール)"
#tooltip = "範囲選択を解除 (スクロールしない) または 位置を復帰"
#include "include/IO.js"
// #icon = "selection_collapse.ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",212

// 推奨割当:「Esc」

/**
 * sukemaru, 2019/10/21 - 2019/11/13 【include 版】
 * 要:include ライブラリ
 * 
 * ・「すべて選択」マクロ実行前の
 *    選択範囲(キャレット位置)とスクロール位置の情報を
 *   JSON ファイルから読みこんで復元する(位置を復帰)。
 * ・「すべて選択」以外の範囲選択状態から実行したときは
 *    スクロールなしで範囲選択を解除する。
 * ・「範囲選択なし」の状態から実行したときはキャレット位置までスクロールする。
 * 
 * ※「すべて選択」の状態から「位置を復帰」したときのみ
 *    当該ファイルの位置情報を JSON から削除する。
 */

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

// 位置情報の保存用ファイルのベース名
var jsonName = "位置情報を保存";

  // ※ 「すべて選択」 「選択解除」 「位置を復帰」 マクロで同一の名前を指定すること
  // 保存先は…		(e.g. "位置情報を保存" の場合)
  // ・ポータブル版: Mery\Macros\MacroSettings\位置情報を保存.json
  // ・インストール版: %AppData%\Mery\MacroSettings\位置情報を保存.json
  
// ---------- ▲ 設定項目 ▲ ----------

var d = editor.ActiveDocument,  s = d.selection;
var dText = d.Text,  dLength = dText.length;
var act = s.GetActivePos();
var sx = ScrollX,  sy = ScrollY;
Redraw = false;

// 「すべて選択」状態のとき
if ( s.Text.length == dLength ) {
  var dPath = d.FullName || "無題";

  var setting = { fileList: [] };
  setting = IO.Deserialize( setting, jsonName );	// JSON 読み込み

  var list = setting.fileList;
  var len = list.length;
  var infoExist = false;
  var fileInfo;

  for ( var i = 0; i < len; i ++ ) {

    // リストにファイル情報があれば
    if ( list[i][0] == dPath ) {
      infoExist = true;
      fileInfo = list[i];

      /**
       * list[i] = [ dPath, dLength, anc, act, sx, sy ]
       *  フルパス、文字数
       *  選択範囲の開始/終了位置(anc, act)
       *  スクロール位置(sx, sy)
       */
      // 文書の文字数が同じなら、選択範囲とスクロール位置を復元
      if ( fileInfo[1] == dLength ) {
        Restore( fileInfo[3], fileInfo[4], fileInfo[5], fileInfo[2] );
      }
      // 文書の文字数が異なるなら、選択解除 (スクロールしない)
      else {
        Restore( act, sx, sy );
      }

      // リストからファイル情報を削除
      list.splice( i, 1 );
      setting.fileList = list;
      IO.Serialize( setting, jsonName );	// JSON 書き込み
      break;
    }
  }
}

// 「すべて選択」以外の範囲選択状態のときは、選択解除 (スクロールしない)
if ( ! infoExist && s.Text ) {
  Restore( act, sx, sy );
}

// 「選択範囲なし」の状態のときは、キャレット位置までスクロールする
else if ( ! infoExist && s.IsEmpty ) {
  s.SelectLine();
  s.SetActivePos( act );
}

Redraw = true;


// 関数 Restore( activePos, scrollX, scrollY [, anchorPos] )
function Restore( act, sx, sy, anc ) {
  anc = anc >= 0 ? anc : act;
  editor.ActiveDocument.selection.SetActivePos( anc );
  editor.ActiveDocument.selection.SetActivePos( act, true );
  ScrollX = sx;  ScrollY = sy;
}


【include 版】位置を復帰/保存[編集]

単純に キャレット位置(選択範囲)を 保存/復元 するためのマクロです。

ファイル内の閲覧のさいのスクロールや検索操作をする前などに、任意の位置(キャレット位置/選択範囲/アクティブ行)を 一時保存 し、任意のタイミングで復帰することができます。

※「位置情報を保存」と「位置を復帰」操作のあいだに編集操作(文書全体の文字数の変化)があった場合、復帰先は 保存したアクティブ行番号の行頭位置 になります。
※ 「【include版】 すべて選択 (非スクロール)」マクロや「【include版】 選択範囲を解除 (非スクロール)」マクロと連携させて利用する前提で、位置情報保存用の JSON ファイルを共用します。

  • Ctrl キーを押しながらこのマクロを実行したときは「位置情報を保存」します。
※ ファイル名、文字数、選択範囲(キャレット位置)とスクロール位置などの情報を JSON ファイルに書き出します。
  • Ctrl キーを押さずにこのマクロを実行したときは「位置を復帰」します。
※ Ctrl キーを押しながらこのマクロを実行して保存したときの位置情報か、「【include版】 すべて選択 (非スクロール)」マクロ実行前のキャレット位置(選択範囲)を JSON ファイルから読みこんで復元します。
  • JSON ファイルに保存された情報と文字数がことなるときは、保存された行番号(論理行)の行頭に復帰します。
※ 保存されたスクロール位置を復帰せず、キャレット位置までスクロールします。
  • 「位置を復帰」の前後でキャレット位置(選択範囲)に変化がないとき、または JSON ファイルに位置情報がないときは、キャレット位置までスクロールするだけです。


  • 「位置を復帰」の動作では JSON ファイルに保存された位置情報を削除しません。
※ Ctrl キーを押しながらこのマクロを実行したとき、または「【include版】 すべて選択 (非スクロール)」マクロ実行時の「位置情報を保存」処理のさいに、開かれていないファイルの位置情報は JSON から削除されます。
  • このマクロには アクティブタブの位置情報を削除 する機能はありません。
このマクロで保存した位置情報を、当該ファイルのタブを閉じずに削除したい場合は、「【include版】 すべて選択 (非スクロール)」マクロと「【include版】 選択範囲を解除 (非スクロール)」マクロをつづけて実行してください。
※「すべて選択」の状態から「選択解除」マクロを実行すると(位置の復帰動作)、当該ファイルの位置情報は JSON から削除されます。
※ このマクロ単独で「位置情報を保存/位置を復帰」の運用をする場合、JSON から位置情報を削除するには、当該ファイルのタブを閉じた状態で 別のタブ上から「位置情報を保存」の操作 をするしかありません (Shift キー押し下げで「削除」という方法もありますが、実行時のタイムラグが大きくなるので保留)。
  • このマクロは、「includeライブラリ」を利用し、外部ファイル(JSON)に情報を保存/参照します。
    あらかじめ「includeライブラリ」を Mery\Macros フォルダに配置してください。
  • 外部ファイルの保存場所は Mery\Macros\MacroSettings\<位置情報を保存>.json
    または %AppData%\Mery\MacroSettings\<位置情報を保存>.json です。
  • 環境によっては、外部ファイルへの書き込みの 遅延 などによりエラーが発生することがあるかもしれません。
  • 外部ファイルは「【include版】 すべて選択 (非スクロール)」「【include版】 選択範囲を解除 (非スクロール)」マクロと共用する前提にしてあります。
あらかじめ ZIP ファイルをダウンロード・解凍して、実行ファイル「GetKeyState.exe」を Mery\Macros フォルダに配置してください。


ソースコード[編集]

#title = "位置を復帰/保存"
#tooltip = "選択範囲(カーソル位置)を復帰 または 位置情報を保存"
#include "include/IO.js"
// #icon = "arrows_swap_vertical[1].ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",224

/**
 * sukemaru, 2019/11/13 【include 版】
 * 要:include ライブラリ
 * 要: GetKeyState.exe
 * 
 * ※ 能書きはソースコード末尾のコメントブロックに。
 */

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

// ■ 位置情報の保存用ファイルのベース名
var jsonName = "位置情報を保存";

  // ※ 「すべて選択」 「選択解除」 「位置を復帰」 マクロで同一の名前を指定すること
  // 保存先は…		(e.g. "位置情報を保存" の場合)
  // ・ポータブル版: Mery\Macros\MacroSettings\位置情報を保存.json
  // ・インストール版: %AppData%\Mery\MacroSettings\位置情報を保存.json

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

var $ctrl = 0;
var getKeyState = editor.FullName.replace( /[^\\]+$/i , "" )
                + "Macros\\GetKeyState.exe";
var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
if ( Fso.FileExists( getKeyState ) ) {
  var WshShell = new ActiveXObject( "WScript.Shell" );
  $ctrl = WshShell.Run( "\"" + getKeyState + "\" ctrl", 0, true );
}

var d = editor.ActiveDocument,  s = d.selection;
var dPath = d.FullName || "無題";
var dText = d.Text,  dLength = dText.length;
var act = s.GetActivePos(),  anc = s.GetAnchorPos();
var sx = ScrollX,  sy = ScrollY;

var setting = { fileList: [] };
setting = IO.Deserialize( setting, jsonName );	// JSON 読み込み
var infoExist = false;

var list = setting.fileList;
var len = list.length;

// 位置を復帰
if ( $ctrl == 0 ) {
  Redraw = false;

  for ( var i = 0, fileInfo; i < len; i ++ ) {
    fileInfo = list[i];
      /**
       * list[i] = [ dPath, dLength, anc, act, sx, sy, ay ]
       *  フルパス、文字数
       *  選択範囲の開始/終了位置(anc, act)
       *  スクロール位置(sx, sy)
       */

    // リストにファイル情報があれば
    if ( fileInfo[0] == dPath ) {
      infoExist = true;

      // 文書の文字数が同じなら、選択範囲(キャレット位置)を復元
      if ( fileInfo[1] == dLength ) {
        s.SetAnchorPos( fileInfo[2] );
        s.SetActivePos( fileInfo[3], true );
        ScrollX = fileInfo[4];
        ScrollY = fileInfo[5];
      }
      else {
        // 文書の文字数が異なるなら、行番号(行頭)に復帰
        s.SetActivePoint( mePosLogical, 1, fileInfo[6], false );
      }
      // 実行前と選択範囲が同じならスクロールする
      if ( s.GetActivePos() == act && s.GetAnchorPos() == anc ) {
        var yy = s.GetActivePointY( mePosView );
        ScrollY = yy;
        // var xx = s.GetActivePointX( mePosView );
        // ScrollX = xx;
      }
      break;
    }
  }

  // ファイル情報がないときは、キャレット位置までスクロールするだけ
  if ( ! infoExist  ) {
    s.SetActivePos( anc );
    s.SetActivePos( act, true );
  }

  Redraw = true;
}

// 位置情報を保存
else if ( $ctrl == 1 ) {
  /**
   *  フルパス、文字数
   *  選択範囲の開始/終了位置(anc, act)
   *  スクロール位置(sx, sy)、アクティブ行(ay)
   */
  var ay = s.GetActivePointY( mePosLogical );
  for ( var i = 0, path; i < list.length; i ++ ) {
    path = list[i][0];

    // リストにファイルの情報があれば書き換える
    if ( path == dPath ) {
      infoExist = true;
      list[i] = [ dPath, dLength, anc, act, sx, sy, ay ];
    }

    // リストに現在開かれていないファイルの情報があれば削除する
    else {
      var eCount = Editors.Count;
      var docus,  dCount,  filePath,  hit;
      for ( var ee = 0, hit = 0; ee < eCount; ee ++ ) {
        docus = Editors.Item( ee ).Documents;
        dCount = docus.Count;
        for ( var dd = 0; dd < dCount; dd ++ ) {
          filePath = docus.Item( dd ).FullName;
          if ( path == filePath ) { hit ++ }
        }
      }
      if ( ! hit ) { list.splice( i --, 1 ) }
    }
  }

  // リストにファイルの情報がなければ追加する
  if ( ! infoExist ) {
    list.push( [ dPath, dLength, anc, act, sx, sy, ay ] );
  }

  setting.fileList = list;
  IO.Serialize( setting, jsonName );	// JSON 書き込み
}


/**
 * ・Ctrl キーを押しながらこのマクロを実行したときは「位置情報を保存」する。
 *  ※ ファイル名、文字数、選択範囲(キャレット位置)とスクロール位置などの
 *    情報を JSON ファイルに書き出す。
 * 
 * ・Ctrl キーを押さずにこのマクロを実行したときは「位置を復帰」する。
 *  ※ Ctrl キーを押しながらこのマクロを実行して保存した位置情報か、
 *   「すべて選択」マクロ実行前のキャレット位置(選択範囲)を
 *    JSON ファイルから読みこんで復元する。
 * 
 * ・JSON ファイルに保存された情報と文字数がことなるときは、
 *   保存された行番号(論理行)の行頭に復帰する。
 *  ※ 保存されたスクロール位置を復帰せず、キャレット位置までスクロールする。
 * 
 * ・「位置を復帰」の前後でキャレット位置(選択範囲)に変化がないとき、
 *   または JSON ファイルに位置情報がないときは、
 *   キャレット位置にスクロールするだけ。
 * 
 * ・「位置を復帰」の動作では JSON ファイルに保存された位置情報を削除しない。
 *  ※ Ctrl キーを押しながらこのマクロを実行したとき、
 *     または「すべて選択」マクロ実行時の「位置情報を保存」処理のさいに、
 *     開かれていないファイルの位置情報は JSON から削除される。
 * 
 * ・このマクロで保存した位置情報を、当該ファイルのタブを閉じずに削除したい場合は、
 *   「すべて選択」マクロと「選択解除」マクロをつづけて実行する。
 *  ※「すべて選択」の状態から「選択解除」マクロを実行したとき(位置の復帰動作)
 *     当該ファイルの位置情報は JSON から削除される。
 *  ※ このマクロ単独で「位置情報を保存/位置を復帰」の運用をする場合、
 *     JSON から位置情報を削除するには、当該ファイルのタブを閉じた状態で
 *     別のタブ上から「位置情報を保存」操作をするしかない。
 */
スポンサーリンク