|
|
| (4人の利用者による、間の26版が非表示) |
| 1行目: |
1行目: |
| <div>__TOC__</div>
| | このマクロは[https://www.haijin-boys.com/software/mery/mery-3-6-0#17 Mery Ver 3.6.1]で追加されたコマンド「対応する括弧へ移動」と同機能です。 |
|
| |
|
| = Kuro, kurama 版 (2009/08) = | | == Kuro, kurama 版 == |
| * 「shift」変数を「true」に書き換えると、選択しながら移動します。
| | 対応する括弧に移動します。「shift」変数を「true」に設定した場合は選択しながら移動します。 |
|
| |
|
| <source lang="javascript"> | | <syntaxhighlight lang="javascript" copy> |
| // ----------------------------------------------------------------------------- | | // ----------------------------------------------------------------------------- |
| // 対応する括弧に移動 | | // 対応する括弧に移動 |
| // | | // |
| // Copyright (c) Kuro. All Rights Reserved. | | // Copyright (c) Kuro. All Rights Reserved. |
| // www: http://www.haijin-boys.com/ | | // www: https://www.haijin-boys.com/ |
| // Special Thanks for Kurama さん, Take さん | | // Special Thanks for Kurama さん, Take さん |
| // ----------------------------------------------------------------------------- | | // ----------------------------------------------------------------------------- |
| 22行目: |
22行目: |
| // ステータスバーを消去 | | // ステータスバーを消去 |
| Status = ""; | | Status = ""; |
| with (document.selection) {
| | // Selection オブジェクトを取得 |
| // カーソル位置を保存
| | var sel = document.selection; |
| var ax = GetActivePointX(mePosLogical);
| | // カーソル位置を保存 |
| var ay = GetActivePointY(mePosLogical);
| | var ax = sel.GetActivePointX(mePosLogical); |
| // スクロール位置を保存
| | var ay = sel.GetActivePointY(mePosLogical); |
| var sx = ScrollX;
| | // スクロール位置を保存 |
| var sy = ScrollY;
| | var sx = ScrollX; |
| // カーソル位置を復元
| | var sy = ScrollY; |
| SetActivePoint(mePosLogical, ax, ay, false);
| | // カーソル位置を復元 |
| // 単語を選択
| | sel.SetActivePoint(mePosLogical, ax, ay, false); |
| SelectWord();
| | // 単語を選択 |
| // 現在位置の括弧を取得
| | sel.SelectWord(); |
| var c1 = Text;
| | // 現在位置の括弧を取得 |
| // 選択範囲を解除
| | var c1 = sel.Text; |
| Collapse();
| | // 選択範囲を解除 |
| var l = lp.indexOf(c1);
| | sel.Collapse(); |
| var r = rp.indexOf(c1);
| | var l = lp.indexOf(c1); |
| var st = 0;
| | var r = rp.indexOf(c1); |
| if (l > -1) {
| | var st = 0; |
| // 対応する括弧の種類を取得
| | if (l > -1) { |
| var c2 = rp.charAt(l);
| | // 対応する括弧の種類を取得 |
| EndOfDocument(true);
| | var c2 = rp.charAt(l); |
| var s = Text;
| | sel.EndOfDocument(true); |
| // カーソル位置を復元
| | var s = sel.Text; |
| SetActivePoint(mePosLogical, ax, ay, false);
| | // カーソル位置を復元 |
| // スクロール位置を復元
| | sel.SetActivePoint(mePosLogical, ax, ay, false); |
| ScrollX = sx;
| | // スクロール位置を復元 |
| ScrollY = sy;
| | ScrollX = sx; |
| var x = ax;
| | ScrollY = sy; |
| var y = ay;
| | var x = ax; |
| for (var i = 0; i < s.length; i++) {
| | var y = ay; |
| x++;
| | for (var i = 0; i < s.length; i++) { |
| if (s.charAt(i) == c1)
| | x++; |
| st++;
| | if (s.charAt(i) == c1) { |
| if (s.charAt(i) == c2)
| | st++; |
| st--;
| | } |
| if (st == 0) {
| | if (s.charAt(i) == c2) { |
| y = GetActivePointY(mePosLogical);
| | st--; |
| // カーソル位置を復元
| | } |
| SetActivePoint(mePosLogical, ax, ay, false);
| | if (st == 0) { |
| SetActivePoint(mePosLogical, x, y, shift);
| | y = sel.GetActivePointY(mePosLogical); |
| // 左に戻る
| | // カーソル位置を復元 |
| CharLeft(shift, 1);
| | sel.SetActivePoint(mePosLogical, ax, ay, false); |
| break;
| | sel.SetActivePoint(mePosLogical, x, y, shift); |
| }
| | // 左に戻る |
| if (s.charAt(i) == "\n") {
| | sel.CharLeft(shift, 1); |
| x = 1;
| | break; |
| y = GetActivePointY(mePosLogical) + 1;
| | } |
| SetActivePoint(mePosLogical, x, y, false);
| | if (s.charAt(i) == "\n") { |
| StartOfLine(false, mePosLogical);
| | x = 1; |
| x = GetActivePointX(mePosLogical);
| | y = sel.GetActivePointY(mePosLogical) + 1; |
| }
| | sel.SetActivePoint(mePosLogical, x, y, false); |
| }
| | sel.StartOfLine(false, mePosLogical); |
| } else if (r > -1) {
| | x = sel.GetActivePointX(mePosLogical); |
| // 対応する括弧の種類を取得
| | } |
| var c2 = lp.charAt(r);
| | } |
| CharRight(false, 1);
| | } else if (r > -1) { |
| StartOfDocument(true);
| | // 対応する括弧の種類を取得 |
| var s = Text;
| | var c2 = lp.charAt(r); |
| // カーソル位置を復元
| | sel.CharRight(false, 1); |
| SetActivePoint(mePosLogical, ax, ay, false);
| | sel.StartOfDocument(true); |
| // スクロール位置を復元
| | var s = sel.Text; |
| ScrollX = sx;
| | // カーソル位置を復元 |
| ScrollY = sy;
| | sel.SetActivePoint(mePosLogical, ax, ay, false); |
| var x = ax;
| | // スクロール位置を復元 |
| for (var i = s.length - 1; i >= 0; i--) {
| | ScrollX = sx; |
| x--;
| | ScrollY = sy; |
| if (s.charAt(i) == c1)
| | var x = ax; |
| st++;
| | for (var i = s.length - 1; i >= 0; i--) { |
| if (s.charAt(i) == c2)
| | x--; |
| st--;
| | if (s.charAt(i) == c1) { |
| if (st == 0) {
| | st++; |
| y = GetActivePointY(mePosLogical);
| | } |
| // カーソル位置を復元
| | if (s.charAt(i) == c2) { |
| SetActivePoint(mePosLogical, ax, ay, false);
| | st--; |
| SetActivePoint(mePosLogical, x, y, shift);
| | } |
| // 右に進む
| | if (st == 0) { |
| CharRight(shift, 1);
| | y = sel.GetActivePointY(mePosLogical); |
| break;
| | // カーソル位置を復元 |
| }
| | sel.SetActivePoint(mePosLogical, ax, ay, false); |
| if (s.charAt(i) == "\n") {
| | sel.SetActivePoint(mePosLogical, x, y, shift); |
| x = 1;
| | // 右に進む |
| y = GetActivePointY(mePosLogical) - 1;
| | sel.CharRight(shift, 1); |
| SetActivePoint(mePosLogical, x, y, false);
| | break; |
| EndOfLine(false, mePosLogical);
| | } |
| x = GetActivePointX(mePosLogical);
| | if (s.charAt(i) == "\n") { |
| }
| | x = 1; |
| }
| | y = sel.GetActivePointY(mePosLogical) - 1; |
| } else {
| | sel.SetActivePoint(mePosLogical, x, y, false); |
| // 括弧が無い場合は元の位置に戻す
| | sel.EndOfLine(false, mePosLogical); |
| SetActivePoint(mePosLogical, ax, ay, false);
| | x = sel.GetActivePointX(mePosLogical); |
| Status = "カーソル位置に括弧が見つかりませんでした";
| | } |
| }
| | } |
| if (st != 0) {
| | } else { |
| SetActivePoint(mePosLogical, ax, ay, false);
| | // 括弧が無い場合は元の位置に戻す |
| Status = "対応する括弧が見つかりませんでした";
| | sel.SetActivePoint(mePosLogical, ax, ay, false); |
| }
| | Status = "カーソル位置に括弧が見つかりませんでした"; |
| | } |
| | if (st != 0) { |
| | sel.SetActivePoint(mePosLogical, ax, ay, false); |
| | Status = "対応する括弧が見つかりませんでした"; |
| } | | } |
| // 描画開始 | | // 描画開始 |
| Redraw = true; | | Redraw = true; |
| </source> | | </syntaxhighlight> |
| <br>
| |
|
| |
|
| = masme 版 = | | == masme 版 == |
| * ステータスバーに括弧間の文字数を表示するようにしました。 | | * ステータスバーに括弧間の文字数を表示するようにしました。 |
| * Kuro, kurama 版の不安定な挙動を調整しました。 | | * Kuro, kurama 版の不安定な挙動を調整しました。 |
| 131行目: |
134行目: |
| ** 開き括弧の直前ではなく、直後に移動する場合<sup>※</sup>があるのを修正。直前に移動するよう統一した。<br>※カーソル右側が改行か[EOF]の場合。改行をまたぐ移動になる場合。対応する括弧が行頭にある場合。 | | ** 開き括弧の直前ではなく、直後に移動する場合<sup>※</sup>があるのを修正。直前に移動するよう統一した。<br>※カーソル右側が改行か[EOF]の場合。改行をまたぐ移動になる場合。対応する括弧が行頭にある場合。 |
|
| |
|
| == 更新履歴 == | | === 変更履歴 === |
| * 2019/04/12 | | * 1.0.2 (2019-04-12) |
| ** Quit() → break ラベル文に変更。 | | ** Quit() → break ラベル文に変更 |
| * 2017/05/27 | | * 1.0.1 (2017-05-27) |
| ** 処理方法を正規表現検索 → 文字列検索に変更し、高速化。 | | ** 処理方法を正規表現検索 → 文字列検索に変更し、高速化 |
| ** 対応する括弧が見つからなかった場合、選択解除する → しない仕様に変更。 | | ** 対応する括弧が見つからなかった場合、選択解除する → しない仕様に変更 |
| * 2014/02/05 | | * 1.0.0 (2014-02-05) |
| ** 初版公開。 | | ** 初版公開 |
|
| |
|
| == ソースコード == | | === ソースコード === |
| <source lang="javascript"> | | <syntaxhighlight lang="javascript" copy> |
| //■対応する括弧に移動 | | //■対応する括弧に移動 |
| // 2014/02/05-2019/04/12 | | // 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); //対応する開き括弧を取得
| | var eBrc = BRACKET.charAt(iBrc-1); //対応する開き括弧を取得 |
| while (nest) {
| | while (nest) { |
| s = txt.lastIndexOf(sBrc,ePos-1);
| | s = txt.lastIndexOf(sBrc,ePos-1); |
| e = txt.lastIndexOf(eBrc,ePos-1);
| | e = txt.lastIndexOf(eBrc,ePos-1); |
| if (e===-1 || ePos<=0) break;
| | if (e===-1 || ePos<=0) break; |
| if (e<s) {nest++; ePos=s;} else {nest--; ePos=e;}
| | if (e<s) {nest++; ePos=s;} else {nest--; ePos=e;} |
| }
| | } |
| } else { //◆開き括弧の場合、末尾方向へ探す | | } else { //◆開き括弧の場合、末尾方向へ探す |
| var eBrc = BRACKET.charAt(iBrc+1); //対応する閉じ括弧を取得
| | var eBrc = BRACKET.charAt(iBrc+1); //対応する閉じ括弧を取得 |
| while (nest) {
| | while (nest) { |
| s = txt.indexOf(sBrc,ePos+1);
| | s = txt.indexOf(sBrc,ePos+1); |
| e = txt.indexOf(eBrc,ePos+1);
| | e = txt.indexOf(eBrc,ePos+1); |
| if (e===-1) break;
| | if (e===-1) break; |
| if (s<e && s!==-1) {nest++; ePos=s;} else {nest--; ePos=e;}
| | 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)+"文字"; |
| } | | } |
| </source>
| | </syntaxhighlight> |
| <br>
| |
| | |
| = 範囲選択の拡張 =
| |
| (sukemaru 2019/04/24)<br>
| |
| [[GetKeyState.exe(キー状態取得実行ファイル)]] を利用して、'''カッコを含めた全体を範囲選択'''、または '''カッコの内側部分だけを範囲選択''' するための追加コードです。<br>
| |
| [[#masme 版|masme 版]] (2019/04/12) のソースコードに追加コードを挿入してください('''2ヵ所''')。<br><br>
| |
| <span style="color:#c00;">ツールバーアイコンやメニュー(マクロメニューや右クリックメニュー)からマクロを実行するさいに Ctrl または Shift キーを押しながら実行すると、拡張コードが適用されます。 </span><br>
| |
| | |
| * <kbd>Ctrl</kbd> キーを押しながらマクロを実行した場合には、カッコを含めた全体を範囲選択します。
| |
| ::<span style="background:#bfdfff;">【 Ctrl ありでの選択範囲 】</span> → ※カーソルは 開きカッコの左 (選択範囲の先頭)
| |
| * <kbd>Shift</kbd> キーを押しながらマクロを実行した場合には、カッコの内側部分だけを範囲選択します。
| |
| :: 【<span style="background:#bfdfff;"> Shift ありでの選択範囲 </span>】 → ※カーソルは 閉じカッコの左 (選択範囲の末尾)
| |
| * <kbd>Ctrl</kbd><kbd>Shift</kbd> キー両方が押されている(または両方とも押されていない)場合には、masme 版の設定変数「SHIFT」の true / false で指定された動作をします。
| |
| ::<span style="background:#bfdfff;">【 SHIFT=true のばあい </span>】
| |
| ※「対応する括弧に移動」を連続で実行(トグル移動)できるよう、拡張機能で範囲選択したあともカーソルは開きカッコか閉じカッコいずれかの「カッコの左」にセットされます。
| |
| <br><br>
| |
| ※ ショートカットキーでマクロを実行する場合、Ctrl キーを含むパターン、Shift キーを含むパターン、Ctrl と Shift 両方を含む(または両方を含まない)パターンのみっつのショートカットキーを登録する必要があります。 すでに masme 版「対応する括弧に移動」マクロにショートカットキーを割り当てて使用している場合、この追加コードを使用するにあたり、ショートカットの再割り当てをしてください。<br>
| |
| e.g. Ctrl+F9 / Shift+F9 / Ctrl+Shift+F9(または Alt+F9 など)
| |
| <span style="color:#c00;">※ 外部実行ファイル GetKeyState.exe を2回呼び出すため、拡張コードの処理にはタイムラグが生じます。選択範囲が確定するまで Ctrl または Shift キーを押しっぱなしにしてください。</span><br><br>
| |
| ※ GetKeyState.exe のダウンロードや導入方法については、マクロライブラリ内の「[[GetKeyState.exe(キー状態取得実行ファイル)]] 」のページへ
| |
| <br><br>
| |
| | |
| ;追加コード➀<br>
| |
| 15行目<br>
| |
| <syntaxhighlight lang="javascript" inline>if (iBrc===-1 || sBrc==="") { Status = "カーソル右側に括弧がありません"; break quit; }</syntaxhighlight><br>
| |
| の下に'''追加'''する<br>
| |
| ※「[[#カーソルの右側にカッコがないなら左側のカッコで|カーソルの右側にカッコがないなら左側のカッコで]]」の改造コードと併用する場合は、改造コードの下に挿入してください。
| |
| <source lang="javascript">
| |
| // ▼ GetKeyState を利用した機能拡張 ▼
| |
| // Ctrl / Shift キーの状態を取得
| |
| var $ctrl = 0, $shift = 0;
| |
| var getKeyState = editor.FullName.replace(/mery\.exe$/i,"") + "Macros\\GetKeyState.exe";
| |
| var WshShell = new ActiveXObject("WScript.Shell");
| |
| $ctrl = WshShell.Run('"' + getKeyState + '" ctrl',0,true);
| |
| $shift = WshShell.Run('"' + getKeyState + '" shift',0,true);
| |
| // ▲ GetKeyState を利用した機能拡張 ▲
| |
| </source>
| |
| <br>
| |
| ;追加コード➁<br>
| |
| 37行目<br>
| |
| <syntaxhighlight lang="javascript" inline>Status = "対応する括弧の距離: "+(Math.abs(ePos - sPos)-1)+"文字";</syntaxhighlight><br>
| |
| の下に'''追加'''する
| |
| <source lang="javascript">
| |
| // ▼ GetKeyState を利用した機能拡張 ▼
| |
| // ※SHIFT 変数による選択範囲を上書きする(SHIFT = false; でも拡張コードでの範囲選択は有効)
| |
| if ($ctrl || $shift) {
| |
| var tPos = Math.min(sPos,ePos);
| |
| var bPos = Math.max(sPos,ePos);
| |
| // Ctrl キーだけ押し下げ時にはカッコを含めた全体を範囲選択
| |
| if ($ctrl>0 && $shift==0) {
| |
| Sel.SetActivePos(tPos);
| |
| Sel.SetAnchorPos(bPos+1);
| |
| }
| |
| // Shift キーだけ押し下げ時にはカッコの内側だけを範囲選択
| |
| else if ($ctrl==0 && $shift>0) {
| |
| Sel.SetActivePos(bPos);
| |
| Sel.SetAnchorPos(tPos+1);
| |
| }
| |
| }
| |
| // ▲ GetKeyState を利用した機能拡張 ▲
| |
| </source>
| |
| | |
| * 2019/05/12 変数名間違いを修正 sel → Sel (sukemaru)
| |
| <br><br>
| |
| | |
| = カーソルの右側にカッコがないなら左側のカッコで =
| |
| (sukemaru 2019/12/01)<br>
| |
| <span style="color:#c00;">カーソルの右側にカッコがないとき</span> で、左側にカッコがあるなら、そのカッコに対応するカッコに移動します。<br>
| |
| * <b style="color:#c00;">右側のカッコ優先</b> です。<br>
| |
| : 移動後は対応する '''カッコの左側''' にカーソルがセットされます(連続で実行しても元のカッコの左側に)。
| |
| <br>
| |
| [[#masme 版|masme 版]] (2019/04/12) のソースコードを以下のとおり書き換えてください。
| |
| | |
| '''変更箇所''': 15 行目<br>
| |
| <syntaxhighlight lang="javascript" inline>if (iBrc===-1 || sBrc==="") { Status = "カーソル右側に括弧がありません"; break quit; }</syntaxhighlight><br>
| |
| をコメントアウトして
| |
| <source lang="javascript">
| |
| // if (iBrc===-1 || sBrc==="") { Status = "カーソル右側に括弧がありません"; break quit; } // ※ 1行 コメントアウト
| |
| | |
| // ▼ カーソルの左側にカッコがある場合に対応 ▼
| |
| if (iBrc>-1 && sBrc) { /* empty */ ; }
| |
| else if (BRACKET.indexOf(txt.charAt(sPos-1))>-1) {
| |
| sPos = ePos = sPos-1;
| |
| sBrc = txt.charAt(sPos);
| |
| iBrc = BRACKET.indexOf(txt.charAt(sPos));
| |
| }
| |
| else { Status = "カーソルの側に括弧がありません"; break quit; }
| |
| // ▲ カーソルの左側にカッコがある場合に対応 ▲
| |
| </source>
| |
| | |
| ※「[[#範囲選択の拡張|範囲選択の拡張]]」コードを併用する場合は、この変更箇所の下に「追加コード①」を挿入してください。
| |
| <br><br>
| |
| | |
| == おまけ ==
| |
| [[#masme 版|masme 版]] (2019/04/12) のソースコードに '''カッコの種類を追加''' します。
| |
| :※ Mery 本体のオプション機能の「対応する括弧を強調する」には非対応です。
| |
| <br>
| |
| 4 行目<br>
| |
| <syntaxhighlight lang="javascript" inline>var BRACKET = "()<>[]{}「」『』【】()";</syntaxhighlight><br>
| |
| の下に追加する
| |
| <source lang="javascript">
| |
| BRACKET += "<>[]{}「」〖〗⦅⦆〈〉《》〚〛〔〕〘〙‹›«»≪≫〝〟‘’“”︵︶︿﹀︽︾︷︸﹁﹂﹃﹄︻︼︹︺";
| |
| </source>
| |
| | |
| ※ 左右のカッコのかたち(文字)が異なるペアしか登録できないので、半角二重引用符 <syntaxhighlight lang="javascript" inline> "" </syntaxhighlight> や 半角一重引用符 <syntaxhighlight lang="javascript" inline> '' </syntaxhighlight> などは不可。
| |