「
検索ジャンプの人柱版
」を編集中
2018年11月26日 (月) 00:00時点における
Sukemaru
(
トーク
|
投稿記録
)
による版
(
→
人柱版
)
(
差分
)
← 古い版
|
最新版
(
差分
) |
新しい版 →
(
差分
)
ナビゲーションに移動
検索に移動
警告: このページの古い版を編集しています。
公開すると、この版以降になされた変更がすべて失われます。
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、さまざまなメリットもあります。
スパム攻撃防止用のチェックです。 決して、ここには、値の入力は
しない
でください!
[[ポップアップメニューで検索先にジャンプ#人柱版のソースコード|>> もとのページ]] ポップアップメニューで検索先にジャンプ(sukemaru 版) == 人柱版 == '''動作検証が不十分'''ですが、ご興味のある方は [[ポップアップメニューで検索先にジャンプ#ダウンロード (sukemaru 版)|ZIP書庫]] 内の「人柱版(空行+空白行検索に対応)」フォルダの JS ファイルをお使いください。 ▼ 追加オプション ▼ * 検索のさいに「大文字/小文字を区別」するかしないかを選択できます(変数で設定)。 * 空行にキャレットがある状態か、"末尾改行をふくめて" 空白行を範囲選択している状態から、「すべての空行+空白行」を検索できるオプションを追加しました(変数で設定)。 :* 「空行+空白行」オプションが有効 ( true ) の場合は、末尾改行 "\n" をふくめて「空白文字のみの行」を範囲選択しているときに、すべての「空行+空白行」を検索対象にします。末尾改行をふくめずに「空白文字のみの行」を範囲選択しているときは「一致する空白文字列」を検索対象にします。 :* 「空行+空白行」オプションが無効 ( false ) の場合、空白文字のみの行」を範囲選択しているときには「一致する空白文字列」を検索対象にします。空行で実行した場合にはポップアップメニューは表示されません。 : ※「空行+空白行」が対象のとき以外は正規表現を使わずに行単位で検索するので、選択範囲が複数行(末尾以外に改行 "\n" がある)の場合や、空白行オプションが無効で選択範囲が空行 "^\n" の場合は検索できません。 * 検索対象が「空行+空白行」でないときは、ヒットした行数とは別に「ヒットした件数」をステータスバーに表示できます(◆変数で設定)。「ヒット件数」の判定は、大文字/小文字オプションの設定に依拠します。 * 検索対象が「空行+空白行」でないとき、ポップアップメニューの右隅に以下のマーキングを表示できます(「ヒット件数」オプションが有効の場合のみ)。 :* 検索文字列が行全体のとき、アクティブ行に「 ⏎ 」マーク :* アクティブ行と完全に一致する重複行に「 ** 」マーク (※行検索でないときにも表示) :* 検索文字列と完全に一致する行に「 * 」マーク :* 検索文字列が複数回ヒットした行に「 x2 」マーク : ※「一致」の判定では、つねに大文字/小文字を区別します。 * ポップアップメニューを Space キーでもキャンセルできるようにしました。ただし、メニューに表示されるヒットした行の文字列に「アンパサンドと半角スペース "&␣"」があるときは Esc キーのみ( "&&␣" なら可)。 ※大きな文書の場合、「空行/空白行/空白文字列」や「頻出する文字/単語」の検索では処理に時間がかかります。 <br> ※「人柱版 設定項目」の変数の値をすべて無効 false にすれば通常版とおなじ動作になります。 [[ポップアップメニューで検索先にジャンプ#人柱版のソースコード|>> もとのページ]] == ソースコード == <source lang="javascript"> #title = "ジャンプ" #tooltip = "ポップアップメニューで検索先にジャンプ" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",229 // ◆ 人柱版 ◆ 「大文字/小文字の区別」に対応 // 「空行+空白行」の検索に対応 // 「ヒット件数(出現回数)」を表示 /** * ------------------------------------------------------------ * "ポップアップメニューで検索先にジャンプ" * pooupJump.js * Original Copyright: 手石 (2014/04/04) * ------------------------------------------------------------ * Modified by: sukemaru (2018/11/12 - 2018/11/25) * ------------------------------------------------------------ */ // ---------- ▼ 通常版 設定項目 ▼ ---------- // ■行の表示方法 (true; 論理座標 /false; 表示座標) var logical = true; // ■初期値 = true; (論理座標) // ■検索文字列の強調表示を残すか? (true; 残す /false; 残さない) var highlightEnable = true; // ■初期値 = true; (残す) // ■選択範囲なしの状態から実行したときに自動マーカーを表示するか? (true; 表示する / false; 表示しない) // ※ [表示]メニュー >> [マーカー] >> [自動マーカー] が OFF なら効果なし。 var markerEnable = true; // ■初期値 = true; (表示する) // ---------- ▼ 人柱版 設定項目 ▼ ---------- // ◆検索文字列の大文字/小文字を区別するか? (true; 区別する / false; 区別しない) var caseEnable = false; // ◆初期値 = false; (区別しない) // ◆空行/空白行を検索対象にするか? (true; する /false; しない) var blankEnable = true; // ◆初期値 = true; (する) // ◆ヒット件数(出現回数)を表示するか? (true; する /false; しない) var countEnable = true; // ◆初期値 = true; (する) // ---------- ▼ 手石版 設定項目 ▼ ---------- // ●ポップアップメニューに表示する文字数 var menuWidth = 66; // ---------- ▲ 設定項目 ここまで ▲ ---------- Redraw = markerEnable; var sx = ScrollX, sy = ScrollY; var d = document, s = document.selection; /* 検索文字列の準備 */ var blank = new RegExp( "^[\t ]*$" , "" ); // 空白行の正規表現 // 選択範囲なしならキャレット位置の単語を選択する if ( s.IsEmpty ) { var p = s.GetActivePos(); // "選択範囲なし" のフラグ s.SelectWord(); } var st = s.Text; // 検索文字列 // 選択範囲の末尾が改行 "\n" なら検索文字列から除外する if ( ! st || st.charAt( st.length - 1 ) == "\n" ) { st = st.replace( /\n$/g , "" ); // 自動マーカーを効かせるために選択範囲も調整する var anc = s.GetAnchorPos(); var act = s.GetActivePos(); // "末尾調整" フラグ if ( anc < act && ! ( blankEnable && st.match( blank ) ) ) s.SetActivePos( act - 1, true ); if ( act < anc && ! ( blankEnable && st.match( blank ) ) ) { s.SetAnchorPos( anc - 1 ); s.SetActivePos( act, true ); } if ( blankEnable && st.match( blank ) ) var re = true; // "空白行の正規表現検索" フラグ } // 選択範囲の先頭位置と、文書全体の行数(論理行/表示行) var ty = s.GetTopPointY( logical ? mePosLogical : mePosView ); var lines = d.GetLines( logical ? 0 : meGetLineView ); var cancel = 5; // "キャンセル" フラグ // 検索文字列がないとき(空行) if ( ! blankEnable && ! st ) cancel = 1; // 検索条件エラー(選択範囲に改行あり) else if ( st.match( /\n/g ) ) cancel = 2; // ポップアップメニューでジャンプ先リスト else { /* 文書全体を行単位で分割し、配列に */ if ( logical ) // 論理行 var a = d.Text.split( "\n" ); else // 表示行 for( var i = 1, a = []; i <= lines ; i ++ ) a.push( d.GetLine( i, meGetLineView ) ); a.unshift( "" ); // a[0] に空要素を追加 /* ポップアップメニューの最上部に表示するアイテム */ var m = CreatePopupMenu(); // 文字列の検索では先頭に「キャンセル」のアイテムを表示 if ( ! re ) { m.Add( " キャンセル & ", 0 ); // Space キーでキャンセル可 m.Add( "", 0, meMenuSeparator ); var gt = 0 , h = 0; // アクティブ行(検索開始行)の文字列を取得 if ( countEnable ) var activeLine = d.GetLine( ty, logical ? 0 : meGetLineView ); } // 「空行+空白行」の検索では配列を使用する else { var mArray = [], sm1Array = [], sm2Array = []; var h = 0, b = 0, n = 0, w = 0; } /* 検索文字列がヒットした行をポップアップメニューのアイテムとして取得する */ for( var i = 1; i < a.length; i ++ ) { // i = 行番号 => y // 空行からの検索なら「空行+空白行」以外はスキップ if ( re && ! a[i].match( blank ) ) continue; // 「大文字/小文字を区別」する/しない var findCaseTF = caseEnable ? a[i].indexOf( st ) : /* else */ a[i].toLowerCase().indexOf( st.toLowerCase() ); // 検索文字列がヒットしたら if ( ( ! re && findCaseTF >= 0 ) || ( re && a[i].match( blank ) ) ) { // 行内でのヒット回数 if ( ! re && countEnable ) { // && ! st.match( blank ) var t = a[i].match( RegExp( st.replace( /\W/g , "\\$&" ) , caseEnable ? "g" : "gi" ) ); gt += t.length; // 総ヒット回数(大文字/小文字を区別できる) } // 右側につけるマーキング var check = ( ! re && countEnable ) ? Marking() : ""; // アクティブ行は左に ✓ チェックマーク付き var flags = ( i == ty ) ? meMenuChecked : 0; // + meMenuGrayed /* ポップアップメニューにアイテム(行)を追加する */ if ( ! re ) { // 行頭空白は除去、空白文字は半角スペースに置換、文字数を圧縮して取得 m.Add( Labeling( a[i], i ) + check, i, flags ); h ++; // ヒットした行数 } // 「空行+空白行」の検索ではサブメニュー用の配列に分別 else { // if ( re ) b ++; // 空行+空白行数 if ( a[i] == st ) { mArray.push( [ Labeling( a[i], i ) + check, i, flags ] ); h ++; // 一致した行数 } if ( st && a[i] == "" ) { sm1Array.push( [ Labeling( a[i], i ) + check, i, flags ] ); n ++; // 空行数 } else if ( a[i].length ) { sm2Array.push( [ Labeling( a[i], i ) + check, i, flags ] ); w ++; // 空白行数 } } } } // end for() // 配列から「空行+空白行」をポップアップメニューに追加する if ( re ) { m.Add( " すべての空行+空白行: " + SeparateNum( b ) + " 行", 0 ); m.Add( "", 0, meMenuSeparator ); if ( n && st ) { // n == sm1Array.length var sm1 = CreatePopupMenu(); m.AddPopup( " すべての空行: " + SeparateNum( n ) + " 行 (&N)", sm1 ); for ( var i = 0; i < n; i ++ ) sm1.Add( sm1Array[i][0], sm1Array[i][1], sm1Array[i][2] ); } if ( w && ( n + h != b ) ) { // w == sm2Array.length var sm2 = CreatePopupMenu(); m.AddPopup( " すべての空白行: " + SeparateNum( w ) + " 行 (&W)", sm2 ); for ( var i = 0; i < w; i ++ ) sm2.Add( sm2Array[i][0], sm2Array[i][1], sm2Array[i][2] ); } m.Add( "", 0, meMenuSeparator ); // キャンセルを兼ねる , meMenuGrayed m.Add( " ▼ 一致した行: " + SeparateNum( h ) + " 行 ▼\t& ", 0 ); for ( var i = 0; i < h; i ++ ) // h == mArray.length m.Add( mArray[i][0], mArray[i][1], mArray[i][2] ); } // ポップアップメニューを表示するのは、検索ヒット行が複数のとき if ( h > 1 || b > 1) { // ステータスバー Status = ( re ? " 一致した行数: " + SeparateNum( h ) + " 行" + " / すべての空(白)行数: " + SeparateNum( b ) + " 行" : /* ! re */ ( gt ? ( " ヒット数: " + SeparateNum( gt ) + " 件 /" ) : "" ) + " ヒットした行数: " + SeparateNum( h ) + " 行" ) + " / 全体の行数: " + SeparateNum( lines ) + ( logical ? " 行 (論理行)" : " 行 (表示行)" ); /* カーソル位置にポップアップメニューを表示 */ var y = m.Track( mePosMouse ); /* 選択した行番号(行頭)にジャンプして検索文字列を選択 */ if ( y > 0 ) { s.SetActivePoint( logical ? mePosLogical : mePosView, 1, y ); // 空白行でジャンプしたときは検索履歴に残さない if ( re && d.GetLine( y ) ) s.SetAnchorPoint( logical ? mePosLogical : mePosView, 1, y + 1 ); // 文字列でジャンプしたときは検索履歴に残す else if ( ! re ) s.Find( st, meFindNext ); d.HighlightFind = highlightEnable; // 「検索文字列の強調表示を解除」する/しない cancel = 0; } /* キャンセルした場合 */ // ポップアップメニューをキャンセル else cancel = 3; } // ほかの行でヒットなし else cancel = 4; } // end else { ポップアップメニューでジャンプ先リスト } /* ジャンプしなかったときは、キャレット位置/選択範囲を復帰 */ if ( cancel ) { if ( p ) s.SetActivePos( p ); else if ( anc < act ) s.SetActivePos( act, true ); else if ( act < anc ) { s.SetAnchorPos( anc ); s.SetActivePos( act, true ); } Status = // ステータスバーにメッセージを表示 ( ( cancel == 1 ) ? " 検索文字列がありません(空行)。" : ( cancel == 2 ) ? " 検索文字列に【 改行 】を含めることはできません。" : ( cancel == 3 ) ? " キャンセルしました。 ヒット: " + ( gt ? ( SeparateNum( gt ) + " 件 ・ " ) : "" ) + SeparateNum( h ) + " 行" : ( cancel == 4 ) ? " ほかの行には見つかりませんでした。" : /* else */ " 無効な検索文字列。" ) + " / 全体の行数: " + SeparateNum( lines ) + ( logical ? " 行 (論理行)" : " 行 (表示行)" ); ScrollX = sx; ScrollY = sy; } Redraw = true; /* 関数 Marking() */ // ポップアップメニューの右側に表示するマーキング function Marking() { var _check = ( ( i != ty && a[i] == activeLine ) ? "\t **" : // ①アクティブ行と完全一致する行(重複行) ( t && t.length > 1 ) ? "\t x" + t.length : // ②検索文字列が複数ヒットした行 ( i == ty && a[i] == st ) ? "\t ⏎" : // ③アクティブ行(行検索のとき)✓↵ ( i != ty && a[i] == st ) ? "\t *" : // ④検索文字列と完全一致する行 "" // ⑤検索文字列を含む行 ); return _check; } /* 関数 Labeling( str, num ) */ // ポップアップメニューに表示する文字列の整形 function Labeling( line, i ) { // 行頭空白を除去、空白文字は半角スペースに置換、文字数を圧縮して取得 var label = line.replace( /^[\t ]+/ , "" ) .replace( /(\t|[ ]{2,}|[ ])+/g , " " ); label = ( ! line.length ) ? "( 空行 )" : ( ! label.length ) ? ( line == st ) ? "( 空白行 " + line.length + " 文字 * )" : "( 空白行 " + line.length + " 文字 )" : ( label.length > menuWidth + 1 ) ? label.slice( 0, menuWidth ) + "..." : /* else */ label; return "" + ( " " + i ).slice( -4 ) + " : " + label; } /* 関数 SeparateNum( num ) */ // 数値を3ケタ区切りに function SeparateNum( num ) { return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g , "$1," ); } </source> [[ポップアップメニューで検索先にジャンプ#人柱版のソースコード|>> もとのページ]]
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
キャンセル
編集ヘルプ
(新しいウィンドウで開きます)
スポンサーリンク
ナビゲーション メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク