Spec-Zone.ru › Elisp

Настройка «магических» имён файлов

Вы можете реализовать специальную обработку для определённых имён файлов. Это называется магическими именами. Основное применение этой функции — в реализации доступа к удалённым файлам (см. Удалённые файлы в Справочнике GNU Emacs).

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

Переменная file-name-handler-alist содержит список обработчиков вместе с регулярными выражениями, определяющими, когда применять каждый обработчик. Каждый элемент имеет такой вид:

(regexp . handler)

Все примитивы Emacs для доступа к файлам и преобразования имён файлов проверяют указанное имя файла на соответствие file-name-handler-alist. Если имя файла соответствует regexp, примитивы обрабатывают этот файл, вызвав handler.

Первый аргумент, передаваемый handler, — это имя примитива в виде символа; остальные аргументы — аргументы, переданные этому примитиву. (Первый из этих аргументов чаще всего является самим именем файла). Например, если вы сделаете так:

(file-exists-p filename)

и у filename есть обработчик handler, то handler вызывается так:

(funcall handler 'file-exists-p filename)

Когда функция принимает два или более аргументов, которые должны быть именами файлов, она проверяет каждое из этих имён на наличие обработчика. Например, если вы сделаете так:

(expand-file-name filename dirname)

то она проверит наличие обработчика для filename, а затем для dirname. В любом случае, handler вызывается так:

(funcall handler 'expand-file-name filename dirname)

Затем handler должен определить, обрабатывать ли filename или dirname.

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

Вот операции, которые может обрабатывать обработчик магических имён файлов:

access-file, add-name-to-file, byte-compiler-base-file-name, copy-directory, copy-file, delete-directory, delete-file, diff-latest-backup-file, directory-file-name, directory-files, directory-files-and-attributes, dired-compress-file, dired-uncache, exec-path, expand-file-name, file-accessible-directory-p, file-acl, file-attributes, file-directory-p, file-equal-p, file-executable-p, file-exists-p, file-in-directory-p, file-local-copy, file-locked-p, file-modes, file-name-all-completions, file-name-as-directory, file-name-case-insensitive-p, file-name-completion, file-name-directory, file-name-nondirectory, file-name-sans-versions, file-newer-than-file-p, file-notify-add-watch, file-notify-rm-watch, file-notify-valid-p, file-ownership-preserved-p, file-readable-p, file-regular-p, file-remote-p, file-selinux-context, file-symlink-p, file-system-info, file-truename, file-writable-p, find-backup-file-name, get-file-buffer, insert-directory, insert-file-contents, load, lock-file, make-auto-save-file-name, make-directory, make-directory-internal, make-lock-file-name, make-nearby-temp-file, make-process, make-symbolic-link, process-file, rename-file, set-file-acl, set-file-modes, set-file-selinux-context, set-file-times, set-visited-file-modtime, shell-command, start-file-process, substitute-in-file-name, temporary-file-directory, unhandled-file-name-directory, unlock-file, vc-registered, verify-visited-file-modtime, write-region.

Обработчики для insert-file-contents обычно должны сбрасывать флаг изменения буфера с помощью (set-buffer-modified-p nil), если аргумент visit не равен nil. Это также приводит к разблокировке буфера, если он заблокирован.

Функция обработчика должна обрабатывать все вышеперечисленные операции, а возможно и другие, которые могут быть добавлены в будущем. Она не обязана сама реализовывать все эти операции — когда ей нечего делать для определённой операции, она может повторно вызвать примитив, чтобы обработать операцию обычным способом. Она всегда должна повторно вызывать примитив для операции, которую не распознаёт. Вот один способ сделать это:

(defun my-file-handler (operation &rest args)
  ;; First check for the specific operations
  ;; that we have special handling for.
  (cond ((eq operation 'insert-file-contents) …)
        ((eq operation 'write-region) …)
        …
        ;; Handle any operation we don’t know about.
        (t (let ((inhibit-file-name-handlers
                  (cons 'my-file-handler
                        (and (eq inhibit-file-name-operation operation)
                             inhibit-file-name-handlers)))
                 (inhibit-file-name-operation operation))
             (apply operation args)))))

Когда функция обработчика решает вызвать обычный примитив Emacs для текущей операции, ей необходимо предотвратить повторное обращение примитива к тому же обработчику, что приведёт к бесконечной рекурсии. Приведённый пример показывает, как это сделать, используя переменные inhibit-file-name-handlers и inhibit-file-name-operation. Обратите внимание на точное следование вышеуказанному примеру; детали имеют решающее значение для правильной работы в случае множества обработчиков и для операций, имеющих два имени файлов, которые могут иметь обработчики.

Обработчики, которые не выполняют каких-либо особых действий при фактическом доступе к файлу (например, те, которые реализуют завершение имён хостов для имён удалённых файлов), должны иметь свойство, отличное от nil safe-magic. Например, Emacs обычно защищает имена каталогов, которые находит в PATH, от преобразования в магические, если они похожи на магические имена файлов, добавляя к ним префикс «/:». Но если обработчик, который должен использоваться для них, имеет свойство, отличное от nil safe-magic, префикс «/:» не добавляется.

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

Простое делегирование всех операций к обычным примитивам не работает. Например, если обработчик имени файла применяется к file-exists-p, то он должен сам обрабатывать load, поскольку обычный код load в этом случае не будет работать должным образом. Однако, если обработчик использует свойство operations для указания того, что он не обрабатывает file-exists-p, то он не обязан обрабатывать load нетривиальным образом.

Переменная: inhibit-file-name-handlers

Эта переменная содержит список обработчиков, использование которых в данный момент запрещено для определённой операции.

Переменная: inhibit-file-name-operation

Операция, для которой некоторые обработчики в настоящее время запрещены.

Функция: find-file-name-handler операция с файлом

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

Функция: file-local-copy имя файла

Эта функция копирует файл filename в обычный локальный файл без магических свойств, если он ещё не находится на локальной машине. Магические имена файлов должны обрабатывать операцию file-local-copy если они ссылаются на файлы на других машинах. Магическое имя файла, используемое для целей, отличных от доступа к удалённым файлам, не должно обрабатывать file-local-copy; в этом случае функция будет рассматривать файл как локальный.

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

Функция: file-remote-p имя файла &optional идентификация подключение

Эта функция проверяет, является ли filename удалённым файлом. Если filename локальный (не удалённый), возвращаемое значение равно nil. Если filename действительно удалённый, возвращаемое значение — строка, идентифицирующая удалённую систему.

Эта строка идентификатора может включать имя хоста и имя пользователя, а также символы, обозначающие метод доступа к удалённой системе. Например, строка идентификатора для имени файла /sudo::/some/file равна /sudo:root@localhost:.

Если file-remote-p возвращает один и тот же идентификатор для двух разных имён файлов, это означает, что они хранятся в одной файловой системе и могут быть доступны локально относительно друг друга. Это означает, например, что возможно запустить удалённый процесс, обращаясь к обоим файлам одновременно. Реализаторы обработчиков имён файлов должны гарантировать, что это правило выполняется.

идентификация указывает, какая часть идентификатора должна быть возвращена как строка. идентификация может быть символом method, user или host; любое другое значение обрабатывается как nil и означает возврат всей строки идентификатора. В примере выше, строкой идентификатора удалённого user будет root.

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

Функция: unhandled-file-name-directory имя файла

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

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

END_OF_DOCUMENT_MARKER
Функция: file-local-name имя файла

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

(file-local-name "/ssh:user@host:/foo/bar")
     ⇒ "/foo/bar"

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

Пользовательский параметр: remote-file-name-inhibit-cache

Атрибуты удалённых файлов могут кэшироваться для повышения производительности. Если они изменены вне контроля Emacs, кэшированные значения становятся недействительными и должны быть перечитаны.

Если эта переменная установлена в nil, кэшированные значения никогда не истекают. Используйте эту настройку с осторожностью, только если вы уверены, что ничего кроме Emacs не изменяет удалённые файлы. Если она установлена в t, кэшированные значения никогда не используются. Это самое безопасное значение, но может привести к снижению производительности.

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

(defun display-time-file-nonempty-p (file)
  (let ((remote-file-name-inhibit-cache
         (- display-time-interval 5)))
    (and (file-exists-p file)
         (< 0 (file-attribute-size
               (file-attributes
                (file-chase-links file)))))))

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/Magic-File-Names.html

Spec-Zone.ru

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