「対応する括弧に移動」の版間の差分
ナビゲーションに移動
検索に移動
編集の要約なし |
(「masme版」を追加。目次を表示。) |
||
1行目: | 1行目: | ||
対応する括弧に移動します。「shift」変数を「true」に設定した場合は選択しながら移動します。 | 対応する括弧に移動します。「shift」変数を「true」に設定した場合は選択しながら移動します。 | ||
<div>__TOC__</div> | |||
= Kuro, kurama 版 (2009/08) = | |||
<source lang="javascript"> | <source lang="javascript"> | ||
119行目: | 123行目: | ||
// 描画開始 | // 描画開始 | ||
Redraw = true; | Redraw = true; | ||
</source> | |||
= masme 版 (2014/02) = | |||
Get/SetActivePos メソッドと正規表現検索を活用したバージョンです。 | |||
* 正規表現検索を利用することで、より高速に動作するようになりました。 | |||
* ステータスバーに括弧間の距離(文字数)を表示するようにしました。 | |||
* Kuro, kurama 版に存在するバグっぽい挙動を修正しました。 | |||
** カーソル右側に改行がある場合に限り、左側の括弧に反応するのを修正。例外なく、右側の括弧にのみ反応するようにした。 | |||
** 開き括弧の「直前」ではなく「直後」に移動する場合があるのを修正。括弧の「直前」に移動するよう統一した。 | |||
<source lang="javascript"> | |||
//■対応する括弧に移動 | |||
// 2014/02/05 | |||
//■範囲選択(true:する/false:しない) | |||
var shift = false; | |||
//■括弧の定義(0+2n:開き/1+2n:閉じ) | |||
var br = "()<>[]{}「」『』【】()"; | |||
(function(){ | |||
var sel = Document.Selection; | |||
var pos = sel.GetActivePos(); //カーソル位置を記憶 | |||
var $br1 = Document.Text.charAt(pos) || -1; //右側の文字を取得/[EOF]の場合、-1 に | |||
var $bri = br.indexOf($br1); | |||
switch (true) { //括弧の判定、探索準備 | |||
case ($bri == -1): //◆括弧でない場合 | |||
Status = "カーソル右側に括弧がありません"; | |||
Quit(); | |||
case ($bri % 2 == 0): //◆開き括弧の場合 | |||
var $br2 = br.charAt($bri+1); //対応する閉じ括弧を取得 | |||
var $text = Document.Text.slice(pos+1); | |||
//※探索範囲は括弧の直後から文末まで | |||
break; | |||
case ($bri % 2 == 1): //◆閉じ括弧の場合 | |||
var $br2 = br.charAt($bri-1); //対応する開き括弧を取得 | |||
var $text = Document.Text.slice(0,pos).split("").reverse().join(""); | |||
//※探索範囲は括弧の直前から文頭まで | |||
break; | |||
} | |||
//対応する括弧を探索し、距離を測定 | |||
var nest= 1, dist= i= 0, re= new RegExp("["+"\\"+$br1+"\\"+$br2+"]"); | |||
while (nest) { //ネストが無くなるまで探す | |||
i = $text.search(re); | |||
if (i == -1) break; //括弧が見当たらない場合、探索終了 | |||
if ($text.charAt(i) == $br1) nest++; else nest--; | |||
$text = $text.slice(i+1); //探索した範囲を除去 | |||
dist += i+1; //距離を加算 | |||
} | |||
switch (true) { //結果の判定、移動処理 | |||
case (nest != 0): //◆ネストが残る場合 | |||
Status = "対応する括弧が見つかりませんでした"; | |||
sel.SetActivePos(pos); //カーソル位置を復元、選択解除 | |||
Quit(); | |||
case ($bri % 2 == 0): //◆開き括弧の場合 | |||
sel.SetAnchorPos(pos); | |||
sel.SetActivePos(pos + dist, shift); //閉じ括弧の直前に移動 | |||
break; | |||
case ($bri % 2 == 1): //◆閉じ括弧の場合 | |||
sel.SetAnchorPos(pos); | |||
sel.SetActivePos(pos - dist, shift); //開き括弧の直前に移動 | |||
break; | |||
} | |||
Status = "対応する括弧間の距離: "+(dist - 1)+"文字"; | |||
})(); | |||
</source> | </source> |
2014年2月5日 (水) 19:35時点における版
対応する括弧に移動します。「shift」変数を「true」に設定した場合は選択しながら移動します。
Kuro, kurama 版 (2009/08)
// -----------------------------------------------------------------------------
// 対応する括弧に移動
//
// Copyright (c) Kuro. All Rights Reserved.
// www: http://www.haijin-boys.com/
// Special Thanks for Kurama さん, Take さん
// -----------------------------------------------------------------------------
// シフトの状態(オンの場合は選択、オフの場合は移動)
var shift = false;
// 括弧として認識する文字
var lp = "(<[{「『【(";
var rp = ")>]}」』】)";
// 描画停止
Redraw = false;
// ステータスバーを消去
Status = "";
with (document.selection) {
// カーソル位置を保存
var ax = GetActivePointX(mePosLogical);
var ay = GetActivePointY(mePosLogical);
// スクロール位置を保存
var sx = ScrollX;
var sy = ScrollY;
// カーソル位置を復元
SetActivePoint(mePosLogical, ax, ay, false);
// 単語を選択
SelectWord();
// 現在位置の括弧を取得
var c1 = Text;
// 選択範囲を解除
Collapse();
var l = lp.indexOf(c1);
var r = rp.indexOf(c1);
var st = 0;
if (l > -1) {
// 対応する括弧の種類を取得
var c2 = rp.charAt(l);
EndOfDocument(true);
var s = Text;
// カーソル位置を復元
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 = GetActivePointY(mePosLogical);
// カーソル位置を復元
SetActivePoint(mePosLogical, ax, ay, false);
SetActivePoint(mePosLogical, x, y, shift);
// 左に戻る
CharLeft(shift, 1);
break;
}
if (s.charAt(i) == "\n") {
x = 1;
y = GetActivePointY(mePosLogical) + 1;
SetActivePoint(mePosLogical, x, y, false);
StartOfLine(false, mePosLogical);
x = GetActivePointX(mePosLogical);
}
}
} else if (r > -1) {
// 対応する括弧の種類を取得
var c2 = lp.charAt(r);
CharRight(false, 1);
StartOfDocument(true);
var s = Text;
// カーソル位置を復元
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 = GetActivePointY(mePosLogical);
// カーソル位置を復元
SetActivePoint(mePosLogical, ax, ay, false);
SetActivePoint(mePosLogical, x, y, shift);
// 右に進む
CharRight(shift, 1);
break;
}
if (s.charAt(i) == "\n") {
x = 1;
y = GetActivePointY(mePosLogical) - 1;
SetActivePoint(mePosLogical, x, y, false);
EndOfLine(false, mePosLogical);
x = GetActivePointX(mePosLogical);
}
}
} else {
// 括弧が無い場合は元の位置に戻す
SetActivePoint(mePosLogical, ax, ay, false);
Status = "カーソル位置に括弧が見つかりませんでした";
}
if (st != 0) {
SetActivePoint(mePosLogical, ax, ay, false);
Status = "対応する括弧が見つかりませんでした";
}
}
// 描画開始
Redraw = true;
masme 版 (2014/02)
Get/SetActivePos メソッドと正規表現検索を活用したバージョンです。
- 正規表現検索を利用することで、より高速に動作するようになりました。
- ステータスバーに括弧間の距離(文字数)を表示するようにしました。
- Kuro, kurama 版に存在するバグっぽい挙動を修正しました。
- カーソル右側に改行がある場合に限り、左側の括弧に反応するのを修正。例外なく、右側の括弧にのみ反応するようにした。
- 開き括弧の「直前」ではなく「直後」に移動する場合があるのを修正。括弧の「直前」に移動するよう統一した。
//■対応する括弧に移動
// 2014/02/05
//■範囲選択(true:する/false:しない)
var shift = false;
//■括弧の定義(0+2n:開き/1+2n:閉じ)
var br = "()<>[]{}「」『』【】()";
(function(){
var sel = Document.Selection;
var pos = sel.GetActivePos(); //カーソル位置を記憶
var $br1 = Document.Text.charAt(pos) || -1; //右側の文字を取得/[EOF]の場合、-1 に
var $bri = br.indexOf($br1);
switch (true) { //括弧の判定、探索準備
case ($bri == -1): //◆括弧でない場合
Status = "カーソル右側に括弧がありません";
Quit();
case ($bri % 2 == 0): //◆開き括弧の場合
var $br2 = br.charAt($bri+1); //対応する閉じ括弧を取得
var $text = Document.Text.slice(pos+1);
//※探索範囲は括弧の直後から文末まで
break;
case ($bri % 2 == 1): //◆閉じ括弧の場合
var $br2 = br.charAt($bri-1); //対応する開き括弧を取得
var $text = Document.Text.slice(0,pos).split("").reverse().join("");
//※探索範囲は括弧の直前から文頭まで
break;
}
//対応する括弧を探索し、距離を測定
var nest= 1, dist= i= 0, re= new RegExp("["+"\\"+$br1+"\\"+$br2+"]");
while (nest) { //ネストが無くなるまで探す
i = $text.search(re);
if (i == -1) break; //括弧が見当たらない場合、探索終了
if ($text.charAt(i) == $br1) nest++; else nest--;
$text = $text.slice(i+1); //探索した範囲を除去
dist += i+1; //距離を加算
}
switch (true) { //結果の判定、移動処理
case (nest != 0): //◆ネストが残る場合
Status = "対応する括弧が見つかりませんでした";
sel.SetActivePos(pos); //カーソル位置を復元、選択解除
Quit();
case ($bri % 2 == 0): //◆開き括弧の場合
sel.SetAnchorPos(pos);
sel.SetActivePos(pos + dist, shift); //閉じ括弧の直前に移動
break;
case ($bri % 2 == 1): //◆閉じ括弧の場合
sel.SetAnchorPos(pos);
sel.SetActivePos(pos - dist, shift); //開き括弧の直前に移動
break;
}
Status = "対応する括弧間の距離: "+(dist - 1)+"文字";
})();
スポンサーリンク