21.2 Чтение текстовых строк с помощью минибуфера

Самый базовый примитив для ввода в минибуфере — это read-from-minibuffer, который можно использовать для чтения как строки, так и Lisp-объекта в текстовой форме. Функция read-regexp используется для чтения регулярных выражений (см. Регулярные выражения), которые являются особым видом строк. Также существуют специализированные функции для чтения команд, переменных, имён файлов и т.д. (см. Дополнение).

В большинстве случаев вам не следует вызывать функции ввода минибуфера в середине Lisp-функции. Вместо этого выполняйте весь ввод из минибуфера как часть чтения аргументов для команды в спецификации interactive. См. Определение команд.

Функция: read-from-minibuffer prompt &optional initial keymap read history default inherit-input-method

Эта функция является наиболее общим способом получения ввода из минибуфера. По умолчанию она принимает произвольный текст и возвращает его в виде строки; однако если read не равен nil, то она использует read для преобразования текста в Lisp-объект (см. Функции ввода).

Первое, что делает эта функция — активирует минибуфер и отображает его с prompt (который должен быть строкой) в качестве приглашения. Затем пользователь может редактировать текст в минибуфере.

Когда пользователь вводит команду для выхода из минибуфера, read-from-minibuffer формирует возвращаемое значение из текста в минибуфере. Обычно она возвращает строку, содержащую этот текст. Однако если read не равен nil, read-from-minibuffer читает текст и возвращает результирующий Lisp-объект без вычисления. (См. Функции ввода для получения информации о чтении.)

Аргумент default задаёт значения по умолчанию, доступные через команды истории. Это должна быть строка, список строк или nil. Строка или строки становятся «будущей историей» минибуфера, доступной пользователю с помощью M-n. Кроме того, если вызов предоставляет дополнение (например, через аргумент keymap), кандидаты дополнения добавляются в «будущую историю», когда значения в default исчерпываются M-n; см. minibuffer-default-add-function.

Если read не равен nil, то default также используется как ввод для read, если пользователь вводит пустой ввод. Если default — список строк, первая строка используется как ввод. Если default равен nil, пустой ввод приводит к ошибке end-of-file. Однако в обычном случае (когда read равен nil), read-from-minibuffer игнорирует default, когда пользователь вводит пустой ввод, и возвращает пустую строку "". В этом отношении она отличается от всех остальных функций ввода минибуфера в этой главе.

Если keymap не равен nil, эта карта клавиш используется как локальная карта клавиш в минибуфере. Если keymap опущен или равен nil, в качестве карты клавиш используется значение minibuffer-local-map. Задание карты клавиш — важнейший способ настройки минибуфера для различных приложений, таких как дополнение.

Аргумент history задаёт переменную списка истории для сохранения ввода и для команд истории, используемых в минибуфере. По умолчанию это minibuffer-history. Если history — символ t, история не записывается. Вы также можете указать начальную позицию в списке истории. См. История минибуфера.

Если переменная minibuffer-allow-text-properties не равна nil (либо локально привязана, либо локальна для буфера в минибуфере), то возвращаемая строка включает все текстовые свойства, которые присутствовали в минибуфере. В противном случае все текстовые свойства удаляются при возврате значения. (По умолчанию эта переменная равна nil.)

Текстовые свойства из minibuffer-prompt-properties применяются к приглашению. По умолчанию этот список свойств определяет лицо (face), используемое для приглашения. Это лицо, если оно присутствует, добавляется в конец списка лиц и объединяется перед отображением.

Если пользователь хочет полностью контролировать внешний вид приглашения, наиболее удобный способ — указать лицо default в конце всех списков лиц. Например:

(read-from-minibuffer
 (concat
  (propertize "Жирный" 'face '(bold default))
  (propertize " и обычный: " 'face '(default))))

Если аргумент inherit-input-method не равен nil, то минибуфер наследует текущий метод ввода (см. Методы ввода) и установку enable-multibyte-characters (см. Текстовые представления) из того буфера, который был текущим перед входом в минибуфер.

Использование initial в основном устарело; мы рекомендуем использовать значение, отличное от nil, только в сочетании с указанием ячейки cons для history. См. Начальный ввод.

Функция: read-string prompt &optional initial history default inherit-input-method

