「インデントブロック作り」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
Inuuik (トーク | 投稿記録)
ページの作成:「 <pre> カーソルがある論理行の下に新しいインデントした{}ブロックを作る(挿入)。 まず開始文字列を挿入して改行、 ...」
 
Inuuik (トーク | 投稿記録)
編集の要約なし
34行目: 34行目:
ツール - オプション - キーボード の マクロ で Shift+Ctrl+[ に割り当て。
ツール - オプション - キーボード の マクロ で Shift+Ctrl+[ に割り当て。
</pre>
</pre>
<pre>
 
ここから長くコピーしてエディタに貼り付けるのではなく、ファイルからの登録に。
ここから長くコピーしてエディタに貼り付けるのではなく、ファイルからの登録に。


※ マクロitokusuセット_01: [[ファイル:itokusu_01_120906.zip]]
※ マクロitokusuセット_01: [[ファイル:itokusu_01_120906.zip]]
 
<pre>
   逆タブ(Shift+Tab).js                      … 逆タブと逆インデント
   逆タブ(Shift+Tab).js                      … 逆タブと逆インデント
   インデント{}ブロック作り(Shift+Ctrl+[).js … 閉じてインデントブロック
   インデント{}ブロック作り(Shift+Ctrl+[).js … 閉じてインデントブロック

2012年9月7日 (金) 15:16時点における版

  カーソルがある論理行の下に新しいインデントした{}ブロックを作る(挿入)。
    まず開始文字列を挿入して改行、
    現在行(挿入される行のすぐ上)の開始桁と揃うだけの幅の空白を追加して
    終了文字列を挿入し、
    その右に続けてカーソル以降の文字列を表示。
    そしてその行の上に新しい行を挿入。
    カーソルは前の行の開始桁より、右方向にタブ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;
}
// - ------------------------ --------------------------------------------------
スポンサーリンク