「
次/前の文字列を検索・改
」を編集中
ナビゲーションに移動
検索に移動
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、その他の利点もあります。
中間の版での編集と競合したため、取り消せませんでした。
スパム攻撃防止用のチェックです。 けっして、ここには、値の入力は
しない
でください!
__toc__ == 次/前の文字列を検索・改 == <br><br> ; ダウンロード >> 「[[メディア:次/前の文字列を検索・改.zip|次/前の文字列を検索・改.zip]]」(アイコン入り) <br> === 機能 === [https://www.haijin-boys.com/software/mery/mery-tips#2 ショートカットキー [ Ctrl+Shift+ ↓ または ↑ ]] の「[[ヘルプ:検索#次の文字列を検索|次/前の文字列を検索]]」コマンドの機能をカスタマイズしたマクロです。 *「次/前の文字列を検索」コマンドでは、「検索/置換」ダイアログ内のオプションの ☑ 状態を適用したくない ('''適用したいオプション項目が決まっている''') *'''選択範囲が改行をふくむ複数行'''(論理行)のばあいでも「次/前の文字列を検索」と同様のジャンプ機能がほしい という個人的希望を実現する目論見です。 <br><br> === 設定項目 === このマクロの特色(上記の <q>目論見</q>)を有効にするなら * '''''optionEnable''' = <b style="color:#c00;">false</b>'' * '''''multiLinesEnable''' = <b style="color:#0000c0;">true</b>'' での運用をお勧めします(その他の設定項目はお好みで)。 <br><br> ---- '''▼ 優先オプション ▼''' <br><br> ==== 設定項目: ''findNext'' ==== * <b style="color:#0000c0;">"Next"</b> なら「次(下)の文字列を検索」 * <b style="color:#c00;">"Prev"</b> なら「前(上)の文字列を検索」 : ※ 実際のところ "Next"、"Down"、true、1 のいずれかなら「次」、それ以外の値なら「前」になるようにしてあります。 : ※ ZIP 書庫を [[#ダウンロード|ダウンロード]] した場合、あらかじめ「次」と「前」ふたつの JS ファイルを用意してあります。 <br> ==== 設定項目: ''optionEnable'' ==== 「検索」ダイアログのオプションフラグを使用するかしないかを指定します。 <div class="warningbox"> ※ '''[https://www.haijin-boys.com/software/mery/mery-3-0-0#13 Mery ver 3.0.1]''' 以降で '''複数選択''' や '''矩形選択''' している状態からこのマクロを実行したときは、強制的に '''''optionEnable''' = <b style="color:#0000c0;">true</b>'' での動作になります。 </div> * <b style="color:#0000c0;">true</b> なら、カスタマイズなしで、ショートカットキー [ Ctrl+Shift+ ↓ / ↑ ] の機能そのままに「次/前の文字列を検索」のジャンプを実行します。 : <u>[ Ctrl+Shift+ ↓ / ↑ ] の機能そのままでツールバーにマクロの '''アイコン''' を登録したいだけの場合は、<b style="color:#0000c0;">true</b> にしてください。</u> : ※「検索」ダイアログのオプションフラグ「大文字と小文字を区別する」や「文末まで検索したら文頭に移動する」が適用されます。 : ※ ジャンプした後も、「検索」ダイアログに検索文字列の履歴が残ります。 : ※ このマクロからは「検索」ダイアログのオプションフラグを取得できないので、設定項目 '''''[[#設定項目: hitCountEnable|hitCountEnable]]''' = <b style="color:#0000c0;">true</b>'' にする場合、ヒット件数は '''''matchCaseEnable''''' と '''''onlyWordEnable''''' の設定状態にしたがってカウントします。 <br><div id="false"></div> * <b style="color:#c00;">false</b> なら、「検索」ダイアログのオプションフラグを一度リセットしてから「次/前の文字列を検索」と同様のジャンプを実行します。 : ※ リセット(解除)されるオプションフラグは、以下の4項目です。 :* 「大文字と小文字を区別する」 :* 「正規表現を使用する」 :* 「単語のみを検索する」 :* 「文末まで検索したら文頭に移動する」 : ※ [https://www.haijin-boys.com/software/mery/mery-3-0-0#13 Mery ベータ版 ver 3.0.1] 以降では「migemo を使用する」[https://www.haijin-boys.com/software/mery/mery-2-8-3#13] も解除されます。 : ※「大文字と小文字を区別する」「単語のみを検索する」「文末まで検索したら文頭に移動する」については、個別の変数をもうけて再設定可能にしてあります。 : ※「終了したら閉じる」と、[https://www.haijin-boys.com/software/mery/mery-2-6-10#1 ベータ版 2.6.10] で追加された「インクリメンタルサーチ」のオプションフラグは解除されません。 : <span style="color:#c00;">※ 「検索」ダイアログのオプションフラグは、ジャンプの後も、マクロ実行前の状態に復旧されません。</span> このマクロの [[#false2|設定項目で指定した各オプションフラグ]] の ON/OFF 状態になります。 : ※ ジャンプの後、「検索」ダイアログに検索文字列の履歴を残しません。 : ※ <b style="color:#c00;">false</b> にすると「検索」ダイアログに検索文字列の最新の履歴は空になるので、つづけて <span style="color:#c00;">ショートカットキー操作での「次を検索 (F3)」と「前を検索 (Shift+F3)」のジャンプはできません</span>(検索ダイアログが開きます)。 <br> ==== 設定項目: ''highlightEnable'' ==== ジャンプした後に「'''検索文字列の強調表示'''」を残すかどうかを指定します。 * <b style="color:#0000c0;">true</b> なら、検索した文字列はハイライト状態のまま残ります。 : ※「検索文字列の強調を解除」のショートカットキーは [Alt+F3] ですので、任意のタイミングで手動で解除してください。 : ※'''''multiLinesEnable''' = <b style="color:#0000c0;">true</b>'' での複数行検索では、検索文字列はハイライトされません(Mery の仕様)。 * <b style="color:#c00;">false</b> なら、検索した文字列のハイライトを残しません。 : ※「検索文字列の強調表示」を手動で解除するのが面倒な人は <b style="color:#c00;">false</b> にしてください。 : ※「自動マーカー」が有効なら自動マーカーによる強調表示は残ります。 <br> ==== 設定項目: ''hitCountEnable'' ==== 検索文字列の出現回数をステータスバーに表示させるかを指定します。<br> ''ref. ''「[[検索ヒット数表示(選択文字列)]]」マクロ * <b style="color:#0000c0;">true</b> なら、検索ヒット数を表示します。 : ※ ヒット数のカウント方式は、基本的に Mery 標準の検索メソッドにあわせてありますが、検索ダイアログのオプションフラグに連動させることができないため '''''optionEnable''' = <b style="color:#0000c0;">true</b>'' の場合も '''''matchCaseEnable''''' と '''''onlyWordEnable''''' の設定でヒット数をカウントします。 : ※ '''''onlyWordEnable''''' (単語のみ検索) オプションが有効のときの正確度には問題があるかもしれません。 * <b style="color:#c00;">false</b> なら、検索ヒット数を表示しません。 : ※ 別途で「検索ヒット数表示」マクロのような「選択範囲が変更された時」にステータス表示するイベントマクロを使用しているばあいは、イベントマクロによってステータス表示が上書きされます。 <br> '''▲ 優先オプション ▲''' <br><br> ---- '''▼ ''optionEnable = <span id="false2" style="color:#c00;">false</span>'' のとき ▼''' <br><br> ==== 設定項目: ''findAroundEnable'' ==== * <b style="color:#0000c0;">true</b> なら、「'''文末まで検索したら文頭に移動する'''」オプションを適用して、「次/前の文字列を検索」と同様のジャンプ機能を実行します。 : ※ 「検索/置換」ダイアログ内の「文末まで検索したら文頭に移動する」オプションは、ジャンプ後も有効化されたままになります。 <br> ==== 設定項目: ''matchCaseEnable'' ==== * <b style="color:#0000c0;">true</b> なら、「'''大文字と小文字を区別する'''」オプションを適用して「次/前の文字列を検索」と同様のジャンプ機能を実行します。 : ※ 「検索/置換」ダイアログ内の「大文字と小文字を区別する」オプションは、ジャンプ後も有効化されたままになります。 <br> ==== 設定項目: ''onlyWordEnable'' ==== * <b style="color:#0000c0;">true</b> なら、「'''単語のみ検索する'''」オプションを適用して「次/前の文字列を検索」と同様のジャンプ機能を実行します。 : ※ 「検索/置換」ダイアログ内の「単語のみ検索する」オプションは、ジャンプ後も有効化されたままになります。 : <span style="color:#0000c0;">※ 実質的に「単語のみ検索」オプションが有効になるのは、検索文字列が「'''英単語のみ''' (半角アルファベットと半角数字のみ)」のときだけです。</span> 検索文字列にアンダーバー <q>_</q> 以外の記号や空白文字、 ascii 外の文字がふくまれるばあいは、'''''onlyWordEnable''' = <b style="color:#0000c0;">true</b>'' であっても「単語のみ」オプションの ON/OFF 状態は無視されます(Mery 本体の仕様と同様)。 <br> ==== 設定項目: ''multiLinesEnable'' ==== '''選択範囲が改行をふくむ複数行のばあい'''でも「次/前の文字列を検索」と同様のジャンプを可能にするための独自オプションです (Mery 本体の機能として用意されている <syntaxhighlight lang="javascript" inline style="white-space:nowrap">Document.Selection.Find( str, meFindReplaceRegExp )</syntaxhighlight> メソッドを活用しているだけですが)。 <div class="warningbox"> '''''multiLinesEnable''' = <b style="color:#0000c0;">true</b>'' でも選択範囲が改行をふくまない1行内(論理行)であれば、'''''optionEnable''' = <b style="color:#c00;">false</b>'' の [[#false|説明内容]] でジャンプを実行します。 </div> * <b style="color:#0000c0;">true</b> なら、選択範囲が複数行でも「次/前の文字列を検索」と同様のジャンプができます。 : ※ 選択範囲が改行記号をふくむ複数行の状態からジャンプしたばあいは、'''''highlightEnable''' = <b style="color:#0000c0;">true</b>'' であっても「検索文字列の強調表示」はされません(Mery 本体の仕様)。 また、Mery 本体の「自動マーカー」機能による強調表示もされません。 : ※ 選択範囲が改行記号をふくむ複数行の状態からジャンプしたばあいは、ジャンプ後に「検索」ダイアログ内のオプションフラグの設定状態をリセットします (Mery ベータ版 ver 3.0.1 以降の場合はオプションフラグをクリアしません / 2020/05/11: 第4版)。 * <b style="color:#c00;">false</b> で選択範囲が複数行だったばあいは、選択範囲をいったん解除してから、あらためてキャレット付近の '''単語''' を自動選択して「次/前の文字列を検索」と同様のジャンプをします。 <br> '''▲ ''optionEnable = <span style="color:#c00;">false</span>'' のとき ▲''' <br><br> === ダウンロード === ダウンロード >> 「[[ファイル:次/前の文字列を検索・改.zip]]」 * マクロ「次の文字列を検索・改.js」 * マクロ「前の文字列を検索・改.js」 * 専用アイコン(マテリアルデザインっぽいアイコン) <br> ; 更新履歴 * 2019/09/07(第1版) * 2019/09/09(第2版) : 検索方向「次/前」を変数で指定 : 検索ヒット数のステータス表示機能を追加 : ソースコードが長くなったので、ZIP 書庫をアップロード * 2019/12/01 - 2019/12/03(第3版) : 「単語のみ検索する」にも対応させた * 2020/05/11 - 2020/05/12(第4版) : '''[https://www.haijin-boys.com/software/mery/mery-3-0-0#13 Mery ver 3.0.1]''' で追加されたマルチカーソル機能(と矩形選択)への 対応・回避処理 を追加 : ※ Mery ver 2.x 上で実行したときの動作は 2019/12/03 版とおなじまま : <span style="color:#c00;">※ 2020/05/12: コード修正</span> <br> === ソースコード === <syntaxhighlight lang="javascript" style="height:80em; overflow:auto;"> #title = "次の文字列を検索" #tooltip = "次の文字列を検索・改" // #icon = "select_next.ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",124 // #title = "前の文字列を検索" // #tooltip = "前の文字列を検索・改" // #icon = "select_previous.ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",125 // ▲ 「次/前」の部分を直してからマクロを登録すること ▲ // 「マテリアルデザインっぽいアイコン」のインデックスは、次 = 124 / 前 = 125 /** * ---------------------------------------------- * 「次/前の文字列を検索・改」 * sukemaru, (2018/07/19 - 2020/05/12) * https://www.haijin-boys.com/wiki/次/前の文字列を検索・改 * ---------------------------------------------- * 「次/前の文字列を検索」機能をカスタマイズ * * ・検索強調なし、検索履歴なしでジャンプ可 * ・複数行選択からの検索ジャンプに対応 * ・「検索ヒット数表示(選択文字列)」マクロ(機能強化版)の関数を移植して * ヒット数をステータス表示できるようにした * * → 推奨: ショートカット [ Shift+Ctrl+ ↓ / ↑ ] に登録して置きかえる * * ※ 複数行選択でジャンプした場合は、強制的に「検索強調なし」「検索履歴なし」 * ※「検索履歴なし」では、最新の履歴が "空" になる * ※ 実行後は「検索/置換」ダイアログ内の「正規表現」オプションは OFF になる * * 2020/05/11: * ※ Mery ver 3.0.x への対応(Mery ver 3.0.1 以上) * ・矩形選択・複数選択で optionEnable=true を強制適用 * ・複数行検索で検索オプションを維持(定数 meFindKeepOptions を適用) */ var start = new Date(); // ---------- ▼ 設定項目 ▼ ---------- // ■ 検索する方向 ( 次: "Next" / 前: "Prev" ) var findNext = "Prev"; /* optionEnable, highlightEnable 両方を false にすると、検索履歴に残さない */ var optionEnable = false; // 推奨: false // true なら、検索ダイアログの「正規表現」以外のオプションが適用される // false なら、検索オプションをリセットする // ※「終了したら閉じる」と、ベータ版 2.6.10 で追加された「インクリメンタルサーチ」のオプションフラグは解除されない // ※Mery 3.0.1 以降で矩形選択や複数選択の状態からこのマクロを実行したときは、強制的に true を適用 var highlightEnable = false; // true なら、検索文字列の強調を残す // false なら、検索文字列の強調を解除する var hitCountEnable = true; // true なら、検索文字列の出現回数をステータスバーに表示する // false なら、検索ヒット数をステータスバーに表示しない // ※ 検索ダイアログのオプションフラグの状態を取得できないので、 // optionEnable = true のばあいでも、 // matchCaseEnable と onlyWordEnable のフラグを利用する /* ▼ optionEnable = false のとき ▼ */ var findAroundEnable = true; // true なら、文末まで検索したら文頭に移動する // false なら、文末まで検索したらストップ // ※ true の場合、ジャンプ後も検索ダイアログの「文末まで検索したら文頭に移動する」は ON のままにする var matchCaseEnable = false; // true なら、大文字と小文字を区別する // false なら、大文字と小文字を区別しない // ※ true の場合、ジャンプ後も検索ダイアログの「大文字と小文字を区別する」は ON のままにする var onlyWordEnable = false; // true なら、選択範囲の文字列と一致する単語を検索する(半角英数のみのとき) // false なら、選択範囲の文字列を部分的にふくむ単語も検索対象にする // ※ true の場合、ジャンプ後も検索ダイアログの「単語のみ検索する」は ON のままにする // ※ 検索文字列に半角英数字以外の文字が含まれているときは、自動的に無効 // i.e. 非単語構成文字 /\W/ を含むなら無効( /^[A-Za-z0-9_]+$/ でのみ有効) var multiLinesEnable = true; // 推奨: true // true なら、複数行選択から検索(検索強調なし、履歴なし)できる // false なら、複数行選択から検索しない // ※ true でも、選択範囲が1行内なら highlightEnable = true/false を適用 // ※ false で複数行選択のときは、キャレット位置の単語を自動選択して検索 // ---------- ▲ 設定項目 ▲ ---------- Redraw = false, Status = ""; var d = editor.ActiveDocument, s = d.selection; var st = s.Text; var sy = ScrollY; var meModeStream, meModeBox, meModeMulti, meFindKeepOptions; var isSingleStream = ( ! meModeStream || s.Mode == meModeStream ); var direction = /^(?:next|down|true|1)$/i.test( String( findNext ) ) ? meFindNext : meFindPrevious; var findAround = findAroundEnable ? meFindAround : 0; var matchCase = matchCaseEnable ? meFindReplaceCase : 0; var onlyWord = onlyWordEnable ? meFindReplaceOnlyWord : 0; var multiLines = ( multiLinesEnable && st.indexOf( "\n" ) > -1 ); var keepOptions = ( multiLines && meFindKeepOptions ) ? meFindKeepOptions : 0; // ※ ただし、複数行選択のときは強制オフ onlyWord = ( multiLines || /\W/.test( st ) ) ? 0 : onlyWord; // 検索オプションを適用して検索する場合 ※「次/前の文字列を検索」コマンド if ( optionEnable || ! isSingleStream ) { editor.ExecuteCommandByID( 2137 - direction ); // 次: 2136 / 前: 2137 } // 検索オプションをリセットして検索する場合 else { var flags = direction + findAround + matchCase + onlyWord; // 複数行選択では正規表現で検索(検索オプションを維持) if ( multiLines ) { s.Find( st.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ), flags + meFindReplaceRegExp + keepOptions ); } // 1行内の範囲選択または単語自動選択からの検索 else { // 検索オプションをリセットして「次/前の文字列を検索」 s.Find( "", flags ); s.FindRepeat( direction + meFindRepeatWord ); // + meFindKeepOptions } // 検索文字列を検索履歴から消す // multiLines || ! highlightEnable if ( ! highlightEnable && ! keepOptions ) { s.Find( "", flags ); } } // 検索強調表示の有無 d.HighlightFind = highlightEnable; // スクロール位置を調整 ScrollY = ( ScrollY == sy ) ? sy : s.GetActivePointY( mePosView ); // 検索ヒット数をステータス表示 st = s.Text; var hitStatus = ( st && hitCountEnable ) ? ( onlyWord ) ? WordHitStatus( st, d.Text, matchCase ) + " reg " : HitStatus( st, d.Text, matchCase, countMinimum = false ) : " "; Status = hitStatus + ( Status ? " " + Status + " " : "" ) + TimerStatus( new Date, start ); // 選択範囲変更イベントを発生させる if ( isSingleStream && Status.indexOf( "すべての文章に" ) == -1 ) { var anc = s.GetAnchorPos(), act = s.GetActivePos(); s.SetActivePos( anc ), s.SetActivePos( act, true ); } Redraw = true; // ---------- ▼ 関数 ▼ ---------- // /** * 関数 TimerStatus( end, start ) * start からの経過時間を [ s.sss 秒 ] で返す */ function TimerStatus( end, start ) { var elapsed = end - start; // start からの経過時間を [ s.sss 秒 ] で返す return " [ " + ( elapsed / 1000 ).toFixed( 3 ).replace( /\./, ". " ) + " sec. ]"; } /** * 関数 HitStatus( strSelection, strDocuText, matchCase, countMinimum ) * 選択文字列の出現回数を返す * https://www.haijin-boys.com/wiki/検索ヒット数表示(選択文字列)#機能強化バージョン */ function HitStatus( word, docu, matchCase, countMinimum ) { word = matchCase ? word : word.toLowerCase(); docu = matchCase ? docu : docu.toLowerCase(); var s = editor.ActiveDocument.selection; var tPos = Math.min( s.GetActivePos(), s.GetAnchorPos() ); var count = 0, hit = 0; var offset = countMinimum ? word.length : 1; var pos = docu.indexOf( word ); while ( pos >= 0 ) { count ++; if ( pos == tPos ) { hit = count; } pos = docu.indexOf( word, pos + offset ); } word = docu = ""; return count ? ( " ヒット数:" + count + " 件" + " ( " + hit + " 件目 ) " ).replace( /(\d)(?=(?:\d{3})+(?!\d))/g, "$1," ) : " "; } /** * 関数 WordHitStatus( strSelection, strDocuText, matchCase ) * 選択文字列の出現回数を返す(※単語のみ検索) * https://www.haijin-boys.com/wiki/検索ヒット数表示(選択文字列)#機能強化バージョン */ function WordHitStatus( word, docu, matchCase ) { word = word.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ); var s = editor.ActiveDocument.selection; var bPos = Math.max( s.GetActivePos(), s.GetAnchorPos() ); var reg = RegExp( "\\b" + word + "\\b", matchCase ? "g" : "gi" ); var count = ( docu.match( reg ) || [] ).length; var hit = ( docu.slice( 0, bPos ).match( reg ) || [] ).length; word = docu = ""; return count ? ( " ヒット数:" + count + " 件" + " ( " + hit + " 件目 ) " ).replace( /(\d)(?=(?:\d{3})+(?!\d))/g, "$1," ) : " "; } </syntaxhighlight> <br> == 次/前の文字列を検索・改 2 == 2021/01/20 追加 <br> === 改2の機能 === Mery 標準機能の「検索」「次/前の文字列を検索」コマンドとは完全に切りはなし、「検索/置換」ダイアログの '''オプション設定''' や '''検索履歴'''、'''検索文字列の強調表示''' の状態などを変更せずに検索・ジャンプできるようにしました。 <br><br> Mery 標準機能の '''検索文字列の強調表示''' の状態(ハイライトされた文字列)を変更せずに検索・ジャンプしたい方は、こちらの「次/前の文字列を検索・改 2」マクロをお試しください。 <br> : ※ <span style="color:#c00;">マルチカーソルには非対応 </span>につき、マルチカーソル・複数選択範囲の状態から実行した場合は Mery 標準機能の「次/前の文字列を検索」コマンドを試行します (検索履歴やハイライト状態が変更されます)。 : ※ Javascript/JScript の機能で検索・ジャンプをおこなうため、<span style="color:#c00;">古い OS</span> や <span style="color:#c00;">低スペックの PC</span> 環境、かつ、<span style="color:#c00;">長大な文書(ドキュメント)</span>では動作がやや遅い場合があります。 <br> 「[[#次/前の文字列を検索・改|次/前の文字列を検索・改]]」マクロの [[設定項目]] のうち、4項目 var [[#設定項目: optionEnable|optionEnable]] = false; var [[#設定項目: historyEnable|historyEnable]] = false; var [[#設定項目: highlightEnable|highlightEnable]] = 0; var [[#設定項目: multiLinesEnable|multiLinesEnable]] = true; は固定状態での動作になります。<br> <br> 検索ダイアログのオプション項目「文末まで検索したら文頭に移動する」「大文字と小文字を区別する」「単語のみ検索する」にあたる <b><code>findAroundEnable</code> <code>matchCaseEnable</code> <code>onlyWordEnable</code></b> と検索文字列の出現回数のステータス表示設定 <b><code>hitCountEnable</code></b> の <syntaxhighlight lang="javascript" inline>true</syntaxhighlight>/<syntaxhighlight lang="javascript" inline>false</syntaxhighlight> 、長大な文書で動作が遅くなる場合の回避設定 <b><code>maxLength</code></b> の数値を任意にカスタマイズしてご利用ください。 <br><br> === 改2のダウンロード === ダウンロード >> 「[[ファイル:次/前の文字列を検索・改_2.zip]]」 * マクロ「次の文字列を検索・改2.js」 * マクロ「前の文字列を検索・改2.js」 * 専用アイコン(マテリアルデザインっぽいアイコン) <br> ; 更新履歴 * 2021/01/20(改2 第1版) <br> === 改2のソースコード === <syntaxhighlight lang="javascript" style="height:80em; overflow:auto;"> #title = "次の文字列を検索" #tooltip = "次の文字列を検索・改 2" // #icon = "select_next.ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",124 // #title = "前の文字列を検索" // #tooltip = "前の文字列を検索・改 2" // #icon = "select_previous.ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",125 // ▲ 「次/前」の部分を直してからマクロを登録すること ▲ // 「マテリアルデザインっぽいアイコン」のインデックスは、次 = 124 / 前 = 125 /** * ---------------------------------------------- * 「次/前の文字列を検索・改 2」 * sukemaru, 2021/01/20 * https://www.haijin-boys.com/wiki/次/前の文字列を検索・改#次/前の文字列を検索・改_2 * ---------------------------------------------- * 「次/前の文字列を検索」の機能をカスタマイズした検索ジャンプ。 * * ※ Mery 標準機能の「検索/置換」ダイアログ内のオプション設定を変更しない * (Mery の検索機能を利用せず Javascript で検索・ジャンプを実行する) * * ・検索履歴に残さない * ・実行前にあった検索ハイライトを維持する * (このマクロで検索した文字列をハイライト表示しない) * ・複数行選択からの検索ジャンプ可 * ・検索ヒット数をステータス表示可 * * ※ Mery ver 3.0 以降のマルチカーソル・複数選択範囲から実行した場合は、 * Mery 標準機能の「次/前の文字列を検索」コマンドでのジャンプを試行する * (検索ダイアログのオプションを適用し、検索履歴に残る) */ var start = new Date(); // ---------- ▼ 「改2」版 設定項目 ▼ ---------- // ■ 検索する方向 ( 次: "Next" / 前: "Prev" ) var findNext = "Next"; // ■ 検索ダイアログの「文末まで検索したら文頭に移動する」オプションに相当 var findAroundEnable = true; // true なら、文末まで検索したら文頭に移動する // false なら、文末まで検索したらストップ // ※ 前を検索のときは、"文頭まで検索したら文末に移動する/しない" // ■ 検索ダイアログの「大文字と小文字を区別する」オプションに相当 var matchCaseEnable = false; // true なら、大文字と小文字を区別する // false なら、大文字と小文字を区別しない // ■ 検索ダイアログの「単語のみ検索する」オプションに相当 var onlyWordEnable = false; // true なら、選択範囲の文字列と一致する単語を検索する(半角英数字のみのとき) // false なら、選択範囲の文字列を部分的にふくむ単語も検索対象にする // ※ 検索文字列に半角英数字以外の文字が含まれている場合は、強制的に無効(false) // ■ 検索文字列の出現回数をステータスバーに表示 var hitCountEnable = true; // true なら、検索ヒット数をステータスバーに表示する // false なら、検索ヒット数をステータスバーに表示しない // ■ 長大な文書で実行して動作が遅くなる場合の回避設定 var maxLength = 0; // 0 ~ 99999 なら制限しない / 100000 以上の数値を設定すると文字数制限 // ※ 文字数が maxLength を超える文書では、強制的に // Mery 標準機能の「次/前の文字列を検索」コマンドで検索ジャンプする // ---------- ▼ 「改」旧版 設定項目 ▼ ---------- var optionEnable = false; // 「改2」版での初期値: false var historyEnable = false; // 「改2」版での初期値: false var highlightEnable = 0; // 「改2」版での初期値: 0 var multiLinesEnable = true; // 「改2」版での初期値: true // ---------- ▲ 設定項目 ▲ ---------- Status = ""; var d = editor.ActiveDocument, s = d.selection; var st = s.Text; var sy = ScrollY; var isSingleStream = ( ! s.Mode || s.Mode == 1 ); var isMultiLines = ( st.indexOf( "\n" ) > -1 ); var direction = /^(?:next|down|true|1)$/i.test( String( findNext ) ) ? 1 : 0; // meFindNext = 1 / meFindPrevious = 0 onlyWordEnable = /\W/.test( st ) ? false : onlyWordEnable; maxLength = ( maxLength >= 100000 ) ? maxLength : 0; historyEnable = ( maxLength && d.TextLength >= maxLength ) ? true : historyEnable; var keepOptions = ! historyEnable || multiLinesEnable && isMultiLines; // ---------- ▼ Main ▼ ---------- // Main: { // 「検索オプションを適用」して検索する場合 ※「次/前の文字列を検索」コマンド if ( optionEnable || ! isSingleStream ) { editor.ExecuteCommandByID( 2137 - direction ); // 次: 2136 / 前: 2137 highlightEnable = Boolean( highlightEnable ); } else if ( ! multiLinesEnable && isMultiLines ) { Status = "無効な検索文字列(複数行)。 "; break Main; } // 「次/前の文字列を検索・改 2」マクロ // 検索履歴に残さないで検索場合(検索オプションをリセットしない) else if ( keepOptions ) { if ( ! st ) { s.SelectWord(); st = s.Text; if ( ! st ) { Status = "検索文字列がありません。 "; break Main; } } var id, dt = d.Text; // 「次の文字列を検索・改 2」 if ( direction ) { var tp = Math.min( s.GetActivePos(), s.GetAnchorPos() ); id = SearchNext( st, onlyWordEnable, matchCaseEnable, dt, tp + 1 ); if ( id === -1 ) { Status = "文末まで検索しました。"; if ( findAroundEnable ) { id = SearchNext( st, onlyWordEnable, matchCaseEnable, dt ); } } } // 「前の文字列を検索・改 2」 else { var bp = Math.max( s.GetActivePos(), s.GetAnchorPos() ); id = SearchPrevious( st, onlyWordEnable, matchCaseEnable, dt, bp - 1 ); if ( id === -1 ) { Status = "文頭まで検索しました。"; if ( findAroundEnable ) { id = SearchPrevious( st, onlyWordEnable, matchCaseEnable, dt ); } } } if ( id > -1 ) { s.SetActivePos( id ); s.SetAnchorPos( id + st.length ); } } // 旧「次/前の文字列を検索・改」マクロ // 検索オプションをリセットして検索する場合(検索履歴に残す) else { var findAround = findAroundEnable ? meFindAround : 0; var matchCase = matchCaseEnable ? meFindReplaceCase : 0; var onlyWord = onlyWordEnable && ! /\W/.test( st ) ? meFindReplaceOnlyWord : 0; var flags = direction + findAround + matchCase + onlyWord; // 検索オプションをリセットして「次/前の文字列を検索」 s.Find( "", flags ); s.FindRepeat( direction + meFindRepeatWord ); if ( ! s.Text ) { Status = "検索文字列がありません。 "; break Main; } highlightEnable = Boolean( highlightEnable ); } // 検索強調表示の有無 if ( typeof highlightEnable === "boolean" ) { d.HighlightFind = highlightEnable; } // スクロール位置を調整 ScrollY = ( ScrollY === sy ) ? sy : s.GetActivePointY( mePosView ); } // ---------- ▲ Main ▲ ---------- // // 検索ヒット数をステータス表示 st = s.Text; var hitStatus = ( st && hitCountEnable ) ? ( onlyWordEnable ) ? WordHitStatus( st, dt || d.Text, matchCaseEnable ) : HitStatus( st, dt || d.Text, matchCaseEnable, countMinimum = false ) : " "; Status = hitStatus + ( Status ? " " + Status + " " : "" ) + TimerStatus( new Date, start ); // 選択範囲変更イベントを発生させる if ( st && isSingleStream && Status.indexOf( "すべての文章に" ) === -1 ) { var anc = s.GetAnchorPos(); var act = s.GetActivePos(); s.SetActivePos( anc ); s.SetActivePos( act, true ); } st = dt = null; // ---------- ▼ 関数 ▼ ---------- // /** * 関数 TimerStatus( end, start ) * start からの経過時間を [ s. sss 秒 ] で返す */ function TimerStatus( end, start ) { var elapsed = end - start; return " [ " + ( elapsed / 1000 ).toFixed( 3 ).replace( /\./, ". " ) + " sec. ]"; } /** * 関数 SearchNext( word, onlyWord, matchCase, txt [, offset] ) * 「次の文字列を検索」し、ヒットした位置を返す * * ※「単語のみ検索」「大文字と小文字を区別」のフラグを指定(必須) * ※ 検索開始位置のオフセット指定可 * ※ 戻り値は txt 全体におけるインデックス(pos >= 0) * または -1(ほかにヒットしなかったとき) * ※ 長大な文書ではオプションに関係なく遅い... */ function SearchNext( word, onlyWord, matchCase, txt, offset ) { offset = offset || 0; var pos; if ( onlyWord ) { var searchReg = RegExp( "\\b" + word.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ) + "\\b" , matchCase ? "" : "i" ); pos = txt.slice( offset ).search( searchReg ); } else { word = matchCase ? word : word.toLowerCase(); txt = matchCase ? txt : txt.toLowerCase(); pos = txt.slice( offset ).indexOf( word ); } word = txt = null; return ( pos > -1 ) ? pos + offset : -1; // ヒットなしなら -1 } /** * 関数 SearchPrevious( word, onlyWord, matchCase, txt [, offset] ) * 「前の文字列を検索」し、ヒットした位置を返す * * ※「単語のみ検索」「大文字と小文字を区別」のフラグを指定(必須) * ※ 検索開始位置のオフセット指定可 * ※ 戻り値は txt 全体におけるインデックス(pos >= 0) * または -1(ほかにヒットしなかったとき) * ※ 長大な文書ではオプションに関係なく遅い... */ function SearchPrevious( word, onlyWord, matchCase, txt, offset ) { txt = offset ? txt.slice( 0, offset ) : txt; txt = matchCase ? txt : txt.toLowerCase(); word = matchCase ? word : word.toLowerCase(); var pos = txt.lastIndexOf( word ); if ( onlyWord && pos > -1 ) { var searchReg = RegExp( "\\b" + word.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ) + "\\b" , "" ); // lastIndexOf() でヒットした word が「単語」かチェックする for ( var prev = Math.max( pos - 1, 0 ); prev > -1; prev -= 1 ) { pos = txt.slice( prev ).search( searchReg ); if ( pos > -1 ) { return prev + pos; } prev = txt.slice( 0, prev ).lastIndexOf( word ); } } word = txt = null; return pos; // ヒットなしなら -1 } /** * 関数 HitStatus( strSelection, strDocuText, matchCase, countMinimum ) * 選択文字列の出現回数を返す * https://www.haijin-boys.com/wiki/検索ヒット数表示(選択文字列)#機能強化バージョン */ function HitStatus( word, txt, matchCase, countMinimum ) { word = matchCase ? word : word.toLowerCase(); txt = matchCase ? txt : txt.toLowerCase(); var s = editor.ActiveDocument.selection; var tp = Math.min( s.GetActivePos(), s.GetAnchorPos() ); var count = 0; var hit = 0; var offset = countMinimum ? word.length : 1; var pos = txt.indexOf( word ); while ( pos >= 0 ) { count ++; if ( pos === tp ) { hit = count; } pos = txt.indexOf( word, pos + offset ); } word = txt = null; return ( count > 0 ) ? ( " ヒット数:" + count + " 件" + " ( " + hit + " 件目 ) " ).replace( /(\d)(?=(?:\d{3})+(?!\d))/g, "$1," ) : " "; } /** * 関数 WordHitStatus( strSelection, strDocuText, matchCase ) * 選択文字列の出現回数を返す(※単語のみ検索) * https://www.haijin-boys.com/wiki/検索ヒット数表示(選択文字列)#機能強化バージョン */ function WordHitStatus( word, txt, matchCase ) { word = word.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ); var s = editor.ActiveDocument.selection; var bp = Math.max( s.GetActivePos(), s.GetAnchorPos() ); var reg = RegExp( "\\b" + word + "\\b", matchCase ? "g" : "gi" ); var count = ( $count = docu.match( reg ) ) ? $count.length : 0; var hit = ( txt.slice( 0, bp ).match( reg ) || [] ).length; word = txt = null; return ( count > 0 ) ? ( " ヒット数:" + count + " 件" + " ( " + hit + " 件目 ) " ).replace( /(\d)(?=(?:\d{3})+(?!\d))/g, "$1," ) : " "; } </syntaxhighlight> <br> == メモ == Mery 標準機能の「次/前の文字列を検索」コマンドをそのままマクロ化(→ ツールバーアイコン化)する場合 <syntaxhighlight lang="javascript"> #title = "次の文字列を検索" #tooltip = "カーソル位置の文字列で次を検索します" // #icon = "select_next.ico" editor.ExecuteCommandByID( 2136 ); </syntaxhighlight><syntaxhighlight lang="javascript"> #title = "前の文字列を検索" #tooltip = "カーソル位置の文字列で前を検索します" // #icon = "select_previous.ico" editor.ExecuteCommandByID( 2137 ); </syntaxhighlight> <br> ---- <br> *個人的には、通常の「次/前の文字列を検索」コマンドのショートカットキー [ Ctrl+Shift+ ↓ または ↑ ] は変更せず、このマクロ(検索強調なし)はツールバーアイコンからの実行専用にして、検索強調の要否で使い分けています。(sukemaru) *[[利用者:Sukemaru#Find() メソッド と FindRepeat() メソッド の 定数|個人的な覚え書き]] のページに [[マクロリファレンス:Selection インターフェイス#FindRepeat メソッド|FindRepeat メソッド]] で「大文字と小文字を区別」や「末尾まで検索したら先頭から検索」オプションを使うために [[マクロリファレンス:Selection インターフェイス#Find メソッド|Find メソッド]] を併用する方法の説明を書いています。(sukemaru) *「単語のみ検索する」にあわせた検索ヒット数表示用の関数 ''WordHitStatus()'' の正確度について、あまり自信がありません (ふだん「単語のみ検索」を利用していないため)。 なにがしかの問題または改善点を見つけた方は、[https://www.haijin-boys.com/discussions Mery 公式フォーラム] などからお知らせください。(sukemaru) <br> ---- <br> *Mery ver 3 以降の [[マクロリファレンス:3:Selection オブジェクト#Find メソッド|Find メソッド]] の定数 <code>meFindKeepOptions</code> を使用したマクロを実行した後の「検索文字列の強調表示 (ハイライト)」の状態が好ましくないため、Mery 標準機能の「検索」「次/前の文字列を検索」コマンドから完全に切りはなした「[[#次/前の文字列を検索・改 2|次/前の文字列を検索・改 2]]」マクロを制作しました。(sukemaru, 2021/01/20) <br> ---- <br>
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
編集を中止
編集の仕方
(新しいウィンドウで開きます)
スポンサーリンク
案内メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク