Spec-Zone.ru › Elisp

Потоки ввода

Большинство функций Lisp для чтения текста принимают поток ввода в качестве аргумента. Поток ввода определяет, где и как получить символы текста для чтения. Вот возможные типы потоков ввода:

buffer

Символы ввода считываются из buffer, начиная с символа непосредственно после точки. Точка перемещается по мере чтения символов.

marker

Символы ввода считываются из буфера, в котором находится marker, начиная с символа непосредственно после маркера. Положение маркера перемещается по мере чтения символов. Значение точки в буфере не влияет на поток, если он является маркером.

string

Символы ввода берутся из string, начиная с первого символа в строке и используя столько символов, сколько необходимо.

function

Символы ввода генерируются функцией function, которая должна поддерживать два вида вызовов:

  • При вызове без аргументов она должна возвращать следующий символ.
  • При вызове с одним аргументом (всегда символ), function должна сохранить аргумент и организовать его возврат при следующем вызове. Это называется возвратом символа; это происходит, когда читатель Lisp считывает один символ слишком много и хочет вернуть его обратно. В этом случае значение, возвращаемое 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: ’. (Это всегда подсказка, используемая при чтении из потока 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.

Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Input-Streams.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API