Эта функция читает строку из минибуфера и возвращает её. Аргументы prompt, initial, history и inherit-input-method используются так же, как в read-from-minibuffer. Используемая карта клавиш — minibuffer-local-map.

Необязательный аргумент default используется так же, как в read-from-minibuffer, за исключением того, что если он не равен nil, он также задаёт значение по умолчанию, возвращаемое, если пользователь вводит пустой ввод. Как и в read-from-minibuffer, это должна быть строка, список строк или nil, что эквивалентно пустой строке. Когда default — строка, эта строка является значением по умолчанию. Когда это список строк, первая строка является значением по умолчанию. (Все эти строки доступны пользователю в «будущей истории минибуфера».)

Эта функция работает путём вызова функции read-from-minibuffer:

(read-string prompt initial history default inherit)
≡
(let ((value
       (read-from-minibuffer prompt initial nil nil
                             history default inherit)))
  (if (and (equal value "") default)
      (if (consp default) (car default) default)
    value))

Если у вас есть длинная строка (например, занимающая несколько строк), которую вы хотите отредактировать, использование read-string может быть не идеальным. В этом случае переход в новый обычный буфер, где пользователь может редактировать строку, может быть более удобным, и вы можете использовать функцию read-string-from-buffer для этого.

Функция: read-regexp prompt &optional defaults history

Эта функция читает регулярное выражение в виде строки из минибуфера и возвращает его. Если строка приглашения минибуфера prompt не заканчивается на ‘:’ (с последующими необязательными пробельными символами), функция добавляет ‘: ’ в конец, перед значением по умолчанию (см. ниже), если оно не пустое.

Необязательный аргумент defaults управляет значением по умолчанию, возвращаемым, если пользователь вводит пустой ввод, и должен быть одним из: строка; nil, что эквивалентно пустой строке; список строк; или символ.

Если defaults — символ, read-regexp обращается к значению переменной read-regexp-defaults-function (см. ниже), и если она не равна nil, использует её вместо defaults. Значение в этом случае должно быть либо:

  • regexp-history-last, что означает использование первого элемента соответствующего списка истории минибуфера (см. ниже).
  • Функция без аргументов, возвращаемое значение которой (должно быть nil, строкой или списком строк) становится значением defaults.

read-regexp теперь гарантирует, что результат обработки defaults является списком (т.е. если значение — nil или строка, оно преобразуется в список из одного элемента). К этому списку read-regexp затем добавляет несколько потенциально полезных кандидатов для ввода. Это:

  • Слово или символ в точке.
  • Последнее регулярное выражение, использованное в инкрементальном поиске.
  • Последняя строка, использованная в инкрементальном поиске.
  • Последняя строка или шаблон, использованные в командах query-replace.

Теперь функция имеет список регулярных выражений, который она передаёт read-from-minibuffer для получения ввода пользователя. Первый элемент списка является результатом по умолчанию в случае пустого ввода. Все элементы списка доступны пользователю как список «будущей истории минибуфера» (см. будущий список в Руководстве GNU Emacs).

Необязательный аргумент history, если не равен nil, является символом, задающим список истории минибуфера для использования (см. История минибуфера). Если он опущен или равен nil, список истории по умолчанию равен regexp-history.

Пользователь может использовать команду M-s c, чтобы указать, должно ли учитываться регистра. Если пользователь использовал эту команду, возвращаемая строка будет иметь текстовое свойство case-fold, установленное в fold или inhibit-fold. Вызывающий read-regexp должен сам использовать это значение, и для этого предоставляется удобная функция read-regexp-case-fold-search. Типичный шаблон использования здесь может выглядеть так:

(let* ((regexp (read-regexp "Искать: "))
       (case-fold-search (read-regexp-case-fold-search regexp)))
  (re-search-forward regexp))
Пользовательская опция: read-regexp-defaults-function

Функция read-regexp может использовать значение этой переменной для определения своего списка регулярных выражений по умолчанию. Если не равна nil, значение этой переменной должно быть либо:

  • Символ regexp-history-last.
  • Функция без аргументов, которая возвращает либо nil, строку, либо список строк.

Подробнее об использовании этих значений см. read-regexp выше.

Переменная: minibuffer-allow-text-properties

