@cindex file name abbreviations
@cindex abbreviated file names
+@vindex directory-abbrev-alist
@defun abbreviate-file-name filename
@anchor{abbreviate-file-name}
This function returns an abbreviated form of @var{filename}. It
nil
"Alist of abbreviations for file directories.
A list of elements of the form (FROM . TO), each meaning to replace
-FROM with TO when it appears in a directory name. This replacement is
-done when setting up the default directory of a newly visited file.
+a match for FROM with TO when a directory name matches FROM. This
+replacement is done when setting up the default directory of a
+newly visited file buffer.
-FROM is matched against directory names anchored at the first
-character, so it should start with a \"\\\\\\=`\", or, if directory
-names cannot have embedded newlines, with a \"^\".
+FROM is a regexp that is matched against directory names anchored at
+the first character, so it should start with a \"\\\\\\=`\", or, if
+directory names cannot have embedded newlines, with a \"^\".
FROM and TO should be equivalent names, which refer to the
-same directory. Do not use `~' in the TO strings;
-they should be ordinary absolute directory names.
+same directory. TO should be an absolute directory name.
+Do not use `~' in the TO strings.
Use this feature when you have directories which you normally refer to
via absolute symbolic links. Make TO the name of the link, and FROM
-the name it is linked to."
+a regexp matching the name it is linked to."
:type '(repeat (cons :format "%v"
:value ("\\`" . "")
(regexp :tag "From")
(make-obsolete-variable 'automount-dir-prefix 'directory-abbrev-alist "24.3")
(defvar abbreviated-home-dir nil
- "The user's homedir abbreviated according to `directory-abbrev-alist'.")
+ "Regexp matching the user's homedir at the beginning of file name.
+The value includes abbreviation according to `directory-abbrev-alist'.")
(defun abbreviate-file-name (filename)
"Return a version of FILENAME shortened using `directory-abbrev-alist'.
(or abbreviated-home-dir
(setq abbreviated-home-dir
(let ((abbreviated-home-dir "$foo"))
- (concat "\\`" (abbreviate-file-name (expand-file-name "~"))
- "\\(/\\|\\'\\)"))))
+ (setq abbreviated-home-dir
+ (concat "\\`"
+ (abbreviate-file-name (expand-file-name "~"))
+ "\\(/\\|\\'\\)"))
+ ;; Depending on whether default-directory does or
+ ;; doesn't include non-ASCII characters, the value
+ ;; of abbreviated-home-dir could be multibyte or
+ ;; unibyte. In the latter case, we need to decode
+ ;; it. Note that this function is called for the
+ ;; first time (from startup.el) when
+ ;; locale-coding-system is already set up.
+ (if (multibyte-string-p abbreviated-home-dir)
+ abbreviated-home-dir
+ (decode-coding-string abbreviated-home-dir
+ (if (eq system-type 'windows-nt)
+ 'utf-8
+ locale-coding-system))))))
;; If FILENAME starts with the abbreviated homedir,
;; make it start with `~' instead.
;; terminal-coding-system with the ANSI or console codepage.
(when (and (eq system-type 'windows-nt)
(boundp 'w32-ansi-code-page))
- (let* ((code-page-coding
- (intern (format "cp%d" (if noninteractive
- (w32-get-console-codepage)
- w32-ansi-code-page))))
+ (let* ((ansi-code-page-coding
+ (intern (format "cp%d" w32-ansi-code-page)))
+ (code-page-coding
+ (if noninteractive
+ (intern (format "cp%d" (w32-get-console-codepage)))
+ ansi-code-page-coding))
(output-coding
(if noninteractive
(intern (format "cp%d" (w32-get-console-output-codepage)))
(unless frame (setq locale-coding-system code-page-coding))
(set-keyboard-coding-system code-page-coding frame)
(set-terminal-coding-system output-coding frame)
- (setq default-file-name-coding-system code-page-coding))))
+ (setq default-file-name-coding-system ansi-code-page-coding))))
(when (eq system-type 'darwin)
;; On Darwin, file names are always encoded in utf-8, no matter
to have non-stub implementations of APIs we need to convert file
names between UTF-8 and the system's ANSI codepage. */
maybe_load_unicows_dll ();
+ /* Initialize the codepage for file names, needed to decode
+ non-ASCII file names during startup. */
+ w32_init_file_name_codepage ();
#endif
/* This has to be done before module_init is called below, so that
the latter could use the thread ID of the main thread. */
if (!(newdir = egetenv ("HOME")))
newdir = newdirlim = "";
nm++;
- /* `egetenv' may return a unibyte string, which will bite us since
- we expect the directory to be multibyte. */
#ifdef WINDOWSNT
if (newdir[0])
{
filename_from_ansi (newdir, newdir_utf8);
tem = make_unibyte_string (newdir_utf8, strlen (newdir_utf8));
+ newdir = SSDATA (tem);
}
else
#endif
tem = build_string (newdir);
newdirlim = newdir + SBYTES (tem);
+ /* `egetenv' may return a unibyte string, which will bite us
+ if we expect the directory to be multibyte. */
if (multibyte && !STRING_MULTIBYTE (tem))
{
hdir = DECODE_FILE (tem);
newdir = pw->pw_dir;
/* `getpwnam' may return a unibyte string, which will
- bite us since we expect the directory to be
- multibyte. */
+ bite us when we expect the directory to be multibyte. */
tem = make_unibyte_string (newdir, strlen (newdir));
newdirlim = newdir + SBYTES (tem);
if (multibyte && !STRING_MULTIBYTE (tem))
/* Current codepage for encoding file names. */
static int file_name_codepage;
+/* Initialize the codepage used for decoding file names. This is
+ needed to undo the value recorded during dumping, which might not
+ be correct when we run the dumped Emacs. */
+void
+w32_init_file_name_codepage (void)
+{
+ file_name_codepage = CP_ACP;
+ w32_ansi_code_page = CP_ACP;
+}
+
/* Produce a Windows ANSI codepage suitable for encoding file names.
Return the information about that codepage in CP_INFO. */
int
if (NILP (current_encoding))
current_encoding = Vdefault_file_name_coding_system;
- if (!EQ (last_file_name_encoding, current_encoding))
+ if (!EQ (last_file_name_encoding, current_encoding)
+ || NILP (last_file_name_encoding))
{
/* Default to the current ANSI codepage. */
file_name_codepage = w32_ansi_code_page;
- if (NILP (current_encoding))
+ if (!NILP (current_encoding))
{
char *cpname = SSDATA (SYMBOL_NAME (current_encoding));
char *cp = NULL, *end;
if (!GetCPInfo (file_name_codepage, &cp))
emacs_abort ();
}
+
+ /* Cache the new value. */
+ last_file_name_encoding = current_encoding;
}
if (cp_info)
*cp_info = cp;
extern int filename_to_ansi (const char *, char *);
extern int filename_from_utf16 (const wchar_t *, char *);
extern int filename_to_utf16 (const char *, wchar_t *);
+extern void w32_init_file_name_codepage (void);
extern int codepage_for_filenames (CPINFO *);
extern Lisp_Object ansi_encode_filename (Lisp_Object);
extern int w32_copy_file (const char *, const char *, int, int, int);
This variable is set to non-nil by default when Emacs runs on Windows
systems of the NT family, including W2K, XP, Vista, Windows 7 and
Windows 8. It is set to nil on Windows 9X. */);
- w32_unicode_filenames = 0;
+ if (os_subtype == OS_9X)
+ w32_unicode_filenames = 0;
+ else
+ w32_unicode_filenames = 1;
/* FIXME: The following variable will be (hopefully) removed