Ярлыки каталогов в буфере Emacs

8

Поэтому я задал этот вопрос о ярлыках каталогов в оболочке. Идея в том, что я хотел бы открыть файл /home/Documents/foo, скажем, набрав C-x C-f ~foo/file.

Итак, есть ли способ эмулировать "именованные каталоги" zsh в буфере emacs?

Кстати, определения ярлыков, которые я хочу использовать, уже есть в моем .zshrc, если есть решение, которое читает их напрямую, которое получает бонусные баллы.

Симус
источник
Возможно, это не вопрос Unix SE, и я должен попытать счастья на SU?
Симус
Этот вопрос не специфичен для Unix (даже до zsh: есть порт zsh для Windows или, по крайней мере, для Cygwin), поэтому он должен быть на SU. Но, ну, это здесь и сейчас, поэтому я ответил здесь.
Жиль "ТАК - перестань быть злым"

Ответы:

8

Компонент Emacs, который отвечает за расширение ~имен файлов expand-file-name. К сожалению, он написан на C, и глубоко внутри его кишечника находится код, который предполагает, что последующим ~является имя пользователя. К счастью, в Emacs есть общий способ добавления обертки вокруг функций, поэтому вы можете делать все, что хотите, если не возражаете повторить некоторую логику во встроенной функции.

Вот некоторый полностью непроверенный код, который должен помочь вам. Для получения дополнительной информации обратитесь к разделу «Советы по функциям Emacs Lisp» в руководстве по Emacs Lisp. Основная идея заключается в том, что defadviceдобавляет некоторый код для запуска перед фактическим кодом expand-file-name. Пожалуйста, отметьте ошибки, которые я неизбежно сделал в комментариях (знаете ли вы, как их исправить или нет).

(defvar expand-file-name-custom-tilde-alist
  '(("foo" . "/home/Documents/foo")))

(defadvice expand-file-name (before expand-file-name-custom-tilde
                             (name &optional default-directory)
                             activate compile)
  "User-defined expansions for ~NAME in file names."
  (save-match-data
    (when (string-match "\\`\\(\\(.*/\\)?~\\([^:/]+\\)\\)/" name)
      (let ((replacement (assoc (match-string 3 name) expand-file-name-custom-tilde-alist)))
        (when replacement
          (setq name (replace-match (cdr replacement) t t name 1)))))))

Я оставлю разбор ярлыков, .zshrcчтобы заполнить expand-file-name-custom-tilde-alist(или любой другой метод, который вы выберете, чтобы синхронизировать псевдонимы) в качестве упражнения.

Жиль "ТАК - перестань быть злым"
источник
Мое решение для упражнений:(defun my/add-to-tilde-alist (hash) (let* ((tilde:dir (split-string hash "=")) (tilde (car tilde:dir)) (dir (cadr tilde:dir))) (push (cons tilde dir) expand-file-name-custom-tilde-alist))) (mapc #'my/add-to-tilde-alist (split-string (with-output-to-string (call-process "zsh" nil standard-output nil "-ic" "hash -d")) "\n" t))
Михаэль
4

Просто используйте $fooвместо ~fooминибуфера. Emacs будет обрабатывать fooкак имя переменной окружения и использовать ее значение.

Фридель
источник
Какая убийца скрытая особенность! (примечание: экспортируйте переменную, чтобы они были доступны)
AdrieanKhisbe