21.6.5 Чтение имён файлов

Функции завершения высокого уровня read-file-name, read-directory-name и read-shell-command предназначены для чтения имён файлов, имён каталогов и команд оболочки соответственно. Они предоставляют специальные возможности, включая автоматическую вставку каталога по умолчанию.

Функция: read-file-name prompt &optional directory default require-match initial predicate

Эта функция читает имя файла, выводя приглашение prompt и предоставляя завершение.

В виде исключения эта функция читает имя файла с использованием графического диалога выбора файла вместо минибуфера, если выполняются все следующие условия:

  1. Она вызвана через команду мыши.
  2. Выбранный фрейм находится на графическом дисплее, поддерживающем такие диалоги.
  3. Переменная use-dialog-box не равна nil. См. Диалоговые окна в Руководстве GNU Emacs.
  4. Аргумент directory, описанный ниже, не задаёт удалённый файл. См. Удалённые файлы в Руководстве GNU Emacs.

Точное поведение при использовании графического диалога выбора файла зависит от платформы. Здесь мы описываем только поведение при использовании минибуфера.

read-file-name автоматически не раскрывает возвращаемое имя файла. Вы можете вызвать expand-file-name самостоятельно, если требуется абсолютное имя файла.

Необязательный аргумент require-match имеет тот же смысл, что и в completing-read. См. Завершение и минибуфер.

Аргумент directory задаёт каталог, используемый для завершения относительных имён файлов. Это должно быть абсолютное имя каталога. Если переменная insert-default-directory не равна nil, directory также вставляется в минибуфер как начальный ввод. По умолчанию используется значение default-directory текущего буфера.

Если вы задаёте initial, это начальное имя файла для вставки в буфер (после directory, если он вставлен). В этом случае точка помещается в начало initial. По умолчанию для initial используется nil — не вставлять никакого имени файла. Чтобы увидеть, что делает initial, попробуйте команду C-x C-v в буфере, посещающем файл. Обратите внимание: мы рекомендуем использовать default вместо initial в большинстве случаев.

Если default не равен nil, то функция возвращает default, если пользователь выходит из минибуфера с тем же непустым содержимым, которое read-file-name вставил изначально. Начальное содержимое минибуфера всегда непусто, если insert-default-directory не равен nil, как это и бывает по умолчанию. default не проверяется на корректность, независимо от значения require-match. Однако если require-match не равен nil, начальное содержимое минибуфера должно быть корректным именем файла (или каталога). В противном случае read-file-name пытается выполнить завершение, если пользователь выходит без каких-либо правок, и не возвращает default. default также доступен через команды истории.

Если default равен nil, read-file-name пытается найти заменяемое значение по умолчанию для использования вместо него, которое он обрабатывает точно так же, как если бы оно было задано явно. Если default равен nil, но initial не равен nil, то значением по умолчанию является абсолютное имя файла, полученное из directory и initial. Если и default, и initial равны nil, а буфер посещает файл, read-file-name использует абсолютное имя этого файла в качестве значения по умолчанию. Если буфер не посещает файл, то значения по умолчанию нет. В этом случае, если пользователь нажимает RET без каких-либо правок, read-file-name просто возвращает предварительно вставленное содержимое минибуфера.

Если пользователь нажимает RET в пустом минибуфере, эта функция возвращает пустую строку, независимо от значения require-match. Это, например, позволяет пользователю сделать так, чтобы текущий буфер не посещал никакой файл, с помощью M-x set-visited-file-name.

Если predicate не равен nil, он задаёт функцию одного аргумента, которая определяет, какие имена файлов являются допустимыми альтернативами завершения. Имя файла является допустимым значением, если predicate возвращает не nil для него.

Вот пример использования read-file-name:

(read-file-name "Файл: ")

;; После вычисления предыдущего выражения
;;   в минибуфере появляется следующее:

---------- Буфер: Минибуфер ----------
Файл: /gp/gnu/elisp/∗
---------- Буфер: Минибуфер ----------

Ввод manual TAB даёт следующий результат:

---------- Буфер: Минибуфер ----------
Файл: /gp/gnu/elisp/manual.texi∗
---------- Буфер: Минибуфер ----------

Если пользователь нажимает RET, read-file-name возвращает имя файла в виде строки "/gp/gnu/elisp/manual.texi".

Переменная: read-file-name-function

Если не равна nil, это должна быть функция, принимающая те же аргументы, что и read-file-name. Когда вызывается read-file-name, она вызывает эту функцию с переданными аргументами вместо выполнения своей обычной работы.

Пользовательская опция: read-file-name-completion-ignore-case

Если эта переменная не равна nil, read-file-name игнорирует регистр при выполнении завершения.

Функция: read-directory-name prompt &optional directory default require-match initial

Эта функция подобна read-file-name, но допускает в качестве альтернатив завершения только имена каталогов.

Если default равен nil, а initial не равен nil, read-directory-name конструирует заменяемое значение по умолчанию, комбинируя directory (или каталог по умолчанию текущего буфера, если directory равен nil) и initial. Если и default, и initial равны nil, эта функция использует directory в качестве заменяемого значения по умолчанию или каталог по умолчанию текущего буфера, если directory равен nil.

Пользовательская опция: insert-default-directory

Эта переменная используется read-file-name и, следовательно, косвенно, большинством команд, читающих имена файлов. (Это включает все команды, которые используют кодовые буквы ‘f’ или ‘F’ в своей интерактивной форме. См. Кодовые символы для interactive.) Её значение управляет тем, начинает ли read-file-name с размещения имени каталога по умолчанию в минибуфере, а также начального имени файла, если оно есть. Если значение этой переменной равно nil, то read-file-name не помещает никакого начального ввода в минибуфер (если только вы не зададите начальный ввод с помощью аргумента initial). В этом случае каталог по умолчанию всё равно используется для завершения относительных имён файлов, но не отображается.

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

Например:

;; Здесь минибуфер начинается с каталога по умолчанию.
(let ((insert-default-directory t))
  (read-file-name "Файл: "))

---------- Буфер: Минибуфер ----------
Файл: ~lewis/manual/∗
---------- Буфер: Минибуфер ----------

;; Здесь минибуфер пуст, и в его строке отображается
;;   только приглашение.
(let ((insert-default-directory nil))
  (read-file-name "Файл: "))

---------- Буфер: Минибуфер ----------
Файл: ∗
---------- Буфер: Минибуфер ----------
Функция: read-shell-command prompt &optional initial history &rest args

Эта функция читает команду оболочки из минибуфера, выводя приглашение prompt и предоставляя интеллектуальное завершение. Она завершает первое слово команды, используя кандидаты, подходящие для имён команд, а остальные слова команды — как имена файлов.

Эта функция использует minibuffer-local-shell-command-map в качестве карты клавиш для ввода в минибуфере. Аргумент history задаёт список истории для использования; если он опущен или равен nil, по умолчанию используется shell-command-history (см. shell-command-history). Необязательный аргумент initial задаёт начальное содержимое минибуфера (см. Начальный ввод). Остальные args, если они присутствуют, используются как аргументы default и inherit-input-method в read-from-minibuffer (см. Чтение текстовых строк с помощью минибуфера).

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

Эта карта клавиш используется read-shell-command для завершения имён команд и файлов, которые являются частью команды оболочки. Она использует minibuffer-local-map в качестве родительской карты клавиш и связывает TAB с completion-at-point.