「検索ジャンプの include版」の版間の差分
ナビゲーションに移動
検索に移動
ソースコードを修正 |
修正と更新 |
||
| 8行目: | 8行目: | ||
includeライブラリを使用し、設定内容を外部ファイルに保存します(◆settingEnable 変数で設定。デフォルト: 有効)。 | 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 class="warningbox"> | <div class="warningbox"> | ||
| 28行目: | 30行目: | ||
* 検索のさいに「英単語のみ検索」するかしないかを選択できます(◆変数で設定)。 | * 検索のさいに「英単語のみ検索」するかしないかを選択できます(◆変数で設定)。 | ||
:* | :* ただし、このオプションを有効にして検索できるのは英単語のみです。<br> 欧文でも ascii 範囲外のアルファベットを使った単語では正常に機能しません。<br><span style="color:#c00;">このオプションを有効にすると日本語の文字列は検索できません。</span> | ||
:* 有効にした場合は正規表現を使用しての検索になるので、処理がやや遅くなります。 | :* 有効にした場合は正規表現を使用しての検索になるので、処理がやや遅くなります。 | ||
| 36行目: | 38行目: | ||
== ソースコード == | == ソースコード == | ||
最終更新: 2018/12/20 | |||
※ポップアップメニューの表示に unicode 文字を使用していますので、シフトJISなどで保存しないでください。 | |||
<source lang="javascript"> | <source lang="javascript"> | ||
#title = "ジャンプ" | #title = "ジャンプ" | ||
| 43行目: | 47行目: | ||
#include "include/MeryInfo.js" | #include "include/MeryInfo.js" | ||
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",229 | // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",229 | ||
/** | /** | ||
* | |||
* ※※ メニューに検索ヒットした行が表示されないときは、メニューの「英単語のみ」のチェックをはずしてください ※※ | |||
* | |||
* ------------------------------------------------------------ | * ------------------------------------------------------------ | ||
* "ポップアップメニューで検索先にジャンプ" | * "ポップアップメニューで検索先にジャンプ" | ||
* Original Copyright: 手石 (2014/04/04) | * Original Copyright: 手石 (2014/04/04) | ||
* ------------------------------------------------------------ | * ------------------------------------------------------------ | ||
* Modified by: sukemaru (2018/11/12 - 2018/12/ | * Modified by: sukemaru (2018/11/12 - 2018/12/20) | ||
* ------------------------------------------------------------ | * ------------------------------------------------------------ | ||
* | |||
* ◆ include版 ◆ | |||
* 「includeライブラリ」を使用 | |||
* 設定内容を外部 JSON ファイルに書き出し/読み込み | |||
* 設定項目はポップアップメニューから変更可 | |||
* 「英単語のみ検索する」に対応 | |||
* 選択範囲が何件目のヒットかを表示 | |||
* | |||
*/ | */ | ||
var start = new Date(); // 所要時間の計測開始 | var start = new Date(); // 所要時間の計測開始 | ||
var setting = {}; | var setting = {}; | ||
// ---------- ▼ include版 追加設定項目 ▼ ---------- | // ---------- ▼ include版 追加設定項目 ▼ ---------- | ||
| 82行目: | 76行目: | ||
setting.settingEnable = true; // ◆初期値 = true; (表示しない) | setting.settingEnable = true; // ◆初期値 = true; (表示しない) | ||
// ◆英単語のみを検索する? (true; する / false; しない) | // ◆英単語のみを検索する? (true; する / false; しない) | ||
setting.wholeWordEnable = false; // ◆初期値 = false; (しない) | setting.wholeWordEnable = false; // ◆初期値 = false; (しない) | ||
| 91行目: | 85行目: | ||
// ※ ◆人柱版◆ の追加設定で autoLineModeEnable が true の場合は無効(自動設定) | // ※ ◆人柱版◆ の追加設定で autoLineModeEnable が true の場合は無効(自動設定) | ||
setting.logical = true; // ■初期値 = true; (論理座標) | setting.logical = true; // ■初期値 = true; (論理座標) | ||
// ■検索文字列の強調表示を残すか? (true; 残す / false; 残さない) | // ■検索文字列の強調表示を残すか? (true; 残す / false; 残さない) | ||
// ※ ◆人柱版◆ の追加設定で historyDisable が true の場合は無効(強調表示しない) | // ※ ◆人柱版◆ の追加設定で historyDisable が true の場合は無効(強調表示しない) | ||
| 101行目: | 95行目: | ||
// ◆検索処理の所要時間を表示するか? (true; する / false; しない) | // ◆検索処理の所要時間を表示するか? (true; する / false; しない) | ||
setting.timerEnable = true; // ◆初期値 = true; (する) | setting.timerEnable = true; // ◆初期値 = true; (する) | ||
// ◆行の表示方法を Mery.ini から自動で読み込むか? (true; 読み込む /false; 読み込まない) | // ◆行の表示方法を Mery.ini から自動で読み込むか? (true; 読み込む /false; 読み込まない) | ||
setting.autoLineModeEnable = false; // ◆初期値 = false; (読み込まない) | setting.autoLineModeEnable = false; // ◆初期値 = false; (読み込まない) | ||
// ◆検索文字列を「検索履歴」に残さない? (true; 残さない / false; 残す) | // ◆検索文字列を「検索履歴」に残さない? (true; 残さない / false; 残す) | ||
// ※ historyDisable が true の場合、通常版の設定 highliteEnable は無効になります(強調表示しない) | |||
setting.historyDisable = false; // ◆初期値 = true; (残す) | setting.historyDisable = false; // ◆初期値 = true; (残す) | ||
// ◆検索文字列の「大文字/小文字」を区別するか? (true; 区別する / false; 区別しない) | // ◆検索文字列の「大文字/小文字」を区別するか? (true; 区別する / false; 区別しない) | ||
setting.caseEnable = false; // ◆初期値 = false; (区別しない) | setting.caseEnable = false; // ◆初期値 = false; (区別しない) | ||
// ◆空行/空白行を検索対象にするか? (true; する / false; しない) | // ◆空行/空白行を検索対象にするか? (true; する / false; しない) | ||
setting.blankEnable = false; // ◆初期値 = true; (します) | setting.blankEnable = false; // ◆初期値 = true; (します) | ||
// ◆ヒット件数(出現回数)を表示するか? (true; 表示する / false; 表示しない) | // ◆ヒット件数(出現回数)を表示するか? (true; 表示する / false; 表示しない) | ||
setting.countEnable = false; // ◆初期値 = true; (表示します) | setting.countEnable = false; // ◆初期値 = true; (表示します) | ||
| 123行目: | 118行目: | ||
// ---------- ▲ 設定項目 ここまで ▲ ---------- | // ---------- ▲ 設定項目 ここまで ▲ ---------- | ||
var initialSettings = setting; | var initialSettings = setting; | ||
var json = ScriptName.replace( /\.js$/i , "" ); | var json = ScriptName.replace( /\.js$/i , "" ); | ||
// JSON ファイルから設定を読み込む | // JSON ファイルから設定を読み込む | ||
| 136行目: | 129行目: | ||
/* ポップアップメニューの「行番号の表示方法」 */ | /* ポップアップメニューの「行番号の表示方法」 */ | ||
// Mery.ini から「行の表示方法」を取得する | |||
if ( setting.autoLineModeEnable ) { | if ( setting.autoLineModeEnable ) { | ||
var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" ); | var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" ); | ||
$LineColumnView = Number( iniText.match( /^LineColumnView=[01]$/m ).shift().slice( -1 ) ); | $LineColumnView = Number( iniText.match( /^LineColumnView=[01]$/m ).shift().slice( -1 ) ); | ||
setting.logical = | setting.logical = ! $LineColumnView; | ||
} | } | ||
// 「行番号の表示方法」の定数を変数に | |||
var posMode = setting.logical ? mePosLogical : mePosView; | var posMode = setting.logical ? mePosLogical : mePosView; | ||
var lineMode = setting.logical ? 0 : meGetLineView; | var lineMode = setting.logical ? 0 : meGetLineView; | ||
| 146行目: | 141行目: | ||
var d = document, s = document.selection; | var d = document, s = document.selection; | ||
var sx = ScrollX, sy = ScrollY; | var sx = ScrollX, sy = ScrollY; | ||
// 選択範囲の先頭位置(行番号)と、文書全体の行数(論理行/表示行) | |||
var ty = s.GetTopPointY( posMode ); | var ty = s.GetTopPointY( posMode ); | ||
var lines = d.GetLines( lineMode ); | var lines = d.GetLines( lineMode ); | ||
var lineStatus = "全体の行数: " + SeparateNum( lines ) | |||
+ ( setting.logical ? " 行 ( 論理行 )" : " 行 ( 表示行 )" ); | |||
// メニューにピン止めする固定アイテムの字下げ = EN SPACE * ( 文書全体の行数のケタ数 / 2 ) | |||
var linesWidth = lines.toString().length; // 全体の行数のケタ数 | |||
var menuIndent = " ".slice( 0 - Math.round( linesWidth / 2 ) ); | |||
/* 検索文字列の準備 */ | /* 検索文字列の準備 */ | ||
var blank = new RegExp( "^[\t ]*$" , "" ); | var blank = new RegExp( "^[\t ]*$" , "" ); // 空白行の正規表現 | ||
var re; | var re; // "空白行の正規表現検索" フラグ | ||
// 選択範囲なしならキャレット位置の単語を選択する | |||
if ( s.IsEmpty ) { | if ( s.IsEmpty ) { | ||
var pos = s.GetActivePos(); | var pos = s.GetActivePos(); // "選択範囲なし" のフラグ | ||
s.SelectWord(); | s.SelectWord(); | ||
} | } | ||
var st = s.Text; | var st = s.Text; // 検索文字列 | ||
// 選択範囲の末尾が改行 "\n" なら検索文字列から除外する | // 選択範囲の末尾が改行 "\n" なら検索文字列から除外する | ||
if ( ! st || st.charAt( st.length - 1 ) == "\n" ) { | if ( ! st || st.charAt( st.length - 1 ) == "\n" ) { | ||
st = st.replace( /\n$/g , "" ); | st = st.replace( /\n$/g , "" ); | ||
// 自動マーカーを効かせるために選択範囲も調整する | |||
var anc = s.GetAnchorPos(); | var anc = s.GetAnchorPos(); | ||
var act = s.GetActivePos(); | var act = s.GetActivePos(); // "末尾調整" フラグ | ||
if ( anc < act && ! ( setting.blankEnable && st.match( blank ) ) ) | if ( anc < act && ! ( setting.blankEnable && st.match( blank ) ) ) { | ||
s.SetActivePos( act - 1, true ); | s.SetActivePos( act - 1, true ); | ||
} | |||
if ( act < anc && ! ( setting.blankEnable && st.match( blank ) ) ) { | if ( act < anc && ! ( setting.blankEnable && st.match( blank ) ) ) { | ||
s.SetAnchorPos( anc - 1 ); | s.SetAnchorPos( anc - 1 ); | ||
s.SetActivePos( act, true ); | s.SetActivePos( act, true ); | ||
} | } | ||
if ( setting.blankEnable && st.match( blank ) ) | if ( setting.blankEnable && st.match( blank ) ) { | ||
re = true; | re = true; // "空白行の正規表現検索" フラグ | ||
} | |||
} | } | ||
// 文書末尾の空白行の場合でも "空白行の正規表現検索" フラグ | |||
else if ( ty == lines && st == d.GetLine( ty, lineMode ) | else if ( ty == lines && st == d.GetLine( ty, lineMode ) | ||
&& setting.blankEnable && st.match( blank ) ) | && setting.blankEnable && st.match( blank ) ) { | ||
re = true; | re = true; | ||
} | |||
// "キャンセル" フラグ | |||
if ( ! setting.blankEnable && ! st ) | var cancel = 5; | ||
cancel = 1; | if ( ! setting.blankEnable && ! st ) { | ||
else if ( st.match( /\n/g ) ) | cancel = 1; // 検索文字列がないとき(空行) | ||
cancel = 2; | } | ||
else if ( st.match( /\n/g ) ) { | |||
cancel = 2; // 検索条件エラー(選択範囲に改行あり) | |||
} | |||
// ポップアップメニューでジャンプ先リスト | |||
else { | else { | ||
/* ポップアップメニューの準備 */ | /* ポップアップメニューの準備 */ | ||
var m = CreatePopupMenu(), flags; | var m = CreatePopupMenu(), flags; | ||
// include 版の設定変更メニュー | // include 版の設定変更メニュー | ||
if ( setting.settingEnable ) | if ( setting.settingEnable ) { | ||
SettingsMenu(); | SettingsMenu(); | ||
} | |||
// 「文字列」の検索では先頭に「キャンセル」のアイテムを表示 | // 「文字列」の検索では先頭に「キャンセル」のアイテムを表示 | ||
if ( ! re ) { | if ( ! re ) { | ||
m.Add( " | m.Add( menuIndent + "キャンセル & ", 0 ); // Space キーでキャンセル可 | ||
m.Add( "", 0, meMenuSeparator ); | m.Add( "", 0, meMenuSeparator ); | ||
// | // Grand total, Hit, Variables | ||
var mArray = [], | var mArray = [], rArray = [], t , me , gt = 0, hit = 0, v = 0, check = ""; | ||
if ( setting.countEnable ) | var stQuote = st.replace( /\W/g , "\\$&" ); | ||
if ( setting.countEnable ) { | |||
// アクティブ行(検索開始行)全体の文字列を取得 | |||
var activeLine = d.GetLine( ty, lineMode ); | var activeLine = d.GetLine( ty, lineMode ); | ||
var | var tx = s.GetTopPointX( posMode ); | ||
var reg = new RegExp( stQuote , setting. | // 行内のヒット数とヒット総数カウント用 | ||
var reg = new RegExp( | |||
( setting.wholeWordEnable ? ( "\\b" + stQuote + "\\b" ) : stQuote ) | |||
, ( setting.caseEnble ? "g" : "gi" ) ); | |||
} | |||
} | } | ||
// 「空行+空白行」の検索ではパターンごとの配列を使用する | |||
else { | else { | ||
var hArray = [], nArray = [], wArray = []; | var hArray = [], nArray = [], wArray = []; | ||
// Hit ( match completely ), Blank line ( n + w ), New line ( ^$ ), White space ( ^[\s ]+$ ) | |||
var h = 0, b = 0, n = 0, w = 0; | var h = 0, b = 0, n = 0, w = 0; | ||
} | } | ||
/* 文書全体を行単位で分割し、配列に */ | /* 文書全体を行単位で分割し、配列に */ | ||
for ( var a = [ "" ], i = 1; i <= lines ; i ++ ) | for ( var a = [ "" ], i = 1; i <= lines ; i ++ ) { // a[0] = "" / i = 行番号 | ||
a.push( d.GetLine( i, lineMode ) ); | a.push( d.GetLine( i, lineMode ) ); | ||
} | |||
/* 検索文字列がヒットした行をポップアップメニューのアイテムとして取得する */ | /* 検索文字列がヒットした行をポップアップメニューのアイテムとして取得する */ | ||
for ( var i = 1, len = a.length; i < len; i ++ ) { | for ( var i = 1, len = a.length; i < len; i ++ ) { // a[0] = 空要素、i = 行番号 => y | ||
// アクティブ行は左に ✓ チェックマーク付き | |||
flags = ( i == ty ) ? meMenuChecked : 0; // + meMenuGrayed | flags = ( i == ty ) ? meMenuChecked : 0; // + meMenuGrayed | ||
// 「検索文字列」がヒットしたら(「大文字/小文字」「英単語のみ」オプションに対応) | // 「検索文字列」がヒットしたら(「大文字/小文字」「英単語のみ」オプションに対応) | ||
if ( ! re && | if ( ! re && FindCaseTF( a[i] ) >= 0 ) { | ||
// | // 総ヒット数フラグが有効の場合 | ||
if ( setting.countEnable ) { | if ( setting.countEnable ) { | ||
rArray.push( [ i, gt ] ); | |||
// 行内でのヒット回数 | |||
t = a[i].match( reg ); | t = a[i].match( reg ); | ||
gt += t.length; | // 選択範囲が「何件目のヒット」か | ||
if ( i == ty ) { | |||
me = ( t.length > 1 && a[i].substr( 0, tx - 1 ).match( RegExp( reg ) ) ) | |||
? gt + 1 + a[i].substr( 0, tx - 1 ).match( RegExp( reg ) ).length | |||
: gt + 1; | |||
} | |||
gt += t.length; // 総ヒット回数(大文字/小文字を区別できる) | |||
check = Marking(); // 右側につけるマーキング | check = Marking(); // 右側につけるマーキング | ||
// 変数/関数の定義行はメニューの先頭にも置く | // 変数/関数の定義行はメニューの先頭にも置く | ||
if ( check.match( /←/ ) ) { | if ( check.match( /←/ ) ) { | ||
| 228行目: | 262行目: | ||
// 行頭空白を除去、空白文字を半角スペースに置換、文字数を圧縮 | // 行頭空白を除去、空白文字を半角スペースに置換、文字数を圧縮 | ||
// 「検索文字列がヒットした行」を配列に格納 | // 「検索文字列がヒットした行」を配列に格納 | ||
mArray.push( [ Labeling( a[i], i ) + check, i, flags ] ); | mArray.push( [ Labeling( a[i], i ) + check, i, flags ] ); // ヒットした行 | ||
hit ++; | hit ++; // ヒットした行数 | ||
} | } // end if () { 検索文字列がヒットしたら } | ||
// 「空行+空白行」の検索ではサブメニュー用の配列に分別 | // 「空行+空白行」の検索ではサブメニュー用の配列に分別 | ||
else if ( re && a[i].match( blank ) ) { | else if ( re && a[i].match( blank ) ) { | ||
b ++; | b ++; // 空行+空白行の総数: Blank line ( n + w ) | ||
if ( a[i] == st ) { | if ( a[i] == st ) { | ||
hArray.push( [ Labeling( a[i], i ), i, flags ] ); | hArray.push( [ Labeling( a[i], i ), i, flags ] ); // 一致した行 | ||
h ++; | h ++; // 一致した行数: Hit ( match completely ) | ||
} | } | ||
if ( st && ! a[i] ) { | if ( st && ! a[i] ) { | ||
nArray.push( [ Labeling( a[i], i ), i, flags ] ); | nArray.push( [ Labeling( a[i], i ), i, flags ] ); // 空行 a[i] == "" | ||
n ++; | n ++; // 空行数: New line ( /^$/ ) | ||
} | } | ||
else if ( a[i] ) { | else if ( a[i] ) { | ||
wArray.push( [ Labeling( a[i], i ), i, flags ] ); | wArray.push( [ Labeling( a[i], i ), i, flags ] ); // 空白行 a[i].length > 0 | ||
w ++; | w ++; // 空白行数: White space ( /^\s+$/ ) | ||
} | } | ||
} | } // end else if () { 「空行+空白行」の検索 } | ||
} | } // end for () { ヒットした行を取得する } | ||
// 配列から「検索文字列がヒットした行」をポップアップメニューに追加する | // 配列から「検索文字列がヒットした行」をポップアップメニューに追加する | ||
if ( ! re && hit ) { | if ( ! re && hit ) { | ||
if ( v ) | if ( v ) | ||
m.Add( "", 0, meMenuSeparator ); | m.Add( "", 0, meMenuSeparator ); | ||
for ( var i = 0; i < hit; i ++ ) { | if ( v < hit ) { | ||
for ( var i = 0; i < hit; i ++ ) { | |||
// 10件ごとにセパレータ、30件ごとに「キャンセル」行を追加 | |||
AddCancelLines( m, i ); | |||
m.Add( mArray[i][0], mArray[i][1], mArray[i][2] ); | |||
} | |||
} | } | ||
} | } | ||
// 配列から「空行+空白行」をポップアップメニューに追加する | // 配列から「空行+空白行」をポップアップメニューに追加する | ||
if ( re && b ) { | if ( re && b ) { | ||
if ( b != h ) { // ( n + w ) > h | if ( b != h ) { // ( n + w ) > h | ||
m.Add( " すべての空行+空白行: " + SeparateNum( b ) + " 行", 0 ); | m.Add( menuIndent + "すべての空行+空白行: " + SeparateNum( b ) + " 行", 0 ); // , meMenuGrayed | ||
m.Add( "", 0, meMenuSeparator ); | m.Add( "", 0, meMenuSeparator ); | ||
} | } | ||
if ( n && st ) { | if ( n && st ) { // ( nArray.length > 0 ) && ( st.length > 0 ) | ||
var sm1 = CreatePopupMenu(); | var sm1 = CreatePopupMenu(); | ||
m.AddPopup( " すべての空行: " + SeparateNum( n ) + " 行 (&N)", sm1 ); | m.AddPopup( menuIndent + "すべての空行: " + SeparateNum( n ) + " 行 (&N)", sm1 ); | ||
for ( var i = 0; i < n; i ++ ) { | for ( var i = 0; i < n; i ++ ) { | ||
AddCancelLines( sm1, i ); // 30件ごとに「キャンセル」行を追加 | AddCancelLines( sm1, i ); // 30件ごとに「キャンセル」行を追加 | ||
| 273行目: | 311行目: | ||
} | } | ||
} | } | ||
if ( w && n + h != b ) { | if ( w && n + h != b ) { // ( wArray.length > 0 ) && ( n + h != b ) | ||
var sm2 = CreatePopupMenu(); | var sm2 = CreatePopupMenu(); | ||
m.AddPopup( " すべての空白行: " + SeparateNum( w ) + " 行 (&W)", sm2 ); | m.AddPopup( menuIndent + "すべての空白行: " + SeparateNum( w ) + " 行 (&W)", sm2 ); | ||
for ( var i = 0; i < w; i ++ ) { | for ( var i = 0; i < w; i ++ ) { | ||
AddCancelLines( sm2, i ); // 30件ごとに「キャンセル」行を追加 | AddCancelLines( sm2, i ); // 30件ごとに「キャンセル」行を追加 | ||
| 281行目: | 319行目: | ||
} | } | ||
} | } | ||
if ( ( n && st ) || ( w && n + h != b ) ) | if ( ( n && st ) || ( w && n + h != b ) ) { | ||
m.Add( "", 0, meMenuSeparator ); | m.Add( "", 0, meMenuSeparator ); | ||
// キャンセルを兼ねる(Space キーでキャンセル可) | } | ||
m.Add( " | // キャンセルを兼ねる(Space キーでキャンセル可) , meMenuGrayed | ||
m.Add( " ▼ 一致した行: " + SeparateNum( h ) + " 行 ▼\t& ", 0 ); | |||
for ( var i = 0; i < h; i ++ ) { // h == hArray.length | for ( var i = 0; i < h; i ++ ) { // h == hArray.length | ||
AddCancelLines( m, i ); // 30件ごとに「キャンセル」行を追加 | AddCancelLines( m, i ); // 30件ごとに「キャンセル」行を追加 | ||
m.Add( hArray[i][0], hArray[i][1], hArray[i][2] ); | m.Add( hArray[i][0], hArray[i][1], hArray[i][2] ); | ||
} | } | ||
} | } // end if () { 配列から「空行+空白行」をポップアップメニューに追加する } | ||
/* 検索開始からポップアップメニューを表示するまでの所要時間を取得 */ | /* 検索開始からポップアップメニューを表示するまでの所要時間を取得 */ | ||
if ( setting.timerEnable ) | if ( setting.timerEnable ) { | ||
var timerStatus = TimerElapsed( new Date(), start ); | var timerStatus = TimerElapsed( new Date(), start ); | ||
} | |||
/* ポップアップメニューを表示するのは、検索ヒット行が複数のとき */ | /* ポップアップメニューを表示するのは、検索ヒット行が複数のとき */ | ||
if ( hit > 1 || b > 1 || setting.settingEnable ) { | if ( hit > 1 || b > 1 || setting.settingEnable ) { | ||
var findStatus = ( | |||
// ポップアップメニューを出すまえにステータスバー表示させること | |||
var findStatus = FindStatus( me ); | |||
Status = findStatus; | Status = findStatus; | ||
| 316行目: | 348行目: | ||
if ( y >= 100000 ) { | if ( y >= 100000 ) { | ||
SettingsChange( y ); | SettingsChange( y ); | ||
var isChanged = true; | var isChanged = true; // 選択範囲復旧のためのフラグ | ||
} | } | ||
| 322行目: | 354行目: | ||
else if ( y ) { | else if ( y ) { | ||
s.SetActivePoint( posMode, 1, y ); | s.SetActivePoint( posMode, 1, y ); | ||
// 空白行でジャンプしたときは検索履歴に残さない | // 空白行でジャンプしたときは検索履歴に残さない | ||
if ( re && d.GetLine( y, lineMode ) ) | if ( re && d.GetLine( y, lineMode ) ) { | ||
// 行(空白文字列)全体を範囲選択する(※完全な空行 ^\n では範囲選択しない) | // 行(空白文字列)全体を範囲選択する(※完全な空行 ^\n では範囲選択しない) | ||
s.SetAnchorPoint( posMode, 1, y + 1 ); | s.SetAnchorPoint( posMode, 1, y + 1 ); | ||
} | |||
// 文字列でジャンプしたとき | // 文字列でジャンプしたとき | ||
else if ( ! re ) { | else if ( ! re ) { | ||
if ( setting.historyDisable ) { | if ( setting.historyDisable ) { | ||
// 検索履歴に残さない ※「検索文字列の強調表示」なし | // 検索履歴に残さない ※「検索文字列の強調表示」なし | ||
s.SetActivePos( s.GetActivePos() + | s.SetActivePos( s.GetActivePos() + FindCaseTF( d.GetLine( y, lineMode ) ) ); | ||
s.SetAnchorPos( s.GetActivePos() + st.length ); | s.SetAnchorPos( s.GetActivePos() + st.length ); | ||
} | } | ||
| 337行目: | 371行目: | ||
s.Find( st, meFindNext ); | s.Find( st, meFindNext ); | ||
d.HighlightFind = setting.highlightEnable; // 「検索文字列の強調表示」を解除する/しない | d.HighlightFind = setting.highlightEnable; // 「検索文字列の強調表示」を解除する/しない | ||
} | |||
// ジャンプ後の選択範囲が何件目のヒットかを取得する | |||
if ( setting.countEnable ) { | |||
for ( i = 0; i < rArray.length; i ++ ) { | |||
if ( rArray[i][0] == y ) { | |||
var im = rArray[i][1] + 1; | |||
break; | |||
} | |||
} | |||
} | } | ||
} | } | ||
ScrollY = ( ScrollY == sy ) ? ScrollY | ScrollY = ( ScrollY == sy ) ? ScrollY | ||
: s.GetActivePointY( mePosView ); | : s.GetActivePointY( mePosView ); | ||
cancel = 0; | |||
} // end else ( ジャンプして、検索文字列を範囲選択 ) | |||
/* キャンセルした場合 */ | |||
else { | |||
cancel = 3; // ポップアップメニューをキャンセル ( y == 0 ) | |||
} | } | ||
} // end if () { ポップアップメニューを表示 } | |||
else { | |||
cancel = 4; // ほかの行でヒットなし ( hit == 1 || b == 1 ) | |||
} | } | ||
} // end else { ポップアップメニューでジャンプ先リスト } | |||
} | |||
/* ジャンプしなかったときは、キャレット位置/選択範囲を復帰 */ | /* ジャンプしなかったときは、キャレット位置/選択範囲を復帰 */ | ||
if ( cancel || isChanged ) { | if ( cancel || isChanged ) { | ||
if ( pos || pos === 0 ) | if ( pos || pos === 0 ) { | ||
s.SetActivePos( pos ); | s.SetActivePos( pos ); | ||
else if ( act ) { | } | ||
else if ( act || act === 0 ) { | |||
s.SetAnchorPos( anc ); | s.SetAnchorPos( anc ); | ||
s.SetActivePos( act, true ); | s.SetActivePos( act, true ); | ||
} | } | ||
ScrollX = sx; ScrollY = sy; | ScrollX = sx; ScrollY = sy; | ||
} | |||
/ | // キャンセルフラグの値が 1 or 2 のとき、所要時間の計測終了 | ||
timerStatus = ( setting.timerEnable ) | |||
? ( ! timerStatus ) | |||
? TimerElapsed( new Date(), start ) | |||
( isChanged || cancel == 3 ) ? findStatus : | : timerStatus | ||
( ( cancel == 1 ) ? " | : ""; | ||
/* ステータスバーに終了メッセージを表示 */ | |||
Status = | |||
( isChanged || cancel == 3 ) ? findStatus : // ヒット数表示のまま | |||
( cancel == 0 ) ? FindStatus( im ) : // ヒット数表示 | |||
( ( cancel == 1 ) ? " 検索文字列がありません ( 空行 )。 " : | |||
( cancel == 2 ) ? " 無効な検索文字列 ( 改行 )。 " : | |||
( cancel == 4 ) ? " ヒットなし。 " : | |||
/* else */ " 無効な検索文字列。 " // ← 使われないはず | |||
) + lineStatus + timerStatus; | |||
Quit(); | Quit(); | ||
// ------------------------------------------------------------ | // ------------------------------------------------------------ | ||
| 389行目: | 439行目: | ||
} | } | ||
/* 関数 FindCaseTF( str | /* 関数 FindCaseTF( str ) */ | ||
// 文字列 str 内で st を検索するさいに「大文字/小文字を区別」する/しない | // 文字列 str 内で st を検索するさいに「大文字/小文字を区別」する/しない | ||
// および 「英単語のみ検索」する/しない | // および 「英単語のみ検索」する/しない オプションに対応 | ||
function FindCaseTF( str | function FindCaseTF( str ) { | ||
return setting.wholeWordEnable | return setting.wholeWordEnable | ||
? str.search( RegExp( "\\b" + stQuote + "\\b" , setting.caseEnable ? "g" : "gi" ) ) | ? str.search( RegExp( "\\b" + stQuote + "\\b" , setting.caseEnable ? "g" : "gi" ) ) | ||
| 406行目: | 456行目: | ||
// 変数の宣言の行: "var st" ... / "var hoge = piyo , st " ... | // 変数の宣言の行: "var st" ... / "var hoge = piyo , st " ... | ||
a[i].match( RegExp( "\\b(?:var |let |const )(?:\\s*|[^\(]+[,]\\s+)[$]?" | a[i].match( RegExp( "\\b(?:var |let |const )(?:\\s*|[^\(]+[,]\\s+)[$]?" | ||
+ stQuote + "(?=\\s*(?:[=,;]|$))" , "" ) ) ? "\t ← v a r" : | + stQuote + "(?=\\s*(?:[=,;]|$))" , "" ) ) | ||
? "\t ← v a r" : // ※カッコの員数あわせ→)※ | |||
// 変数の宣言の行: "var hoge = fuga(), " + st | // 変数の宣言の行: "var hoge = fuga(), " + st | ||
( a[i].match( RegExp( "\\b(?:var |let |const ).*?\\(.*?[,]\\s*[$]?" | ( a[i].match( RegExp( "\\b(?:var |let |const ).*?\\(.*?[,]\\s*[$]?" | ||
+ stQuote + "(?=\\s*(?:[=,;]|$))" , "" ) ) // ※員数あわせ→)※ | |||
// 閉じていないカッコがあるかの簡易的なチェック | // 閉じていないカッコがあるかの簡易的なチェック | ||
&& SearchCloseBrc( a[i], stQuote ) ) ? "\t ← v a r" : | && SearchCloseBrc( a[i], stQuote ) ) | ||
? "\t ← v a r" : | |||
// 変数に値を代入している行 st + " = fuga" | // 変数に値を代入している行 st + " = fuga" | ||
a[i].match( RegExp( "\\b" + stQuote + "(?=\\s*=(?!=))" , "" ) ) ? "\t ← s u b" : | ( ! st.match( blank ) && | ||
a[i].match( RegExp( "\\b" + stQuote + "(?=\\s*(?:\\+=|\\+\\+|-=|--|=(?!=)))" , "" ) ) ) | |||
? "\t ← s u b" : | |||
// 関数の定義の行 | // 関数の定義の行 | ||
a[i].match( RegExp( "\\bfunction +[$]?" + stQuote + "(?=[\\s(])" , "" ) ) ? "\t ← f n" : | a[i].match( RegExp( "\\bfunction +[$]?" + stQuote + "(?=[\\s(])" , "" ) ) | ||
? "\t ← f n" : // ※員数あわせ→)※ | |||
( i != ty && a[i] == activeLine ) ? "\t **" : // ①アクティブ行と完全一致する行(重複行) | ( i != ty && a[i] == activeLine ) ? "\t **" : // ①アクティブ行と完全一致する行(重複行) | ||
( t && t.length > 1 ) ? "\t x" + t.length : // ②検索文字列が複数ヒットした行 | ( t && t.length > 1 ) ? "\t x" + t.length : // ②検索文字列が複数ヒットした行 | ||
( i == ty && a[i] == st ) ? "\t ⏎" : | ( i == ty && a[i] == st ) ? "\t ⏎" : // ③アクティブ行(行検索のとき)✓↵ | ||
( i != ty && a[i] == st ) ? "\t *" : | ( i != ty && a[i] == st ) ? "\t *" : // ④検索文字列と完全一致する行 | ||
"" | "" // ⑤検索文字列を含む行 | ||
); | ); | ||
return _check; | return _check; | ||
| 444行目: | 502行目: | ||
/* else */ label | /* else */ label | ||
); | ); | ||
return ( " | return ( " " + i ).slice( 0 - linesWidth ) + " : " + label; | ||
} | } | ||
| 451行目: | 509行目: | ||
function AddCancelLines( menu, num ) { | function AddCancelLines( menu, num ) { | ||
// 「文字列の検索」では10件ごとにセパレータを追加 | // 「文字列の検索」では10件ごとにセパレータを追加 | ||
if ( ! re && num > 0 && num % 10 == 0 && num % 30 != 0 ) | if ( ! re && num > 0 && num % 10 == 0 && num % 30 != 0 ) { | ||
menu.Add( "", 0, meMenuSeparator ); | menu.Add( "", 0, meMenuSeparator ); | ||
} | |||
// 30件ごとに「キャンセル」行を追加 | |||
if ( num % 30 == 0 ) { | if ( num % 30 == 0 ) { | ||
if ( num != 0 ) | if ( num != 0 ) { | ||
menu.Add( "", 0, meMenuSeparator ); | menu.Add( "", 0, meMenuSeparator ); | ||
} | |||
if ( num != 0 || menu != m) { | if ( num != 0 || menu != m) { | ||
menu.Add( " | menu.Add( menuIndent + "キャンセル", 0 ); | ||
menu.Add( "", 0, meMenuSeparator ); | menu.Add( "", 0, meMenuSeparator ); | ||
} | } | ||
} | } | ||
} | |||
/* 関数 FindStatus( num ) */ | |||
// ステータスバーに表示するヒット数や所要時間の情報など | |||
function FindStatus( num ) { | |||
var statusStr = | |||
( re ? " 一致: " + SeparateNum( h ) + " 行" + " / 空白行数: " + SeparateNum( b ) + " 行 / " | |||
: ( gt ? " ヒット数: " + SeparateNum( gt ) + " 件 ( " + SeparateNum( num ) + " 件目 ) ・ " | |||
: " ヒット: " ) | |||
+ SeparateNum( hit ) + " 行 / " | |||
) + lineStatus + timerStatus; | |||
return statusStr; | |||
} | } | ||
| 466行目: | 539行目: | ||
// 数値を3ケタ区切りに | // 数値を3ケタ区切りに | ||
function SeparateNum( num ) { | function SeparateNum( num ) { | ||
if ( ! num ) { num = ""; } | if ( ! num ) { | ||
num = ""; | |||
} | |||
return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g , "$1," ); | return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g , "$1," ); | ||
} | } | ||
| 499行目: | 574行目: | ||
var maxWidthFlag = setting.menuWidth > 100 ? meMenuGrayed : 0; | var maxWidthFlag = setting.menuWidth > 100 ? meMenuGrayed : 0; | ||
var minWidthFlag = setting.menuWidth < 30 ? meMenuGrayed : 0; | var minWidthFlag = setting.menuWidth < 30 ? meMenuGrayed : 0; | ||
m.Add( "", 0, meMenuSeparator ); | m.Add( "", 0, meMenuSeparator ); | ||
m.AddPopup( " | m.AddPopup( menuIndent + "設定を変更する (&S)", subMenu ); | ||
m.Add( "", 0, meMenuSeparator ); | m.Add( "", 0, meMenuSeparator ); | ||
subMenu.Add( "「大文字/小文字」 を区別する (&C)", 100007, caseFlag ); | subMenu.Add( "「大文字/小文字」 を区別する (&C)", 100007, caseFlag ); | ||
| 509行目: | 585行目: | ||
subMenu.Add( "「検索文字列の強調表示」 を残す (&F)", 100003, highlightFlag + grayOut2 ); | subMenu.Add( "「検索文字列の強調表示」 を残す (&F)", 100003, highlightFlag + grayOut2 ); | ||
subMenu.Add( "", 0, meMenuSeparator ); | subMenu.Add( "", 0, meMenuSeparator ); | ||
subMenu.Add( "「行の表示方法」 を自動設定する (&A | subMenu.Add( "「行の表示方法」 を自動設定する (&A)", 100005, autoLineModeFlag ); | ||
subMenu.Add( " 行数を 「論理行」 で表示する (&L)", 100001, logicalFlag + grayOut1 ); | subMenu.Add( " 行数を 「論理行」 で表示する (&L)", 100001, logicalFlag + grayOut1 ); | ||
subMenu.Add( " 行数を 「表示行」 で表示する (&V)", 100002, | subMenu.Add( " 行数を 「表示行」 で表示する (&V)", 100002, viewFlag ); | ||
subMenu.Add( "", 0, meMenuSeparator ); | subMenu.Add( "", 0, meMenuSeparator ); | ||
subMenu.Add( "「検索処理の所要時間」 を表示する (&T)", 100004, timerFlag ); | subMenu.Add( "「検索処理の所要時間」 を表示する (&T)", 100004, timerFlag ); | ||
| 532行目: | 608行目: | ||
function SettingsChange( num ) { | function SettingsChange( num ) { | ||
var setting = IO.Deserialize( setting, json ); | var setting = IO.Deserialize( setting, json ); | ||
var | var sIsChanged = true; | ||
switch ( num ) { | switch ( num ) { | ||
case 100001: case 100002: | case 100001: case 100002: | ||
| 568行目: | 644行目: | ||
break; | break; | ||
case 100013: | case 100013: | ||
sIsChanged = false; | |||
OpenJumpJS(); | OpenJumpJS(); | ||
break; | break; | ||
case 100014: | case 100014: | ||
sIsChanged = false; | |||
OpenJumpJson(); | OpenJumpJson(); | ||
break; | break; | ||
case 100015: | case 100015: | ||
sIsChanged = false; | |||
CheckJsonFile(); | CheckJsonFile(); | ||
break; | break; | ||
default: | default: | ||
sIsChanged = false; | |||
break; | break; | ||
} | } | ||
if ( | if ( sIsChanged ) { | ||
IO.Serialize( setting, json ); | IO.Serialize( setting, json ); | ||
} | |||
} | } | ||
| 590行目: | 667行目: | ||
// このマクロを開いて設定項目の行にジャンプする | // このマクロを開いて設定項目の行にジャンプする | ||
function OpenJumpJS() { | function OpenJumpJS() { | ||
var | // Count は 1 からの整数値、Item は 0 からの整数値 | ||
var isOpen = false, | var eCount = editors.Count; | ||
for ( var | var isOpen = false, ee , dd; | ||
OuterLoop: | |||
for ( var j = 0; j < eCount; j ++ ) { | |||
var dCount = editors.Item( j ).documents.Count; | |||
for ( var i = 0; i < dCount; i ++ ) { | |||
if ( editors.Item( j ).documents.Item( i ).FullName == ScriptFullName ) { | |||
isOpen = true; | |||
ee = j; | |||
dd = i; | |||
break OuterLoop; | |||
} | |||
} | } | ||
} | } | ||
if ( isOpen ) | if ( isOpen ) { | ||
editors.Item( ee ).documents.Item( dd ).Activate(); | |||
} | |||
else { | else { | ||
editor.NewFile(); | editor.NewFile(); | ||
ee = ( editors.Count == 1 ) ? 0 : eCount; | |||
editors.Item( ee ).OpenFile( ScriptFullName ); | |||
} | } | ||
var js = | var js = editors.Item( ee ).ActiveDocument; | ||
var settingPos = js.Text.indexOf( "setting.settingEnable" ); | |||
js.selection.SetActivePos( settingPos ); | |||
// 狙った行にスクロールしないようなので、強引にやる | |||
var yy = js.selection.GetActivePointY( mePosLogical ); | |||
new ActiveXObject( "WScript.Shell" ).Run( '"' + editor.FullName + '" /l ' + yy + ' "' + ScriptFullName + '"' ); | |||
} | } | ||
| 622行目: | 701行目: | ||
// JSON ファイルを開く | // JSON ファイルを開く | ||
function OpenJumpJson() { | function OpenJumpJson() { | ||
var jsonPath = IO.Path.Add( MeryInfo.GetMacroFolderPath(), | var jsonPath = IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings", json + ".json" ); | ||
IO.Serialize( setting, json ); | IO.Serialize( setting, json ); | ||
Sleep( 500 ); | Sleep( 500 ); | ||
if ( IO.Path.IsExist( jsonPath ) ) { | if ( IO.Path.IsExist( jsonPath ) ) { | ||
var confirmMessage = Confirm( "設定ファイルは正常です\n" | |||
+ jsonPath + "\n\n" | |||
+ IO.LoadFromFile( jsonPath ).replace( /^\{|\}$/g , " " ) | |||
.replace( /,/g , ",\n " ) | |||
+ "\n\n設定ファイルを開きますか?" ); | |||
if ( confirmMessage ) { | |||
new ActiveXObject( "WScript.Shell" ).Run( '"' + editor.FullName + '" "' + jsonPath + '"' ); | new ActiveXObject( "WScript.Shell" ).Run( '"' + editor.FullName + '" "' + jsonPath + '"' ); | ||
} | |||
} | } | ||
else | else { | ||
Alert( "設定ファイルがありません\n" | Alert( "設定ファイルがありません\n" | ||
+ IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings" ) ); | + IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings" ) ); | ||
} | |||
} | } | ||
/* 関数 CheckJsonFile() */ | /* 関数 CheckJsonFile() */ | ||
| 644行目: | 724行目: | ||
function CheckJsonFile() { | function CheckJsonFile() { | ||
if ( Confirm( "設定ファイルを初期化しますか?" ) ) { | if ( Confirm( "設定ファイルを初期化しますか?" ) ) { | ||
var jsonPath = IO.Path.Add( MeryInfo.GetMacroFolderPath(), | var jsonPath = IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings", json + ".json" ); | ||
IO.Serialize( initialSettings, json ); | IO.Serialize( initialSettings, json ); | ||
Sleep( 500 ); | Sleep( 500 ); | ||
Alert( IO.Path.IsExist( jsonPath ) ? "設定ファイルは正常です\n" + jsonPath + "\n\n" | Alert( | ||
IO.Path.IsExist( jsonPath ) | |||
? "設定ファイルは正常です\n" + jsonPath + "\n\n" | |||
+ IO.LoadFromFile( jsonPath ).replace( /^\{|\}$/g , " " ) | |||
.replace( /,/g , ",\n " ) | |||
: "設定ファイルがありません\n" | |||
+ IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings" ) | |||
); | ); | ||
Quit(); | Quit(); | ||
| 664行目: | 745行目: | ||
: 新規アップロード | : 新規アップロード | ||
* 2018/12/17 | * 2018/12/17 | ||
: | : ・ソースコードのミスを修正 | ||
: ・設定用 JSON ファイルをポップアップメニューから初期化し、内容を参照できるようにした | |||
* 2018/12/20 | |||
: ・ソースコードのミスを修正 | |||
: ・文字列の検索のさいに「選択範囲が何件目のヒットか」を表示 | |||
: ・行番号の表示桁数の制限をなくした(5000行以上のファイルにはあまり適さないとおもう… 処理速度的に) | |||
行の表示方法が「表示座標」のとき、折り返し部分にかかった文字列にはマッチしないままです。<br> 実装すると動作速度が遅くなり、実用に適さなくなってしまいます… | |||
2018年12月20日 (木) 21:57時点における版
ポップアップメニューで検索先にジャンプ(sukemaru 版)
include版
includeライブラリを使用し、設定内容を外部ファイルに保存します(◆settingEnable 変数で設定。デフォルト: 有効)。
設定内容の読み込み/書き出しが可能になったので、設定の変更はポップアップメニュー内の項目のチェック ON/OFF でできるようになります。
- あらかじめ includeライブラリ をインストールしてください。
- 設定内容の保存場所は Mery\Macros\MacroSettings\ジャンプ.json です
※ <ジャンプ> の部分はこのマクロのファイル名)。
- 「▼ 通常版 初期設定項目 ▼」以降の設定項目は『初期値』としてのみ利用され、ソースコード内の設定項目を直接書き換えする必要はありません。
ただし、settingEnable 変数をを無効にする場合は、ソースコード内で変更する必要があります。
settingEnable を無効にした場合は「人柱版」と同じ状態になるので、設定変更はソースコードの直接編集(変数の true/false の変更)でおこなう必要があります。
- はじめての設定変更のさいにエラーが発生する場合は、
- ポップアップメニューの「設定内容を初期化する」を実行して、ファイルを確認してください( → JSON ファイルを新規作成して設定値を書き出します)。
- ポップアップメニューの「JSON ファイルを開く」を実行して、ファイルを確認してください。
- JSON ファイルが正常に作成されない場合は、同梱の「ジャンプ.json」を Mery\Macros\MacroSettings\ フォルダに配置してください。
▼ 追加オプション ▼
- 検索のさいに「英単語のみ検索」するかしないかを選択できます(◆変数で設定)。
- ただし、このオプションを有効にして検索できるのは英単語のみです。
欧文でも ascii 範囲外のアルファベットを使った単語では正常に機能しません。
このオプションを有効にすると日本語の文字列は検索できません。 - 有効にした場合は正規表現を使用しての検索になるので、処理がやや遅くなります。
- ただし、このオプションを有効にして検索できるのは英単語のみです。
ソースコード
最終更新: 2018/12/20
※ポップアップメニューの表示に unicode 文字を使用していますので、シフトJISなどで保存しないでください。
#title = "ジャンプ"
#tooltip = "ポップアップメニューで検索先にジャンプ"
#include "include/IO.js"
#include "include/MeryInfo.js"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",229
/**
*
* ※※ メニューに検索ヒットした行が表示されないときは、メニューの「英単語のみ」のチェックをはずしてください ※※
*
* ------------------------------------------------------------
* "ポップアップメニューで検索先にジャンプ"
* Original Copyright: 手石 (2014/04/04)
* ------------------------------------------------------------
* Modified by: sukemaru (2018/11/12 - 2018/12/20)
* ------------------------------------------------------------
*
* ◆ include版 ◆
* 「includeライブラリ」を使用
* 設定内容を外部 JSON ファイルに書き出し/読み込み
* 設定項目はポップアップメニューから変更可
* 「英単語のみ検索する」に対応
* 選択範囲が何件目のヒットかを表示
*
*/
var start = new Date(); // 所要時間の計測開始
var setting = {};
// ---------- ▼ include版 追加設定項目 ▼ ----------
// ◆このマクロの「設定を変更するための項目」をポップアップメニューに表示するか?
setting.settingEnable = true; // ◆初期値 = true; (表示しない)
// ◆英単語のみを検索する? (true; する / false; しない)
setting.wholeWordEnable = false; // ◆初期値 = false; (しない)
// ---------- ▼ 通常版 初期設定項目 ▼ ----------
// ■行の表示方法 (true; 論理座標 /false; 表示座標)
// ※ ◆人柱版◆ の追加設定で autoLineModeEnable が true の場合は無効(自動設定)
setting.logical = true; // ■初期値 = true; (論理座標)
// ■検索文字列の強調表示を残すか? (true; 残す / false; 残さない)
// ※ ◆人柱版◆ の追加設定で historyDisable が true の場合は無効(強調表示しない)
setting.highlightEnable = true; // ■初期値 = true; (残す)
// ---------- ▼ 人柱版 初期設定項目 ▼ ----------
// ◆人柱版のオプションを有効にすると処理が遅くなります
// ◆検索処理の所要時間を表示するか? (true; する / false; しない)
setting.timerEnable = true; // ◆初期値 = true; (する)
// ◆行の表示方法を Mery.ini から自動で読み込むか? (true; 読み込む /false; 読み込まない)
setting.autoLineModeEnable = false; // ◆初期値 = false; (読み込まない)
// ◆検索文字列を「検索履歴」に残さない? (true; 残さない / false; 残す)
// ※ historyDisable が true の場合、通常版の設定 highliteEnable は無効になります(強調表示しない)
setting.historyDisable = false; // ◆初期値 = true; (残す)
// ◆検索文字列の「大文字/小文字」を区別するか? (true; 区別する / false; 区別しない)
setting.caseEnable = false; // ◆初期値 = false; (区別しない)
// ◆空行/空白行を検索対象にするか? (true; する / false; しない)
setting.blankEnable = false; // ◆初期値 = true; (します)
// ◆ヒット件数(出現回数)を表示するか? (true; 表示する / false; 表示しない)
setting.countEnable = false; // ◆初期値 = true; (表示します)
// ---------- ▼ 手石版 初期設定項目 ▼ ----------
// ●ポップアップメニューに表示する文字数
setting.menuWidth = 65;
// ---------- ▲ 設定項目 ここまで ▲ ----------
var initialSettings = setting;
var json = ScriptName.replace( /\.js$/i , "" );
// JSON ファイルから設定を読み込む
if ( setting.settingEnable ) {
setting = IO.Deserialize( setting, json );
}
/* ポップアップメニューの「行番号の表示方法」 */
// Mery.ini から「行の表示方法」を取得する
if ( setting.autoLineModeEnable ) {
var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" );
$LineColumnView = Number( iniText.match( /^LineColumnView=[01]$/m ).shift().slice( -1 ) );
setting.logical = ! $LineColumnView;
}
// 「行番号の表示方法」の定数を変数に
var posMode = setting.logical ? mePosLogical : mePosView;
var lineMode = setting.logical ? 0 : meGetLineView;
var d = document, s = document.selection;
var sx = ScrollX, sy = ScrollY;
// 選択範囲の先頭位置(行番号)と、文書全体の行数(論理行/表示行)
var ty = s.GetTopPointY( posMode );
var lines = d.GetLines( lineMode );
var lineStatus = "全体の行数: " + SeparateNum( lines )
+ ( setting.logical ? " 行 ( 論理行 )" : " 行 ( 表示行 )" );
// メニューにピン止めする固定アイテムの字下げ = EN SPACE * ( 文書全体の行数のケタ数 / 2 )
var linesWidth = lines.toString().length; // 全体の行数のケタ数
var menuIndent = " ".slice( 0 - Math.round( linesWidth / 2 ) );
/* 検索文字列の準備 */
var blank = new RegExp( "^[\t ]*$" , "" ); // 空白行の正規表現
var re; // "空白行の正規表現検索" フラグ
// 選択範囲なしならキャレット位置の単語を選択する
if ( s.IsEmpty ) {
var pos = 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 && ! ( setting.blankEnable && st.match( blank ) ) ) {
s.SetActivePos( act - 1, true );
}
if ( act < anc && ! ( setting.blankEnable && st.match( blank ) ) ) {
s.SetAnchorPos( anc - 1 );
s.SetActivePos( act, true );
}
if ( setting.blankEnable && st.match( blank ) ) {
re = true; // "空白行の正規表現検索" フラグ
}
}
// 文書末尾の空白行の場合でも "空白行の正規表現検索" フラグ
else if ( ty == lines && st == d.GetLine( ty, lineMode )
&& setting.blankEnable && st.match( blank ) ) {
re = true;
}
// "キャンセル" フラグ
var cancel = 5;
if ( ! setting.blankEnable && ! st ) {
cancel = 1; // 検索文字列がないとき(空行)
}
else if ( st.match( /\n/g ) ) {
cancel = 2; // 検索条件エラー(選択範囲に改行あり)
}
// ポップアップメニューでジャンプ先リスト
else {
/* ポップアップメニューの準備 */
var m = CreatePopupMenu(), flags;
// include 版の設定変更メニュー
if ( setting.settingEnable ) {
SettingsMenu();
}
// 「文字列」の検索では先頭に「キャンセル」のアイテムを表示
if ( ! re ) {
m.Add( menuIndent + "キャンセル & ", 0 ); // Space キーでキャンセル可
m.Add( "", 0, meMenuSeparator );
// Grand total, Hit, Variables
var mArray = [], rArray = [], t , me , gt = 0, hit = 0, v = 0, check = "";
var stQuote = st.replace( /\W/g , "\\$&" );
if ( setting.countEnable ) {
// アクティブ行(検索開始行)全体の文字列を取得
var activeLine = d.GetLine( ty, lineMode );
var tx = s.GetTopPointX( posMode );
// 行内のヒット数とヒット総数カウント用
var reg = new RegExp(
( setting.wholeWordEnable ? ( "\\b" + stQuote + "\\b" ) : stQuote )
, ( setting.caseEnble ? "g" : "gi" ) );
}
}
// 「空行+空白行」の検索ではパターンごとの配列を使用する
else {
var hArray = [], nArray = [], wArray = [];
// Hit ( match completely ), Blank line ( n + w ), New line ( ^$ ), White space ( ^[\s ]+$ )
var h = 0, b = 0, n = 0, w = 0;
}
/* 文書全体を行単位で分割し、配列に */
for ( var a = [ "" ], i = 1; i <= lines ; i ++ ) { // a[0] = "" / i = 行番号
a.push( d.GetLine( i, lineMode ) );
}
/* 検索文字列がヒットした行をポップアップメニューのアイテムとして取得する */
for ( var i = 1, len = a.length; i < len; i ++ ) { // a[0] = 空要素、i = 行番号 => y
// アクティブ行は左に ✓ チェックマーク付き
flags = ( i == ty ) ? meMenuChecked : 0; // + meMenuGrayed
// 「検索文字列」がヒットしたら(「大文字/小文字」「英単語のみ」オプションに対応)
if ( ! re && FindCaseTF( a[i] ) >= 0 ) {
// 総ヒット数フラグが有効の場合
if ( setting.countEnable ) {
rArray.push( [ i, gt ] );
// 行内でのヒット回数
t = a[i].match( reg );
// 選択範囲が「何件目のヒット」か
if ( i == ty ) {
me = ( t.length > 1 && a[i].substr( 0, tx - 1 ).match( RegExp( reg ) ) )
? gt + 1 + a[i].substr( 0, tx - 1 ).match( RegExp( reg ) ).length
: gt + 1;
}
gt += t.length; // 総ヒット回数(大文字/小文字を区別できる)
check = Marking(); // 右側につけるマーキング
// 変数/関数の定義行はメニューの先頭にも置く
if ( check.match( /←/ ) ) {
m.Add( Labeling( a[i], i ) + check, i, flags );
v ++;
}
}
// 行頭空白を除去、空白文字を半角スペースに置換、文字数を圧縮
// 「検索文字列がヒットした行」を配列に格納
mArray.push( [ Labeling( a[i], i ) + check, i, flags ] ); // ヒットした行
hit ++; // ヒットした行数
} // end if () { 検索文字列がヒットしたら }
// 「空行+空白行」の検索ではサブメニュー用の配列に分別
else if ( re && a[i].match( blank ) ) {
b ++; // 空行+空白行の総数: Blank line ( n + w )
if ( a[i] == st ) {
hArray.push( [ Labeling( a[i], i ), i, flags ] ); // 一致した行
h ++; // 一致した行数: Hit ( match completely )
}
if ( st && ! a[i] ) {
nArray.push( [ Labeling( a[i], i ), i, flags ] ); // 空行 a[i] == ""
n ++; // 空行数: New line ( /^$/ )
}
else if ( a[i] ) {
wArray.push( [ Labeling( a[i], i ), i, flags ] ); // 空白行 a[i].length > 0
w ++; // 空白行数: White space ( /^\s+$/ )
}
} // end else if () { 「空行+空白行」の検索 }
} // end for () { ヒットした行を取得する }
// 配列から「検索文字列がヒットした行」をポップアップメニューに追加する
if ( ! re && hit ) {
if ( v )
m.Add( "", 0, meMenuSeparator );
if ( v < hit ) {
for ( var i = 0; i < hit; i ++ ) {
// 10件ごとにセパレータ、30件ごとに「キャンセル」行を追加
AddCancelLines( m, i );
m.Add( mArray[i][0], mArray[i][1], mArray[i][2] );
}
}
}
// 配列から「空行+空白行」をポップアップメニューに追加する
if ( re && b ) {
if ( b != h ) { // ( n + w ) > h
m.Add( menuIndent + "すべての空行+空白行: " + SeparateNum( b ) + " 行", 0 ); // , meMenuGrayed
m.Add( "", 0, meMenuSeparator );
}
if ( n && st ) { // ( nArray.length > 0 ) && ( st.length > 0 )
var sm1 = CreatePopupMenu();
m.AddPopup( menuIndent + "すべての空行: " + SeparateNum( n ) + " 行 (&N)", sm1 );
for ( var i = 0; i < n; i ++ ) {
AddCancelLines( sm1, i ); // 30件ごとに「キャンセル」行を追加
sm1.Add( nArray[i][0], nArray[i][1], nArray[i][2] );
}
}
if ( w && n + h != b ) { // ( wArray.length > 0 ) && ( n + h != b )
var sm2 = CreatePopupMenu();
m.AddPopup( menuIndent + "すべての空白行: " + SeparateNum( w ) + " 行 (&W)", sm2 );
for ( var i = 0; i < w; i ++ ) {
AddCancelLines( sm2, i ); // 30件ごとに「キャンセル」行を追加
sm2.Add( wArray[i][0], wArray[i][1], wArray[i][2] );
}
}
if ( ( n && st ) || ( w && n + h != b ) ) {
m.Add( "", 0, meMenuSeparator );
}
// キャンセルを兼ねる(Space キーでキャンセル可) , meMenuGrayed
m.Add( " ▼ 一致した行: " + SeparateNum( h ) + " 行 ▼\t& ", 0 );
for ( var i = 0; i < h; i ++ ) { // h == hArray.length
AddCancelLines( m, i ); // 30件ごとに「キャンセル」行を追加
m.Add( hArray[i][0], hArray[i][1], hArray[i][2] );
}
} // end if () { 配列から「空行+空白行」をポップアップメニューに追加する }
/* 検索開始からポップアップメニューを表示するまでの所要時間を取得 */
if ( setting.timerEnable ) {
var timerStatus = TimerElapsed( new Date(), start );
}
/* ポップアップメニューを表示するのは、検索ヒット行が複数のとき */
if ( hit > 1 || b > 1 || setting.settingEnable ) {
// ポップアップメニューを出すまえにステータスバー表示させること
var findStatus = FindStatus( me );
Status = findStatus;
/* カーソル位置にポップアップメニューを表示 */
var y = m.Track( mePosMouse ); // Track( 0 ) ならキャレット位置
/* include 版の設定変更サブメニュー項目を選択した場合 */
if ( y >= 100000 ) {
SettingsChange( y );
var isChanged = true; // 選択範囲復旧のためのフラグ
}
/* 選択した行番号(行頭)にジャンプして、検索文字列を範囲選択 */
else if ( y ) {
s.SetActivePoint( posMode, 1, y );
// 空白行でジャンプしたときは検索履歴に残さない
if ( re && d.GetLine( y, lineMode ) ) {
// 行(空白文字列)全体を範囲選択する(※完全な空行 ^\n では範囲選択しない)
s.SetAnchorPoint( posMode, 1, y + 1 );
}
// 文字列でジャンプしたとき
else if ( ! re ) {
if ( setting.historyDisable ) {
// 検索履歴に残さない ※「検索文字列の強調表示」なし
s.SetActivePos( s.GetActivePos() + FindCaseTF( d.GetLine( y, lineMode ) ) );
s.SetAnchorPos( s.GetActivePos() + st.length );
}
else {
// 検索履歴に残す ※ Mery の検索機能で文字列を範囲選択
s.Find( st, meFindNext );
d.HighlightFind = setting.highlightEnable; // 「検索文字列の強調表示」を解除する/しない
}
// ジャンプ後の選択範囲が何件目のヒットかを取得する
if ( setting.countEnable ) {
for ( i = 0; i < rArray.length; i ++ ) {
if ( rArray[i][0] == y ) {
var im = rArray[i][1] + 1;
break;
}
}
}
}
ScrollY = ( ScrollY == sy ) ? ScrollY
: s.GetActivePointY( mePosView );
cancel = 0;
} // end else ( ジャンプして、検索文字列を範囲選択 )
/* キャンセルした場合 */
else {
cancel = 3; // ポップアップメニューをキャンセル ( y == 0 )
}
} // end if () { ポップアップメニューを表示 }
else {
cancel = 4; // ほかの行でヒットなし ( hit == 1 || b == 1 )
}
} // end else { ポップアップメニューでジャンプ先リスト }
/* ジャンプしなかったときは、キャレット位置/選択範囲を復帰 */
if ( cancel || isChanged ) {
if ( pos || pos === 0 ) {
s.SetActivePos( pos );
}
else if ( act || act === 0 ) {
s.SetAnchorPos( anc );
s.SetActivePos( act, true );
}
ScrollX = sx; ScrollY = sy;
}
// キャンセルフラグの値が 1 or 2 のとき、所要時間の計測終了
timerStatus = ( setting.timerEnable )
? ( ! timerStatus )
? TimerElapsed( new Date(), start )
: timerStatus
: "";
/* ステータスバーに終了メッセージを表示 */
Status =
( isChanged || cancel == 3 ) ? findStatus : // ヒット数表示のまま
( cancel == 0 ) ? FindStatus( im ) : // ヒット数表示
( ( cancel == 1 ) ? " 検索文字列がありません ( 空行 )。 " :
( cancel == 2 ) ? " 無効な検索文字列 ( 改行 )。 " :
( cancel == 4 ) ? " ヒットなし。 " :
/* else */ " 無効な検索文字列。 " // ← 使われないはず
) + lineStatus + timerStatus;
Quit();
// ------------------------------------------------------------
/* 関数 TimerElapsed( end, start ) */
// start からの経過時間を [ s.sss 秒 ] で返す
function TimerElapsed( end, start ) {
var elapsed = end - start;
return " [ "
+ ( ( elapsed / 1000 ) + "000" ).replace( /(\.)(\d{3})(0*)/, "$1 $2" )
+ " 秒 ]";
}
/* 関数 FindCaseTF( str ) */
// 文字列 str 内で st を検索するさいに「大文字/小文字を区別」する/しない
// および 「英単語のみ検索」する/しない オプションに対応
function FindCaseTF( str ) {
return setting.wholeWordEnable
? str.search( RegExp( "\\b" + stQuote + "\\b" , setting.caseEnable ? "g" : "gi" ) )
: setting.caseEnable
? str.indexOf( st )
: str.toLowerCase().indexOf( st.toLowerCase() );
}
/* 関数 Marking() */
// ポップアップメニューの右側に表示するマーキング
function Marking() {
var _check = (
// 変数の宣言の行: "var st" ... / "var hoge = piyo , st " ...
a[i].match( RegExp( "\\b(?:var |let |const )(?:\\s*|[^\(]+[,]\\s+)[$]?"
+ stQuote + "(?=\\s*(?:[=,;]|$))" , "" ) )
? "\t ← v a r" : // ※カッコの員数あわせ→)※
// 変数の宣言の行: "var hoge = fuga(), " + st
( a[i].match( RegExp( "\\b(?:var |let |const ).*?\\(.*?[,]\\s*[$]?"
+ stQuote + "(?=\\s*(?:[=,;]|$))" , "" ) ) // ※員数あわせ→)※
// 閉じていないカッコがあるかの簡易的なチェック
&& SearchCloseBrc( a[i], stQuote ) )
? "\t ← v a r" :
// 変数に値を代入している行 st + " = fuga"
( ! st.match( blank ) &&
a[i].match( RegExp( "\\b" + stQuote + "(?=\\s*(?:\\+=|\\+\\+|-=|--|=(?!=)))" , "" ) ) )
? "\t ← s u b" :
// 関数の定義の行
a[i].match( RegExp( "\\bfunction +[$]?" + stQuote + "(?=[\\s(])" , "" ) )
? "\t ← f n" : // ※員数あわせ→)※
( 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 ) { // Labeling( a[i], i ) ※ line = a[i] ヒットした行全体
// 行頭空白を除去、空白文字は全角スペースに置換、文字数を圧縮して取得
// 判別しづらい半角メタ文字を全角に置きかえる
var label = line.replace( /^[\t ]+/ , "" )
.replace( /(\t|[ ]{3,}|[ ]{2,})+/g , " › " )
.replace( /[.,:;(){}]/g , function( $0 ) {
return String.fromCharCode( $0.charCodeAt( 0 ) + 0xFEE0 )
} );
label = (
( ! line.length ) ? "( 空行 )" :
( ! label.length ) ?
( line == st ) ? "( 空白行 " + line.length + " 文字 * )" :
"( 空白行 " + line.length + " 文字 )" :
( label.length > setting.menuWidth + 1 ) ? label.slice( 0, setting.menuWidth ) + "..." :
/* else */ label
);
return ( " " + i ).slice( 0 - linesWidth ) + " : " + label;
}
/* 関数 AddCancelLines( menu, num ) */
// 30行ごとに「キャンセル」行を追加する
function AddCancelLines( menu, num ) {
// 「文字列の検索」では10件ごとにセパレータを追加
if ( ! re && num > 0 && num % 10 == 0 && num % 30 != 0 ) {
menu.Add( "", 0, meMenuSeparator );
}
// 30件ごとに「キャンセル」行を追加
if ( num % 30 == 0 ) {
if ( num != 0 ) {
menu.Add( "", 0, meMenuSeparator );
}
if ( num != 0 || menu != m) {
menu.Add( menuIndent + "キャンセル", 0 );
menu.Add( "", 0, meMenuSeparator );
}
}
}
/* 関数 FindStatus( num ) */
// ステータスバーに表示するヒット数や所要時間の情報など
function FindStatus( num ) {
var statusStr =
( re ? " 一致: " + SeparateNum( h ) + " 行" + " / 空白行数: " + SeparateNum( b ) + " 行 / "
: ( gt ? " ヒット数: " + SeparateNum( gt ) + " 件 ( " + SeparateNum( num ) + " 件目 ) ・ "
: " ヒット: " )
+ SeparateNum( hit ) + " 行 / "
) + lineStatus + timerStatus;
return statusStr;
}
/* 関数 SeparateNum( num ) */
// 数値を3ケタ区切りに
function SeparateNum( num ) {
if ( ! num ) {
num = "";
}
return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g , "$1," );
}
/* 関数 SearchCloseBrc( str, word ) */
// 閉じていないカッコがないかを簡易的にチェックする(閉じていなければ false )
function SearchCloseBrc( str, word ) {
var txt = str.substr( str.search( /\b(?:var |let |const )/ ),
str.search( RegExp( "\\b" + word + "\\b" , "" ) )
);
var oBrc = txt.match( /\(/g ); // 開きカッコの数
var cBrc = txt.match (/\)/g ); // 閉じカッコの数
return ( ! cBrc || oBrc.length > cBrc.length ) ? 0 : 1;
}
/* 関数 SettingsMenu() */
// ポップアップメニューに設定変更用のサブメニューを表示する
function SettingsMenu() {
var subMenu = CreatePopupMenu();
var grayOut1 = setting.autoLineModeEnable ? meMenuGrayed : 0;
var logicalFlag = setting.logical ? meMenuChecked : 0;
var viewFlag = setting.logical ? 0 : meMenuChecked;
var grayOut2 = setting.historyDisable ? meMenuGrayed : 0;
var highlightFlag = ( setting.highlightEnable && ! setting.historyDisable ) ? meMenuChecked : 0;
var timerFlag = setting.timerEnable ? meMenuChecked : 0;
var autoLineModeFlag = setting.autoLineModeEnable ? meMenuChecked : 0;
var historyFlag = setting.historyDisable ? meMenuChecked : 0;
var caseFlag = setting.caseEnable ? meMenuChecked : 0;
var wholeWordFlag = setting.wholeWordEnable ? meMenuChecked : 0;
var blankFlag = setting.blankEnable ? meMenuChecked : 0;
var countFlag = setting.countEnable ? meMenuChecked : 0;
var maxWidthFlag = setting.menuWidth > 100 ? meMenuGrayed : 0;
var minWidthFlag = setting.menuWidth < 30 ? meMenuGrayed : 0;
m.Add( "", 0, meMenuSeparator );
m.AddPopup( menuIndent + "設定を変更する (&S)", subMenu );
m.Add( "", 0, meMenuSeparator );
subMenu.Add( "「大文字/小文字」 を区別する (&C)", 100007, caseFlag );
subMenu.Add( "「英単語のみ」 検索する (&W)", 100008, wholeWordFlag );
subMenu.Add( "「空行/空白行」 を検索対象にする (&B)", 100009, blankFlag );
subMenu.Add( "", 0, meMenuSeparator );
subMenu.Add( "「検索履歴」 に残さない (&H)", 100006, historyFlag );
subMenu.Add( "「検索文字列の強調表示」 を残す (&F)", 100003, highlightFlag + grayOut2 );
subMenu.Add( "", 0, meMenuSeparator );
subMenu.Add( "「行の表示方法」 を自動設定する (&A)", 100005, autoLineModeFlag );
subMenu.Add( " 行数を 「論理行」 で表示する (&L)", 100001, logicalFlag + grayOut1 );
subMenu.Add( " 行数を 「表示行」 で表示する (&V)", 100002, viewFlag );
subMenu.Add( "", 0, meMenuSeparator );
subMenu.Add( "「検索処理の所要時間」 を表示する (&T)", 100004, timerFlag );
subMenu.Add( "「ヒット件数」(出現総数)を表示する (&G)", 100010, countFlag );
subMenu.Add( "", 0, meMenuSeparator );
subMenu.Add( " メニューの表示幅を 10文字 増やす (&P) \t" + setting.menuWidth
+ ( setting.menuWidth > 100 ? "" : " → " + ( setting.menuWidth + 10 ) ), 100011, maxWidthFlag );
subMenu.Add( " メニューの表示幅を 10文字 減らす (&M) \t" + setting.menuWidth
+ ( setting.menuWidth < 30 ? "" : " → " + ( setting.menuWidth - 10 ) ), 100012, minWidthFlag );
subMenu.Add( "", 0, meMenuSeparator );
subMenu.Add( "", 0, meMenuSeparator );
subMenu.Add( " このマクロの JS ファイルを開く (&O)", 100013 );
subMenu.Add( " このマクロの JSON ファイルを開く (&J)", 100014 );
subMenu.Add( "", 0, meMenuSeparator );
subMenu.Add( " 設定内容を初期化する (&I)", 100015 );
}
/* 関数 SettingsChange( num ) */
// ポップアップメニューで選択した項目の設定状態を変更する
function SettingsChange( num ) {
var setting = IO.Deserialize( setting, json );
var sIsChanged = true;
switch ( num ) {
case 100001: case 100002:
setting.logical = ! setting.logical;
break;
case 100003:
setting.highlightEnable = ! setting.highlightEnable;
break;
case 100004:
setting.timerEnable = ! setting.timerEnable;
break;
case 100005:
setting.autoLineModeEnable = ! setting.autoLineModeEnable;
break;
case 100006:
setting.historyDisable = ! setting.historyDisable;
break;
case 100007:
setting.caseEnable = ! setting.caseEnable;
break;
case 100008:
setting.wholeWordEnable = ! setting.wholeWordEnable;
break;
case 100009:
setting.blankEnable = ! setting.blankEnable;
break;
case 100010:
setting.countEnable = ! setting.countEnable;
break;
case 100011:
setting.menuWidth += 10;
break;
case 100012:
setting.menuWidth -= 10;
break;
case 100013:
sIsChanged = false;
OpenJumpJS();
break;
case 100014:
sIsChanged = false;
OpenJumpJson();
break;
case 100015:
sIsChanged = false;
CheckJsonFile();
break;
default:
sIsChanged = false;
break;
}
if ( sIsChanged ) {
IO.Serialize( setting, json );
}
}
/* 関数 OpenJumpJS() */
// このマクロを開いて設定項目の行にジャンプする
function OpenJumpJS() {
// Count は 1 からの整数値、Item は 0 からの整数値
var eCount = editors.Count;
var isOpen = false, ee , dd;
OuterLoop:
for ( var j = 0; j < eCount; j ++ ) {
var dCount = editors.Item( j ).documents.Count;
for ( var i = 0; i < dCount; i ++ ) {
if ( editors.Item( j ).documents.Item( i ).FullName == ScriptFullName ) {
isOpen = true;
ee = j;
dd = i;
break OuterLoop;
}
}
}
if ( isOpen ) {
editors.Item( ee ).documents.Item( dd ).Activate();
}
else {
editor.NewFile();
ee = ( editors.Count == 1 ) ? 0 : eCount;
editors.Item( ee ).OpenFile( ScriptFullName );
}
var js = editors.Item( ee ).ActiveDocument;
var settingPos = js.Text.indexOf( "setting.settingEnable" );
js.selection.SetActivePos( settingPos );
// 狙った行にスクロールしないようなので、強引にやる
var yy = js.selection.GetActivePointY( mePosLogical );
new ActiveXObject( "WScript.Shell" ).Run( '"' + editor.FullName + '" /l ' + yy + ' "' + ScriptFullName + '"' );
}
/* 関数 OpenJumpJson() */
// JSON ファイルを開く
function OpenJumpJson() {
var jsonPath = IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings", json + ".json" );
IO.Serialize( setting, json );
Sleep( 500 );
if ( IO.Path.IsExist( jsonPath ) ) {
var confirmMessage = Confirm( "設定ファイルは正常です\n"
+ jsonPath + "\n\n"
+ IO.LoadFromFile( jsonPath ).replace( /^\{|\}$/g , " " )
.replace( /,/g , ",\n " )
+ "\n\n設定ファイルを開きますか?" );
if ( confirmMessage ) {
new ActiveXObject( "WScript.Shell" ).Run( '"' + editor.FullName + '" "' + jsonPath + '"' );
}
}
else {
Alert( "設定ファイルがありません\n"
+ IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings" ) );
}
}
/* 関数 CheckJsonFile() */
// JSON ファイルの初期化/実在確認
function CheckJsonFile() {
if ( Confirm( "設定ファイルを初期化しますか?" ) ) {
var jsonPath = IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings", json + ".json" );
IO.Serialize( initialSettings, json );
Sleep( 500 );
Alert(
IO.Path.IsExist( jsonPath )
? "設定ファイルは正常です\n" + jsonPath + "\n\n"
+ IO.LoadFromFile( jsonPath ).replace( /^\{|\}$/g , " " )
.replace( /,/g , ",\n " )
: "設定ファイルがありません\n"
+ IO.Path.Add( MeryInfo.GetMacroFolderPath(), "MacroSettings" )
);
Quit();
}
}
メモ
- 2018/12/16
- 新規アップロード
- 2018/12/17
- ・ソースコードのミスを修正
- ・設定用 JSON ファイルをポップアップメニューから初期化し、内容を参照できるようにした
- 2018/12/20
- ・ソースコードのミスを修正
- ・文字列の検索のさいに「選択範囲が何件目のヒットか」を表示
- ・行番号の表示桁数の制限をなくした(5000行以上のファイルにはあまり適さないとおもう… 処理速度的に)
行の表示方法が「表示座標」のとき、折り返し部分にかかった文字列にはマッチしないままです。
実装すると動作速度が遅くなり、実用に適さなくなってしまいます…
スポンサーリンク
