/* (Tab=4) [概要] カーソルのある行を、スペース(1文字)を空けて、前の行(上の行)と 連結します。 前の行が空行(空白類が0文字以上のみの行)の場合、 スペース(1文字)は挿入しません。 (emacsの delete-indentation (M-^, ESC ^)の様な機能です。) [変更履歴] 2012/08/05 新規 (Unicode版にも対応) */ // メッセージボックスを出すのにWshShell.Popup()を使用する。 // 書式(MSDNのWSHより): intButton = WshShell.Popup(strText,[nSecondsToWait],[strTitle],[nType]) //var WshShell = new ActiveXObject("WScript.Shell"); // メッセージボックスのタイトル (本マクロ名) //var CAPTION = Editor.ExpandParameter("$M").replace( /^.*\\/, "" ); // 削除(置換)されるスペース・タブ (正規表現) // 前の行(上の行)の行末のスペース・タブと、カーソル行の行頭のスペース・タブは、 // スペース(1文字)に置換されます。 var sSPACE; sSPACE = "[ \t]"; // 半角スペース、タブ // sSPACE = "[ \t ]"; // 半角スペース、タブ、全角スペース //-------------- // メイン Main(); function Main() { var sSakuraVer; // サクラエディタのバージョン (例:ANSI版="1.6.6.0" / Unicode版="2.0.5.0") sSakuraVer = Editor.ExpandParameter("$V"); // とりあえず4桁にして比較 (例:"1.23.456.7890" → "0001.0023.0456.7890") sSakuraVer = sSakuraVer.replace( /\d+/g, function($0){return ("000"+$0).slice(-4);} ); if( sSakuraVer >= "0002.0000.0004.0000" ){ Sub2(); // sakura:2.0.4.0以降(Unicode版)。MoveCursor() が使える。 }else{ Sub1(); // ANSI版/Unicode版 両対応。動作がぎこちない。 } } // ANSI版/Unicode版 両対応。動作がぎこちない。 function Sub1() { var y; // カーソル行の行位置 var sLinePrev; // 前の行(上の行)の文字列 var sLineCur; // カーソル行の文字列 var re; // 正規表現 var bPrevIsBlankLine; // 前の行は空行か var sLineNew; // 前の行の行末(行末のスペース・タブを除く)と、 // カーソル行全体(行頭のスペース・タブを除く)とを、 // スペース(1文字)を空けて連結した文字列 Editor.CancelMode(); // 範囲選択中なら取り消し。 y = Editor.ExpandParameter("$y") -0; // -0:文字列→数値化 if( y == 1 ){ // 先頭行なら何もせず終了。 Editor.GoFileTop(); // 行頭(=ファイルの先頭)へ return; } // 前の行(上の行)と、カーソル行を取得。 sLinePrev = Editor.GetLineStr( y - 1 ); sLineCur = Editor.GetLineStr( 0 ); // 前の行は空行か。 // 空行でなければ、連結した文字列にスペース(1文字)を入れる。 re = new RegExp( "^" + sSPACE + "*[\r\n]+" ); // re = /^[ \t]*[\r\n]+/ bPrevIsBlankLine = (sLinePrev.search( re ) != -1); sLineNew = (bPrevIsBlankLine) ? "" : " "; // カーソル行の、先頭の連続したスペース・タブを削除した文字列。 re = new RegExp( "^" + sSPACE + "*" ); // re = /^[ \t]*/ sLineNew += sLineCur.replace( re, "" ); // 前の行の、行末の連続したスペース・タブの開始位置(無ければ行末)に移動。 // (マクロ実行後のカーソル位置でもある。) Editor.GoLineTop( (1<<3)|(1<<0) ); // 行頭へ(改行単位) Editor.Left(); // 前の行の行末へ if( bPrevIsBlankLine ){ // 前の行が空行なら行頭に移動、となる。 Editor.GoLineTop( (1<<3)|(1<<0) ); // 行頭へ(改行単位) }else{ // 行末から前方へ、スペース・タブ以外の文字の出現位置を探す。 re = new RegExp( "^" + sSPACE ); // re = /^[ \t]/ while(true){ Editor.WordLeft(); if( Editor.ExpandParameter("$C").search( re ) == -1 ) break; // "$C":カーソル位置の単語 } Editor.SelectWord(); // 単語を選択して、 Editor.Right(); // 右へ } Editor.MoveHistSet(); // 位置を記憶 // カーソル行の次の行の先頭から、現カーソル位置までを選択し、置き換える。 // (Undo時、カーソルは前の行の行末の連続したスペース・タブの左端) Editor.SelectLine(0); // 前の行→カーソル行へ移動し、 Editor.SelectLine(0); // カーソル行→次の行へ移動 Editor.BeginSelect(); Editor.MoveHistPrev(); Editor.MoveHistSet(); // 再び(同じ位置を)記憶 Editor.InsText( sLineNew ); // マクロ実行後のカーソル位置へ移動。(連結したスペース(1文字)の位置。) Editor.GoLineTop( (1<<3)|(1<<0) ); // 行頭へ(改行単位) // ↑無くてもよいが、折り返しが右側画面外のときに左スクロールするので。 Editor.MoveHistPrev(); Editor.CancelMode(); // 範囲選択中なら取り消し。(編集禁止時用) Editor.ReDraw(); } // sakura:2.0.4.0以降(Unicode版)。MoveCursor() が使える。 function Sub2() { var y; // 行位置(1開始) var sLinePrev; // 前の行(上の行)の文字列 var sLineCur; // カーソル行の文字列 var i; var c; var nSta, nEnd; // 文字列内の位置(0開始) Editor.CancelMode(); // 範囲選択中なら取り消し。 y = Editor.ExpandParameter("$y") -0; // -0:文字列→数値化 if( y == 1 ){ // 先頭行なら何もせず終了。 Editor.GoFileTop(); // 行頭(=ファイルの先頭)へ return; } // 前の行(上の行)と、カーソル行を取得。 sLinePrev = Editor.GetLineStr( y - 1 ); sLineCur = Editor.GetLineStr( 0 ); // 前の行の、行末の連続したスペース・タブの開始位置(無ければ行末)を得る。 for(i = sLinePrev.length - 1; i >= 0; i--){ c = sLinePrev.charAt( i ); if( c.search( /[\r\n]/ ) != -1 ) continue; if( c.search( sSPACE ) == -1 ) break; } nSta = i + 1; // (nSta=0なら空行) // カーソル行の、行頭の連続したスペース・タブの終了位置(無ければ行頭)を得る。 for(i = 0; i < sLineCur.length; i++){ if( sLineCur.charAt( i ).search( sSPACE ) == -1 ) break; } nEnd = i; // 範囲選択して、スペース(1文字)に置き換える。 // (Undo時、カーソルは前の行の行末の連続したスペース・タブの左端) // Editor.MoveCursor( y, nEnd + 1, 0 ); // オプション 0=未選択 // Editor.MoveCursor( y - 1, nSta + 1, 1 ); // オプション 1=通常選択 // (Undo時、カーソルはカーソル行の行頭の連続したスペース・タブの右端) Editor.MoveCursor( y - 1, nSta + 1, 0 ); // オプション 0=未選択 Editor.MoveCursor( y, nEnd + 1, 1 ); // オプション 1=通常選択 if( nSta == 0 ){ // 前の行は空行だった。スペース(1文字)は入れない。 Editor.Delete(); }else{ // 前の行は空行ではない。スペース(1文字)を入れる。 Editor.InsText( " " ); // マクロ実行後のカーソル位置へ移動。(連結したスペース(1文字)の位置。) Editor.Left(); } Editor.CancelMode(); // 範囲選択中なら取り消し。(編集禁止時用) Editor.ReDraw(); }