Last active
April 6, 2018 17:22
-
-
Save cat2151/495854927eaffe0e50556a5738a06b59 to your computer and use it in GitHub Desktop.
サクラエディタ用マクロ Eclipse風コメントアウト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* @file commentOutEclipseLike.js | |
* @brief 選択範囲、もしくはカーソル行をコメントアウト/アンコメントするサクラエディタマクロ | |
* @author cat2151 | |
* | |
* phodra氏作成の同様のマクロを改変したもの。 | |
* http://sakura-editor.sourceforge.net/cgi-bin/cyclamen/cyclamen.cgi?log=macro&tree=c591 | |
* | |
* ・コメントアウト行を選択した場合はアンコメント。そうでない場合はコメントアウト。 | |
* ・クイックハックなのでリファクタリング不足。 | |
*/ | |
if(!String.prototype.trim) { | |
String.prototype.trim = function () { | |
return this.replace(/^\s+|\s+$/g,''); | |
}; | |
} | |
toggleCommentOut(); | |
// コメントアウトをトグルで行う | |
// 選択時は選択範囲の先頭行の行頭、それ以外は現在行の行頭、にコメントステートメントがあればアンコメント、それ以外はコメントアウトする | |
function toggleCommentOut() { | |
// エディタがビューモード(読み取り専用)なら終了。 | |
if( Editor.ExpandParameter("${R?読専$:$:$}") == "読専" ) return; | |
// 拡張子別にコメントステートメントを定義 | |
var comment = new Array(); | |
comment["cpp"] = "//"; comment["c"] = "//"; comment["h"] = "//"; comment["nut"] = "//"; | |
comment["js"] = "//"; comment["java"] = "//"; | |
comment["php"] = "//"; comment["uws"] = "//"; | |
comment["mac"] = "//"; comment["ppa"] = "//"; | |
comment["vbs"] = "'"; comment["bas"] = "'"; comment["frm"] = "'"; | |
comment["cls"] = "'"; comment["vb"] = "'"; | |
comment["cgi"] = "#"; comment["pl"] = "#"; comment["pm"] = "#"; comment["sh"] = "#"; | |
comment["asm"] = ";"; comment["ini"] = ";"; comment["inf"] = ";"; comment["s"] = ";"; | |
comment["cnf"] = ";"; comment["conf"] = ";"; | |
comment["tex"] = "%"; | |
comment["cmd"] = "REM "; | |
comment["bat"] = "REM "; | |
comment["txt"] = " "; comment["noext"] = " "; | |
// 拡張子を切り出し | |
var fname = Editor.ExpandParameter("$f"); | |
var ext = fname.substring( fname.lastIndexOf(".") + 1); | |
ext = ext==fname? "noext": ext.toLowerCase(); | |
// 登録されていない拡張子であれば終了。 | |
if( comment[ext] == null ) return; | |
// 選択範囲の先頭行または、現在行を取得(コメントアウトされているかどうかの判断用) | |
{ | |
var selmode = Editor.IsTextSelected(); | |
var fromLineNum, toLineNum; | |
var isComment = false; | |
if( selmode ){ // 選択状態 | |
// コメントアウトされているか判断 | |
isComment = !containsCodeOrContainsOnlySpace(comment, ext); | |
}else{ // 選択していない | |
// ロジック座標を取得 | |
fromLineNum = parseInt(Editor.ExpandParameter("$y")); | |
// コメントアウトされているか判断 | |
if (GetLineStr(fromLineNum).trim().substring(0, comment[ext].length) == comment[ext]) isComment = true; | |
} | |
if (isComment){ // コメントアウトされている | |
unComment(comment); | |
} else { // コメントアウトされていない | |
commentOut(comment); | |
} | |
} | |
} | |
function containsCodeOrContainsOnlySpace(comment, ext) { | |
// レイアウト座標を取得 | |
var lay_fl = Editor.GetSelectLineFrom(); | |
var lay_tl = Editor.GetSelectLineTo(); | |
// レイアウト座標をロジック座標に変換 | |
// ExpandParameterではカーソル位置しか分からないので…… | |
fromLineNum = Editor.LayoutToLogicLineNum( lay_fl ); | |
toLineNum = Editor.LayoutToLogicLineNum( lay_tl ); | |
var numOfComments = 0; | |
for (var i = fromLineNum; i < toLineNum; i++) { | |
// 行頭空白をとりのぞき、文字列Aを得る | |
var strA = GetLineStr(i).trim(); | |
// 文字列Aが空の場合、空行とみなし、チェック対象外とする | |
if (strA == "") continue; | |
if (strA.substring(0, comment[ext].length) != comment[ext]) { | |
// コード行の場合、つまり文字列Aの先頭がコメントステートメント以外の場合 | |
return true; | |
} | |
numOfComments++; | |
} | |
// すべて空行の場合 | |
if (!numOfComments) return true; | |
// コード行がなく、コメント行が1行以上ある場合 | |
return false; | |
} | |
// コメントアウト | |
function commentOut(comment) { | |
// 拡張子を切り出し | |
var fname = Editor.ExpandParameter("$f"); | |
var ext = fname.substring( fname.lastIndexOf(".") + 1); | |
ext = ext==fname? "noext": ext.toLowerCase(); | |
// 登録されていない拡張子であれば終了。 | |
if( comment[ext] == null ) return; | |
// ちらつき防止 | |
Editor.SetDrawSwitch(0); | |
// 選択モード(この変数は復元する際にも使用する) | |
var selmode = Editor.IsTextSelected(); | |
if( selmode ){ // 選択状態 | |
// レイアウト座標を取得 | |
var lay_fl = Editor.GetSelectLineFrom(); | |
var lay_tl = Editor.GetSelectLineTo(); | |
// レイアウト座標をロジック座標に変換 | |
// 選択位置のロジック座標を取得する関数はない? | |
var fl = Editor.LayoutToLogicLineNum( lay_fl ); | |
var tl = Editor.LayoutToLogicLineNum( lay_tl ); | |
var fc = Editor.LineColumnToIndex( lay_fl, Editor.GetSelectColmFrom() ); | |
var tc = Editor.LineColumnToIndex( lay_tl, Editor.GetSelectColmTo() ); | |
// 行選択でマクロに入った場合、一つ上の行までにする | |
var endl = tc==1? tl-1: tl; | |
// 範囲内の行を配列としてとる | |
var lines = new Array(); | |
var str = ""; | |
for( var i=fl; i<=endl; i++ ){ | |
str = Editor.GetLineStr(i) | |
lines.push( comment[ext] + str ); | |
} | |
// 必要な範囲を行選択 | |
Editor.MoveCursor( fl, 1, 0); | |
Editor.MoveCursor( endl, str.length+1, 1); | |
// 選択範囲を上書き | |
Editor.InsText( lines.join("") ); | |
// 選択範囲を復元 | |
Editor.MoveCursor( fl, fc+comment[ext].length, 0); | |
Editor.MoveCursor( tl, tc==1? tc: tc+comment[ext].length, selmode); | |
}else{ // 選択していない | |
// ロジック座標を取得 | |
// 選択範囲がないのでレイアウトから変換する必要はない | |
var l = parseInt(Editor.ExpandParameter("$y")); | |
var c = parseInt(Editor.ExpandParameter("$x")); | |
// 行頭に移動 | |
Editor.MoveCursor( l, 1, 0); | |
// コメントステートメントを挿入 | |
Editor.InsText(comment[ext]); | |
// 位置を復元 | |
Editor.MoveCursor( l, c+comment[ext], selmode); | |
} | |
// 描画フラグを戻してから再描画 | |
Editor.SetDrawSwitch(1); | |
Editor.ReDraw(0); | |
} | |
// アンコメント | |
function unComment(comment) { | |
//拡張子を切り出し | |
var fname = Editor.ExpandParameter("$f"); | |
var ext = fname.substring( fname.lastIndexOf(".") + 1); | |
ext = ext==fname? "noext": ext.toLowerCase(); | |
// 登録されていない拡張子であれば終了。 | |
if( comment[ext] == null ) return; | |
// ちらつき防止 | |
Editor.SetDrawSwitch(0); | |
// 置換対象にする部分の正規表現 | |
// なぜかエスケープしないといけない | |
var uncmt = new RegExp("\(\^\\s\*\?\)" + comment[ext]); | |
// 選択モード(この変数は復元する際にも使用する) | |
var selmode = Editor.IsTextSelected(); | |
if( selmode ){ // 選択状態 | |
// レイアウト座標を取得 | |
var lay_fl = Editor.GetSelectLineFrom(); | |
var lay_tl = Editor.GetSelectLineTo(); | |
// レイアウト座標をロジック座標に変換 | |
// 選択位置のロジック座標を取得する関数はない? | |
var fl = Editor.LayoutToLogicLineNum( lay_fl ); | |
var tl = Editor.LayoutToLogicLineNum( lay_tl ); | |
var fc = Editor.LineColumnToIndex( lay_fl, Editor.GetSelectColmFrom() ); | |
var tc = Editor.LineColumnToIndex( lay_tl, Editor.GetSelectColmTo() ); | |
// 行選択でマクロに入った場合、一つ上の行までにする | |
var endl = tc==1? tl-1: tl; | |
// 範囲内の行を配列としてとる | |
var lines = new Array(); | |
var reped = new Array(); | |
var str = ""; | |
var cnt = 0; | |
for( var i=fl; i<=endl; i++ ){ | |
str = Editor.GetLineStr(i); | |
var rep = str.replace( uncmt, "$1" ); | |
lines.push( str ); | |
reped.push( rep ); | |
if( str == rep ) cnt++; | |
} | |
// 処理していない行が全体の行数に等しいときは何もしない | |
if( cnt < reped.length ){ | |
// 必要な範囲を行選択 | |
Editor.MoveCursor( fl, 1, 0); | |
Editor.MoveCursor( endl, str.length+1, 1); | |
// 選択範囲を上書き | |
Editor.InsText( reped.join("") ); | |
// 範囲復元時のX位置 | |
// コメントステートメントより後ならコメントステートメントの字数分ずらす | |
// コメントステートメントの中ならコメントステートメントが現れた位置 | |
// コメントステートメントより前ならそのままの位置 | |
var idx = lines[0].indexOf( comment[ext] ); | |
var gap_f = | |
fc>idx+comment[ext].length? fc-comment[ext].length: | |
fc>idx+1? idx+1: | |
fc; | |
idx = lines[lines.length-1].indexOf( comment[ext] ); | |
var gap_t = | |
tc>idx+comment[ext].length? tc-comment[ext].length: | |
tc>idx+1? idx+1: | |
tc; | |
// 選択範囲を復元 | |
Editor.MoveCursor( fl, gap_f, 0); | |
Editor.MoveCursor( tl, gap_t, selmode); | |
} | |
}else{ // 選択していない | |
// ロジック座標を取得 | |
// 選択範囲がないのでレイアウトから変換する必要はない | |
var l = parseInt(Editor.ExpandParameter("$y")); | |
var c = parseInt(Editor.ExpandParameter("$x")); | |
// 対象行の文字列を取得 | |
var str = Editor.GetLineStr(l); | |
// コメントステートメントを除去した文字列 | |
var rep = str.replace( uncmt, "$1" ); | |
if( str != rep ){ | |
// 行選択 | |
Editor.MoveCursor( l, 1, 0); | |
Editor.MoveCursor( l, str.length+1, 1); | |
// 置換した文字列で上書き | |
Editor.InsText( rep ); | |
// 復元時のカーソルX位置 | |
// コメントステートメントより後ならコメントステートメントの字数分ずらす | |
// コメントステートメントの中ならコメントステートメントが現れた位置 | |
// コメントステートメントより前ならそのままの位置 | |
var idx = str.indexOf( comment[ext] ); | |
var gap = | |
c>idx+comment[ext].length? c-comment[ext].length: | |
c>idx+1? idx+1: | |
c; | |
// カーソル位置を復元 | |
Editor.MoveCursor( l, gap, selmode); | |
} | |
} | |
// 描画フラグを戻してから再描画 | |
Editor.SetDrawSwitch(1); | |
Editor.ReDraw(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment