/* [概要] "//" (行型コメント) または "/*" と "*/" (ブロック型コメント)を アンコメントします(コメントを外します)。 但しブロック型コメントの場合、開始文字列 "/*" が、"//" 同様に 行頭または空白類が先行する場合にのみ処理します。 範囲選択していない場合、カーソルのある行を処理します。 範囲選択している場合、選択範囲にある行全体を選択して処理します。 (矩形選択でも同じです。) 範囲選択は、行頭からではなく行の途中から(桁位置>=2)でも構いません。 コメント文字列はデフォルトでC/C++スタイルですが、 ファイルの拡張子、及び 現在適用されているタイプ別設定 により変わります。 大文字・小文字は区別されません。(rem等) (対応:sakura:1.6.5.0以降) [制限] ・挙動: ・"//"、"/*" の後にスペース1文字が存在すれば、そのスペース1文字も削除されます。 ・"*/" の前にスペース1文字が存在すれば、そのスペース1文字も削除されます。 ・次の変数の定義値を変えることで、挙動を変更可能です: bCOMMENTHEAD_RemoveOneSpace bCOMMENTHEAD_RemoveOneTab bCOMMENTTAIL_RemoveOneSpace bCOMMENTTAIL_RemoveOneTab [変更履歴] 2014/05/24 case "xxx" 追加:awk, def, dpr,pas, sql,plsql case "psp" 変更:"#"→"--" case "tex" :ブロック型(?)追加 タイプ別設定によりコメント文字列を変える。 選択範囲の最大行数制限を廃止。 ReplaceAll()→InsText()に。 処理手法を全面変更。(拡張子により正規表現エラーが出るのも修正。) 2009/04/15 新規 */ // bCOMMENTHEAD_RemoveOneSpace:(行型コメント、ブロック型コメントに作用) // true :"//"、"/*" の後にスペース1文字が存在すれば、そのスペース1文字も削除します。 // false :"//"、"/*" の後にスペース1文字が存在しても、そのスペースは削除されません。 // bCOMMENTHEAD_RemoveOneTab :(行型コメント、ブロック型コメントに作用) // true :"//"、"/*" の後にタブ1文字が存在すれば、そのタブ1文字も削除します。 // false :"//"、"/*" の後にタブ1文字が存在しても、そのタブは削除されません。 // bCOMMENTHEAD_RemoveOneSpace と bCOMMENTHEAD_RemoveOneTab が true の場合: // "// " または "//\t" または "//" を削除します。 // "/* " または "/*\t" または "/*" を削除します。 // bCOMMENTHEAD_RemoveOneSpace と bCOMMENTHEAD_RemoveOneTab が false の場合: // "//" のみを削除します。"//" の後のスペースやタブは削除されません。 // "/*" のみを削除します。"/*" の後のスペースやタブは削除されません。 // // bCOMMENTTAIL_RemoveOneSpace:(ブロック型コメントに作用) // true :"*/" の前にスペース1文字が存在すれば、そのスペース1文字も削除します。 // false :"*/" の前にスペース1文字が存在しても、そのスペースは削除されません。 // bCOMMENTTAIL_RemoveOneTab :(ブロック型コメントに作用) // true :"*/" の前にタブ1文字が存在すれば、そのタブ1文字も削除します。 // false :"*/" の前にタブ1文字が存在しても、そのタブは削除されません。 // bCOMMENTTAIL_RemoveOneSpace と bCOMMENTTAIL_RemoveOneTab が true の場合: // " */" または "\t*/" または "*/" を削除します。 // bCOMMENTTAIL_RemoveOneSpace と bCOMMENTTAIL_RemoveOneTab が false の場合: // "*/" のみを削除します。"*/" の前のスペースやタブは削除されません。 var bCOMMENTHEAD_RemoveOneSpace = true; var bCOMMENTHEAD_RemoveOneTab = false; var bCOMMENTTAIL_RemoveOneSpace = true; var bCOMMENTTAIL_RemoveOneTab = false; //2014/05/24 選択範囲の最大行数制限を廃止。 // // メッセージボックスのタイトル。 // var CAPTION = Editor.ExpandParameter("$M"); // $M=マクロ名(フルパス)。 // CAPTION = CAPTION.substring( CAPTION.lastIndexOf("\\") + 1 ); // ファイル名部分の取り出し。 // // メッセージボックスを出すのにWshShell.Popup()を使用する。 // // 書式(MSDNのWSHより): intButton = WshShell.Popup(strText,[nSecondsToWait],[strTitle],[nType]) // var WshShell = new ActiveXObject("WScript.shell"); // // 選択範囲の最大行数。(安全の為、制限する。) // var nMAX_LINES = 50; //-------------- // メイン Main(); function Main() { var sExt; // ファイル名の拡張子。(ピリオドを含まない) var sTypeExtAry; // 現在適用されているタイプ別設定の拡張子。(「基本」は除く) var sKey, sTypeExt; var sCmntAry; // 各種コメント。(配列。要素の最後にカンマOK) var sHeadPlus, sTailPlus; // "//" "/*" の後や "*/" の前のスペースやタブ1文字。 var sLine, sBlock; // 行型コメント、ブロック型コメント。 var nGroup; // 正規表現のグループ数。("(...)" の数) var i; var head, tail; var sFrom; // 置換前 正規表現文字列。 var sTo; // 置換後 正規表現文字列。 //2014/05/24 ReplaceAll()→InsText()に変更。 // var bits; // 置換ダイアログの状態。 var sSrc; // 選択文字列。 var sDst; // 処理後の文字列。 // エディタがビューモード(読み取り専用)なら終了。 if( Editor.ExpandParameter("${R?読専$:$:$}") == "読専" ) return; // ファイル名の拡張子に応じてコメント文字列を変える。 sExt = Editor.ExpandParameter("$f").replace( /^(.*\.|.*)/, "" ).toLowerCase(); //2014/05/24 タイプ別設定によりコメント文字列を変える。 // 現在適用されているタイプ別設定(タイプ別設定の一時適用)に対応。 // ファイル名の拡張子より優先させる。(但し「基本」のタイプ別設定は除く。) // 例1: .logファイル(「テキスト」「TeX」に登録)で、「TeX」を一時適用。 // → 拡張子を "tex" に。 // 例2: .logファイルで、「基本」を一時適用。 // → 拡張子は "log" のまま。(「基本」は除く。) // IsSameTypeExt("xxx",""):拡張子 "xxx" がタイプ別設定「基本」かを調べる。 // タイプ別設定に登録されていない拡張子は「基本」扱いになるので // "xxx" が「基本」(未登録)なら1、「基本」以外なら0が返る(はず)。 sTypeExtAry = [ // デフォルト。 "txt", "c", "html", "sql", "cbl", "java", "asm", "awk", "bat", "dpr", "tex", "cgi", "bas", "rtf", "ini", // ユーザーが追加。(拡張子が未登録(=「基本」)なら無視される。) "mac", "ppa", "js", ]; for( sKey in sTypeExtAry ){ sTypeExt = sTypeExtAry[ sKey ]; if( (Editor.IsCurTypeExt( sTypeExt )) && (!Editor.IsSameTypeExt( sTypeExt, "" )) ){ sExt = sTypeExt.toLowerCase(); break; } } // 拡張子毎のコメント文字列。(case "xxx" のxxxは必ず小文字で。) // 書式:(行型、ブロック型の順は不問) // sCmntAry = [ // // 行型 // "//", ←文字列。 // // ブロック型 // [ "/*", "*/" ], ←文字列の配列。[ "開始", "終了" ] の順。 // ]; switch( sExt ){ case "asm": case "def": case "ini": case "inf": case "reg": case "wsh": sCmntAry = [ ";", ]; break; case "asp": case "wsf": sCmntAry = [ "'", "rem", "//", [ "/*", "*/" ], [ "" ], ]; break; case "aspx": sCmntAry = [ "//", // "'", // VBを使う場合はアンコメントして下さい。 // "rem", [ "/*", "*/" ], [ "" ], [ "<%--", "--%>" ], ]; break; case "awk": case "cgi": case "conf": case "pl": case "pm": case "pls": sCmntAry = [ "#", ]; break; case "bat": case "cmd": sCmntAry = [ "rem", ]; break; case "dpr": case "pas": sCmntAry = [ "//", [ "{", "}" ], [ "(*", "*)" ], ]; break; case "hta": case "html": case "htm": case "shtml": case "shtm": case "sht": case "xhtml": case "xhtm": case "xht": sCmntAry = [ "//", [ "/*", "*/" ], [ "" ], ]; break; case "jsp": case "jspf": sCmntAry = [ "//", [ "/*", "*/" ], [ "" ], [ "<%--", "--%>" ], ]; break; case "mac": case "ppa": sCmntAry = [ "//", ]; break; case "php": sCmntAry = [ "#", "//", [ "/*", "*/" ], [ "" ], ]; break; case "psp": sCmntAry = [ "--", [ "" ], [ "<%--", "--%>" ], ]; break; case "sql": case "plsql": sCmntAry = [ "--", ]; break; case "tex": sCmntAry = [ "%", [ "\\begin{comment}", "\\end{comment}" ], ]; break; case "vb": case "bas": case "cls": case "frm": case "vbs": sCmntAry = [ "'", "rem", ]; break; case "xml": sCmntAry = [ [ "" ], ]; break; case "": default: // C/C++スタイルのコメント。 sCmntAry = [ // 行型 "//", // ブロック型 [ "/*", "*/" ], ]; break; } // 記号類を全てバックスラッシュエスケープする。 for(i=0; i < sCmntAry.length; i++){ if( sCmntAry[i] == undefined ) continue; // 配列の最後に "," を置いた等 if( typeof sCmntAry[i] == "string" ){ sCmntAry[i] = sCmntAry[i].replace( /\W/g, "\\" + "$&" ); }else{ sCmntAry[i][0] = sCmntAry[i][0].replace( /\W/g, "\\" + "$&" ); sCmntAry[i][1] = sCmntAry[i][1].replace( /\W/g, "\\" + "$&" ); } } sHeadPlus = ""; if( bCOMMENTHEAD_RemoveOneSpace ) sHeadPlus += " "; if( bCOMMENTHEAD_RemoveOneTab ) sHeadPlus += "\\t"; if( sHeadPlus != "" ) sHeadPlus = "[" + sHeadPlus + "]?"; // 例:"[ ]?" sTailPlus = ""; if( bCOMMENTTAIL_RemoveOneSpace ) sTailPlus += " "; if( bCOMMENTTAIL_RemoveOneTab ) sTailPlus += "\\t"; if( sTailPlus != "" ) sTailPlus = "[" + sTailPlus + "]?"; // 例:"[ \t]?" // ブロック型を優先させてみる。(ブロック型の内側にある行型は処理されない。) // ブロック型も行型も、開始は行頭(空白類は許可)とする。 // 概念: // /Block|Block|...|Block|Line|Line|...|Line/igm // 例: // /^(\s*) // (?: \/\*[ ]?([\s\S]*?)[ ]?\*\/ :ブロック型 /* */ // | :ブロック型 // | <%--[ ]?([\s\S]*?)[ ]?--%> :ブロック型 <%-- --%> // | \/\/[ ]? :行型 // // | '[ ]? :行型 ' (アポストロフィ) // | rem(?=\b)[ ]? :行型 rem (remの直後は単語境界とする) // ) // /igm // 補足:remの直後の文字 // 通常remの直後には空白類を置くが、コマンドプロンプトでは . や = など使用可能な // 記号もあれば、# や ? など使用不可のものもある。(VBSでは記号類は使用可能の模様。) sLine = sBlock = ""; nGroup = 1; // nGroup=1+(ブロック型の個数) for(i=0; i < sCmntAry.length; i++){ switch( typeof sCmntAry[i] ){ case "string": // 行型コメント sLine += sCmntAry[i] + ((sCmntAry[i].match( /^rem$/i )) ? "(?=\\b)":"") + sHeadPlus + "|"; break; case "object": // ブロック型コメント (objectは配列と仮定) sBlock += sCmntAry[i][0] + sHeadPlus + "([\\s\\S]*?)" + sTailPlus + sCmntAry[i][1] + "|"; nGroup++; break; //case "undefined": // 配列の最後に "," を置いた等 default: break; } } if( (sLine == "") && (sBlock == "") ) return; // 一応。 sFrom = "^(\\s*)(?:" + (sBlock + sLine).slice( 0, -1 ) + ")"; //slice():最後の "|" を消す。 sTo = ""; for(i=1; i <= nGroup; i++) sTo += "$" + i; SelectLinesOnSelectedRange(); sSrc = Editor.GetSelectedString(0); sDst = sSrc.replace( new RegExp( sFrom, "igm" ), sTo ); if( sSrc == sDst ){ // 変化が無ければ変更しない。 if( Editor.IsTextSelected() != 0 ) Editor.Left(); // 範囲選択開始行の先頭へ。(非EOF行) Editor.CancelMode(); if( "StatusMsg" in Editor ) Editor.StatusMsg("(No change)"); //おまけ(sakura:2.1.0.0以降) return; } Editor.InsText( sDst ); Editor.ReDraw(); } //-------------------------------------------------------------- // カーソル行(非選択時) または 選択範囲の行すべてを範囲選択する。 // 選択範囲の開始桁、終了桁は行の途中でも可。(行全体を選択していなくても可。) // EOFのみの行(行番号が表示されない行)だと何も選択されない(非選択状態)。 // 戻り値:true=成功 / false=メッセージボックスでCancel function SelectLinesOnSelectedRange() { var nIsTextSelected; var row1, row2, col2; var y1, y2, x2; //2014/05/24 選択範囲の最大行数制限を廃止。 // var ans; nIsTextSelected = Editor.IsTextSelected(); if( nIsTextSelected == 0 ){ // カーソルのある行を1行選択。 Editor.SelectLine(0); }else{ // 選択範囲の開始行(の行頭)から終了行(の行末)までを選択。 row1 = Editor.GetSelectLineFrom(); // 選択開始行(折り返し単位) row2 = Editor.GetSelectLineTo(); // 選択終了行(折り返し単位) col2 = Editor.GetSelectColmTo(); // 選択終了桁(折り返し単位) // 選択状態の取り消し。(範囲選択開始(F6)、矩形範囲選択開始(Shift+F6)の取り消し。) Editor.CancelMode(); // 選択開始行の行頭(改行単位)へ移動。 Editor.Jump( row1, 0 ); // 折り返し単位 Editor.GoLineTop( 1<<3|1<<0 ); // 行頭(改行単位) y1 = Editor.ExpandParameter("$y") -0; // 行位置(改行単位)、文字列→数値 // 範囲選択開始。 Editor.BeginSelect(); // 選択終了行の、次の行の行頭へ移動。 Editor.Jump( row2, 0 ); // 折り返し単位 y2 = Editor.ExpandParameter("$y") -0; // 行位置(改行単位)、文字列→数値 x2 = Editor.ExpandParameter("$x") -0; // 桁位置(改行単位)、文字列→数値 if( (nIsTextSelected != 2) && ((col2 == 1) && (x2 == 1)) // 選択終了位置は行頭(改行単位)だった。 && (Editor.GetSelectLineTo() >= row2) // 最終行選択や、選択開始行=終了行だと偽。 ){ //y2 = y2; そのまま。 }else{ y2++; // 選択終了行の行末まで(次の行の行頭まで)を選択。(EOF行なら最後まで。) } Editor.Jump( y2, 1 ); // 改行単位 // 範囲選択終了 しておく。 Editor.BeginSelect(); //2014/05/24 選択範囲の最大行数制限を廃止。 // // 選択範囲の最大行数。(安全の為、制限する。) // if( y2 - y1 > nMAX_LINES ){ // ans = WshShell.Popup( // "選択範囲が多すぎます。\n" + // "安全のため、最大 " + nMAX_LINES + " 行に制限しています。\n\n" + // "続けますか?", 0, CAPTION, // 1|48|256 ); // 1=MB_OKCANCEL, 48=MB_ICONEXCLAMATION, 256=MB_DEFBUTTON2 // if( ans != 1 ){ // 1=IDOK // //Editor.CancelMode(); とりあえず選択したまま。 // return false; // } // } } return true; }