テキスト・エディタの interactive 引数指定の正規表現

GNU Emacs の編集コマンドは interactive 特殊形式を持つだけでなく、 この特殊形式で対話時に引数をどのように得るかを指定します。 この仕掛けは、 関数と編集コマンドの差異をなくす働きをします。 エディタの read-eval-print ループからは、 特殊形式を基に引数を作ってコマンドを呼び出します。 一方、 関数やコマンドからは、 この特殊形式を無視し、 コマンドをあたかも通常の関数であるかのように摘要に利用できます。

引数指定は文字列になっています。 その中で、 1 つの引数を 1 文字で指定します。 例えば、 コマンド・プレフィックスから数を得たいときは (interactive "p") と記述します。 ミニバッファを使って文字列を得たいときは s にプロンプトを続けて (interactive "sString ?") と記述します。 ミニバッファから値を得る引数指定のプロンプトを省略することはできません。 また、 プロンプト付き引数指定の後に他の引数指定を続けるときは、 1 つの改行で区切ります。

  (interactive "sString 1 ?\nsString 2 ?")

プロンプトが付かない引数指定も改行で区切ります。 現点 (d) とマーカー (m) の値を引数に受け取る指定は次のようにします。

  (interactive "d\nm")

ここでのローカルな規則の緩和として、 末尾に改行を付けても良いことにしましょう。

  (interactive "sString 1 ?\nsString 2 ?\n")

さらに、 パターンを簡単にするため、 プロンプトなしの引数指定文字 p と、 プロンプト付きの引数指定文字 s の 2 つだけが使えるものとしましょう。

  1. 空行を許す
  2. p にプロンプトを指定しない
  3. p の後に ps を続けるときは改行を 1 つ挟まなければならない
  4. s にプロンプトを指定しなければならない
  5. sプロンプト の後に ps を続けるときは改行を 1 つ挟まなければならない
  6. 末尾に改行があっても良い
  7. 改行を 2 つ以上並べることは禁止

このような規則にマッチする ruby正規表現は簡単なものです。

  INTERACTIVE_PATTERN = %r{
    \A (?: [p] | [s][^\n]+ ) (?: \n (?: [p] | [s][^\n]+ ) )* \n? \z
  }msx