「ブックマーク一覧ジャンプ」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
Sukemaru (トーク | 投稿記録)
Sukemaru (トーク | 投稿記録)
sukemaru版のソースコードと ZIP を更新
1行目: 1行目:
ポップアップメニューでジャンプ先を選択。範囲指定中はジャンプ先まで選択範囲を拡大します。
ポップアップメニューでジャンプ先を選択。範囲指定中はジャンプ先まで選択範囲を拡大します。


= goat版 =
= goat 版 =


Mery Ver.1.1.2.2840 および Ver.2.0.9.3936 での動作を確認しています。
Mery Ver.1.1.2.2840 および Ver.2.0.9.3936 での動作を確認しています。
81行目: 81行目:




= sukemaru版 =
= sukemaru 版 =


goat さんのソースコードを元にして、ポップアップメニューを表示するまでの速度をすこしだけ改善しました。
goat 版のソースコードを元にして、ポップアップメニューを表示するまでの速度をすこしだけ改善しました。




goat 版からの変更点
;▼ goat 版からの変更点
* ソースコード内の設定項目から "表示行" / "論理行" の選択可(初期値は "論理行")
* ソースコード内の設定項目から "表示行" / "論理行" の選択可(初期値は "論理行")
* 設定項目で "ジャンプ先までの範囲選択" はしない状態を初期値にした
* 設定項目で "ジャンプ先までの範囲選択" はしない状態を初期値にした
* ブックマーク行の文字列取得 メニューに表示するラベルの生成 の速度を改善
* ブックマーク行の検索 ポップアップメニューの表示 までの速度を改善
* ポップアップメニューの体裁を変更(「[[ポップアップメニューで検索先にジャンプ#sukemaru_版|検索ジャンプ]]」マクロにあわせた)
* ポップアップメニューの体裁を変更(「[[ポップアップメニューで検索先にジャンプ#sukemaru_版|検索ジャンプ]]」マクロにあわせた)
* ステータスバーにブックマーク件数などの情報を表示
* ステータスバーにブックマーク件数などの情報を表示
* 「ブックマークがありません」メニュー(先頭行か最終行にジャンプ可)。
* ジャンプしたときのスクロール位置を調整。
Mery でプログラミング用のフォントを使っている人だと、ポップアップメニュー内で半角 '''¥''' 記号 (U+005C) が'''バックスラッシュ''' (U+005C) にならないのは気落ち悪いかも? ということで、ソースコード内の関数 MenuKey() のコードのコメントアウトしてある行を有効化すると "擬似的に" '''バックスラッシュ'''化できます <br> (※「∖」(U+2216) に置換して表示します)。


== ソースコード ==
== ソースコード ==


'''ダウンロード:''' 「[[ファイル:ブックマーク一覧ジャンプ.zip]]」(アイコン入り) 
'''ダウンロード:''' 「[[ファイル:ブックマークジャンプ.zip]]」(アイコン入り) 
<br> 最終更新: 2019/04/07 (Quit メソッドを削除)
<br> 最終更新: 2019/04/08
----


* このマクロではポップアップメニューの表示に EN SPACE「 」(U+2002) を使用します。ファイルに保存するさいは、文字コードを Shift JIS にしないでください('''UTF-8''' などの Unicode )。
* このマクロではポップアップメニューの表示に EN SPACE「 」(U+2002) などを使用します。ファイルに保存するさいは、文字コードをシフト JIS にしないでください('''UTF-8''' Unicode で保存する)。
<source lang="javascript" style="height:60em; overflow:auto;">
<source lang="javascript" style="height:60em; overflow:auto;">
#title = "ブックマーク一覧ジャンプ"
#title = "ブックマーク一覧ジャンプ"
109行目: 115行目:
  * 「ブックマーク一覧ジャンプ」
  * 「ブックマーク一覧ジャンプ」
  *  Orginal created by:  goat  (Last update:  2012/09/24)
  *  Orginal created by:  goat  (Last update:  2012/09/24)
  *  Modified by:  sukemaru     (2018/08/08 - 2019/03/29)
  *  Modified by:  sukemaru (2018/08/08 - 2019/04/08)
  * ---------------------------------------------------------
  * ---------------------------------------------------------
  */
  */
126行目: 132行目:
// ■ 行の表示方法(手動設定)
// ■ 行の表示方法(手動設定)
var $LineColumnView = 0; // ( 0: 論理行 / 1: 表示行 )
var $LineColumnView = 0; // ( 0: 論理行 / 1: 表示行 )
// ■ ポップアップメニューに表示する文字数(全角/半角の区別なし)
var menuWidth = 65;


// ---------- ▲ 設定項目 ▲ ----------
// ---------- ▲ 設定項目 ▲ ----------
132行目: 141行目:
// Mery.ini から「行の表示方法」を取得する( 表示行 = 1 / 論理行 = 0 )
// Mery.ini から「行の表示方法」を取得する( 表示行 = 1 / 論理行 = 0 )
if ( autoLineModeEnable ) {
if ( autoLineModeEnable ) {
   $LineColumnView = GetIniOptionNum( "LineColumnView" );
   lineColumnView = GetIniOptionNum( "LineColumnView" );
}
}
// 表示行/論理行 の定数
// 表示行/論理行 の定数
var posMode = $LineColumnView ? mePosView : mePosLogical;
var posMode = lineColumnView ? mePosView : mePosLogical;
var lineMode = $LineColumnView ? meGetLineView : 0;
var lineMode = lineColumnView ? meGetLineView : 0;


 
var d = editor.ActiveDocument;
var d = document,  s = document.selection;
var s = editor.ActiveDocument.selection;
var lines = d.GetLines( lineMode ).toString();
var lines = d.GetLines( lineMode ).toString(); // 全体の行数
var linesWidth = lines.length;
var linesWidth = lines.length; // 全体の行数のケタ数
 
var ay = s.GetActivePointY( posMode );
var regY = new RegExp( "&" + ay + ":  ", "" );
var lineStr = "";
var bmArray = new Array();
var flgBlock = ! s.isEmpty;
var isTopMarked = false;


//カーソル位置の保存
//カーソル位置の保存
154行目: 156行目:
var anc = s.GetAnchorPos();
var anc = s.GetAnchorPos();
var sx = ScrollX,  sy = ScrollY;
var sx = ScrollX,  sy = ScrollY;
var ay = s.GetActivePointY( posMode );
var by;
var flgBlock = ! s.isEmpty;
var lineStr = "";
var menuKey = "";
var bmArray = new Array(); // ブックマーク行の文字列を収納する


Redraw = false;
Redraw = false;


// 先頭行がブックマークされてないか
// 先頭行がブックマークされているか
s.SetActivePos( 1 );
s.SetActivePos( 1 );
if ( s.PreviousBookmark() ) {
if ( s.PreviousBookmark() ) {
   isTopMarked = true;
   by = s.GetActivePointY( posMode );
  // ブックマーク行の文字列を取得する
   lineStr = d.GetLine( by, lineMode ); // 文字列を取得
   lineStr = d.GetLine( s.GetActivePointY( posMode ), lineMode );
   // メニュー用ラベルを生成して配列に収納する
   // 関数でメニュー用ラベルを生成して配列に収容する
   bmArray.push( [ MenuKey( lineStr, by ), by ] );
   bmArray.push( MenuKey( lineStr, s.GetActivePointY( posMode ) ) );
}
}
else {
  s.StartOfDocument();
}
// 2行目以降のブックマークを探す
// 2行目以降のブックマークを探す
s.SetActivePos( 0 );
while ( s.NextBookmark() ) {
while ( s.NextBookmark() ) {
   // ブックマーク行の文字列を取得する
   by = s.GetActivePointY( posMode );
   lineStr = d.GetLine( s.GetActivePointY( posMode ), lineMode );
   lineStr = d.GetLine( by, lineMode ); // 文字列を取得
   // 関数でメニュー用ラベルを生成して配列に収容する
   // メニュー用ラベルを生成して配列に収納する
   bmArray.push( MenuKey( lineStr, s.GetActivePointY( posMode ) ) );
   bmArray.push( [ MenuKey( lineStr, by ), by ] );
}
}
// カーソル位置を復帰
s.SetActivePos( act );
s.SetAnchorPos( anc );
ScrollX = sx;
ScrollY = sy;


// ブックマークの件数
// ブックマークの件数
var bmCount = bmArray.length;
var bmCount = bmArray.length;


// ブックマークがなければカーソル位置を復帰して終了
// 「ブックマークがありません」ポップアップメニュー
if ( ! bmCount ) {
if ( ! bmCount ) {
   s.SetActivePos( act );
   var statusStr1 = " ブックマークがありません。"
  s.SetAnchorPos( anc );
  var statusStr2 = " 全体の行数: "
   ScrollX = sx, ScrollY = sy;
                + lines.replace( /(\d)(?=(?:\d{3})+$)/g , "$1," )  
                + ( lineColumnView ? " 行 (表示行)" : " 行 (論理行)" );
   Status = statusStr1 + statusStr2 + TimerElapsed( new Date(), start );


   // ステータスバーにキャンセルメッセージ
   var menu = CreatePopupMenu();
   Status = " ブックマークがありません。/ 全体の行数: "  
   menu.Add( "※" + statusStr1 + "& ※", 0 );
        + lines.replace( /(\d)(?=(?:\d{3})+$)/g , "$1," )  
  menu.Add( statusStr2 + "& ", 0 );
        + ( $LineColumnView ? " 行 (表示行)" : " 行 (論理行)" )
  menu.Add( "", 0, meMenuSeparator );
        + TimerElapsed( new Date(), start );
  menu.Add( "   先頭行へジャンプ (&S)", 1 );
  menu.Add( "   最終行へジャンプ (&E)", + lines );
 
  var y = menu.Track( mePosMouse );
  if ( y > 0 ) {
    s.SetActivePoint( posMode, 1, y );
  }
}
}


// ブックマークがあればポップアップメニューを表示
// 「ブックマーク一覧」ポップアップメニュー
else {
else { // if ( bmCount )
   var BookmarkMenu = CreatePopupMenu();
   var BookmarkMenu = CreatePopupMenu();
   // メニューの上部に「キャンセル」行をピン止め
   // メニューの上部に「キャンセル」行をピン止め
   BookmarkMenu.Add( ( "          " ).slice( - linesWidth - 1 ) + " キャンセル& ", 0 );
   BookmarkMenu.Add( ( "          " ).slice( - linesWidth - 1 )
 
                  + " キャンセル& ", 0 );
   for ( var i = 0, flags; i < bmCount; i ++ ) {
  var flags;
   for ( var i = 0; i < bmCount; i ++ ) {
     // 10行ごとにセパレータ
     // 10行ごとにセパレータ
     if ( i % 10 == 0 ) {
     if ( i % 10 == 0 ) {
       BookmarkMenu.Add( "", 0, meMenuSeparator );
       BookmarkMenu.Add( "", 0, meMenuSeparator );
     }
     }
     // アクティブ行にはチェックマークフラグ
     // アクティブ行にチェックマークフラグ
     flags = regY.test( bmArray[i] ) ? meMenuChecked : 0;
     flags = ( bmArray[i][1] == ay ) ? meMenuChecked : 0;
 
    // ブックマーク行をポップアップメニューに追加
     BookmarkMenu.Add( bmArray[i], i + 1, flags )
     BookmarkMenu.Add( bmArray[i][0], bmArray[i][1], flags );
   }
   }


  // ステータスバーにヒット件数を表示
   Status = " ブックマーク:" + bmCount
   Status = "  " + bmCount
         + " 件  / 全体の行数: "  
         + " 件  / 全体の行数: "  
         + lines.replace( /(\d)(?=(?:\d{3})+$)/g , "$1," )   
         + lines.replace( /(\d)(?=(?:\d{3})+$)/g , "$1," )   
         + ( $LineColumnView ? " 行 (表示行)" : " 行 (論理行)" )
         + ( lineColumnView ? " 行 (表示行)" : " 行 (論理行)" )
         + TimerElapsed( new Date(), start );
         + TimerElapsed( new Date(), start );


   // ポップアップメニューを表示
   // ポップアップメニューを表示
   // Track(0);ならキャレット位置にサブメニューがポップアップ
   var y = BookmarkMenu.Track( mePosMouse );
   // Track(1);ならカーソル位置にサブメニューがポップアップ
   // ジャンプ
  var r = BookmarkMenu.Track( 1 );
  if ( y > 0 ) {
    s.SetActivePoint( posMode, 1, y );
    ScrollY = ( ScrollY == sy ) ? sy
                                : s.GetActivePointY( mePosView );


  // キャンセル → カーソル位置の復帰
     // ジャンプ前の選択開始位置からジャンプ後の行まで範囲選択
  if ( r == 0 ) {
    s.SetActivePos( act );
    s.SetAnchorPos( anc );
    ScrollX = sx,  ScrollY = sy;
  }
 
  // ジャンプ
  else  {
    s.StartOfDocument();
    if( isTopMarked ) {
      r --;
    }
    for( i = 0; i < r; i ++ ) {
      s.NextBookmark();
    }
     // ジャンプ前の選択開始位置からジャンプ後のカーソル位置まで範囲選択
     if ( flgBlockEnable && flgBlock ) {
     if ( flgBlockEnable && flgBlock ) {
       s.SetAnchorPos( anc );
       s.SetAnchorPos( anc );
       if ( ay < s.GetActivePointY( posMode ) ) {
       if ( ay < s.GetActivePointY( posMode ) ) {
         s.EndOfLine( true, mePosLogical );
         s.EndOfLine( true, posMode );
       }
       }
     }
     }
    ScrollY = s.GetActivePointY( mePosView );
   }
   }
}
}
253行目: 258行目:




// ---------------------------------------------------------
// ---------- ▼ 関数 ▼ ----------


/* 関数 MenuKey( str, num ) */
/**
// ポップアップメニューに表示するラベルを生成する
* 関数 MenuKey( str, num )
* ポップアップメニューに表示するラベルを生成する
* ・行頭空白を除去
* ・空白文字を圧縮
* ・削られてしまう「&」を補完
* ・判別しづらいメタ文字を全角に置換
* ・文字数を切り詰め
* ・行番号をケタ埋め: EN SPACE「 」(U+2002)
*  ▼ 2019/03/30 追加 ▼
* ・「\」を「∖」に置換: 「∖」(U+2216) または「╲」(U+2572) 「﹨」(U+FE68)
* ・「a-z」を全角に置換
*/
function MenuKey( str, num ) {
function MenuKey( str, num ) {
  // 行頭空白を除去/空白文字を圧縮/削られてしまう "&" を補完/判別しづらいメタ文字を全角に
   var menuKey = str.replace( /^[\t  ]+/ , "" )
   var menuKey = str.replace( /^[\t  ]+/ , "" )
                   .replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g , " › " )
                   .replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g , " › " )
                   .replace( /&/g , "&&" )
                   .replace( /&/g , "&&" )
                  .replace( /[.,:;(){}|!%']/g ,
                // .replace( /[\\]/g , "∖" )
                      function( $0 ) {
                // .replace( /([^∖!"',.:;`|\t  ])([∖]+)/g , "$1 $2" )
                        return String.fromCharCode( $0.charCodeAt( 0 ) + 0xFEE0 )
                  .replace( /[!"%'(),.:;@\[\]`a-z{|}]/g ,
                      } )
                    function( $0 ) {
                  .slice( 0, 50 ); // 文字数を圧縮
                      return String.fromCharCode( $0.charCodeAt( 0 ) + 0xFEE0 )
 
                    } );
  menuKey = ( menuKey.length > menuWidth )
          ? menuKey.slice( 0, menuWidth ) + " ..."
          : menuKey;
   return ( "          \&" + num ).slice( - linesWidth - 1 ) + ":  " + menuKey;
   return ( "          \&" + num ).slice( - linesWidth - 1 ) + ":  " + menuKey;
}
}




/* 関数 TimerElapsed( end, start ) */
/**
// start からの経過時間を [ s.sss 秒 ] で返す
* 関数 TimerElapsed( end, start )
* start からの経過時間計測
* [ s.sss 秒 ] で返す
*/
function TimerElapsed( end, start ) {
function TimerElapsed( end, start ) {
   var elapsed = end - start;
   var elapsed = ( end - start ) / 1000;
   return "  [ "
   return "  [ "
         + ( ( elapsed / 1000 ) + "000" ).replace( /(\.)(\d{3})(0*)/, "$1 $2" )
         + ( elapsed + "000" ).replace( /(\.)(\d{3})(0*)/, "$1 $2" )
         + " 秒 ]";
         + " 秒 ]";
}
}




/* 関数 GetIniOptionNum( key ) */
/**
// 引数で指定された設定項目の「値」を返す(※数値1ケタ)
* 関数 GetIniOptionNum( key )
* 引数で指定された設定項目の「値」を返す(※数値1ケタ)
*/
function GetIniOptionNum( key ) {
function GetIniOptionNum( key ) {
   var regIniKey = new RegExp( "^" + key + "=\\d$", "m" );
   var regIniKey = new RegExp( "^" + key + "=\\d$", "m" );
296行目: 319行目:
   var iniFile = Fso.OpenTextFile( iniPath, 1 );
   var iniFile = Fso.OpenTextFile( iniPath, 1 );
   var iniText = iniFile.ReadAll();
   var iniText = iniFile.ReadAll();
  iniFile.Close();
   // 項目の値を取得する
   // 項目の値を取得する
   var dist = + iniText.match( regIniKey ).shift().slice( - 1 );
   var dist = + iniText.match( regIniKey ).shift().slice( - 1 );
   iniFile.Close();
   iniFile.Close();
   return dist;
   return dist;
}
</source>
== バックスラッシュ化 ==
Mery でプログラミング用のフォントを使っている人だと、ポップアップメニュー内で半角 '''¥''' 記号 (U+005C) が'''バックスラッシュ''' (U+005C) にならないのは気落ち悪いかも? ということで。
: MenuKey() 関数の replace() 重ねがけ部分に以下のようなコードをはさむと "擬似的に" '''バックスラッシュ'''化できます。 <br> ※「∖」(U+2216) に置換して表示します。
<source lang="javascript">
// ※追加コードを replace() の重ねがけ部分に挟みこむ
/* 関数 MenuKey( str, num ) */
// ポップアップメニューに表示するラベルを生成する
function MenuKey( str, num ) {
  var menuKey = str.replace( /^[\t  ]+/ , "" )
                  .replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g , " › " )
                  .replace( /&/g , "&&" )
// ※追加コード ここから ----------
                  // 半角の「¥」を「∖」(U+2216) に置換
                  // ※または ╲(U+2572), ﹨(U+FE68)
                  .replace( /[\\]/g , "∖" )
                  // 見づらいようなら前後に空白を追加
                // .replace( /([^∖:])([∖]+)([^∖])?/g , "$1 $2 $3" )
// ※追加コード ここまで ----------
                  .replace( /[.,:;(){}|!%']/g ,
                      function( $0 ) {
                        return String.fromCharCode( $0.charCodeAt( 0 ) + 0xFEE0 )
                      } )
                  .slice( 0, 50 );
  return ( "          \&" + num ).slice( - linesWidth - 1 ) + ":  " + menuKey;
}
}
</source>
</source>

2019年4月8日 (月) 21:19時点における版

ポップアップメニューでジャンプ先を選択。範囲指定中はジャンプ先まで選択範囲を拡大します。

goat 版

Mery Ver.1.1.2.2840 および Ver.2.0.9.3936 での動作を確認しています。 (2012.09.24)

 #title="ブックマーク一覧"
 /*
 * ブックマーク一覧をポップアップメニューにして選択ジャンプ
 * Mery標準のブックマークが対象
 * 範囲選択中の場合は選択範囲を拡大
 */
 (function(){
   // 描画停止
   Redraw = false;
   with(document.selection){
     var flgBlock = !isEmpty;
     //カーソル位置の保存
     var activePos = GetActivePos();
     var anchorPos = GetAnchorPos();
     var sX = ScrollX;
     var sY = ScrollY;
 
     var bookmarks = new Array();
     StartOfDocument(false);
     // 先頭行がブックマークされてないか
     var isTopMarked = false;
     CharRight(false);
     if(PreviousBookmark()){
       isTopMarked = true;
       SelectLine();
       menuKey = Text.slice(0,24).replace(/\t/g, "\\t");
       Collapse();
       bookmarks.push("Line " + GetActivePointY(mePosLogical) + ":\t" + menuKey);
     } else {
       StartOfDocument(false);
     }
     while(NextBookmark()){
       SelectLine();
       menuKey = Text.slice(0, 24).replace(/\t/g, "\\t");
       Collapse();
       bookmarks.push("Line " + GetActivePointY(mePosLogical) + ":\t" + menuKey);
     }
     var bmcount = bookmarks.length;
     if(bmcount == 0){
       //カーソル位置の復帰
       SetActivePos(activePos);
       SetAnchorPos(anchorPos);
       ScrollX = sX;
       ScrollY = sY;
     } else {
       var BookmarkMenu = CreatePopupMenu();
       for(var i = 0; i < bmcount; i++){
         //メニューのアクセスキーも1から始まるほうが便利
         BookmarkMenu.Add("&" + (i+1) + " " + bookmarks[i], i+1)
       }
       var ret = BookmarkMenu.Track(0);
       if(ret == 0){
         //カーソル位置の復帰
         SetActivePos(activePos);
         SetAnchorPos(anchorPos);
         ScrollX = sX;
         ScrollY = sY;
       } else {
         StartOfDocument(false);
         if(isTopMarked)ret--;
         for(i = 0; i < ret; i++){ NextBookmark(); }
       }
     }
     if(flgBlock){
       //ジャンプ前の選択開始位置からジャンプ後のカーソル位置まで範囲選択
       SetAnchorPos(anchorPos);
     }
   }
   // 描画再開
   Redraw = true;
 })()


sukemaru 版

goat 版のソースコードを元にして、ポップアップメニューを表示するまでの速度をすこしだけ改善しました。


▼ goat 版からの変更点 ▼
  • ソースコード内の設定項目から "表示行" / "論理行" の選択可(初期値は "論理行")
  • 設定項目で "ジャンプ先までの範囲選択" はしない状態を初期値にした
  • ブックマーク行の検索 ~ ポップアップメニューの表示 までの速度を改善
  • ポップアップメニューの体裁を変更(「検索ジャンプ」マクロにあわせた)
  • ステータスバーにブックマーク件数などの情報を表示
  • 「ブックマークがありません」メニュー(先頭行か最終行にジャンプ可)。
  • ジャンプしたときのスクロール位置を調整。

Mery でプログラミング用のフォントを使っている人だと、ポップアップメニュー内で半角 ¥ 記号 (U+005C) がバックスラッシュ (U+005C) にならないのは気落ち悪いかも? ということで、ソースコード内の関数 MenuKey() のコードのコメントアウトしてある行を有効化すると "擬似的に" バックスラッシュ化できます
(※「∖」(U+2216) に置換して表示します)。


ソースコード

ダウンロード:ファイル:ブックマークジャンプ.zip」(アイコン入り) 
最終更新: 2019/04/08


  • このマクロではポップアップメニューの表示に EN SPACE「 」(U+2002) などを使用します。ファイルに保存するさいは、文字コードをシフト JIS にしないでください(UTF-8 や Unicode で保存する)。
#title = "ブックマーク一覧ジャンプ"
#tooltip = "ポップアップメニューでブックマーク行にジャンプ"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",243
// または 244

/**
 * ---------------------------------------------------------
 * 「ブックマーク一覧ジャンプ」
 *   Orginal created by:  goat  (Last update:  2012/09/24)
 *   Modified by:  sukemaru  (2018/08/08 - 2019/04/08)
 * ---------------------------------------------------------
 */

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


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

// ■ ジャンプする前に選択範囲があったときはジャンプ先の行まで範囲選択する?
var flgBlockEnable = false;	// (true; 範囲選択する/false; 範囲選択しない)

// ■ 行の表示方法を Mery.ini から「自動」で読み込むか?
var autoLineModeEnable = false;	// (true; 読み込む /false; 読み込まない)

// ■ 行の表示方法(手動設定)
var $LineColumnView = 0;	// ( 0: 論理行 / 1: 表示行 )

// ■ ポップアップメニューに表示する文字数(全角/半角の区別なし)
var menuWidth = 65;

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


// Mery.ini から「行の表示方法」を取得する( 表示行 = 1 / 論理行 = 0 )
if ( autoLineModeEnable ) {
  lineColumnView = GetIniOptionNum( "LineColumnView" );
}
// 表示行/論理行 の定数
var posMode = lineColumnView ? mePosView : mePosLogical;
var lineMode = lineColumnView ? meGetLineView : 0;

var d = editor.ActiveDocument;
var s = editor.ActiveDocument.selection;
var lines = d.GetLines( lineMode ).toString();	// 全体の行数
var linesWidth = lines.length;			// 全体の行数のケタ数

//カーソル位置の保存
var act = s.GetActivePos();
var anc = s.GetAnchorPos();
var sx = ScrollX,  sy = ScrollY;
var ay = s.GetActivePointY( posMode );
var by;
var flgBlock = ! s.isEmpty;

var lineStr = "";
var menuKey = "";
var bmArray = new Array();	// ブックマーク行の文字列を収納する

Redraw = false;

// 先頭行がブックマークされているか
s.SetActivePos( 1 );
if ( s.PreviousBookmark() ) {
  by = s.GetActivePointY( posMode );
  lineStr = d.GetLine( by, lineMode );	// 文字列を取得
  // メニュー用ラベルを生成して配列に収納する
  bmArray.push( [ MenuKey( lineStr, by ), by ] );
}
// 2行目以降のブックマークを探す
s.SetActivePos( 0 );
while ( s.NextBookmark() ) {
  by = s.GetActivePointY( posMode );
  lineStr = d.GetLine( by, lineMode );	// 文字列を取得
  // メニュー用ラベルを生成して配列に収納する
  bmArray.push( [ MenuKey( lineStr, by ), by ] );
}
// カーソル位置を復帰
s.SetActivePos( act );
s.SetAnchorPos( anc );
ScrollX = sx;
ScrollY = sy;

// ブックマークの件数
var bmCount = bmArray.length;

// 「ブックマークがありません」ポップアップメニュー
if ( ! bmCount ) {
  var statusStr1 = " ブックマークがありません。"
  var statusStr2 = " 全体の行数: " 
                 + lines.replace( /(\d)(?=(?:\d{3})+$)/g , "$1," ) 
                 + ( lineColumnView ? " 行 (表示行)" : " 行 (論理行)" );
  Status = statusStr1 + statusStr2 + TimerElapsed( new Date(), start );

  var menu = CreatePopupMenu();
  menu.Add( "※" + statusStr1 + "& ※", 0 );
  menu.Add( statusStr2 + "& ", 0 );
  menu.Add( "", 0, meMenuSeparator );
  menu.Add( "   先頭行へジャンプ (&S)", 1 );
  menu.Add( "   最終行へジャンプ (&E)", + lines );

  var y = menu.Track( mePosMouse );
  if ( y > 0 ) {
    s.SetActivePoint( posMode, 1, y );
  }
}

// 「ブックマーク一覧」ポップアップメニュー
else {	// if ( bmCount )
  var BookmarkMenu = CreatePopupMenu();

  // メニューの上部に「キャンセル」行をピン止め
  BookmarkMenu.Add( ( "          " ).slice( - linesWidth - 1 )
                  + " キャンセル& ", 0 );
  var flags;
  for ( var i = 0; i < bmCount; i ++ ) {
    // 10行ごとにセパレータ
    if ( i % 10 == 0 ) {
      BookmarkMenu.Add( "", 0, meMenuSeparator );
    }
    // アクティブ行にチェックマークフラグ
    flags = ( bmArray[i][1] == ay ) ? meMenuChecked : 0;
    // ブックマーク行をポップアップメニューに追加
    BookmarkMenu.Add( bmArray[i][0], bmArray[i][1], flags );
  }

  Status = " ブックマーク:" + bmCount
         + " 件  / 全体の行数: " 
         + lines.replace( /(\d)(?=(?:\d{3})+$)/g , "$1," )  
         + ( lineColumnView ? " 行 (表示行)" : " 行 (論理行)" )
         + TimerElapsed( new Date(), start );

  // ポップアップメニューを表示
  var y = BookmarkMenu.Track( mePosMouse );
  // ジャンプ
  if ( y > 0 ) {
    s.SetActivePoint( posMode, 1, y );
    ScrollY = ( ScrollY == sy ) ? sy
                                : s.GetActivePointY( mePosView );

    // ジャンプ前の選択開始位置からジャンプ後の行まで範囲選択
    if ( flgBlockEnable && flgBlock ) {
      s.SetAnchorPos( anc );
      if ( ay < s.GetActivePointY( posMode ) ) {
        s.EndOfLine( true, posMode );
      }
    }
  }
}

Redraw = true;


// ---------- ▼ 関数 ▼ ----------

/**
 * 関数 MenuKey( str, num )
 * ポップアップメニューに表示するラベルを生成する
 * ・行頭空白を除去
 * ・空白文字を圧縮
 * ・削られてしまう「&」を補完
 * ・判別しづらいメタ文字を全角に置換
 * ・文字数を切り詰め
 * ・行番号をケタ埋め:		EN SPACE「 」(U+2002)
 *  ▼ 2019/03/30 追加 ▼
 * ・「\」を「∖」に置換:	「∖」(U+2216) または「╲」(U+2572) 「﹨」(U+FE68)
 * ・「a-z」を全角に置換
 */
function MenuKey( str, num ) {
  var menuKey = str.replace( /^[\t  ]+/ , "" )
                   .replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g , " › " )
                   .replace( /&/g , "&&" )
                // .replace( /[\\]/g , "∖" )
                // .replace( /([^∖!"',.:;`|\t  ])([∖]+)/g , "$1 $2" )
                   .replace( /[!"%'(),.:;@\[\]`a-z{|}]/g ,
                     function( $0 ) {
                       return String.fromCharCode( $0.charCodeAt( 0 ) + 0xFEE0 )
                     } );
  menuKey = ( menuKey.length > menuWidth )
          ? menuKey.slice( 0, menuWidth ) + " ..."
          : menuKey;
  return ( "          \&" + num ).slice( - linesWidth - 1 ) + ":  " + menuKey;
}


/**
 * 関数 TimerElapsed( end, start )
 * start からの経過時間計測
 * [ s.sss 秒 ] で返す
 */
function TimerElapsed( end, start ) {
  var elapsed = ( end - start ) / 1000;
  return "  [ "
         + ( elapsed + "000" ).replace( /(\.)(\d{3})(0*)/, "$1 $2" )
         + " 秒 ]";
}


/**
 * 関数 GetIniOptionNum( key )
 * 引数で指定された設定項目の「値」を返す(※数値1ケタ)
 */
function GetIniOptionNum( key ) {
  var regIniKey = new RegExp( "^" + key + "=\\d$", "m" );
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  // Mery.ini を探す
  var iniPath = editor.FullName.replace( /\.exe$/i , ".ini" );
  if ( ! Fso.FileExists( iniPath ) ) {
    var WshShell = new ActiveXObject( "WScript.Shell" );
    iniPath = WshShell.ExpandEnvironmentStrings( "%APPDATA%\\Mery\\Mery.ini" );
  }
  // Mery.ini を読み込む
  var iniFile = Fso.OpenTextFile( iniPath, 1 );
  var iniText = iniFile.ReadAll();
  iniFile.Close();
  // 項目の値を取得する
  var dist = + iniText.match( regIniKey ).shift().slice( - 1 );
  iniFile.Close();
  return dist;
}
スポンサーリンク