インデントブロック作り
カーソルがある論理行の下に新しいインデントした{}ブロックを作る(挿入)。
まず開始文字列を挿入して改行、
現在行(挿入される行のすぐ上)の開始桁と揃うだけの幅の空白を追加して
終了文字列を挿入し、
その右に続けてカーソル以降の文字列を表示。
そしてその行の上に新しい行を挿入。
カーソルは前の行の開始桁より、右方向にタブ1つ幅を移動。
... {
|←カーソル
}
の形のブロックとなる。
行頭で使えば行頭がそろい
{
|←カーソル
}
の形となる。
すでにある1行または複数行をインデントブロックにする。
選択範囲が1字でもあれば、範囲の最後の行末まで選択を拡張してから、
範囲をすべてインデントブロックにする。
ブロックの最後の行に新しい行を挿入。
インデント{}ブロック作り(Shift+Ctrl+[).js
まず、My Macros フォルダに itokusu フォルダを用意。
下の内容を、上の名前のファイルにして、My Macros\itokusu に置く。
そこから Mery で開いて、マクロ - これを選択、
ツール - オプション - キーボード の マクロ で Shift+Ctrl+[ に割り当て。
ここから長くコピーしてエディタに貼り付けるのではなく、ファイルからの登録に。
※ マクロitokusuセット_01: [[ファイル:itokusu_01_120906.zip]]
逆タブ(Shift+Tab).js … 逆タブと逆インデント
インデント{}ブロック作り(Shift+Ctrl+[).js … 閉じてインデントブロック
行を選択(Ctrl+¥、F11).js … 追加の行選択
行頭から行末まで選択(Shift+Ctrl+¥、Shift+Ctrl+F11).js … 改行前選択
行の両端移動と選択解除(Ctrl+;).js … そこで解除→行末→行頭
行頭まで選択と字頭移動(Ctrl+:).js … 行頭から選択→本文の頭位置
省略記号…(Ctrl+Alt+.).js … …記号、注釈記号、注釈解除
マクロitokusuセットの使い方:
フォルダ付きで展開したら、itokusu フォルダを My Macros にコピー。
マクロ - カスタマイズ - 新規作成 で、 My Macros\itokusu フォルダ
を選択、Ctrlキーを押しながらファイル名をクリックで、登録しようと
している複数のマクロをすべて選択してから - 開く。
マクロの名前に書かれているキー(全角字は半角に読みかえて…)に、
ツール - オプション - キーボード の マクロ でそれぞれを割り当て。
// - 糸くす~------------------------------------- Copyright(C)2011-2012 inuuik -
// インデント{}ブロック作り(Shift+Ctrl+[)
//
// カーソルがある論理行の下に新しいインデントした{}ブロックを作る(挿入)。
// まず開始文字列を挿入して改行、現在行(挿入される行のすぐ上)の開始桁と揃うだ
// けの幅の空白を追加して終了文字列を挿入し、その右に続けてカーソル以降の文字
// 列を表示。そしてその行の上に新しい行を挿入。カーソルは前の行の開始桁より右
// 方向にタブ1つ幅を移動。
//
// ... {
// |←カーソル
// }
// の形のブロックとなる。
// 行頭で使うか、「行を揃いで下に新しく(Shift+Enter).js」を使えば行頭がそろい
// {
// |←カーソル
// }
// の形となる。
//
//
// 選択範囲が 1字でもあれば範囲の最後の行末まで選択を拡張してから範囲をすべて
// インデントブロックにする。ブロックの最後の行に新しい行を挿入。
//
// 選択範囲が改行以外の文字で始まるときは、文字の前から空白を削除、改行し、そ
// の文字からインデントブロックの最初の行を始める。1行に記述していたブロック
// 文を複数行のブロックに書き換えることを想定し、1行の行末に空白と終了カッコ
// があれば削除。
//
//
// 別のカッコを使うときは開始文字を入れた直後に動作させると、カーソル位置の直
// 前の1語を開始文字列として判別し、対応する終了文字列を判定する。間に空白が
// あると機能しない。
//
// 行頭がコメント文字らしきときはそれらの文字も含めて行頭に追加。追加する空白
// 文字列は現在行と同じ内容を転記して使用。
//
//
// 特殊動作として開始文字を数字とすると終了文字列を連番にした同じ形のインデン
// トブロックを挿入する。番号づけをしながら字下げをして記述を続けるなどに。連
// 番の進行で桁が増えると挿入の開始位置は同じなのでカーソル位置が右にずれる。
// 必要なら使用者が数字の頭を左に移動するなどの位置ぞろえをする。全角数字も。
//
// HTMLや XMLのタグブロックとして <タグ名> を開始文字とすると、</タグ名> の終
// 了タグを終了文字列にしたインデントブロックを挿入する。
//
// revised inuuik 2011-08-04
// revised inuuik 2012-09-02 s.NewLine(2) を自動インデントに対応調整
// - ------------------------ --------------------------------------------------
{
/*
文字列の特定文字を\x5cエスケープ
*/
if (!String.prototype.esc_x5c) {
String.prototype.esc_x5c = function() {
var esc = "";
var src = this.toString();
for (var p = 0, ch = ""; p < src.length; p++) {
ch = src.charAt(p);
switch (ch) {
case '"': ch = '\x5c"'; break; // \x5c\x22
case '$': ch = '\x5c$'; break; // \x5c\x24
case '&': ch = '\x5c&'; break; // \x5c\x26
case "'": ch = "\x5c'"; break; // \x5c\x27
case '(': ch = '\x5c('; break; // \x5c\x28
case ')': ch = '\x5c)'; break; // \x5c\x29
case '*': ch = '\x5c*'; break; // \x5c\x2a
case '+': ch = '\x5c+'; break; // \x5c\x2b
case '-': ch = '\x5c-'; break; // \x5c\x2d
case '.': ch = '\x5c.'; break; // \x5c\x2e
case '/': ch = '\x5c/'; break; // \x5c\x2f
case '?': ch = '\x5c?'; break; // \x5c\x3f
case '[': ch = '\x5c['; break; // \x5c\x5b
case "\\": ch = "\x5c\\"; break; // \x5c\x5c
case ']': ch = '\x5c]'; break; // \x5c\x5d
case '^': ch = '\x5c^'; break; // \x5c\x5e
case '|': ch = '\x5c|'; break; // \x5c\x7c
}
esc += ch;
}
return esc;
};
}
/*
文字列の全角数字と主な記号(空白と英字とカナと記号を除く)を半角に変換
引数を true にすると一致のテストのみして結果を論理値で返す
*/
if (!String.prototype.toHan_s) {
String.prototype.toHan_s = function(isTest) {
function conv_han_s(str, p1, offset, s) {
var cnv = "";
var src = p1;
for (var p = 0, ch = ""; p < src.length; p++) {
ch = src.charAt(p);
switch (ch) {
// case "\": ch = "\"; break; // 例外対応 \xff3c を 無変換 本来は \x5c (\)
case "¥": ch = "\\"; break; // 例外対応 \xffe5 を \x5c (\) 、本来は \xff3c (バックスラッシュ)
default:
ch = String.fromCharCode(ch.charCodeAt(0) - 0xfee0); break;
}
cnv += ch;
}
return cnv;
}
// var re_han_s = /([!--~¥]+)/g;
// var re_han_s = /([!-[]-~¥]+)/g;
var re_han_s = /([!-@[]-`{-~¥]+)/g;
if (! isTest) {
return this.toString().replace(re_han_s, conv_han_s);
}
else {
return re_han_s.test(this.toString());
}
};
}
/*
文字列の半角数字と主な記号(空白と英字とカナと記号を除く)を全角に変換
引数を true にすると一致のテストのみして結果を論理値で返す
*/
if (!String.prototype.toZen_s) {
String.prototype.toZen_s = function(isTest) {
function conv_zen_s(str, p1, offset, s) {
var cnv = "";
var src = p1;
for (var p = 0, ch = ""; p < src.length; p++) {
ch = src.charAt(p);
switch (ch) {
// case "\": ch = "\"; break; // 例外対応 \xff3c を 無変換 本来は \x5c (\)
case "\\": ch = "¥"; break; // 例外対応 \x5c (\) を \xffe5 (¥) 、本来は \xff3c (バックスラッシュ)
default:
ch = String.fromCharCode(ch.charCodeAt(0) + 0xfee0); break;
}
cnv += ch;
}
return cnv;
}
// var re_zen_s = /([!-~\\]+)/g;
var re_zen_s = /([!-@\[\]-`{-~\\]+)/g; // }
if (! isTest) {
return this.toString().replace(re_zen_s, conv_zen_s);
}
else {
return re_zen_s.test(this.toString());
}
};
}
var s = document.selection;
var x = s.GetActivePointX(mePosLogical);
var y = s.GetActivePointY(mePosLogical); // タブの操作は論理行で
var tx = s.GetTopPointX(mePosLogical);
var ty = s.GetTopPointY(mePosLogical);
var bx = s.GetBottomPointX(mePosLogical);
var by = s.GetBottomPointY(mePosLogical);
var t = "";
// Redraw = false;
if (!s.IsEmpty) { // 選択範囲を最終行末まで保存
s.SetAnchorPoint(mePosLogical, tx, ty);
s.SetActivePoint(mePosLogical, bx, by, true);
s.EndOfLine(true, mePosLogical);
t = s.Text.replace(/^[ \t\u3000\xa0]+/, "").replace(/\n$/, ""); // カーソル前空白と続く改行、最終改行
s.Delete(); // 選択範囲があれば削除
}
s.SetActivePoint(mePosLogical, tx, ty, false);
s.StartOfLine(true, mePosLogical); // カーソルより前で開始文字列を探す
var lp = s.Text.replace(/^.*[\s\u3000\xa0]+/, ""); // left parenthesis
var rp = ""; // right parenthesis
if (/[1-9][0-9]*$/.test(lp)) { // 特殊動作 数字で開始すると終了文字列が連番
rp = lp.replace(/[1-9][0-9]*$/, (parseInt(lp, 10) + 1).toString());
rpo = ((rpl = rp.length - lp.length) > 0 ? rp.substr(0, rpl).replace(/^0+/, "") : "");
rp = rpo + rp.substr(rpl);
lp = "";
}
else if (/[1-9][0-9]*$/.test(lp)) { // 特殊動作 全角数字で開始すると終了文字列が連番
rp = lp.replace(/[1-9][0-9]*$/, (parseInt(lp.toHan_s(), 10) + 1).toString().toZen_s());
rpo = ((rpl = rp.length - lp.length) > 0 ? rp.substr(0, rpl).replace(/^0+/, "") : "");
rp = rpo + rp.substr(rpl);
lp = "";
}
else if (/(?:<+[^<>\/]>+$)|(?:<+[^<>\/][^<>]*[^<>\/]>+$)|<+>+$/.test(s.Text)) { // 特殊動作 タグ(単一タグを除く)
rp = (lp = s.Text).replace(/(?:.*?(<+)([^ <>]*) ?[^<>]*(>+)$)|(<+)(>+)$/, "$1$4\/$2$3$5");
lp = "";
}
else { // 通常動作 すでに直前にある開始文字列から終了文字列を判定
switch (lp) {
case "{": lp = ""; rp = "}"; break;
case "(": lp = ""; rp = ")"; break;
case "[": lp = ""; rp = "]"; break;
case "<": lp = ""; rp = ">"; break;
case "begin": lp = ""; rp = "end;"; break;
case "{": lp = ""; rp = "}"; break;
case "(": lp = ""; rp = ")"; break;
case "[": lp = ""; rp = "]"; break;
case "<": lp = ""; rp = ">"; break;
case "≪": lp = ""; rp = "≫"; break;
case "「": lp = ""; rp = "」"; break;
case "『": lp = ""; rp = "』"; break;
case "〈": lp = ""; rp = "〉"; break;
case "《": lp = ""; rp = "》"; break;
case "【": lp = ""; rp = "】"; break;
case "〔": lp = ""; rp = "〕"; break;
case "<?php": lp = ""; rp = "?>"; break;
case "/*": lp = ""; rp = "*/"; break;
case "=pod": lp = ""; rp = "=cut"; break;
case ">": lp = ""; rp = "</ >"; break;
case "<!--": lp = ""; rp = "-->"; break;
case "{-": lp = ""; rp = "-}"; break;
case "{{": lp = ""; rp = "}}"; break;
case "((": lp = ""; rp = "))"; break;
case "[[": lp = ""; rp = "]]"; break;
case "<<": lp = ""; rp = ">>"; break;
default: lp = "{"; rp = "}"; break; // 通常動作 開始文字列と終了文字列に { } の対を使用
}
}
s.SetActivePoint(mePosLogical, tx, ty, false);
s.Text = lp; // ブロックの開始文字列
// s.LineOpen(false); // ←折り返し表示をしていると挿入位置を上方向に誤る
// 現在行の下にカーソル桁位置以降の文字列を含む新しい行を挿入
s.NewLine(1);
s.StartOfLine(true, mePosLogical);
if (!s.IsEmpty) {
s.Text = "";
}
s.NewLine(1);
// s.LineUp(false, 1); // ←mePosLogicalとの併用だと分割表示で予期の動作をしない
s.SetActivePoint(mePosLogical, 1, (s.GetActivePointY(mePosLogical) - 1), false);
// タブの長さを知る
s.Text = "\t";
var i = s.GetActivePointX(mePosLogical); // タブ1つ幅の桁数
s.StartOfLine(true, mePosLogical);
s.Untabify();
var ii = s.Text; // タブ1つ幅の半角空白
s.Delete();
if (ty > 1) { // 1行目でなければ上の行で目標の桁位置を見る
// s.LineUp(false, 1); // ←mePosLogicalとの併用だと分割表示で予期の動作をしない
// s.StartOfLine(false, mePosLogical);
s.SetActivePoint(mePosLogical, 1, (s.GetActivePointY(mePosLogical) - 1), false);
s.EndOfLine(true, mePosLogical);
switch (s.Text.slice(0, 1)) {
case " ":
case "\t":
case "\u3000":
case ">": // \x3e citation
case "/": // \x2f comment // c,c++,c#,JavaScript,php,Delphi
case ";": // \x3b comment ; HSP,Lisp,Scheme,xyzzy
case "#": // \x23 comment # perl,make,Ruby,MySQL
case "!": // \x21 comment ! gasp
case "'": // \x27 comment ' vb,vba,basic
case "*": // \x2a comment * cobol
case "-": // \x2d comment -- SQL
case "%": // \x25 comment % LilyPond
// 行頭空白そのまま
var il = s.Text.replace(/(^[\s\u3000\xa0]*[\s\u3000\xa0\x3e\x2f\x3b\x23\x21\x27\x2a\x2d\x25]{1,2}[\s\u3000\xa0]*).*$/,"$1");
il = il.replace(/\x2f\x2a|\x2a\x2f/, (rp === "\x2a\x2f" ? "" : " ")); // /* */ このブロックを除外、生成に対応
// タブ1つ幅を加えるときに使う文字を行頭空白によって変更
switch (il.slice(0, 1)) {
case "\t": ii = "\t"; break; // 行頭がハードタブならこれで追加
case "\u3000": ii = ii.replace(/ /g, "\u3000"); break; // 行頭が全角空白ならこれで追加
}
break;
case (s.Text.slice(0, 3).toLowerCase() === "rem" ? s.Text.slice(0, 1) : "rem"): // \x52|\x72 comment REM|rem bat
var il = s.Text.replace(/(^[Rr][Ee][Mm][\s\u3000\xa0]{1,2}[\s\u3000\xa0]*).*$/,"$1");
break;
default:
il = "";
break;
}
// s.LineDown(false, 1); // ←mePosLogicalとの併用だと分割表示で予期の動作をしない
s.SetActivePoint(mePosLogical, 1, (s.GetActivePointY(mePosLogical) + 1), false);
}
else { // 1行目のときは下の行で目標の桁位置を見る
// s.LineDown(false, 1); // ←mePosLogicalとの併用だと分割表示で予期の動作をしない
// s.StartOfLine(false, mePosLogical);
s.SetActivePoint(mePosLogical, 1, (s.GetActivePointY(mePosLogical) + 1), false);
s.EndOfLine(true, mePosLogical);
switch (s.Text.slice(0, 1)) {
case " ":
case "\t":
case "\u3000":
case ">": // \x3e citation
case "/": // \x2f comment // c,c++,c#,JavaScript,php,Delphi
case ";": // \x3b comment ; HSP,Lisp,Scheme,xyzzy
case "#": // \x23 comment # perl,make,Ruby,MySQL
case "!": // \x21 comment ! gasp
case "'": // \x27 comment ' vb,vba,basic
case "*": // \x2a comment * cobol
case "-": // \x2a comment -- SQL
case "%": // \x25 comment % LilyPond
// 行頭空白そのまま
var il = s.Text.replace(/(^[\s\u3000\xa0]*[\s\u3000\xa0\x3e\x2f\x3b\x23\x21\x27\x2a\x2d\x25]{1,2}[\s\u3000\xa0]*).*$/,"$1");
il = il.replace(/\x2f\x2a|\x2a\x2f/, (rp === "\x2a\x2f" ? "" : " ")); // /* */ このブロックを除外、生成に対応
// タブ1つ幅を加えるときに使う文字を行頭空白によって変更
switch (il.slice(0, 1)) {
case "\t": ii = "\t"; break; // 行頭がハードタブならこれで追加
case "\u3000": ii = ii.replace(/ /g, "\u3000"); break; // 行頭が全角空白ならこれで追加
}
break;
case (s.Text.slice(0, 3).toLowerCase() === "rem" ? s.Text.slice(0, 1) : "rem"): // \x52|\x72 comment REM|rem bat
var il = s.Text.replace(/(^[Rr][Ee][Mm][\s\u3000\xa0]{1,2}[\s\u3000\xa0]*).*$/,"$1");
break;
default:
il = "";
break;
}
// s.LineUp(false, 1); // ←mePosLogicalとの併用だと分割表示で予期の動作をしない
s.SetActivePoint(mePosLogical, 1, (s.GetActivePointY(mePosLogical) - 1), false);
}
// 新しい行の行頭を形作る
s.Text = il; // 上行と同じ行頭空白に揃うよう右に進む
s.EndOfLine(false, mePosLogical);
s.CharRight(true, 1);
s.Delete();
s.Text = rp; // ブロックの終了文字列
// s.LineOpen(true); // ←折り返し表示をしていると挿入位置を上方向に誤る
// カーソル桁位置に関わらず現在行を下にずらし(上に)行を挿入
s.StartOfLine(false, mePosLogical);
s.NewLine(1);
// s.LineUp(false, 1); // ←mePosLogicalとの併用だと分割表示で予期の動作をしない
y = s.GetActivePointY(mePosLogical) - 1;
s.SetActivePoint(mePosLogical, 1, y, false);
// 保存した選択範囲があれば挿入
if (t > "") {
var re_one = new RegExp("^([^\n]*?)([ \t\u3000\xa0]*" + rp.esc_x5c() + "[ \t\u3000\xa0]*)(?=\n|$)"); // one line text
if (re_one.test(t)) { t = t.replace(re_one, "$1"); }
t = (t.charAt(0) === "\n" ? "" : il + ii) + t.replace(/\n/g, "\n" + ii).replace(/^\n/, "") + "\n";
}
s.Text = t;
// 新しい行の行頭を形作る
s.Text = il + ii; // 上行と同じ行頭空白にタブ1つ幅を加えて右に進む
s.EndOfLine(false, mePosLogical);
Redraw = true;
}
// - ------------------------ --------------------------------------------------
スポンサーリンク