|
|
| (3人の利用者による、間の23版が非表示) |
| 1行目: |
1行目: |
| 論理行単位で字下げ・字上げします。<br> | | == 概要 == |
| | 論理行単位で字下げ・字上げします。 |
| | |
| インデントには任意の文字列を設定できます。※初期設定は半角空白2個です。 | | インデントには任意の文字列を設定できます。※初期設定は半角空白2個です。 |
|
| |
|
| [[ファイル:Indent-Unindent.png]] | | [[ファイル:Indent-Unindent.png]] |
|
| |
|
| = masme 版 = | | == 変更履歴 == |
| ==更新履歴==
| | * 1.0.3 (2019-06-01) |
| * 2019/04/12 | | ** 字下げ・字上げした次の行に変更行の印がつかないようにした |
| ** (字下げ) Quit() → break ラベル文に変更。 | | *** 末尾の改行(次の行頭)を範囲に含めず書き換えるように変更 |
| * 2015/02/14 | | ** with 文を使用せず変数化した(他の自作マクロに合わせた) |
| ** (字上げ) 「インデントの定義」に正規表現の特殊文字があると誤動作する不具合を修正。 | | * 1.0.2 (2019-04-12) |
| ** 矩形選択(始点or終点が左下かつ論理行頭)時、下端の行が範囲から漏れる不具合を修正。 | | ** (字下げ) Quit() → break ラベル文に変更 |
| * 2014/02/09 | | * 1.0.1 (2015-02-14) |
| ** 初版公開。 | | ** (字上げ) 「インデントの定義」に正規表現の特殊文字があると誤動作する不具合を修正 |
| | ** 矩形選択(始点or終点が左下かつ論理行頭)時、下端の行が範囲から漏れる不具合を修正 |
| | * 1.0.0 (2014-02-09) |
| | ** 初版公開 |
|
| |
|
| ==字下げ (インデント)== | | == 字下げ (インデント) == |
| * 複数行選択時 (選択範囲が2行以上) は、字下げします。<br>単一行選択時 (選択範囲が1行以内) または非選択時は、タブ文字を挿入します。<br><span style="color:#c00;">※選択範囲の行数は、ステータスバーの「xx文字 (xx行) 選択」の部分で判断してください。</span> | | * 複数行選択時 (選択範囲が2行以上) は字下げします。<br>単一行選択時 (選択範囲が1行以内) または非選択時はタブ文字を挿入します。<br><b style="color:#c00;">※選択範囲の行数はステータスバーの「xx文字 (xx行) 選択」の部分で判断してください。</b> |
| * 空行 (改行のみの行) は字下げされません。 | | * 空行 (改行のみの行) は初期状態では字下げしません。 |
| * 「Tab」キーなどに割り当ててご利用ください。 | | * 「Tab」キーなどに割り当ててご利用ください。 |
|
| |
|
| <source lang="javascript"> | | === ソースコード === |
| | <syntaxhighlight lang="javascript" copy> |
| //■字下げ(インデント) | | //■字下げ(インデント) |
| // 2014/02/09-2019/04/12 | | // 2014-02-09 - 2019-06-01 |
| //・論理行単位で字下げする。空行は字下げしない。非選択時/単行選択時はタブ挿入。 | | //・論理行単位で字下げする。空行は字下げしない。非選択時/単行選択時はタブ挿入。 |
|
| |
|
| //■インデントの定義 ●初期値=" " (半角空白2個) | | //■インデントの定義 ●初期値=" " |
| var $INDENT = " "; | | var INDENT = " "; |
| quit: | | |
| with (Document.Selection) {
| | quit: { |
| //非選択時/単行選択時はタブ挿入して終了
| | var Sel = Document.Selection; |
| if (GetTopPointY(mePosView)==GetBottomPointY(mePosView)) {Text="\t"; break quit;}
| | if (Sel.GetTopPointY(mePosView)===Sel.GetBottomPointY(mePosView)) { |
|
| | Sel.Text = "\t"; break quit; //非選択時/単行選択時はタブ挿入して終了 |
| var ty = GetTopPointY(mePosLogical);
| |
| var by = GetBottomPointY(mePosLogical);
| |
| var bx = GetBottomPointX(mePosLogical);
| |
| var br =(Text.match(/\n/g)||[]).length;
| |
| if (bx==1 && by-ty==br && br) by--; //次行行頭を含めないよう対策
| |
| SetActivePoint(mePosLogical, 1, by+1);
| |
| SetAnchorPoint(mePosLogical, 1, ty);
| |
| Text = Text.replace(/^(?!$)/gm,$INDENT); //(空行を除く)行頭にインデントを付加
| |
| SetActivePoint(mePosLogical, 1, by+1);
| |
| SetAnchorPoint(mePosLogical, 1, ty);
| |
| } | | } |
| </source> | | var ty = Sel.GetTopPointY(mePosLogical); |
| | var by = Sel.GetBottomPointY(mePosLogical); |
| | var bx = Sel.GetBottomPointX(mePosLogical); |
| | var nn =(Sel.Text.match(/\n/g)||[]).length; |
| | if (bx===1 && nn<=by-ty && nn) by--; //末尾改行対策 |
| | Sel.SetActivePoint(mePosLogical, 1, by); |
| | Sel.EndOfLine(false, mePosLogical); |
| | Sel.SetAnchorPoint(mePosLogical, 1, ty); |
| | Sel.Text = Sel.Text.replace(/^(?!$)/gm,INDENT); |
| | Sel.SetActivePoint(mePosLogical, 1, by+1); |
| | Sel.SetAnchorPoint(mePosLogical, 1, ty); |
| | } |
| | </syntaxhighlight> |
|
| |
|
| ==字上げ (アンインデント)== | | == 字上げ (アンインデント) == |
| * 単一行選択時 (選択範囲が1行以内) または非選択時でも、字上げします。 | | * 単一行選択時 (選択範囲が1行以内) または非選択時でも字上げします。 |
| * 「Shift + Tab」キーなどに割り当ててご利用ください。 | | * 「Shift + Tab」キーなどに割り当ててご利用ください。 |
|
| |
|
| <source lang="javascript"> | | === ソースコード === |
| | <syntaxhighlight lang="javascript" copy> |
| //■字上げ(アンインデント) | | //■字上げ(アンインデント) |
| // 2014/02/09-2015/02/14 | | // 2014-02-09 - 2019-06-01 |
| //・論理行単位で字上げする。非選択時/単行選択時でも字上げする。 | | //・論理行単位で字上げする。非選択時/単行選択時でも字上げする。 |
|
| |
|
| //■インデントの定義 ●初期値=" " (半角空白2個) | | //■インデントの定義 ●初期値=" " |
| var $INDENT = " "; | | var INDENT = " "; |
| | |
| with (Document.Selection) {
| |
| //特殊文字をエスケープ
| |
| $INDENT = new RegExp("^"+$INDENT.replace(/([$()*+.?[\\\]^{|}])/g,"\\$1"),"gm");
| |
|
| |
| var ty = GetTopPointY(mePosLogical);
| |
| var by = GetBottomPointY(mePosLogical);
| |
| var bx = GetBottomPointX(mePosLogical);
| |
| var br =(Text.match(/\n/g)||[]).length;
| |
| if (bx==1 && by-ty==br && br) by--; //次行行頭を含めないよう対策
| |
| SetActivePoint(mePosLogical, 1, by+1);
| |
| SetAnchorPoint(mePosLogical, 1, ty);
| |
| Text = Text.replace($INDENT,""); //行頭のインデントを削除
| |
| SetActivePoint(mePosLogical, 1, by+1);
| |
| SetAnchorPoint(mePosLogical, 1, ty);
| |
| }
| |
| </source>
| |
| | |
| = sukemaru 版 =
| |
| <br>
| |
| '''ダウンロード:''' 「[[ファイル:字下げ/字上げ.zip]](アイコン入り)」 最終更新: 2019/04/07
| |
| * [[#字下げ(スペース×2 追加)|スペース×2 追加]].js
| |
| * [[#字上げ(スペース×2 削除)|スペース×2 削除]].js
| |
| * [[#インデント|インデント]].js
| |
| * [[#逆インデント|アンインデント]].js
| |
| それぞれ専用の「マテリアルデザインっぽいアイコン」を同梱
| |
| | |
| | |
| == 字下げ(スペース×2 追加) ==
| |
| ;スペース×2 追加.js
| |
| <br>
| |
| キャレットまたは選択範囲をふくむ論理行の各先頭に「半角スペース×2」を追加します。
| |
| * 選択範囲がなかった場合は「タブ文字」を追加、または「半角スペース×2」を行頭に追加します。
| |
| * 選択範囲があった場合は、つねに「半角スペース×2」を行頭に追加します。
| |
| * 行頭に「半角スペース×2」を追加する場合は、空行を無視します。
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| | |
| <source lang="javascript" style="height:40em; overflow:auto;">
| |
| #title = "字下げ"
| |
| #tooltip = "スペース×2 追加"
| |
| // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",247
| |
| // ※「引用の追加」マクロから行頭に文字列を追加するコードを拝借した
| |
| | |
| // ■選択範囲なしのときには「タブ文字×1」を追加するか?
| |
| var tabEnable = 0;
| |
| | |
| // 0 なら、「半角スペース×2」を行頭に追加する(空行は無視)
| |
| // 1 なら、選択範囲なしのときは「タブ文字×1」を行頭に追加する
| |
| // 2 なら、選択範囲なしのときは「タブ文字×1」をキャレット位置に追加する
| |
| | |
| // ■行頭に追加する空白文字の定義(初期値:「半角スペース×2 " "」)
| |
| var blank = " "; // 半角スペース×2
| |
| | |
| | |
| var s = document.selection;
| |
| | |
| // "選択範囲なし" のフラグ
| |
| var pos = s.IsEmpty ? s.GetActivePos() : "";
| |
| | |
| // キャレット位置に「タブ文字×1」を挿入して終了するパターン
| |
| if ( pos && tabEnable > 1 ) { // tabEnable == 2
| |
| s.Text = "\t";
| |
| }
| |
| else {
| |
| var sx = ScrollX, sy = ScrollY;
| |
| | |
| // 選択範囲を取得
| |
| var ty = s.GetTopPointY( mePosLogical );
| |
| var bx = s.GetBottomPointX( mePosLogical );
| |
| var by = s.GetBottomPointY( mePosLogical );
| |
| // 選択範囲を拡張
| |
| if ( by != ty && bx == 1 ) {
| |
| by -= 1;
| |
| }
| |
| s.SetActivePoint( mePosLogical, 1, by );
| |
| s.EndOfLine( false, mePosLogical );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| // 選択範囲の文字列を取得
| |
| var st = s.Text;
| |
| | |
| // 最初に選択範囲がなかった場合は、行頭に「タブ文字×1」を追加
| |
| if ( pos && tabEnable == 1 ) {
| |
| var tab = "\t";
| |
| s.Text = InsertSpace( st, tab );
| |
| s.SetActivePos( pos + tab.length ); // 範囲選択を残さない
| |
| }
| |
| | |
| // 選択範囲があった場合は、行頭に「半角スペース×2」を追加(空行は無視)
| |
| else { // ( ! pos || tabEnable == 0 )
| |
| var t = InsertSpace( st, blank );
| |
| if ( t != st ) {
| |
| s.Text = t;
| |
| }
| |
| | |
| if ( pos ) { // 範囲選択を残さない
| |
| s.SetActivePos( pos + ( t.length - st.length ) );
| |
| }
| |
| else { // 範囲選択を残す
| |
| s.SetActivePoint( mePosLogical, 1, by + 1 );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| }
| |
| }
| |
| ScrollX = sx; ScrollY = sy;
| |
| }
| |
| | |
| // 「引用の追加」マクロより拝借
| |
| function InsertSpace( arg1, arg2 ) {
| |
| var a = arg1.split( "\n" );
| |
| for ( var i = 0; i < a.length; i ++ )
| |
| if ( a[i].length || arg2 == "\t" )
| |
| a[i] = arg2 + a[i];
| |
| return a.join( "\n" );
| |
| }
| |
| </source>
| |
| | |
| | |
| == 字上げ(スペース×2 削除) ==
| |
| ;スペース×2 削除.js
| |
| <br>
| |
| キャレットまたは選択範囲をふくむ論理行の各先頭から「半角スペース×2」を削除します。
| |
| * 行頭の「空白文字」を削除、またはキャレット位置の前後にある「タブ文字」を削除します。
| |
| * 選択範囲があった場合は、つねに行頭の「空白文字」だけを削除します。
| |
| * 削除対象の行頭の「空白文字」には「半角スペース×2」以外の空白文字もふくめます。
| |
| : ''i.e.'' 「半角スペース×2」「半角スペース×1」「全角スペース×1」「タブ文字×1」
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| | |
| ※ sukemaru 版の「字上げ」と「逆インデント」マクロを並存させるメリットは少ないとおもいますので、お好みで選んでください。 <br>
| |
| 「字上げ」マクロなら、削除対象に「空白文字」以外の任意の "文字列" や "記号" なども追加できます。
| |
| | |
| <source lang="javascript" style="height:40em; overflow:auto;">
| |
| #title = "字上げ"
| |
| #tooltip = "スペース×2 削除"
| |
| // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",249
| |
| // ※「引用の追加」マクロから行頭の文字列を削除するコードを拝借した
| |
| | |
| // ■選択範囲なしのときに、キャレット位置の前後にある「タブ文字」を優先的に削除するか?
| |
| var nearestTab = true;
| |
| | |
| // false にすると、つねに行頭の空白文字のみを削除
| |
| // true にすると、キャレット付近の「タブ文字×1」を優先的に削除(タブ文字がなければ行頭の空白を削除)
| |
| | |
| // ■削除対象(削除の単位)にする行頭の空白文字の定義
| |
| var blank = new Array( " " , " " , " " , "\t" );
| |
| | |
| // 初期値: new Array( " " , " " , " " , "\t" )
| |
| // i.e. 「半角スペース×2 " "」「半角スペース×1 " "」「全角スペース×1 " " 」「タブ文字×1 "\t"」
| |
| // ※ 前に置いたもののほうが優先順位が高くなるので、行頭に半角スペースが3つある行で連続で実行した場合、
| |
| // 1回目では「半角スペース×2」を削除し、2回目で「半角スペース×1」を削除する
| |
| // ※ 空白文字以外の "文字列" を Array() のなかに追加するのも可
| |
| | |
| | |
| var s = document.selection;
| |
| | |
| // "選択範囲なし" のフラグ
| |
| var pos = s.IsEmpty ? s.GetActivePos() : "";
| |
| | |
| // キャレット付近の「タブ文字×1」を優先的に削除するパターン
| |
| var isDone = false;
| |
| if ( pos && nearestTab ) {
| |
| if ( document.Text.charAt( pos - 1 ) == "\t" ) {
| |
| s.DeleteLeft();
| |
| isDone = true;
| |
| }
| |
| else if ( document.Text.charAt( pos ) == "\t" ) {
| |
| s.Delete();
| |
| isDone = true;
| |
| }
| |
| }
| |
| if ( ! isDone ) {
| |
| var sx = ScrollX, sy = ScrollY;
| |
| | |
| // 選択範囲を取得
| |
| var ty = s.GetTopPointY( mePosLogical );
| |
| var by = s.GetBottomPointY( mePosLogical );
| |
| var bx = s.GetBottomPointX( mePosLogical );
| |
| // 選択範囲を拡張
| |
| if ( by != ty && bx == 1 ) {
| |
| by -= 1;
| |
| }
| |
| s.SetActivePoint( mePosLogical, 1, by );
| |
| s.EndOfLine( false, mePosLogical );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| // 選択範囲の文字列を取得
| |
| var st = s.Text;
| |
| | |
| // 行頭の空白文字を削除
| |
| var t = DeleteSpace( st, blank );
| |
| if ( t != st ) {
| |
| s.Text = t;
| |
| }
| |
| | |
| if ( pos ) { // 範囲選択を残さない
| |
| s.SetActivePos( pos - ( st.length - t.length ) );
| |
| }
| |
| else { // 範囲選択を残す
| |
| s.SetActivePoint( mePosLogical, 1, by + 1 );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| }
| |
| ScrollX = sx; ScrollY = sy;
| |
| }
| |
| | |
| // 「引用の追加」マクロより拝借
| |
| function DeleteSpace( arg1, arg2 ) {
| |
| var a = arg1.split( "\n" );
| |
| for ( var i = 0; i < a.length; i ++ ) {
| |
| for ( var j = 0; j < arg2.length; j ++ ) {
| |
| if ( arg2[j].length == 0 )
| |
| continue;
| |
| if ( a[i].substr( 0, arg2[j].length ) == arg2[j] ) {
| |
| a[i] = a[i].substr( arg2[j].length );
| |
| break;
| |
| }
| |
| }
| |
| }
| |
| return a.join( "\n" );
| |
| }
| |
| </source>
| |
| | |
| | |
| == インデント ==
| |
| ;インデント.js <br>
| |
| 既存のツールバーアイコンのアイテム「インデント」から置きかえて使う目的のマクロで、<span style="color:#c00;">選択範囲がなくてもタブインデント</span>します。 <br> ソースコードの内容は「字上げ(スペース×2 追加)」マクロとほぼ同じですが、こちらの「インデント」マクロの場合は、挿入する空白は「タブ文字」のみで空白行にたいしてもインデントを追加します。
| |
| * 論理行全体をタブインデント(行頭)して範囲選択します。 <br> 選択範囲が1行内ならもとの選択範囲を維持し、複数行なら対象の論理行全体を範囲選択します。
| |
| * またはカーソル位置にタブ文字を挿入します。
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| | |
| | |
| 【推奨設定】 Tab キーに割りあてるなら ''tabEnable = 2'' , ツールバーアイコンにするなら ''tabEnable = 0''
| |
| | |
| <source lang="javascript" style="height:40em; overflow:auto;">
| |
| #title = "インデント"
| |
| #tooltip = "選択範囲がなくてもインデント"
| |
| #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",260
| |
| | |
| // ■選択範囲があるときに、選択範囲を「タブ文字」にするか? 行全体をタブインデントするか?
| |
| var tabEnable = 0;
| |
| | |
| // 0 にすると、選択範囲がなくてもつねに行全体をタブインデント(行頭)
| |
| // 1 にすると、選択範囲があれば行全体をタブインデント(※ツールバーアイコンの「インデント」に似た動作)
| |
| // 2 にすると、選択範囲が1行内のときだけ選択範囲を「タブ文字」にする (※Tab キーの通常動作にちかい)
| |
| // 3 にすると、つねに選択範囲を「タブ文字」にする(※インデントしない)
| |
| | |
| // ※ 0 の場合、「タブ文字」を挿入することができないので、ツールバーアイコン向けの設定。
| |
| // ※ 1 の場合、選択範囲を「タブ文字」にすることができないので、Tab キーにマクロを割りあてると少し不便になるかも?
| |
| // 範囲選択 → 削除 (Delete / BackSpace) → 「インデント」マクロ (Tab)
| |
| // ※ 2 の場合に1行だけインデントさせるなら、行頭でクリックするか、行内でトリプルクリック
| |
| // または行番号のクリックで行全体を選択範囲にして「インデント」マクロ (末尾改行まで含める必要あり)。
| |
| // [EOF] マークのある(さいごに改行がない)文書末行だけの1行選択ではインデントできない。
| |
| // ⇔ Tab キーの通常動作では末尾改行を含める必要はない
| |
| // ※ 3 は、わざわざマクロでやる意味もないかと。
| |
| | |
| | |
| var sx = ScrollX, sy = ScrollY;
| |
| var s = document.selection;
| |
| | |
| // 選択範囲
| |
| var act = s.GetActivePos();
| |
| var anc = s.GetAnchorPos();
| |
| var ty = s.GetTopPointY( mePosLogical );
| |
| var bx = s.GetBottomPointX( mePosLogical );
| |
| var by = y = s.GetBottomPointY( mePosLogical );
| |
| | |
| // カーソル位置にタブを挿入して終了するパターン
| |
| if ( ( s.IsEmpty && tabEnable == 1 ) || ( tabEnable == 2 && ty == by ) || tabEnable == 3 ) {
| |
| s.Text = "\t";
| |
| }
| |
| else {
| |
| // 選択範囲を拡張
| |
| if ( ty != by && bx == 1 ) {
| |
| y --; // 選択範囲の末尾が行頭 x = 1 にあるときの調整
| |
| }
| |
| s.SetActivePoint( mePosLogical, 1, y );
| |
| s.EndOfLine( false, mePosLogical );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| var st = s.Text;
| |
| | |
| // インデント
| |
| s.Text = st.replace( /^/gm , "\t" );
| |
| | |
| // 選択範囲を復元
| |
| if ( ty == by ) {
| |
| s.SetActivePos( act + 1 );
| |
| s.SetAnchorPos( anc + 1 );
| |
| }
| |
| else {
| |
| s.SetActivePos( s.GetActivePos() + 1 );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| }
| |
| }
| |
| | |
| ScrollX = sx; ScrollY = sy;
| |
| </source>
| |
| | |
| | |
| == 逆インデント ==
| |
| ;アンインデント.js <br>
| |
| 既存のツールバーアイコンのアイテム「逆インデント」から置きかえて使う目的のマクロで、<span style="color:#c00;">選択範囲がなくてもアンインデント</span>します。 <br>
| |
| 機能的には「字上げ(スペース×2 削除)」マクロとほぼ同じですが、削除できる「半角スペース×n」の最大数をかんたんに設定できるようにしてあります ( "␣␣␣␣", "␣␣␣", "␣␣", "␣" なら ''deleteSpace ='' '''''4''''' と指定するだけ)。
| |
| * 行頭またはカーソル付近の「タブ文字×1」か、行頭の「半角スペース×n」を削除します。
| |
| * 選択範囲なしならカーソル付近のタブを削除するか、またはカーソルのある1行をアンインデントして、カーソル位置を復帰します。
| |
| * 選択範囲ありなら論理行全体をアンインデント(行頭)して範囲選択します。
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| | |
| | |
| 【推奨設定】 「字上げ」マクロと並存させるなら ''deleteSpace = 0'' , 「字上げ」マクロなしで Shift+Tab キーに割りあてるなら ''deleteSpace ≠ 0'' <br>
| |
| : 設定用変数 ''deleteSpace = n'' で '''3''' 以上の数値を指定するさいは、Mery のオプション設定の「タブの桁数」を目安にしてください(大きな数字や非整数値を入れての動作検証はしていません)。
| |
| | |
| ※ sukemaru 版の「逆インデント」と「字上げ(スペース×2 削除)」マクロを並存させるメリットは特にないとおもいますので、お好みで選んでください。
| |
| | |
| <source lang="javascript" style="height:40em; overflow:auto;">
| |
| #title = "逆インデント"
| |
| #tooltip = "選択範囲がなくてもアンインデント"
| |
| #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",261
| |
| | |
| // ■選択範囲なしのときに、カーソル位置の前後にある「タブ文字」を優先的に削除するか?
| |
| var nearestTab = true;
| |
| | |
| // false にすると、つねに行頭の空白文字のみを削除
| |
| // true にすると、カーソル付近の「タブ文字×1」を優先的に削除(タブ文字がなければ行頭の空白を削除)
| |
| | |
| // ■行頭の「半角スペース」や「「全角スペース」も削除するか?
| |
| var deleteSpace = 1;
| |
| | |
| // ※ 正の整数値で指定してください
| |
| // 0 にすると、「タブ文字×1」だけを削除
| |
| // 1 にすると、行頭の「半角スペース×2」と「半角スペース×1」も削除
| |
| // 2 にすると、行頭の「半角スペース×2」と「半角スペース×1」と「全角スペース×1」も削除
| |
| // 3 以上にすると、1回の逆インデントで削除できる「半角スペース×n」の最大数が増加
| |
| // → 削除できる「全角スペース」の最大数は n / 2 (初期設定では小数点以下を切り捨て)
| |
| | |
| | |
| var sx = ScrollX, sy = ScrollY;
| |
| var s = document.selection;
| |
| | |
| // "選択範囲なし" のフラグ
| |
| var pos = s.IsEmpty ? s.GetActivePos() : "";
| |
| | |
| // カーソル付近の「タブ文字×1」を削除する場合(左側優先)
| |
| var isDone = false;
| |
| if ( pos && nearestTab ) {
| |
| if ( document.Text.charAt( pos - 1 ) == "\t" ) {
| |
| s.DeleteLeft();
| |
| isDone = true;
| |
| }
| |
| else if ( document.Text.charAt( pos ) == "\t" ) {
| |
| s.Delete();
| |
| isDone = true;
| |
| }
| |
| }
| |
| if ( ! isDone ) {
| |
| // 選択範囲
| |
| var act = s.GetActivePos();
| |
| var anc = s.GetAnchorPos();
| |
| var ty = s.GetTopPointY( mePosLogical );
| |
| var bx = s.GetBottomPointX( mePosLogical );
| |
| var by = y = s.GetBottomPointY( mePosLogical );
| |
| // 選択範囲を拡張
| |
| if ( ty != by && bx == 1 ) {
| |
| y --; // 選択範囲の末尾が行頭 x = 1 にあるときの調整
| |
| }
| |
| s.SetActivePoint( mePosLogical, 1, y );
| |
| s.EndOfLine( false, mePosLogical );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| var st = s.Text;
| |
| | |
| // 逆インデント
| |
| // ( deleteSpace >= 3 ) では、/^\t|^[ ]{1,n}|^[ ]{1,m}/gm の n に deleteSpace の値、m に n/2 を代入 ※toString().replace() で小数点以下を切り捨て
| |
| // ■ m = n/2 の小数点以下を切り上げ(四捨五入)にするなら Math.round() 関数の行を使用する
| |
| // ※必ず ( deleteSpace >= 3 ) の行のひとつをコメントアウト状態にしておくこと
| |
| var indent = ( deleteSpace == 1 ) ? "^\\t|^[ ]{1,2}"
| |
| : ( deleteSpace == 2 ) ? "^\\t|^[ ]{1,2}|^[ ]"
| |
| : ( deleteSpace >= 3 ) ? "^\\t|^[ ]{1," + deleteSpace + "}|^[ ]{1," + ( deleteSpace / 2 ).toString().replace( /\.\d+$/ , "" ) + "}"
| |
| // : ( deleteSpace >= 3 ) ? "^\\t|^[ ]{1," + deleteSpace + "}|^[ ]{1," + Math.round( deleteSpace / 2 ) + "}"
| |
| /* else */ : "^\\t";
| |
| | |
| var u = st.replace( new RegExp( indent , "gm" ) , "" );
| |
| if ( u != s.Text ) {
| |
| s.Text = u;
| |
| }
| |
| | |
| // カーソル位置または選択範囲を復元
| |
| if ( ty == by ) {
| |
| s.SetActivePos( act - ( st.length - u.length ) );
| |
| s.SetAnchorPos( anc - ( st.length - u.length ) );
| |
| if ( s.GetTopPointY( mePosLogical ) != ty )
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| }
| |
| else {
| |
| s.SetActivePos( s.GetActivePos() + 1 );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| }
| |
| }
| |
| ScrollX = sx; ScrollY = sy;
| |
| </source>
| |
| | |
|
| |
|
| == メモ == | | var Sel = Document.Selection; |
| *(2019/04/07 sukemaru)
| | var ty = Sel.GetTopPointY(mePosLogical); |
| :ソースコードから Quit() メソッドを削除
| | var by = Sel.GetBottomPointY(mePosLogical); |
| | var bx = Sel.GetBottomPointX(mePosLogical); |
| | var nn =(Sel.Text.match(/\n/g)||[]).length; |
| | if (bx===1 && nn<=by-ty && nn) by--; //末尾改行対策 |
| | Sel.SetActivePoint(mePosLogical, 1, by); |
| | Sel.EndOfLine(false, mePosLogical); |
| | Sel.SetAnchorPoint(mePosLogical, 1, ty); |
| | var pat = "^"+ INDENT.replace(/[$()*+.?\[\\\]^{|}]/g,"\\$&"); |
| | Sel.Text = Sel.Text.replace(new RegExp(pat,"gm"),""); |
| | Sel.SetActivePoint(mePosLogical, 1, by+1); |
| | Sel.SetAnchorPoint(mePosLogical, 1, ty); |
| | </syntaxhighlight> |