Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

So I asked this question about directory shortcuts in a shell. The idea is I'd like to be able to open a file in /home/Documents/foo, say, by typing C-x C-f ~foo/file.

So, is there a way to emulate zsh's "named directories" in the emacs buffer?

Incidentally, the shortcut definitions I want to use are already in my .zshrc, if there's a solution that reads them directly, that gets bonus points.

share|improve this question
    
Perhaps this isn't a unix SE question and I should try my luck on SU? –  Seamus Sep 6 '10 at 20:17
    
this question isn't unix-specific (even down to the zsh part: there's a zsh port for Windows, or at least for Cygwin), so it should be on SU. But, well, it's here now, so I answered it here. –  Gilles Sep 6 '10 at 22:16
add comment

2 Answers

up vote 7 down vote accepted

The Emacs component that's responsible for expanding ~ in file names is expand-file-name. Unfortunately, it's written in C, and deep inside its bowels is code that assumes that what comes after ~ is a user name. Fortunately, Emacs has a generic way of adding a wrapper around functions, so you can do what you want if you don't mind repeating some of the logic in the built-in function.

Here's some completely untested code that should get you going. Look up “Advising Emacs Lisp Functions” in the Emacs Lisp manual for more information; the basic idea is that defadvice adds some code to run before the actual code of expand-file-name. Please signal the mistakes I've inevitably made in comments (whether you know how to fix them or not).

(ad-define-subr-args 'expand-file-name '(name &optional default-directory))
(defvar expand-file-name-custom-tilde-alist
  '("foo" . "/home/Documents/foo"))
(defadvice expand-file-name (before expand-file-name-custom-tilde
                             activate compile)
  "User-defined expansions for ~NAME in file names."
  (save-match-data
    (if (string-match "\\`\\(\\(.*/\\)?~\\([^:/]+\\)\\)/" name)
        (let ((replacement (assoc (match-string 2 name) expand-file-name )))
          (if replacement
              (setq name (replace-match replacement t t name 1)))))))

I'll leave parsing the shortcuts in .zshrc to fill expand-file-name-custom-tilde-alist (or whatever technique you choose to keep the aliases in synch) as an exercise.

share|improve this answer
add comment

Simply use $foo instead of ~foo in the minibuffer. Emacs will treat foo as the name of an environment variable and use its value.

share|improve this answer
    
What a killer hidden feature! (remark: export the variable for them to be available) –  AdrieanKhisbe Feb 15 at 23:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.