|
|
| 76行目: |
76行目: |
| Sel.SetAnchorPoint(mePosLogical, 1, ty); | | Sel.SetAnchorPoint(mePosLogical, 1, ty); |
| </source> | | </source> |
|
| |
| = sukemaru 版 =
| |
| <br>
| |
| '''ダウンロード:''' 「[[ファイル:字下げ/字上げ.zip]]」(アイコン入り)<br>
| |
| 最終更新: 2020/06/29 '''マルチカーソル''' & '''ブックマーク''' に対応
| |
| * [[#字下げ(スペース×2 追加)|スペース×2 追加]].js
| |
| * [[#字上げ(スペース×2 削除)|スペース×2 削除]].js
| |
| * [[#インデント|インデント]].js
| |
| * [[#逆インデント|アンインデント]].js
| |
| : それぞれ専用の「マテリアルデザインっぽいアイコン」を同梱
| |
| <br>
| |
| * マルチカーソル/複数選択範囲に対応('''Mery ver 3.0.1 以上''')
| |
|
| |
| * ブックマーク対応の推奨要件: '''Mery ver 2.8.6 以上'''
| |
| : <span style="color:#0000c0;"> Mery ver 2.6.7 と ver 2.8.6 以上でブックマークを正常に保持できることを確認しています。</span>
| |
| :※ Mery ver 2.7.0 - ver 2.8.5 では、Mery 本体側のブックマーク機能の仕様が安定していないので、ブックマークを正しく復元できないことがあります。
| |
|
| |
|
| |
| == 字下げ(スペース×2 追加) ==
| |
| ;スペース×2 追加.js <br>
| |
| キャレットまたは選択範囲をふくむ論理行の各先頭に「半角スペース×2」を追加します。
| |
| * 選択範囲がなかった場合は「タブ文字」を追加、または「半角スペース×2」を行頭に追加します。
| |
| * 選択範囲があった場合は、つねに「半角スペース×2」を行頭に追加します。
| |
| * 行頭に「半角スペース×2」を追加する場合は、空行を無視します。
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| * <span style="color:#0000c0;">マルチカーソル/複数選択範囲に対応(Mery ver 3.0.1 以上)</span>
| |
|
| |
| <source lang="javascript" style="height:60em; overflow:auto;">
| |
| #title = "字下げ"
| |
| #tooltip = "スペース×2 追加"
| |
| // #icon = "space_x2[1].ico"
| |
| // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",247
| |
|
| |
| var start = new Date();
| |
|
| |
| /**
| |
| * ---------------------------------------------------------
| |
| * 「字下げ(スペース×2 追加)」マクロ
| |
| * sukemaru, 2018/11/01 - 2020/06/29
| |
| * ---------------------------------------------------------
| |
| * 最初に選択範囲がなかった場合は「タブ文字」を追加、
| |
| * または「半角スペース×2」を行頭に追加する。
| |
| * 選択範囲があった場合は、つねに「半角スペース×2」を行頭に追加する(空行は無視)。
| |
| *
| |
| * 2020/06/29: マルチカーソル/複数選択範囲に対応
| |
| * ブックマーク行を字下げしたときのみブックマークの復元をするように変更
| |
| * ブックマークの収集範囲を選択範囲に限定
| |
| * ブックマークの収集/復元コードを関数化
| |
| * 行頭空白追加の処理をループ関数から正規表現置換に変更
| |
| */
| |
|
| |
| // ---------- ▼ 設定項目 ▼ ----------
| |
|
| |
| // ■ 選択範囲なしのとき
| |
| var tabEnable = 0;
| |
| /**
| |
| * 0: 「半角空白×2」を行頭に追加する(空行は無視)
| |
| * 1: 選択範囲なしのときは「タブ文字×1」を行頭に追加
| |
| * 2: 選択範囲なしのときは「タブ文字×1」をキャレット位置に追加
| |
| */
| |
|
| |
|
| |
| // ■ 行頭に追加する空白文字の定義(初期値:「半角空白×2」)
| |
| var blank = " "; // 半角空白×2
| |
|
| |
| // ---------- ▲ 設定項目 ▲ ----------
| |
|
| |
| var tab = "\t";
| |
|
| |
| var d = editor.ActiveDocument;
| |
| if ( d.ReadOnly ) {
| |
| Status = " ドキュメントは書き換え禁止です。";
| |
| }
| |
| else {
| |
| var s = d.selection;
| |
| var sx = ScrollX, sy = ScrollY;
| |
|
| |
| // マルチカーソル対応
| |
| var arg = [ tabEnable, blank ];
| |
| // 選択範囲が1つで矩形選択ではないとき
| |
| if ( ! s.Mode || s.Mode === meModeStream ) {
| |
| AddSpace2_Main( arg );
| |
| }
| |
| // 複数行または複数選択のとき
| |
| else {
| |
| BeginUndoGroup();
| |
| AddUndo();
| |
| MultiFunction( AddSpace2_Main, arg );
| |
| EndUndoGroup();
| |
| }
| |
| ScrollX = sx; ScrollY = sy;
| |
|
| |
| var elapsedSec = ( ( new Date() - start ) / 1000 ).toFixed( 3 );
| |
| Status = " 「スペース×2 追加」マクロ [ "
| |
| + elapsedSec.replace( /\./, ". " )
| |
| + " 秒 ]";
| |
| }
| |
|
| |
|
| |
| /**
| |
| * 関数 AddSpace2_Main( [ tabEnable, blank ] )
| |
| * 「字上げ(スペース×2 追加)」マクロ
| |
| */
| |
| function AddSpace2_Main( arg ) {
| |
| var tabEnable = arg[0];
| |
| var blank = arg[1];
| |
|
| |
| var d = editor.ActiveDocument;
| |
| var s = d.selection;
| |
|
| |
| // "選択範囲なし" のフラグ
| |
| var pos = s.IsEmpty ? s.GetActivePos() : -1;
| |
|
| |
| /* キャレット位置に「タブ文字×1」を挿入するパターン */
| |
| if ( tabEnable === 2 && pos > -1 ) {
| |
| s.Text = tab;
| |
| }
| |
|
| |
| else {
| |
| 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, d.GetLine( by, 0 ).length + 1, by );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
|
| |
| // 選択範囲の文字列を取得
| |
| var st = s.Text;
| |
| var tp = s.GetAnchorPos();
| |
|
| |
| /* 最初に選択範囲がなかった場合は、行頭に「タブ文字×1」を追加するパターン */
| |
| if ( tabEnable === 1 && pos > -1 ) {
| |
| s.Text = tab + st;
| |
| s.SetActivePos( pos + tab.length ); // 範囲選択を残さない
| |
| }
| |
|
| |
| /* 選択範囲があった場合は、行頭に「半角スペース×2」を追加(空行は無視) */
| |
| else {
| |
| var tmp = st.replace( /^(?!$)/gm, blank );
| |
| if ( tmp !== st ) {
| |
| // ブックマークを保存
| |
| var bmArray = GetBookmark( ty, by );
| |
| // 字下げ完了
| |
| s.Text = tmp;
| |
| // ブックマークを復元
| |
| RestoreBookmark( ty, by, bmArray );
| |
| }
| |
|
| |
| // 範囲選択を残さない
| |
| if ( pos > -1 ) {
| |
| s.SetActivePos( pos + ( tmp.length - st.length ) );
| |
| }
| |
| // 範囲選択を残す(論理行単位)
| |
| else {
| |
| s.SetActivePos( tp + tmp.length + 1 );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| }
| |
| }
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 GetBookmark( ty, by )
| |
| * 指定された範囲のブックマークを収集
| |
| */
| |
| function GetBookmark( ty, by ) {
| |
| var bmArray = [], bmY;
| |
| var s = editor.ActiveDocument.selection;
| |
| if ( ty < by ) {
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
|
| |
| if ( ty === 1 ) {
| |
| s.SetActivePoint( mePosLogical, 1, 2 );
| |
| if ( s.PreviousBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| }
| |
| s.SetActivePos( 0 );
| |
| }
| |
| else { s.SetActivePoint( mePosLogical, 1, ty - 1 ); }
| |
|
| |
| while ( s.NextBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| else if ( bmY > by ) { break; }
| |
| }
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| return bmArray;
| |
| }
| |
|
| |
| /**
| |
| * 関数 RestoreBookmark( ty, by, bmArray )
| |
| * 指定された範囲のブックマークを復元
| |
| */
| |
| function RestoreBookmark( ty, by, bmArray, sel ) {
| |
| var bmCount = bmArray.length;
| |
| if ( bmCount ) {
| |
| var s = editor.ActiveDocument.selection;
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| s.ClearBookmark();
| |
| for ( var i = 0; i < bmCount, bmArray[i] <= by; i ++ ) {
| |
| if ( bmArray[i] < ty ) { continue; }
| |
| s.SetActivePoint( mePosLogical, 1, bmArray[i], false );
| |
| s.SetBookmark();
| |
| }
| |
| if ( sel ) {
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 MultiFunction( Fn, arg1 )
| |
| * マルチカーソル(複数選択範囲)に対応させる
| |
| * 第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 ); // AddSpace2_Main() 関数
| |
|
| |
| // Fn() の残した選択範囲(またはキャレット位置)を回収
| |
| Sel[i].act = s.GetActivePos();
| |
| Sel[i].anc = s.GetAnchorPos();
| |
| diff += d.TextLength - dl; // 文字数の増減量(累積)
| |
| }
| |
|
| |
| // マルチカーソル(複数選択範囲)を復帰
| |
| s.SetActivePos( Sel[0].anc );
| |
| for ( var i = 0; i < sCount; i ++ ) {
| |
| s.AddPos( Sel[i].anc, Sel[i].act );
| |
| }
| |
| }
| |
| </source>
| |
|
| |
|
| |
| == 字上げ(スペース×2 削除) ==
| |
| ;スペース×2 削除.js <br>
| |
| キャレットまたは選択範囲をふくむ論理行の各先頭から「半角スペース×2」を削除します。
| |
| * 行頭の「空白文字」を削除、またはキャレット位置の前後にある「タブ文字」を削除します。
| |
| * 選択範囲があった場合は、つねに行頭の「空白文字」だけを削除します。
| |
| * 削除対象の行頭の「空白文字」には「半角スペース×2」以外の空白文字もふくめます。
| |
| : ''e.g.'' 「半角スペース×2」「半角スペース×1」「全角スペース×1」「タブ文字×1」
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| * <span style="color:#0000c0;">マルチカーソル/複数選択範囲に対応(Mery ver 3.0.1 以上)</span>
| |
|
| |
| ※ sukemaru 版の「字上げ」と「逆インデント」マクロを並存させるメリットは少ないとおもいますので、どちらかお好みで選んでください。 <br>
| |
| 「字上げ」マクロの場合、削除対象に「空白文字」以外の任意の "文字列" や "記号" なども追加できます。
| |
|
| |
| <source lang="javascript" style="height:60em; overflow:auto;">
| |
| #title = "字上げ"
| |
| #tooltip = "スペース×2 削除"
| |
| // #icon = "space_x2[2].ico"
| |
| // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",249
| |
|
| |
| var start = new Date();
| |
|
| |
| /**
| |
| * ---------------------------------------------------------
| |
| * 「字上げ(スペース×2 削除)」マクロ
| |
| * sukemaru, 2018/11/01 - 2020/06/29
| |
| * ---------------------------------------------------------
| |
| * 行頭の「空白文字」を削除、またはキャレット位置の前後にある「タブ文字」を削除する。
| |
| * 選択範囲があった場合は、つねに行頭の「空白文字」だけを削除する。
| |
| * 削除対象の「空白文字」は、「半角スペース×2」以外の空白文字もふくめて
| |
| * 配列 blank で定義する。
| |
| *
| |
| * 2020/06/29: マルチカーソル/複数選択範囲に対応
| |
| * ブックマーク行を字下げしたときのみブックマークの復元をするように変更
| |
| * ブックマークの収集範囲を選択範囲に限定
| |
| * ブックマークの収集/復元コードを関数化
| |
| * 行頭空白削除の処理をループ関数から正規表現置換に変更
| |
| */
| |
|
| |
| // ---------- ▼ 設定項目 ▼ ----------
| |
|
| |
| // ■ 選択範囲なしのときに、キャレット位置の前後にある「タブ文字」を優先的に削除するか?
| |
| var deleteNearestTab = true;
| |
| /**
| |
| * false にすると、つねに行頭の空白文字のみを削除
| |
| * true にすると、キャレット付近の「タブ文字×1」を優先的に削除
| |
| * (タブ文字がなければ行頭の空白を削除)
| |
| */
| |
|
| |
|
| |
| // ■ 削除対象(削除の単位)にする行頭の空白文字の定義
| |
| var blank = [ " " , " " , " " , "\t" ];
| |
| /**
| |
| * 初期値: [ " " , " " , " " , "\t" ]
| |
| * i.e. 「半角空白×2」「半角空白×1」「全角空白×1」「タブ文字×1」
| |
| * ※ 前に置いたもののほうが優先順位が高くなる。
| |
| * e.g. 行頭に半角空白が3つある行で連続で実行した場合、
| |
| * 1回目では「半角空白×2」を削除し、2回目で「半角空白×1」を削除する。
| |
| * ※ 削除対象を「半角空白×4 ~ 1」「全角空白×2 ~ 1」「タブ文字×1」にするなら
| |
| * blank = [ " " , " " , " " , " " , " " , " " , "\t" ];
| |
| * ※ 空白文字以外の "文字列" を [ ... ] のなかに追加するのも可。
| |
| */
| |
|
| |
| // ---------- ▲ 設定項目 ▲ ----------
| |
|
| |
|
| |
| var d = editor.ActiveDocument;
| |
| if ( d.ReadOnly ) {
| |
| Status = " ドキュメントは書き換え禁止です。";
| |
| }
| |
| else {
| |
| var s = d.selection;
| |
| var sx = ScrollX, sy = ScrollY;
| |
|
| |
| // マルチカーソル対応
| |
| var arg = [ deleteNearestTab, blank ];
| |
| // 選択範囲が1つで矩形選択ではないとき
| |
| if ( ! s.Mode || s.Mode === meModeStream ) {
| |
| DeleteSpace2_Main( arg );
| |
| }
| |
| // 複数行または複数選択のとき
| |
| else {
| |
| BeginUndoGroup();
| |
| AddUndo();
| |
| MultiFunction( DeleteSpace2_Main, arg );
| |
| EndUndoGroup();
| |
| }
| |
| ScrollX = sx; ScrollY = sy;
| |
|
| |
| var elapsedSec = ( ( new Date() - start ) / 1000 ).toFixed( 3 );
| |
| Status = " 「スペース×2 削除」マクロ [ "
| |
| + elapsedSec.replace( /\./, ". " )
| |
| + " 秒 ]";
| |
| }
| |
|
| |
|
| |
| /**
| |
| * 関数 DeleteSpace2_Main( [ deleteNearestTab, blank ] )
| |
| * 「字上げ(スペース×2 削除)」マクロ
| |
| */
| |
| function DeleteSpace2_Main( arg ) {
| |
| var deleteNearestTab = arg[0];
| |
| var blank = arg[1];
| |
|
| |
| var d = editor.ActiveDocument;
| |
| var s = d.selection;
| |
|
| |
| // "選択範囲なし" のフラグ
| |
| var pos = s.IsEmpty ? s.GetActivePos() : -1;
| |
|
| |
| /* カーソル付近の「タブ文字×1」を削除するパターン(左側優先) */
| |
| if ( pos > -1 && deleteNearestTab ) {
| |
| if ( d.Text.charAt( pos - 1 ) === "\t" ) {
| |
| s.DeleteLeft(); return;
| |
| }
| |
| else if ( d.Text.charAt( pos ) === "\t" ) {
| |
| s.Delete(); return;
| |
| }
| |
| }
| |
|
| |
| // 選択範囲を取得
| |
| var tx = s.GetTopPointX( mePosLogical );
| |
| 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, d.GetLine( by, 0 ).length + 1, by );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
|
| |
| /* 行頭の空白文字を削除 */
| |
| var st = s.Text;
| |
| var tp = s.GetAnchorPos();
| |
| for ( var i = 0, len = blank.length; i < len; i ++ ) {
| |
| blank[i].replace( /\W/g, "\\$&" );
| |
| }
| |
| var reg = RegExp( "^(?:" + blank.join( "|" ) + ")", "gm" );
| |
| var tmp = st.replace( reg, "" );
| |
| if ( tmp !== st ) {
| |
| // ブックマークを保存
| |
| var bmArray = GetBookmark( ty, by );
| |
| // 字上げ完了
| |
| s.Text = tmp;
| |
| // ブックマークを復元
| |
| RestoreBookmark( ty, by, bmArray );
| |
| }
| |
|
| |
| // 範囲選択を残さない
| |
| if ( pos > -1 ) {
| |
| if ( st.length - tmp.length >= tx ) {
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| }
| |
| else {
| |
| s.SetActivePos( pos - ( st.length - tmp.length ) );
| |
| }
| |
| }
| |
| // 範囲選択を残す(論理行単位)
| |
| else {
| |
| s.SetActivePos( tp + tmp.length + 1 );
| |
| s.SetAnchorPos( tp );
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 GetBookmark( ty, by )
| |
| * 指定された範囲のブックマークを収集
| |
| */
| |
| function GetBookmark( ty, by ) {
| |
| var bmArray = [], bmY;
| |
| var s = editor.ActiveDocument.selection;
| |
| if ( ty < by ) {
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
|
| |
| if ( ty === 1 ) {
| |
| s.SetActivePoint( mePosLogical, 1, 2 );
| |
| if ( s.PreviousBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| }
| |
| s.SetActivePos( 0 );
| |
| }
| |
| else { s.SetActivePoint( mePosLogical, 1, ty - 1 ); }
| |
|
| |
| while ( s.NextBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| else if ( bmY > by ) { break; }
| |
| }
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| return bmArray;
| |
| }
| |
|
| |
| /**
| |
| * 関数 RestoreBookmark( ty, by, bmArray )
| |
| * 指定された範囲のブックマークを復元
| |
| */
| |
| function RestoreBookmark( ty, by, bmArray, sel ) {
| |
| var bmCount = bmArray.length;
| |
| if ( bmCount ) {
| |
| var s = editor.ActiveDocument.selection;
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| s.ClearBookmark();
| |
| for ( var i = 0; i < bmCount, bmArray[i] <= by; i ++ ) {
| |
| if ( bmArray[i] < ty ) { continue; }
| |
| s.SetActivePoint( mePosLogical, 1, bmArray[i], false );
| |
| s.SetBookmark();
| |
| }
| |
| if ( sel ) {
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 MultiFunction( Fn, arg1 )
| |
| * マルチカーソル(複数選択範囲)に対応させる
| |
| * 第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 ); // DeleteSpace2_Main() 関数
| |
|
| |
| // Fn() の残した選択範囲(またはキャレット位置)を回収
| |
| Sel[i].act = s.GetActivePos();
| |
| Sel[i].anc = s.GetAnchorPos();
| |
| diff += d.TextLength - dl; // 文字数の増減量(累積)
| |
| }
| |
|
| |
| // マルチカーソル(複数選択範囲)を復帰
| |
| s.SetActivePos( Sel[0].anc );
| |
| for ( var i = 0; i < sCount; i ++ ) {
| |
| s.AddPos( Sel[i].anc, Sel[i].act );
| |
| }
| |
| }
| |
| </source>
| |
|
| |
| == インデント ==
| |
| ;インデント.js <br>
| |
| 既存のツールバーアイコンのアイテム「インデント」から置きかえて使う目的のマクロで、<span style="color:#0000c0;">選択範囲がなくてもタブインデント</span>します。 <br> ソースコードの内容は「字上げ(スペース×2 追加)」マクロとほぼ同じですが、こちらの「インデント」マクロの場合は、挿入する空白は「タブ文字」のみで空白行にたいしてもインデントを追加します。
| |
| * 論理行全体をタブインデント(行頭)して範囲選択します。 <br> 選択範囲が1行内ならもとの選択範囲を維持し、複数行なら対象の論理行全体を範囲選択します。
| |
| * またはカーソル位置にタブ文字を挿入します。
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| * <span style="color:#0000c0;">マルチカーソル/複数選択範囲に対応(Mery ver 3.0.1 以上)</span>
| |
|
| |
|
| |
| 【推奨設定】 <br>
| |
| Tab キーに割りあてるなら <syntaxhighlight lang="javascript" inline>var tabEnable = 2</syntaxhighlight>,<br>
| |
| ツールバーアイコンにするなら <syntaxhighlight lang="javascript" inline>var tabEnable = 0</syntaxhighlight>
| |
|
| |
| <source lang="javascript" style="height:60em; overflow:auto;">
| |
| #title = "インデント"
| |
| #tooltip = "選択範囲がなくてもインデント"
| |
| // #icon = "indent_right.ico"
| |
| // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",260
| |
|
| |
| var start = new Date();
| |
|
| |
| /**
| |
| * ---------------------------------------------------------
| |
| * 「インデント」マクロ
| |
| * sukemaru, 2018/11/15 - 2020/06/29
| |
| * ---------------------------------------------------------
| |
| * ・選択範囲なしでも、論理行全体をタブインデント(行頭)して範囲選択する
| |
| * 選択範囲が1行内ならもとの選択範囲を維持し、
| |
| * 複数行なら対象の論理行全体を範囲選択する
| |
| * ・またはカーソル位置にタブ文字を挿入する
| |
| * 【推奨設定】 Tab キーに割りあてるなら tabEnable = 2
| |
| * ツールバーアイコンにするなら tabEnable = 0
| |
| *
| |
| * 2020/06/29: マルチカーソル/複数選択範囲に対応
| |
| * ブックマーク行を字下げしたときのみブックマークの復元をするように変更
| |
| * ブックマークの収集範囲を選択範囲に限定
| |
| * ブックマークの収集/復元コードを関数化
| |
| */
| |
|
| |
| // ---------- ▼ 設定項目 ▼ ----------
| |
|
| |
| // ■選択範囲があるときに、選択範囲を「タブ文字」にするか? 行全体をタブインデントするか?
| |
| var tabEnable = 0;
| |
| /**
| |
| * 0: 選択範囲がなくてもつねに行全体をタブインデント(行頭)
| |
| * 1: 選択範囲があれば行全体をタブインデント、
| |
| * なければキャレット位置に「タブ文字」を挿入
| |
| * (※ツールバーアイコンの「インデント」に似た動作)
| |
| * 2: 選択範囲が1行内(論理行)のときは選択範囲を「タブ文字」にする
| |
| * 選択範囲がないときはキャレット位置に「タブ文字」を挿入
| |
| * 選択範囲が複数行(論理行)のときはタブインデントする
| |
| * (※Tab キーの通常動作にちかい ← Mery 標準機能では "表示行" で1行内)
| |
| * 3: つねに選択範囲を「タブ文字」にする(※インデントしない)
| |
| * 4: 選択範囲があり、1行内(論理行)のときは選択範囲の先頭に「タブ文字」を追加し、
| |
| * それ以外の場合には 0 と同じ動作(行全体をタブインデント)をする
| |
| *
| |
| * ※ 0 の場合、「タブ文字」を挿入することができないので、
| |
| * ツールバーアイコン向けの設定。
| |
| * ※ 1 の場合、選択範囲を「タブ文字」にすることができないので、
| |
| * Tab キーにマクロを割りあてると少し不便になるかも?
| |
| * 範囲選択 → 削除 (Delete / BackSpace) → 「インデント」マクロ (Tab)
| |
| * ※ 2 の場合に1行だけインデントさせるなら、行頭でクリックするか、
| |
| * 行内でトリプルクリック、または行番号のクリックで行全体を選択範囲にして
| |
| * 「インデント」マクロを実行する (末尾改行まで含める必要あり)。
| |
| * [EOF] マークのある文書末行(さいごに改行がない)だけの1行選択では
| |
| * インデントできない。
| |
| * ⇔ Tab キーの通常動作では末尾改行を含める必要はない
| |
| * ※ 3 は、わざわざマクロでやる意味もないかと。
| |
| * ※ 4 は、0 と 1 の動作の統合型(1 の動作条件を反転させたもの)。
| |
| */
| |
|
| |
| // ---------- ▲ 設定項目 ▲ ----------
| |
|
| |
| var d = editor.ActiveDocument;
| |
|
| |
| if ( d.ReadOnly ) {
| |
| Status = " ドキュメントは書き換え禁止です。";
| |
| }
| |
|
| |
| else {
| |
| var s = d.selection;
| |
| var sx = ScrollX, sy = ScrollY;
| |
| var tab = "\t";
| |
|
| |
| // マルチカーソル/複数選択に対応
| |
| var arg = [ tabEnable, tab ];
| |
| // 選択範囲が1つで矩形選択ではないとき
| |
| if ( ! s.Mode || s.Mode === 1 ) {
| |
| Indent_Main( arg );
| |
| }
| |
| // 矩形選択または複数選択のとき
| |
| else {
| |
| BeginUndoGroup();
| |
| AddUndo();
| |
| MultiFunction( Indent_Main, arg );
| |
| EndUndoGroup();
| |
| }
| |
| ScrollX = sx; ScrollY = sy;
| |
|
| |
| var elapsedSec = ( ( new Date() - start ) / 1000 ).toFixed( 3 );
| |
| Status = " 「インデント」マクロ [ "
| |
| + elapsedSec.replace( /\./, ". " )
| |
| + " 秒 ]";
| |
| }
| |
|
| |
|
| |
| /**
| |
| * 関数 Indent_Main( [ tabEnable, tab ] )
| |
| * 「インデント」マクロ
| |
| */
| |
| function Indent_Main( arg ) {
| |
| var tabEnable = arg[0];
| |
| var tab = arg[1];
| |
|
| |
| // 選択範囲
| |
| var act = s.GetActivePos();
| |
| var anc = s.GetAnchorPos();
| |
| var tx = s.GetTopPointX( mePosLogical );
| |
| var ty = s.GetTopPointY( mePosLogical );
| |
| var bx = s.GetBottomPointX( mePosLogical );
| |
| var by = yy = s.GetBottomPointY( mePosLogical );
| |
| var inLine = ( ty === by && act !== anc );
| |
|
| |
| /* 行の途中の選択範囲を字下げするパターン */
| |
| if ( tabEnable === 4 && inLine ) {
| |
| s.Text = tab + s.Text;
| |
| s.SetAnchorPoint( mePosLogical, tx, ty );
| |
| }
| |
|
| |
| /* カーソル位置にタブを挿入するパターン */
| |
| else if ( ( tabEnable === 1 && s.IsEmpty )
| |
| || ( tabEnable === 2 && ty === by )
| |
| || tabEnable === 3 ) {
| |
| s.Text = tab;
| |
| }
| |
|
| |
| else {
| |
| // 選択範囲を拡張
| |
| if ( ty !== by && bx === 1 ) { yy --; }
| |
| s.SetActivePoint( mePosLogical, d.GetLine( yy, 0 ).length + 1, yy );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
|
| |
| /* インデント */
| |
| var tp = s.GetAnchorPos();
| |
| var st = s.Text;
| |
| var tmp = st.replace( /^/gm , tab );
| |
| if ( tmp !== st ) {
| |
| // ブックマークを保存
| |
| var bmArray = GetBookmark( ty, by );
| |
| // インデント完了
| |
| s.Text = tmp;
| |
| // ブックマークを復元
| |
| RestoreBookmark( ty, by, bmArray );
| |
| }
| |
|
| |
| // 選択範囲を復元
| |
| if ( ty === by ) {
| |
| s.SetActivePos( act + tab.length );
| |
| s.SetAnchorPos( anc + tab.length );
| |
| }
| |
| else {
| |
| s.SetActivePos( tp + tmp.length + 1 );
| |
| s.SetAnchorPos( tp );
| |
| }
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 GetBookmark( ty, by )
| |
| * 指定された範囲のブックマークを収集
| |
| */
| |
| function GetBookmark( ty, by ) {
| |
| var bmArray = [], bmY;
| |
| var s = editor.ActiveDocument.selection;
| |
| if ( ty < by ) {
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
|
| |
| if ( ty === 1 ) {
| |
| s.SetActivePoint( mePosLogical, 1, 2 );
| |
| if ( s.PreviousBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| }
| |
| s.SetActivePos( 0 );
| |
| }
| |
| else { s.SetActivePoint( mePosLogical, 1, ty - 1 ); }
| |
|
| |
| while ( s.NextBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| else if ( bmY > by ) { break; }
| |
| }
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| return bmArray;
| |
| }
| |
|
| |
| /**
| |
| * 関数 RestoreBookmark( ty, by, bmArray )
| |
| * 指定された範囲のブックマークを復元
| |
| */
| |
| function RestoreBookmark( ty, by, bmArray, sel ) {
| |
| var bmCount = bmArray.length;
| |
| if ( bmCount ) {
| |
| var s = editor.ActiveDocument.selection;
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| s.ClearBookmark();
| |
| for ( var i = 0; i < bmCount, bmArray[i] <= by; i ++ ) {
| |
| if ( bmArray[i] < ty ) { continue; }
| |
| s.SetActivePoint( mePosLogical, 1, bmArray[i], false );
| |
| s.SetBookmark();
| |
| }
| |
| if ( sel ) {
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 MultiFunction( Fn, arg1 )
| |
| * マルチカーソル(複数選択範囲)に対応させる
| |
| * 第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 ); // Indent_Main() 関数
| |
|
| |
| // Fn() の残した選択範囲(またはキャレット位置)を回収
| |
| Sel[i].act = s.GetActivePos();
| |
| Sel[i].anc = s.GetAnchorPos();
| |
| diff += d.TextLength - dl; // 文字数の増減量(累積)
| |
| }
| |
|
| |
| // マルチカーソル(複数選択範囲)を復帰
| |
| s.SetActivePos( Sel[0].anc );
| |
| for ( var i = 0; i < sCount; i ++ ) {
| |
| s.AddPos( Sel[i].anc, Sel[i].act );
| |
| }
| |
| }
| |
| </source>
| |
|
| |
|
| |
| == 逆インデント ==
| |
| ;アンインデント.js <br>
| |
| 既存のツールバーアイコンのアイテム「逆インデント」から置きかえて使う目的のマクロで、<span style="color:#0000c0;">選択範囲がなくてもアンインデント</span>します。 <br>
| |
| 機能的には「字上げ(スペース×2 削除)」マクロとほぼ同じですが、削除できる「半角スペース×n」の最大数をかんたんに設定できるようにしてあります <br>
| |
| ( "␣␣␣␣", "␣␣␣", "␣␣", "␣" なら <syntaxhighlight lang="javascript" inline style="white-space:nowrap">var deleteSpace = 4</syntaxhighlight> と指定するだけ)。
| |
| * 行頭またはカーソル付近の「タブ文字×1」か、行頭の「半角スペース×n」を削除します(<q>半角スペース×n</q> は行頭だけが対象です)。
| |
| * 選択範囲なしならカーソル付近のタブを削除するか、またはカーソルのある1行をアンインデントして、カーソル位置を復帰します。
| |
| * 選択範囲ありなら論理行全体をアンインデント(行頭)して範囲選択します。
| |
| * 選択範囲が末尾に改行を含んでいた場合は、最後の改行を無視します。
| |
| * <span style="color:#0000c0;">マルチカーソル/複数選択範囲に対応(Mery ver 3.0.1 以上)</span>
| |
|
| |
|
| |
| 【推奨設定】<br>
| |
| 「字上げ」マクロと並存させるなら <syntaxhighlight lang="javascript" inline>var deleteSpace = 0</syntaxhighlight> ,<br>
| |
| 「字上げ」マクロなしで Shift+Tab キーに割りあてるなら <syntaxhighlight lang="javascript" inline>var deleteSpace ≠ 0</syntaxhighlight> ( 1 以上の値)<br>
| |
|
| |
| ※ 設定用変数 <syntaxhighlight lang="javascript" inline>var deleteSpace = n</syntaxhighlight> で '''3''' 以上の数値を指定するさいは、Mery のオプション設定の「タブの桁数」を目安にしてください(大きな数字や非整数値を入れての動作検証はしていません)。
| |
|
| |
| ※ sukemaru 版の「逆インデント」と「字上げ(スペース×2 削除)」マクロを並存させるメリットは特にないとおもいますので、どちらかお好みで選んでください。
| |
|
| |
| <source lang="javascript" style="height:60em; overflow:auto;">
| |
| #title = "逆インデント"
| |
| #tooltip = "選択範囲がなくてもアンインデント"
| |
| // #icon = "indent_left.ico"
| |
| // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",261
| |
|
| |
| var start = new Date();
| |
|
| |
| /**
| |
| * ---------------------------------------------------------
| |
| * 「逆インデント」マクロ
| |
| * sukemaru, 2018/11/15 - 2020/06/29
| |
| * ---------------------------------------------------------
| |
| * 選択範囲なしでも、行頭またはカーソル付近の「タブ文字×1」か、
| |
| * 行頭の「半角スペース×2」を削除する
| |
| * ・選択範囲なしならカーソル付近のタブを削除するか、
| |
| * またはカーソルのある1行をアンインデントして、カーソル位置を復帰する
| |
| * ・選択範囲ありなら論理行全体をアンインデントして範囲選択する
| |
| *
| |
| * 2020/06/29: マルチカーソル/複数選択範囲に対応
| |
| * ブックマーク行を字下げしたときのみブックマークの復元をするように変更
| |
| * ブックマークの収集範囲を選択範囲に限定
| |
| * ブックマークの収集/復元コードを関数化
| |
| */
| |
|
| |
| // ---------- ▼ 設定項目 ▼ ----------
| |
|
| |
| // ■ 選択範囲なしのときに、カーソル位置の前後にある「タブ文字」を優先的に削除するか?
| |
| // ※ 選択範囲が1行内で、先頭に「タブ文字」がある場合も優先的に削除する
| |
| var deleteNearestTab = true;
| |
| /**
| |
| * false にすると、つねに行頭の空白文字のみを削除
| |
| * true にすると、カーソル付近の「タブ文字×1」を優先的に削除
| |
| * (タブ文字がなければ行頭の空白を削除)
| |
| */
| |
|
| |
|
| |
| // ■ 行頭の「半角スペース」や「全角スペース」も削除するか?
| |
| var deleteSpace = 1;
| |
| /**
| |
| * ※ 正の整数値で指定してください
| |
| * 0: 行頭の「タブ文字×1」だけを削除
| |
| * 1: 行頭の「タブ文字×1」と「半角スペース×1~2」も削除
| |
| * 2: 行頭の「タブ文字×1」と「半角スペース×1~2」と「全角スペース×1」も削除
| |
| * 3: 1回の逆インデントで削除できる「半角スペース×n」の最大数が増加
| |
| * ※ 削除できる「全角スペース」の最大数は n / 2 ( → roundDecimal 変数で設定 )
| |
| */
| |
|
| |
|
| |
| // ■ deleteSpace が 3 以上のとき、削除できる「全角スペース」の最大数
| |
| var roundDecimal = false;
| |
| /**
| |
| * ※ deleteSpace が奇数のときの小数点以下の処理
| |
| * false にすると ( deleteSpace / 2 ) の小数点以下を切り捨て
| |
| * true にすると ( deleteSpace / 2 ) の小数点以下を切り上げ(四捨五入)
| |
| */
| |
|
| |
| // ---------- ▲ 設定項目 ▲ ----------
| |
|
| |
| var d = editor.ActiveDocument;
| |
|
| |
| if ( d.ReadOnly ) {
| |
| Status = " ドキュメントは書き換え禁止です。";
| |
| }
| |
| else {
| |
| var s = d.selection;
| |
| var sx = ScrollX, sy = ScrollY;
| |
|
| |
| // マルチカーソル/複数選択に対応
| |
| var arg = [ deleteNearestTab, deleteSpace, roundDecimal ];
| |
| // 選択範囲が1つで矩形選択ではないとき
| |
| if ( ! s.Mode || s.Mode === 1 ) {
| |
| Unindent_Main( arg );
| |
| }
| |
| // 矩形選択または複数選択のとき
| |
| else {
| |
| BeginUndoGroup();
| |
| AddUndo();
| |
| MultiFunction( Unindent_Main, arg );
| |
| EndUndoGroup();
| |
| }
| |
| ScrollX = sx; ScrollY = sy;
| |
|
| |
| var elapsedSec = ( ( new Date() - start ) / 1000 ).toFixed( 3 );
| |
| Status = " 「逆インデント」マクロ [ "
| |
| + elapsedSec.replace( /\./, ". " )
| |
| + " 秒 ]";
| |
| }
| |
|
| |
| /**
| |
| * 関数 Unindent_Main( [ deleteNearestTab, deleteSpace, roundDecimal ] )
| |
| * 「逆インデント」マクロ
| |
| */
| |
| function Unindent_Main( arg ) {
| |
| var deleteNearestTab = arg[0];
| |
| var deleteSpace = arg[1];
| |
| var roundDecimal = arg[2];
| |
|
| |
| var d = editor.ActiveDocument;
| |
| var s = editor.ActiveDocument.selection;
| |
|
| |
| // "選択範囲なし" のフラグ
| |
| var pos = s.IsEmpty ? s.GetActivePos() : -1;
| |
|
| |
| /* カーソル付近の「タブ文字×1」を削除するパターン(左側優先) */
| |
| if ( pos > -1 && deleteNearestTab ) {
| |
| if ( d.Text.charAt( pos - 1 ) === "\t" ) {
| |
| s.DeleteLeft(); return;
| |
| }
| |
| else if ( d.Text.charAt( pos ) === "\t" ) {
| |
| s.Delete(); return;
| |
| }
| |
| }
| |
|
| |
| // 選択範囲
| |
| var act = s.GetActivePos();
| |
| var anc = s.GetAnchorPos();
| |
| var tx = s.GetTopPointX( mePosLogical );
| |
| var ty = s.GetTopPointY( mePosLogical );
| |
| var bx = s.GetBottomPointX( mePosLogical );
| |
| var by = yy = s.GetBottomPointY( mePosLogical );
| |
| var inLine = ( ty === by && act !== anc );
| |
| var st = s.Text;
| |
|
| |
| /* 選択範囲が1行内のときに、先頭の「タブ文字」を優先的に削除するパターン */
| |
| if ( inLine && deleteNearestTab && st.charAt( 0 ) === "\t" ) {
| |
| s.Text = st.replace( /^\t/, "" );
| |
| s.SetAnchorPoint( mePosLogical, tx, ty );
| |
| }
| |
|
| |
| else {
| |
| // 選択範囲を拡張
| |
| if ( ty !== by && bx === 1 ) { yy --; }
| |
| s.SetActivePoint( mePosLogical, d.GetLine( yy, 0 ).length + 1, yy );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
|
| |
| /* 逆インデント */
| |
| var regStr1 = "^\\t|^[ ]{1,2}";
| |
| var regStr2 = "^\\t|^[ ]{1,2}|^[ ]";
| |
| var regStr3 = "^\\t|^[ ]{1," + deleteSpace + "}|^[ ]{1,"
| |
| + ( roundDecimal ? Math.round( deleteSpace / 2 ) // 切り上げ
| |
| : Math.floor( deleteSpace / 2 ) ) // 切り捨て
| |
| + "}";
| |
| var indent = ( deleteSpace === 1 ) ? regStr1
| |
| : ( deleteSpace === 2 ) ? regStr2
| |
| : ( deleteSpace >= 3 ) ? regStr3
| |
| : /* else */ "^\\t";
| |
|
| |
| st = s.Text;
| |
| var tp = s.GetAnchorPos();
| |
| var tmp = st.replace( new RegExp( indent , "gm" ) , "" );
| |
| if ( tmp !== st ) {
| |
| // ブックマークを保存
| |
| var bmArray = GetBookmark( ty, yy );
| |
| // 逆インデント完了
| |
| s.Text = tmp;
| |
| // ブックマークを復元
| |
| RestoreBookmark( ty, yy, bmArray );
| |
| }
| |
|
| |
| // 選択範囲が1行だったときは、位置関係を維持して選択範囲を復元する
| |
| if ( ty === by ) {
| |
| var gap = st.length - tmp.length;
| |
| if ( bx <= gap ) {
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| }
| |
| else if ( anc < act && tx <= gap ) {
| |
| s.SetActivePos( act - gap );
| |
| s.SetAnchorPoint( mePosLogical, 1, ty );
| |
| }
| |
| else if ( tx <= gap ) {
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| s.SetAnchorPos( anc - gap );
| |
| }
| |
| else {
| |
| s.SetActivePos( act - gap );
| |
| s.SetAnchorPos( anc - gap );
| |
| }
| |
| }
| |
| // 選択範囲が複数行だったときは、拡張した選択範囲を復元する
| |
| else {
| |
| s.SetActivePos( tp + tmp.length + 1 );
| |
| s.SetAnchorPos( tp );
| |
| }
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 GetBookmark( ty, by )
| |
| * 指定された範囲のブックマークを収集
| |
| */
| |
| function GetBookmark( ty, by ) {
| |
| var bmArray = [], bmY;
| |
| var s = editor.ActiveDocument.selection;
| |
| if ( ty < by ) {
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
|
| |
| if ( ty === 1 ) {
| |
| s.SetActivePoint( mePosLogical, 1, 2 );
| |
| if ( s.PreviousBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| }
| |
| s.SetActivePos( 0 );
| |
| }
| |
| else { s.SetActivePoint( mePosLogical, 1, ty - 1 ); }
| |
|
| |
| while ( s.NextBookmark() ) {
| |
| bmY = s.GetActivePointY( mePosLogical );
| |
| if ( bmY >= ty && bmY <= by ) {
| |
| bmArray.push( bmY );
| |
| }
| |
| else if ( bmY > by ) { break; }
| |
| }
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| return bmArray;
| |
| }
| |
|
| |
| /**
| |
| * 関数 RestoreBookmark( ty, by, bmArray )
| |
| * 指定された範囲のブックマークを復元
| |
| */
| |
| function RestoreBookmark( ty, by, bmArray, sel ) {
| |
| var bmCount = bmArray.length;
| |
| if ( bmCount ) {
| |
| var s = editor.ActiveDocument.selection;
| |
| var anc = s.GetAnchorPos(), act = s.GetActivePos();
| |
| s.SetActivePoint( mePosLogical, 1, ty );
| |
| s.ClearBookmark();
| |
| for ( var i = 0; i < bmCount, bmArray[i] <= by; i ++ ) {
| |
| if ( bmArray[i] < ty ) { continue; }
| |
| s.SetActivePoint( mePosLogical, 1, bmArray[i], false );
| |
| s.SetBookmark();
| |
| }
| |
| if ( sel ) {
| |
| s.SetActivePos( act ); s.SetAnchorPos( anc );
| |
| }
| |
| }
| |
| }
| |
|
| |
| /**
| |
| * 関数 MultiFunction( Fn, arg1 )
| |
| * マルチカーソル(複数選択範囲)に対応させる
| |
| * 第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 ); // Unindent_Main() 関数
| |
|
| |
| // Fn() の残した選択範囲(またはキャレット位置)を回収
| |
| Sel[i].act = s.GetActivePos();
| |
| Sel[i].anc = s.GetAnchorPos();
| |
| diff += d.TextLength - dl; // 文字数の増減量(累積)
| |
| }
| |
|
| |
| // マルチカーソル(複数選択範囲)を復帰
| |
| s.SetActivePos( Sel[0].anc );
| |
| for ( var i = 0; i < sCount; i ++ ) {
| |
| s.AddPos( Sel[i].anc, Sel[i].act );
| |
| }
| |
| }
| |
| </source>
| |
|
| |
|
| |
| == メモ ==
| |
| '''2019/04/07''' (sukemaru)
| |
| :ソースコードから Quit() メソッドを削除
| |
| ----
| |
| '''2019/11/10''' (sukemaru)
| |
| :Mery 2.8.6 以上でブックマークを保持
| |
| :※ Mery 2.8.5 以前ではブックマーク機能の仕様が不安定なので、個別対応はあきらめた…。
| |
| ----
| |
| '''2019/11/17''' (sukemaru)
| |
| :Mery 2.8.6 以上、または Mery 2.6.7 でブックマークを保持
| |
| :※ Mery 2.7.0 - 2.8.5 ではブックマーク機能の仕様が不安定なので、1行のみの「字下げ/字上げ (インデント/逆インデント)」をしたときにブックマークがおかしくなることがある。<br> 現時点での最新の正式版と最新ベータ版で正常に機能するように調整した。
| |
| '''2019/11/18''' (sukemaru)
| |
| :「スペース×2 削除.js」のソースコードで設定項目部分がダブっていたのを修正
| |
| ----
| |
| '''2019/12/01''' (sukemaru)
| |
| : 複数行選択のときのみブックマークの保存/復元するように変更
| |
| :(ブックマークが大量にある文書で、範囲選択1行内で実行したときの速度を改善)
| |
| ----
| |
| '''2020/06/29''' (sukemaru)
| |
| : マルチカーソル/複数選択範囲に対応
| |
| : ブックマークの収集/復元コードを関数化
| |
| : (ブックマークの収集を選択範囲内の行に限定し、ブックマーク行を「字下げ/字上げ」したときのみ復元処理をするように変更)
| |
| ----
| |