Function: abbreviate-file-name
abbreviate-file-name is a byte-compiled function defined in
files.el.gz.
Signature
(abbreviate-file-name FILENAME)
Documentation
Return a version of FILENAME shortened using directory-abbrev-alist.
This also substitutes "~" for the user's home directory (unless the home directory is a root directory).
When this function is first called, it caches the user's home
directory as a regexp in abbreviated-home-dir, and reuses it
afterwards (so long as the home directory does not change;
if you want to permanently change your home directory after having
started Emacs, set abbreviated-home-dir to nil so it will be recalculated).
Other relevant functions are documented in the file-name group.
Probably introduced at or before Emacs version 22.1.
Shortdoc
;; file-name
(abbreviate-file-name "/home/some-user")
e.g. => "~some-user"
Aliases
viper-abbreviate-file-name (obsolete since 27.1)
f-abbrev
f-short
Source Code
;; Defined in /usr/src/emacs/lisp/files.el.gz
(defun abbreviate-file-name (filename)
"Return a version of FILENAME shortened using `directory-abbrev-alist'.
This also substitutes \"~\" for the user's home directory (unless the
home directory is a root directory).
When this function is first called, it caches the user's home
directory as a regexp in `abbreviated-home-dir', and reuses it
afterwards (so long as the home directory does not change;
if you want to permanently change your home directory after having
started Emacs, set `abbreviated-home-dir' to nil so it will be recalculated)."
;; Get rid of the prefixes added by the automounter.
(save-match-data ;FIXME: Why?
(if-let ((handler (find-file-name-handler filename 'abbreviate-file-name)))
(funcall handler 'abbreviate-file-name filename)
;; Avoid treating /home/foo as /home/Foo during `~' substitution.
(let ((case-fold-search (file-name-case-insensitive-p filename)))
;; If any elt of directory-abbrev-alist matches this name,
;; abbreviate accordingly.
(setq filename (directory-abbrev-apply filename))
;; Compute and save the abbreviated homedir name.
;; We defer computing this until the first time it's needed, to
;; give time for directory-abbrev-alist to be set properly.
(unless abbreviated-home-dir
(put 'abbreviated-home-dir 'home (expand-file-name "~"))
(setq abbreviated-home-dir
(directory-abbrev-make-regexp
(let ((abbreviated-home-dir "\\`\\'.")) ;Impossible regexp.
(abbreviate-file-name
(get 'abbreviated-home-dir 'home))))))
;; If FILENAME starts with the abbreviated homedir,
;; and ~ hasn't changed since abbreviated-home-dir was set,
;; make it start with `~' instead.
;; If ~ has changed, we ignore abbreviated-home-dir rather than
;; invalidating it, on the assumption that a change in HOME
;; is likely temporary (eg for testing).
;; FIXME Is it even worth caching abbreviated-home-dir?
;; Ref: https://debbugs.gnu.org/19657#20
(let (mb1)
(if (and (string-match abbreviated-home-dir filename)
(setq mb1 (match-beginning 1))
;; If the home dir is just /, don't change it.
(not (and (= (match-end 0) 1)
(= (aref filename 0) ?/)))
;; MS-DOS root directories can come with a drive letter;
;; Novell Netware allows drive letters beyond `Z:'.
(not (and (memq system-type '(ms-dos windows-nt cygwin))
(string-match "\\`[a-zA-`]:/\\'" filename)))
(equal (get 'abbreviated-home-dir 'home)
(expand-file-name "~")))
(setq filename
(concat "~"
(substring filename mb1))))
filename)))))