「ポップアップメニューで検索先にジャンプ」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
Sukemaru (トーク | 投稿記録)
sukemaru 版: 人柱版を更新(第3版)
MSY-07 (トーク | 投稿記録)
SyntaxHighlightにcopyの追加
 
(2人の利用者による、間の21版が非表示)
1行目: 1行目:
= 概要 =
ポップアップメニューで検索にヒットした箇所へジャンプできます。
ポップアップメニューで検索にヒットした箇所へジャンプできます。


= 手石 版 =
== 機能 ==
== 機能 ==
* 選択した文字列(選択していないときはカーソルのある語)を検索します。
* 選択した文字列(選択していないときはカーソルのある語)を検索します。
9行目: 7行目:
* 検索文字列の強調解除は、変更していなければ「Alt+F3」です。
* 検索文字列の強調解除は、変更していなければ「Alt+F3」です。


== コード (手石 版) ==
== ソースコード ==
<source lang="javascript">
<syntaxhighlight lang="javascript" copy>
// pooupJump.js
// pooupJump.js
// 2014/04/04
// 2014-04-04


var sel = document.selection
var sel = document.selection
50行目: 48行目:
     };
     };
};
};
</source>
</syntaxhighlight>


== 履歴 ==
== 変更履歴 ==
* 2014/04/04 初版
* 1.0.0 (2014-04-04)
** 初版


