拡張自動選択
通常の「カーソル位置の単語の選択 (ダブルクリック)」を拡張したかんじの自動選択機能を提供します。
※ マクロを "ダブルクリック" に割りあてることはできません
Mery Ver 3.0.1 以降の マルチカーソル/複数選択範囲 に対応
ちょっと便利な自動選択拡張機能
「選択範囲がない」状態からこのマクロを実行すると「拡張自動選択」モードになります。
- 1. 「キャレット位置の単語」の自動選択 (通常のダブルクリックと同等)
- 2. 「同一記号の繰り返し部分」の自動選択
- 半角記号
#####、全角記号※※※※※、全角空白など、おなじ記号が連続する部分を範囲選択します。
- 半角記号
- 3. 「全角空白を含む空白文字列」の自動選択
- 通常のダブルクリックでも「タブと半角空白が混在した空白文字列」の部分を自動選択できますが、このマクロでは全角空白を含めて「タブと全角/半角空白が混在した空白文字列」全体を自動選択できます。
- 4. 「日付」の自動選択
- キャレットの右側が「日付」の数字部分なら、
2001年1月1日、2002-2-2、2003/3/3、2020.05.31のような「日付」の文字列全体を自動選択します。
- キャレットの右側が「日付」の数字部分なら、
- 5. 「行全体を選択」 (改行を含めない)
- 2. - 4. に該当しなかったときに「行全体」を自動選択します(設定項目で表示行か論理行かを指定)。
行番号のクリックとはことなり、末尾改行を選択範囲に含めません。 - ※ Mery Ver 3.0.1 以降でマルチカーソルが有効のばあい、矩形選択範囲は行に分割して各行を範囲選択します。
- 2. - 4. に該当しなかったときに「行全体」を自動選択します(設定項目で表示行か論理行かを指定)。
- ⇒ 範囲選択したらマクロ終了
- ※ 3 と 5 の機能は、ソースコード内の設定項目の値を変更すると利用できます(初期値:無効)。
注意事項
- 「同一記号の繰り返し」の自動選択機能は、たまに "ダブルクリックで同じ記号2文字選択できちゃった" が発生するのと同じレベルの頻度で失敗することがあります。
- URL 文字列上(Mery の標準機能で下線のついた URL 部分)で実行した場合は、URL が範囲選択され、URL を勝手にブラウザで開かれることがあります。
今日の日付に変換
「日付」の文字列を範囲選択した状態からこのマクロを実行すると「今日の日付」モードになります。
2001年1月1日、2002-2-2、2003/3/3、2020.05.31のような「日付」の文字列を「今日の日付」に変換しますので、このマクロを 連続実行 することで キャレット位置の「日付を自動選択」 ⇒ 「今日の日付に変換」 ができます。
- 「日付」の判定基準
-
- 「年」は、
1900-2099の範囲内の4ケタの半角数字 - 「月」は、
1-12または01-09の範囲内の半角数字 - 「日」は、
1-31または01-09の範囲内の半角数字 ("小の月" を考慮しない) - 年月日の数字の区切りは、
-./のいずれかの記号×2回、または年月日
- 「年」は、
- ※
2020年01.01や1900/1-5のように区切り文字の形式が混在した文字列からは変換しません。 - ※ 和暦の年号や全角数字で記述された日付、
20200601のような区切り文字のない半角8ケタの数値は対象外です。 - ※
2001-02-31のような実在しない日付でも「今日の日付」に変換されます。
- 変換後の「日付」の形式
- 「区切り文字」の部分は変換前とおなじままになりますが、月と日の数字部分はつねに
2020/06/01のようにゼロ埋めした2ケタに変換されます。
1行コメントアウト/アンコメント
末尾改行を含めずに「論理行全体」(1行) を範囲選択した状態からこのマクロを実行すると「1行コメントアウト/アンコメント」モードを利用できます(ソースコード内の設定項目の初期値:無効 commentOut = false )。
- 行頭に
のようなコメントマークを付けたりはずしたりできますので、このマクロを 連続実行 することで 「論理行全体を自動選択」 ⇒ 「1行コメントアウト/アンコメント」 ができます。>
※ 設定項目selectLine = 0のとき
- ※ 「1行コメントアウト」は、範囲選択なしの空行でも実行できます(コメントマーク挿入)。
- ※「コメントマーク付け外し」マクロなどから「編集モードによるコメントマークの定義切替」のコードを移植することもできます。
ソースコード
- ダウンロード >> 「ファイル:ちょっと便利な拡張自動選択.zip」(アイコン入り)
(最終更新:2020/07/01)
#title = "拡張自動選択"
#tooltip = "ちょっと便利な自動選択拡張機能 + α"
#icon = "select_ex.ico"
/**
* ---------------------------------------------------------
* 「拡張自動選択」マクロ
* sukemaru, 2020/05/31 - 2020/07/01
* ---------------------------------------------------------
* 通常の「カーソル位置の単語の選択」を拡張した自動選択機能
* ※ ダブルクリックにマクロを割りあてることはできません
* ※「選択範囲がある」状態からマクロを実行したときは「今日の日付」か
* 「1行コメントアウト/アンコメント」機能のみ
*
* ■ マルチカーソル/複数選択範囲に対応 (2020/07/01)
* ※ 矩形選択範囲から実行したときは、行に分けてからマルチ処理
*
* 「選択範囲がない」状態からマクロを実行すると「拡張自動選択」モード
*
* 1.「キャレット位置の単語」の自動選択(通常のダブルクリックと同等)
* 2.「同一記号の繰り返し」の自動選択 ##### ※※※※※
* 3.「全角空白を含む空白文字列」の自動選択
* 4.「日付け」の自動選択(キャレットの右側が数字のとき)
* ○ 2001年1月1日, 2002-2-2, 2003/3/03, 2020.05.31 / × 2020/05.31
* 5.「行全体を選択」(改行を含めない)
* ⇒ 範囲選択したらマクロ終了
*
* ※ 3, 5 は設定項目で可否を選択(初期値:無効)
* ※ fullWSpc = false の設定でも、キャレットの右側に全角空白があれば
* 「連続する全角空白」の部分を自動選択できる(2 の機能)
* ※ 5 は「タブと半角空白のみの空白文字列」上からでも実行可
*
* マクロ実行時の選択範囲の文字列が「日付」なら「今日の日付」に変換する
*
* マクロ実行時の選択範囲が論理行全体なら「1行コメントアウト/アンコメント」可
* ※ 「1行コメントアウト」は空行上でも実行可
*/
// ---------- ▼ 設定項目 ▼ ---------- //
// ■ 「空白文字列の自動選択」に「全角空白」を含める
var fullWSpc = false; // true 含める / false 含めない (タブと半角空白のみ)
// ■ 説明欄の 1 - 4 に該当しなかったときには「行全体を選択」する(改行を含めない)
var selectLine = 0; // 0 しない / 1 表示行を選択 / 2 論理行を選択
// ■ 選択範囲が論理行全体のとき「1行コメントアウト/アンコメント」する
var commentOut = false; // true する / false しない
var commentMark = "> "; // コメントマーク
// ---------- ▲ 設定項目 ▲ ---------- //
var d = editor.ActiveDocument, s = d.selection;
var sx = ScrollX, sy = ScrollY;
/* マルチカーソル/複数選択範囲に対応 */
var dt = d.Text;
var sMode = s.Mode || 1;
var arg = [ fullWSpc, selectLine, commentOut, commentMark ];
// 選択範囲が1つで矩形選択ではないとき
if ( sMode == 1 ) {
SelectEx_Main( arg );
}
// 矩形選択または複数選択のとき
else {
BeginUndoGroup();
if ( ! d.ReadOnly ) { AddUndo(); }
MultiFunction( SelectEx_Main, arg );
EndUndoGroup();
}
/* 無駄な UNDO 履歴が残らないよう対策 */
// テキストの変更なしなら一度 UNDO して、拡張自動選択だけ再試行する
if ( sMode > 1 && d.Text === dt ) {
if ( ! d.ReadOnly ) { d.Undo(); }
MultiFunction( SelectWordEx, arg );
}
ScrollX = sx; ScrollY = sy;
/**
* 関数 SelectEx_Main()
* 「拡張自動選択」マクロ
*/
function SelectEx_Main( arg ) {
var fullWSpc = arg[0];
var selectLine = arg[1];
var commentOut = arg[2];
var commentMark = arg[3];
var d = editor.ActiveDocument, s = d.selection;
var st = s.Text;
var readOnly = d.ReadOnly;
if ( readOnly ) {
Status = " ドキュメントは書き換え禁止です。";
}
// 選択範囲の文字列が日付なら「今日の日付」に変換して終了
else if ( st ) {
var today = DateOfToday( st );
if ( s.Text !== today ) {
s.Text = today;
return;
}
}
// 「キャレット位置の単語」の自動選択 または
// 「同一記号の繰り返し」/「全角空白を含む空白文字列」/「日付」の自動選択
if ( ! st && SelectWordEx( arg ) ) {
return;
}
// 「1行コメントアウト/アンコメント」
if ( ! readOnly && commentOut && commentMark
&& s.Text === d.GetLine( s.GetActivePointY( mePosLogical ), 0 )
&& CommentOut( s.Text, commentMark ) ) {
return;
}
}
/**
* 関数 DateOfToday( str )
* 選択範囲の文字列が日付なら今日の日付に変換する
*
* 引数の条件(日付の判定基準)
* ・「年」は 19 か 20 ではじまる4ケタの半角数字
* ・「月」は 1 - 12 または 01 - 09 の範囲内の半角数字
* ・「日」は 1 - 31 または 01 - 09 の範囲内の半角数字(小の月を考慮しない)
* ・年月日の数字の区切りは
* 「-」「.」「/」のいずれか(同一の記号2回の場合のみ)
* または「年月日」
* ・和暦の年号や全角数字、区切り文字のない半角8ケタの数値は不可
*
* 戻り値の「月日」の数字はつねにゼロ埋め
*/
function DateOfToday( str ) {
var reg1 = /^(?:19|20)\d{2}([-.\/])(?:0?[1-9]|1[0-2])(\1)(?:0?[1-9]|[12][0-9]|3[01])(\b)$/;
var reg2 = /^(?:19|20)\d{2}(年)(?:0?[1-9]|1[0-2])(月)(?:0?[1-9]|[12][0-9]|3[01])(日)$/;
if ( str.match( reg1 ) || str.match( reg2 ) ) {
var sep1 = RegExp["$1"], sep2 = RegExp["$2"], sep3 = RegExp["$3"];
var Pad = function( tmp ) { return tmp < 10 ? "0" + tmp : tmp; }
var dt = new Date();
var yyyy = dt.getFullYear() + sep1;
var mm = Pad( dt.getMonth() + 1 ) + sep2;
var dd = Pad( dt.getDate() ) + sep3;
str = yyyy + mm + dd;
}
return str;
}
/**
* 関数 SelectWordEx( [ fullWSpc, selectLine ] )
* ※ 引数: 「全角空白を含む空白文字列」の自動選択の許可フラグ
* 拡張自動選択
* 1.「キャレット位置の単語」の自動選択(通常のダブルクリックと同等)
* 2.「同一記号の繰り返し」の自動選択 ##### ※※※※※
* 3.「全角空白を含む空白文字列」の自動選択
* 4.「日付け」の自動選択
* ○ 2001年1月1日, 2002-2-2, 2003/3/03, 2020.05.31 / × 2020/05.31
* ※ 「日付け」の自動選択は、キャレットの右側が数字のときのみ
*/
function SelectWordEx( arg ) {
var fullWSpc = arg[0];
var selectLine = arg[1];
var d = editor.ActiveDocument, s = d.selection;
if ( s.IsEmpty ) { s.SelectWord(); } // キャレットは選択範囲の末尾
var st = s.Text; if ( ! st ) { return false; }
var ax = s.GetActivePointX( mePosLogical );
var ay = s.GetActivePointY( mePosLogical );
var line = d.GetLine( ay, 0 );
var str1 = line.slice( 0, ax - 1 ); // キャレットより前の文字列
var str2 = line.slice( ax - 1 ); // キャレットより後ろの文字列
// ※ 全角空白をふくむ空白文字列全体を自動選択
if ( fullWSpc && /^[\t ]+$/.test( st ) ) {
var sig1 = String( str1.match( /[\t ]+$/ ) || "" );
var sig2 = String( str2.match( /^[\t ]+/ ) || "" );
if ( sig1 || sig2 ) {
s.SetAnchorPoint( mePosLogical, ax - sig1.length, ay );
s.SetActivePoint( mePosLogical, ax + sig2.length, ay, true );
}
if ( s.Text !== st ) { return true; }
}
// ※ 同一記号の繰り返し文字列の自動選択
if ( st.length === 1 ) {
var sig1 = String( str1.match( new RegExp( "\\" + st + "+$", "" ) ) || "" );
var sig2 = String( str2.match( new RegExp( "^\\" + st + "+", "" ) ) || "" );
if ( sig1 || sig2 ) {
s.SetAnchorPoint( mePosLogical, ax - sig1.length, ay );
s.SetActivePoint( mePosLogical, ax + sig2.length, ay, true );
}
if ( s.Text !== st ) { return true; }
}
// ※ 日付の自動選択
if ( /^\d{4}$/.test( st ) // yyyy
&& ( mmdd = str2.match( /^年(?:0?[1-9]|1[0-2])月(?:0?[1-9]|[12][0-9]|3[01])日/ ) )
|| ( mmdd = str2.match( /^([-.\/])(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|[12][0-9]|3[01])\b/ ) )
) {
s.SetActivePoint( mePosLogical, ax + String( mmdd[0] ).length, ay, true );
return true;
}
var reg1 = /^(?:19|20)\d{2}([-.\/])(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|[12][0-9]|3[01])$/;
var reg2 = /^(?:19|20)\d{2}年(?:0?[1-9]|1[0-2])月(?:0?[1-9]|[12][0-9]|3[01])日$/;
if ( /^(?:0?[1-9]|1[0-2])$/.test( st ) // mm
&& ( yy = str1.slice( 0, - st.length ).match( /\b\d{4}[-.\/年]$/ ) )
&& ( dd = str2.match( /^[-.\/月](?:0?[1-9]|[12][0-9]|3[01])日?(?=$|\D)/ ) )
&& ( reg1.test( yy + st + dd ) || reg2.test( yy + st + dd ) ) ) {
s.SetAnchorPoint( mePosLogical, ax - ( yy + st ).length, ay );
s.SetActivePoint( mePosLogical, ax + String( dd ).length, ay, true );
return true;
}
if ( /^(?:0?[1-9]|[12][0-9]|3[01])$/.test( st ) // dd
&& ( yymm = str1.slice( 0, - st.length ).match( /\b\d{4}[-.\/年](?:0?[1-9]|1[0-2])[-.\/月]$/ ) )
&& ( dd = str2.match( /^日?(?=$|\D)/ ) )
&& ( reg1.test( yymm + st + dd ) || reg2.test( yymm + st + dd ) )
) {
s.SetAnchorPoint( mePosLogical, ax - ( yymm + st ).length, ay );
s.SetActivePoint( mePosLogical, ax + String( dd ).length, ay, true );
return true;
}
// ※ 行の自動選択
if ( selectLine ) {
s.StartOfLine( false, selectLine );
s.EndOfLine( true, selectLine );
if ( s.Text ) { return true; }
}
return false;
}
/**
* 関数 CommentOut( str, commentMark )
* 1行コメントアウト/アンコメント
*/
function CommentOut( line, commentMark ) {
var s = editor.ActiveDocument.selection;
// s.EndOfLine( false, mePosLogical );
// s.StartOfLine( true, mePosLogical );
// var line = s.Text;
var comBlank = commentMark.match( /\s+$/ ) || "";
var comEscaped = commentMark.replace( /\s+$/g, "" ).replace( /\W/g, "\\$&" );
var regUnComment = new RegExp(
"^(\\s*)(" + comEscaped + ( comBlank ? comBlank : "" ) + ")"
, "" );
if ( regUnComment.test( line ) ) {
s.Text = line.replace( regUnComment, "$1" );
}
else {
s.Text = line.replace( /^(\s*)(\S*)/, "$1" + commentMark + "$2" );
}
s.StartOfLine( true, mePosLogical );
return true;
}
/**
* 関数 MultiFunction( Fn, arg )
* マルチカーソル(複数選択範囲)に対応させる
* 第1引数: Function; 選択範囲ごとに適用する処理の関数
* 第2引数: Function に渡す引数をまとめた配列
*/
function MultiFunction( Fn, arg ) {
var d = editor.ActiveDocument;
var s = d.selection;
// 矩形選択範囲は行に分ける
s.Mode = meModeMulti;
// 選択範囲の座標を取得
var sCount = s.Count;
var Sel = [];
for ( var i = 0; i < sCount; i ++ ) {
Sel[i] = {
act: s.GetActivePos( i ),
anc: s.GetAnchorPos( i )
};
}
// 各選択範囲を処理
for ( var i = 0, diff = 0, dl; i < sCount; i ++ ) {
dl = d.TextLength;
s.SetActivePos( Sel[i].act + diff );
s.SetAnchorPos( Sel[i].anc + diff );
Fn( arg ); // SelectEX_Main() 関数
// Fn() の残した選択範囲(またはキャレット位置)を回収
Sel[i].act = s.GetActivePos();
Sel[i].anc = s.GetAnchorPos();
diff += d.TextLength - dl; // 文字数の増減量(累積)
}
// マルチカーソル(複数選択範囲)を復帰
for ( var i = 0; i < sCount; i ++ ) {
s.AddPos( Sel[i].anc, Sel[i].act );
}
}
メモ
- 2020/05/31 ➀
- このマクロは、「TAB/半角空白 トグル変換」マクロとおなじく「Yes/No マクロ」への自家用追加コードとしてつくったものを単独マクロとして切出したものです。 現在自分が使用している「同一記号の繰り返し部分の自動選択」と「日付の自動選択」⇒「今日の日付に変換」機能以外は、公開・配布用のソースコードでも初期値を「無効」に設定してあります。
- ZIP には既製の「マテリアルデザインっぽいアイコン」からちょっといじって詰めておきましたが、いい感じではなくて申しわけないです。
- 2020/05/31 ➁
- 正規表現のミスを修正。
- 2020/07/01
- マルチカーソル/複数選択範囲に対応。
- 「日付の自動選択」の誤爆を減らす修正。
- 「全角空白を含む空白文字列」の自動選択の不具合を修正。
- 「行全体を選択」と「1行コメントアウト/アンコメント」以外の機能は「Yes/No マクロ」に移植済み。
スポンサーリンク