ブックマーク一覧ジャンプ

提供: MeryWiki
2019年4月7日 (日) 13:27時点におけるSukemaru (トーク | 投稿記録)による版 (sukemaru版: Quit メソッドを削除)
ナビゲーションに移動 検索に移動

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

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 版からの変更点

  • ソースコード内の設定項目から "表示行" / "論理行" の選択可(初期値は "論理行")
  • 設定項目で "ジャンプ先までの範囲選択" はしない状態を初期値にした
  • ブックマーク行の文字列取得 ~ メニューに表示するラベルの生成 の速度を改善
  • ポップアップメニューの体裁を変更(「検索ジャンプ」マクロにあわせた)
  • ステータスバーにブックマーク件数などの情報を表示

ソースコード

ダウンロード:ファイル:ブックマーク一覧ジャンプ.zip」(アイコン入り) 
投稿日: 2019/03/29(2019/04/07 Quit メソッドを削除)

  • このマクロではポップアップメニューの表示に EN SPACE「 」(U+2002) を使用します。ファイルに保存するさいは、文字コードを Shift 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/03/29)
 * ---------------------------------------------------------
 */

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


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

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

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

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

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


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


var d = document,  s = document.selection;
var lines = d.GetLines( lineMode ).toString();
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;

//カーソル位置の保存
var act = s.GetActivePos();
var anc = s.GetAnchorPos();
var sx = ScrollX,  sy = ScrollY;

Redraw = false;

// 先頭行がブックマークされてないか
s.SetActivePos( 1 );
if ( s.PreviousBookmark() ) {
  isTopMarked = true;
  // ブックマーク行の文字列を取得する
  lineStr = d.GetLine( s.GetActivePointY( posMode ), lineMode );
  // 関数でメニュー用ラベルを生成して配列に収容する
  bmArray.push( MenuKey( lineStr, s.GetActivePointY( posMode ) ) );
}
else {
  s.StartOfDocument();
}

// 2行目以降のブックマークを探す
while ( s.NextBookmark() ) {
  // ブックマーク行の文字列を取得する
  lineStr = d.GetLine( s.GetActivePointY( posMode ), lineMode );
  // 関数でメニュー用ラベルを生成して配列に収容する
  bmArray.push( MenuKey( lineStr, s.GetActivePointY( posMode ) ) );
}

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

// ブックマークがなければカーソル位置を復帰して終了
if ( ! bmCount ) {
  s.SetActivePos( act );
  s.SetAnchorPos( anc );
  ScrollX = sx,  ScrollY = sy;

  // ステータスバーにキャンセルメッセージ
  Status = " ブックマークがありません。/ 全体の行数: " 
         + lines.replace( /(\d)(?=(?:\d{3})+$)/g , "$1," ) 
         + ( $LineColumnView ? " 行 (表示行)" : " 行 (論理行)" )
         + TimerElapsed( new Date(), start );
}

// ブックマークがあればポップアップメニューを表示
else {
  var BookmarkMenu = CreatePopupMenu();
  // メニューの上部に「キャンセル」行をピン止め
  BookmarkMenu.Add( ( "          " ).slice( - linesWidth - 1 ) + " キャンセル& ", 0 );

  for ( var i = 0, flags; i < bmCount; i ++ ) {
    // 10行ごとにセパレータ
    if ( i % 10 == 0 ) {
      BookmarkMenu.Add( "", 0, meMenuSeparator );
    }
    // アクティブ行にはチェックマークフラグ
    flags = regY.test( bmArray[i] ) ? meMenuChecked : 0;

    BookmarkMenu.Add( bmArray[i], i + 1, flags )
  }

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

  // ポップアップメニューを表示
  // Track(0);ならキャレット位置にサブメニューがポップアップ
  // Track(1);ならカーソル位置にサブメニューがポップアップ
  var r = BookmarkMenu.Track( 1 );

  // キャンセル → カーソル位置の復帰
  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 ) {
      s.SetAnchorPos( anc );
      if ( ay < s.GetActivePointY( posMode ) ) {
        s.EndOfLine( true, mePosLogical );
      }
    }
    ScrollY = s.GetActivePointY( mePosView );
  }
}

Redraw = true;


// ---------------------------------------------------------

/* 関数 MenuKey( str, num ) */
// ポップアップメニューに表示するラベルを生成する
function MenuKey( str, num ) {
  // 行頭空白を除去/空白文字を圧縮/削られてしまう "&" を補完/判別しづらいメタ文字を全角に
  var menuKey = str.replace( /^[\t  ]+/ , "" )
                   .replace( /(?:\t|[ ]{3,}|[ ]{2,})+/g , " › " )
                   .replace( /&/g , "&&" )
                   .replace( /[.,:;(){}|!%']/g ,
                       function( $0 ) {
                         return String.fromCharCode( $0.charCodeAt( 0 ) + 0xFEE0 )
                       } )
                   .slice( 0, 50 );	// 文字数を圧縮

  return ( "          \&" + num ).slice( - linesWidth - 1 ) + ":  " + menuKey;
}


/* 関数 TimerElapsed( end, start ) */
// start からの経過時間を [ s.sss 秒 ] で返す
function TimerElapsed( end, start ) {
  var elapsed = end - start;
  return "  [ "
         + ( ( elapsed / 1000 ) + "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();
  // 項目の値を取得する
  var dist = + iniText.match( regIniKey ).shift().slice( - 1 );
  iniFile.Close();

  return dist;
}


バックスラッシュ化

Mery でプログラミング用のフォントを使っている人だと、ポップアップメニュー内で半角 ¥ 記号 (U+005C) がバックスラッシュ (U+005C) にならないのは気落ち悪いかも? ということで。

MenuKey() 関数の replace() 重ねがけ部分に以下のようなコードをはさむと "擬似的に" バックスラッシュ化できます。
※「∖」(U+2216) に置換して表示します。
// ※追加コードを 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;
}
スポンサーリンク