== その他 ==
== その他 ==
* 不具合があったら教えていただけると幸いです。
* 不具合があったら教えていただけると幸いです。
= sukemaru 版 =
手石版のソースコードをベースにして、自分好みにカスタマイズしました。手石版の[[#機能|機能]]にあげられている部分はそのまま踏襲・流用しています。
ポップアップメニューを表示させるだけ(キャンセルする)であれば、検索履歴には残らないようにしてあります。 <br>
検索ダイアログの最新の検索文字列を置きかえることなく、重複行の確認や選択文字列が出現する行の確認をできます。
※ ポップアップメニューは Esc キーでキャンセルできます。 <br>
※<span style="color:#c00;">「行の表示方法」オプションが "false" (表示座標 = 表示行)で、折り返しにより検索文字列が途切れている場合はヒットしません</span>(Mery 標準の検索ダイアログでは検出できるのですが…)。
== 変更点 ==
▼ 手石版からの変更点 ▼
* エディタ設定の「行の表示方法」にあわせられるように、ポップアップメニューに表示する行番号は表示行/論理行を選択できます(■ソースコード内の変数で設定)。
* 検索文字列がほかの行でヒットしなかった場合や、ポップアップメニューからジャンプしなかった(キャンセル)場合に、検索履歴に残さないようにしました。 <br> そのさい、マクロの実行前に選択範囲なしだったときは単語選択もキャンセルします。
* 検索文字列の強調表示を解除できます(■ソースコード内の変数で設定)。
* ヒットした行数や文書全体の行数をステータスバーに表示します。
* 重複行のチェックをしやすくなるよう、論理行全体を範囲選択しているときは末尾改行を除外するようにしました。
* ポップアップメニューをキャンセルすればムダな検索履歴も残らないので、検索文字列のダメ文字条件をなくしました。 <br>
※ 正規表現を使わずに行単位で検索するので、改行は末尾の "\n" ×1 以外ダメ(空行も不可)。
== ダウンロード (sukemaru 版) ==
ダウンロード: 「[[ファイル:ジャンプ.zip]] (アイコン入り)」 (2018/12/10 人柱版のみ更新)
: 以下のマクロ4点と、それぞれ専用の「マテリアルデザインっぽいアイコン」を同梱してあります。 <br> 「ジャンプ」の下の3点は[[マテリアルデザインっぽいアイコンと『小マクロ集』#メニュー項目をアイコン化する小マクロ|『小マクロ集』]]にソースコードを置いてあります。
:* ジャンプ(ポップアップメニューで検索先にジャンプ) <br> (※「[[#人柱版|人柱版]]」も同梱)
:* [[マテリアルデザインっぽいアイコンと『小マクロ集』#次の文字列を検索|次の文字列を検索]] (強調なし)
:* [[マテリアルデザインっぽいアイコンと『小マクロ集』#前の文字列を検索|前の文字列を検索]] (強調なし)
:* [[マテリアルデザインっぽいアイコンと『小マクロ集』#検索文字列の強調を解除|検索強調を解除]]
== コード (sukemaru 版) ==
<source lang="javascript" style="height:40em; overflow:auto;">
#title = "ジャンプ"
#tooltip = "ポップアップメニューで検索先にジャンプ"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",229
/**
* ------------------------------------------------------------
* "ポップアップメニューで検索先にジャンプ"
* pooupJump.js
* Original Copyright: 手石 (2014/04/04)
* ------------------------------------------------------------
* Modified by: sukemaru (2018/11/12 - 2018/11/21)
* ------------------------------------------------------------
*/
// ■行の表示方法 (true; 論理座標 /false; 表示座標)
var logical = true;
// ■検索文字列の強調表示を残すか? (true; 残す /false; 残さない)
var highlightEnable = true;
// ■選択範囲なしの状態から実行したときに自動マーカーを表示するか? (true; 表示する / false; 表示しない)
// ※ [表示]メニュー >> [マーカー] >> [自動マーカー] が ON でなければ効果なし
var markerEnable = true;
// ■ポップアップメニューに表示する文字数
var menuWidth = 66;
Redraw = markerEnable;
var sx = ScrollX,  sy = ScrollY;
var d = document,  s = document.selection;
if ( s.IsEmpty ) { // 選択範囲なしならカーソル位置の単語を選択
  var p = s.GetActivePos();
  s.SelectWord();
}
var st = s.Text; // 検索文字列
// 選択範囲の末尾が改行 "\n" なら検索文字列から除外する
if ( st.length > 1 && st.charAt( st.length - 1 ) == "\n" ) {
  st = st.slice( 0, st.length - 1 );
  var adjust = true;
  var anc = s.GetAnchorPos();
  var act = s.GetActivePos();
  if ( anc < act ) s.SetActivePos( act - 1, true );
  if ( act < anc ) s.SetAnchorPos( anc - 1 ),  s.SetActivePos( act, true );
}
// 選択範囲の先頭と文書全体の行数(論理行/表示行)
var ty = ( logical ) ? s.GetTopPointY( mePosLogical )
                    : s.GetTopPointY( mePosView );
var lines = ( logical ) ? d.GetLines( 0 )
                        : d.GetLines( meGetLineView );
var cancel = 5;
if ( ! st ) cancel = 1; // 検索文字列がない(空行)
else if ( st.match( /\n/g ) ) cancel = 2; // 検索条件エラー(改行)
// ポップアップメニューでジャンプ先リスト
else {
  // 文書全体を行単位で分割して配列にする
  if ( logical ) { // 論理行
    var a = d.Text.split( "\n" );
    a.unshift( "" );
  }
  else { // 表示行
    for( var i = 0, a = []; i <= lines ; i ++ )
      a.push( d.GetLine( i, meGetLineView ) );
  }
  // 検索文字列がヒットした行をポップアップメニューのアイテムとして取得する
  var m = CreatePopupMenu();
  var h = 0; // ヒットした行数
  for( var i = 0; i < a.length; i ++ ) { // a[0] = 空要素、i = 行番号 = y
    if ( a[i].toLowerCase().indexOf( st.toLowerCase() ) >= 0 ) {
      // 行頭空白は除去、空白文字は半角スペースに置換、文字数を圧縮して取得
      var label = a[i].replace( /^\s+/, "" ).replace( /\t+|[ ]{3,}/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 = " ヒットした行数: " + SeparateNum( h ) + " 行"
            + " / 全体の行数: " + SeparateNum( lines )
            + ( logical ? " 行 (論理行)" : " 行 (表示行)" );
    var y = m.Track( mePosMouse ); // Track(0) ならキャレット位置にポップアップ
    if ( y > 0 ) {
      // 選択した行番号にジャンプして検索文字列を選択
      if ( logical ) s.SetActivePoint( mePosLogical, 1, y );
      else          s.SetActivePoint( mePosView, 1, y );
      s.Find( st, meFindNext ); // ジャンプしたら検索履歴に残す
      d.HighlightFind = highlightEnable;
      cancel = 0;
    }
    else cancel = 3; // ポップアップメニューをキャンセル
  }
  else cancel = 4; // ほかの行でヒットなし
}
// ジャンプしなかったとき
if ( cancel ) {
  if ( p ) s.SetActivePos( p );
  else if ( adjust && anc < act ) s.SetActivePos( act, true );
  else if ( adjust && act < anc ) s.SetAnchorPos( anc ),  s.SetActivePos( act, true );
  Status = ( ( cancel == 1 ) ? " 検索文字列がありません(空行)。" :
            ( cancel == 2 ) ? " 検索文字列に【 改行 】を含めることはできません。" :
            ( cancel == 3 ) ? " 検索ジャンプをキャンセルしました。 ヒット: "
                              + SeparateNum( h ) + " 行" :
            ( cancel == 4 ) ? " ほかの行には見つかりませんでした。" :
            /* cancel == 5 */  " 無効な検索文字列(ダメ文字)。" )
          + " / 全体の行数: " + SeparateNum( lines )
          + ( logical ? " 行 (論理行)" : " 行 (表示行)" );
  ScrollX = sx;  ScrollY = sy;
}
Redraw = true;
// 数値を3ケタ区切りにする
function SeparateNum( num ) {
  return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g, "$1," )
}
</source>
== 人柱版 ==
「表示行」で運用した場合の '''動作検証が不十分''' ですが、以下の追加オプションにご興味のある方は [[#ダウンロード (sukemaru 版)|ZIP 書庫]] 内の「人柱版(空行+空白行検索に対応)」フォルダの JS ファイルをお使いください。 <br>
動作に異常があるようでしたら、ソースコード内の設定セクションで「人柱版の設定項目」を無効化( false )してください。
▼ 追加オプション ▼
* 検索文字列を検索/置換ダイアログの「検索履歴に残すか残さないか」を選択できます(◆変数で設定)。
:* 「残さない」場合は Mery の検索機能を使用せずにジャンプするため、通常版と共通の設定項目「検索文字列の強調表示を残す」も無効になります。
* 検索のさいに「大文字/小文字を区別」するかしないかを選択できます(◆変数で設定)。
* 空行にキャレットがある状態か、"末尾改行をふくめて" 空白行を範囲選択している状態から、「すべての空行+空白行」を検索できるオプションを追加しました(◆変数で設定)。
:* 「空行+空白行」オプションが有効 ( true ) の場合は、末尾改行 "\n" をふくめて「空白文字のみの行」を範囲選択しているときに、すべての「空行+空白行」を検索対象にします。末尾改行をふくめずに「空白文字のみの行」を範囲選択しているときは「一致する空白文字列」を検索対象にします。
:* 「空行+空白行」オプションが無効 ( false ) の場合、空白文字のみの行」を範囲選択しているときには「一致する空白文字列」を検索対象にします。空行で実行した場合にはポップアップメニューは表示されません。
: ※「空行+空白行」が対象のとき以外は正規表現を使わずに行単位で検索するので、選択範囲が複数行(末尾以外に改行 "\n" がある)の場合や、空白行オプションが無効で選択範囲が空行 "^\n" の場合は検索できません。
* 検索対象が「空行+空白行」でないときは、ヒットした行数とは別に「ヒットした件数」をステータスバーに表示できます(◆変数で設定)。「ヒット件数」の判定は、大文字/小文字オプションの設定に依拠します。
* 検索対象が「空行+空白行」でないとき、ポップアップメニューの右隅に以下のマーキングを表示できます(◆「ヒット件数」オプションが有効の場合のみ)。
:* 検索文字列が行全体のとき、アクティブ行に「 ⏎ 」マーク
:* アクティブ行と完全に一致する'''重複行'''に「 ** 」マーク (※行検索でないときにも表示)
:* 検索文字列と完全に一致する行に「 * 」マーク
:* 検索文字列が複数回ヒットした行に「 x2 」マーク
: ※「一致」の判定では、つねに「大文字/小文字を区別」します。
* ポップアップメニューを Space キーでもキャンセルできるようにしました。ただし、メニューに表示されるヒットした行の文字列に「アンパサンドと半角スペース "&␣"」があるときは Esc キーのみ( "&&␣" なら可)。
※大きな文書の場合、「空行/空白行/空白文字列」や「頻出する文字/単語」の検索では処理に時間がかかります。 <br>
※「人柱版 設定項目」の変数の値をすべて無効 false にすれば通常版とおなじ動作になります。
=== 人柱版のソースコード ===
[[検索ジャンプの人柱版|>> 別ページに掲載]]
== メモ ==
* (2018/11/12 sukemaru)
: Get/SetActivePoint() や GetLines() のオプションパラメータ( mePosView や meGetLineView )を変数にすると機能しなくなるようで条件文 if ( logical ) や ( logical ) ? : をひとつひとつ書かかざるをえず、余計に長くなってしまいました。
* (2018/11/14 sukemaru)
: ・ZIP の「ジャンプ.js」がソースコードのものより古い版だったので差し替えました。
: ・11/12 のソースコードでは表示行だと最終行を取得しなかったので修正しました。
* (2018/11/19 sukemaru)
: ヒット数や行数を表示する機能をつけてから、ムダに利用頻度があがった気がします。
* (2018/11/21 sukemaru)
: むしろジャンプしないほうが便利な? 検索ポップアップメニューになりました。
* (2018/11/23 sukemaru)
: 空行を数えられます…。
* (2018/11/25 sukemaru)
: 重いです。
* (2018/12/10 sukemaru)
: 論理行表示で「人柱版」を使っていますが、とくに問題なさそうです。<br>いまとなっては「通常版」が短いマクロであるかのように錯覚してしまいます。

2025年6月30日 (月) 00:32時点における最新版

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

機能[編集]

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

変更履歴[編集]

  • 1.0.0 (2014-04-04)
    • 初版

その他[編集]

  • 不具合があったら教えていただけると幸いです。
スポンサーリンク