「Eclipse風コメントアウト(改)」の版間の差分
ナビゲーションに移動
検索に移動
(→概要) |
(→概要) |
||
3行目: | 3行目: | ||
ksさんの作成された、[[Eclipse風コメントアウト]]は、私にとって欠かせないツールです。 | ksさんの作成された、[[Eclipse風コメントアウト]]は、私にとって欠かせないツールです。 | ||
便利に使わせていただく一方、細かい挙動が気になって変更したり、機能を追加しているうちに、すっかり別物になってしまいました。 | 便利に使わせていただく一方、細かい挙動が気になって変更したり、機能を追加しているうちに、すっかり別物になってしまいました。 | ||
ksさんに感謝するとともに、せっかく作成したので、ここに公開します。 | ksさんに感謝するとともに、せっかく作成したので、ここに公開します。 | ||
なお、SHIFTキーの状態を取得したかったのですが、スクリプトからは難しかったので、別途実行ファイルを作成しました。 | なお、SHIFTキーの状態を取得したかったのですが、スクリプトからは難しかったので、別途実行ファイルを作成しました。 | ||
zipファイルを展開して、Macrosフォルダーに配置してください。 | zipファイルを展開して、Macrosフォルダーに配置してください。 | ||
コマンドライン引数で、"shift" "ctrl" "alt" を指定すると、そのキーの押下状態を取得できるので、他のマクロからもご利用いただけます。 | コマンドライン引数で、"shift" "ctrl" "alt" を指定すると、そのキーの押下状態を取得できるので、他のマクロからもご利用いただけます。 | ||
2019年3月4日 (月) 17:08時点における版
概要
Eclipse風なコメントアウト <=> コメントの除去を行います。
ksさんの作成された、Eclipse風コメントアウトは、私にとって欠かせないツールです。
便利に使わせていただく一方、細かい挙動が気になって変更したり、機能を追加しているうちに、すっかり別物になってしまいました。
ksさんに感謝するとともに、せっかく作成したので、ここに公開します。
なお、SHIFTキーの状態を取得したかったのですが、スクリプトからは難しかったので、別途実行ファイルを作成しました。
zipファイルを展開して、Macrosフォルダーに配置してください。
コマンドライン引数で、"shift" "ctrl" "alt" を指定すると、そのキーの押下状態を取得できるので、他のマクロからもご利用いただけます。
ソースも置いときます(VS2005 C++)
更新履歴
2018/3/4 新規作成
コード
#title = "選択行コメントアウト"
// -----------------------------------------------------------------------------
// Eclipse風なコメントアウト
// 複数行一括コメントアウト,復帰マクロ
// 1) 対象は行全体(行途中の選択も行全体とみなす)
// 2) 空白行はコメントアウトしない
// 3) インデントは選択行の範囲で一番左(タブ幅単位)に合わせる
// 4) 選択範囲全体がコメントアウトされている場合は復帰
//
// Copyright (c) ks. All Rights Reserved.
// www: http://merysmacro.seesaa.net/
// -----------------------------------------------------------------------------
// a) 最終行の先頭までの選択状態では、最終行は処理範囲外にする(行選択対応)
// b) コメント文字の種類を追加(Mery標準で単一行コメント可能な編集モード全て対応)
// c) スペースが含まれるコメント文字に対応
// d) コメント文字が正規表現文字でも正しく動作するようにした
// e) コメント文字不明時、SHIFTキー押下起動時はコメント文字を入力できるようにした
// (Mery.iniと同じ場所に設定ファイルとして一時記憶)
// f) 選択方向を維持するようにした(下から上への選択対応)
// g) 空白行で実行するとUndoされてしまう問題に対処
// h) OutputBarにフォーカスがある場合に処理できない問題に対処
//
// SHIFTキー状態取得のために、"GetKeyState.exe"が必要です
//
// Improved by pizz
// -----------------------------------------------------------------------------
var doc = editor.ActiveDocument;
var COM = ""; // 単一行コメント
var settingFilename = "CommentMacro.ini";
switch(doc.Mode.toLowerCase()){
case "bat":
COM = "rem ";
break;
case "c#":
case "c++":
case "coldfusion":
case "delphi":
case "java":
case "javascript":
case "jsp":
case "php":
case "uwsc":
COM = "// ";
break;
case "hsp":
case "ini":
case "x86 assembler":
COM = "; ";
break;
case "perl":
case "perlscript":
case "powershell":
case "python":
case "rhtml":
case "ruby":
COM = "# ";
break;
case "sql":
COM = "-- ";
break;
case "tex":
COM = "% ";
break;
case "vbscript":
case "visualbasic":
COM = "'";
break;
}
var wshShell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");
// カレントディレクトリをマクロディレクトリに変更
wshShell.CurrentDirectory = editor.FullName.match(/^.*\\/)[0] + 'Macros';
// 設定ファイルからコメント文字を読み込む
var comSelected = LoadDocSetting();
if(comSelected == "") comSelected = COM;
var comTrim = comSelected.replace(/(^\s+)|(\s+$)/g, ""); // スペースなしのコメント文字
// SHIFTキー状態を取得
var shift = wshShell.Run("GetKeyState.exe shift", 0, true);
if(shift == -1) window.Quit();
// コメント文字の入力を受ける
if(comTrim == "" || shift == 1){
var comInput = "// ";
if(comTrim != "") comInput = comSelected;
comInput = prompt("コメント文字を指定してください", comInput);
comTrim = comInput.replace(/(^\s+)|(\s+$)/g, ""); // スペースなしのコメント文字
if(comTrim == "") window.Quit();
if(comInput != comSelected){
SaveDocSetting(comInput);
comSelected = comInput;
}
}
var meGetLineLogical = 0;
var regOrg = new RegExp("^[ \\t]*" + comSelected.replace(/\W/g, "\\$&"));
var regTrim = new RegExp("^[ \\t]*" + comTrim.replace(/\W/g, "\\$&"));
var scrollY = window.ScrollY;
var sel = doc.Selection;
var st = sel.GetTopPointY(mePosLogical);
var ed = sel.GetBottomPointY(mePosLogical);
var ac = sel.GetActivePointY(mePosLogical);
if(st != ed && sel.GetBottomPointX(mePosLogical) == 1){
// 複数行選択、最下行選択位置が行頭の場合は、最終行は除外
ed--;
}
var tab = GetTabSpace();
sel.SetActivePoint(mePosLogical, doc.GetLine(ed, meGetLineLogical).length + 1, ed);
sel.SetAnchorPoint(mePosLogical, 1, st);
var lines = sel.Text.split("\n")
if(sel.Text.length > 0) sel.Untabify();
var linesWithoutTab = sel.Text.split("\n");
if(sel.Text.length > 0) doc.Undo();
// インデント取得
var indent = -1;
var existNotCommentLine = false; // 空白・コメント行でない行が存在するか
for(var i=0, len = linesWithoutTab.length; i < len; i++){
var line = linesWithoutTab[i];
var left = line.search(/[^ ]/);
if(left >= 0 && (indent < 0 || left < indent)){
// インデントはタブ幅単位(左寄せ)
indent = Math.floor(left / tab) * tab;
}
if(left >= 0){
// コメント行判定
if(!existNotCommentLine && line.search(regTrim) == -1){
existNotCommentLine = true;
}
}
}
var txt = "";
var changed = false;
if(existNotCommentLine){
// コメントアウト
for(var i = 0, len = lines.length; i < len; i++){
var line = lines[i] + "\n";
// 空白行はコメントアウトしない
if(line.search(/[^ \t\n]/) == -1){
txt += line;
continue;
}
// 挿入位置をタブと空白を考慮して決定
var index = 0, j;
for(j = 0; index < indent; j++){
// indent の範囲には半角スペースかタブしかない
if(line.charAt(j) == " "){
index += 1;
}else{
index += tab - (index % tab);
}
}
txt += line.substring(0, j) + comSelected + line.substring(j);
changed = true;
}
}else{
// コメントから復帰
for(var i = 0, len = lines.length; i < len; i++){
var line = lines[i] + "\n";
if(line.match(regTrim)){
if(line.match(regOrg)){
txt += line.replace(comSelected, ""); // 先頭のコメント(空白付き)の削除
}else{
txt += line.replace(comTrim, ""); // 先頭のコメント(空白なし)の削除
}
changed = true;
}else{
txt += line;
}
}
}
// コメントアウト部分を書き換えて,全体を選択
if(doc.GetLine(ed + 1, meGetLineWithNewLines) == "") txt = txt.substring(0, txt.length - 1); // 最後の改行は除去
if(ac == st){
// 下から上への選択状態
sel.SetActivePoint(mePosLogical, 1, st);
sel.SetAnchorPoint(mePosLogical, 1, ed + 1);
if(changed) sel.Text = txt;
sel.SetActivePoint(mePosLogical, 1, st);
sel.SetAnchorPoint(mePosLogical, 1, ed + 1);
}else{
// 上から下への選択状態
sel.SetActivePoint(mePosLogical, 1, ed + 1);
sel.SetAnchorPoint(mePosLogical, 1, st);
if(changed) sel.Text = txt;
sel.SetAnchorPoint(mePosLogical, 1, st);
}
window.ScrollY = scrollY;
//========================================
// 関数
//========================================
// タブ幅を取得
function GetTabSpace()
{
var doc = editor.ActiveDocument;
var sel = doc.Selection;
var saved = doc.Saved;
sel.EndOfDocument();
doc.Write("\n\t");
sel.SetAnchorPoint(mePosLogical, sel.GetActivePointX(mePosLogical) - 1, sel.GetActivePointY(mePosLogical));
sel.Untabify();
var n = sel.Text.length;
doc.Undo(); doc.Undo();
doc.Saved = saved
return n;
}
// コメント文字設定をファイルから読み込み
function LoadDocSetting()
{
var dic = LoadDocSettingDataListWithOpend();
var ret = "";
for(var key in dic){
if(key.toLowerCase() == window.document.FullName.toLowerCase()){
ret = dic[window.document.FullName.toLowerCase()];
}
}
return ret;
}
// コメント文字設定をファイルに書き込み
function SaveDocSetting(comStr)
{
var dic = LoadDocSettingDataListWithOpend();
dic[window.document.FullName.toLowerCase()] = comStr;
SaveDocSettingDataListWithOpend(dic);
}
// 設定ファイルから全ての設定値を取得
function LoadDocSettingDataListWithOpend()
{
var settingPath = GetSettingFilePath();
var dic = {};
var deleted = false;
if(fso.FileExists(settingPath)){
var tso = fso.OpenTextFile(settingPath, 1, false, -1);
while(tso.AtEndOfStream == false){
var setting = tso.ReadLine().split("\t", 2);
var detect = false;
for(var i = 0; i < window.Editors.Count; i++){
for(var j = 0; j < window.Editors.Item(i).Documents.Count; j++){
if(window.Editors.Item(i).Documents.Item(j).FullName.toLowerCase() == setting[0].toLowerCase()){
dic[setting[0].toLowerCase()] = setting[1];
detect = true;
break;
}
}
if(detect) break;
}
if(detect == false) deleted = true;
}
tso.Close();
}
if(deleted) SaveDocSettingDataListWithOpend(dic);
return dic;
}
// 設定ファイルを全て書き換え
function SaveDocSettingDataListWithOpend(dic)
{
var settingPath = GetSettingFilePath();
var tso = fso.OpenTextFile(settingPath, 2, true, -1);
for(var key in dic){
tso.WriteLine(key + "\t" + dic[key]);
}
tso.Close();
}
// コメント文字設定ファイルの場所を取得する
function GetSettingFilePath()
{
var meryDir = fso.GetParentFolderName(editor.FullName);
var settingPath = "";
if(fso.FileExists(fso.BuildPath(meryDir, "Mery.ini"))){
settingPath = fso.BuildPath(meryDir, settingFilename);
}else{
var appDataPath = fso.BuildPath(wshShell.SpecialFolders('Appdata'), 'Mery');
if(fso.FileExists(fso.BuildPath(appDataPath, "Mery.ini"))){
settingPath = fso.BuildPath(appDataPath, settingFilename);
}
}
if(settingPath == ""){
window.Alert("Mery.ini ファイルが見つかりません");
window.Quit();
}
return settingPath;
}
スポンサーリンク