ポップアップメニューで検索先にジャンプ

提供: MeryWiki
移動先: 案内検索

概要[編集]

ポップアップメニューで検索にヒットした箇所へジャンプできます。

手石 版[編集]

機能[編集]

  • 選択した文字列(選択していないときはカーソルのある語)を検索します。
  • ヒットした行をポップアップメニューに表示し、選択するとその行へジャンプします。
  • 同一行にヒットする箇所が複数あったときは最初のヒット箇所にジャンプします。
  • 検索文字列の強調解除は、変更していなければ「Alt+F3」です。

コード (手石 版)[編集]

// pooupJump.js
// 2014/04/04

var sel = document.selection
if ( sel.isEmpty ){ sel.SelectWord(); };
var s = sel.Text;
var ty = sel.GetTopPointY( mePosView );
var p = sel.GetActivePos();
sel.Find( s, meFindNext + meFindAround );
sel.SetActivePos( p );

// ポップアップメニューでジャンプ先リスト
var menu_width = 66;
if ( "\t .,;:(){}[]+-=\"\\".indexOf( s ) < 0 && s.length > 0 ){
    var menu = CreatePopupMenu();
    var ary = [];
    for( var i = 0, n = document.GetLines( meGetLineView ); i < n ; i++ ){
        ary.push( document.GetLine( i+1, meGetLineView ));
    };
    var p = 0;
    for( var i = 0, n = ary.length; i < n ; i++ ){
        if ( ary[i].toLowerCase().indexOf( s.toLowerCase() ) >= 0 ){
            var item = ary[i].replace( /^\s*|\t/g, "" )
            item = ( item.length > menu_width + 1 )? item.slice( 0, menu_width ) + "..." : item ;
            var flags = ( (i+1) == ty )? meMenuChecked : 0 ; // meMenuGrayed  
            menu.Add( ( "    " + (i + 1) ).slice( -4 ) + " : " + item, i + 1, flags );
            p++;
        };
    };
    if ( p > 1 ){ // ポップアップメニューを表示するのは、検索ヒット行が複数のとき。
        var r = menu.Track( mePosMouse );  // mePosMouse 
        if ( r > 0 ){
            var line = document.GetLine( r, meGetLineView );
            sel.SetActivePoint( mePosView, line.indexOf( s ) + s.length + 1, r, false );
            sel.CharLeft( true, s.length );
            ScrollY = r-10;
        };
    };
};

履歴[編集]

  • 2014/04/04 初版

その他[編集]

  • 不具合があったら教えていただけると幸いです。


sukemaru 版[編集]

手石版のソースコードをベースにして、自分好みにカスタマイズしました。手石版の機能にあげられている部分はそのまま流用・踏襲しています。
ポップアップメニューを表示させるだけ(キャンセルする)であれば検索履歴には残らないので、検索ダイアログの最新の検索文字列を置きかえることなく重複行の確認や選択文字列が出現する行の確認をできます。
※ ポップアップメニューは Esc キーでキャンセルできます。

変更点[編集]

手石版からの変更点

  • エディタ設定の「行の表示方法」にあわせられるように、ポップアップメニューに表示する行番号は表示行/論理行を選択できます(ソースコード内の変数で設定)。
  • 検索文字列がほかの行でヒットしなかった場合や、ポップアップメニューからジャンプしなかった(キャンセル)場合に、検索履歴に残さないようにしました。
    そのさい、マクロの実行前に選択範囲なしだったときは単語選択もキャンセルします。
  • 検索文字列の強調表示を解除できます(ソースコード内の変数で設定)。
  • ヒットした行数や文書全体の行数をステータスバーに表示します。

ダウンロード (sukemaru 版)[編集]

ダウンロード: 「ファイル:ジャンプ.zip (アイコン入り)」 (2018/11/19)

以下のマクロと、それぞれの専用の「マテリアルデザインっぽいアイコン」を同梱してあります。
「ジャンプ」の下の3点は『小マクロ集』にソースコードを置いてあります。

コード (sukemaru 版)[編集]

#title = "ジャンプ"
#tooltip = "ポップアップメニューで検索先にジャンプ"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",229

/**
 * ------------------------------------------------------------
 * "ポップアップメニューで検索先にジャンプ"
 * pooupJump.js	
 * Original Copyright: 手石 (2014/04/04)
 * ------------------------------------------------------------
 * Modified by: sukemaru (2018/11/12 - 2018/11/19)
 * ------------------------------------------------------------
 */

// ■行の表示方法 (論理座標なら 0; /表示座標なら 1; )
var lineUnit = 0;

// ■検索文字列の強調表示を残すか? (残すなら true; /残さないなら false; )
var highlightEnable = true;

// ■ポップアップメニューに表示する文字数
var menuWidth = 66;

// ■選択範囲なしの状態からポップアップメニューを表示するときに自動マーカー表示をするか?
// (※ [表示]メニュー >> [マーカー] >> [自動マーカー] が ON でなければ効果なし)
var markerEnable = true;


var sx = ScrollX, sy = ScrollY;
Redraw = markerEnable;	// true なら単語を自動選択したときに自動マーカーを表示

var d = document
var s = document.selection
if ( s.IsEmpty ) {	// 選択範囲なしならカーソル位置の単語を選択
  var p = s.GetActivePos();
  s.SelectWord();
}
var st = s.Text;	// 検索文字列
var ty = ( lineUnit ) ? s.GetTopPointY( mePosView )		// 表示行
                      : s.GetTopPointY( mePosLogical );	// 論理行
var lines = ( lineUnit ) ? d.GetLines( meGetLineView )	// 全行数(表示行)
                         : d.GetLines( 0 );				// 全行数(論理行)

// ポップアップメニューでジャンプ先リスト
if ( "\n\t .,;:(){}[]+-=\"\\".indexOf( st ) < 0 && st.length > 0 ) {
  // 文書全体を行単位で分割
  if ( lineUnit ) {	// 表示行
    var a = [];
    for( var i = 0; i <= lines ; i ++ )
      a.push( d.GetLine( i, meGetLineView ) );
  }
  else {	// 論理行
    var a = d.Text.split( "\n" );
    a.unshift( "" );
  }
  // 検索文字列がヒットした行をポップアップメニューのアイテムとして取得する
  var m = CreatePopupMenu();
  var h = 0;	// ヒットした行数
  for( var i = 0; i < a.length; i ++ ) {	// a[0] = 空要素、i = 行番号
    if ( a[i].toLowerCase().indexOf( st.toLowerCase() ) >= 0 ) {
      // 行頭空白は除去、空白文字は半角スペースに置換、文字数を圧縮して取得
      var label = a[i].replace( /^\s+/, "" ).replace( /\s+/g, "  " );
      label = ( label.length > menuWidth + 1 ) ? label.slice( 0, menuWidth ) + "..." : label;
      var flags = ( i == ty ) ? meMenuChecked : 0;	// + meMenuGrayed
      m.Add( ( "    " + i ).slice( -4 ) + " : " + label, i, flags );
      h ++;
    }
  }
  // ポップアップメニューを表示するのは、検索ヒット行が複数のとき
  if ( h > 1 ) {
    Status = " ヒットした行数: " + h + " 行 /  全体の行数: "
           + lines.toString().replace( /(\d)(?=(\d{3})+$)/g, "$1," )
           + ( lineUnit ? " 行 ( 表示行 )" : " 行 ( 論理行 )" );
    var y = m.Track( mePosMouse );	// Track( 0 ) ならキャレット位置にポップアップ
    if ( y > 0 ) {
      // 選択した行番号にジャンプして検索文字列を選択
      if ( lineUnit )  s.SetActivePoint( mePosView, 1, y );
      else             s.SetActivePoint( mePosLogical, 1, y );
      s.Find( st, meFindNext );
      p = 0;
      d.HighlightFind = highlightEnable;	// 検索文字列の強調を解除
    }
    else
      Status = " 検索ジャンプをキャンセルしました。 ヒット: "
             + h + "行 / 全体の行数: "
             + lines.toString().replace( /(\d)(?=(\d{3})+$)/g, "$1," )
             + ( lineUnit ? " 行 (表示行)" : "行 (論理行)" );
  }
  // 検索条件エラー
  else if ( st.match( /\n/g ) )
    Status = " 検索文字列に【改行】を含めることはできません。 / 全体の行数: "
           + lines.toString().replace( /(\d)(?=(\d{3})+$)/g, "$1," )
           + ( lineUnit ? "行 (表示行)" : "行 (論理行)" );
  // ほかの行でヒットしなかったとき
  else
    Status = " ほかの行には見つかりませんでした。 / 全体の行数: "
           + lines.toString().replace( /(\d)(?=(\d{3})+$)/g, "$1," )
           + ( lineUnit ? "行 (表示行)" : "行 (論理行)" );
}
var pos = ( lineUnit ) ? s.GetActivePointY( mePosView )
                       : s.GetActivePointY( mePosLogical );
if ( p && pos == ty ) {
  s.SetActivePos( p );			// 単語選択を解除
  ScrollX = sx;  ScrollY = sy;	// ジャンプをかけないならスクロール位置を復元
}
Redraw = true;

メモ[編集]

  • (2018/11/12 sukemaru)
Get/SetActivePoint() や GetLines() のオプションパラメータ( mePosView や meGetLineView )を変数にすると機能しなくなるようで条件文 if ( lineUnit ) や ( lineUnit ) ? : をひとつひとつ書かかざるをえず、余計に長くなってしまいました。
  • (2018/11/14 sukemaru)
・ZIP の「ジャンプ.js」がソースコードのものより古い版だったので差し替えました。
・11/12 のソースコードでは表示行だと最終行を取得しなかったので修正しました。
  • (2018/11/19 sukemaru)
ヒット数や行数を表示する機能をつけてから、ムダに利用頻度があがった気がします。
スポンサーリンク