「対応する括弧に移動」の版間の差分
ナビゲーションに移動
検索に移動
細 →おまけ |
SyntaxHighlightにcopyの追加 |
||
| (4人の利用者による、間の21版が非表示) | |||
| 1行目: | 1行目: | ||
このマクロは[https://www.haijin-boys.com/software/mery/mery-3-6-0#17 Mery Ver 3.6.1]で追加されたコマンド「対応する括弧へ移動」と同機能です。 | |||
= Kuro, kurama 版 | == Kuro, kurama 版 == | ||
対応する括弧に移動します。「shift」変数を「true」に設定した場合は選択しながら移動します。 | |||
< | <syntaxhighlight lang="javascript" copy> | ||
// ----------------------------------------------------------------------------- | // ----------------------------------------------------------------------------- | ||
// 対応する括弧に移動 | // 対応する括弧に移動 | ||
// | // | ||
// Copyright (c) Kuro. All Rights Reserved. | // Copyright (c) Kuro. All Rights Reserved. | ||
// www: | // www: https://www.haijin-boys.com/ | ||
// Special Thanks for Kurama さん, Take さん | // Special Thanks for Kurama さん, Take さん | ||
// ----------------------------------------------------------------------------- | // ----------------------------------------------------------------------------- | ||
| 22行目: | 22行目: | ||
// ステータスバーを消去 | // ステータスバーを消去 | ||
Status = ""; | Status = ""; | ||
// Selection オブジェクトを取得 | |||
var sel = document.selection; | |||
// カーソル位置を保存 | |||
var ax = sel.GetActivePointX(mePosLogical); | |||
var ay = sel.GetActivePointY(mePosLogical); | |||
// スクロール位置を保存 | |||
var sx = ScrollX; | |||
var sy = ScrollY; | |||
// カーソル位置を復元 | |||
sel.SetActivePoint(mePosLogical, ax, ay, false); | |||
// 単語を選択 | |||
sel.SelectWord(); | |||
// 現在位置の括弧を取得 | |||
var c1 = sel.Text; | |||
// 選択範囲を解除 | |||
sel.Collapse(); | |||
var l = lp.indexOf(c1); | |||
var r = rp.indexOf(c1); | |||
var st = 0; | |||
if (l > -1) { | |||
// 対応する括弧の種類を取得 | |||
var c2 = rp.charAt(l); | |||
sel.EndOfDocument(true); | |||
var s = sel.Text; | |||
// カーソル位置を復元 | |||
sel.SetActivePoint(mePosLogical, ax, ay, false); | |||
// スクロール位置を復元 | |||
ScrollX = sx; | |||
ScrollY = sy; | |||
var x = ax; | |||
var y = ay; | |||
for (var i = 0; i < s.length; i++) { | |||
x++; | |||
if (s.charAt(i) == c1) { | |||
st++; | |||
} | |||
if (s.charAt(i) == c2) { | |||
st--; | |||
} | |||
if (st == 0) { | |||
y = sel.GetActivePointY(mePosLogical); | |||
// カーソル位置を復元 | |||
sel.SetActivePoint(mePosLogical, ax, ay, false); | |||
sel.SetActivePoint(mePosLogical, x, y, shift); | |||
// 左に戻る | |||
sel.CharLeft(shift, 1); | |||
break; | |||
} | |||
if (s.charAt(i) == "\n") { | |||
x = 1; | |||
y = sel.GetActivePointY(mePosLogical) + 1; | |||
sel.SetActivePoint(mePosLogical, x, y, false); | |||
sel.StartOfLine(false, mePosLogical); | |||
x = sel.GetActivePointX(mePosLogical); | |||
} | |||
} | |||
} else if (r > -1) { | |||
// 対応する括弧の種類を取得 | |||
var c2 = lp.charAt(r); | |||
sel.CharRight(false, 1); | |||
sel.StartOfDocument(true); | |||
var s = sel.Text; | |||
// カーソル位置を復元 | |||
sel.SetActivePoint(mePosLogical, ax, ay, false); | |||
// スクロール位置を復元 | |||
ScrollX = sx; | |||
ScrollY = sy; | |||
var x = ax; | |||
for (var i = s.length - 1; i >= 0; i--) { | |||
x--; | |||
if (s.charAt(i) == c1) { | |||
st++; | |||
} | |||
if (s.charAt(i) == c2) { | |||
st--; | |||
} | |||
if (st == 0) { | |||
y = sel.GetActivePointY(mePosLogical); | |||
// カーソル位置を復元 | |||
sel.SetActivePoint(mePosLogical, ax, ay, false); | |||
sel.SetActivePoint(mePosLogical, x, y, shift); | |||
// 右に進む | |||
sel.CharRight(shift, 1); | |||
break; | |||
} | |||
if (s.charAt(i) == "\n") { | |||
x = 1; | |||
y = sel.GetActivePointY(mePosLogical) - 1; | |||
sel.SetActivePoint(mePosLogical, x, y, false); | |||
sel.EndOfLine(false, mePosLogical); | |||
x = sel.GetActivePointX(mePosLogical); | |||
} | |||
} | |||
} else { | |||
// 括弧が無い場合は元の位置に戻す | |||
sel.SetActivePoint(mePosLogical, ax, ay, false); | |||
Status = "カーソル位置に括弧が見つかりませんでした"; | |||
} | |||
if (st != 0) { | |||
sel.SetActivePoint(mePosLogical, ax, ay, false); | |||
Status = "対応する括弧が見つかりませんでした"; | |||
} | } | ||
// 描画開始 | // 描画開始 | ||
Redraw = true; | Redraw = true; | ||
</ | </syntaxhighlight> | ||
= masme 版 = | == masme 版 == | ||
* ステータスバーに括弧間の文字数を表示するようにしました。 | * ステータスバーに括弧間の文字数を表示するようにしました。 | ||
* Kuro, kurama 版の不安定な挙動を調整しました。 | * Kuro, kurama 版の不安定な挙動を調整しました。 | ||
| 131行目: | 134行目: | ||
** 開き括弧の直前ではなく、直後に移動する場合<sup>※</sup>があるのを修正。直前に移動するよう統一した。<br>※カーソル右側が改行か[EOF]の場合。改行をまたぐ移動になる場合。対応する括弧が行頭にある場合。 | ** 開き括弧の直前ではなく、直後に移動する場合<sup>※</sup>があるのを修正。直前に移動するよう統一した。<br>※カーソル右側が改行か[EOF]の場合。改行をまたぐ移動になる場合。対応する括弧が行頭にある場合。 | ||
== | === 変更履歴 === | ||
* 2019 | * 1.0.2 (2019-04-12) | ||
** Quit() → break | ** Quit() → break ラベル文に変更 | ||
* 2017 | * 1.0.1 (2017-05-27) | ||
** 処理方法を正規表現検索 → | ** 処理方法を正規表現検索 → 文字列検索に変更し、高速化 | ||
** 対応する括弧が見つからなかった場合、選択解除する → | ** 対応する括弧が見つからなかった場合、選択解除する → しない仕様に変更 | ||
* 2014 | * 1.0.0 (2014-02-05) | ||
** | ** 初版公開 | ||
== ソースコード == | === ソースコード === | ||
< | <syntaxhighlight lang="javascript" copy> | ||
//■対応する括弧に移動 | //■対応する括弧に移動 | ||
// 2014 | // 2014-02-05 - 2019-04-12 | ||
//■括弧の定義(0+2n:開き/1+2n:閉じ) | //■括弧の定義(0+2n:開き/1+2n:閉じ) | ||
| 159行目: | 162行目: | ||
var nest = 1, s, e; | var nest = 1, s, e; | ||
if (iBrc % 2) { //◆閉じ括弧の場合、先頭方向へ探す | if (iBrc % 2) { //◆閉じ括弧の場合、先頭方向へ探す | ||
var eBrc = BRACKET.charAt(iBrc-1); //対応する開き括弧を取得 | |||
while (nest) { | |||
s = txt.lastIndexOf(sBrc,ePos-1); | |||
e = txt.lastIndexOf(eBrc,ePos-1); | |||
if (e===-1 || ePos<=0) break; | |||
if (e<s) {nest++; ePos=s;} else {nest--; ePos=e;} | |||
} | |||
} else { //◆開き括弧の場合、末尾方向へ探す | } else { //◆開き括弧の場合、末尾方向へ探す | ||
var eBrc = BRACKET.charAt(iBrc+1); //対応する閉じ括弧を取得 | |||
while (nest) { | |||
s = txt.indexOf(sBrc,ePos+1); | |||
e = txt.indexOf(eBrc,ePos+1); | |||
if (e===-1) break; | |||
if (s<e && s!==-1) {nest++; ePos=s;} else {nest--; ePos=e;} | |||
} | |||
} | } | ||
if (nest!==0) { Status = "対応する括弧が見つかりませんでした"; break quit; } | if (nest!==0) { Status = "対応する括弧が見つかりませんでした"; break quit; } | ||
| 180行目: | 183行目: | ||
Status = "対応する括弧の距離: "+(Math.abs(ePos - sPos)-1)+"文字"; | Status = "対応する括弧の距離: "+(Math.abs(ePos - sPos)-1)+"文字"; | ||
} | } | ||
</ | </syntaxhighlight> | ||
2025年6月30日 (月) 01:00時点における最新版
このマクロはMery Ver 3.6.1で追加されたコマンド「対応する括弧へ移動」と同機能です。
Kuro, kurama 版[編集]
対応する括弧に移動します。「shift」変数を「true」に設定した場合は選択しながら移動します。
// -----------------------------------------------------------------------------
// 対応する括弧に移動
//
// Copyright (c) Kuro. All Rights Reserved.
// www: https://www.haijin-boys.com/
// Special Thanks for Kurama さん, Take さん
// -----------------------------------------------------------------------------
// シフトの状態(オンの場合は選択、オフの場合は移動)
var shift = false;
// 括弧として認識する文字
var lp = "(<[{「『【(";
var rp = ")>]}」』】)";
// 描画停止
Redraw = false;
// ステータスバーを消去
Status = "";
// Selection オブジェクトを取得
var sel = document.selection;
// カーソル位置を保存
var ax = sel.GetActivePointX(mePosLogical);
var ay = sel.GetActivePointY(mePosLogical);
// スクロール位置を保存
var sx = ScrollX;
var sy = ScrollY;
// カーソル位置を復元
sel.SetActivePoint(mePosLogical, ax, ay, false);
// 単語を選択
sel.SelectWord();
// 現在位置の括弧を取得
var c1 = sel.Text;
// 選択範囲を解除
sel.Collapse();
var l = lp.indexOf(c1);
var r = rp.indexOf(c1);
var st = 0;
if (l > -1) {
// 対応する括弧の種類を取得
var c2 = rp.charAt(l);
sel.EndOfDocument(true);
var s = sel.Text;
// カーソル位置を復元
sel.SetActivePoint(mePosLogical, ax, ay, false);
// スクロール位置を復元
ScrollX = sx;
ScrollY = sy;
var x = ax;
var y = ay;
for (var i = 0; i < s.length; i++) {
x++;
if (s.charAt(i) == c1) {
st++;
}
if (s.charAt(i) == c2) {
st--;
}
if (st == 0) {
y = sel.GetActivePointY(mePosLogical);
// カーソル位置を復元
sel.SetActivePoint(mePosLogical, ax, ay, false);
sel.SetActivePoint(mePosLogical, x, y, shift);
// 左に戻る
sel.CharLeft(shift, 1);
break;
}
if (s.charAt(i) == "\n") {
x = 1;
y = sel.GetActivePointY(mePosLogical) + 1;
sel.SetActivePoint(mePosLogical, x, y, false);
sel.StartOfLine(false, mePosLogical);
x = sel.GetActivePointX(mePosLogical);
}
}
} else if (r > -1) {
// 対応する括弧の種類を取得
var c2 = lp.charAt(r);
sel.CharRight(false, 1);
sel.StartOfDocument(true);
var s = sel.Text;
// カーソル位置を復元
sel.SetActivePoint(mePosLogical, ax, ay, false);
// スクロール位置を復元
ScrollX = sx;
ScrollY = sy;
var x = ax;
for (var i = s.length - 1; i >= 0; i--) {
x--;
if (s.charAt(i) == c1) {
st++;
}
if (s.charAt(i) == c2) {
st--;
}
if (st == 0) {
y = sel.GetActivePointY(mePosLogical);
// カーソル位置を復元
sel.SetActivePoint(mePosLogical, ax, ay, false);
sel.SetActivePoint(mePosLogical, x, y, shift);
// 右に進む
sel.CharRight(shift, 1);
break;
}
if (s.charAt(i) == "\n") {
x = 1;
y = sel.GetActivePointY(mePosLogical) - 1;
sel.SetActivePoint(mePosLogical, x, y, false);
sel.EndOfLine(false, mePosLogical);
x = sel.GetActivePointX(mePosLogical);
}
}
} else {
// 括弧が無い場合は元の位置に戻す
sel.SetActivePoint(mePosLogical, ax, ay, false);
Status = "カーソル位置に括弧が見つかりませんでした";
}
if (st != 0) {
sel.SetActivePoint(mePosLogical, ax, ay, false);
Status = "対応する括弧が見つかりませんでした";
}
// 描画開始
Redraw = true;
masme 版[編集]
- ステータスバーに括弧間の文字数を表示するようにしました。
- Kuro, kurama 版の不安定な挙動を調整しました。
- カーソル右側が改行か[EOF]の場合、左側の括弧に反応するのを修正。例外なく右側のみ反応するようにした。
- 開き括弧の直前ではなく、直後に移動する場合※があるのを修正。直前に移動するよう統一した。
※カーソル右側が改行か[EOF]の場合。改行をまたぐ移動になる場合。対応する括弧が行頭にある場合。
変更履歴[編集]
- 1.0.2 (2019-04-12)
- Quit() → break ラベル文に変更
- 1.0.1 (2017-05-27)
- 処理方法を正規表現検索 → 文字列検索に変更し、高速化
- 対応する括弧が見つからなかった場合、選択解除する → しない仕様に変更
- 1.0.0 (2014-02-05)
- 初版公開
ソースコード[編集]
//■対応する括弧に移動
// 2014-02-05 - 2019-04-12
//■括弧の定義(0+2n:開き/1+2n:閉じ)
var BRACKET = "()<>[]{}「」『』【】()";
//■範囲選択(true:する/false:しない)
var SHIFT = false;
quit: {
var Sel = Document.Selection;
var txt = Document.Text;
var sPos = Sel.GetActivePos(), ePos = sPos; //カーソル始点, 探索位置&終点
var sBrc = txt.charAt(sPos); //カーソル右側の文字を取得
var iBrc = BRACKET.indexOf(sBrc);
if (iBrc===-1 || sBrc==="") { Status = "カーソル右側に括弧がありません"; break quit; }
var nest = 1, s, e;
if (iBrc % 2) { //◆閉じ括弧の場合、先頭方向へ探す
var eBrc = BRACKET.charAt(iBrc-1); //対応する開き括弧を取得
while (nest) {
s = txt.lastIndexOf(sBrc,ePos-1);
e = txt.lastIndexOf(eBrc,ePos-1);
if (e===-1 || ePos<=0) break;
if (e<s) {nest++; ePos=s;} else {nest--; ePos=e;}
}
} else { //◆開き括弧の場合、末尾方向へ探す
var eBrc = BRACKET.charAt(iBrc+1); //対応する閉じ括弧を取得
while (nest) {
s = txt.indexOf(sBrc,ePos+1);
e = txt.indexOf(eBrc,ePos+1);
if (e===-1) break;
if (s<e && s!==-1) {nest++; ePos=s;} else {nest--; ePos=e;}
}
}
if (nest!==0) { Status = "対応する括弧が見つかりませんでした"; break quit; }
Sel.SetActivePos(sPos);
Sel.SetActivePos(ePos, SHIFT);
Status = "対応する括弧の距離: "+(Math.abs(ePos - sPos)-1)+"文字";
}
スポンサーリンク