「拡張自動選択」の版間の差分
ナビゲーションに移動
検索に移動
修正 |
更新(マルチカーソル/複数選択範囲に対応) |
||
| 1行目: | 1行目: | ||
通常の「カーソル位置の単語の選択 (ダブルクリック)」を拡張したかんじの自動選択機能を提供します。<br> | 通常の「カーソル位置の単語の選択 (ダブルクリック)」を拡張したかんじの自動選択機能を提供します。<br> | ||
<span class="warningbox">※ マクロを "ダブルクリック" に割りあてることはできません</span> | |||
Mery ver 3.0.1 以降の '''マルチカーソル/複数選択範囲''' に対応 | |||
== ちょっと便利な自動選択拡張機能 == | == ちょっと便利な自動選択拡張機能 == | ||
<u>「選択範囲がない」状態からこのマクロを実行</u> | <u>「選択範囲がない」状態からこのマクロを実行</u>すると「'''拡張自動選択'''」モードになります。 | ||
<br><br> | <br><br> | ||
: 1. 「'''キャレット位置の単語'''」の自動選択 (通常のダブルクリックと同等) | : 1. 「'''キャレット位置の単語'''」の自動選択 (通常のダブルクリックと同等) | ||
| 10行目: | 13行目: | ||
:: 半角記号 <code>#####</code>、全角記号 <code>※※※※※</code>、全角空白 <code> </code> など、おなじ記号が連続する部分を範囲選択します。 | :: 半角記号 <code>#####</code>、全角記号 <code>※※※※※</code>、全角空白 <code> </code> など、おなじ記号が連続する部分を範囲選択します。 | ||
: 3. 「'''全角空白を含む空白文字列'''」の自動選択 | : 3. 「'''全角空白を含む空白文字列'''」の自動選択 | ||
:: | :: 通常のダブルクリックでも「タブと半角空白が混在した空白文字列」の部分を自動選択できますが、このマクロでは全角空白を含めて「タブと全角/半角空白が混在した空白文字列」全体を自動選択できます。 | ||
: 4. 「'''日付'''」の自動選択 | : 4. 「'''日付'''」の自動選択 | ||
:: | :: <u>キャレットの右側が「日付」の数字部分なら</u>、<code>2001年1月1日</code>、<code>2002-2-2</code>、<code>2003/3/3</code>、<code>2020.05.31</code> のような「日付」の文字列全体を自動選択します。 | ||
: 5. 「'''行全体を選択'''」 (改行を含めない) | : 5. 「'''行全体を選択'''」 (改行を含めない) | ||
:: 2. - 4. に該当しなかったときに「行全体」を自動選択します(設定項目で表示行か論理行かを指定)。 行番号のクリックとはことなり、末尾改行を選択範囲に含めません。 | :: 2. - 4. に該当しなかったときに「行全体」を自動選択します(設定項目で表示行か論理行かを指定)。<br> 行番号のクリックとはことなり、末尾改行を選択範囲に含めません。 | ||
:: ※ Mery ver 3.0.1 以降でマルチカーソルが有効のばあい、矩形選択範囲は行に分割して各行を範囲選択します。 | |||
: ⇒ 範囲選択したらマクロ終了 | : ⇒ 範囲選択したらマクロ終了 | ||
<br> | <br> | ||
: ※ '''3''' と '''5''' | : ※ '''3''' と '''5''' の機能は、ソースコード内の設定項目の値を変更すると利用できます(初期値:無効)。 | ||
<br> | <br> | ||
;【注意】 | ;【注意】 | ||
*「同一記号の繰り返し」の自動選択機能は、たまに "ダブルクリックで同じ記号2文字選択できちゃった" が発生するのと同じレベルの頻度で失敗することがあります。 | *「同一記号の繰り返し」の自動選択機能は、たまに "ダブルクリックで同じ記号2文字選択できちゃった" が発生するのと同じレベルの頻度で失敗することがあります。 <!-- | ||
* 「日付」の自動選択は、<code>2020年01.01</code> や <code>1900/1.5</code> のような区切り文字の形式が不揃いな「日付っぽい文字列」にも誤爆して範囲選択します (もともと、このマクロをあえてそういう文字列上で実行する必要性がないので修正しません)。 | * 「日付」の自動選択は、<code>2020年01.01</code> や <code>1900/1.5</code> のような区切り文字の形式が不揃いな「日付っぽい文字列」にも誤爆して範囲選択します (もともと、このマクロをあえてそういう文字列上で実行する必要性がないので修正しません)。 --> | ||
* <span style="color:#c00;">URL 文字列上(Mery の標準機能で下線のついた URL 部分)で実行した場合は、URL | * <span style="color:#c00;">URL 文字列上(Mery の標準機能で下線のついた URL 部分)で実行した場合は、URL が範囲選択され、URL を勝手にブラウザで開かれることがあります。</span> | ||
<br> | <br> | ||
== | == 今日の日付に変換 == | ||
<u>「日付」の文字列を範囲選択した状態からこのマクロを実行</u> | <u>「日付」の文字列を範囲選択した状態からこのマクロを実行</u>すると「'''今日の日付'''」モードになります。 | ||
<br><br> | <br><br> | ||
: <code>2001年1月1日</code>、<code>2002-2-2</code>、<code>2003/3/3</code>、<code>2020.05.31</code> のような「日付」の文字列を「今日の日付」に変換しますので、このマクロを '''連続実行''' することで | : <code>2001年1月1日</code>、<code>2002-2-2</code>、<code>2003/3/3</code>、<code>2020.05.31</code> のような「日付」の文字列を「今日の日付」に変換しますので、このマクロを '''連続実行''' することで キャレット位置の「日付を自動選択」 ⇒ 「今日の日付に変換」 ができます。 | ||
<br> | <br> | ||
; 「日付」の判定基準 | ; 「日付」の判定基準 | ||
| 37行目: | 41行目: | ||
:* 年月日の数字の区切りは、<code>-</code> <code>.</code> <code>/</code> のいずれかの記号×2回、または <code>年</code> <code>月</code> <code>日</code> | :* 年月日の数字の区切りは、<code>-</code> <code>.</code> <code>/</code> のいずれかの記号×2回、または <code>年</code> <code>月</code> <code>日</code> | ||
<br> | <br> | ||
: ※ | : ※ <code>2020年01.01</code> や <code>1900/1-5</code> のように区切り文字の形式が混在した文字列からは変換しません。 | ||
:※ 和暦の年号や全角数字で記述された日付、<code>20200601</code> のような区切り文字のない半角8ケタの数値は対象外です。 | :※ 和暦の年号や全角数字で記述された日付、<code>20200601</code> のような区切り文字のない半角8ケタの数値は対象外です。 | ||
:※ <code>2001-02-31</code> のような実在しない日付でも「今日の日付」に変換されます。 | :※ <code>2001-02-31</code> のような実在しない日付でも「今日の日付」に変換されます。 | ||
<br> | <br> | ||
; 変換後の「日付」の形式 | ; 変換後の「日付」の形式 | ||
: <span style="color:#c00;"> | : 「区切り文字」の部分は変換前とおなじままになりますが、<span style="color:#c00;">月と日の数字部分はつねに <code>2020/06/01</code> のようにゼロ埋めした2ケタに変換されます。</span> | ||
== 1行コメントアウト/アンコメント == | == 1行コメントアウト/アンコメント == | ||
<u>末尾改行を含めずに「論理行全体」(1行) を範囲選択した状態からこのマクロを実行</u> | <u>末尾改行を含めずに「論理行全体」(1行) を範囲選択した状態からこのマクロを実行</u>すると「'''1行コメントアウト/アンコメント'''」モードを利用できます(ソースコード内の設定項目の初期値:無効 <code>commentOut = false</code> )。 | ||
<br><br> | <br><br> | ||
:行頭に <q><code>> </code></q> のようなコメントマークを付けたりはずしたりできますので、このマクロを '''連続実行''' することで 「論理行全体を自動選択」 ⇒ 「1行コメントアウト/アンコメント」 ができます。 | : 行頭に <q><code>> </code></q> のようなコメントマークを付けたりはずしたりできますので、このマクロを '''連続実行''' することで 「論理行全体を自動選択」 ⇒ 「1行コメントアウト/アンコメント」 ができます。<br> ※ 設定項目 <code>selectLine = 0</code> のとき | ||
<br> | <br> | ||
: ※ 「1行コメントアウト」は、範囲選択なしの空行でも実行できます(コメントマーク挿入)。 | : ※ 「1行コメントアウト」は、範囲選択なしの空行でも実行できます(コメントマーク挿入)。 | ||
| 57行目: | 61行目: | ||
<br> | <br> | ||
; ダウンロード >> 「[[ファイル:ちょっと便利な拡張自動選択.zip]]」(アイコン入り) | ; ダウンロード >> 「[[ファイル:ちょっと便利な拡張自動選択.zip]]」(アイコン入り) | ||
(最終更新:2020/07/01) | |||
<br> | <br> | ||
<source lang="javascript" style="height:60em; overflow:auto;"> | <source lang="javascript" style="height:60em; overflow:auto;"> | ||
#title = "拡張自動選択" | #title = "拡張自動選択" | ||
#tooltip = "ちょっと便利な自動選択拡張機能 + α" | #tooltip = "ちょっと便利な自動選択拡張機能 + α" | ||
#icon = "select_ex.ico" | |||
/** | /** | ||
* --------------------------------------------------------- | * --------------------------------------------------------- | ||
* 「拡張自動選択」マクロ | * 「拡張自動選択」マクロ | ||
* sukemaru, 2020/05/31 | * 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行コメントアウト」は空行上でも実行可 | |||
*/ | */ | ||
| 76行目: | 107行目: | ||
var fullWSpc = false; // true 含める / false 含めない (タブと半角空白のみ) | var fullWSpc = false; // true 含める / false 含めない (タブと半角空白のみ) | ||
// ■ 説明欄の 1 - 4 | // ■ 説明欄の 1 - 4 に該当しなかったときには「行全体を選択」する(改行を含めない) | ||
var selectLine = 0; // 0 しない / 1 表示行を選択 / 2 論理行を選択 | var selectLine = 0; // 0 しない / 1 表示行を選択 / 2 論理行を選択 | ||
| 87行目: | 118行目: | ||
var d = editor.ActiveDocument, s = d.selection; | var d = editor.ActiveDocument, s = d.selection; | ||
var | var sx = ScrollX, sy = ScrollY; | ||
var | |||
/* マルチカーソル/複数選択範囲に対応 */ | |||
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(); | |||
} | |||
if ( d.ReadOnly ) { | /* 無駄な UNDO 履歴が残らないよう対策 */ | ||
// テキストの変更なしなら一度 UNDO して、拡張自動選択だけ再試行する | |||
if ( sMode > 1 && d.Text === dt ) { | |||
if ( ! d.ReadOnly ) { d.Undo(); } | |||
MultiFunction( SelectWordEx, arg ); | |||
} | } | ||
// 選択範囲の文字列が日付なら「今日の日付」に変換して終了 | ScrollX = sx; ScrollY = sy; | ||
else if ( st ) { | |||
/** | |||
* 関数 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 ( ! | if ( ! st && SelectWordEx( arg ) ) { | ||
return; | |||
} | } | ||
// 「1行コメントアウト/アンコメント」 | // 「1行コメントアウト/アンコメント」 | ||
if ( ! | if ( ! readOnly && commentOut && commentMark | ||
&& s.Text === d.GetLine( s.GetActivePointY( mePosLogical ), 0 ) | && s.Text === d.GetLine( s.GetActivePointY( mePosLogical ), 0 ) | ||
&& CommentOut( s.Text, commentMark ) ) { | |||
return; | |||
} | |||
} | } | ||
| 126行目: | 198行目: | ||
* 「-」「.」「/」のいずれか(同一の記号2回の場合のみ) | * 「-」「.」「/」のいずれか(同一の記号2回の場合のみ) | ||
* または「年月日」 | * または「年月日」 | ||
* ・和暦の年号や全角数字、区切り文字のない半角8ケタの数値は不可 | * ・和暦の年号や全角数字、区切り文字のない半角8ケタの数値は不可 | ||
* | * | ||
* 戻り値の「月日」の数字はつねにゼロ埋め | * 戻り値の「月日」の数字はつねにゼロ埋め | ||
*/ | */ | ||
function DateOfToday( str | 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 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])(日)$/; | var reg2 = /^(?:19|20)\d{2}(年)(?:0?[1-9]|1[0-2])(月)(?:0?[1-9]|[12][0-9]|3[01])(日)$/; | ||
| 147行目: | 218行目: | ||
/** | /** | ||
* 関数 SelectWordEx( fullWSpc, selectLine ) | * 関数 SelectWordEx( [ fullWSpc, selectLine ] ) | ||
* ※ 引数: 「全角空白を含む空白文字列」の自動選択の許可フラグ | * ※ 引数: 「全角空白を含む空白文字列」の自動選択の許可フラグ | ||
* 拡張自動選択 | * 拡張自動選択 | ||
| 154行目: | 225行目: | ||
* 3.「全角空白を含む空白文字列」の自動選択 | * 3.「全角空白を含む空白文字列」の自動選択 | ||
* 4.「日付け」の自動選択 | * 4.「日付け」の自動選択 | ||
* 2001年1月1日 2002-2-2 2003/3/ | * ○ 2001年1月1日, 2002-2-2, 2003/3/03, 2020.05.31 / × 2020/05.31 | ||
* ※ 「日付け」の自動選択は、キャレットの右側が数字のときのみ | * ※ 「日付け」の自動選択は、キャレットの右側が数字のときのみ | ||
*/ | */ | ||
function SelectWordEx( fullWSpc | function SelectWordEx( arg ) { | ||
var fullWSpc = arg[0]; | |||
var selectLine = arg[1]; | |||
var d = editor.ActiveDocument, s = d.selection; | var d = editor.ActiveDocument, s = d.selection; | ||
s.SelectWord(); // キャレットは選択範囲の末尾 | if ( s.IsEmpty ) { s.SelectWord(); } // キャレットは選択範囲の末尾 | ||
var | var st = s.Text; if ( ! st ) { return false; } | ||
var ax = s.GetActivePointX( mePosLogical ); | var ax = s.GetActivePointX( mePosLogical ); | ||
var ay = s.GetActivePointY( mePosLogical ); | var ay = s.GetActivePointY( mePosLogical ); | ||
| 168行目: | 241行目: | ||
var str2 = line.slice( ax - 1 ); // キャレットより後ろの文字列 | var str2 = line.slice( ax - 1 ); // キャレットより後ろの文字列 | ||
// ※ | // ※ 全角空白をふくむ空白文字列全体を自動選択 | ||
if ( | if ( fullWSpc && /^[\t ]+$/.test( st ) ) { | ||
var sig1 = String( str1.match( | var sig1 = String( str1.match( /[\t ]+$/ ) || "" ); | ||
var sig2 = String( str2.match( | var sig2 = String( str2.match( /^[\t ]+/ ) || "" ); | ||
if ( sig1 || sig2 ) { | if ( sig1 || sig2 ) { | ||
s.SetAnchorPoint( mePosLogical, ax - sig1.length, ay ); | s.SetAnchorPoint( mePosLogical, ax - sig1.length, ay ); | ||
s.SetActivePoint( mePosLogical, ax + sig2.length, ay, true ); | s.SetActivePoint( mePosLogical, ax + sig2.length, ay, true ); | ||
} | } | ||
if ( s.Text !== | if ( s.Text !== st ) { return true; } | ||
} | } | ||
// ※ | // ※ 同一記号の繰り返し文字列の自動選択 | ||
if ( | if ( st.length === 1 ) { | ||
var sig1 = String( str1.match( | var sig1 = String( str1.match( new RegExp( "\\" + st + "+$", "" ) ) || "" ); | ||
var sig2 = String( str2.match( | var sig2 = String( str2.match( new RegExp( "^\\" + st + "+", "" ) ) || "" ); | ||
if ( sig1 || sig2 ) { | if ( sig1 || sig2 ) { | ||
s.SetAnchorPoint( mePosLogical, ax - sig1.length, ay ); | s.SetAnchorPoint( mePosLogical, ax - sig1.length, ay ); | ||
s.SetActivePoint( mePosLogical, ax + sig2.length, ay, true ); | s.SetActivePoint( mePosLogical, ax + sig2.length, ay, true ); | ||
} | } | ||
if ( s.Text !== | 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 ).length, ay, true ); | s.SetActivePoint( mePosLogical, ax + String( mmdd[0] ).length, ay, true ); | ||
return true; | return true; | ||
} | } | ||
if ( /^(?:0?[1-9]|1[0-2])$/.test( | var reg1 = /^(?:19|20)\d{2}([-.\/])(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|[12][0-9]|3[01])$/; | ||
&& ( yy = str1.slice( 0, - | var reg2 = /^(?:19|20)\d{2}年(?:0?[1-9]|1[0-2])月(?:0?[1-9]|[12][0-9]|3[01])日$/; | ||
&& ( dd = str2.match( /^[-.\/月](?:0?[1-9]|[12][0-9]|3[01])日?(?=$|\D)/ ) ) ) { | if ( /^(?:0?[1-9]|1[0-2])$/.test( st ) // mm | ||
s.SetAnchorPoint( mePosLogical, ax - ( yy + | && ( 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 ); | s.SetActivePoint( mePosLogical, ax + String( dd ).length, ay, true ); | ||
return true; | return true; | ||
} | } | ||
if ( /^(?:0?[1-9]|[12][0-9]|3[01])$/.test( | if ( /^(?:0?[1-9]|[12][0-9]|3[01])$/.test( st ) // dd | ||
&& ( yymm = str1.slice( 0, - | && ( yymm = str1.slice( 0, - st.length ).match( /\b\d{4}[-.\/年](?:0?[1-9]|1[0-2])[-.\/月]$/ ) ) | ||
&& ( dd = str2.match( /^日?(?=$|\D)/ ) ) ) { | && ( dd = str2.match( /^日?(?=$|\D)/ ) ) | ||
s.SetAnchorPoint( mePosLogical, ax - ( yymm + | && ( 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 ); | s.SetActivePoint( mePosLogical, ax + String( dd ).length, ay, true ); | ||
return true; | return true; | ||
} | } | ||
// ※ 行の自動選択 | |||
if ( selectLine ) { | if ( selectLine ) { | ||
s.StartOfLine( false, selectLine ); | s.StartOfLine( false, selectLine ); | ||
| 227行目: | 306行目: | ||
function CommentOut( line, commentMark ) { | function CommentOut( line, commentMark ) { | ||
var s = editor.ActiveDocument.selection; | var s = editor.ActiveDocument.selection; | ||
// s.EndOfLine( false, mePosLogical ); | |||
// s.StartOfLine( true, mePosLogical ); | |||
// var line = s.Text; | |||
var comBlank = commentMark.match( /\s+$/ ) || ""; | var comBlank = commentMark.match( /\s+$/ ) || ""; | ||
var comEscaped = commentMark.replace( /\s+$/g, "" ).replace( /\W/g, "\\$&" ); | var comEscaped = commentMark.replace( /\s+$/g, "" ).replace( /\W/g, "\\$&" ); | ||
| 241行目: | 323行目: | ||
s.StartOfLine( true, mePosLogical ); | s.StartOfLine( true, mePosLogical ); | ||
return true; | 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 ); | |||
} | |||
} | } | ||
</source> | </source> | ||
| 246行目: | 371行目: | ||
== メモ == | == メモ == | ||
; 2020/05/31 ➀ | |||
* このマクロは、「[[TAB/半角空白 トグル変換]]」マクロとおなじく「[[TrueとFalse を切り替える|Yes/No マクロ]]」への自家用追加コードとしてつくったものを単独マクロとして切出したものです。 現在自分が使用している「同一記号の繰り返し部分の自動選択」と「日付の自動選択」⇒「今日の日付に変換」機能以外は、公開・配布用のソースコードでも初期値を「無効」に設定してあります。 | |||
* ZIP には既製の「マテリアルデザインっぽいアイコン」からちょっといじって詰めておきましたが、いい感じではなくて申しわけないです。 | |||
; 2020/05/31 ➁ | |||
* 正規表現のミスを修正。 | |||
; 2020/07/01 | |||
* マルチカーソル/複数選択範囲に対応。 | |||
* 「日付の自動選択」の誤爆を減らす修正。 | |||
* 「全角空白を含む空白文字列」の自動選択の不具合を修正。 | |||
* 「行全体を選択」と「1行コメントアウト/アンコメント」の機能は「[[TrueとFalse を切り替える|Yes/No マクロ]]」に移植済み。 | |||
2020年7月1日 (水) 22:11時点における版
通常の「カーソル位置の単語の選択 (ダブルクリック)」を拡張したかんじの自動選択機能を提供します。
※ マクロを "ダブルクリック" に割りあてることはできません
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 マクロ」に移植済み。
スポンサーリンク