Раскрытие имени файла означает преобразование относительного имени файла в абсолютное. Поскольку это делается относительно каталога по умолчанию, вы должны указать как каталог по умолчанию, так и имя файла, которое нужно раскрыть. Это также включает раскрытие сокращений, таких как ~/ (см. abbreviate-file-name), и устранение избыточностей, таких как ./ и имя/../.
Эта функция преобразует filename в абсолютное имя файла. Если указан directory, он является каталогом по умолчанию, с которого начинается, если filename является относительным и не начинается с ‘~’.
(Значение directory должно
само быть абсолютным именем каталога или именем файла-каталога; оно может
начинаться с ‘~’.) В противном случае используется значение default-directory текущего буфера. Например:
(expand-file-name "foo")
⇒ "/xcssun/users/rms/lewis/foo"
(expand-file-name "../foo")
⇒ "/xcssun/users/rms/foo"
(expand-file-name "foo" "/usr/spool/")
⇒ "/usr/spool/foo"
Если часть filename перед первой косой чертой — это
‘~’, она раскрывается в ваш домашний каталог, который обычно
задаётся значением переменной окружения HOME
(см. Общие переменные в Руководстве по GNU Emacs).
Если часть перед первой
косой чертой — это ‘~user’ и если user является допустимым именем для входа,
она раскрывается в домашний каталог user.
Если вы не хотите такого раскрытия для относительного filename, который
может начинаться с буквального ‘~’, вы можете использовать (concat
(file-name-as-directory directory) filename) вместо
(expand-file-name filename directory).
Имена файлов, содержащие ‘.’ или ‘..’, упрощаются до их канонической формы:
(expand-file-name "bar/../foo")
⇒ "/xcssun/users/rms/lewis/foo"
В некоторых случаях ведущий компонент ‘..’ может остаться в выводе:
(expand-file-name "../home" "/")
⇒ "/../home"
Это сделано ради файловых систем, в которых существует понятие супер-корня над корневым каталогом /. В других файловых системах /../ интерпретируется точно так же, как /.
Раскрытие . или пустой строки возвращает каталог по умолчанию:
(expand-file-name "." "/usr/spool/")
⇒ "/usr/spool"
(expand-file-name "" "/usr/spool/")
⇒ "/usr/spool"
Обратите внимание, что expand-file-name не раскрывает переменные
окружения; это делает только substitute-in-file-name:
(expand-file-name "$HOME/foo")
⇒ "/xcssun/users/rms/lewis/$HOME/foo"
Также обратите внимание, что expand-file-name не переходит по символическим ссылкам
на любом уровне. Это приводит к различию между тем, как
file-truename и expand-file-name обрабатывают ‘..’.
Предполагая, что ‘/tmp/bar’ является символической ссылкой на каталог
‘/tmp/foo/bar’, получаем:
(file-truename "/tmp/bar/../myfile")
⇒ "/tmp/foo/myfile"
(expand-file-name "/tmp/bar/../myfile")
⇒ "/tmp/myfile"
Если вам может понадобиться переходить по символическим ссылкам, предшествующим ‘..’, вам
следует вызывать file-truename без предварительных прямых или
косвенных вызовов expand-file-name. См. Истинные имена.
Значение этой буферно-локальной переменной является каталогом по умолчанию для текущего буфера. Оно должно быть абсолютным именем каталога; может начинаться с ‘~’. Эта переменная является буферно-локальной в каждом буфере.
expand-file-name использует каталог по умолчанию, когда его второй
аргумент равен nil.
Значение всегда является строкой, оканчивающейся косой чертой.
default-directory
⇒ "/user/lewis/manual/"
Эта функция заменяет ссылки на переменные окружения в filename значениями переменных окружения. Следуя стандартному синтаксису Unix-оболочки, ‘$’ является префиксом для подстановки значения переменной окружения. Если входное значение содержит ‘$$’, оно преобразуется в ‘$’; это даёт пользователю способ экранировать ‘$’.
Имя переменной окружения — это последовательность буквенно-цифровых символов (включая символы подчёркивания), следующих за ‘$’. Если символ после ‘$’ — это ‘{’, то именем переменной является всё до соответствующей ‘}’.
Вызов substitute-in-file-name для вывода, полученного от
substitute-in-file-name, как правило, даёт неверные результаты. Например,
использование ‘$$’ для экранирования одного ‘$’ не будет работать
должным образом, а ‘$’ в значении переменной окружения может привести
к повторной подстановке. Поэтому программы, которые вызывают эту функцию
и помещают вывод туда, где он будет передан этой функции, должны
удваивать все символы ‘$’, чтобы предотвратить последующие неверные
результаты.
Здесь мы предполагаем, что переменная окружения HOME, которая содержит
домашний каталог пользователя, имеет значение ‘/xcssun/users/rms’.
(substitute-in-file-name "$HOME/foo")
⇒ "/xcssun/users/rms/foo"
После подстановки, если ‘~’ или ‘/’ появляется непосредственно после другого ‘/’, функция отбрасывает всё перед ним (включая непосредственно предшествующий ‘/’).
(substitute-in-file-name "bar/~/foo")
⇒ "~/foo"
(substitute-in-file-name "/usr/local/$HOME/foo")
⇒ "/xcssun/users/rms/foo"
;; /usr/local/ был отброшен.
Иногда раскрывать имена файлов нежелательно. В таких случаях имя файла можно заключить в кавычки, чтобы подавить раскрытие и обрабатывать имя файла буквально. Экранирование выполняется путём добавления к имени файла префикса ‘/:’.
Этот макрос добавляет префикс экранирования ‘/:’ к файлу name. Для локального файла name он добавляет к name префикс ‘/:’. Если name — это удалённое имя файла, локальная часть name (см. Превращение некоторых имён файлов в “волшебные”) заключается в кавычки. Если name уже является экранированным именем файла, возвращается name без изменений.
(substitute-in-file-name (file-name-quote "bar/~/foo"))
⇒ "/:bar/~/foo"
(substitute-in-file-name (file-name-quote "/ssh:host:bar/~/foo"))
⇒ "/ssh:host:/:bar/~/foo"
Макрос не может использоваться для подавления обработчиков имён файлов для волшебных имён файлов (см. Превращение некоторых имён файлов в “волшебные”).
Этот макрос удаляет префикс экранирования ‘/:’ из файла name, если он есть. Если name — это удалённое имя файла, локальная часть name раскрывается.
Этот макрос возвращает не nil, если name экранировано с помощью
префикса ‘/:’. Если name — это удалённое имя файла, проверяется локальная
часть name.