Потоки ввода
Большинство функций 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