Atalhos de diretório no buffer emacs

8

Então, fiz esta pergunta sobre atalhos de diretório em um shell. A idéia é que eu gostaria de poder abrir um arquivo /home/Documents/foodigitando C-x C-f ~foo/file.

Então, existe uma maneira de emular os "diretórios nomeados" do zsh no buffer do emacs?

Aliás, as definições de atalho que eu quero usar já estão no meu .zshrc, se houver uma solução que as leia diretamente, que receba pontos de bônus.

Seamus
fonte
Talvez essa não seja uma pergunta unix do SE e eu deveria tentar a sorte no SU?
Seamus
essa pergunta não é específica para unix (até a parte zsh: existe uma porta zsh para Windows ou, pelo menos, para Cygwin); portanto, ela deve estar no SU. Mas, bem, está aqui agora, então eu respondi aqui.
Gilles 'SO- stop be evil'

Respostas:

8

O componente Emacs responsável pela expansão dos ~nomes dos arquivos é expand-file-name. Infelizmente, está escrito em C, e no fundo de seu intestino está o código que assume que o que vem depois ~é um nome de usuário. Felizmente, o Emacs tem uma maneira genérica de adicionar um wrapper às funções, para que você possa fazer o que quiser se não se importar em repetir parte da lógica na função interna.

Aqui está um código completamente não testado que deve ajudá-lo. Consulte “Orientando as funções do Emacs Lisp” no manual do Emacs Lisp para obter mais informações; a idéia básica é que defadviceadicione algum código para executar antes do código real de expand-file-name. Por favor, indique os erros que cometi inevitavelmente nos comentários (se você sabe como corrigi-los ou não).

(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)))))))

Vou deixar de analisar os atalhos .zshrcpara preencher expand-file-name-custom-tilde-alist(ou qualquer outra técnica que você escolher para manter os aliases sincronizados) como um exercício.

Gilles 'SO- parar de ser mau'
fonte
Minha solução de exercício:(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))
Michaël
4

Basta usar em $foovez de ~foono minibuffer. O Emacs tratará foocomo o nome de uma variável de ambiente e usará seu valor.

Friedel
fonte
Que característica escondida! (observação: exportar a variável para que eles estejam disponíveis)
AdrieanKhisbe