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

提供: MeryWiki
ナビゲーションに移動 検索に移動
Sukemaru (トーク | 投稿記録)
MSY-07 (トーク | 投稿記録)
SyntaxHighlightにcopyの追加
 
(2人の利用者による、間の13版が非表示)
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 版 =
手石版のソースコードをベースにして、自分好みにカスタマイズしました。手石版の[[#機能|機能]]にあげられている部分はそのまま踏襲・流用しています。
ポップアップメニューを表示させるだけ(キャンセルする)であれば検索履歴には残らないようにしてありますので、検索ダイアログの最新の検索文字列を置きかえることなく、重複行の確認や選択文字列が出現する行の確認をできます。
※ ポップアップメニューは Esc キーでキャンセルできます。 <br>
※<span style="color:#c00;">「行の表示方法」オプションが "false" (表示座標 = 表示行)で、折り返しにより検索文字列が途切れている場合はヒットしません</span>(Mery 標準の検索ダイアログでは検出できるのですが…)。
== 変更点 ==
▼ '''手石版からの変更点''' ▼
* エディタ設定の「行の表示方法」にあわせられるように、ポップアップメニューに表示する行番号は表示行/論理行を選択できます(■ソースコード内の変数で設定)。
* 検索文字列がほかの行でヒットしなかった場合や、ポップアップメニューからジャンプしなかった(キャンセル)場合に、検索履歴に残さないようにしました。 <br> そのさい、マクロの実行前に選択範囲なしだったときは単語選択もキャンセルします。
* 検索文字列の強調表示を解除できます(■ソースコード内の変数で設定)。
* ヒットした行数や文書全体の行数をステータスバーに表示します。
* 重複行のチェックをしやすくなるよう、論理行全体を範囲選択しているときは末尾改行を除外するようにしました。
* ポップアップメニューをキャンセルすればムダな検索履歴も残らないので、検索文字列の禁止文字条件をなくしました。 <br>
※ 正規表現を使わずに行単位で検索するので、改行は末尾の "\n" ×1 以外ダメ(空行も不可)。
▼ '''人柱版から移植した追加機能''' (2018/12/13) ▼
* 「検索処理の所要時間」をステータスバーに表示できます(◆ソースコード内の変数で設定)。
* キャンセルせずに検索ジャンプしたときにも検索文字列を検索/置換ダイアログの「検索履歴」に残さないようにできます(◆ソースコード内の変数で設定)。 <br> 「残さない」場合は Mery の検索機能を使用せずにジャンプするため、通常版の設定項目「■検索文字列の強調表示を残す」も無効になります。
* 検索のさいに「大文字/小文字を区別」するかしないかを選択できます(◆ソースコード内の変数で設定)
== ダウンロード (sukemaru 版) ==
'''ダウンロード:''' 「[[ファイル:ジャンプ.zip]] (アイコン入り)」 (2019/04/07 更新)
: 以下のマクロと、それぞれ専用の「マテリアルデザインっぽいアイコン」を同梱してあります。 <br> おまけマクロのソースコードは [[マテリアルデザインっぽいアイコンと『小マクロ集』#メニュー項目をアイコン化する小マクロ|『小マクロ集』]] に置いてあります。
:; ジャンプ(ポップアップメニューで検索先にジャンプ)
:* [[#sukemaru 版|通常版]] 最終更新: 2018/12/13
:* [[#人柱版|人柱版]]  最終更新: 2018/12/13
:* [[#include版|include版]] 最終更新: 2019/04/07
:; おまけマクロ
:* [[マテリアルデザインっぽいアイコンと『小マクロ集』#次の文字列を検索|次の文字列を検索]] (強調なし)
:* [[マテリアルデザインっぽいアイコンと『小マクロ集』#前の文字列を検索|前の文字列を検索]] (強調なし)
:* [[マテリアルデザインっぽいアイコンと『小マクロ集』#検索文字列の強調を解除|検索強調を解除]]
: を同梱
== コード (sukemaru 版) ==
最終更新: 2018/12/13
<source lang="javascript" style="height:40em; overflow:auto;">
#title = "ジャンプ"
#tooltip = "ポップアップメニューで検索先にジャンプ"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",229
/**
* ------------------------------------------------------------
* "ポップアップメニューで検索先にジャンプ"
* Original Copyright: 手石 (2014/04/04)
* ------------------------------------------------------------
* Modified by: sukemaru (2018/11/12 - 2018/12/13)
* ------------------------------------------------------------
*/
var start = new Date().getTime(); // 所要時間の計測開始
// ■行の表示方法 (true; 論理座標 /false; 表示座標)
var logical = true;
// ■検索文字列の強調表示を残すか? (true; 残す /false; 残さない)
var highlightEnable = true;
// ■選択範囲なしの状態から実行したときに自動マーカーを表示するか? (true; 表示する / false; 表示しない)
// ※ [表示]メニュー >> [マーカー] >> [自動マーカー] が ON でなければ効果なし
var markerEnable = true;
// ◆検索文字列を「検索履歴」に残さない? (true; 残さない / false; 残す)
// ※ historyDisable = true の場合、通常版の設定 highliteEnable は無効になる(強調表示しない)
var historyDisable = true;
// ◆検索文字列の「大文字/小文字」を区別するか? (true; 区別する / false; 区別しない)
var caseEnable = false;
// ◆検索処理の所要時間を表示するか? (true; する /false; しない)
var timerEnable = true;
// ■ポップアップメニューに表示する文字数
var menuWidth = 66;
Redraw = markerEnable;
var sx = ScrollX,  sy = ScrollY;
var d = document,  s = document.selection;
// 論理行/表示行の設定を変数に
var posMode = logical ? mePosLogical : mePosView;
var lineMode = logical ? 0 : meGetLineView;
// 選択範囲なしならカーソル位置の単語を選択
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(),  act = s.GetActivePos();
  if ( anc < act ) { s.SetActivePos( act - 1, true ); }
  if ( act < anc ) { s.SetAnchorPos( anc - 1 );  s.SetActivePos( act, true ); }
}
// 選択範囲の先頭と文書全体の行数(論理行/表示行)
var ty = s.GetTopPointY( posMode );
var lines = d.GetLines( lineMode );
var cancel = 5;
if ( ! st )  cancel = 1; // 検索文字列がない(空行)
else if ( st.match( /\n/g ) )  cancel = 2; // 検索条件エラー(改行)
// ポップアップメニューでジャンプ先リスト
else {
  // 文書全体を行単位で分割して配列にする
    for( var i = 1, a = [ "" ]; i <= lines ; i ++ )
      a.push( d.GetLine( i, lineMode ) );
  // 検索文字列がヒットした行をポップアップメニューのアイテムとして取得する
  var m = CreatePopupMenu();
  for( var i = 1, h = 0; i < a.length; i ++ ) { // a[0] = 空要素、i = 行番号 = y
    if ( findCaseTF( a[i], st ) >= 0 ) {
      // 行頭空白は除去、空白文字は半角スペースに置換、文字数を圧縮して取得
      // 判別しづらい半角メタ文字を全角に置きかえる
      var label = a[i].replace( /^\s+/, "" ).replace( /\t+|[ ]{3,}/g, "  " )
                      .replace( /[.,:;(){}]/g ,
                        function( $0 ) { return String.fromCharCode( $0.charCodeAt( 0 ) + 0xFEE0 ) }
                      );
      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 ( timerEnable ) {
  var elapsed = new Date().getTime() - start;
  var timerStatus = "  [ "
                  + ( ( elapsed / 1000 ) + "000" ).replace( /(\.)(\d{3})(0*)/, "$1 $2" )
                  + " 秒 ]";
  }
  // ポップアップメニューを表示するのは、検索ヒット行が複数のとき
  if ( h > 1 ) {
    Status = " ヒットした行数: " + SeparateNum( h ) + " 行"
            + " / 全体の行数: " + SeparateNum( lines )
            + ( logical ? " 行 (論理行)" : " 行 (表示行)" )
            + ( timerEnable ? timerStatus : "" );
    var y = m.Track( mePosMouse ); // Track(0) ならキャレット位置にポップアップ
    if ( y > 0 ) {
      // 選択した行番号にジャンプして検索文字列を選択
      s.SetActivePoint( posMode, 1, y );
      if ( historyDisable ) {
        // 検索履歴に残さない ※「検索文字列の強調表示」なし
        s.SetActivePos( s.GetActivePos() + findCaseTF( d.GetLine( y, lineMode ), st ) );
        s.SetAnchorPos( s.GetActivePos() + st.length );
      }
      else {
        // 検索履歴に残す ※ Mery の検索機能で文字列を範囲選択
        s.Find( st, meFindNext );
        d.HighlightFind = highlightEnable; // 「検索文字列の強調表示」を解除する/しない
      }
      cancel = 0; // cancel フラグを解除
    }
    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 );
  // キャンセルフラグの値が 1 or 2 のとき、所要時間の計測終了
  if ( timerEnable && ! elapsed ) {
    var elapsed = new Date().getTime() - start;
    var timerStatus = "  [ "
                    + ( ( elapsed / 1000 ) + "000" ).replace( /(\.)(\d{3})(0*)/, "$1 $2" )
                    + " 秒 ]";
  }
  Status = ( ( cancel == 1 ) ? " 検索文字列がありません(空行)。" :
            ( cancel == 2 ) ? " 検索文字列に【 改行 】を含めることはできません。" :
            ( cancel == 3 ) ? " 検索ジャンプをキャンセルしました。 ヒット: "
                              + SeparateNum( h ) + " 行" :
            ( cancel == 4 ) ? " ほかの行には見つかりませんでした。" :
            /* cancel == 5 */  " 無効な検索文字列。" )
          + " / 全体の行数: " + SeparateNum( lines )
          + ( logical ? " 行 (論理行)" : " 行 (表示行)" )
          + ( timerEnable ? timerStatus : "" );
  ScrollX = sx;  ScrollY = sy;
}
Redraw = true;
/* 関数 findCaseTF( str, st ) */
// 文字列 str 内で st を検索するさいに「大文字/小文字を区別」する/しない
// ヒットすればヒットした位置(  0 ~ )、ヒットしなければ -1 を返す
function findCaseTF( str, st ) {
  return caseEnable ? str.indexOf( st ) :
        /* else */  str.toLowerCase().indexOf( st.toLowerCase() )
}
/* 関数 SeparateNum( num ) */
// 数値を3ケタ区切りにする
function SeparateNum( num ) {
  return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g, "$1," )
}
</source>
== 人柱版 ==
「表示行」で運用した場合の '''動作検証が不十分''' ですが、以下の追加オプションにご興味のある方は [[#ダウンロード (sukemaru 版)|ZIP 書庫]] 内の「人柱版(空行+空白行検索に対応)」フォルダの JS ファイルをお使いください。 <br>
動作に異常があるようでしたら、ソースコード内の設定セクションで「人柱版の設定項目」を無効化( false )してください。
▼ '''追加オプション''' ▼
* 「検索処理の所要時間」をステータスバーに表示します(◆変数で設定)。
:* 人柱版では処理が遅くなる追加機能が多いので…。
* 「行の表示方法」の設定を Mery.ini から自動取得するかしないかを選択できます(◆変数で設定)。
:* ただし、ini ファイルが肥大化またはフラグメントしていると、処理が多少遅くなります。
* 検索文字列を検索/置換ダイアログの「検索履歴に残すか残さないか」を選択できます(◆変数で設定)。
:* 「残さない」場合は Mery の検索機能を使用せずにジャンプするため、通常版と共通の設定項目「検索文字列の強調表示を残す」も無効になります。
* 検索のさいに「大文字/小文字を区別」するかしないかを選択できます(◆変数で設定)。
* 空行にキャレットがある状態か、"末尾改行をふくめて" 空白行を範囲選択している状態から、「すべての空行+空白行」を検索できるオプションを追加しました(変数で設定)。
:* 「空行+空白行」オプションが有効 ( true ) の場合は、末尾改行 "\n" をふくめて「空白文字のみの行」を範囲選択しているときに、すべての「空行+空白行」を検索対象にします。末尾改行をふくめずに「空白文字のみの行」を範囲選択しているときは「一致する空白文字列」を検索対象にします。
:* 「空行+空白行」オプションが無効 ( false ) の場合、空白文字のみの行」を範囲選択しているときには「一致する空白文字列」を検索対象にします。空行で実行した場合にはポップアップメニューは表示されません。
: ※「空行+空白行」が対象のとき以外は正規表現を使わずに行単位で検索するので、選択範囲が複数行(末尾以外に改行 "\n" がある)の場合や、空白行オプションが無効で選択範囲が空行 "^\n" の場合は検索できません。
* 検索対象が「空行+空白行」でないときは、ヒットした行数とは別に「ヒットした件数」をステータスバーに表示できます(◆変数で設定)。「ヒット件数」の判定は、大文字/小文字オプションの設定に依拠します。
* 検索対象が「空行+空白行」でないとき、ポップアップメニューの右隅に以下のマーキングを表示できます(「ヒット件数」オプションが有効の場合のみ)。
:* JavaScript で検索文字列が変数/関数名のとき、定義行に「 '''← var''' 」「 '''← fn''' 」マーク
:* 検索文字列が行全体のとき、アクティブ行に「 '''⏎''' 」マーク
:* アクティブ行と完全に一致する重複行に「 '''**''' 」マーク (※行検索でないときにも表示)
:* 検索文字列と完全に一致する行に「 '''*''' 」マーク
:* 検索文字列が複数回ヒットした行に「 '''x2''' 」マーク
: ※「一致」の判定は、「大文字/小文字」オプションに依拠します。
* ポップアップメニューを Space キーでもキャンセルできるようにしました。ただし、メニューに表示されるヒットした行の文字列に「アンパサンドと半角スペース "&␣"」があるときは Esc キーのみ( "&&␣" なら可)。
※大きな文書の場合、「空行/空白行/空白文字列」や「頻出する文字/単語」の検索では処理に時間がかかります。 <br>
※「人柱版 設定項目」の変数の値をすべて無効 false にすれば通常版とほぼおなじ動作になります。
=== 人柱版のソースコード ===
最終更新: 2018/12/13 <br>
[[検索ジャンプの人柱版|>> 別ページに掲載]]
== include版 ==
[[includeライブラリ]] を使用し、設定内容を外部ファイルに保存します(◆settingEnable 変数で設定。デフォルト: 有効)。
設定内容の読み込み/書き出しが可能になったので、<span style="color:#c00;">設定の変更はポップアップメニュー内の項目のチェック ON/OFF でできるようになります。 </span><br>
[[ファイル:Mery_ジャンプ_SS_2.png|link=https://www.haijin-boys.com/wiki/images/0/0f/Mery_ジャンプ_SS.png|スクリーンショット]]
<div id="注1" class="warningbox">
* あらかじめ [[includeライブラリ]] をインストールしてください。
* 設定内容の保存場所は '''Mery\Macros\MacroSettings\<ジャンプ>.json''' <br> または '''%AppData%\Mery\MacroSettings\<ジャンプ>.jso'''n です。<br> (※ <ジャンプ> の部分はこのマクロのファイル名)
</div>
* 「▼ 通常版 初期設定項目 ▼」以降の設定項目は『初期値』としてのみ利用され、ソースコード内の設定項目を直接書き換えする必要はありません。<br> ただし、settingEnable 変数を完全に無効にする場合は、ソースコード内で変更する必要があります。<br> → settingEnable を無効にした場合は「人柱版」と同じ状態になるので、設定変更はソースコードの直接編集(変数の true/false の変更)でおこなう必要があります。
* はじめての設定変更のさいにエラーが発生する場合は、以下の ①~③ を試行してください。
# ポップアップメニューの「設定内容を初期化する」を実行して、ファイルを確認する<br> ( → JSON ファイルを新規作成して設定値を書き出します)。
# ポップアップメニューの「JSON ファイルを開く」を実行して、ファイルを確認する。
# JSON ファイルが正常に作成されない場合は、同梱の「ジャンプ.json」を '''上記の "設定ファイルの保存場所" フォルダ''' に配置してください。
* 設定変更メニューを組み込んでいるため、「検索設定の変更」オプションが有効のときは、検索語が他の行でヒットしなかった場合でもポップアップメニューを表示します。<br> ただし、複数行選択状態で実行した場合(「表示行」で選択範囲が折り返しを含む場合も)、「英単語のみ」オプションが有効なときや「空行/空白行」がオプション無効のときに検索条件にたいして「無効な検索文字列」を検索した場合は、ポップアップメニューを表示せず、ステータスバーにエラー内容を表示します。
※ include版ではドキュメントの行数制限(9,999,999行)があります。
▼ '''追加機能''' ▼
* 検索のさいに「英単語のみ検索」するかしないかを選択できます(◆変数で設定)。<br> これにより、ソースコードの1文字変数(''e.g. '''var s''';'')や '''<nowiki><a></nowiki>''' タグなどの検索がしやすくなります。
:* 「英単語のみ」オプションが有効のときは、マクロ実行前の選択範囲の有無によらず、キャレット位置の '''単語''' を自動選択して既存の選択範囲から置きかえます 。
:* <span style="color:#c00;">「英単語のみ」オプションを有効にして検索できるのは英単語(JavaScript の正規表現で '''\w+''' )のみです。</span> <br> 単語の自動選択には Mery ビルトインのメソッドを使用しているので、英文でなくても単語の範囲選択までは行いますが、<span style="color:#c00;">日本語の文字列は検索できません。</span> <br> また、英文・欧文でも各種記号や空白文字、ascii 範囲外のアルファベットを使った単語でも検索できません。
:* このオプションを有効にした場合は正規表現を使用しての検索になるので、処理がやや遅くなります。
<div id="注2" class="warningbox">
* メニューに検索ヒットした行が表示されないときは、<br> メニューの「英単語のみ」のチェックをはずしてください。
</div>
* 文字列の検索のさいに「ヒット件数表示」オプションが有効な場合、選択範囲が「何件目」のヒット箇所かの表示を追加します(ジャンプしたあとの選択範囲が「何件目」のヒット箇所かも表示します)。
=== include版のソースコード ===
最終更新: 2019/04/07 <br>
[[検索ジャンプの include版|>> 別ページに掲載]]
== メモ ==
おもな更新履歴
* (2018/11/12 sukemaru)
: ・新規アップロード(sukemaru版の【通常版】)
* (2018/11/25 sukemaru)
:・【[[検索ジャンプの人柱版|人柱版]]】を新規アップロード
* (2018/12/13 sukemaru)
: ・【通常版】を更新(【人柱版】から追加機能の一部を逆移植)
: ・【人柱版】を更新(機能追加)
* (2018/12/16 sukemaru)
: ・【[[検索ジャンプの include版」|include版]]】を新規アップロード
: ・【人柱版】を修正
* (2019/03/13 sukemaru)
: ・【include版】を修正・更新
----
行の表示方法が「表示座標」のとき、折り返し部分にかかった文字列にはマッチしないままです。<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)
    • 初版

その他[編集]

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