GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Input-Streams.html ・ emacs-doc.conao3.com

20.2 入力ストリーム

テキストを読み込むためのLisp関数の多くは、入力ストリームを引数として取ります。入力ストリームは、読み込むテキストの文字をどこで、あるいはどのように取得するかを指定します。入力ストリームとして指定可能な型は以下の通りです。

buffer

入力文字は buffer から、ポイントの直後の文字を先頭として読み込まれます。文字が読み込まれるにつれて、ポイントは進みます。

marker

入力文字は、marker が含まれるバッファから、マーカーの直後の文字を先頭として読み込まれます。文字が読み込まれるにつれて、マーカーの位置が進みます。ストリームがマーカーである場合、バッファ内の point の値は影響しません。

string

入力文字は string から取得され、文字列の先頭文字から始まり、必要な数だけ文字が使用されます。

function

入力文字はfunctionによって生成され、このタグは2種類の呼び出しをサポートする必要があります。

  • 引数なしで呼び出された場合、次の文字を返す必要があります。
  • 引数を1つ(常に文字)取って呼び出された場合、function はその引数を保存し、次回の呼び出し時にそれを返すように処理します。これを文字のアンリーディングと呼びます。これは、Lispリーダーが文字を1つ多く読み込んでしまい、それを元の場所に戻したい場合に発生します。この場合、function がどのような値を返すかは問題になりません。
t

t をストリームとして使用する場合、入力はミニバッファから読み込まれます。実際には、ミニバッファが一度呼び出され、ユーザーが指定したテキストが文字列に変換され、それが入力ストリームとして使用されます。Emacs がバッチモードで動作している場合(バッチモードを参照)、ミニバッファの代わりに標準入力が使用されます。例えば、

(message "%s" (read t))

バッチモードでは、標準入力からLisp式を読み込み、その結果を標準出力に出力します。

nil

nil が入力ストリームとして指定された場合は、代わりに standard-input の値を使用することになります。その値は デフォルト入力ストリーム であり、nil 以外の入力ストリームである必要があります。

symbol

入力ストリームとしてのシンボルは、そのシンボルの関数定義(もしあれば)と同等である。

バッファであるストリームから読み込む例を以下に示します。前後でポイントがどこにあるかを示しています。

---------- Buffer: foo ----------
This∗ is the contents of foo.
---------- Buffer: foo ----------

(read (get-buffer "foo"))
     ⇒ is
(read (get-buffer "foo"))
     ⇒ the

---------- Buffer: foo ----------
This is the∗ contents of foo.
---------- Buffer: foo ----------

なお、最初の読み込みではスペースがスキップされます。読み込み時には、重要なテキストに先行する任意の量の空白がスキップされます。

以下に、最初は表示されているバッファの先頭に配置されたマーカーであるストリームから読み込む例を示します。読み出された値はシンボル This です。


---------- Buffer: foo ----------
This is the contents of foo.
---------- Buffer: foo ----------

(setq m (set-marker (make-marker) 1 (get-buffer "foo")))
     ⇒ #<marker at 1 in foo>
(read m)
     ⇒ This
m
     ⇒ #<marker at 5 in foo>   ;; Before the first space.

ここでは、文字列の内容から読み取りを行います:

(read "(When in) the course")
     ⇒ (When in)

以下の例では、ミニバッファから読み込みを行います。プロンプトは ‘Lisp expression: ’ です。(これは、ストリーム t から読み込む際に常に使用されるプロンプトです。)ユーザーの入力は、プロンプトの後に表示されます。

(read t)
     ⇒ 23
---------- Buffer: Minibuffer ----------
Lisp expression: 23 RET
---------- Buffer: Minibuffer ----------

最後に、useless-stream という名前の関数であるストリームの例を示します。ストリームを使用する前に、変数 useless-list を文字のリストで初期化します。その後、関数 useless-stream が呼び出されるたびに、リスト内の次の文字を取得するか、あるいは文字をリストの先頭に追加して未読状態にします。

(setq useless-list (append "XY()" nil))
     ⇒ (88 89 40 41)

(defun useless-stream (&optional unread)
  (if unread
      (setq useless-list (cons unread useless-list))
    (prog1 (car useless-list)
           (setq useless-list (cdr useless-list)))))
     ⇒ useless-stream

それでは、このように構築したストリームを用いて読み込みます:

(read 'useless-stream)
     ⇒ XY

useless-list
     ⇒ (40 41)

なお、リストには開き括弧と閉じ括弧がそのまま残っている点に注意してください。Lispリーダーは開き括弧を検出し、それが入力の終端であると判断して、読み飛ばしました。この時点でストリームから再度読み込もうとすると、‘()’が読み込まれ、nilが返されます。