Если эта переменная равна nil (значение по умолчанию), то read-from-minibuffer и все функции, осуществляющие ввод в минибуфере, удаляют все текстовые свойства из ввода минибуфера перед его возвратом.

Однако read-minibuffer и связанные с ней функции (см. Чтение Lisp-объектов с помощью минибуфера) удаляют текстовые свойства безусловно, независимо от значения этой переменной.

Если эта переменная не равна nil (либо локально привязана, либо локальна для буфера в минибуфере), то read-from-minibuffer, read-string и все связанные функции сохраняют текстовые свойства. Но функции, осуществляющие ввод в минибуфере с дополнением, удаляют свойство face, сохраняя другие текстовые свойства.

(minibuffer-with-setup-hook
    (lambda ()
      (setq-local minibuffer-allow-text-properties t))
  (completing-read
   "Строка: " (list (propertize "foobar" 'face 'baz 'data 'zot))))
=> #("foobar" 0 6 (data zot))

В этом примере пользователь ввёл ‘foo’ и затем нажал клавишу TAB, и все текстовые свойства сохранены, кроме свойства face.

Переменная: minibuffer-local-map

Это локальная карта клавиш по умолчанию для чтения из минибуфера. По умолчанию она устанавливает следующие привязки:

C-j

exit-minibuffer

RET

exit-minibuffer

M-<

minibuffer-beginning-of-buffer

C-g

abort-recursive-edit

M-n
DOWN

next-history-element

M-p
UP

previous-history-element

M-s

next-matching-history-element

M-r

previous-matching-history-element

Переменная minibuffer-mode-map является псевдонимом для этой переменной.

Функция: read-no-blanks-input prompt &optional initial inherit-input-method

Эта функция читает строку из минибуфера, но не позволяет пробельным символам быть частью ввода: вместо этого такие символы завершают ввод. Аргументы prompt, initial и inherit-input-method используются так же, как в read-from-minibuffer.

Это упрощённый интерфейс к функции read-from-minibuffer, передающий значение карты клавиш minibuffer-local-ns-map в качестве аргумента keymap для этой функции. Поскольку карта клавиш minibuffer-local-ns-map не переназначает C-q, можно вставить пробел в строку, экранируя его.

Переменная: minibuffer-local-ns-map

Эта встроенная переменная является картой клавиш, используемой как локальная карта минибуфера в функции read-no-blanks-input. По умолчанию она делает следующие привязки в дополнение к привязкам minibuffer-local-map:

SPC

exit-minibuffer

TAB

exit-minibuffer

?

self-insert-and-exit

Функция: format-prompt prompt default &rest format-args

Форматирует prompt со значением по умолчанию default в соответствии с переменной minibuffer-default-prompt-format.

minibuffer-default-prompt-format — это строка формата (по умолчанию ‘" (default %s)"’), которая определяет, как форматируется часть «по умолчанию» в приглашениях вида ‘"Local filename (default somefile): "’.

Чтобы позволить пользователям настраивать отображение, код, запрашивающий у пользователя значение (и имеющий значение по умолчанию), должен выглядеть примерно так:

(read-file-name
 (format-prompt "Local filename" file)
 nil file)

Если format-args равен nil, prompt используется как буквальная строка. Если format-args не равен nil, prompt используется как управляющая строка формата, и prompt вместе с format-args передаются в format (см. Форматирование строк).

minibuffer-default-prompt-format может быть равен ‘""’, в этом случае значения по умолчанию не отображаются.

Если default равен nil, значения по умолчанию нет, и, следовательно, строка «значение по умолчанию» не включается в результирующее значение. Если default — не nil список, первый элемент списка используется в приглашении.

Как prompt, так и minibuffer-default-prompt-format обрабатываются через substitute-command-keys (см. Подстановка привязок клавиш в документации).

Переменная: read-minibuffer-restore-windows

Если эта опция не равна nil (значение по умолчанию), получение ввода из минибуфера восстанавливает при выходе конфигурации окон того фрейма, из которого был вызван минибуфер, и, если он отличается, фрейма, которому принадлежит окно минибуфера. Это означает, что если, например, пользователь разделил окно во время ввода из минибуфера в том же фрейме, это разделение будет отменено при выходе из минибуфера.

Если эта опция равна nil, восстановление не выполняется. Таким образом, упомянутое выше разделение окон сохранится после выхода из минибуфера.