1992-05-30 23:54:21 +00:00
|
|
|
|
;;; files.el --- file input and output commands for Emacs
|
|
|
|
|
|
2006-02-06 15:23:23 +00:00
|
|
|
|
;; Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994, 1995, 1996,
|
2010-03-18 04:54:51 +00:00
|
|
|
|
;; 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
|
|
|
|
;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1992-07-22 04:22:42 +00:00
|
|
|
|
;; Maintainer: FSF
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
2008-05-06 08:06:51 +00:00
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
1991-07-19 14:42:53 +00:00
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
2008-05-06 08:06:51 +00:00
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
2008-05-06 08:06:51 +00:00
|
|
|
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1993-03-22 03:27:18 +00:00
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; Defines most of Emacs's file- and directory-handling functions,
|
|
|
|
|
;; including basic file visiting, backup generation, link handling,
|
|
|
|
|
;; ITS-id version control, load- and write-hook handling, and the like.
|
|
|
|
|
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;;; Code:
|
|
|
|
|
|
2009-09-07 15:23:09 +00:00
|
|
|
|
(eval-when-compile (require 'cl))
|
|
|
|
|
|
2005-08-31 13:49:25 +00:00
|
|
|
|
(defvar font-lock-keywords)
|
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defgroup backup nil
|
|
|
|
|
"Backups of edited data files."
|
1997-06-18 17:24:59 +00:00
|
|
|
|
:group 'files)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defgroup find-file nil
|
1997-06-18 17:24:59 +00:00
|
|
|
|
"Finding files."
|
|
|
|
|
:group 'files)
|
1997-05-05 22:04:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defcustom delete-auto-save-files t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means delete auto-save file when a buffer is saved or killed.
|
1998-01-07 09:41:30 +00:00
|
|
|
|
|
2003-10-06 16:29:50 +00:00
|
|
|
|
Note that the auto-save file will not be deleted if the buffer is killed
|
1998-01-07 09:41:30 +00:00
|
|
|
|
when it has unsaved changes."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'auto-save)
|
|
|
|
|
|
|
|
|
|
(defcustom directory-abbrev-alist
|
1991-07-19 14:42:53 +00:00
|
|
|
|
nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Alist of abbreviations for file directories.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
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.
|
2009-11-11 19:02:35 +00:00
|
|
|
|
*Every* FROM string should start with \"\\\\`\".
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2007-10-13 14:10:21 +00:00
|
|
|
|
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.
|
1993-09-17 17:51:40 +00:00
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
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
|
1997-05-05 22:04:00 +00:00
|
|
|
|
the name it is linked to."
|
|
|
|
|
:type '(repeat (cons :format "%v"
|
|
|
|
|
:value ("" . "")
|
|
|
|
|
(regexp :tag "From")
|
|
|
|
|
(regexp :tag "To")))
|
|
|
|
|
:group 'abbrev
|
|
|
|
|
:group 'find-file)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2008-07-31 05:33:56 +00:00
|
|
|
|
(defcustom make-backup-files t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means make a backup of a file the first time it is saved.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
This can be done by renaming the file or by copying.
|
|
|
|
|
|
|
|
|
|
Renaming means that Emacs renames the existing file so that it is a
|
|
|
|
|
backup file, then writes the buffer into a new file. Any other names
|
|
|
|
|
that the old file had will now refer to the backup file. The new file
|
|
|
|
|
is owned by you and its group is defaulted.
|
|
|
|
|
|
|
|
|
|
Copying means that Emacs copies the existing file into the backup
|
|
|
|
|
file, then writes the buffer on top of the existing file. Any other
|
|
|
|
|
names that the old file had will now refer to the new (edited) file.
|
|
|
|
|
The file's owner and group are unchanged.
|
|
|
|
|
|
|
|
|
|
The choice of renaming or copying is controlled by the variables
|
2000-10-04 17:16:59 +00:00
|
|
|
|
`backup-by-copying', `backup-by-copying-when-linked',
|
|
|
|
|
`backup-by-copying-when-mismatch' and
|
|
|
|
|
`backup-by-copying-when-privileged-mismatch'. See also `backup-inhibited'."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'backup)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
;; Do this so that local variables based on the file name
|
|
|
|
|
;; are not overridden by the major mode.
|
|
|
|
|
(defvar backup-inhibited nil
|
1993-08-13 01:17:59 +00:00
|
|
|
|
"Non-nil means don't make a backup, regardless of the other parameters.
|
|
|
|
|
This variable is intended for use by making it local to a buffer.
|
|
|
|
|
But it is local only if you make it local.")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(put 'backup-inhibited 'permanent-local t)
|
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom backup-by-copying nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means always use copying to create backup files.
|
1997-05-05 22:04:00 +00:00
|
|
|
|
See documentation of variable `make-backup-files'."
|
2008-07-31 21:35:59 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'backup)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom backup-by-copying-when-linked nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means use copying to create backups for files with multiple names.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
This causes the alternate names to refer to the latest version as edited.
|
1997-05-05 22:04:00 +00:00
|
|
|
|
This variable is relevant only if `backup-by-copying' is nil."
|
2008-07-31 21:35:59 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'backup)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom backup-by-copying-when-mismatch nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means create backups by copying if this preserves owner or group.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
Renaming may still be used (subject to control of other variables)
|
|
|
|
|
when it would not result in changing the owner or group of the file;
|
|
|
|
|
that is, for files which are owned by you and whose group matches
|
|
|
|
|
the default for a new file created there by you.
|
1997-05-05 22:04:00 +00:00
|
|
|
|
This variable is relevant only if `backup-by-copying' is nil."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'backup)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defcustom backup-by-copying-when-privileged-mismatch 200
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means create backups by copying to preserve a privileged owner.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
Renaming may still be used (subject to control of other variables)
|
|
|
|
|
when it would not result in changing the owner of the file or if the owner
|
|
|
|
|
has a user id greater than the value of this variable. This is useful
|
|
|
|
|
when low-numbered uid's are used for special system users (such as root)
|
|
|
|
|
that must maintain ownership of certain files.
|
|
|
|
|
This variable is relevant only if `backup-by-copying' and
|
|
|
|
|
`backup-by-copying-when-mismatch' are nil."
|
|
|
|
|
:type '(choice (const nil) integer)
|
|
|
|
|
:group 'backup)
|
|
|
|
|
|
|
|
|
|
(defvar backup-enable-predicate 'normal-backup-enable-predicate
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Predicate that looks at a file name and decides whether to make backups.
|
2000-06-02 18:46:19 +00:00
|
|
|
|
Called with an absolute file name as argument, it returns t to enable backup.")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom buffer-offer-save nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil in a buffer means always offer to save buffer on exit.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
Do so even if the buffer is not visiting a file.
|
1997-05-05 22:04:00 +00:00
|
|
|
|
Automatically local in all buffers."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'backup)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(make-variable-buffer-local 'buffer-offer-save)
|
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom find-file-existing-other-name t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means find a file under alternative names, in existing buffers.
|
1992-10-12 04:45:53 +00:00
|
|
|
|
This means if any existing buffer is visiting the file you want
|
1997-05-05 22:04:00 +00:00
|
|
|
|
under another name, you get the existing buffer instead of a new buffer."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'find-file)
|
1992-10-12 04:45:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom find-file-visit-truename nil
|
2008-11-13 16:01:47 +00:00
|
|
|
|
"Non-nil means visit a file under its truename.
|
1992-10-12 04:45:53 +00:00
|
|
|
|
The truename of a file is found by chasing all links
|
1997-05-05 22:04:00 +00:00
|
|
|
|
both at the file level and at the levels of the containing directories."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'find-file)
|
2007-07-01 03:23:11 +00:00
|
|
|
|
(put 'find-file-visit-truename 'safe-local-variable 'booleanp)
|
1992-10-12 04:45:53 +00:00
|
|
|
|
|
2005-07-20 01:57:49 +00:00
|
|
|
|
(defcustom revert-without-query nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Specify which files should be reverted without query.
|
1996-12-15 20:52:40 +00:00
|
|
|
|
The value is a list of regular expressions.
|
|
|
|
|
If the file name matches one of these regular expressions,
|
1997-05-20 05:27:50 +00:00
|
|
|
|
then `revert-buffer' reverts the file without querying
|
1997-05-05 22:04:00 +00:00
|
|
|
|
if the file has changed on disk and you have not edited the buffer."
|
1997-10-02 02:57:16 +00:00
|
|
|
|
:type '(repeat regexp)
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:group 'find-file)
|
1996-12-15 20:52:40 +00:00
|
|
|
|
|
1992-10-12 04:45:53 +00:00
|
|
|
|
(defvar buffer-file-number nil
|
|
|
|
|
"The device number and file number of the file visited in the current buffer.
|
|
|
|
|
The value is a list of the form (FILENUM DEVNUM).
|
|
|
|
|
This pair of numbers uniquely identifies the file.
|
|
|
|
|
If the buffer is visiting a new file, the value is nil.")
|
|
|
|
|
(make-variable-buffer-local 'buffer-file-number)
|
|
|
|
|
(put 'buffer-file-number 'permanent-local t)
|
|
|
|
|
|
1996-06-04 16:17:22 +00:00
|
|
|
|
(defvar buffer-file-numbers-unique (not (memq system-type '(windows-nt)))
|
2005-07-20 01:57:49 +00:00
|
|
|
|
"Non-nil means that `buffer-file-number' uniquely identifies files.")
|
1996-06-04 16:17:22 +00:00
|
|
|
|
|
2001-11-01 19:33:52 +00:00
|
|
|
|
(defvar buffer-file-read-only nil
|
|
|
|
|
"Non-nil if visited file was read-only when visited.")
|
|
|
|
|
(make-variable-buffer-local 'buffer-file-read-only)
|
|
|
|
|
|
2001-11-24 23:59:28 +00:00
|
|
|
|
(defcustom temporary-file-directory
|
2001-11-21 12:04:17 +00:00
|
|
|
|
(file-name-as-directory
|
|
|
|
|
(cond ((memq system-type '(ms-dos windows-nt))
|
|
|
|
|
(or (getenv "TEMP") (getenv "TMPDIR") (getenv "TMP") "c:/temp"))
|
|
|
|
|
(t
|
|
|
|
|
(or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "/tmp"))))
|
2001-11-24 23:59:28 +00:00
|
|
|
|
"The directory for writing temporary files."
|
|
|
|
|
:group 'files
|
2009-09-13 00:52:55 +00:00
|
|
|
|
:initialize 'custom-initialize-delay
|
2001-11-24 23:59:28 +00:00
|
|
|
|
:type 'directory)
|
2001-11-21 12:04:17 +00:00
|
|
|
|
|
2001-11-24 23:59:28 +00:00
|
|
|
|
(defcustom small-temporary-file-directory
|
2001-11-21 12:04:17 +00:00
|
|
|
|
(if (eq system-type 'ms-dos) (getenv "TMPDIR"))
|
|
|
|
|
"The directory for writing small temporary files.
|
|
|
|
|
If non-nil, this directory is used instead of `temporary-file-directory'
|
|
|
|
|
by programs that create small temporary files. This is for systems that
|
2001-11-24 23:59:28 +00:00
|
|
|
|
have fast storage with limited space, such as a RAM disk."
|
|
|
|
|
:group 'files
|
2009-09-13 00:52:55 +00:00
|
|
|
|
:initialize 'custom-initialize-delay
|
2002-04-29 03:55:57 +00:00
|
|
|
|
:type '(choice (const nil) directory))
|
2001-11-21 12:04:17 +00:00
|
|
|
|
|
|
|
|
|
;; The system null device. (Should reference NULL_DEVICE from C.)
|
2009-10-26 06:43:36 +00:00
|
|
|
|
(defvar null-device (purecopy "/dev/null") "The system null device.")
|
2001-11-21 12:04:17 +00:00
|
|
|
|
|
2007-11-22 01:05:55 +00:00
|
|
|
|
(declare-function msdos-long-file-names "msdos.c")
|
|
|
|
|
(declare-function w32-long-file-name "w32proc.c")
|
* frame.el (msdos-mouse-p):
* generic-x.el (w32-shell-name):
* files.el (msdos-long-file-names, w32-long-file-name)
(msdos-long-file-names, dired-get-filename, dired-unmark)
(dired-do-flagged-delete, dos-8+3-filename, vms-read-directory)
(view-mode-disable):
* term/mac-win.el (mac-code-convert-string, mac-coerce-ae-data)
(mac-resume-apple-event, mac-font-panel-mode)
(mac-atsu-font-face-attributes, mac-ae-set-reply-parameter)
(mac-clear-font-name-table):
* term/pc-win.el (msdos-remember-default-colors)
(w16-set-clipboard-data, w16-get-clipboard-data):
* term/w32-win.el (w32-send-sys-command, w32-select-font)
(set-message-beep):
* w32-fns.el (set-message-beep, w32-get-clipboard-data)
(w32-get-locale-info, w32-get-valid-locale-ids)
(w32-set-clipboard-data):
* help-fns.el (ad-get-advice-info):
* font-lock.el (fast-lock-after-fontify-buffer)
(fast-lock-after-unfontify-buffer, fast-lock-mode)
(lazy-lock-after-fontify-buffer)
(lazy-lock-after-unfontify-buffer, lazy-lock-mode):
* net/browse-url.el (w32-shell-execute):
* dos-fns.el (int86, msdos-long-file-names):
* dos-w32.el (default-printer-name): Declare as functions.
2007-11-21 03:06:01 +00:00
|
|
|
|
(declare-function dired-get-filename "dired" (&optional localp no-error-if-not-filep))
|
|
|
|
|
(declare-function dired-unmark "dired" (arg))
|
|
|
|
|
(declare-function dired-do-flagged-delete "dired" (&optional nomessage))
|
|
|
|
|
(declare-function dos-8+3-filename "dos-fns" (filename))
|
|
|
|
|
(declare-function view-mode-disable "view" ())
|
2008-12-26 18:00:26 +00:00
|
|
|
|
(declare-function dosified-file-name "dos-fns" (file-name))
|
* frame.el (msdos-mouse-p):
* generic-x.el (w32-shell-name):
* files.el (msdos-long-file-names, w32-long-file-name)
(msdos-long-file-names, dired-get-filename, dired-unmark)
(dired-do-flagged-delete, dos-8+3-filename, vms-read-directory)
(view-mode-disable):
* term/mac-win.el (mac-code-convert-string, mac-coerce-ae-data)
(mac-resume-apple-event, mac-font-panel-mode)
(mac-atsu-font-face-attributes, mac-ae-set-reply-parameter)
(mac-clear-font-name-table):
* term/pc-win.el (msdos-remember-default-colors)
(w16-set-clipboard-data, w16-get-clipboard-data):
* term/w32-win.el (w32-send-sys-command, w32-select-font)
(set-message-beep):
* w32-fns.el (set-message-beep, w32-get-clipboard-data)
(w32-get-locale-info, w32-get-valid-locale-ids)
(w32-set-clipboard-data):
* help-fns.el (ad-get-advice-info):
* font-lock.el (fast-lock-after-fontify-buffer)
(fast-lock-after-unfontify-buffer, fast-lock-mode)
(lazy-lock-after-fontify-buffer)
(lazy-lock-after-unfontify-buffer, lazy-lock-mode):
* net/browse-url.el (w32-shell-execute):
* dos-fns.el (int86, msdos-long-file-names):
* dos-w32.el (default-printer-name): Declare as functions.
2007-11-21 03:06:01 +00:00
|
|
|
|
|
1998-05-21 14:26:10 +00:00
|
|
|
|
(defvar file-name-invalid-regexp
|
|
|
|
|
(cond ((and (eq system-type 'ms-dos) (not (msdos-long-file-names)))
|
2009-10-26 06:43:36 +00:00
|
|
|
|
(purecopy
|
1998-07-15 10:21:04 +00:00
|
|
|
|
(concat "^\\([^A-Z[-`a-z]\\|..+\\)?:\\|" ; colon except after drive
|
1998-05-21 14:26:10 +00:00
|
|
|
|
"[+, ;=|<>\"?*]\\|\\[\\|\\]\\|" ; invalid characters
|
2008-02-24 16:57:51 +00:00
|
|
|
|
"[\000-\037]\\|" ; control characters
|
1998-05-21 14:26:10 +00:00
|
|
|
|
"\\(/\\.\\.?[^/]\\)\\|" ; leading dots
|
2009-10-26 06:43:36 +00:00
|
|
|
|
"\\(/[^/.]+\\.[^/.]*\\.\\)"))) ; more than a single dot
|
2003-01-31 15:24:20 +00:00
|
|
|
|
((memq system-type '(ms-dos windows-nt cygwin))
|
2009-10-26 06:43:36 +00:00
|
|
|
|
(purecopy
|
1998-07-15 10:21:04 +00:00
|
|
|
|
(concat "^\\([^A-Z[-`a-z]\\|..+\\)?:\\|" ; colon except after drive
|
2009-10-26 06:43:36 +00:00
|
|
|
|
"[|<>\"?*\000-\037]"))) ; invalid characters
|
|
|
|
|
(t (purecopy "[\000]")))
|
1998-05-21 14:26:10 +00:00
|
|
|
|
"Regexp recognizing file names which aren't allowed by the filesystem.")
|
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom file-precious-flag nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means protect against I/O errors while saving files.
|
1995-06-07 20:45:11 +00:00
|
|
|
|
Some modes set this non-nil in particular buffers.
|
1995-06-09 01:00:42 +00:00
|
|
|
|
|
|
|
|
|
This feature works by writing the new contents into a temporary file
|
|
|
|
|
and then renaming the temporary file to replace the original.
|
|
|
|
|
In this way, any I/O error in writing leaves the original untouched,
|
|
|
|
|
and there is never any instant where the file is nonexistent.
|
|
|
|
|
|
|
|
|
|
Note that this feature forces backups to be made by copying.
|
1995-06-07 20:45:11 +00:00
|
|
|
|
Yet, at the same time, saving a precious file
|
2008-11-14 23:36:37 +00:00
|
|
|
|
breaks any hard links between it and other files.
|
|
|
|
|
|
|
|
|
|
This feature is advisory: for example, if the directory in which the
|
2008-12-03 03:26:01 +00:00
|
|
|
|
file is being saved is not writable, Emacs may ignore a non-nil value
|
2008-11-29 19:04:14 +00:00
|
|
|
|
of `file-precious-flag' and write directly into the file.
|
|
|
|
|
|
|
|
|
|
See also: `break-hardlink-on-save'."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'backup)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2008-11-29 19:04:14 +00:00
|
|
|
|
(defcustom break-hardlink-on-save nil
|
|
|
|
|
"Non-nil means when saving a file that exists under several names
|
2008-11-29 21:32:39 +00:00
|
|
|
|
\(i.e., has multiple hardlinks), break the hardlink associated with
|
2008-11-29 19:04:14 +00:00
|
|
|
|
`buffer-file-name' and write to a new file, so that the other
|
|
|
|
|
instances of the file are not affected by the save.
|
|
|
|
|
|
|
|
|
|
If `buffer-file-name' refers to a symlink, do not break the symlink.
|
|
|
|
|
|
|
|
|
|
Unlike `file-precious-flag', `break-hardlink-on-save' is not advisory.
|
|
|
|
|
For example, if the directory in which a file is being saved is not
|
2008-12-03 03:26:01 +00:00
|
|
|
|
itself writable, then error instead of saving in some
|
2008-11-29 19:04:14 +00:00
|
|
|
|
hardlink-nonbreaking way.
|
|
|
|
|
|
|
|
|
|
See also `backup-by-copying' and `backup-by-copying-when-linked'."
|
|
|
|
|
:type 'boolean
|
2008-11-29 21:32:39 +00:00
|
|
|
|
:group 'files
|
|
|
|
|
:version "23.1")
|
2008-11-29 19:04:14 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom version-control nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Control use of version numbers for backup files.
|
2007-01-02 01:26:20 +00:00
|
|
|
|
When t, make numeric backup versions unconditionally.
|
|
|
|
|
When nil, make them for files that have some already.
|
|
|
|
|
The value `never' means do not make them."
|
1998-06-24 09:08:57 +00:00
|
|
|
|
:type '(choice (const :tag "Never" never)
|
|
|
|
|
(const :tag "If existing" nil)
|
|
|
|
|
(other :tag "Always" t))
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:group 'backup
|
|
|
|
|
:group 'vc)
|
2006-05-12 12:29:08 +00:00
|
|
|
|
(put 'version-control 'safe-local-variable
|
|
|
|
|
'(lambda (x) (or (booleanp x) (equal x 'never))))
|
1997-05-05 22:04:00 +00:00
|
|
|
|
|
|
|
|
|
(defcustom dired-kept-versions 2
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"When cleaning directory, number of versions to keep."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'integer
|
|
|
|
|
:group 'backup
|
|
|
|
|
:group 'dired)
|
|
|
|
|
|
|
|
|
|
(defcustom delete-old-versions nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"If t, delete excess backup versions silently.
|
1997-05-05 22:04:00 +00:00
|
|
|
|
If nil, ask confirmation. Any other value prevents any trimming."
|
|
|
|
|
:type '(choice (const :tag "Delete" t)
|
|
|
|
|
(const :tag "Ask" nil)
|
1998-06-24 09:08:57 +00:00
|
|
|
|
(other :tag "Leave" other))
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:group 'backup)
|
|
|
|
|
|
|
|
|
|
(defcustom kept-old-versions 2
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Number of oldest versions to keep when a new numbered backup is made."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'integer
|
|
|
|
|
:group 'backup)
|
2006-05-11 15:01:41 +00:00
|
|
|
|
(put 'kept-old-versions 'safe-local-variable 'integerp)
|
1997-05-05 22:04:00 +00:00
|
|
|
|
|
|
|
|
|
(defcustom kept-new-versions 2
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Number of newest versions to keep when a new numbered backup is made.
|
1997-05-05 22:04:00 +00:00
|
|
|
|
Includes the new backup. Must be > 0"
|
|
|
|
|
:type 'integer
|
|
|
|
|
:group 'backup)
|
2006-05-11 15:01:41 +00:00
|
|
|
|
(put 'kept-new-versions 'safe-local-variable 'integerp)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom require-final-newline nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Whether to add a newline automatically at the end of the file.
|
2004-12-31 14:48:12 +00:00
|
|
|
|
|
|
|
|
|
A value of t means do this only when the file is about to be saved.
|
|
|
|
|
A value of `visit' means do this right after the file is visited.
|
|
|
|
|
A value of `visit-save' means do it at both of those times.
|
|
|
|
|
Any other non-nil value means ask user whether to add a newline, when saving.
|
2007-05-14 10:28:06 +00:00
|
|
|
|
A value of nil means don't add newlines.
|
2004-12-31 14:48:12 +00:00
|
|
|
|
|
|
|
|
|
Certain major modes set this locally to the value obtained
|
|
|
|
|
from `mode-require-final-newline'."
|
|
|
|
|
:type '(choice (const :tag "When visiting" visit)
|
|
|
|
|
(const :tag "When saving" t)
|
|
|
|
|
(const :tag "When visiting or saving" visit-save)
|
2005-04-24 21:29:15 +00:00
|
|
|
|
(const :tag "Don't add newlines" nil)
|
2005-05-01 12:56:42 +00:00
|
|
|
|
(other :tag "Ask each time" ask))
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:group 'editing-basics)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2004-12-31 14:48:12 +00:00
|
|
|
|
(defcustom mode-require-final-newline t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Whether to add a newline at end of file, in certain major modes.
|
2004-12-31 14:48:12 +00:00
|
|
|
|
Those modes set `require-final-newline' to this value when you enable them.
|
2005-05-01 12:56:42 +00:00
|
|
|
|
They do so because they are often used for files that are supposed
|
2004-12-31 14:48:12 +00:00
|
|
|
|
to end in newlines, and the question is how to arrange that.
|
|
|
|
|
|
|
|
|
|
A value of t means do this only when the file is about to be saved.
|
|
|
|
|
A value of `visit' means do this right after the file is visited.
|
|
|
|
|
A value of `visit-save' means do it at both of those times.
|
2005-04-01 04:48:39 +00:00
|
|
|
|
Any other non-nil value means ask user whether to add a newline, when saving.
|
|
|
|
|
|
2007-05-14 10:28:06 +00:00
|
|
|
|
A value of nil means do not add newlines. That is a risky choice in this
|
|
|
|
|
variable since this value is used for modes for files that ought to have
|
|
|
|
|
final newlines. So if you set this to nil, you must explicitly check and
|
|
|
|
|
add a final newline, whenever you save a file that really needs one."
|
2004-12-31 14:48:12 +00:00
|
|
|
|
:type '(choice (const :tag "When visiting" visit)
|
|
|
|
|
(const :tag "When saving" t)
|
|
|
|
|
(const :tag "When visiting or saving" visit-save)
|
2005-04-24 21:29:15 +00:00
|
|
|
|
(const :tag "Don't add newlines" nil)
|
|
|
|
|
(other :tag "Ask each time" ask))
|
2004-12-31 14:48:12 +00:00
|
|
|
|
:group 'editing-basics
|
2005-02-09 15:50:47 +00:00
|
|
|
|
:version "22.1")
|
2004-12-31 14:48:12 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom auto-save-default t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil says by default do auto-saving of every file-visiting buffer."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'auto-save)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defcustom auto-save-file-name-transforms
|
2004-05-19 00:30:43 +00:00
|
|
|
|
`(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'"
|
2002-03-29 14:02:54 +00:00
|
|
|
|
;; Don't put "\\2" inside expand-file-name, since it will be
|
|
|
|
|
;; transformed to "/2" on DOS/Windows.
|
2002-04-20 22:22:57 +00:00
|
|
|
|
,(concat temporary-file-directory "\\2") t))
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Transforms to apply to buffer file name before making auto-save file name.
|
2002-04-20 22:22:57 +00:00
|
|
|
|
Each transform is a list (REGEXP REPLACEMENT UNIQUIFY):
|
2000-10-04 17:16:59 +00:00
|
|
|
|
REGEXP is a regular expression to match against the file name.
|
|
|
|
|
If it matches, `replace-match' is used to replace the
|
|
|
|
|
matching part with REPLACEMENT.
|
2002-04-20 22:22:57 +00:00
|
|
|
|
If the optional element UNIQUIFY is non-nil, the auto-save file name is
|
2002-06-01 18:04:35 +00:00
|
|
|
|
constructed by taking the directory part of the replaced file-name,
|
2002-04-20 22:22:57 +00:00
|
|
|
|
concatenated with the buffer file name with all directory separators
|
|
|
|
|
changed to `!' to prevent clashes. This will not work
|
|
|
|
|
correctly if your filesystem truncates the resulting name.
|
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
All the transforms in the list are tried, in the order they are listed.
|
|
|
|
|
When one transform applies, its result is final;
|
|
|
|
|
no further transforms are tried.
|
|
|
|
|
|
2001-11-21 08:32:57 +00:00
|
|
|
|
The default value is set up to put the auto-save file into the
|
|
|
|
|
temporary directory (see the variable `temporary-file-directory') for
|
2002-04-20 22:22:57 +00:00
|
|
|
|
editing a remote file.
|
|
|
|
|
|
|
|
|
|
On MS-DOS filesystems without long names this variable is always
|
|
|
|
|
ignored."
|
2000-10-04 17:16:59 +00:00
|
|
|
|
:group 'auto-save
|
2002-04-20 22:22:57 +00:00
|
|
|
|
:type '(repeat (list (string :tag "Regexp") (string :tag "Replacement")
|
|
|
|
|
(boolean :tag "Uniquify")))
|
2009-09-13 00:52:55 +00:00
|
|
|
|
:initialize 'custom-initialize-delay
|
2000-10-04 17:16:59 +00:00
|
|
|
|
:version "21.1")
|
|
|
|
|
|
2001-11-11 01:53:50 +00:00
|
|
|
|
(defcustom save-abbrevs t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means save word abbrevs too when files are saved.
|
2001-12-04 18:27:06 +00:00
|
|
|
|
If `silently', don't ask the user before saving."
|
|
|
|
|
:type '(choice (const t) (const nil) (const silently))
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:group 'abbrev)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom find-file-run-dired t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means allow `find-file' to visit directories.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
To visit the directory, `find-file' runs `find-directory-functions'."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'find-file)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defcustom find-directory-functions '(cvs-dired-noselect dired-noselect)
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"List of functions to try in sequence to visit a directory.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
Each function is called with the directory name as the sole argument
|
|
|
|
|
and should return either a buffer or nil."
|
|
|
|
|
:type '(hook :options (cvs-dired-noselect dired-noselect))
|
|
|
|
|
:group 'find-file)
|
|
|
|
|
|
2009-11-25 17:11:29 +00:00
|
|
|
|
;; FIXME: also add a hook for `(thing-at-point 'filename)'
|
|
|
|
|
(defcustom file-name-at-point-functions '(ffap-guess-file-name-at-point)
|
|
|
|
|
"List of functions to try in sequence to get a file name at point.
|
|
|
|
|
Each function should return either nil or a file name found at the
|
|
|
|
|
location of point in the current buffer."
|
|
|
|
|
:type '(hook :options (ffap-guess-file-name-at-point))
|
|
|
|
|
:group 'find-file)
|
|
|
|
|
|
1993-02-15 19:02:55 +00:00
|
|
|
|
;;;It is not useful to make this a local variable.
|
|
|
|
|
;;;(put 'find-file-not-found-hooks 'permanent-local t)
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(defvar find-file-not-found-functions nil
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"List of functions to be called for `find-file' on nonexistent file.
|
|
|
|
|
These functions are called as soon as the error is detected.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
Variable `buffer-file-name' is already set up.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
The functions are called in the order given until one of them returns non-nil.")
|
2005-07-20 01:57:49 +00:00
|
|
|
|
(define-obsolete-variable-alias 'find-file-not-found-hooks
|
|
|
|
|
'find-file-not-found-functions "22.1")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1993-02-15 19:02:55 +00:00
|
|
|
|
;;;It is not useful to make this a local variable.
|
|
|
|
|
;;;(put 'find-file-hooks 'permanent-local t)
|
2008-04-12 03:17:19 +00:00
|
|
|
|
(define-obsolete-variable-alias 'find-file-hooks 'find-file-hook "22.1")
|
2003-10-06 16:29:50 +00:00
|
|
|
|
(defcustom find-file-hook nil
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"List of functions to be called after a buffer is loaded from a file.
|
|
|
|
|
The buffer's local variables (if any) will have been processed before the
|
2003-10-06 16:29:50 +00:00
|
|
|
|
functions are called."
|
|
|
|
|
:group 'find-file
|
|
|
|
|
:type 'hook
|
|
|
|
|
:options '(auto-insert)
|
2005-02-09 15:50:47 +00:00
|
|
|
|
:version "22.1")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(defvar write-file-functions nil
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"List of functions to be called before writing out a buffer to a file.
|
|
|
|
|
If one of them returns non-nil, the file is considered already written
|
1992-04-04 05:55:39 +00:00
|
|
|
|
and the rest are not called.
|
|
|
|
|
These hooks are considered to pertain to the visited file.
|
2002-06-23 21:16:38 +00:00
|
|
|
|
So any buffer-local binding of this variable is discarded if you change
|
|
|
|
|
the visited file name with \\[set-visited-file-name], but not when you
|
|
|
|
|
change the major mode.
|
|
|
|
|
|
2004-01-07 20:51:14 +00:00
|
|
|
|
This hook is not run if any of the functions in
|
|
|
|
|
`write-contents-functions' returns non-nil. Both hooks pertain
|
|
|
|
|
to how to save a buffer to file, for instance, choosing a suitable
|
|
|
|
|
coding system and setting mode bits. (See Info
|
|
|
|
|
node `(elisp)Saving Buffers'.) To perform various checks or
|
2005-07-20 01:57:49 +00:00
|
|
|
|
updates before the buffer is saved, use `before-save-hook'.")
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(put 'write-file-functions 'permanent-local t)
|
2005-07-20 01:57:49 +00:00
|
|
|
|
(define-obsolete-variable-alias 'write-file-hooks 'write-file-functions "22.1")
|
2002-06-23 21:16:38 +00:00
|
|
|
|
|
|
|
|
|
(defvar local-write-file-hooks nil)
|
1993-09-21 07:23:26 +00:00
|
|
|
|
(make-variable-buffer-local 'local-write-file-hooks)
|
|
|
|
|
(put 'local-write-file-hooks 'permanent-local t)
|
2005-02-09 15:50:47 +00:00
|
|
|
|
(make-obsolete-variable 'local-write-file-hooks 'write-file-functions "22.1")
|
1992-04-04 05:55:39 +00:00
|
|
|
|
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(defvar write-contents-functions nil
|
1992-04-04 05:55:39 +00:00
|
|
|
|
"List of functions to be called before writing out a buffer to a file.
|
|
|
|
|
If one of them returns non-nil, the file is considered already written
|
2004-06-23 14:38:19 +00:00
|
|
|
|
and the rest are not called and neither are the functions in
|
|
|
|
|
`write-file-functions'.
|
1996-01-09 23:17:37 +00:00
|
|
|
|
|
|
|
|
|
This variable is meant to be used for hooks that pertain to the
|
|
|
|
|
buffer's contents, not to the particular visited file; thus,
|
|
|
|
|
`set-visited-file-name' does not clear this variable; but changing the
|
1996-01-15 05:08:57 +00:00
|
|
|
|
major mode does clear it.
|
|
|
|
|
|
2004-01-07 20:51:14 +00:00
|
|
|
|
For hooks that _do_ pertain to the particular visited file, use
|
|
|
|
|
`write-file-functions'. Both this variable and
|
|
|
|
|
`write-file-functions' relate to how a buffer is saved to file.
|
|
|
|
|
To perform various checks or updates before the buffer is saved,
|
|
|
|
|
use `before-save-hook'.")
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(make-variable-buffer-local 'write-contents-functions)
|
2005-07-20 01:57:49 +00:00
|
|
|
|
(define-obsolete-variable-alias 'write-contents-hooks
|
|
|
|
|
'write-contents-functions "22.1")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom enable-local-variables t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Control use of local variables in files you visit.
|
2007-11-09 10:40:32 +00:00
|
|
|
|
The value can be t, nil, :safe, :all, or something else.
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
|
|
|
|
|
A value of t means file local variables specifications are obeyed
|
2006-02-21 19:49:55 +00:00
|
|
|
|
if all the specified variable values are safe; if any values are
|
|
|
|
|
not safe, Emacs queries you, once, whether to set them all.
|
2006-04-11 17:57:34 +00:00
|
|
|
|
\(When you say yes to certain values, they are remembered as safe.)
|
|
|
|
|
|
|
|
|
|
:safe means set the safe variables, and ignore the rest.
|
2006-04-18 21:20:03 +00:00
|
|
|
|
:all means set all variables, whether safe or not.
|
|
|
|
|
(Don't set it permanently to :all.)
|
2007-05-14 10:28:06 +00:00
|
|
|
|
A value of nil means always ignore the file local variables.
|
2006-02-21 19:49:55 +00:00
|
|
|
|
|
|
|
|
|
Any other value means always query you once whether to set them all.
|
2006-04-11 17:57:34 +00:00
|
|
|
|
\(When you say yes to certain values, they are remembered as safe, but
|
|
|
|
|
this has no effect when `enable-local-variables' is \"something else\".)
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
|
1998-11-07 02:01:59 +00:00
|
|
|
|
This variable also controls use of major modes specified in
|
|
|
|
|
a -*- line.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1998-11-07 02:01:59 +00:00
|
|
|
|
The command \\[normal-mode], when used interactively,
|
|
|
|
|
always obeys file local variable specifications and the -*- line,
|
|
|
|
|
and ignores this variable."
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
:risky t
|
2006-04-18 21:20:03 +00:00
|
|
|
|
:type '(choice (const :tag "Query Unsafe" t)
|
2006-04-11 17:57:34 +00:00
|
|
|
|
(const :tag "Safe Only" :safe)
|
2006-04-18 21:20:03 +00:00
|
|
|
|
(const :tag "Do all" :all)
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(const :tag "Ignore" nil)
|
1998-06-24 09:08:57 +00:00
|
|
|
|
(other :tag "Query" other))
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:group 'find-file)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1998-06-13 06:17:13 +00:00
|
|
|
|
(defvar local-enable-local-variables t
|
|
|
|
|
"Like `enable-local-variables' but meant for buffer-local bindings.
|
1998-11-07 02:01:59 +00:00
|
|
|
|
The meaningful values are nil and non-nil. The default is non-nil.
|
1998-06-13 06:17:13 +00:00
|
|
|
|
If a major mode sets this to nil, buffer-locally, then any local
|
1998-11-07 02:01:59 +00:00
|
|
|
|
variables list in the file will be ignored.
|
|
|
|
|
|
|
|
|
|
This variable does not affect the use of major modes
|
|
|
|
|
specified in a -*- line.")
|
1998-06-13 06:17:13 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom enable-local-eval 'maybe
|
2006-07-02 14:26:53 +00:00
|
|
|
|
"Control processing of the \"variable\" `eval' in a file's local variables.
|
1992-06-23 21:48:27 +00:00
|
|
|
|
The value can be t, nil or something else.
|
2008-11-14 13:05:18 +00:00
|
|
|
|
A value of t means obey `eval' variables.
|
2007-05-14 10:28:06 +00:00
|
|
|
|
A value of nil means ignore them; anything else means query."
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
:risky t
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type '(choice (const :tag "Obey" t)
|
|
|
|
|
(const :tag "Ignore" nil)
|
1998-06-24 09:08:57 +00:00
|
|
|
|
(other :tag "Query" other))
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:group 'find-file)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
;; Avoid losing in versions where CLASH_DETECTION is disabled.
|
|
|
|
|
(or (fboundp 'lock-buffer)
|
1993-04-25 06:14:06 +00:00
|
|
|
|
(defalias 'lock-buffer 'ignore))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(or (fboundp 'unlock-buffer)
|
1993-04-25 06:14:06 +00:00
|
|
|
|
(defalias 'unlock-buffer 'ignore))
|
1996-09-16 09:43:42 +00:00
|
|
|
|
(or (fboundp 'file-locked-p)
|
|
|
|
|
(defalias 'file-locked-p 'ignore))
|
1993-07-20 07:12:30 +00:00
|
|
|
|
|
2003-04-18 13:53:18 +00:00
|
|
|
|
(defcustom view-read-only nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means buffers visiting files read-only do so in view mode.
|
2003-04-24 01:58:49 +00:00
|
|
|
|
In fact, this means that all read-only buffers normally have
|
|
|
|
|
View mode enabled, including buffers that are read-only because
|
|
|
|
|
you visit a file you cannot alter, and buffers you make read-only
|
|
|
|
|
using \\[toggle-read-only]."
|
2003-04-18 13:53:18 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'view)
|
1997-06-18 17:24:59 +00:00
|
|
|
|
|
2006-10-12 23:00:44 +00:00
|
|
|
|
(defvar file-name-history nil
|
2007-12-22 17:08:03 +00:00
|
|
|
|
"History list of file names entered in the minibuffer.
|
|
|
|
|
|
|
|
|
|
Maximum length of the history list is determined by the value
|
|
|
|
|
of `history-length', which see.")
|
2006-10-12 23:00:44 +00:00
|
|
|
|
|
2002-08-24 02:57:31 +00:00
|
|
|
|
(put 'ange-ftp-completion-hook-function 'safe-magic t)
|
1993-07-20 07:12:30 +00:00
|
|
|
|
(defun ange-ftp-completion-hook-function (op &rest args)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Provides support for ange-ftp host name completion.
|
|
|
|
|
Runs the usual ange-ftp hook, but only for completion operations."
|
|
|
|
|
;; Having this here avoids the need to load ange-ftp when it's not
|
|
|
|
|
;; really in use.
|
1993-07-20 07:12:30 +00:00
|
|
|
|
(if (memq op '(file-name-completion file-name-all-completions))
|
|
|
|
|
(apply 'ange-ftp-hook-function op args)
|
1994-04-27 23:43:46 +00:00
|
|
|
|
(let ((inhibit-file-name-handlers
|
|
|
|
|
(cons 'ange-ftp-completion-hook-function
|
|
|
|
|
(and (eq inhibit-file-name-operation op)
|
|
|
|
|
inhibit-file-name-handlers)))
|
|
|
|
|
(inhibit-file-name-operation op))
|
1993-07-20 07:12:30 +00:00
|
|
|
|
(apply op args))))
|
1996-01-01 22:51:51 +00:00
|
|
|
|
|
2010-05-15 08:31:40 +00:00
|
|
|
|
(declare-function dos-convert-standard-filename "dos-fns.el" (filename))
|
|
|
|
|
(declare-function w32-convert-standard-filename "w32-fns.el" (filename))
|
|
|
|
|
|
1996-01-01 22:51:51 +00:00
|
|
|
|
(defun convert-standard-filename (filename)
|
2004-11-14 23:24:14 +00:00
|
|
|
|
"Convert a standard file's name to something suitable for the OS.
|
2004-05-30 21:21:42 +00:00
|
|
|
|
This means to guarantee valid names and perhaps to canonicalize
|
|
|
|
|
certain patterns.
|
|
|
|
|
|
2005-05-31 13:26:21 +00:00
|
|
|
|
FILENAME should be an absolute file name since the conversion rules
|
|
|
|
|
sometimes vary depending on the position in the file name. E.g. c:/foo
|
|
|
|
|
is a valid DOS file name, but c:/bar/c:/foo is not.
|
|
|
|
|
|
2004-05-30 21:21:42 +00:00
|
|
|
|
This function's standard definition is trivial; it just returns
|
|
|
|
|
the argument. However, on Windows and DOS, replace invalid
|
2006-07-29 12:05:28 +00:00
|
|
|
|
characters. On DOS, make sure to obey the 8.3 limitations.
|
|
|
|
|
In the native Windows build, turn Cygwin names into native names,
|
|
|
|
|
and also turn slashes into backslashes if the shell requires it (see
|
2004-11-14 23:24:14 +00:00
|
|
|
|
`w32-shell-dos-semantics').
|
|
|
|
|
|
|
|
|
|
See Info node `(elisp)Standard File Names' for more details."
|
2010-05-15 08:31:40 +00:00
|
|
|
|
(cond
|
|
|
|
|
((eq system-type 'cygwin)
|
|
|
|
|
(let ((name (copy-sequence filename))
|
|
|
|
|
(start 0))
|
|
|
|
|
;; Replace invalid filename characters with !
|
|
|
|
|
(while (string-match "[?*:<>|\"\000-\037]" name start)
|
|
|
|
|
(aset name (match-beginning 0) ?!)
|
|
|
|
|
(setq start (match-end 0)))
|
|
|
|
|
name))
|
|
|
|
|
((eq system-type 'windows-nt)
|
|
|
|
|
(w32-convert-standard-filename filename))
|
|
|
|
|
((eq system-type 'ms-dos)
|
|
|
|
|
(dos-convert-standard-filename filename))
|
|
|
|
|
(t filename)))
|
2002-05-28 09:08:42 +00:00
|
|
|
|
|
|
|
|
|
(defun read-directory-name (prompt &optional dir default-dirname mustmatch initial)
|
|
|
|
|
"Read directory name, prompting with PROMPT and completing in directory DIR.
|
|
|
|
|
Value is not expanded---you must call `expand-file-name' yourself.
|
2004-01-31 04:38:32 +00:00
|
|
|
|
Default name to DEFAULT-DIRNAME if user exits with the same
|
|
|
|
|
non-empty string that was inserted by this function.
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(If DEFAULT-DIRNAME is omitted, DIR combined with INITIAL is used,
|
|
|
|
|
or just DIR if INITIAL is nil.)
|
2004-01-31 04:38:32 +00:00
|
|
|
|
If the user exits with an empty minibuffer, this function returns
|
|
|
|
|
an empty string. (This can only happen if the user erased the
|
|
|
|
|
pre-inserted contents or if `insert-default-directory' is nil.)
|
2002-05-28 09:08:42 +00:00
|
|
|
|
Fourth arg MUSTMATCH non-nil means require existing directory's name.
|
|
|
|
|
Non-nil and non-t means also require confirmation after completion.
|
|
|
|
|
Fifth arg INITIAL specifies text to start with.
|
2004-01-31 04:38:32 +00:00
|
|
|
|
DIR should be an absolute directory name. It defaults to
|
|
|
|
|
the value of `default-directory'."
|
2002-05-28 09:08:42 +00:00
|
|
|
|
(unless dir
|
|
|
|
|
(setq dir default-directory))
|
2005-05-14 00:56:30 +00:00
|
|
|
|
(read-file-name prompt dir (or default-dirname
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(if initial (expand-file-name initial dir)
|
|
|
|
|
dir))
|
|
|
|
|
mustmatch initial
|
2002-05-28 09:08:42 +00:00
|
|
|
|
'file-directory-p))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun pwd ()
|
|
|
|
|
"Show the current default directory."
|
|
|
|
|
(interactive nil)
|
|
|
|
|
(message "Directory %s" default-directory))
|
|
|
|
|
|
1993-04-25 06:14:06 +00:00
|
|
|
|
(defvar cd-path nil
|
|
|
|
|
"Value of the CDPATH environment variable, as a list.
|
2000-10-07 03:05:14 +00:00
|
|
|
|
Not actually set up until the first time you use it.")
|
1993-04-25 06:14:06 +00:00
|
|
|
|
|
|
|
|
|
(defun parse-colon-path (cd-path)
|
2004-06-11 01:02:51 +00:00
|
|
|
|
"Explode a search path into a list of directory names.
|
2004-06-16 23:56:46 +00:00
|
|
|
|
Directories are separated by occurrences of `path-separator'
|
|
|
|
|
\(which is colon in GNU and GNU-like systems)."
|
2000-10-04 17:16:59 +00:00
|
|
|
|
;; We could use split-string here.
|
1993-04-25 06:14:06 +00:00
|
|
|
|
(and cd-path
|
2003-04-17 21:15:04 +00:00
|
|
|
|
(let (cd-list (cd-start 0) cd-colon)
|
1995-05-15 22:22:25 +00:00
|
|
|
|
(setq cd-path (concat cd-path path-separator))
|
|
|
|
|
(while (setq cd-colon (string-match path-separator cd-path cd-start))
|
1993-04-25 06:14:06 +00:00
|
|
|
|
(setq cd-list
|
1993-05-24 21:45:20 +00:00
|
|
|
|
(nconc cd-list
|
1993-07-22 05:34:53 +00:00
|
|
|
|
(list (if (= cd-start cd-colon)
|
|
|
|
|
nil
|
|
|
|
|
(substitute-in-file-name
|
1993-07-20 22:04:53 +00:00
|
|
|
|
(file-name-as-directory
|
|
|
|
|
(substring cd-path cd-start cd-colon)))))))
|
1993-04-25 06:14:06 +00:00
|
|
|
|
(setq cd-start (+ cd-colon 1)))
|
|
|
|
|
cd-list)))
|
|
|
|
|
|
|
|
|
|
(defun cd-absolute (dir)
|
1993-06-11 16:02:27 +00:00
|
|
|
|
"Change current directory to given absolute file name DIR."
|
1994-07-27 18:55:38 +00:00
|
|
|
|
;; Put the name into directory syntax now,
|
|
|
|
|
;; because otherwise expand-file-name may give some bad results.
|
2008-07-31 05:33:56 +00:00
|
|
|
|
(setq dir (file-name-as-directory dir))
|
2009-10-01 03:34:04 +00:00
|
|
|
|
;; We used to additionally call abbreviate-file-name here, for an
|
|
|
|
|
;; unknown reason. Problem is that most buffers are setup
|
|
|
|
|
;; without going through cd-absolute and don't call
|
|
|
|
|
;; abbreviate-file-name on their default-directory, so the few that
|
|
|
|
|
;; do end up using a superficially different directory.
|
|
|
|
|
(setq dir (expand-file-name dir))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(if (not (file-directory-p dir))
|
1997-07-16 05:30:34 +00:00
|
|
|
|
(if (file-exists-p dir)
|
|
|
|
|
(error "%s is not a directory" dir)
|
1997-08-05 05:49:10 +00:00
|
|
|
|
(error "%s: no such directory" dir))
|
2007-12-29 12:59:09 +00:00
|
|
|
|
(unless (file-executable-p dir)
|
|
|
|
|
(error "Cannot cd to %s: Permission denied" dir))
|
|
|
|
|
(setq default-directory dir)
|
2009-09-25 04:35:14 +00:00
|
|
|
|
(setq list-buffers-directory dir)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1993-04-25 06:14:06 +00:00
|
|
|
|
(defun cd (dir)
|
|
|
|
|
"Make DIR become the current buffer's default directory.
|
2004-06-11 01:02:51 +00:00
|
|
|
|
If your environment includes a `CDPATH' variable, try each one of
|
|
|
|
|
that list of directories (separated by occurrences of
|
2004-06-16 23:56:46 +00:00
|
|
|
|
`path-separator') when resolving a relative directory name.
|
|
|
|
|
The path separator is colon in GNU and GNU-like systems."
|
1995-07-30 07:02:13 +00:00
|
|
|
|
(interactive
|
2002-05-28 09:08:42 +00:00
|
|
|
|
(list (read-directory-name "Change default directory: "
|
1995-09-30 16:35:12 +00:00
|
|
|
|
default-directory default-directory
|
|
|
|
|
(and (member cd-path '(nil ("./")))
|
|
|
|
|
(null (getenv "CDPATH"))))))
|
1993-06-11 16:02:27 +00:00
|
|
|
|
(if (file-name-absolute-p dir)
|
|
|
|
|
(cd-absolute (expand-file-name dir))
|
|
|
|
|
(if (null cd-path)
|
|
|
|
|
(let ((trypath (parse-colon-path (getenv "CDPATH"))))
|
|
|
|
|
(setq cd-path (or trypath (list "./")))))
|
|
|
|
|
(if (not (catch 'found
|
2007-09-25 11:05:46 +00:00
|
|
|
|
(mapc
|
1993-06-11 16:02:27 +00:00
|
|
|
|
(function (lambda (x)
|
|
|
|
|
(let ((f (expand-file-name (concat x dir))))
|
|
|
|
|
(if (file-directory-p f)
|
|
|
|
|
(progn
|
|
|
|
|
(cd-absolute f)
|
|
|
|
|
(throw 'found t))))))
|
|
|
|
|
cd-path)
|
|
|
|
|
nil))
|
|
|
|
|
(error "No such directory found via CDPATH environment variable"))))
|
1993-04-25 06:14:06 +00:00
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun load-file (file)
|
|
|
|
|
"Load the Lisp file named FILE."
|
2000-12-06 18:38:47 +00:00
|
|
|
|
;; This is a case where .elc makes a lot of sense.
|
|
|
|
|
(interactive (list (let ((completion-ignored-extensions
|
2000-12-08 14:19:00 +00:00
|
|
|
|
(remove ".elc" completion-ignored-extensions)))
|
2000-12-06 18:38:47 +00:00
|
|
|
|
(read-file-name "Load file: "))))
|
|
|
|
|
(load (expand-file-name file) nil nil t))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2002-04-30 01:56:23 +00:00
|
|
|
|
(defun locate-file (filename path &optional suffixes predicate)
|
|
|
|
|
"Search for FILENAME through PATH.
|
2005-05-06 13:08:15 +00:00
|
|
|
|
If found, return the absolute file name of FILENAME, with its suffixes;
|
|
|
|
|
otherwise return nil.
|
|
|
|
|
PATH should be a list of directories to look in, like the lists in
|
|
|
|
|
`exec-path' or `load-path'.
|
2002-04-30 01:56:23 +00:00
|
|
|
|
If SUFFIXES is non-nil, it should be a list of suffixes to append to
|
|
|
|
|
file name when searching. If SUFFIXES is nil, it is equivalent to '(\"\").
|
2005-05-06 13:08:15 +00:00
|
|
|
|
Use '(\"/\") to disable PATH search, but still try the suffixes in SUFFIXES.
|
2002-04-30 01:56:23 +00:00
|
|
|
|
If non-nil, PREDICATE is used instead of `file-readable-p'.
|
2002-05-19 15:55:04 +00:00
|
|
|
|
PREDICATE can also be an integer to pass to the `access' system call,
|
|
|
|
|
in which case file-name handlers are ignored. This usage is deprecated.
|
|
|
|
|
|
|
|
|
|
For compatibility, PREDICATE can also be one of the symbols
|
|
|
|
|
`executable', `readable', `writable', or `exists', or a list of
|
|
|
|
|
one or more of those symbols."
|
2002-04-30 01:56:23 +00:00
|
|
|
|
(if (and predicate (symbolp predicate) (not (functionp predicate)))
|
|
|
|
|
(setq predicate (list predicate)))
|
|
|
|
|
(when (and (consp predicate) (not (functionp predicate)))
|
|
|
|
|
(setq predicate
|
|
|
|
|
(logior (if (memq 'executable predicate) 1 0)
|
|
|
|
|
(if (memq 'writable predicate) 2 0)
|
|
|
|
|
(if (memq 'readable predicate) 4 0))))
|
|
|
|
|
(locate-file-internal filename path suffixes predicate))
|
|
|
|
|
|
2008-04-19 03:33:13 +00:00
|
|
|
|
(defun locate-file-completion-table (dirs suffixes string pred action)
|
|
|
|
|
"Do completion for file names passed to `locate-file'."
|
2009-09-04 03:18:08 +00:00
|
|
|
|
(cond
|
|
|
|
|
((file-name-absolute-p string)
|
2009-10-21 20:03:57 +00:00
|
|
|
|
;; FIXME: maybe we should use completion-file-name-table instead,
|
|
|
|
|
;; tho at least for `load', the arg is passed through
|
|
|
|
|
;; substitute-in-file-name for historical reasons.
|
|
|
|
|
(read-file-name-internal string pred action))
|
2009-09-04 03:18:08 +00:00
|
|
|
|
((eq (car-safe action) 'boundaries)
|
|
|
|
|
(let ((suffix (cdr action)))
|
2009-09-07 15:23:09 +00:00
|
|
|
|
(list* 'boundaries
|
2009-09-04 03:18:08 +00:00
|
|
|
|
(length (file-name-directory string))
|
|
|
|
|
(let ((x (file-name-directory suffix)))
|
|
|
|
|
(if x (1- (length x)) (length suffix))))))
|
|
|
|
|
(t
|
2002-03-16 02:25:56 +00:00
|
|
|
|
(let ((names nil)
|
2008-04-19 03:33:13 +00:00
|
|
|
|
(suffix (concat (regexp-opt suffixes t) "\\'"))
|
2009-09-04 03:18:08 +00:00
|
|
|
|
(string-dir (file-name-directory string))
|
|
|
|
|
(string-file (file-name-nondirectory string)))
|
2008-04-19 03:33:13 +00:00
|
|
|
|
(dolist (dir dirs)
|
2004-04-17 19:58:19 +00:00
|
|
|
|
(unless dir
|
|
|
|
|
(setq dir default-directory))
|
2002-03-16 02:25:56 +00:00
|
|
|
|
(if string-dir (setq dir (expand-file-name string-dir dir)))
|
|
|
|
|
(when (file-directory-p dir)
|
|
|
|
|
(dolist (file (file-name-all-completions
|
2009-09-04 03:18:08 +00:00
|
|
|
|
string-file dir))
|
|
|
|
|
(push file names)
|
2002-03-16 02:25:56 +00:00
|
|
|
|
(when (string-match suffix file)
|
|
|
|
|
(setq file (substring file 0 (match-beginning 0)))
|
2009-09-04 03:18:08 +00:00
|
|
|
|
(push file names)))))
|
|
|
|
|
(completion-table-with-context
|
|
|
|
|
string-dir names string-file pred action)))))
|
2008-04-19 03:33:13 +00:00
|
|
|
|
|
|
|
|
|
(defun locate-file-completion (string path-and-suffixes action)
|
|
|
|
|
"Do completion for file names passed to `locate-file'.
|
|
|
|
|
PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)."
|
|
|
|
|
(locate-file-completion-table (car path-and-suffixes)
|
|
|
|
|
(cdr path-and-suffixes)
|
|
|
|
|
string nil action))
|
|
|
|
|
(make-obsolete 'locate-file-completion 'locate-file-completion-table "23.1")
|
2002-03-16 02:25:56 +00:00
|
|
|
|
|
2008-10-25 15:18:53 +00:00
|
|
|
|
(defvar locate-dominating-stop-dir-regexp
|
2009-10-26 06:43:36 +00:00
|
|
|
|
(purecopy "\\`\\(?:[\\/][\\/][^\\/]+[\\/]\\|/\\(?:net\\|afs\\|\\.\\.\\.\\)/\\)\\'")
|
2008-10-25 15:18:53 +00:00
|
|
|
|
"Regexp of directory names which stop the search in `locate-dominating-file'.
|
|
|
|
|
Any directory whose name matches this regexp will be treated like
|
|
|
|
|
a kind of root directory by `locate-dominating-file' which will stop its search
|
|
|
|
|
when it bumps into it.
|
|
|
|
|
The default regexp prevents fruitless and time-consuming attempts to find
|
2009-03-30 13:48:06 +00:00
|
|
|
|
special files in directories in which filenames are interpreted as hostnames,
|
|
|
|
|
or mount points potentially requiring authentication as a different user.")
|
2008-10-25 15:18:53 +00:00
|
|
|
|
|
|
|
|
|
;; (defun locate-dominating-files (file regexp)
|
|
|
|
|
;; "Look up the directory hierarchy from FILE for a file matching REGEXP.
|
|
|
|
|
;; Stop at the first parent where a matching file is found and return the list
|
|
|
|
|
;; of files that that match in this directory."
|
|
|
|
|
;; (catch 'found
|
|
|
|
|
;; ;; `user' is not initialized yet because `file' may not exist, so we may
|
|
|
|
|
;; ;; have to walk up part of the hierarchy before we find the "initial UID".
|
|
|
|
|
;; (let ((user nil)
|
|
|
|
|
;; ;; Abbreviate, so as to stop when we cross ~/.
|
|
|
|
|
;; (dir (abbreviate-file-name (file-name-as-directory file)))
|
|
|
|
|
;; files)
|
|
|
|
|
;; (while (and dir
|
|
|
|
|
;; ;; As a heuristic, we stop looking up the hierarchy of
|
|
|
|
|
;; ;; directories as soon as we find a directory belonging to
|
|
|
|
|
;; ;; another user. This should save us from looking in
|
|
|
|
|
;; ;; things like /net and /afs. This assumes that all the
|
|
|
|
|
;; ;; files inside a project belong to the same user.
|
|
|
|
|
;; (let ((prev-user user))
|
|
|
|
|
;; (setq user (nth 2 (file-attributes dir)))
|
|
|
|
|
;; (or (null prev-user) (equal user prev-user))))
|
|
|
|
|
;; (if (setq files (condition-case nil
|
|
|
|
|
;; (directory-files dir 'full regexp 'nosort)
|
|
|
|
|
;; (error nil)))
|
|
|
|
|
;; (throw 'found files)
|
|
|
|
|
;; (if (equal dir
|
|
|
|
|
;; (setq dir (file-name-directory
|
|
|
|
|
;; (directory-file-name dir))))
|
|
|
|
|
;; (setq dir nil))))
|
|
|
|
|
;; nil)))
|
|
|
|
|
|
|
|
|
|
(defun locate-dominating-file (file name)
|
|
|
|
|
"Look up the directory hierarchy from FILE for a file named NAME.
|
2008-11-13 16:01:47 +00:00
|
|
|
|
Stop at the first parent directory containing a file NAME,
|
|
|
|
|
and return the directory. Return nil if not found."
|
2008-10-25 15:18:53 +00:00
|
|
|
|
;; We used to use the above locate-dominating-files code, but the
|
|
|
|
|
;; directory-files call is very costly, so we're much better off doing
|
|
|
|
|
;; multiple calls using the code in here.
|
2008-11-13 16:01:47 +00:00
|
|
|
|
;;
|
2008-10-25 15:18:53 +00:00
|
|
|
|
;; Represent /home/luser/foo as ~/foo so that we don't try to look for
|
|
|
|
|
;; `name' in /home or in /.
|
|
|
|
|
(setq file (abbreviate-file-name file))
|
|
|
|
|
(let ((root nil)
|
|
|
|
|
(prev-file file)
|
|
|
|
|
;; `user' is not initialized outside the loop because
|
|
|
|
|
;; `file' may not exist, so we may have to walk up part of the
|
|
|
|
|
;; hierarchy before we find the "initial UID".
|
|
|
|
|
(user nil)
|
|
|
|
|
try)
|
|
|
|
|
(while (not (or root
|
|
|
|
|
(null file)
|
|
|
|
|
;; FIXME: Disabled this heuristic because it is sometimes
|
|
|
|
|
;; inappropriate.
|
|
|
|
|
;; As a heuristic, we stop looking up the hierarchy of
|
|
|
|
|
;; directories as soon as we find a directory belonging
|
|
|
|
|
;; to another user. This should save us from looking in
|
|
|
|
|
;; things like /net and /afs. This assumes that all the
|
|
|
|
|
;; files inside a project belong to the same user.
|
|
|
|
|
;; (let ((prev-user user))
|
|
|
|
|
;; (setq user (nth 2 (file-attributes file)))
|
|
|
|
|
;; (and prev-user (not (equal user prev-user))))
|
|
|
|
|
(string-match locate-dominating-stop-dir-regexp file)))
|
|
|
|
|
(setq try (file-exists-p (expand-file-name name file)))
|
|
|
|
|
(cond (try (setq root file))
|
|
|
|
|
((equal file (setq prev-file file
|
|
|
|
|
file (file-name-directory
|
|
|
|
|
(directory-file-name file))))
|
|
|
|
|
(setq file nil))))
|
|
|
|
|
root))
|
|
|
|
|
|
2007-07-19 03:29:47 +00:00
|
|
|
|
|
2005-05-11 16:24:55 +00:00
|
|
|
|
(defun executable-find (command)
|
|
|
|
|
"Search for COMMAND in `exec-path' and return the absolute file name.
|
|
|
|
|
Return nil if COMMAND is not found anywhere in `exec-path'."
|
|
|
|
|
;; Use 1 rather than file-executable-p to better match the behavior of
|
|
|
|
|
;; call-process.
|
|
|
|
|
(locate-file command exec-path exec-suffixes 1))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun load-library (library)
|
2009-04-28 19:00:38 +00:00
|
|
|
|
"Load the Emacs Lisp library named LIBRARY.
|
2009-08-15 17:51:37 +00:00
|
|
|
|
This is an interface to the function `load'. LIBRARY is searched
|
|
|
|
|
for in `load-path', both with and without `load-suffixes' (as
|
|
|
|
|
well as `load-file-rep-suffixes').
|
|
|
|
|
|
|
|
|
|
See Info node `(emacs)Lisp Libraries' for more details.
|
|
|
|
|
See `load-file' for a different interface to `load'."
|
2002-04-30 01:56:23 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(list (completing-read "Load library: "
|
2008-04-19 03:33:13 +00:00
|
|
|
|
(apply-partially 'locate-file-completion-table
|
|
|
|
|
load-path
|
|
|
|
|
(get-load-suffixes)))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(load library))
|
1992-09-14 01:39:31 +00:00
|
|
|
|
|
2007-07-17 21:07:49 +00:00
|
|
|
|
(defun file-remote-p (file &optional identification connected)
|
2004-06-26 14:41:13 +00:00
|
|
|
|
"Test whether FILE specifies a location on a remote system.
|
2008-01-30 21:25:08 +00:00
|
|
|
|
Returns nil or a string identifying the remote connection (ideally
|
|
|
|
|
a prefix of FILE). For example, the remote identification for filename
|
|
|
|
|
\"/user@host:/foo\" could be \"/user@host:\".
|
|
|
|
|
A file is considered \"remote\" if accessing it is likely to be slower or
|
|
|
|
|
less reliable than accessing local files.
|
|
|
|
|
Furthermore, relative file names do not work across remote connections.
|
2007-07-08 18:03:20 +00:00
|
|
|
|
|
2007-07-17 21:07:49 +00:00
|
|
|
|
IDENTIFICATION specifies which part of the identification shall
|
|
|
|
|
be returned as string. IDENTIFICATION can be the symbol
|
2008-09-29 05:39:39 +00:00
|
|
|
|
`method', `user', `host' or `localname'; any other value is
|
|
|
|
|
handled like nil and means to return the complete identification
|
|
|
|
|
string.
|
2007-07-17 21:07:49 +00:00
|
|
|
|
|
2007-07-08 18:03:20 +00:00
|
|
|
|
If CONNECTED is non-nil, the function returns an identification only
|
|
|
|
|
if FILE is located on a remote system, and a connection is established
|
|
|
|
|
to that remote system.
|
|
|
|
|
|
|
|
|
|
`file-remote-p' will never open a connection on its own."
|
2004-05-29 22:42:06 +00:00
|
|
|
|
(let ((handler (find-file-name-handler file 'file-remote-p)))
|
2002-07-02 18:58:29 +00:00
|
|
|
|
(if handler
|
2007-07-17 21:07:49 +00:00
|
|
|
|
(funcall handler 'file-remote-p file identification connected)
|
2004-05-29 22:42:06 +00:00
|
|
|
|
nil)))
|
2002-07-02 18:58:29 +00:00
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defun file-local-copy (file)
|
1992-09-14 01:39:31 +00:00
|
|
|
|
"Copy the file FILE into a temporary file on this machine.
|
|
|
|
|
Returns the name of the local copy, or nil, if FILE is directly
|
|
|
|
|
accessible."
|
2000-10-04 17:16:59 +00:00
|
|
|
|
;; This formerly had an optional BUFFER argument that wasn't used by
|
|
|
|
|
;; anything.
|
1994-04-22 23:59:24 +00:00
|
|
|
|
(let ((handler (find-file-name-handler file 'file-local-copy)))
|
1992-09-14 01:39:31 +00:00
|
|
|
|
(if handler
|
|
|
|
|
(funcall handler 'file-local-copy file)
|
|
|
|
|
nil)))
|
1992-10-12 04:45:53 +00:00
|
|
|
|
|
1994-07-05 20:23:13 +00:00
|
|
|
|
(defun file-truename (filename &optional counter prev-dirs)
|
1992-10-12 04:45:53 +00:00
|
|
|
|
"Return the truename of FILENAME, which should be absolute.
|
|
|
|
|
The truename of a file name is found by chasing symbolic links
|
|
|
|
|
both at the level of the file and at the level of the directories
|
1994-07-05 20:23:13 +00:00
|
|
|
|
containing it, until no links are left at any level.
|
|
|
|
|
|
2004-11-04 10:04:16 +00:00
|
|
|
|
\(fn FILENAME)" ;; Don't document the optional arguments.
|
2004-05-13 19:51:57 +00:00
|
|
|
|
;; COUNTER and PREV-DIRS are only used in recursive calls.
|
|
|
|
|
;; COUNTER can be a cons cell whose car is the count of how many
|
|
|
|
|
;; more links to chase before getting an error.
|
1994-07-05 20:23:13 +00:00
|
|
|
|
;; PREV-DIRS can be a cons cell whose car is an alist
|
|
|
|
|
;; of truenames we've just recently computed.
|
2004-04-17 19:58:19 +00:00
|
|
|
|
(cond ((or (string= filename "") (string= filename "~"))
|
|
|
|
|
(setq filename (expand-file-name filename))
|
|
|
|
|
(if (string= filename "")
|
|
|
|
|
(setq filename "/")))
|
|
|
|
|
((and (string= (substring filename 0 1) "~")
|
|
|
|
|
(string-match "~[^/]*/?" filename))
|
|
|
|
|
(let ((first-part
|
|
|
|
|
(substring filename 0 (match-end 0)))
|
|
|
|
|
(rest (substring filename (match-end 0))))
|
|
|
|
|
(setq filename (concat (expand-file-name first-part) rest)))))
|
|
|
|
|
|
1994-07-05 20:23:13 +00:00
|
|
|
|
(or counter (setq counter (list 100)))
|
1994-07-29 03:45:49 +00:00
|
|
|
|
(let (done
|
|
|
|
|
;; For speed, remove the ange-ftp completion handler from the list.
|
|
|
|
|
;; We know it's not needed here.
|
|
|
|
|
;; For even more speed, do this only on the outermost call.
|
|
|
|
|
(file-name-handler-alist
|
|
|
|
|
(if prev-dirs file-name-handler-alist
|
|
|
|
|
(let ((tem (copy-sequence file-name-handler-alist)))
|
|
|
|
|
(delq (rassq 'ange-ftp-completion-hook-function tem) tem)))))
|
|
|
|
|
(or prev-dirs (setq prev-dirs (list nil)))
|
1997-09-02 19:38:31 +00:00
|
|
|
|
|
|
|
|
|
;; andrewi@harlequin.co.uk - none of the following code (except for
|
|
|
|
|
;; invoking the file-name handler) currently applies on Windows
|
|
|
|
|
;; (ie. there are no native symlinks), but there is an issue with
|
|
|
|
|
;; case differences being ignored by the OS, and short "8.3 DOS"
|
|
|
|
|
;; name aliases existing for all files. (The short names are not
|
|
|
|
|
;; reported by directory-files, but can be used to refer to files.)
|
|
|
|
|
;; It seems appropriate for file-truename to resolve these issues in
|
|
|
|
|
;; the most natural way, which on Windows is to call the function
|
|
|
|
|
;; `w32-long-file-name' - this returns the exact name of a file as
|
|
|
|
|
;; it is stored on disk (expanding short name aliases with the full
|
|
|
|
|
;; name in the process).
|
|
|
|
|
(if (eq system-type 'windows-nt)
|
2002-11-27 23:53:44 +00:00
|
|
|
|
(let ((handler (find-file-name-handler filename 'file-truename)))
|
1997-09-02 19:38:31 +00:00
|
|
|
|
;; For file name that has a special handler, call handler.
|
|
|
|
|
;; This is so that ange-ftp can save time by doing a no-op.
|
|
|
|
|
(if handler
|
|
|
|
|
(setq filename (funcall handler 'file-truename filename))
|
|
|
|
|
;; If filename contains a wildcard, newname will be the old name.
|
2002-11-27 23:53:44 +00:00
|
|
|
|
(unless (string-match "[[*?]" filename)
|
2008-07-11 23:08:07 +00:00
|
|
|
|
;; If filename exists, use the long name. If it doesn't exist,
|
|
|
|
|
;; drill down until we find a directory that exists, and use
|
|
|
|
|
;; the long name of that, with the extra non-existent path
|
|
|
|
|
;; components concatenated.
|
|
|
|
|
(let ((longname (w32-long-file-name filename))
|
|
|
|
|
missing rest)
|
|
|
|
|
(if longname
|
|
|
|
|
(setq filename longname)
|
2008-09-15 09:23:45 +00:00
|
|
|
|
;; Include the preceding directory separator in the missing
|
2008-07-11 23:08:07 +00:00
|
|
|
|
;; part so subsequent recursion on the rest works.
|
|
|
|
|
(setq missing (concat "/" (file-name-nondirectory filename)))
|
2008-09-15 09:23:45 +00:00
|
|
|
|
(let ((length (length missing)))
|
|
|
|
|
(setq rest
|
|
|
|
|
(if (> length (length filename))
|
|
|
|
|
""
|
|
|
|
|
(substring filename 0 (- length)))))
|
2008-07-11 23:08:07 +00:00
|
|
|
|
(setq filename (concat (file-truename rest) missing))))))
|
1997-09-02 19:38:31 +00:00
|
|
|
|
(setq done t)))
|
|
|
|
|
|
1994-07-05 20:23:13 +00:00
|
|
|
|
;; If this file directly leads to a link, process that iteratively
|
|
|
|
|
;; so that we don't use lots of stack.
|
|
|
|
|
(while (not done)
|
|
|
|
|
(setcar counter (1- (car counter)))
|
|
|
|
|
(if (< (car counter) 0)
|
|
|
|
|
(error "Apparent cycle of symbolic links for %s" filename))
|
|
|
|
|
(let ((handler (find-file-name-handler filename 'file-truename)))
|
|
|
|
|
;; For file name that has a special handler, call handler.
|
|
|
|
|
;; This is so that ange-ftp can save time by doing a no-op.
|
|
|
|
|
(if handler
|
|
|
|
|
(setq filename (funcall handler 'file-truename filename)
|
|
|
|
|
done t)
|
1994-10-02 20:10:39 +00:00
|
|
|
|
(let ((dir (or (file-name-directory filename) default-directory))
|
1994-07-05 20:23:13 +00:00
|
|
|
|
target dirfile)
|
|
|
|
|
;; Get the truename of the directory.
|
|
|
|
|
(setq dirfile (directory-file-name dir))
|
|
|
|
|
;; If these are equal, we have the (or a) root directory.
|
|
|
|
|
(or (string= dir dirfile)
|
|
|
|
|
;; If this is the same dir we last got the truename for,
|
|
|
|
|
;; save time--don't recalculate.
|
|
|
|
|
(if (assoc dir (car prev-dirs))
|
|
|
|
|
(setq dir (cdr (assoc dir (car prev-dirs))))
|
|
|
|
|
(let ((old dir)
|
|
|
|
|
(new (file-name-as-directory (file-truename dirfile counter prev-dirs))))
|
|
|
|
|
(setcar prev-dirs (cons (cons old new) (car prev-dirs)))
|
|
|
|
|
(setq dir new))))
|
|
|
|
|
(if (equal ".." (file-name-nondirectory filename))
|
|
|
|
|
(setq filename
|
|
|
|
|
(directory-file-name (file-name-directory (directory-file-name dir)))
|
|
|
|
|
done t)
|
|
|
|
|
(if (equal "." (file-name-nondirectory filename))
|
|
|
|
|
(setq filename (directory-file-name dir)
|
|
|
|
|
done t)
|
|
|
|
|
;; Put it back on the file name.
|
|
|
|
|
(setq filename (concat dir (file-name-nondirectory filename)))
|
|
|
|
|
;; Is the file name the name of a link?
|
|
|
|
|
(setq target (file-symlink-p filename))
|
|
|
|
|
(if target
|
|
|
|
|
;; Yes => chase that link, then start all over
|
|
|
|
|
;; since the link may point to a directory name that uses links.
|
|
|
|
|
;; We can't safely use expand-file-name here
|
|
|
|
|
;; since target might look like foo/../bar where foo
|
|
|
|
|
;; is itself a link. Instead, we handle . and .. above.
|
|
|
|
|
(setq filename
|
|
|
|
|
(if (file-name-absolute-p target)
|
|
|
|
|
target
|
|
|
|
|
(concat dir target))
|
|
|
|
|
done nil)
|
|
|
|
|
;; No, we are done!
|
|
|
|
|
(setq done t))))))))
|
|
|
|
|
filename))
|
1992-12-12 15:21:45 +00:00
|
|
|
|
|
2003-04-09 01:34:38 +00:00
|
|
|
|
(defun file-chase-links (filename &optional limit)
|
1993-05-29 20:00:45 +00:00
|
|
|
|
"Chase links in FILENAME until a name that is not a link.
|
2003-04-09 01:34:38 +00:00
|
|
|
|
Unlike `file-truename', this does not check whether a parent
|
|
|
|
|
directory name is a symbolic link.
|
|
|
|
|
If the optional argument LIMIT is a number,
|
|
|
|
|
it means chase no more than that many links and then stop."
|
|
|
|
|
(let (tem (newname filename)
|
2003-04-09 19:06:19 +00:00
|
|
|
|
(count 0))
|
2003-04-09 01:34:38 +00:00
|
|
|
|
(while (and (or (null limit) (< count limit))
|
|
|
|
|
(setq tem (file-symlink-p newname)))
|
1997-06-27 09:04:14 +00:00
|
|
|
|
(save-match-data
|
2003-04-09 19:06:19 +00:00
|
|
|
|
(if (and (null limit) (= count 100))
|
1997-06-27 09:04:14 +00:00
|
|
|
|
(error "Apparent cycle of symbolic links for %s" filename))
|
|
|
|
|
;; In the context of a link, `//' doesn't mean what Emacs thinks.
|
|
|
|
|
(while (string-match "//+" tem)
|
|
|
|
|
(setq tem (replace-match "/" nil nil tem)))
|
|
|
|
|
;; Handle `..' by hand, since it needs to work in the
|
|
|
|
|
;; target of any directory symlink.
|
|
|
|
|
;; This code is not quite complete; it does not handle
|
|
|
|
|
;; embedded .. in some cases such as ./../foo and foo/bar/../../../lose.
|
|
|
|
|
(while (string-match "\\`\\.\\./" tem)
|
|
|
|
|
(setq tem (substring tem 3))
|
|
|
|
|
(setq newname (expand-file-name newname))
|
|
|
|
|
;; Chase links in the default dir of the symlink.
|
|
|
|
|
(setq newname
|
|
|
|
|
(file-chase-links
|
|
|
|
|
(directory-file-name (file-name-directory newname))))
|
|
|
|
|
;; Now find the parent of that dir.
|
|
|
|
|
(setq newname (file-name-directory newname)))
|
|
|
|
|
(setq newname (expand-file-name tem (file-name-directory newname)))
|
2003-04-09 19:06:19 +00:00
|
|
|
|
(setq count (1+ count))))
|
1993-05-29 20:00:45 +00:00
|
|
|
|
newname))
|
2003-03-26 04:42:29 +00:00
|
|
|
|
|
2005-10-22 15:34:37 +00:00
|
|
|
|
(defun make-temp-file (prefix &optional dir-flag suffix)
|
|
|
|
|
"Create a temporary file.
|
|
|
|
|
The returned file name (created by appending some random characters at the end
|
|
|
|
|
of PREFIX, and expanding against `temporary-file-directory' if necessary),
|
|
|
|
|
is guaranteed to point to a newly created empty file.
|
|
|
|
|
You can then use `write-region' to write new data into the file.
|
|
|
|
|
|
|
|
|
|
If DIR-FLAG is non-nil, create a new empty directory instead of a file.
|
|
|
|
|
|
|
|
|
|
If SUFFIX is non-nil, add that at the end of the file name."
|
|
|
|
|
(let ((umask (default-file-modes))
|
|
|
|
|
file)
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
;; Create temp files with strict access rights. It's easy to
|
|
|
|
|
;; loosen them later, whereas it's impossible to close the
|
|
|
|
|
;; time-window of loose permissions otherwise.
|
|
|
|
|
(set-default-file-modes ?\700)
|
|
|
|
|
(while (condition-case ()
|
|
|
|
|
(progn
|
|
|
|
|
(setq file
|
|
|
|
|
(make-temp-name
|
2008-10-04 20:31:33 +00:00
|
|
|
|
(if (zerop (length prefix))
|
|
|
|
|
(file-name-as-directory
|
|
|
|
|
temporary-file-directory)
|
|
|
|
|
(expand-file-name prefix
|
|
|
|
|
temporary-file-directory))))
|
2005-10-22 15:34:37 +00:00
|
|
|
|
(if suffix
|
|
|
|
|
(setq file (concat file suffix)))
|
|
|
|
|
(if dir-flag
|
|
|
|
|
(make-directory file)
|
|
|
|
|
(write-region "" nil file nil 'silent nil 'excl))
|
|
|
|
|
nil)
|
|
|
|
|
(file-already-exists t))
|
|
|
|
|
;; the file was somehow created by someone else between
|
|
|
|
|
;; `make-temp-name' and `write-region', let's try again.
|
|
|
|
|
nil)
|
|
|
|
|
file)
|
|
|
|
|
;; Reset the umask.
|
|
|
|
|
(set-default-file-modes umask))))
|
|
|
|
|
|
2003-03-26 04:42:29 +00:00
|
|
|
|
(defun recode-file-name (file coding new-coding &optional ok-if-already-exists)
|
|
|
|
|
"Change the encoding of FILE's name from CODING to NEW-CODING.
|
|
|
|
|
The value is a new name of FILE.
|
|
|
|
|
Signals a `file-already-exists' error if a file of the new name
|
2005-07-20 01:57:49 +00:00
|
|
|
|
already exists unless optional fourth argument OK-IF-ALREADY-EXISTS
|
|
|
|
|
is non-nil. A number as fourth arg means request confirmation if
|
2003-03-26 04:42:29 +00:00
|
|
|
|
the new name already exists. This is what happens in interactive
|
|
|
|
|
use with M-x."
|
|
|
|
|
(interactive
|
|
|
|
|
(let ((default-coding (or file-name-coding-system
|
|
|
|
|
default-file-name-coding-system))
|
|
|
|
|
(filename (read-file-name "Recode filename: " nil nil t))
|
|
|
|
|
from-coding to-coding)
|
|
|
|
|
(if (and default-coding
|
|
|
|
|
;; We provide the default coding only when it seems that
|
|
|
|
|
;; the filename is correctly decoded by the default
|
|
|
|
|
;; coding.
|
|
|
|
|
(let ((charsets (find-charset-string filename)))
|
|
|
|
|
(and (not (memq 'eight-bit-control charsets))
|
|
|
|
|
(not (memq 'eight-bit-graphic charsets)))))
|
|
|
|
|
(setq from-coding (read-coding-system
|
|
|
|
|
(format "Recode filename %s from (default %s): "
|
|
|
|
|
filename default-coding)
|
|
|
|
|
default-coding))
|
|
|
|
|
(setq from-coding (read-coding-system
|
|
|
|
|
(format "Recode filename %s from: " filename))))
|
2003-05-07 21:58:24 +00:00
|
|
|
|
|
2003-03-26 04:42:29 +00:00
|
|
|
|
;; We provide the default coding only when a user is going to
|
|
|
|
|
;; change the encoding not from the default coding.
|
|
|
|
|
(if (eq from-coding default-coding)
|
|
|
|
|
(setq to-coding (read-coding-system
|
|
|
|
|
(format "Recode filename %s from %s to: "
|
|
|
|
|
filename from-coding)))
|
|
|
|
|
(setq to-coding (read-coding-system
|
|
|
|
|
(format "Recode filename %s from %s to (default %s): "
|
|
|
|
|
filename from-coding default-coding)
|
|
|
|
|
default-coding)))
|
|
|
|
|
(list filename from-coding to-coding)))
|
|
|
|
|
|
|
|
|
|
(let* ((default-coding (or file-name-coding-system
|
|
|
|
|
default-file-name-coding-system))
|
|
|
|
|
;; FILE should have been decoded by DEFAULT-CODING.
|
|
|
|
|
(encoded (encode-coding-string file default-coding))
|
|
|
|
|
(newname (decode-coding-string encoded coding))
|
|
|
|
|
(new-encoded (encode-coding-string newname new-coding))
|
|
|
|
|
;; Suppress further encoding.
|
|
|
|
|
(file-name-coding-system nil)
|
|
|
|
|
(default-file-name-coding-system nil)
|
|
|
|
|
(locale-coding-system nil))
|
|
|
|
|
(rename-file encoded new-encoded ok-if-already-exists)
|
|
|
|
|
newname))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(defcustom confirm-nonexistent-file-or-buffer 'after-completion
|
|
|
|
|
"Whether confirmation is requested before visiting a new file or buffer.
|
|
|
|
|
If nil, confirmation is not requested.
|
|
|
|
|
If the value is `after-completion', confirmation is only
|
|
|
|
|
requested if the user called `minibuffer-complete' right before
|
|
|
|
|
`minibuffer-complete-and-exit'.
|
|
|
|
|
Any other non-nil value means to request confirmation.
|
|
|
|
|
|
2008-11-18 18:26:08 +00:00
|
|
|
|
This affects commands like `switch-to-buffer' and `find-file'."
|
|
|
|
|
:group 'find-file
|
|
|
|
|
:version "23.1"
|
2009-03-01 00:48:51 +00:00
|
|
|
|
:type '(choice (const :tag "After completion" after-completion)
|
|
|
|
|
(const :tag "Never" nil)
|
|
|
|
|
(other :tag "Always" t)))
|
2008-11-24 19:13:58 +00:00
|
|
|
|
|
|
|
|
|
(defun confirm-nonexistent-file-or-buffer ()
|
|
|
|
|
"Whether to request confirmation before visiting a new file or buffer.
|
|
|
|
|
The variable `confirm-nonexistent-file-or-buffer' determines the
|
|
|
|
|
return value, which may be passed as the REQUIRE-MATCH arg to
|
|
|
|
|
`read-buffer' or `find-file-read-args'."
|
|
|
|
|
(cond ((eq confirm-nonexistent-file-or-buffer 'after-completion)
|
|
|
|
|
'confirm-after-completion)
|
|
|
|
|
(confirm-nonexistent-file-or-buffer
|
|
|
|
|
'confirm)
|
|
|
|
|
(t nil)))
|
2008-11-18 18:26:08 +00:00
|
|
|
|
|
2008-04-22 19:48:02 +00:00
|
|
|
|
(defun read-buffer-to-switch (prompt)
|
|
|
|
|
"Read the name of a buffer to switch to and return as a string.
|
|
|
|
|
It is intended for `switch-to-buffer' family of commands since they
|
2008-04-29 14:47:45 +00:00
|
|
|
|
need to omit the name of current buffer from the list of completions
|
2008-04-22 19:48:02 +00:00
|
|
|
|
and default values."
|
2008-04-29 14:47:45 +00:00
|
|
|
|
(let ((rbts-completion-table (internal-complete-buffer-except)))
|
|
|
|
|
(minibuffer-with-setup-hook
|
2009-02-12 02:19:53 +00:00
|
|
|
|
(lambda ()
|
|
|
|
|
(setq minibuffer-completion-table rbts-completion-table)
|
|
|
|
|
;; Since rbts-completion-table is built dynamically, we
|
|
|
|
|
;; can't just add it to the default value of
|
|
|
|
|
;; icomplete-with-completion-tables, so we add it
|
|
|
|
|
;; here manually.
|
|
|
|
|
(if (and (boundp 'icomplete-with-completion-tables)
|
|
|
|
|
(listp icomplete-with-completion-tables))
|
|
|
|
|
(set (make-local-variable 'icomplete-with-completion-tables)
|
|
|
|
|
(cons rbts-completion-table
|
|
|
|
|
icomplete-with-completion-tables))))
|
2008-11-18 18:26:08 +00:00
|
|
|
|
(read-buffer prompt (other-buffer (current-buffer))
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(confirm-nonexistent-file-or-buffer)))))
|
2008-04-22 19:48:02 +00:00
|
|
|
|
|
2008-11-22 11:42:00 +00:00
|
|
|
|
(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
|
|
|
|
|
"Select the buffer specified by BUFFER-OR-NAME in another window.
|
|
|
|
|
BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
|
|
|
|
|
nil. Return the buffer switched to.
|
|
|
|
|
|
2008-11-24 19:13:58 +00:00
|
|
|
|
If called interactively, prompt for the buffer name using the
|
|
|
|
|
minibuffer. The variable `confirm-nonexistent-file-or-buffer'
|
|
|
|
|
determines whether to request confirmation before creating a new
|
|
|
|
|
buffer.
|
|
|
|
|
|
2008-11-22 11:42:00 +00:00
|
|
|
|
If BUFFER-OR-NAME is a string and does not identify an existing
|
2008-11-24 19:13:58 +00:00
|
|
|
|
buffer, create a new buffer with that name. If BUFFER-OR-NAME is
|
|
|
|
|
nil, switch to the buffer returned by `other-buffer'.
|
2008-11-22 11:42:00 +00:00
|
|
|
|
|
|
|
|
|
Optional second argument NORECORD non-nil means do not put this
|
2008-11-14 13:05:18 +00:00
|
|
|
|
buffer at the front of the list of recently selected ones.
|
2001-05-17 10:59:18 +00:00
|
|
|
|
|
|
|
|
|
This uses the function `display-buffer' as a subroutine; see its
|
|
|
|
|
documentation for additional customization information."
|
2008-04-22 19:48:02 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(list (read-buffer-to-switch "Switch to buffer in other window: ")))
|
2004-03-04 16:49:23 +00:00
|
|
|
|
(let ((pop-up-windows t)
|
|
|
|
|
same-window-buffer-names same-window-regexps)
|
2008-11-22 11:42:00 +00:00
|
|
|
|
(pop-to-buffer buffer-or-name t norecord)))
|
|
|
|
|
|
|
|
|
|
(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
|
|
|
|
|
"Switch to buffer BUFFER-OR-NAME in another frame.
|
|
|
|
|
BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
|
|
|
|
|
nil. Return the buffer switched to.
|
|
|
|
|
|
2008-11-24 19:13:58 +00:00
|
|
|
|
If called interactively, prompt for the buffer name using the
|
|
|
|
|
minibuffer. The variable `confirm-nonexistent-file-or-buffer'
|
|
|
|
|
determines whether to request confirmation before creating a new
|
|
|
|
|
buffer.
|
|
|
|
|
|
2008-11-22 11:42:00 +00:00
|
|
|
|
If BUFFER-OR-NAME is a string and does not identify an existing
|
2008-11-24 19:13:58 +00:00
|
|
|
|
buffer, create a new buffer with that name. If BUFFER-OR-NAME is
|
|
|
|
|
nil, switch to the buffer returned by `other-buffer'.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2008-09-16 08:28:18 +00:00
|
|
|
|
Optional second arg NORECORD non-nil means do not put this
|
|
|
|
|
buffer at the front of the list of recently selected ones.
|
2001-05-17 10:59:18 +00:00
|
|
|
|
|
2008-11-22 11:42:00 +00:00
|
|
|
|
This uses the function `display-buffer' as a subroutine; see its
|
|
|
|
|
documentation for additional customization information."
|
2008-04-22 19:48:02 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(list (read-buffer-to-switch "Switch to buffer in other frame: ")))
|
2004-03-04 16:49:23 +00:00
|
|
|
|
(let ((pop-up-frames t)
|
|
|
|
|
same-window-buffer-names same-window-regexps)
|
2008-11-22 11:42:00 +00:00
|
|
|
|
(pop-to-buffer buffer-or-name t norecord)))
|
1991-10-31 08:30:58 +00:00
|
|
|
|
|
2006-03-20 15:05:41 +00:00
|
|
|
|
(defun display-buffer-other-frame (buffer)
|
2008-09-16 08:28:18 +00:00
|
|
|
|
"Display buffer BUFFER in another frame.
|
|
|
|
|
This uses the function `display-buffer' as a subroutine; see
|
|
|
|
|
its documentation for additional customization information."
|
2006-03-20 15:05:41 +00:00
|
|
|
|
(interactive "BDisplay buffer in other frame: ")
|
|
|
|
|
(let ((pop-up-frames t)
|
|
|
|
|
same-window-buffer-names same-window-regexps
|
|
|
|
|
(old-window (selected-window))
|
|
|
|
|
new-window)
|
|
|
|
|
(setq new-window (display-buffer buffer t))
|
2008-03-11 20:48:57 +00:00
|
|
|
|
;; This may have been here in order to prevent the new frame from hiding
|
|
|
|
|
;; the old frame. But it does more harm than good.
|
|
|
|
|
;; Maybe we should call `raise-window' on the old-frame instead? --Stef
|
|
|
|
|
;;(lower-frame (window-frame new-window))
|
|
|
|
|
|
|
|
|
|
;; This may have been here in order to make sure the old-frame gets the
|
|
|
|
|
;; focus. But not only can it cause an annoying flicker, with some
|
|
|
|
|
;; window-managers it just makes the window invisible, with no easy
|
|
|
|
|
;; way to recover it. --Stef
|
|
|
|
|
;;(make-frame-invisible (window-frame old-window))
|
|
|
|
|
;;(make-frame-visible (window-frame old-window))
|
|
|
|
|
))
|
2006-03-20 15:05:41 +00:00
|
|
|
|
|
2005-03-28 19:58:58 +00:00
|
|
|
|
(defmacro minibuffer-with-setup-hook (fun &rest body)
|
2010-01-01 20:03:37 +00:00
|
|
|
|
"Temporarily add FUN to `minibuffer-setup-hook' while executing BODY.
|
2005-03-28 19:58:58 +00:00
|
|
|
|
BODY should use the minibuffer at most once.
|
2010-01-01 20:03:37 +00:00
|
|
|
|
Recursive uses of the minibuffer are unaffected (FUN is not
|
|
|
|
|
called additional times).
|
|
|
|
|
|
2010-01-17 02:25:53 +00:00
|
|
|
|
This macro actually adds an auxiliary function that calls FUN,
|
2010-01-01 20:03:37 +00:00
|
|
|
|
rather than FUN itself, to `minibuffer-setup-hook'."
|
2005-03-28 19:58:58 +00:00
|
|
|
|
(declare (indent 1) (debug t))
|
|
|
|
|
(let ((hook (make-symbol "setup-hook")))
|
2005-04-23 16:53:21 +00:00
|
|
|
|
`(let (,hook)
|
|
|
|
|
(setq ,hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; Clear out this hook so it does not interfere
|
|
|
|
|
;; with any recursive minibuffer usage.
|
|
|
|
|
(remove-hook 'minibuffer-setup-hook ,hook)
|
2008-05-02 17:22:04 +00:00
|
|
|
|
(funcall ,fun)))
|
2005-03-28 19:58:58 +00:00
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
(add-hook 'minibuffer-setup-hook ,hook)
|
|
|
|
|
,@body)
|
|
|
|
|
(remove-hook 'minibuffer-setup-hook ,hook)))))
|
|
|
|
|
|
2002-06-21 08:35:50 +00:00
|
|
|
|
(defun find-file-read-args (prompt mustmatch)
|
2009-11-25 17:11:29 +00:00
|
|
|
|
(list (read-file-name prompt nil default-directory mustmatch)
|
2002-12-07 14:47:40 +00:00
|
|
|
|
t))
|
2002-05-19 15:55:04 +00:00
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
(defun find-file (filename &optional wildcards)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Edit file FILENAME.
|
|
|
|
|
Switch to a buffer visiting file FILENAME,
|
1999-01-24 20:10:30 +00:00
|
|
|
|
creating one if none already exists.
|
2002-05-19 15:55:04 +00:00
|
|
|
|
Interactively, the default if you just type RET is the current directory,
|
|
|
|
|
but the visited file name is available through the minibuffer history:
|
|
|
|
|
type M-n to pull it into the minibuffer.
|
|
|
|
|
|
2007-09-13 08:30:45 +00:00
|
|
|
|
You can visit files on remote machines by specifying something
|
|
|
|
|
like /ssh:SOME_REMOTE_MACHINE:FILE for the file name. You can
|
|
|
|
|
also visit local files as a different user by specifying
|
2007-09-13 08:49:47 +00:00
|
|
|
|
/sudo::FILE for the file name.
|
|
|
|
|
See the Info node `(tramp)Filename Syntax' in the Tramp Info
|
|
|
|
|
manual, for more about this.
|
2007-09-13 08:30:45 +00:00
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
Interactively, or if WILDCARDS is non-nil in a call from Lisp,
|
2004-05-30 13:34:19 +00:00
|
|
|
|
expand wildcards (if any) and visit multiple files. You can
|
2006-02-11 18:42:56 +00:00
|
|
|
|
suppress wildcard expansion by setting `find-file-wildcards' to nil.
|
2004-05-30 13:34:19 +00:00
|
|
|
|
|
|
|
|
|
To visit a file without any kind of conversion and without
|
|
|
|
|
automatically choosing a major mode, use \\[find-file-literally]."
|
2007-07-01 01:57:31 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(find-file-read-args "Find file: "
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(confirm-nonexistent-file-or-buffer)))
|
1999-01-24 20:12:25 +00:00
|
|
|
|
(let ((value (find-file-noselect filename nil nil wildcards)))
|
|
|
|
|
(if (listp value)
|
|
|
|
|
(mapcar 'switch-to-buffer (nreverse value))
|
|
|
|
|
(switch-to-buffer value))))
|
1997-02-20 05:44:24 +00:00
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
(defun find-file-other-window (filename &optional wildcards)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Edit file FILENAME, in another window.
|
2007-09-13 08:30:45 +00:00
|
|
|
|
|
|
|
|
|
Like \\[find-file] (which see), but creates a new window or reuses
|
|
|
|
|
an existing one. See the function `display-buffer'.
|
2002-05-19 15:55:04 +00:00
|
|
|
|
|
|
|
|
|
Interactively, the default if you just type RET is the current directory,
|
|
|
|
|
but the visited file name is available through the minibuffer history:
|
|
|
|
|
type M-n to pull it into the minibuffer.
|
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
Interactively, or if WILDCARDS is non-nil in a call from Lisp,
|
|
|
|
|
expand wildcards (if any) and visit multiple files."
|
2007-07-01 01:57:31 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(find-file-read-args "Find file in other window: "
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(confirm-nonexistent-file-or-buffer)))
|
1999-01-24 20:12:25 +00:00
|
|
|
|
(let ((value (find-file-noselect filename nil nil wildcards)))
|
|
|
|
|
(if (listp value)
|
|
|
|
|
(progn
|
|
|
|
|
(setq value (nreverse value))
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(cons (switch-to-buffer-other-window (car value))
|
|
|
|
|
(mapcar 'switch-to-buffer (cdr value))))
|
1999-01-24 20:12:25 +00:00
|
|
|
|
(switch-to-buffer-other-window value))))
|
1999-01-24 20:10:30 +00:00
|
|
|
|
|
|
|
|
|
(defun find-file-other-frame (filename &optional wildcards)
|
1992-07-15 02:24:58 +00:00
|
|
|
|
"Edit file FILENAME, in another frame.
|
2007-09-13 08:30:45 +00:00
|
|
|
|
|
|
|
|
|
Like \\[find-file] (which see), but creates a new frame or reuses
|
|
|
|
|
an existing one. See the function `display-buffer'.
|
2002-05-19 15:55:04 +00:00
|
|
|
|
|
|
|
|
|
Interactively, the default if you just type RET is the current directory,
|
|
|
|
|
but the visited file name is available through the minibuffer history:
|
|
|
|
|
type M-n to pull it into the minibuffer.
|
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
Interactively, or if WILDCARDS is non-nil in a call from Lisp,
|
|
|
|
|
expand wildcards (if any) and visit multiple files."
|
2007-07-01 01:57:31 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(find-file-read-args "Find file in other frame: "
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(confirm-nonexistent-file-or-buffer)))
|
1999-01-24 20:12:25 +00:00
|
|
|
|
(let ((value (find-file-noselect filename nil nil wildcards)))
|
|
|
|
|
(if (listp value)
|
|
|
|
|
(progn
|
|
|
|
|
(setq value (nreverse value))
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(cons (switch-to-buffer-other-frame (car value))
|
|
|
|
|
(mapcar 'switch-to-buffer (cdr value))))
|
1999-01-24 20:12:25 +00:00
|
|
|
|
(switch-to-buffer-other-frame value))))
|
1999-01-24 20:10:30 +00:00
|
|
|
|
|
2006-09-30 10:02:22 +00:00
|
|
|
|
(defun find-file-existing (filename)
|
|
|
|
|
"Edit the existing file FILENAME.
|
2007-09-13 08:30:45 +00:00
|
|
|
|
Like \\[find-file], but only allow a file that exists, and do not allow
|
2006-09-30 10:02:22 +00:00
|
|
|
|
file names with wildcards."
|
|
|
|
|
(interactive (nbutlast (find-file-read-args "Find existing file: " t)))
|
2009-10-02 03:48:36 +00:00
|
|
|
|
(if (and (not (called-interactively-p 'interactive))
|
|
|
|
|
(not (file-exists-p filename)))
|
2006-09-30 10:02:22 +00:00
|
|
|
|
(error "%s does not exist" filename)
|
|
|
|
|
(find-file filename)
|
|
|
|
|
(current-buffer)))
|
2004-11-02 07:57:53 +00:00
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
(defun find-file-read-only (filename &optional wildcards)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Edit file FILENAME but don't allow changes.
|
2007-09-13 08:30:45 +00:00
|
|
|
|
Like \\[find-file], but marks buffer as read-only.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
Use \\[toggle-read-only] to permit editing."
|
2007-07-01 01:57:31 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(find-file-read-args "Find file read-only: "
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(confirm-nonexistent-file-or-buffer)))
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(unless (or (and wildcards find-file-wildcards
|
|
|
|
|
(not (string-match "\\`/:" filename))
|
|
|
|
|
(string-match "[[*?]" filename))
|
|
|
|
|
(file-exists-p filename))
|
|
|
|
|
(error "%s does not exist" filename))
|
|
|
|
|
(let ((value (find-file filename wildcards)))
|
|
|
|
|
(mapc (lambda (b) (with-current-buffer b (toggle-read-only 1)))
|
|
|
|
|
(if (listp value) value (list value)))
|
|
|
|
|
value))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
(defun find-file-read-only-other-window (filename &optional wildcards)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Edit file FILENAME in another window but don't allow changes.
|
2007-09-13 08:30:45 +00:00
|
|
|
|
Like \\[find-file-other-window], but marks buffer as read-only.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
Use \\[toggle-read-only] to permit editing."
|
2007-07-01 01:57:31 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(find-file-read-args "Find file read-only other window: "
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(confirm-nonexistent-file-or-buffer)))
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(unless (or (and wildcards find-file-wildcards
|
|
|
|
|
(not (string-match "\\`/:" filename))
|
|
|
|
|
(string-match "[[*?]" filename))
|
|
|
|
|
(file-exists-p filename))
|
|
|
|
|
(error "%s does not exist" filename))
|
|
|
|
|
(let ((value (find-file-other-window filename wildcards)))
|
|
|
|
|
(mapc (lambda (b) (with-current-buffer b (toggle-read-only 1)))
|
|
|
|
|
(if (listp value) value (list value)))
|
|
|
|
|
value))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
(defun find-file-read-only-other-frame (filename &optional wildcards)
|
1992-07-15 02:24:58 +00:00
|
|
|
|
"Edit file FILENAME in another frame but don't allow changes.
|
2007-09-13 08:30:45 +00:00
|
|
|
|
Like \\[find-file-other-frame], but marks buffer as read-only.
|
1991-10-31 08:30:58 +00:00
|
|
|
|
Use \\[toggle-read-only] to permit editing."
|
2007-07-01 01:57:31 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(find-file-read-args "Find file read-only other frame: "
|
2008-11-24 19:13:58 +00:00
|
|
|
|
(confirm-nonexistent-file-or-buffer)))
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(unless (or (and wildcards find-file-wildcards
|
|
|
|
|
(not (string-match "\\`/:" filename))
|
|
|
|
|
(string-match "[[*?]" filename))
|
|
|
|
|
(file-exists-p filename))
|
|
|
|
|
(error "%s does not exist" filename))
|
|
|
|
|
(let ((value (find-file-other-frame filename wildcards)))
|
|
|
|
|
(mapc (lambda (b) (with-current-buffer b (toggle-read-only 1)))
|
|
|
|
|
(if (listp value) value (list value)))
|
|
|
|
|
value))
|
|
|
|
|
|
|
|
|
|
(defun find-alternate-file-other-window (filename &optional wildcards)
|
1995-10-11 15:39:13 +00:00
|
|
|
|
"Find file FILENAME as a replacement for the file in the next window.
|
2004-12-13 05:08:00 +00:00
|
|
|
|
This command does not select that window.
|
|
|
|
|
|
2007-09-13 08:30:45 +00:00
|
|
|
|
See \\[find-file] for the possible forms of the FILENAME argument.
|
|
|
|
|
|
2004-12-13 05:08:00 +00:00
|
|
|
|
Interactively, or if WILDCARDS is non-nil in a call from Lisp,
|
|
|
|
|
expand wildcards (if any) and replace the file with multiple files."
|
1995-10-11 15:39:13 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(save-selected-window
|
|
|
|
|
(other-window 1)
|
|
|
|
|
(let ((file buffer-file-name)
|
|
|
|
|
(file-name nil)
|
|
|
|
|
(file-dir nil))
|
|
|
|
|
(and file
|
|
|
|
|
(setq file-name (file-name-nondirectory file)
|
|
|
|
|
file-dir (file-name-directory file)))
|
|
|
|
|
(list (read-file-name
|
2009-07-05 22:15:34 +00:00
|
|
|
|
"Find alternate file: " file-dir nil
|
|
|
|
|
(confirm-nonexistent-file-or-buffer) file-name)
|
2004-12-13 05:08:00 +00:00
|
|
|
|
t))))
|
1995-10-11 15:39:13 +00:00
|
|
|
|
(if (one-window-p)
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(find-file-other-window filename wildcards)
|
1995-10-11 15:39:13 +00:00
|
|
|
|
(save-selected-window
|
|
|
|
|
(other-window 1)
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(find-alternate-file filename wildcards))))
|
1995-10-11 15:39:13 +00:00
|
|
|
|
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(defun find-alternate-file (filename &optional wildcards)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Find file FILENAME, select its buffer, kill previous buffer.
|
|
|
|
|
If the current buffer now contains an empty file that you just visited
|
2004-12-13 05:08:00 +00:00
|
|
|
|
\(presumably by mistake), use this command to visit the file you really want.
|
|
|
|
|
|
2007-09-13 08:30:45 +00:00
|
|
|
|
See \\[find-file] for the possible forms of the FILENAME argument.
|
|
|
|
|
|
2004-12-13 05:08:00 +00:00
|
|
|
|
Interactively, or if WILDCARDS is non-nil in a call from Lisp,
|
2006-07-06 13:55:49 +00:00
|
|
|
|
expand wildcards (if any) and replace the file with multiple files.
|
|
|
|
|
|
|
|
|
|
If the current buffer is an indirect buffer, or the base buffer
|
|
|
|
|
for one or more indirect buffers, the other buffer(s) are not
|
|
|
|
|
killed."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(let ((file buffer-file-name)
|
|
|
|
|
(file-name nil)
|
|
|
|
|
(file-dir nil))
|
|
|
|
|
(and file
|
|
|
|
|
(setq file-name (file-name-nondirectory file)
|
|
|
|
|
file-dir (file-name-directory file)))
|
1992-08-06 02:56:35 +00:00
|
|
|
|
(list (read-file-name
|
2009-07-05 22:15:34 +00:00
|
|
|
|
"Find alternate file: " file-dir nil
|
|
|
|
|
(confirm-nonexistent-file-or-buffer) file-name)
|
2004-12-13 05:08:00 +00:00
|
|
|
|
t)))
|
2002-07-14 15:30:54 +00:00
|
|
|
|
(unless (run-hook-with-args-until-failure 'kill-buffer-query-functions)
|
|
|
|
|
(error "Aborted"))
|
2009-09-05 15:16:49 +00:00
|
|
|
|
(when (and (buffer-modified-p) buffer-file-name)
|
|
|
|
|
(if (yes-or-no-p (format "Buffer %s is modified; save it first? "
|
|
|
|
|
(buffer-name)))
|
|
|
|
|
(save-buffer)
|
|
|
|
|
(unless (yes-or-no-p "Kill and replace the buffer without saving it? ")
|
|
|
|
|
(error "Aborted"))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(let ((obuf (current-buffer))
|
|
|
|
|
(ofile buffer-file-name)
|
1993-05-28 01:22:00 +00:00
|
|
|
|
(onum buffer-file-number)
|
2003-02-13 19:38:19 +00:00
|
|
|
|
(odir dired-directory)
|
1993-05-28 01:22:00 +00:00
|
|
|
|
(otrue buffer-file-truename)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(oname (buffer-name)))
|
2009-09-05 16:25:27 +00:00
|
|
|
|
;; Run `kill-buffer-hook' here. It needs to happen before
|
|
|
|
|
;; variables like `buffer-file-name' etc are set to nil below,
|
|
|
|
|
;; because some of the hooks that could be invoked
|
|
|
|
|
;; (e.g., `save-place-to-alist') depend on those variables.
|
|
|
|
|
;;
|
|
|
|
|
;; Note that `kill-buffer-hook' is not what queries whether to
|
|
|
|
|
;; save a modified buffer visiting a file. Rather, `kill-buffer'
|
|
|
|
|
;; asks that itself. Thus, there's no need to temporarily do
|
|
|
|
|
;; `(set-buffer-modified-p nil)' before running this hook.
|
|
|
|
|
(run-hooks 'kill-buffer-hook)
|
|
|
|
|
;; Okay, now we can end-of-life the old buffer.
|
1995-09-17 14:12:02 +00:00
|
|
|
|
(if (get-buffer " **lose**")
|
|
|
|
|
(kill-buffer " **lose**"))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(rename-buffer " **lose**")
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
(unlock-buffer)
|
2003-02-04 10:40:14 +00:00
|
|
|
|
;; This prevents us from finding the same buffer
|
|
|
|
|
;; if we specified the same file again.
|
1996-06-12 14:43:51 +00:00
|
|
|
|
(setq buffer-file-name nil)
|
|
|
|
|
(setq buffer-file-number nil)
|
|
|
|
|
(setq buffer-file-truename nil)
|
2003-02-04 10:40:14 +00:00
|
|
|
|
;; Likewise for dired buffers.
|
|
|
|
|
(setq dired-directory nil)
|
2004-12-13 05:08:00 +00:00
|
|
|
|
(find-file filename wildcards))
|
2002-07-14 15:30:54 +00:00
|
|
|
|
(when (eq obuf (current-buffer))
|
|
|
|
|
;; This executes if find-file gets an error
|
|
|
|
|
;; and does not really find anything.
|
|
|
|
|
;; We put things back as they were.
|
|
|
|
|
;; If find-file actually finds something, we kill obuf below.
|
|
|
|
|
(setq buffer-file-name ofile)
|
|
|
|
|
(setq buffer-file-number onum)
|
|
|
|
|
(setq buffer-file-truename otrue)
|
2003-02-04 10:40:14 +00:00
|
|
|
|
(setq dired-directory odir)
|
2002-07-14 15:30:54 +00:00
|
|
|
|
(lock-buffer)
|
|
|
|
|
(rename-buffer oname)))
|
|
|
|
|
(unless (eq (current-buffer) obuf)
|
2002-08-27 20:38:30 +00:00
|
|
|
|
(with-current-buffer obuf
|
2009-09-05 16:25:27 +00:00
|
|
|
|
;; We already ran these; don't run them again.
|
|
|
|
|
(let (kill-buffer-query-functions kill-buffer-hook)
|
2002-08-27 20:38:30 +00:00
|
|
|
|
(kill-buffer obuf))))))
|
1997-08-11 22:32:01 +00:00
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun create-file-buffer (filename)
|
|
|
|
|
"Create a suitably named buffer for visiting FILENAME, and return it.
|
|
|
|
|
FILENAME (sans directory) is used unchanged if that name is free;
|
2007-08-31 13:30:02 +00:00
|
|
|
|
otherwise a string <2> or <3> or ... is appended to get an unused name.
|
|
|
|
|
Spaces at the start of FILENAME (sans directory) are removed."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(let ((lastname (file-name-nondirectory filename)))
|
|
|
|
|
(if (string= lastname "")
|
|
|
|
|
(setq lastname filename))
|
2007-08-31 13:30:02 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(string-match "^ *\\(.*\\)" lastname)
|
|
|
|
|
(generate-new-buffer (match-string 1 lastname)))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1991-10-31 08:30:58 +00:00
|
|
|
|
(defun generate-new-buffer (name)
|
|
|
|
|
"Create and return a buffer with a name based on NAME.
|
1992-10-21 04:52:59 +00:00
|
|
|
|
Choose the buffer's name using `generate-new-buffer-name'."
|
1991-10-31 08:30:58 +00:00
|
|
|
|
(get-buffer-create (generate-new-buffer-name name)))
|
|
|
|
|
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(defcustom automount-dir-prefix (purecopy "^/tmp_mnt/")
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Regexp to match the automounter prefix in a directory name."
|
|
|
|
|
:group 'files
|
|
|
|
|
:type 'regexp)
|
1992-07-17 22:17:57 +00:00
|
|
|
|
|
1992-12-26 08:46:31 +00:00
|
|
|
|
(defvar abbreviated-home-dir nil
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"The user's homedir abbreviated according to `directory-abbrev-alist'.")
|
1992-12-26 08:46:31 +00:00
|
|
|
|
|
1991-10-31 08:30:58 +00:00
|
|
|
|
(defun abbreviate-file-name (filename)
|
1992-10-21 04:52:59 +00:00
|
|
|
|
"Return a version of FILENAME shortened using `directory-abbrev-alist'.
|
2007-01-06 21:51:04 +00:00
|
|
|
|
This also substitutes \"~\" for the user's home directory (unless the
|
|
|
|
|
home directory is a root directory) and removes automounter prefixes
|
|
|
|
|
\(see the variable `automount-dir-prefix')."
|
1992-07-17 22:17:57 +00:00
|
|
|
|
;; Get rid of the prefixes added by the automounter.
|
2006-07-05 17:13:28 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(if (and automount-dir-prefix
|
|
|
|
|
(string-match automount-dir-prefix filename)
|
|
|
|
|
(file-exists-p (file-name-directory
|
|
|
|
|
(substring filename (1- (match-end 0))))))
|
|
|
|
|
(setq filename (substring filename (1- (match-end 0)))))
|
2008-07-31 21:09:05 +00:00
|
|
|
|
;; Avoid treating /home/foo as /home/Foo during `~' substitution.
|
|
|
|
|
;; To fix this right, we need a `file-name-case-sensitive-p'
|
|
|
|
|
;; function, but we don't have that yet, so just guess.
|
2008-09-29 05:39:39 +00:00
|
|
|
|
(let ((case-fold-search
|
2008-07-31 21:09:05 +00:00
|
|
|
|
(memq system-type '(ms-dos windows-nt darwin cygwin))))
|
2006-07-05 17:13:28 +00:00
|
|
|
|
;; If any elt of directory-abbrev-alist matches this name,
|
|
|
|
|
;; abbreviate accordingly.
|
2008-07-31 21:09:05 +00:00
|
|
|
|
(dolist (dir-abbrev directory-abbrev-alist)
|
|
|
|
|
(if (string-match (car dir-abbrev) filename)
|
2006-07-05 17:13:28 +00:00
|
|
|
|
(setq filename
|
2008-07-31 21:09:05 +00:00
|
|
|
|
(concat (cdr dir-abbrev)
|
|
|
|
|
(substring filename (match-end 0))))))
|
2006-07-05 17:13:28 +00:00
|
|
|
|
;; 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.
|
|
|
|
|
;; We include a slash at the end, to avoid spurious matches
|
|
|
|
|
;; such as `/usr/foobar' when the home dir is `/usr/foo'.
|
|
|
|
|
(or abbreviated-home-dir
|
|
|
|
|
(setq abbreviated-home-dir
|
|
|
|
|
(let ((abbreviated-home-dir "$foo"))
|
2009-10-21 20:03:57 +00:00
|
|
|
|
(concat "\\`" (abbreviate-file-name (expand-file-name "~"))
|
2006-09-06 16:32:18 +00:00
|
|
|
|
"\\(/\\|\\'\\)"))))
|
2006-07-05 17:13:28 +00:00
|
|
|
|
|
|
|
|
|
;; If FILENAME starts with the abbreviated homedir,
|
|
|
|
|
;; make it start with `~' instead.
|
|
|
|
|
(if (and (string-match abbreviated-home-dir filename)
|
|
|
|
|
;; 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:'.
|
2009-10-21 20:03:57 +00:00
|
|
|
|
(not (and (memq system-type '(ms-dos windows-nt cygwin))
|
2006-07-05 17:13:28 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(string-match "^[a-zA-`]:/$" filename)))))
|
1991-10-31 08:30:58 +00:00
|
|
|
|
(setq filename
|
2006-07-05 17:13:28 +00:00
|
|
|
|
(concat "~"
|
|
|
|
|
(match-string 1 filename)
|
|
|
|
|
(substring filename (match-end 0)))))
|
|
|
|
|
filename)))
|
1991-10-31 08:30:58 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom find-file-not-true-dirname-list nil
|
2008-07-31 05:33:56 +00:00
|
|
|
|
"List of logical names for which visiting shouldn't save the true dirname."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type '(repeat (string :tag "Name"))
|
|
|
|
|
:group 'find-file)
|
1993-05-02 12:46:26 +00:00
|
|
|
|
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(defun find-buffer-visiting (filename &optional predicate)
|
1994-03-09 00:23:30 +00:00
|
|
|
|
"Return the buffer visiting file FILENAME (a string).
|
|
|
|
|
This is like `get-file-buffer', except that it checks for any buffer
|
|
|
|
|
visiting the same file, possibly under a different name.
|
2004-12-27 17:18:28 +00:00
|
|
|
|
If PREDICATE is non-nil, only buffers satisfying it are eligible,
|
|
|
|
|
and others are ignored.
|
1994-03-09 00:23:30 +00:00
|
|
|
|
If there is no such live buffer, return nil."
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(let ((predicate (or predicate #'identity))
|
|
|
|
|
(truename (abbreviate-file-name (file-truename filename))))
|
|
|
|
|
(or (let ((buf (get-file-buffer filename)))
|
|
|
|
|
(when (and buf (funcall predicate buf)) buf))
|
|
|
|
|
(let ((list (buffer-list)) found)
|
|
|
|
|
(while (and (not found) list)
|
2009-10-21 20:03:57 +00:00
|
|
|
|
(with-current-buffer (car list)
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(if (and buffer-file-name
|
|
|
|
|
(string= buffer-file-truename truename)
|
|
|
|
|
(funcall predicate (current-buffer)))
|
|
|
|
|
(setq found (car list))))
|
|
|
|
|
(setq list (cdr list)))
|
|
|
|
|
found)
|
|
|
|
|
(let* ((attributes (file-attributes truename))
|
|
|
|
|
(number (nthcdr 10 attributes))
|
|
|
|
|
(list (buffer-list)) found)
|
|
|
|
|
(and buffer-file-numbers-unique
|
2006-09-20 17:35:01 +00:00
|
|
|
|
(car-safe number) ;Make sure the inode is not just nil.
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(while (and (not found) list)
|
|
|
|
|
(with-current-buffer (car list)
|
|
|
|
|
(if (and buffer-file-name
|
|
|
|
|
(equal buffer-file-number number)
|
|
|
|
|
;; Verify this buffer's file number
|
|
|
|
|
;; still belongs to its file.
|
|
|
|
|
(file-exists-p buffer-file-name)
|
|
|
|
|
(equal (file-attributes buffer-file-truename)
|
|
|
|
|
attributes)
|
|
|
|
|
(funcall predicate (current-buffer)))
|
|
|
|
|
(setq found (car list))))
|
|
|
|
|
(setq list (cdr list))))
|
|
|
|
|
found))))
|
1997-08-11 22:32:01 +00:00
|
|
|
|
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(defcustom find-file-wildcards t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means file-visiting commands should handle wildcards.
|
1998-10-16 19:20:55 +00:00
|
|
|
|
For example, if you specify `*.c', that would visit all the files
|
|
|
|
|
whose names match the pattern."
|
|
|
|
|
:group 'files
|
2000-03-26 17:07:06 +00:00
|
|
|
|
:version "20.4"
|
1998-10-16 19:20:55 +00:00
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defcustom find-file-suppress-same-file-warnings nil
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means suppress warning messages for symlinked files.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
When nil, Emacs prints a warning when visiting a file that is already
|
|
|
|
|
visited, but with a different name. Setting this option to t
|
|
|
|
|
suppresses this warning."
|
|
|
|
|
:group 'files
|
|
|
|
|
:version "21.1"
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2003-04-17 21:15:04 +00:00
|
|
|
|
(defcustom large-file-warning-threshold 10000000
|
2003-05-31 07:59:33 +00:00
|
|
|
|
"Maximum size of file above which a confirmation is requested.
|
|
|
|
|
When nil, never request confirmation."
|
|
|
|
|
:group 'files
|
|
|
|
|
:group 'find-file
|
2005-02-09 15:50:47 +00:00
|
|
|
|
:version "22.1"
|
2003-05-31 07:59:33 +00:00
|
|
|
|
:type '(choice integer (const :tag "Never request confirmation" nil)))
|
2003-04-17 21:15:04 +00:00
|
|
|
|
|
2009-07-21 04:37:53 +00:00
|
|
|
|
(defun abort-if-file-too-large (size op-type filename)
|
2008-04-05 21:15:20 +00:00
|
|
|
|
"If file SIZE larger than `large-file-warning-threshold', allow user to abort.
|
2008-04-05 12:03:23 +00:00
|
|
|
|
OP-TYPE specifies the file operation being performed (for message to user)."
|
|
|
|
|
(when (and large-file-warning-threshold size
|
|
|
|
|
(> size large-file-warning-threshold)
|
|
|
|
|
(not (y-or-n-p
|
|
|
|
|
(format "File %s is large (%dMB), really %s? "
|
|
|
|
|
(file-name-nondirectory filename)
|
|
|
|
|
(/ size 1048576) op-type))))
|
|
|
|
|
(error "Aborted")))
|
|
|
|
|
|
1999-01-24 20:10:30 +00:00
|
|
|
|
(defun find-file-noselect (filename &optional nowarn rawfile wildcards)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Read file FILENAME into a buffer and return the buffer.
|
|
|
|
|
If a buffer exists visiting FILENAME, return that one, but
|
|
|
|
|
verify that the file has not changed since visited or saved.
|
1997-02-20 05:44:24 +00:00
|
|
|
|
The buffer is not selected, just returned to the caller.
|
2005-07-20 01:57:49 +00:00
|
|
|
|
Optional second arg NOWARN non-nil means suppress any warning messages.
|
|
|
|
|
Optional third arg RAWFILE non-nil means the file is read literally.
|
|
|
|
|
Optional fourth arg WILDCARDS non-nil means do wildcard processing
|
1999-01-24 20:12:25 +00:00
|
|
|
|
and visit all the matching files. When wildcards are actually
|
2004-12-13 05:08:00 +00:00
|
|
|
|
used and expanded, return a list of buffers that are visiting
|
|
|
|
|
the various files."
|
1992-07-17 22:17:57 +00:00
|
|
|
|
(setq filename
|
|
|
|
|
(abbreviate-file-name
|
|
|
|
|
(expand-file-name filename)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(if (file-directory-p filename)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(or (and find-file-run-dired
|
|
|
|
|
(run-hook-with-args-until-success
|
|
|
|
|
'find-directory-functions
|
|
|
|
|
(if find-file-visit-truename
|
|
|
|
|
(abbreviate-file-name (file-truename filename))
|
|
|
|
|
filename)))
|
|
|
|
|
(error "%s is a directory" filename))
|
1999-01-24 20:10:30 +00:00
|
|
|
|
(if (and wildcards
|
|
|
|
|
find-file-wildcards
|
1999-01-03 15:03:32 +00:00
|
|
|
|
(not (string-match "\\`/:" filename))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(string-match "[[*?]" filename))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(let ((files (condition-case nil
|
|
|
|
|
(file-expand-wildcards filename t)
|
|
|
|
|
(error (list filename))))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(find-file-wildcards nil))
|
1999-01-03 15:03:32 +00:00
|
|
|
|
(if (null files)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(find-file-noselect filename)
|
2000-10-31 16:55:23 +00:00
|
|
|
|
(mapcar #'find-file-noselect files)))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(let* ((buf (get-file-buffer filename))
|
|
|
|
|
(truename (abbreviate-file-name (file-truename filename)))
|
2003-04-17 21:15:04 +00:00
|
|
|
|
(attributes (file-attributes truename))
|
|
|
|
|
(number (nthcdr 10 attributes))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
;; Find any buffer for a file which has same truename.
|
|
|
|
|
(other (and (not buf) (find-buffer-visiting filename))))
|
|
|
|
|
;; Let user know if there is a buffer with the same truename.
|
|
|
|
|
(if other
|
|
|
|
|
(progn
|
|
|
|
|
(or nowarn
|
2000-10-04 17:16:59 +00:00
|
|
|
|
find-file-suppress-same-file-warnings
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(string-equal filename (buffer-file-name other))
|
|
|
|
|
(message "%s and %s are the same file"
|
|
|
|
|
filename (buffer-file-name other)))
|
|
|
|
|
;; Optionally also find that buffer.
|
|
|
|
|
(if (or find-file-existing-other-name find-file-visit-truename)
|
|
|
|
|
(setq buf other))))
|
2003-04-17 21:15:04 +00:00
|
|
|
|
;; Check to see if the file looks uncommonly large.
|
2008-04-05 12:03:23 +00:00
|
|
|
|
(when (not (or buf nowarn))
|
2009-07-21 04:37:53 +00:00
|
|
|
|
(abort-if-file-too-large (nth 7 attributes) "open" filename))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(if buf
|
|
|
|
|
;; We are using an existing buffer.
|
2007-03-05 18:46:36 +00:00
|
|
|
|
(let (nonexistent)
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(or nowarn
|
|
|
|
|
(verify-visited-file-modtime buf)
|
|
|
|
|
(cond ((not (file-exists-p filename))
|
2007-03-05 18:46:36 +00:00
|
|
|
|
(setq nonexistent t)
|
|
|
|
|
(message "File %s no longer exists!" filename))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
;; Certain files should be reverted automatically
|
|
|
|
|
;; if they have changed on disk and not in the buffer.
|
|
|
|
|
((and (not (buffer-modified-p buf))
|
|
|
|
|
(let ((tail revert-without-query)
|
|
|
|
|
(found nil))
|
|
|
|
|
(while tail
|
|
|
|
|
(if (string-match (car tail) filename)
|
|
|
|
|
(setq found t))
|
|
|
|
|
(setq tail (cdr tail)))
|
|
|
|
|
found))
|
|
|
|
|
(with-current-buffer buf
|
|
|
|
|
(message "Reverting file %s..." filename)
|
|
|
|
|
(revert-buffer t t)
|
|
|
|
|
(message "Reverting file %s...done" filename)))
|
|
|
|
|
((yes-or-no-p
|
|
|
|
|
(if (string= (file-name-nondirectory filename)
|
|
|
|
|
(buffer-name buf))
|
|
|
|
|
(format
|
|
|
|
|
(if (buffer-modified-p buf)
|
|
|
|
|
"File %s changed on disk. Discard your edits? "
|
|
|
|
|
"File %s changed on disk. Reread from disk? ")
|
|
|
|
|
(file-name-nondirectory filename))
|
1998-06-09 02:49:43 +00:00
|
|
|
|
(format
|
|
|
|
|
(if (buffer-modified-p buf)
|
1998-10-16 19:20:55 +00:00
|
|
|
|
"File %s changed on disk. Discard your edits in %s? "
|
|
|
|
|
"File %s changed on disk. Reread from disk into %s? ")
|
|
|
|
|
(file-name-nondirectory filename)
|
|
|
|
|
(buffer-name buf))))
|
|
|
|
|
(with-current-buffer buf
|
|
|
|
|
(revert-buffer t t)))))
|
|
|
|
|
(with-current-buffer buf
|
2001-10-05 12:10:57 +00:00
|
|
|
|
|
|
|
|
|
;; Check if a formerly read-only file has become
|
2001-11-01 19:33:52 +00:00
|
|
|
|
;; writable and vice versa, but if the buffer agrees
|
|
|
|
|
;; with the new state of the file, that is ok too.
|
2001-10-05 12:10:57 +00:00
|
|
|
|
(let ((read-only (not (file-writable-p buffer-file-name))))
|
2007-03-05 18:46:36 +00:00
|
|
|
|
(unless (or nonexistent
|
|
|
|
|
(eq read-only buffer-file-read-only)
|
2001-11-01 19:33:52 +00:00
|
|
|
|
(eq read-only buffer-read-only))
|
2001-10-05 12:10:57 +00:00
|
|
|
|
(when (or nowarn
|
2002-06-01 18:04:35 +00:00
|
|
|
|
(let ((question
|
2001-10-05 12:10:57 +00:00
|
|
|
|
(format "File %s is %s on disk. Change buffer mode? "
|
|
|
|
|
buffer-file-name
|
|
|
|
|
(if read-only "read-only" "writable"))))
|
|
|
|
|
(y-or-n-p question)))
|
2001-11-01 19:33:52 +00:00
|
|
|
|
(setq buffer-read-only read-only)))
|
|
|
|
|
(setq buffer-file-read-only read-only))
|
2001-10-05 12:10:57 +00:00
|
|
|
|
|
2002-01-12 13:28:48 +00:00
|
|
|
|
(when (and (not (eq (not (null rawfile))
|
|
|
|
|
(not (null find-file-literally))))
|
2007-03-05 18:46:36 +00:00
|
|
|
|
(not nonexistent)
|
2002-01-12 13:28:48 +00:00
|
|
|
|
;; It is confusing to ask whether to visit
|
|
|
|
|
;; non-literally if they have the file in
|
|
|
|
|
;; hexl-mode.
|
|
|
|
|
(not (eq major-mode 'hexl-mode)))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(if (buffer-modified-p)
|
2006-06-19 21:48:41 +00:00
|
|
|
|
(if (y-or-n-p
|
2006-11-13 10:24:55 +00:00
|
|
|
|
(format
|
2006-06-19 21:48:41 +00:00
|
|
|
|
(if rawfile
|
|
|
|
|
"The file %s is already visited normally,
|
|
|
|
|
and you have edited the buffer. Now you have asked to visit it literally,
|
|
|
|
|
meaning no coding system handling, format conversion, or local variables.
|
|
|
|
|
Emacs can only visit a file in one way at a time.
|
|
|
|
|
|
|
|
|
|
Do you want to save the file, and visit it literally instead? "
|
|
|
|
|
"The file %s is already visited literally,
|
|
|
|
|
meaning no coding system handling, format conversion, or local variables.
|
|
|
|
|
You have edited the buffer. Now you have asked to visit the file normally,
|
|
|
|
|
but Emacs can only visit a file in one way at a time.
|
|
|
|
|
|
|
|
|
|
Do you want to save the file, and visit it normally instead? ")
|
|
|
|
|
(file-name-nondirectory filename)))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(progn
|
|
|
|
|
(save-buffer)
|
|
|
|
|
(find-file-noselect-1 buf filename nowarn
|
|
|
|
|
rawfile truename number))
|
2006-06-19 21:48:41 +00:00
|
|
|
|
(if (y-or-n-p
|
2006-11-13 10:24:55 +00:00
|
|
|
|
(format
|
2006-06-19 21:48:41 +00:00
|
|
|
|
(if rawfile
|
|
|
|
|
"\
|
|
|
|
|
Do you want to discard your changes, and visit the file literally now? "
|
|
|
|
|
"\
|
|
|
|
|
Do you want to discard your changes, and visit the file normally now? ")))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(find-file-noselect-1 buf filename nowarn
|
|
|
|
|
rawfile truename number)
|
|
|
|
|
(error (if rawfile "File already visited non-literally"
|
|
|
|
|
"File already visited literally"))))
|
2006-11-13 10:24:55 +00:00
|
|
|
|
(if (y-or-n-p
|
|
|
|
|
(format
|
2006-06-19 21:48:41 +00:00
|
|
|
|
(if rawfile
|
|
|
|
|
"The file %s is already visited normally.
|
|
|
|
|
You have asked to visit it literally,
|
|
|
|
|
meaning no coding system decoding, format conversion, or local variables.
|
|
|
|
|
But Emacs can only visit a file in one way at a time.
|
|
|
|
|
|
|
|
|
|
Do you want to revisit the file literally now? "
|
|
|
|
|
"The file %s is already visited literally,
|
|
|
|
|
meaning no coding system decoding, format conversion, or local variables.
|
|
|
|
|
You have asked to visit it normally,
|
|
|
|
|
but Emacs can only visit a file in one way at a time.
|
|
|
|
|
|
|
|
|
|
Do you want to revisit the file normally now? ")
|
|
|
|
|
(file-name-nondirectory filename)))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(find-file-noselect-1 buf filename nowarn
|
|
|
|
|
rawfile truename number)
|
|
|
|
|
(error (if rawfile "File already visited non-literally"
|
|
|
|
|
"File already visited literally"))))))
|
|
|
|
|
;; Return the buffer we are using.
|
|
|
|
|
buf)
|
|
|
|
|
;; Create a new buffer.
|
|
|
|
|
(setq buf (create-file-buffer filename))
|
|
|
|
|
;; find-file-noselect-1 may use a different buffer.
|
|
|
|
|
(find-file-noselect-1 buf filename nowarn
|
|
|
|
|
rawfile truename number))))))
|
1998-06-09 02:49:43 +00:00
|
|
|
|
|
|
|
|
|
(defun find-file-noselect-1 (buf filename nowarn rawfile truename number)
|
2004-05-20 23:32:27 +00:00
|
|
|
|
(let (error)
|
1998-06-09 02:49:43 +00:00
|
|
|
|
(with-current-buffer buf
|
|
|
|
|
(kill-local-variable 'find-file-literally)
|
1998-06-23 15:49:54 +00:00
|
|
|
|
;; Needed in case we are re-visiting the file with a different
|
|
|
|
|
;; text representation.
|
1998-07-12 03:14:44 +00:00
|
|
|
|
(kill-local-variable 'buffer-file-coding-system)
|
2002-12-28 21:23:58 +00:00
|
|
|
|
(kill-local-variable 'cursor-type)
|
2004-05-20 23:32:27 +00:00
|
|
|
|
(let ((inhibit-read-only t))
|
2004-05-29 01:54:11 +00:00
|
|
|
|
(erase-buffer))
|
|
|
|
|
(and (default-value 'enable-multibyte-characters)
|
|
|
|
|
(not rawfile)
|
|
|
|
|
(set-buffer-multibyte t))
|
|
|
|
|
(if rawfile
|
2004-05-25 18:51:07 +00:00
|
|
|
|
(condition-case ()
|
2004-05-29 01:54:11 +00:00
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(insert-file-contents-literally filename t))
|
2004-05-25 18:51:07 +00:00
|
|
|
|
(file-error
|
|
|
|
|
(when (and (file-exists-p filename)
|
|
|
|
|
(not (file-readable-p filename)))
|
|
|
|
|
(kill-buffer buf)
|
|
|
|
|
(signal 'file-error (list "File is not readable"
|
|
|
|
|
filename)))
|
2004-05-29 01:54:11 +00:00
|
|
|
|
;; Unconditionally set error
|
|
|
|
|
(setq error t)))
|
|
|
|
|
(condition-case ()
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(insert-file-contents filename t))
|
|
|
|
|
(file-error
|
|
|
|
|
(when (and (file-exists-p filename)
|
|
|
|
|
(not (file-readable-p filename)))
|
|
|
|
|
(kill-buffer buf)
|
|
|
|
|
(signal 'file-error (list "File is not readable"
|
|
|
|
|
filename)))
|
2006-06-23 10:38:24 +00:00
|
|
|
|
;; Run find-file-not-found-functions until one returns non-nil.
|
2004-05-29 01:54:11 +00:00
|
|
|
|
(or (run-hook-with-args-until-success 'find-file-not-found-functions)
|
|
|
|
|
;; If they fail too, set error.
|
|
|
|
|
(setq error t)))))
|
1999-04-29 20:28:43 +00:00
|
|
|
|
;; Record the file's truename, and maybe use that as visited name.
|
|
|
|
|
(if (equal filename buffer-file-name)
|
|
|
|
|
(setq buffer-file-truename truename)
|
1999-05-14 09:46:38 +00:00
|
|
|
|
(setq buffer-file-truename
|
|
|
|
|
(abbreviate-file-name (file-truename buffer-file-name))))
|
1998-06-09 02:49:43 +00:00
|
|
|
|
(setq buffer-file-number number)
|
|
|
|
|
(if find-file-visit-truename
|
2006-07-02 14:26:53 +00:00
|
|
|
|
(setq buffer-file-name (expand-file-name buffer-file-truename)))
|
1998-06-09 02:49:43 +00:00
|
|
|
|
;; Set buffer's default directory to that of the file.
|
1999-04-29 20:28:43 +00:00
|
|
|
|
(setq default-directory (file-name-directory buffer-file-name))
|
1998-06-09 02:49:43 +00:00
|
|
|
|
;; Turn off backup files for certain file names. Since
|
|
|
|
|
;; this is a permanent local, the major mode won't eliminate it.
|
2007-01-04 22:14:32 +00:00
|
|
|
|
(and backup-enable-predicate
|
|
|
|
|
(not (funcall backup-enable-predicate buffer-file-name))
|
1998-06-09 02:49:43 +00:00
|
|
|
|
(progn
|
|
|
|
|
(make-local-variable 'backup-inhibited)
|
|
|
|
|
(setq backup-inhibited t)))
|
2002-06-08 18:28:06 +00:00
|
|
|
|
(if rawfile
|
|
|
|
|
(progn
|
|
|
|
|
(set-buffer-multibyte nil)
|
|
|
|
|
(setq buffer-file-coding-system 'no-conversion)
|
2005-08-09 13:35:12 +00:00
|
|
|
|
(set-buffer-major-mode buf)
|
2002-06-08 18:28:06 +00:00
|
|
|
|
(make-local-variable 'find-file-literally)
|
|
|
|
|
(setq find-file-literally t))
|
|
|
|
|
(after-find-file error (not nowarn)))
|
|
|
|
|
(current-buffer))))
|
1997-08-11 22:32:01 +00:00
|
|
|
|
|
|
|
|
|
(defun insert-file-contents-literally (filename &optional visit beg end replace)
|
|
|
|
|
"Like `insert-file-contents', but only reads in the file literally.
|
|
|
|
|
A buffer may be modified in several ways after reading into the buffer,
|
|
|
|
|
to Emacs features such as format decoding, character code
|
2002-06-23 21:16:38 +00:00
|
|
|
|
conversion, `find-file-hook', automatic uncompression, etc.
|
1997-08-11 22:32:01 +00:00
|
|
|
|
|
|
|
|
|
This function ensures that none of these modifications will take place."
|
|
|
|
|
(let ((format-alist nil)
|
|
|
|
|
(after-insert-file-functions nil)
|
|
|
|
|
(coding-system-for-read 'no-conversion)
|
|
|
|
|
(coding-system-for-write 'no-conversion)
|
|
|
|
|
(find-buffer-file-type-function
|
2003-05-07 21:58:24 +00:00
|
|
|
|
(if (fboundp 'find-buffer-file-type)
|
|
|
|
|
(symbol-function 'find-buffer-file-type)
|
|
|
|
|
nil))
|
|
|
|
|
(inhibit-file-name-handlers
|
2008-04-27 19:49:15 +00:00
|
|
|
|
(append '(jka-compr-handler image-file-handler epa-file-handler)
|
2003-05-07 21:58:24 +00:00
|
|
|
|
inhibit-file-name-handlers))
|
|
|
|
|
(inhibit-file-name-operation 'insert-file-contents))
|
1997-08-11 22:32:01 +00:00
|
|
|
|
(unwind-protect
|
2003-05-07 21:58:24 +00:00
|
|
|
|
(progn
|
|
|
|
|
(fset 'find-buffer-file-type (lambda (filename) t))
|
|
|
|
|
(insert-file-contents filename visit beg end replace))
|
1997-08-11 22:32:01 +00:00
|
|
|
|
(if find-buffer-file-type-function
|
|
|
|
|
(fset 'find-buffer-file-type find-buffer-file-type-function)
|
|
|
|
|
(fmakunbound 'find-buffer-file-type)))))
|
|
|
|
|
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(defun insert-file-1 (filename insert-func)
|
|
|
|
|
(if (file-directory-p filename)
|
|
|
|
|
(signal 'file-error (list "Opening input file" "file is a directory"
|
|
|
|
|
filename)))
|
2008-04-05 12:03:23 +00:00
|
|
|
|
;; Check whether the file is uncommonly large
|
2009-07-21 04:37:53 +00:00
|
|
|
|
(abort-if-file-too-large (nth 7 (file-attributes filename)) "insert" filename)
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(let* ((buffer (find-buffer-visiting (abbreviate-file-name (file-truename filename))
|
|
|
|
|
#'buffer-modified-p))
|
|
|
|
|
(tem (funcall insert-func filename)))
|
|
|
|
|
(push-mark (+ (point) (car (cdr tem))))
|
|
|
|
|
(when buffer
|
|
|
|
|
(message "File %s already visited and modified in buffer %s"
|
|
|
|
|
filename (buffer-name buffer)))))
|
|
|
|
|
|
1997-08-11 22:32:01 +00:00
|
|
|
|
(defun insert-file-literally (filename)
|
|
|
|
|
"Insert contents of file FILENAME into buffer after point with no conversion.
|
|
|
|
|
|
|
|
|
|
This function is meant for the user to run interactively.
|
|
|
|
|
Don't call it from programs! Use `insert-file-contents-literally' instead.
|
|
|
|
|
\(Its calling sequence is different; see its documentation)."
|
|
|
|
|
(interactive "*fInsert file literally: ")
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(insert-file-1 filename #'insert-file-contents-literally))
|
1997-08-11 22:32:01 +00:00
|
|
|
|
|
|
|
|
|
(defvar find-file-literally nil
|
|
|
|
|
"Non-nil if this buffer was made by `find-file-literally' or equivalent.
|
|
|
|
|
This is a permanent local.")
|
|
|
|
|
(put 'find-file-literally 'permanent-local t)
|
1997-07-08 09:57:37 +00:00
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defun find-file-literally (filename)
|
1997-07-08 09:57:37 +00:00
|
|
|
|
"Visit file FILENAME with no conversion of any kind.
|
|
|
|
|
Format conversion and character code conversion are both disabled,
|
|
|
|
|
and multibyte characters are disabled in the resulting buffer.
|
1997-08-04 03:07:28 +00:00
|
|
|
|
The major mode used is Fundamental mode regardless of the file name,
|
|
|
|
|
and local variable specifications in the file are ignored.
|
2000-11-16 17:04:27 +00:00
|
|
|
|
Automatic uncompression and adding a newline at the end of the
|
|
|
|
|
file due to `require-final-newline' is also disabled.
|
1997-08-11 22:32:01 +00:00
|
|
|
|
|
|
|
|
|
You cannot absolutely rely on this function to result in
|
1997-08-27 17:25:46 +00:00
|
|
|
|
visiting the file literally. If Emacs already has a buffer
|
1997-08-11 22:32:01 +00:00
|
|
|
|
which is visiting the file, you get the existing buffer,
|
|
|
|
|
regardless of whether it was created literally or not.
|
|
|
|
|
|
|
|
|
|
In a Lisp program, if you want to be sure of accessing a file's
|
|
|
|
|
contents literally, you should create a temporary buffer and then read
|
|
|
|
|
the file contents into it using `insert-file-contents-literally'."
|
2009-11-25 17:11:29 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(list (read-file-name
|
|
|
|
|
"Find file literally: " nil default-directory
|
|
|
|
|
(confirm-nonexistent-file-or-buffer))))
|
1997-08-11 22:32:01 +00:00
|
|
|
|
(switch-to-buffer (find-file-noselect filename nil t)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1994-08-28 07:37:42 +00:00
|
|
|
|
(defvar after-find-file-from-revert-buffer nil)
|
|
|
|
|
|
1994-08-17 21:46:05 +00:00
|
|
|
|
(defun after-find-file (&optional error warn noauto
|
1995-12-25 21:05:31 +00:00
|
|
|
|
after-find-file-from-revert-buffer
|
|
|
|
|
nomodes)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Called after finding a file and by the default revert function.
|
|
|
|
|
Sets buffer mode, parses local variables.
|
1992-09-24 07:23:59 +00:00
|
|
|
|
Optional args ERROR, WARN, and NOAUTO: ERROR non-nil means there was an
|
1991-07-19 14:42:53 +00:00
|
|
|
|
error in reading the file. WARN non-nil means warn if there
|
|
|
|
|
exists an auto-save file more recent than the visited file.
|
1992-09-24 07:23:59 +00:00
|
|
|
|
NOAUTO means don't mess with auto-save mode.
|
1994-08-17 21:46:05 +00:00
|
|
|
|
Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER non-nil
|
|
|
|
|
means this call was from `revert-buffer'.
|
1995-12-25 21:05:31 +00:00
|
|
|
|
Fifth arg NOMODES non-nil means don't alter the file's modes.
|
2002-06-23 21:16:38 +00:00
|
|
|
|
Finishes by calling the functions in `find-file-hook'
|
1995-12-25 21:05:31 +00:00
|
|
|
|
unless NOMODES is non-nil."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(setq buffer-read-only (not (file-writable-p buffer-file-name)))
|
|
|
|
|
(if noninteractive
|
|
|
|
|
nil
|
|
|
|
|
(let* (not-serious
|
|
|
|
|
(msg
|
2000-10-24 15:18:19 +00:00
|
|
|
|
(cond
|
|
|
|
|
((not warn) nil)
|
|
|
|
|
((and error (file-attributes buffer-file-name))
|
|
|
|
|
(setq buffer-read-only t)
|
|
|
|
|
"File exists, but cannot be read")
|
|
|
|
|
((not buffer-read-only)
|
|
|
|
|
(if (and warn
|
|
|
|
|
;; No need to warn if buffer is auto-saved
|
|
|
|
|
;; under the name of the visited file.
|
|
|
|
|
(not (and buffer-file-name
|
|
|
|
|
auto-save-visited-file-name))
|
|
|
|
|
(file-newer-than-file-p (or buffer-auto-save-file-name
|
|
|
|
|
(make-auto-save-file-name))
|
|
|
|
|
buffer-file-name))
|
2002-08-15 20:08:24 +00:00
|
|
|
|
(format "%s has auto save data; consider M-x recover-this-file"
|
2000-10-24 15:18:19 +00:00
|
|
|
|
(file-name-nondirectory buffer-file-name))
|
|
|
|
|
(setq not-serious t)
|
|
|
|
|
(if error "(New file)" nil)))
|
|
|
|
|
((not error)
|
|
|
|
|
(setq not-serious t)
|
|
|
|
|
"Note: file is write protected")
|
|
|
|
|
((file-attributes (directory-file-name default-directory))
|
|
|
|
|
"File not found and directory write-protected")
|
|
|
|
|
((file-exists-p (file-name-directory buffer-file-name))
|
|
|
|
|
(setq buffer-read-only nil))
|
|
|
|
|
(t
|
|
|
|
|
(setq buffer-read-only nil)
|
2003-06-03 11:08:25 +00:00
|
|
|
|
"Use M-x make-directory RET RET to create the directory and its parents"))))
|
2000-10-24 15:18:19 +00:00
|
|
|
|
(when msg
|
2002-04-23 03:45:45 +00:00
|
|
|
|
(message "%s" msg)
|
2003-06-03 23:23:06 +00:00
|
|
|
|
(or not-serious (sit-for 1 t))))
|
2000-10-24 15:18:19 +00:00
|
|
|
|
(when (and auto-save-default (not noauto))
|
|
|
|
|
(auto-save-mode t)))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
;; Make people do a little extra work (C-x C-q)
|
|
|
|
|
;; before altering a backup file.
|
2000-10-24 15:18:19 +00:00
|
|
|
|
(when (backup-file-name-p buffer-file-name)
|
|
|
|
|
(setq buffer-read-only t))
|
2002-07-07 09:21:52 +00:00
|
|
|
|
;; When a file is marked read-only,
|
|
|
|
|
;; make the buffer read-only even if root is looking at it.
|
2002-07-07 23:15:04 +00:00
|
|
|
|
(when (and (file-modes (buffer-file-name))
|
|
|
|
|
(zerop (logand (file-modes (buffer-file-name)) #o222)))
|
2002-07-07 09:21:52 +00:00
|
|
|
|
(setq buffer-read-only t))
|
2000-10-24 15:18:19 +00:00
|
|
|
|
(unless nomodes
|
|
|
|
|
(when (and view-read-only view-mode)
|
|
|
|
|
(view-mode-disable))
|
1995-12-25 21:05:31 +00:00
|
|
|
|
(normal-mode t)
|
2004-12-31 14:48:12 +00:00
|
|
|
|
;; If requested, add a newline at the end of the file.
|
|
|
|
|
(and (memq require-final-newline '(visit visit-save))
|
|
|
|
|
(> (point-max) (point-min))
|
|
|
|
|
(/= (char-after (1- (point-max))) ?\n)
|
|
|
|
|
(not (and (eq selective-display t)
|
|
|
|
|
(= (char-after (1- (point-max))) ?\r)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(insert "\n")))
|
2000-10-24 15:18:19 +00:00
|
|
|
|
(when (and buffer-read-only
|
|
|
|
|
view-read-only
|
|
|
|
|
(not (eq (get major-mode 'mode-class) 'special)))
|
|
|
|
|
(view-mode-enter))
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(run-hooks 'find-file-hook)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2003-04-17 21:15:04 +00:00
|
|
|
|
(defmacro report-errors (format &rest body)
|
|
|
|
|
"Eval BODY and turn any error into a FORMAT message.
|
|
|
|
|
FORMAT can have a %s escape which will be replaced with the actual error.
|
|
|
|
|
If `debug-on-error' is set, errors are not caught, so that you can
|
|
|
|
|
debug them.
|
|
|
|
|
Avoid using a large BODY since it is duplicated."
|
|
|
|
|
(declare (debug t) (indent 1))
|
|
|
|
|
`(if debug-on-error
|
|
|
|
|
(progn . ,body)
|
|
|
|
|
(condition-case err
|
|
|
|
|
(progn . ,body)
|
|
|
|
|
(error (message ,format (prin1-to-string err))))))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun normal-mode (&optional find-file)
|
|
|
|
|
"Choose the major mode for this buffer automatically.
|
|
|
|
|
Also sets up any specified local variables of the file.
|
|
|
|
|
Uses the visited file name, the -*- line, and the local variables spec.
|
|
|
|
|
|
|
|
|
|
This function is called automatically from `find-file'. In that case,
|
1998-11-07 02:01:59 +00:00
|
|
|
|
we may set up the file-specified mode and local variables,
|
2006-04-11 17:57:34 +00:00
|
|
|
|
depending on the value of `enable-local-variables'.
|
1998-11-07 02:01:59 +00:00
|
|
|
|
In addition, if `local-enable-local-variables' is nil, we do
|
|
|
|
|
not set local variables (though we do notice a mode specified with -*-.)
|
|
|
|
|
|
|
|
|
|
`enable-local-variables' is ignored if you run `normal-mode' interactively,
|
|
|
|
|
or from Lisp without specifying the optional argument FIND-FILE;
|
|
|
|
|
in that case, this function acts as if `enable-local-variables' were t."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive)
|
2009-08-28 17:02:53 +00:00
|
|
|
|
(funcall (or (default-value 'major-mode) 'fundamental-mode))
|
2005-05-12 23:09:33 +00:00
|
|
|
|
(let ((enable-local-variables (or (not find-file) enable-local-variables)))
|
|
|
|
|
(report-errors "File mode specification error: %s"
|
|
|
|
|
(set-auto-mode))
|
|
|
|
|
(report-errors "File local-variables error: %s"
|
2003-04-17 21:15:04 +00:00
|
|
|
|
(hack-local-variables)))
|
2005-08-20 21:50:48 +00:00
|
|
|
|
;; Turn font lock off and on, to make sure it takes account of
|
|
|
|
|
;; whatever file local variables are relevant to it.
|
2005-09-12 15:05:24 +00:00
|
|
|
|
(when (and font-lock-mode
|
|
|
|
|
;; Font-lock-mode (now in font-core.el) can be ON when
|
|
|
|
|
;; font-lock.el still hasn't been loaded.
|
|
|
|
|
(boundp 'font-lock-keywords)
|
|
|
|
|
(eq (car font-lock-keywords) t))
|
2005-08-20 21:50:48 +00:00
|
|
|
|
(setq font-lock-keywords (cadr font-lock-keywords))
|
|
|
|
|
(font-lock-mode 1))
|
|
|
|
|
|
2002-11-06 23:28:29 +00:00
|
|
|
|
(if (fboundp 'ucs-set-table-for-input) ; don't lose when building
|
|
|
|
|
(ucs-set-table-for-input)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2010-03-31 01:51:54 +00:00
|
|
|
|
(defcustom auto-mode-case-fold t
|
2006-12-31 00:29:49 +00:00
|
|
|
|
"Non-nil means to try second pass through `auto-mode-alist'.
|
|
|
|
|
This means that if the first case-sensitive search through the alist fails
|
|
|
|
|
to find a matching major mode, a second case-insensitive search is made.
|
|
|
|
|
On systems with case-insensitive file names, this variable is ignored,
|
2006-12-31 00:34:49 +00:00
|
|
|
|
since only a single case-insensitive search through the alist is made."
|
2006-12-31 00:29:49 +00:00
|
|
|
|
:group 'files
|
|
|
|
|
:version "22.1"
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
1995-11-29 21:18:05 +00:00
|
|
|
|
(defvar auto-mode-alist
|
2003-07-09 20:28:23 +00:00
|
|
|
|
;; Note: The entries for the modes defined in cc-mode.el (c-mode,
|
|
|
|
|
;; c++-mode, java-mode and more) are added through autoload
|
|
|
|
|
;; directives in that file. That way is discouraged since it
|
|
|
|
|
;; spreads out the definition of the initial value.
|
2007-08-08 14:06:02 +00:00
|
|
|
|
(mapcar
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(lambda (elt)
|
|
|
|
|
(cons (purecopy (car elt)) (cdr elt)))
|
2005-05-21 02:42:00 +00:00
|
|
|
|
`(;; do this first, so that .html.pl is Polish html, not Perl
|
2004-10-27 21:44:35 +00:00
|
|
|
|
("\\.s?html?\\(\\.[a-zA-Z_]+\\)?\\'" . html-mode)
|
|
|
|
|
("\\.te?xt\\'" . text-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.[tT]e[xX]\\'" . tex-mode)
|
2003-04-14 20:48:44 +00:00
|
|
|
|
("\\.ins\\'" . tex-mode) ;Installation files for TeX packages.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.ltx\\'" . latex-mode)
|
2003-04-14 20:48:44 +00:00
|
|
|
|
("\\.dtx\\'" . doctex-mode)
|
2007-11-10 17:20:37 +00:00
|
|
|
|
("\\.org\\'" . org-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.el\\'" . emacs-lisp-mode)
|
2009-10-03 19:28:05 +00:00
|
|
|
|
("Project\\.ede\\'" . emacs-lisp-mode)
|
2004-02-04 08:21:48 +00:00
|
|
|
|
("\\.\\(scm\\|stk\\|ss\\|sch\\)\\'" . scheme-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.l\\'" . lisp-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.li?sp\\'" . lisp-mode)
|
|
|
|
|
("\\.[fF]\\'" . fortran-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.for\\'" . fortran-mode)
|
|
|
|
|
("\\.p\\'" . pascal-mode)
|
|
|
|
|
("\\.pas\\'" . pascal-mode)
|
2009-09-07 02:26:37 +00:00
|
|
|
|
("\\.\\(dpr\\|DPR\\)\\'" . delphi-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.ad[abs]\\'" . ada-mode)
|
2002-05-29 16:34:41 +00:00
|
|
|
|
("\\.ad[bs].dg\\'" . ada-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.\\([pP]\\([Llm]\\|erl\\|od\\)\\|al\\)\\'" . perl-mode)
|
2006-01-17 18:11:53 +00:00
|
|
|
|
("Imakefile\\'" . makefile-imake-mode)
|
2006-05-30 06:59:56 +00:00
|
|
|
|
("Makeppfile\\(?:\\.mk\\)?\\'" . makefile-makepp-mode) ; Put this before .mk
|
|
|
|
|
("\\.makepp\\'" . makefile-makepp-mode)
|
2009-08-23 00:45:17 +00:00
|
|
|
|
,@(if (memq system-type '(berkeley-unix darwin))
|
2005-05-21 02:42:00 +00:00
|
|
|
|
'(("\\.mk\\'" . makefile-bsdmake-mode)
|
2005-06-14 07:33:01 +00:00
|
|
|
|
("GNUmakefile\\'" . makefile-gmake-mode)
|
2005-05-21 02:42:00 +00:00
|
|
|
|
("[Mm]akefile\\'" . makefile-bsdmake-mode))
|
|
|
|
|
'(("\\.mk\\'" . makefile-gmake-mode) ; Might be any make, give Gnu the host advantage
|
2005-06-14 07:33:01 +00:00
|
|
|
|
("[Mm]akefile\\'" . makefile-gmake-mode)))
|
2005-05-13 07:58:44 +00:00
|
|
|
|
("\\.am\\'" . makefile-automake-mode)
|
2001-05-11 20:22:46 +00:00
|
|
|
|
;; Less common extensions come here
|
|
|
|
|
;; so more common ones above are found faster.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.texinfo\\'" . texinfo-mode)
|
|
|
|
|
("\\.te?xi\\'" . texinfo-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.[sS]\\'" . asm-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.asm\\'" . asm-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("[cC]hange\\.?[lL]og?\\'" . change-log-mode)
|
2007-06-05 15:46:43 +00:00
|
|
|
|
("[cC]hange[lL]og[-.][0-9]+\\'" . change-log-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\$CHANGE_LOG\\$\\.TXT" . change-log-mode)
|
|
|
|
|
("\\.scm\\.[0-9]*\\'" . scheme-mode)
|
|
|
|
|
("\\.[ck]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode)
|
2002-09-09 19:32:41 +00:00
|
|
|
|
("\\.bash\\'" . sh-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\(/\\|\\`\\)\\.\\(bash_profile\\|z?login\\|bash_login\\|z?logout\\)\\'" . sh-mode)
|
|
|
|
|
("\\(/\\|\\`\\)\\.\\(bash_logout\\|shrc\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode)
|
|
|
|
|
("\\(/\\|\\`\\)\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode)
|
2000-11-21 21:12:49 +00:00
|
|
|
|
("\\.m?spec\\'" . sh-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.m[mes]\\'" . nroff-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.man\\'" . nroff-mode)
|
|
|
|
|
("\\.sty\\'" . latex-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.cl[so]\\'" . latex-mode) ;LaTeX 2e class option
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.bbl\\'" . latex-mode)
|
|
|
|
|
("\\.bib\\'" . bibtex-mode)
|
|
|
|
|
("\\.sql\\'" . sql-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.m[4c]\\'" . m4-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.mf\\'" . metafont-mode)
|
|
|
|
|
("\\.mp\\'" . metapost-mode)
|
|
|
|
|
("\\.vhdl?\\'" . vhdl-mode)
|
|
|
|
|
("\\.article\\'" . text-mode)
|
|
|
|
|
("\\.letter\\'" . text-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.i?tcl\\'" . tcl-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.exp\\'" . tcl-mode)
|
|
|
|
|
("\\.itk\\'" . tcl-mode)
|
|
|
|
|
("\\.icn\\'" . icon-mode)
|
|
|
|
|
("\\.sim\\'" . simula-mode)
|
|
|
|
|
("\\.mss\\'" . scribe-mode)
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.f9[05]\\'" . f90-mode)
|
2001-10-19 16:32:49 +00:00
|
|
|
|
("\\.indent\\.pro\\'" . fundamental-mode) ; to avoid idlwave-mode
|
2008-10-03 07:13:31 +00:00
|
|
|
|
("\\.\\(pro\\|PRO\\)\\'" . idlwave-mode)
|
2009-10-03 19:28:05 +00:00
|
|
|
|
("\\.srt\\'" . srecode-template-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.prolog\\'" . prolog-mode)
|
|
|
|
|
("\\.tar\\'" . tar-mode)
|
2005-03-19 20:00:36 +00:00
|
|
|
|
;; The list of archive file extensions should be in sync with
|
|
|
|
|
;; `auto-coding-alist' with `no-conversion' coding system.
|
2007-09-19 17:26:29 +00:00
|
|
|
|
("\\.\\(\
|
2010-04-18 23:08:52 +00:00
|
|
|
|
arc\\|zip\\|lzh\\|lha\\|zoo\\|[jew]ar\\|xpi\\|rar\\|7z\\|\
|
|
|
|
|
ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . archive-mode)
|
2009-03-13 15:58:06 +00:00
|
|
|
|
("\\.\\(sx[dmicw]\\|od[fgpst]\\|oxt\\)\\'" . archive-mode) ;OpenOffice.org
|
|
|
|
|
("\\.\\(deb\\|[oi]pk\\)\\'" . archive-mode) ; Debian/Opkg packages.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
;; Mailer puts message to be edited in
|
|
|
|
|
;; /tmp/Re.... or Message
|
|
|
|
|
("\\`/tmp/Re" . text-mode)
|
|
|
|
|
("/Message[0-9]*\\'" . text-mode)
|
|
|
|
|
;; some news reader is reported to use this
|
|
|
|
|
("\\`/tmp/fol/" . text-mode)
|
|
|
|
|
("\\.oak\\'" . scheme-mode)
|
|
|
|
|
("\\.sgml?\\'" . sgml-mode)
|
2009-09-24 23:22:17 +00:00
|
|
|
|
("\\.x[ms]l\\'" . xml-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.dtd\\'" . sgml-mode)
|
|
|
|
|
("\\.ds\\(ss\\)?l\\'" . dsssl-mode)
|
2009-08-14 23:40:20 +00:00
|
|
|
|
("\\.js\\'" . js-mode) ; javascript-mode would be better
|
2010-03-12 01:29:30 +00:00
|
|
|
|
("\\.[ds]?vh?\\'" . verilog-mode)
|
2002-09-10 08:08:18 +00:00
|
|
|
|
;; .emacs or .gnus or .viper following a directory delimiter in
|
|
|
|
|
;; Unix, MSDOG or VMS syntax.
|
|
|
|
|
("[]>:/\\]\\..*\\(emacs\\|gnus\\|viper\\)\\'" . emacs-lisp-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\`\\..*emacs\\'" . emacs-lisp-mode)
|
|
|
|
|
;; _emacs following a directory delimiter
|
|
|
|
|
;; in MsDos syntax
|
|
|
|
|
("[:/]_emacs\\'" . emacs-lisp-mode)
|
|
|
|
|
("/crontab\\.X*[0-9]+\\'" . shell-script-mode)
|
|
|
|
|
("\\.ml\\'" . lisp-mode)
|
2007-05-22 06:24:53 +00:00
|
|
|
|
;; Common Lisp ASDF package system.
|
|
|
|
|
("\\.asd\\'" . lisp-mode)
|
2000-11-21 21:12:49 +00:00
|
|
|
|
("\\.\\(asn\\|mib\\|smi\\)\\'" . snmp-mode)
|
|
|
|
|
("\\.\\(as\\|mi\\|sm\\)2\\'" . snmpv2-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("\\.\\(diffs?\\|patch\\|rej\\)\\'" . diff-mode)
|
2000-10-17 12:36:26 +00:00
|
|
|
|
("\\.\\(dif\\|pat\\)\\'" . diff-mode) ; for MSDOG
|
2007-10-18 19:59:52 +00:00
|
|
|
|
("\\.[eE]?[pP][sS]\\'" . ps-mode)
|
2007-12-23 17:37:46 +00:00
|
|
|
|
("\\.\\(?:PDF\\|DVI\\|pdf\\|dvi\\)\\'" . doc-view-mode)
|
2001-06-23 19:44:13 +00:00
|
|
|
|
("configure\\.\\(ac\\|in\\)\\'" . autoconf-mode)
|
2008-09-18 15:02:59 +00:00
|
|
|
|
("\\.s\\(v\\|iv\\|ieve\\)\\'" . sieve-mode)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("BROWSE\\'" . ebrowse-tree-mode)
|
|
|
|
|
("\\.ebrowse\\'" . ebrowse-tree-mode)
|
2000-10-07 03:05:14 +00:00
|
|
|
|
("#\\*mail\\*" . mail-mode)
|
2004-11-10 00:39:54 +00:00
|
|
|
|
("\\.g\\'" . antlr-mode)
|
|
|
|
|
("\\.ses\\'" . ses-mode)
|
|
|
|
|
("\\.docbook\\'" . sgml-mode)
|
2004-12-10 16:40:44 +00:00
|
|
|
|
("\\.com\\'" . dcl-mode)
|
2004-11-10 00:39:54 +00:00
|
|
|
|
("/config\\.\\(?:bat\\|log\\)\\'" . fundamental-mode)
|
|
|
|
|
;; Windows candidates may be opened case sensitively on Unix
|
|
|
|
|
("\\.\\(?:[iI][nN][iI]\\|[lL][sS][tT]\\|[rR][eE][gG]\\|[sS][yY][sS]\\)\\'" . conf-mode)
|
|
|
|
|
("\\.\\(?:desktop\\|la\\)\\'" . conf-unix-mode)
|
2004-11-30 23:31:49 +00:00
|
|
|
|
("\\.ppd\\'" . conf-ppd-mode)
|
2004-11-10 00:39:54 +00:00
|
|
|
|
("java.+\\.conf\\'" . conf-javaprop-mode)
|
|
|
|
|
("\\.properties\\(?:\\.[a-zA-Z0-9._-]+\\)?\\'" . conf-javaprop-mode)
|
|
|
|
|
;; *.cf, *.cfg, *.conf, *.config[.local|.de_DE.UTF8|...], */config
|
2007-12-26 17:29:34 +00:00
|
|
|
|
("[/.]c\\(?:on\\)?f\\(?:i?g\\)?\\(?:\\.[a-zA-Z0-9._-]+\\)?\\'" . conf-mode-maybe)
|
2005-04-16 09:00:14 +00:00
|
|
|
|
("\\`/etc/\\(?:DIR_COLORS\\|ethers\\|.?fstab\\|.*hosts\\|lesskey\\|login\\.?de\\(?:fs\\|vperm\\)\\|magic\\|mtab\\|pam\\.d/.*\\|permissions\\(?:\\.d/.+\\)?\\|protocols\\|rpc\\|services\\)\\'" . conf-space-mode)
|
|
|
|
|
("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . conf-mode)
|
2007-06-05 15:46:43 +00:00
|
|
|
|
;; ChangeLog.old etc. Other change-log-mode entries are above;
|
|
|
|
|
;; this has lower priority to avoid matching changelog.sgml etc.
|
|
|
|
|
("[cC]hange[lL]og[-.][-0-9a-z]+\\'" . change-log-mode)
|
2004-11-10 00:39:54 +00:00
|
|
|
|
;; either user's dot-files or under /etc or some such
|
|
|
|
|
("/\\.?\\(?:gnokiirc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . conf-mode)
|
|
|
|
|
;; alas not all ~/.*rc files are like this
|
2004-11-14 18:11:57 +00:00
|
|
|
|
("/\\.\\(?:enigma\\|gltron\\|gtk\\|hxplayer\\|net\\|neverball\\|qt/.+\\|realplayer\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-mode)
|
2004-11-10 00:39:54 +00:00
|
|
|
|
("/\\.\\(?:gdbtkinit\\|grip\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . conf-mode)
|
|
|
|
|
("/\\.?X\\(?:default\\|resource\\|re\\)s\\>" . conf-xdefaults-mode)
|
|
|
|
|
("/X11.+app-defaults/" . conf-xdefaults-mode)
|
|
|
|
|
("/X11.+locale/.+/Compose\\'" . conf-colon-mode)
|
|
|
|
|
;; this contains everything twice, with space and with colon :-(
|
|
|
|
|
("/X11.+locale/compose\\.dir\\'" . conf-javaprop-mode)
|
2000-10-07 03:05:14 +00:00
|
|
|
|
;; Get rid of any trailing .n.m and try again.
|
|
|
|
|
;; This is for files saved by cvs-merge that look like .#<file>.<rev>
|
2001-05-11 20:22:46 +00:00
|
|
|
|
;; or .#<file>.<rev>-<rev> or VC's <file>.~<rev>~.
|
|
|
|
|
;; Using mode nil rather than `ignore' would let the search continue
|
|
|
|
|
;; through this list (with the shortened name) rather than start over.
|
2004-10-26 21:44:20 +00:00
|
|
|
|
("\\.~?[0-9]+\\.[0-9][-.0-9]*~?\\'" nil t)
|
2001-05-11 20:22:46 +00:00
|
|
|
|
;; The following should come after the ChangeLog pattern
|
|
|
|
|
;; for the sake of ChangeLog.1, etc.
|
|
|
|
|
;; and after the .scm.[0-9] and CVS' <file>.<rev> patterns too.
|
2001-07-25 09:48:04 +00:00
|
|
|
|
("\\.[1-9]\\'" . nroff-mode)
|
2004-11-10 00:39:54 +00:00
|
|
|
|
("\\.\\(?:orig\\|in\\|[bB][aA][kK]\\)\\'" nil t)))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Alist of filename patterns vs corresponding major mode functions.
|
1994-10-19 00:08:18 +00:00
|
|
|
|
Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL).
|
|
|
|
|
\(NON-NIL stands for anything that is not nil; the value does not matter.)
|
|
|
|
|
Visiting a file whose name matches REGEXP specifies FUNCTION as the
|
|
|
|
|
mode function to use. FUNCTION will be called, unless it is nil.
|
|
|
|
|
|
|
|
|
|
If the element has the form (REGEXP FUNCTION NON-NIL), then after
|
|
|
|
|
calling FUNCTION (if it's not nil), we delete the suffix that matched
|
2005-01-03 02:42:25 +00:00
|
|
|
|
REGEXP and search the list again for another match.
|
1992-02-27 23:17:44 +00:00
|
|
|
|
|
2005-01-03 02:42:25 +00:00
|
|
|
|
If the file name matches `inhibit-first-line-modes-regexps',
|
|
|
|
|
then `auto-mode-alist' is not processed.
|
|
|
|
|
|
2006-03-11 11:42:58 +00:00
|
|
|
|
The extensions whose FUNCTION is `archive-mode' should also
|
|
|
|
|
appear in `auto-coding-alist' with `no-conversion' coding system.
|
|
|
|
|
|
2005-01-03 02:42:25 +00:00
|
|
|
|
See also `interpreter-mode-alist', which detects executable script modes
|
|
|
|
|
based on the interpreters they specify to run,
|
|
|
|
|
and `magic-mode-alist', which determines modes based on file contents.")
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
(put 'auto-mode-alist 'risky-local-variable t)
|
1998-03-05 02:17:48 +00:00
|
|
|
|
|
2007-12-26 17:29:34 +00:00
|
|
|
|
(defun conf-mode-maybe ()
|
|
|
|
|
"Select Conf mode or XML mode according to start of file."
|
|
|
|
|
(if (save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(looking-at "<\\?xml \\|<!-- \\|<!DOCTYPE ")))
|
2009-09-24 23:22:17 +00:00
|
|
|
|
(xml-mode)
|
2007-12-26 17:29:34 +00:00
|
|
|
|
(conf-mode)))
|
|
|
|
|
|
1996-12-16 01:33:02 +00:00
|
|
|
|
(defvar interpreter-mode-alist
|
2003-07-09 20:28:23 +00:00
|
|
|
|
;; Note: The entries for the modes defined in cc-mode.el (awk-mode
|
|
|
|
|
;; and pike-mode) are added through autoload directives in that
|
|
|
|
|
;; file. That way is discouraged since it spreads out the
|
|
|
|
|
;; definition of the initial value.
|
2009-10-26 06:43:36 +00:00
|
|
|
|
(mapcar
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(lambda (l)
|
|
|
|
|
(cons (purecopy (car l)) (cdr l)))
|
|
|
|
|
'(("perl" . perl-mode)
|
|
|
|
|
("perl5" . perl-mode)
|
|
|
|
|
("miniperl" . perl-mode)
|
|
|
|
|
("wish" . tcl-mode)
|
|
|
|
|
("wishx" . tcl-mode)
|
|
|
|
|
("tcl" . tcl-mode)
|
|
|
|
|
("tclsh" . tcl-mode)
|
|
|
|
|
("scm" . scheme-mode)
|
|
|
|
|
("ash" . sh-mode)
|
|
|
|
|
("bash" . sh-mode)
|
|
|
|
|
("bash2" . sh-mode)
|
|
|
|
|
("csh" . sh-mode)
|
|
|
|
|
("dtksh" . sh-mode)
|
|
|
|
|
("es" . sh-mode)
|
|
|
|
|
("itcsh" . sh-mode)
|
|
|
|
|
("jsh" . sh-mode)
|
|
|
|
|
("ksh" . sh-mode)
|
|
|
|
|
("oash" . sh-mode)
|
|
|
|
|
("pdksh" . sh-mode)
|
|
|
|
|
("rc" . sh-mode)
|
|
|
|
|
("rpm" . sh-mode)
|
|
|
|
|
("sh" . sh-mode)
|
|
|
|
|
("sh5" . sh-mode)
|
|
|
|
|
("tcsh" . sh-mode)
|
|
|
|
|
("wksh" . sh-mode)
|
|
|
|
|
("wsh" . sh-mode)
|
|
|
|
|
("zsh" . sh-mode)
|
|
|
|
|
("tail" . text-mode)
|
|
|
|
|
("more" . text-mode)
|
|
|
|
|
("less" . text-mode)
|
|
|
|
|
("pg" . text-mode)
|
2005-05-13 07:58:44 +00:00
|
|
|
|
("make" . makefile-gmake-mode) ; Debian uses this
|
2000-10-04 17:16:59 +00:00
|
|
|
|
("guile" . scheme-mode)
|
2010-03-18 04:54:51 +00:00
|
|
|
|
("clisp" . lisp-mode)
|
|
|
|
|
("emacs" . emacs-lisp-mode)))
|
1994-02-16 07:06:10 +00:00
|
|
|
|
"Alist mapping interpreter names to major modes.
|
2005-01-03 02:42:25 +00:00
|
|
|
|
This is used for files whose first lines match `auto-mode-interpreter-regexp'.
|
1994-02-16 07:06:10 +00:00
|
|
|
|
Each element looks like (INTERPRETER . MODE).
|
2005-08-15 02:05:01 +00:00
|
|
|
|
If INTERPRETER matches the name of the interpreter specified in the first line
|
|
|
|
|
of a script, mode MODE is enabled.
|
2005-01-03 02:42:25 +00:00
|
|
|
|
|
|
|
|
|
See also `auto-mode-alist'.")
|
1994-02-16 07:06:10 +00:00
|
|
|
|
|
2009-10-26 06:43:36 +00:00
|
|
|
|
(defvar inhibit-first-line-modes-regexps (mapcar 'purecopy '("\\.tar\\'" "\\.tgz\\'"))
|
1994-04-09 22:27:31 +00:00
|
|
|
|
"List of regexps; if one matches a file name, don't look for `-*-'.")
|
1993-05-31 21:50:52 +00:00
|
|
|
|
|
1996-12-16 01:33:02 +00:00
|
|
|
|
(defvar inhibit-first-line-modes-suffixes nil
|
1995-04-02 02:22:14 +00:00
|
|
|
|
"List of regexps for what to ignore, for `inhibit-first-line-modes-regexps'.
|
|
|
|
|
When checking `inhibit-first-line-modes-regexps', we first discard
|
|
|
|
|
from the end of the file name anything that matches one of these regexps.")
|
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defvar auto-mode-interpreter-regexp
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(purecopy "#![ \t]?\\([^ \t\n]*\
|
|
|
|
|
/bin/env[ \t]\\)?\\([^ \t\n]+\\)")
|
2005-05-14 00:56:30 +00:00
|
|
|
|
"Regexp matching interpreters, for file mode determination.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
This regular expression is matched against the first line of a file
|
2005-05-14 00:56:30 +00:00
|
|
|
|
to determine the file's mode in `set-auto-mode'. If it matches, the file
|
|
|
|
|
is assumed to be interpreted by the interpreter matched by the second group
|
|
|
|
|
of the regular expression. The mode is then determined as the mode
|
|
|
|
|
associated with that interpreter in `interpreter-mode-alist'.")
|
2000-08-08 18:32:10 +00:00
|
|
|
|
|
2007-05-21 16:43:27 +00:00
|
|
|
|
(defvar magic-mode-alist nil
|
2007-05-16 16:13:12 +00:00
|
|
|
|
"Alist of buffer beginnings vs. corresponding major mode functions.
|
|
|
|
|
Each element looks like (REGEXP . FUNCTION) or (MATCH-FUNCTION . FUNCTION).
|
|
|
|
|
After visiting a file, if REGEXP matches the text at the beginning of the
|
|
|
|
|
buffer, or calling MATCH-FUNCTION returns non-nil, `normal-mode' will
|
|
|
|
|
call FUNCTION rather than allowing `auto-mode-alist' to decide the buffer's
|
|
|
|
|
major mode.
|
|
|
|
|
|
|
|
|
|
If FUNCTION is nil, then it is not called. (That is a way of saying
|
|
|
|
|
\"allow `auto-mode-alist' to decide for these files.\")")
|
|
|
|
|
(put 'magic-mode-alist 'risky-local-variable t)
|
|
|
|
|
|
|
|
|
|
(defvar magic-fallback-mode-alist
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(purecopy
|
2007-05-21 16:43:27 +00:00
|
|
|
|
`((image-type-auto-detected-p . image-mode)
|
2009-08-28 23:48:46 +00:00
|
|
|
|
("\\(PK00\\)?[P]K\003\004" . archive-mode) ; zip
|
2007-05-21 16:43:27 +00:00
|
|
|
|
;; The < comes before the groups (but the first) to reduce backtracking.
|
2004-11-03 21:44:49 +00:00
|
|
|
|
;; TODO: UTF-16 <?xml may be preceded by a BOM 0xff 0xfe or 0xfe 0xff.
|
2007-04-23 01:21:11 +00:00
|
|
|
|
;; We use [ \t\r\n] instead of `\\s ' to make regex overflow less likely.
|
2004-11-11 04:52:27 +00:00
|
|
|
|
(,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)")
|
2007-04-23 01:21:11 +00:00
|
|
|
|
(comment-re (concat "\\(?:!--" incomment-re "*-->[ \t\r\n]*<\\)")))
|
|
|
|
|
(concat "\\(?:<\\?xml[ \t\r\n]+[^>]*>\\)?[ \t\r\n]*<"
|
2004-11-11 04:52:27 +00:00
|
|
|
|
comment-re "*"
|
2007-04-23 01:21:11 +00:00
|
|
|
|
"\\(?:!DOCTYPE[ \t\r\n]+[^>]*>[ \t\r\n]*<[ \t\r\n]*" comment-re "*\\)?"
|
2005-01-03 02:42:25 +00:00
|
|
|
|
"[Hh][Tt][Mm][Ll]"))
|
|
|
|
|
. html-mode)
|
2007-04-23 07:17:08 +00:00
|
|
|
|
("<!DOCTYPE[ \t\r\n]+[Hh][Tt][Mm][Ll]" . html-mode)
|
2004-11-03 21:44:49 +00:00
|
|
|
|
;; These two must come after html, because they are more general:
|
2009-09-24 23:22:17 +00:00
|
|
|
|
("<\\?xml " . xml-mode)
|
2004-11-11 21:42:32 +00:00
|
|
|
|
(,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)")
|
2007-04-23 01:23:12 +00:00
|
|
|
|
(comment-re (concat "\\(?:!--" incomment-re "*-->[ \t\r\n]*<\\)")))
|
|
|
|
|
(concat "[ \t\r\n]*<" comment-re "*!DOCTYPE "))
|
2005-01-03 02:42:25 +00:00
|
|
|
|
. sgml-mode)
|
2007-03-20 18:36:15 +00:00
|
|
|
|
("%!PS" . ps-mode)
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
("# xmcd " . conf-unix-mode)))
|
2007-05-10 14:48:46 +00:00
|
|
|
|
"Like `magic-mode-alist' but has lower priority than `auto-mode-alist'.
|
|
|
|
|
Each element looks like (REGEXP . FUNCTION) or (MATCH-FUNCTION . FUNCTION).
|
|
|
|
|
After visiting a file, if REGEXP matches the text at the beginning of the
|
|
|
|
|
buffer, or calling MATCH-FUNCTION returns non-nil, `normal-mode' will
|
|
|
|
|
call FUNCTION, provided that `magic-mode-alist' and `auto-mode-alist'
|
|
|
|
|
have not specified a mode for this file.
|
|
|
|
|
|
|
|
|
|
If FUNCTION is nil, then it is not called.")
|
2007-05-16 16:07:15 +00:00
|
|
|
|
(put 'magic-fallback-mode-alist 'risky-local-variable t)
|
2007-05-10 14:48:46 +00:00
|
|
|
|
|
2006-02-04 23:33:53 +00:00
|
|
|
|
(defvar magic-mode-regexp-match-limit 4000
|
2007-05-10 14:48:46 +00:00
|
|
|
|
"Upper limit on `magic-mode-alist' regexp matches.
|
2007-05-16 16:07:15 +00:00
|
|
|
|
Also applies to `magic-fallback-mode-alist'.")
|
2006-02-04 23:33:53 +00:00
|
|
|
|
|
2004-10-27 21:44:35 +00:00
|
|
|
|
(defun set-auto-mode (&optional keep-mode-if-same)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Select major mode appropriate for current buffer.
|
2004-11-03 21:44:49 +00:00
|
|
|
|
|
2007-05-22 11:42:31 +00:00
|
|
|
|
To find the right major mode, this function checks for a -*- mode tag,
|
|
|
|
|
checks if it uses an interpreter listed in `interpreter-mode-alist',
|
|
|
|
|
matches the buffer beginning against `magic-mode-alist',
|
|
|
|
|
compares the filename against the entries in `auto-mode-alist',
|
|
|
|
|
then matches the buffer beginning against `magic-fallback-mode-alist'.
|
1994-05-23 09:48:37 +00:00
|
|
|
|
|
|
|
|
|
It does not check for the `mode:' local variable in the
|
|
|
|
|
Local Variables section of the file; for that, use `hack-local-variables'.
|
1992-02-27 23:17:44 +00:00
|
|
|
|
|
1992-10-12 04:45:53 +00:00
|
|
|
|
If `enable-local-variables' is nil, this function does not check for a
|
1997-05-05 04:38:26 +00:00
|
|
|
|
-*- mode tag.
|
|
|
|
|
|
2004-10-28 06:09:55 +00:00
|
|
|
|
If the optional argument KEEP-MODE-IF-SAME is non-nil, then we
|
2007-05-22 11:42:31 +00:00
|
|
|
|
set the major mode only if that would change it. In other words
|
|
|
|
|
we don't actually set it to the same mode the buffer already has."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
|
2004-11-11 21:42:32 +00:00
|
|
|
|
(let (end done mode modes)
|
2004-10-27 21:44:35 +00:00
|
|
|
|
;; Find a -*- mode tag
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(skip-chars-forward " \t\n")
|
1993-09-11 10:45:25 +00:00
|
|
|
|
(and enable-local-variables
|
2001-12-12 00:10:17 +00:00
|
|
|
|
(setq end (set-auto-mode-1))
|
2001-12-14 03:21:49 +00:00
|
|
|
|
(if (save-excursion (search-forward ":" end t))
|
|
|
|
|
;; Find all specifications for the `mode:' variable
|
|
|
|
|
;; and execute them left to right.
|
|
|
|
|
(while (let ((case-fold-search t))
|
|
|
|
|
(or (and (looking-at "mode:")
|
|
|
|
|
(goto-char (match-end 0)))
|
|
|
|
|
(re-search-forward "[ \t;]mode:" end t)))
|
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
|
(let ((beg (point)))
|
1993-09-11 10:45:25 +00:00
|
|
|
|
(if (search-forward ";" end t)
|
|
|
|
|
(forward-char -1)
|
|
|
|
|
(goto-char end))
|
|
|
|
|
(skip-chars-backward " \t")
|
2000-10-07 03:05:14 +00:00
|
|
|
|
(push (intern (concat (downcase (buffer-substring beg (point))) "-mode"))
|
2001-12-14 03:21:49 +00:00
|
|
|
|
modes)))
|
|
|
|
|
;; Simple -*-MODE-*- case.
|
|
|
|
|
(push (intern (concat (downcase (buffer-substring (point) end))
|
|
|
|
|
"-mode"))
|
|
|
|
|
modes))))
|
2004-10-27 21:44:35 +00:00
|
|
|
|
;; If we found modes to use, invoke them now, outside the save-excursion.
|
|
|
|
|
(if modes
|
2004-10-28 06:09:55 +00:00
|
|
|
|
(catch 'nop
|
|
|
|
|
(dolist (mode (nreverse modes))
|
|
|
|
|
(if (not (functionp mode))
|
|
|
|
|
(message "Ignoring unknown mode `%s'" mode)
|
|
|
|
|
(setq done t)
|
2004-11-01 23:16:42 +00:00
|
|
|
|
(or (set-auto-mode-0 mode keep-mode-if-same)
|
2004-11-04 20:25:08 +00:00
|
|
|
|
;; continuing would call minor modes again, toggling them off
|
2005-12-16 15:44:39 +00:00
|
|
|
|
(throw 'nop nil))))))
|
2007-05-10 14:48:46 +00:00
|
|
|
|
;; If we didn't, look for an interpreter specified in the first line.
|
|
|
|
|
;; As a special case, allow for things like "#!/bin/env perl", which
|
|
|
|
|
;; finds the interpreter anywhere in $PATH.
|
2005-12-16 15:44:39 +00:00
|
|
|
|
(unless done
|
2004-10-27 21:44:35 +00:00
|
|
|
|
(setq mode (save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(if (looking-at auto-mode-interpreter-regexp)
|
|
|
|
|
(match-string 2)
|
|
|
|
|
""))
|
|
|
|
|
;; Map interpreter name to a mode, signalling we're done at the
|
|
|
|
|
;; same time.
|
|
|
|
|
done (assoc (file-name-nondirectory mode)
|
|
|
|
|
interpreter-mode-alist))
|
2004-11-11 21:42:32 +00:00
|
|
|
|
;; If we found an interpreter mode to use, invoke it now.
|
2004-11-04 20:25:08 +00:00
|
|
|
|
(if done
|
|
|
|
|
(set-auto-mode-0 (cdr done) keep-mode-if-same)))
|
2007-05-10 14:48:46 +00:00
|
|
|
|
;; Next try matching the buffer beginning against magic-mode-alist.
|
2004-11-04 20:25:08 +00:00
|
|
|
|
(unless done
|
2004-11-03 21:44:49 +00:00
|
|
|
|
(if (setq done (save-excursion
|
|
|
|
|
(goto-char (point-min))
|
2006-02-04 23:33:53 +00:00
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region (point-min)
|
|
|
|
|
(min (point-max)
|
|
|
|
|
(+ (point-min) magic-mode-regexp-match-limit)))
|
|
|
|
|
(assoc-default nil magic-mode-alist
|
|
|
|
|
(lambda (re dummy)
|
2006-12-19 09:04:30 +00:00
|
|
|
|
(if (functionp re)
|
|
|
|
|
(funcall re)
|
|
|
|
|
(looking-at re)))))))
|
2007-05-10 14:48:46 +00:00
|
|
|
|
(set-auto-mode-0 done keep-mode-if-same)))
|
|
|
|
|
;; Next compare the filename against the entries in auto-mode-alist.
|
|
|
|
|
(unless done
|
|
|
|
|
(if buffer-file-name
|
2007-08-05 08:50:52 +00:00
|
|
|
|
(let ((name buffer-file-name)
|
|
|
|
|
(remote-id (file-remote-p buffer-file-name)))
|
|
|
|
|
;; Remove remote file name identification.
|
|
|
|
|
(when (and (stringp remote-id)
|
2007-08-05 12:46:33 +00:00
|
|
|
|
(string-match (regexp-quote remote-id) name))
|
2007-08-05 08:50:52 +00:00
|
|
|
|
(setq name (substring name (match-end 0))))
|
2007-05-10 14:48:46 +00:00
|
|
|
|
;; Remove backup-suffixes from file name.
|
|
|
|
|
(setq name (file-name-sans-versions name))
|
|
|
|
|
(while name
|
|
|
|
|
;; Find first matching alist entry.
|
|
|
|
|
(setq mode
|
2008-07-31 05:33:56 +00:00
|
|
|
|
(if (memq system-type '(windows-nt cygwin))
|
2007-05-10 14:48:46 +00:00
|
|
|
|
;; System is case-insensitive.
|
|
|
|
|
(let ((case-fold-search t))
|
|
|
|
|
(assoc-default name auto-mode-alist
|
|
|
|
|
'string-match))
|
|
|
|
|
;; System is case-sensitive.
|
|
|
|
|
(or
|
|
|
|
|
;; First match case-sensitively.
|
|
|
|
|
(let ((case-fold-search nil))
|
|
|
|
|
(assoc-default name auto-mode-alist
|
|
|
|
|
'string-match))
|
|
|
|
|
;; Fallback to case-insensitive match.
|
|
|
|
|
(and auto-mode-case-fold
|
|
|
|
|
(let ((case-fold-search t))
|
|
|
|
|
(assoc-default name auto-mode-alist
|
|
|
|
|
'string-match))))))
|
|
|
|
|
(if (and mode
|
|
|
|
|
(consp mode)
|
|
|
|
|
(cadr mode))
|
|
|
|
|
(setq mode (car mode)
|
|
|
|
|
name (substring name 0 (match-beginning 0)))
|
|
|
|
|
(setq name))
|
|
|
|
|
(when mode
|
|
|
|
|
(set-auto-mode-0 mode keep-mode-if-same)
|
|
|
|
|
(setq done t))))))
|
2007-05-16 16:07:15 +00:00
|
|
|
|
;; Next try matching the buffer beginning against magic-fallback-mode-alist.
|
2007-05-10 14:48:46 +00:00
|
|
|
|
(unless done
|
|
|
|
|
(if (setq done (save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region (point-min)
|
|
|
|
|
(min (point-max)
|
|
|
|
|
(+ (point-min) magic-mode-regexp-match-limit)))
|
2007-05-16 16:07:15 +00:00
|
|
|
|
(assoc-default nil magic-fallback-mode-alist
|
2007-05-10 14:48:46 +00:00
|
|
|
|
(lambda (re dummy)
|
|
|
|
|
(if (functionp re)
|
|
|
|
|
(funcall re)
|
|
|
|
|
(looking-at re)))))))
|
|
|
|
|
(set-auto-mode-0 done keep-mode-if-same)))))
|
2004-10-28 06:09:55 +00:00
|
|
|
|
|
|
|
|
|
;; When `keep-mode-if-same' is set, we are working on behalf of
|
|
|
|
|
;; set-visited-file-name. In that case, if the major mode specified is the
|
|
|
|
|
;; same one we already have, don't actually reset it. We don't want to lose
|
|
|
|
|
;; minor modes such as Font Lock.
|
2004-11-01 23:16:42 +00:00
|
|
|
|
(defun set-auto-mode-0 (mode &optional keep-mode-if-same)
|
2004-10-28 06:09:55 +00:00
|
|
|
|
"Apply MODE and return it.
|
2004-11-01 23:16:42 +00:00
|
|
|
|
If optional arg KEEP-MODE-IF-SAME is non-nil, MODE is chased of
|
|
|
|
|
any aliases and compared to current major mode. If they are the
|
|
|
|
|
same, do nothing and return nil."
|
2007-03-01 17:06:40 +00:00
|
|
|
|
(unless (and keep-mode-if-same
|
|
|
|
|
(eq (indirect-function mode)
|
|
|
|
|
(indirect-function major-mode)))
|
|
|
|
|
(when mode
|
|
|
|
|
(funcall mode)
|
|
|
|
|
mode)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2001-12-12 00:10:17 +00:00
|
|
|
|
(defun set-auto-mode-1 ()
|
|
|
|
|
"Find the -*- spec in the buffer.
|
|
|
|
|
Call with point at the place to start searching from.
|
|
|
|
|
If one is found, set point to the beginning
|
|
|
|
|
and return the position of the end.
|
|
|
|
|
Otherwise, return nil; point may be changed."
|
|
|
|
|
(let (beg end)
|
|
|
|
|
(and
|
|
|
|
|
;; Don't look for -*- if this file name matches any
|
|
|
|
|
;; of the regexps in inhibit-first-line-modes-regexps.
|
|
|
|
|
(let ((temp inhibit-first-line-modes-regexps)
|
|
|
|
|
(name (if buffer-file-name
|
|
|
|
|
(file-name-sans-versions buffer-file-name)
|
|
|
|
|
(buffer-name))))
|
|
|
|
|
(while (let ((sufs inhibit-first-line-modes-suffixes))
|
|
|
|
|
(while (and sufs (not (string-match (car sufs) name)))
|
|
|
|
|
(setq sufs (cdr sufs)))
|
|
|
|
|
sufs)
|
|
|
|
|
(setq name (substring name 0 (match-beginning 0))))
|
|
|
|
|
(while (and temp
|
|
|
|
|
(not (string-match (car temp) name)))
|
|
|
|
|
(setq temp (cdr temp)))
|
|
|
|
|
(not temp))
|
|
|
|
|
|
2005-04-10 20:50:48 +00:00
|
|
|
|
(search-forward "-*-" (line-end-position
|
|
|
|
|
;; If the file begins with "#!"
|
|
|
|
|
;; (exec interpreter magic), look
|
|
|
|
|
;; for mode frobs in the first two
|
|
|
|
|
;; lines. You cannot necessarily
|
|
|
|
|
;; put them in the first line of
|
|
|
|
|
;; such a file without screwing up
|
|
|
|
|
;; the interpreter invocation.
|
2007-11-16 08:03:45 +00:00
|
|
|
|
;; The same holds for
|
|
|
|
|
;; '\"
|
|
|
|
|
;; in man pages (preprocessor
|
|
|
|
|
;; magic for the `man' program).
|
|
|
|
|
(and (looking-at "^\\(#!\\|'\\\\\"\\)") 2)) t)
|
2001-12-12 00:10:17 +00:00
|
|
|
|
(progn
|
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
|
(setq beg (point))
|
2005-04-10 20:50:48 +00:00
|
|
|
|
(search-forward "-*-" (line-end-position) t))
|
2001-12-12 00:10:17 +00:00
|
|
|
|
(progn
|
|
|
|
|
(forward-char -3)
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(setq end (point))
|
|
|
|
|
(goto-char beg)
|
|
|
|
|
end))))
|
2006-02-17 15:33:22 +00:00
|
|
|
|
|
|
|
|
|
;;; Handling file local variables
|
|
|
|
|
|
|
|
|
|
(defvar ignored-local-variables
|
2008-07-31 01:22:54 +00:00
|
|
|
|
'(ignored-local-variables safe-local-variable-values
|
2009-07-19 16:55:16 +00:00
|
|
|
|
file-local-variables-alist dir-local-variables-alist)
|
2006-02-17 15:33:22 +00:00
|
|
|
|
"Variables to be ignored in a file's local variable spec.")
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
(put 'ignored-local-variables 'risky-local-variable t)
|
2006-02-17 15:33:22 +00:00
|
|
|
|
|
|
|
|
|
(defvar hack-local-variables-hook nil
|
|
|
|
|
"Normal hook run after processing a file's local variables specs.
|
|
|
|
|
Major modes can use this to examine user-specified local variables
|
|
|
|
|
in order to initialize other data structure based on them.")
|
|
|
|
|
|
|
|
|
|
(defcustom safe-local-variable-values nil
|
|
|
|
|
"List variable-value pairs that are considered safe.
|
|
|
|
|
Each element is a cons cell (VAR . VAL), where VAR is a variable
|
|
|
|
|
symbol and VAL is a value that is considered safe."
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
:risky t
|
2006-02-17 15:33:22 +00:00
|
|
|
|
:group 'find-file
|
2008-07-31 21:35:59 +00:00
|
|
|
|
:type 'alist)
|
2006-02-17 15:33:22 +00:00
|
|
|
|
|
2009-09-25 22:04:07 +00:00
|
|
|
|
(defcustom safe-local-eval-forms
|
|
|
|
|
'((add-hook 'write-file-functions 'time-stamp)
|
2009-09-29 23:57:17 +00:00
|
|
|
|
(add-hook 'before-save-hook 'time-stamp))
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Expressions that are considered safe in an `eval:' local variable.
|
2006-02-17 15:33:22 +00:00
|
|
|
|
Add expressions to this list if you want Emacs to evaluate them, when
|
|
|
|
|
they appear in an `eval' local variable specification, without first
|
|
|
|
|
asking you for confirmation."
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
:risky t
|
2006-02-17 15:33:22 +00:00
|
|
|
|
:group 'find-file
|
2008-01-10 14:01:13 +00:00
|
|
|
|
:version "22.2"
|
2006-02-17 15:33:22 +00:00
|
|
|
|
:type '(repeat sexp))
|
|
|
|
|
|
|
|
|
|
;; Risky local variables:
|
|
|
|
|
(mapc (lambda (var) (put var 'risky-local-variable t))
|
|
|
|
|
'(after-load-alist
|
|
|
|
|
buffer-auto-save-file-name
|
|
|
|
|
buffer-file-name
|
|
|
|
|
buffer-file-truename
|
|
|
|
|
buffer-undo-list
|
|
|
|
|
debugger
|
|
|
|
|
default-text-properties
|
|
|
|
|
eval
|
|
|
|
|
exec-directory
|
|
|
|
|
exec-path
|
|
|
|
|
file-name-handler-alist
|
|
|
|
|
frame-title-format
|
|
|
|
|
global-mode-string
|
|
|
|
|
header-line-format
|
|
|
|
|
icon-title-format
|
|
|
|
|
inhibit-quit
|
|
|
|
|
load-path
|
|
|
|
|
max-lisp-eval-depth
|
|
|
|
|
max-specpdl-size
|
|
|
|
|
minor-mode-map-alist
|
|
|
|
|
minor-mode-overriding-map-alist
|
|
|
|
|
mode-line-format
|
|
|
|
|
mode-name
|
|
|
|
|
overriding-local-map
|
|
|
|
|
overriding-terminal-local-map
|
|
|
|
|
process-environment
|
|
|
|
|
standard-input
|
|
|
|
|
standard-output
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
unread-command-events))
|
2006-02-17 15:33:22 +00:00
|
|
|
|
|
|
|
|
|
;; Safe local variables:
|
|
|
|
|
;;
|
2006-04-06 19:20:38 +00:00
|
|
|
|
;; For variables defined by major modes, the safety declarations can go into
|
|
|
|
|
;; the major mode's file, since that will be loaded before file variables are
|
|
|
|
|
;; processed.
|
|
|
|
|
;;
|
|
|
|
|
;; For variables defined by minor modes, put the safety declarations in the
|
|
|
|
|
;; file defining the minor mode after the defcustom/defvar using an autoload
|
|
|
|
|
;; cookie, e.g.:
|
|
|
|
|
;;
|
|
|
|
|
;; ;;;###autoload(put 'variable 'safe-local-variable 'stringp)
|
|
|
|
|
;;
|
|
|
|
|
;; Otherwise, when Emacs visits a file specifying that local variable, the
|
|
|
|
|
;; minor mode file may not be loaded yet.
|
|
|
|
|
;;
|
|
|
|
|
;; For variables defined in the C source code the declaration should go here:
|
2006-02-17 15:33:22 +00:00
|
|
|
|
|
2006-05-09 22:55:30 +00:00
|
|
|
|
(mapc (lambda (pair)
|
|
|
|
|
(put (car pair) 'safe-local-variable (cdr pair)))
|
2010-03-29 12:26:24 +00:00
|
|
|
|
'((buffer-read-only . booleanp) ;; C source code
|
|
|
|
|
(default-directory . stringp) ;; C source code
|
|
|
|
|
(fill-column . integerp) ;; C source code
|
|
|
|
|
(indent-tabs-mode . booleanp) ;; C source code
|
|
|
|
|
(left-margin . integerp) ;; C source code
|
|
|
|
|
(no-update-autoloads . booleanp)
|
|
|
|
|
(tab-width . integerp) ;; C source code
|
|
|
|
|
(truncate-lines . booleanp) ;; C source code
|
|
|
|
|
(bidi-display-reordering . booleanp))) ;; C source code
|
2006-02-17 15:33:22 +00:00
|
|
|
|
|
|
|
|
|
(put 'c-set-style 'safe-local-eval-function t)
|
2001-12-12 00:10:17 +00:00
|
|
|
|
|
2008-07-31 01:22:54 +00:00
|
|
|
|
(defvar file-local-variables-alist nil
|
|
|
|
|
"Alist of file-local variable settings in the current buffer.
|
|
|
|
|
Each element in this list has the form (VAR . VALUE), where VAR
|
|
|
|
|
is a file-local variable (a symbol) and VALUE is the value
|
|
|
|
|
specified. The actual value in the buffer may differ from VALUE,
|
|
|
|
|
if it is changed by the major or minor modes, or by the user.")
|
|
|
|
|
(make-variable-buffer-local 'file-local-variables-alist)
|
|
|
|
|
|
2009-07-19 16:55:16 +00:00
|
|
|
|
(defvar dir-local-variables-alist nil
|
|
|
|
|
"Alist of directory-local variable settings in the current buffer.
|
|
|
|
|
Each element in this list has the form (VAR . VALUE), where VAR
|
|
|
|
|
is a directory-local variable (a symbol) and VALUE is the value
|
|
|
|
|
specified in .dir-locals.el. The actual value in the buffer
|
|
|
|
|
may differ from VALUE, if it is changed by the major or minor modes,
|
|
|
|
|
or by the user.")
|
|
|
|
|
(make-variable-buffer-local 'dir-local-variables-alist)
|
|
|
|
|
|
2008-07-31 01:22:54 +00:00
|
|
|
|
(defvar before-hack-local-variables-hook nil
|
|
|
|
|
"Normal hook run before setting file-local variables.
|
|
|
|
|
It is called after checking for unsafe/risky variables and
|
|
|
|
|
setting `file-local-variables-alist', and before applying the
|
|
|
|
|
variables stored in `file-local-variables-alist'. A hook
|
|
|
|
|
function is allowed to change the contents of this alist.
|
|
|
|
|
|
|
|
|
|
This hook is called only if there is at least one file-local
|
|
|
|
|
variable to set.")
|
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defun hack-local-variables-confirm (all-vars unsafe-vars risky-vars dir-name)
|
2007-09-01 16:24:03 +00:00
|
|
|
|
"Get confirmation before setting up local variable values.
|
|
|
|
|
ALL-VARS is the list of all variables to be set up.
|
|
|
|
|
UNSAFE-VARS is the list of those that aren't marked as safe or risky.
|
2008-05-19 22:36:09 +00:00
|
|
|
|
RISKY-VARS is the list of those that are marked as risky.
|
2008-11-22 19:02:47 +00:00
|
|
|
|
DIR-NAME is a directory name if these settings come from
|
|
|
|
|
directory-local variables, or nil otherwise."
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(if noninteractive
|
|
|
|
|
nil
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(let ((name (or dir-name
|
|
|
|
|
(if buffer-file-name
|
|
|
|
|
(file-name-nondirectory buffer-file-name)
|
|
|
|
|
(concat "buffer " (buffer-name)))))
|
2006-03-10 23:22:30 +00:00
|
|
|
|
(offer-save (and (eq enable-local-variables t) unsafe-vars))
|
2006-02-15 01:32:50 +00:00
|
|
|
|
prompt char)
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(save-window-excursion
|
2006-02-15 01:32:50 +00:00
|
|
|
|
(let ((buf (get-buffer-create "*Local Variables*")))
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(pop-to-buffer buf)
|
|
|
|
|
(set (make-local-variable 'cursor-type) nil)
|
|
|
|
|
(erase-buffer)
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(if unsafe-vars
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(insert "The local variables list in " name
|
2006-02-15 01:21:31 +00:00
|
|
|
|
"\ncontains values that may not be safe (*)"
|
|
|
|
|
(if risky-vars
|
|
|
|
|
", and variables that are risky (**)."
|
|
|
|
|
"."))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(if risky-vars
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(insert "The local variables list in " name
|
2006-02-15 01:21:31 +00:00
|
|
|
|
"\ncontains variables that are risky (**).")
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(insert "A local variables list is specified in " name ".")))
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(insert "\n\nDo you want to apply it? You can type
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
y -- to apply the local variables list.
|
2006-03-10 23:22:30 +00:00
|
|
|
|
n -- to ignore the local variables list.")
|
|
|
|
|
(if offer-save
|
|
|
|
|
(insert "
|
2006-04-08 10:41:12 +00:00
|
|
|
|
! -- to apply the local variables list, and permanently mark these
|
|
|
|
|
values (*) as safe (in the future, they will be set automatically.)\n\n")
|
2006-03-10 23:22:30 +00:00
|
|
|
|
(insert "\n\n"))
|
2007-09-01 16:24:03 +00:00
|
|
|
|
(dolist (elt all-vars)
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(cond ((member elt unsafe-vars)
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(insert " * "))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
((member elt risky-vars)
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(insert " ** "))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(t
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(insert " ")))
|
|
|
|
|
(princ (car elt) buf)
|
|
|
|
|
(insert " : ")
|
2006-07-02 14:26:53 +00:00
|
|
|
|
;; Make strings with embedded whitespace easier to read.
|
|
|
|
|
(let ((print-escape-newlines t))
|
|
|
|
|
(prin1 (cdr elt) buf))
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(insert "\n"))
|
2006-03-10 23:22:30 +00:00
|
|
|
|
(setq prompt
|
|
|
|
|
(format "Please type %s%s: "
|
|
|
|
|
(if offer-save "y, n, or !" "y or n")
|
|
|
|
|
(if (< (line-number-at-pos) (window-body-height))
|
|
|
|
|
""
|
|
|
|
|
", or C-v to scroll")))
|
|
|
|
|
(goto-char (point-min))
|
2006-04-11 17:57:34 +00:00
|
|
|
|
(let ((cursor-in-echo-area t)
|
2007-01-27 19:27:53 +00:00
|
|
|
|
(executing-kbd-macro executing-kbd-macro)
|
2006-03-10 23:22:30 +00:00
|
|
|
|
(exit-chars
|
|
|
|
|
(if offer-save '(?! ?y ?n ?\s ?\C-g) '(?y ?n ?\s ?\C-g)))
|
2006-02-15 01:21:31 +00:00
|
|
|
|
done)
|
|
|
|
|
(while (not done)
|
2007-12-06 00:17:56 +00:00
|
|
|
|
(message "%s" prompt)
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(setq char (read-event))
|
|
|
|
|
(if (numberp char)
|
2007-01-27 19:27:53 +00:00
|
|
|
|
(cond ((eq char ?\C-v)
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(scroll-up)
|
|
|
|
|
(error (goto-char (point-min)))))
|
|
|
|
|
;; read-event returns -1 if we are in a kbd
|
|
|
|
|
;; macro and there are no more events in the
|
|
|
|
|
;; macro. In that case, attempt to get an
|
|
|
|
|
;; event interactively.
|
|
|
|
|
((and executing-kbd-macro (= char -1))
|
|
|
|
|
(setq executing-kbd-macro nil))
|
|
|
|
|
(t (setq done (memq (downcase char) exit-chars)))))))
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(setq char (downcase char))
|
2006-03-10 23:22:30 +00:00
|
|
|
|
(when (and offer-save (= char ?!) unsafe-vars)
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(dolist (elt unsafe-vars)
|
|
|
|
|
(add-to-list 'safe-local-variable-values elt))
|
2006-03-08 02:24:47 +00:00
|
|
|
|
;; When this is called from desktop-restore-file-buffer,
|
|
|
|
|
;; coding-system-for-read may be non-nil. Reset it before
|
|
|
|
|
;; writing to .emacs.
|
2006-03-10 23:22:30 +00:00
|
|
|
|
(if (or custom-file user-init-file)
|
|
|
|
|
(let ((coding-system-for-read nil))
|
|
|
|
|
(customize-save-variable
|
|
|
|
|
'safe-local-variable-values
|
|
|
|
|
safe-local-variable-values))))
|
2006-02-15 01:32:50 +00:00
|
|
|
|
(kill-buffer buf)
|
2006-02-15 01:21:31 +00:00
|
|
|
|
(or (= char ?!)
|
|
|
|
|
(= char ?\s)
|
|
|
|
|
(= char ?y)))))))
|
2005-05-10 09:08:28 +00:00
|
|
|
|
|
2003-04-03 23:00:22 +00:00
|
|
|
|
(defun hack-local-variables-prop-line (&optional mode-only)
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
"Return local variables specified in the -*- line.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
Ignore any specification for `mode:' and `coding:';
|
|
|
|
|
`set-auto-mode' should already have handled `mode:',
|
2003-04-03 23:00:22 +00:00
|
|
|
|
`set-auto-coding' should already have handled `coding:'.
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
|
|
|
|
|
If MODE-ONLY is non-nil, all we do is check whether the major
|
|
|
|
|
mode is specified, returning t if it is specified. Otherwise,
|
|
|
|
|
return an alist of elements (VAR . VAL), where VAR is a variable
|
|
|
|
|
and VAL is the specified value."
|
1992-10-12 04:45:53 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(let ((end (set-auto-mode-1))
|
|
|
|
|
result mode-specified)
|
2003-04-03 23:00:22 +00:00
|
|
|
|
;; Parse the -*- line into the RESULT alist.
|
|
|
|
|
;; Also set MODE-SPECIFIED if we see a spec or `mode'.
|
2001-12-12 00:10:17 +00:00
|
|
|
|
(cond ((not end)
|
1992-10-12 04:45:53 +00:00
|
|
|
|
nil)
|
|
|
|
|
((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)")
|
1994-03-29 07:08:23 +00:00
|
|
|
|
;; Simple form: "-*- MODENAME -*-". Already handled.
|
2003-04-03 23:00:22 +00:00
|
|
|
|
(setq mode-specified t)
|
1994-03-29 07:08:23 +00:00
|
|
|
|
nil)
|
1992-10-12 04:45:53 +00:00
|
|
|
|
(t
|
|
|
|
|
;; Hairy form: '-*-' [ <variable> ':' <value> ';' ]* '-*-'
|
|
|
|
|
;; (last ";" is optional).
|
|
|
|
|
(while (< (point) end)
|
|
|
|
|
(or (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*")
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(error "Malformed -*- line"))
|
1992-10-12 04:45:53 +00:00
|
|
|
|
(goto-char (match-end 0))
|
1995-06-05 12:30:11 +00:00
|
|
|
|
;; There used to be a downcase here,
|
|
|
|
|
;; but the manual didn't say so,
|
|
|
|
|
;; and people want to set var names that aren't all lc.
|
2006-07-02 14:26:53 +00:00
|
|
|
|
(let ((key (intern (match-string 1)))
|
1992-10-12 04:45:53 +00:00
|
|
|
|
(val (save-restriction
|
|
|
|
|
(narrow-to-region (point) end)
|
2009-04-29 03:02:54 +00:00
|
|
|
|
(let ((read-circle nil))
|
|
|
|
|
(read (current-buffer))))))
|
1996-10-13 14:00:48 +00:00
|
|
|
|
;; It is traditional to ignore
|
|
|
|
|
;; case when checking for `mode' in set-auto-mode,
|
|
|
|
|
;; so we must do that here as well.
|
|
|
|
|
;; That is inconsistent, but we're stuck with it.
|
1997-09-01 07:17:07 +00:00
|
|
|
|
;; The same can be said for `coding' in set-auto-coding.
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(or (and (equal (downcase (symbol-name key)) "mode")
|
|
|
|
|
(setq mode-specified t))
|
1997-09-01 07:17:07 +00:00
|
|
|
|
(equal (downcase (symbol-name key)) "coding")
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(condition-case nil
|
|
|
|
|
(push (cons (if (eq key 'eval)
|
|
|
|
|
'eval
|
|
|
|
|
(indirect-variable key))
|
|
|
|
|
val) result)
|
|
|
|
|
(error nil)))
|
|
|
|
|
(skip-chars-forward " \t;")))))
|
|
|
|
|
|
|
|
|
|
(if mode-only
|
|
|
|
|
mode-specified
|
|
|
|
|
result))))
|
1992-10-12 04:45:53 +00:00
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defun hack-local-variables-filter (variables dir-name)
|
2008-07-31 01:22:54 +00:00
|
|
|
|
"Filter local variable settings, querying the user if necessary.
|
|
|
|
|
VARIABLES is the alist of variable-value settings. This alist is
|
|
|
|
|
filtered based on the values of `ignored-local-variables',
|
|
|
|
|
`enable-local-eval', `enable-local-variables', and (if necessary)
|
|
|
|
|
user interaction. The results are added to
|
|
|
|
|
`file-local-variables-alist', without applying them.
|
2008-11-22 19:02:47 +00:00
|
|
|
|
DIR-NAME is a directory name if these settings come from
|
|
|
|
|
directory-local variables, or nil otherwise."
|
2009-07-19 01:05:17 +00:00
|
|
|
|
;; Find those variables that we may want to save to
|
|
|
|
|
;; `safe-local-variable-values'.
|
|
|
|
|
(let (all-vars risky-vars unsafe-vars)
|
|
|
|
|
(dolist (elt variables)
|
|
|
|
|
(let ((var (car elt))
|
|
|
|
|
(val (cdr elt)))
|
|
|
|
|
(cond ((memq var ignored-local-variables)
|
|
|
|
|
;; Ignore any variable in `ignored-local-variables'.
|
|
|
|
|
nil)
|
|
|
|
|
;; Obey `enable-local-eval'.
|
|
|
|
|
((eq var 'eval)
|
|
|
|
|
(when enable-local-eval
|
|
|
|
|
(push elt all-vars)
|
|
|
|
|
(or (eq enable-local-eval t)
|
|
|
|
|
(hack-one-local-variable-eval-safep (eval (quote val)))
|
2010-02-24 15:30:49 +00:00
|
|
|
|
(safe-local-variable-p var val)
|
2009-07-19 01:05:17 +00:00
|
|
|
|
(push elt unsafe-vars))))
|
2009-12-17 01:18:14 +00:00
|
|
|
|
;; Ignore duplicates (except `mode') in the present list.
|
|
|
|
|
((and (assq var all-vars) (not (eq var 'mode))) nil)
|
2009-07-19 01:05:17 +00:00
|
|
|
|
;; Accept known-safe variables.
|
|
|
|
|
((or (memq var '(mode unibyte coding))
|
|
|
|
|
(safe-local-variable-p var val))
|
|
|
|
|
(push elt all-vars))
|
|
|
|
|
;; The variable is either risky or unsafe:
|
|
|
|
|
((not (eq enable-local-variables :safe))
|
|
|
|
|
(push elt all-vars)
|
|
|
|
|
(if (risky-local-variable-p var val)
|
|
|
|
|
(push elt risky-vars)
|
|
|
|
|
(push elt unsafe-vars))))))
|
|
|
|
|
(and all-vars
|
|
|
|
|
;; Query, unless all vars are safe or user wants no querying.
|
|
|
|
|
(or (and (eq enable-local-variables t)
|
|
|
|
|
(null unsafe-vars)
|
|
|
|
|
(null risky-vars))
|
2009-07-20 14:21:27 +00:00
|
|
|
|
(memq enable-local-variables '(:all :safe))
|
2009-07-19 01:05:17 +00:00
|
|
|
|
(hack-local-variables-confirm all-vars unsafe-vars
|
|
|
|
|
risky-vars dir-name))
|
|
|
|
|
(dolist (elt all-vars)
|
2009-12-17 01:18:14 +00:00
|
|
|
|
(unless (memq (car elt) '(eval mode))
|
2009-07-19 16:55:16 +00:00
|
|
|
|
(unless dir-name
|
|
|
|
|
(setq dir-local-variables-alist
|
|
|
|
|
(assq-delete-all (car elt) dir-local-variables-alist)))
|
2009-07-19 01:05:17 +00:00
|
|
|
|
(setq file-local-variables-alist
|
|
|
|
|
(assq-delete-all (car elt) file-local-variables-alist)))
|
|
|
|
|
(push elt file-local-variables-alist)))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
1997-05-05 04:38:26 +00:00
|
|
|
|
(defun hack-local-variables (&optional mode-only)
|
|
|
|
|
"Parse and put into effect this buffer's local variables spec.
|
|
|
|
|
If MODE-ONLY is non-nil, all we do is check whether the major mode
|
|
|
|
|
is specified, returning t if it is specified."
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(let ((enable-local-variables
|
|
|
|
|
(and local-enable-local-variables enable-local-variables))
|
|
|
|
|
result)
|
2008-07-31 01:22:54 +00:00
|
|
|
|
(unless mode-only
|
|
|
|
|
(setq file-local-variables-alist nil)
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(report-errors "Directory-local variables error: %s"
|
|
|
|
|
(hack-dir-local-variables)))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(when (or mode-only enable-local-variables)
|
|
|
|
|
(setq result (hack-local-variables-prop-line mode-only))
|
|
|
|
|
;; Look for "Local variables:" line in last page.
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
|
|
|
|
|
'move)
|
|
|
|
|
(when (let ((case-fold-search t))
|
|
|
|
|
(search-forward "Local Variables:" nil t))
|
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
|
;; suffix is what comes after "local variables:" in its line.
|
|
|
|
|
;; prefix is what comes before "local variables:" in its line.
|
|
|
|
|
(let ((suffix
|
|
|
|
|
(concat
|
|
|
|
|
(regexp-quote (buffer-substring (point)
|
|
|
|
|
(line-end-position)))
|
|
|
|
|
"$"))
|
|
|
|
|
(prefix
|
|
|
|
|
(concat "^" (regexp-quote
|
|
|
|
|
(buffer-substring (line-beginning-position)
|
|
|
|
|
(match-beginning 0)))))
|
|
|
|
|
beg)
|
|
|
|
|
|
|
|
|
|
(forward-line 1)
|
|
|
|
|
(let ((startpos (point))
|
|
|
|
|
endpos
|
|
|
|
|
(thisbuf (current-buffer)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(unless (let ((case-fold-search t))
|
|
|
|
|
(re-search-forward
|
|
|
|
|
(concat prefix "[ \t]*End:[ \t]*" suffix)
|
|
|
|
|
nil t))
|
2008-05-28 20:23:06 +00:00
|
|
|
|
;; This used to be an error, but really all it means is
|
|
|
|
|
;; that this may simply not be a local-variables section,
|
|
|
|
|
;; so just ignore it.
|
|
|
|
|
(message "Local variables list is not properly terminated"))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(setq endpos (point)))
|
|
|
|
|
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(insert-buffer-substring thisbuf startpos endpos)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(subst-char-in-region (point) (point-max) ?\^m ?\n)
|
|
|
|
|
(while (not (eobp))
|
|
|
|
|
;; Discard the prefix.
|
|
|
|
|
(if (looking-at prefix)
|
|
|
|
|
(delete-region (point) (match-end 0))
|
|
|
|
|
(error "Local variables entry is missing the prefix"))
|
|
|
|
|
(end-of-line)
|
|
|
|
|
;; Discard the suffix.
|
|
|
|
|
(if (looking-back suffix)
|
|
|
|
|
(delete-region (match-beginning 0) (point))
|
|
|
|
|
(error "Local variables entry is missing the suffix"))
|
|
|
|
|
(forward-line 1))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
|
|
|
|
|
(while (not (eobp))
|
|
|
|
|
;; Find the variable name; strip whitespace.
|
|
|
|
|
(skip-chars-forward " \t")
|
|
|
|
|
(setq beg (point))
|
|
|
|
|
(skip-chars-forward "^:\n")
|
|
|
|
|
(if (eolp) (error "Missing colon in local variables entry"))
|
|
|
|
|
(skip-chars-backward " \t")
|
|
|
|
|
(let* ((str (buffer-substring beg (point)))
|
2009-04-29 03:02:54 +00:00
|
|
|
|
(var (let ((read-circle nil))
|
|
|
|
|
(read str)))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
val)
|
|
|
|
|
;; Read the variable value.
|
|
|
|
|
(skip-chars-forward "^:")
|
|
|
|
|
(forward-char 1)
|
2009-04-29 03:02:54 +00:00
|
|
|
|
(let ((read-circle nil))
|
|
|
|
|
(setq val (read (current-buffer))))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(if mode-only
|
|
|
|
|
(if (eq var 'mode)
|
|
|
|
|
(setq result t))
|
|
|
|
|
(unless (eq var 'coding)
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(push (cons (if (eq var 'eval)
|
|
|
|
|
'eval
|
|
|
|
|
(indirect-variable var))
|
|
|
|
|
val) result)
|
|
|
|
|
(error nil)))))
|
2008-07-31 01:22:54 +00:00
|
|
|
|
(forward-line 1))))))))
|
|
|
|
|
;; Now we've read all the local variables.
|
|
|
|
|
;; If MODE-ONLY is non-nil, return whether the mode was specified.
|
|
|
|
|
(cond (mode-only result)
|
|
|
|
|
;; Otherwise, set the variables.
|
|
|
|
|
(enable-local-variables
|
|
|
|
|
(hack-local-variables-filter result nil)
|
2010-03-12 08:04:54 +00:00
|
|
|
|
(hack-local-variables-apply)))))
|
|
|
|
|
|
|
|
|
|
(defun hack-local-variables-apply ()
|
|
|
|
|
(when file-local-variables-alist
|
|
|
|
|
;; Any 'evals must run in the Right sequence.
|
|
|
|
|
(setq file-local-variables-alist
|
|
|
|
|
(nreverse file-local-variables-alist))
|
|
|
|
|
(run-hooks 'before-hack-local-variables-hook)
|
|
|
|
|
(dolist (elt file-local-variables-alist)
|
|
|
|
|
(hack-one-local-variable (car elt) (cdr elt))))
|
|
|
|
|
(run-hooks 'hack-local-variables-hook))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
|
|
|
|
|
(defun safe-local-variable-p (sym val)
|
|
|
|
|
"Non-nil if SYM is safe as a file-local variable with value VAL.
|
|
|
|
|
It is safe if any of these conditions are met:
|
|
|
|
|
|
|
|
|
|
* There is a matching entry (SYM . VAL) in the
|
|
|
|
|
`safe-local-variable-values' user option.
|
|
|
|
|
|
|
|
|
|
* The `safe-local-variable' property of SYM is a function that
|
|
|
|
|
evaluates to a non-nil value with VAL as an argument."
|
|
|
|
|
(or (member (cons sym val) safe-local-variable-values)
|
|
|
|
|
(let ((safep (get sym 'safe-local-variable)))
|
2006-04-29 13:59:52 +00:00
|
|
|
|
(and (functionp safep) (funcall safep val)))))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
|
|
|
|
|
(defun risky-local-variable-p (sym &optional ignored)
|
|
|
|
|
"Non-nil if SYM could be dangerous as a file-local variable.
|
|
|
|
|
It is dangerous if either of these conditions are met:
|
|
|
|
|
|
|
|
|
|
* Its `risky-local-variable' property is non-nil.
|
|
|
|
|
|
|
|
|
|
* Its name ends with \"hook(s)\", \"function(s)\", \"form(s)\", \"map\",
|
|
|
|
|
\"program\", \"command(s)\", \"predicate(s)\", \"frame-alist\",
|
2006-09-08 11:58:46 +00:00
|
|
|
|
\"mode-alist\", \"font-lock-(syntactic-)keyword*\",
|
|
|
|
|
\"map-alist\", or \"bindat-spec\"."
|
2006-01-26 17:55:04 +00:00
|
|
|
|
;; If this is an alias, check the base name.
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(setq sym (indirect-variable sym))
|
|
|
|
|
(error nil))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
(or (get sym 'risky-local-variable)
|
|
|
|
|
(string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|\
|
|
|
|
|
-commands?$\\|-predicates?$\\|font-lock-keywords$\\|font-lock-keywords\
|
|
|
|
|
-[0-9]+$\\|font-lock-syntactic-keywords$\\|-frame-alist$\\|-mode-alist$\\|\
|
2006-09-08 11:58:46 +00:00
|
|
|
|
-map$\\|-map-alist$\\|-bindat-spec$" (symbol-name sym))))
|
2002-09-28 18:45:56 +00:00
|
|
|
|
|
1994-04-30 04:29:23 +00:00
|
|
|
|
(defun hack-one-local-variable-quotep (exp)
|
|
|
|
|
(and (consp exp) (eq (car exp) 'quote) (consp (cdr exp))))
|
|
|
|
|
|
2002-07-02 18:58:29 +00:00
|
|
|
|
(defun hack-one-local-variable-constantp (exp)
|
|
|
|
|
(or (and (not (symbolp exp)) (not (consp exp)))
|
|
|
|
|
(memq exp '(t nil))
|
|
|
|
|
(keywordp exp)
|
|
|
|
|
(hack-one-local-variable-quotep exp)))
|
|
|
|
|
|
|
|
|
|
(defun hack-one-local-variable-eval-safep (exp)
|
|
|
|
|
"Return t if it is safe to eval EXP when it is found in a file."
|
2002-07-07 09:21:52 +00:00
|
|
|
|
(or (not (consp exp))
|
|
|
|
|
;; Detect certain `put' expressions.
|
|
|
|
|
(and (eq (car exp) 'put)
|
|
|
|
|
(hack-one-local-variable-quotep (nth 1 exp))
|
|
|
|
|
(hack-one-local-variable-quotep (nth 2 exp))
|
2008-08-05 20:46:42 +00:00
|
|
|
|
(let ((prop (nth 1 (nth 2 exp)))
|
|
|
|
|
(val (nth 3 exp)))
|
|
|
|
|
(cond ((memq prop '(lisp-indent-hook
|
|
|
|
|
lisp-indent-function
|
|
|
|
|
scheme-indent-function))
|
|
|
|
|
;; Only allow safe values (not functions).
|
|
|
|
|
(or (numberp val)
|
|
|
|
|
(and (hack-one-local-variable-quotep val)
|
|
|
|
|
(eq (nth 1 val) 'defun))))
|
2006-04-13 10:54:38 +00:00
|
|
|
|
((eq prop 'edebug-form-spec)
|
|
|
|
|
;; Only allow indirect form specs.
|
2006-05-29 05:47:29 +00:00
|
|
|
|
;; During bootstrapping, edebug-basic-spec might not be
|
|
|
|
|
;; defined yet.
|
|
|
|
|
(and (fboundp 'edebug-basic-spec)
|
2007-02-25 09:24:29 +00:00
|
|
|
|
(hack-one-local-variable-quotep val)
|
|
|
|
|
(edebug-basic-spec (nth 1 val)))))))
|
2002-07-07 09:21:52 +00:00
|
|
|
|
;; Allow expressions that the user requested.
|
|
|
|
|
(member exp safe-local-eval-forms)
|
|
|
|
|
;; Certain functions can be allowed with safe arguments
|
|
|
|
|
;; or can specify verification functions to try.
|
|
|
|
|
(and (symbolp (car exp))
|
|
|
|
|
(let ((prop (get (car exp) 'safe-local-eval-function)))
|
|
|
|
|
(cond ((eq prop t)
|
|
|
|
|
(let ((ok t))
|
|
|
|
|
(dolist (arg (cdr exp))
|
|
|
|
|
(unless (hack-one-local-variable-constantp arg)
|
|
|
|
|
(setq ok nil)))
|
|
|
|
|
ok))
|
|
|
|
|
((functionp prop)
|
|
|
|
|
(funcall prop exp))
|
|
|
|
|
((listp prop)
|
|
|
|
|
(let ((ok nil))
|
|
|
|
|
(dolist (function prop)
|
|
|
|
|
(if (funcall function exp)
|
|
|
|
|
(setq ok t)))
|
|
|
|
|
ok)))))))
|
2002-07-02 18:58:29 +00:00
|
|
|
|
|
1992-10-12 04:45:53 +00:00
|
|
|
|
(defun hack-one-local-variable (var val)
|
2007-03-01 17:06:40 +00:00
|
|
|
|
"Set local variable VAR with value VAL.
|
|
|
|
|
If VAR is `mode', call `VAL-mode' as a function unless it's
|
|
|
|
|
already the major mode."
|
1992-10-12 04:45:53 +00:00
|
|
|
|
(cond ((eq var 'mode)
|
2007-03-01 17:06:40 +00:00
|
|
|
|
(let ((mode (intern (concat (downcase (symbol-name val))
|
|
|
|
|
"-mode"))))
|
|
|
|
|
(unless (eq (indirect-function mode)
|
|
|
|
|
(indirect-function major-mode))
|
2009-08-17 23:40:19 +00:00
|
|
|
|
(if (memq mode minor-mode-list)
|
|
|
|
|
;; A minor mode must be passed an argument.
|
|
|
|
|
;; Otherwise, if the user enables the minor mode in a
|
|
|
|
|
;; major mode hook, this would toggle it off.
|
|
|
|
|
(funcall mode 1)
|
|
|
|
|
(funcall mode)))))
|
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
2006-02-14 01:21:31 +00:00
|
|
|
|
((eq var 'eval)
|
|
|
|
|
(save-excursion (eval val)))
|
2006-07-02 14:26:53 +00:00
|
|
|
|
(t
|
|
|
|
|
;; Make sure the string has no text properties.
|
|
|
|
|
;; Some text properties can get evaluated in various ways,
|
|
|
|
|
;; so it is risky to put them on with a local variable list.
|
|
|
|
|
(if (stringp val)
|
|
|
|
|
(set-text-properties 0 (length val) nil val))
|
|
|
|
|
(set (make-local-variable var) val))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
;;; Handling directory-local variables, aka project settings.
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defvar dir-locals-class-alist '()
|
2009-04-11 15:26:26 +00:00
|
|
|
|
"Alist mapping directory-local variable classes (symbols) to variable lists.")
|
|
|
|
|
|
|
|
|
|
(defvar dir-locals-directory-cache '()
|
|
|
|
|
"List of cached directory roots for directory-local variable classes.
|
|
|
|
|
Each element in this list has the form (DIR CLASS MTIME).
|
|
|
|
|
DIR is the name of the directory.
|
|
|
|
|
CLASS is the name of a variable class (a symbol).
|
|
|
|
|
MTIME is the recorded modification time of the directory-local
|
|
|
|
|
variables file associated with this entry. This time is a list
|
|
|
|
|
of two integers (the same format as `file-attributes'), and is
|
|
|
|
|
used to test whether the cache entry is still valid.
|
|
|
|
|
Alternatively, MTIME can be nil, which means the entry is always
|
|
|
|
|
considered valid.")
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defsubst dir-locals-get-class-variables (class)
|
|
|
|
|
"Return the variable list for CLASS."
|
|
|
|
|
(cdr (assq class dir-locals-class-alist)))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defun dir-locals-collect-mode-variables (mode-variables variables)
|
|
|
|
|
"Collect directory-local variables from MODE-VARIABLES.
|
|
|
|
|
VARIABLES is the initial list of variables.
|
2008-05-19 22:36:09 +00:00
|
|
|
|
Returns the new list."
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(dolist (pair mode-variables variables)
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(let* ((variable (car pair))
|
|
|
|
|
(value (cdr pair))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(slot (assq variable variables)))
|
2009-06-22 07:02:04 +00:00
|
|
|
|
;; If variables are specified more than once, only use the last. (Why?)
|
|
|
|
|
;; The pseudo-variables mode and eval are different (bug#3430).
|
|
|
|
|
(if (and slot (not (memq variable '(mode eval))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(setcdr slot value)
|
|
|
|
|
;; Need a new cons in case we setcdr later.
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(push (cons variable value) variables)))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defun dir-locals-collect-variables (class-variables root variables)
|
|
|
|
|
"Collect entries from CLASS-VARIABLES into VARIABLES.
|
2008-05-19 22:36:09 +00:00
|
|
|
|
ROOT is the root directory of the project.
|
2008-11-22 19:02:47 +00:00
|
|
|
|
Return the new variables list."
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(let* ((file-name (buffer-file-name))
|
|
|
|
|
(sub-file-name (if file-name
|
|
|
|
|
(substring file-name (length root)))))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(dolist (entry class-variables variables)
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(let ((key (car entry)))
|
|
|
|
|
(cond
|
|
|
|
|
((stringp key)
|
|
|
|
|
;; Don't include this in the previous condition, because we
|
|
|
|
|
;; want to filter all strings before the next condition.
|
|
|
|
|
(when (and sub-file-name
|
|
|
|
|
(>= (length sub-file-name) (length key))
|
|
|
|
|
(string= key (substring sub-file-name 0 (length key))))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(setq variables (dir-locals-collect-variables
|
|
|
|
|
(cdr entry) root variables))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
((or (not key)
|
|
|
|
|
(derived-mode-p key))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(setq variables (dir-locals-collect-mode-variables
|
|
|
|
|
(cdr entry) variables))))))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
2009-06-18 06:54:47 +00:00
|
|
|
|
(defun dir-locals-set-directory-class (directory class &optional mtime)
|
2008-11-22 19:02:47 +00:00
|
|
|
|
"Declare that the DIRECTORY root is an instance of CLASS.
|
2008-05-19 22:36:09 +00:00
|
|
|
|
DIRECTORY is the name of a directory, a string.
|
|
|
|
|
CLASS is the name of a project class, a symbol.
|
2009-04-11 15:26:26 +00:00
|
|
|
|
MTIME is either the modification time of the directory-local
|
2009-06-17 02:54:49 +00:00
|
|
|
|
variables file that defined this class, or nil.
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
|
|
|
|
When a file beneath DIRECTORY is visited, the mode-specific
|
2009-04-11 15:26:26 +00:00
|
|
|
|
variables from CLASS are applied to the buffer. The variables
|
2008-11-22 19:02:47 +00:00
|
|
|
|
for a class are defined using `dir-locals-set-class-variables'."
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(setq directory (file-name-as-directory (expand-file-name directory)))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(unless (assq class dir-locals-class-alist)
|
|
|
|
|
(error "No such class `%s'" (symbol-name class)))
|
2009-04-11 15:26:26 +00:00
|
|
|
|
(push (list directory class mtime) dir-locals-directory-cache))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
|
|
|
|
|
(defun dir-locals-set-class-variables (class variables)
|
|
|
|
|
"Map the type CLASS to a list of variable settings.
|
|
|
|
|
CLASS is the project class, a symbol. VARIABLES is a list
|
|
|
|
|
that declares directory-local variables for the class.
|
|
|
|
|
An element in VARIABLES is either of the form:
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(MAJOR-MODE . ALIST)
|
|
|
|
|
or
|
|
|
|
|
(DIRECTORY . LIST)
|
|
|
|
|
|
|
|
|
|
In the first form, MAJOR-MODE is a symbol, and ALIST is an alist
|
|
|
|
|
whose elements are of the form (VARIABLE . VALUE).
|
|
|
|
|
|
|
|
|
|
In the second form, DIRECTORY is a directory name (a string), and
|
|
|
|
|
LIST is a list of the form accepted by the function.
|
|
|
|
|
|
|
|
|
|
When a file is visited, the file's class is found. A directory
|
2008-11-22 19:02:47 +00:00
|
|
|
|
may be assigned a class using `dir-locals-set-directory-class'.
|
|
|
|
|
Then variables are set in the file's buffer according to the
|
|
|
|
|
class' LIST. The list is processed in order.
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
|
|
|
|
* If the element is of the form (MAJOR-MODE . ALIST), and the
|
|
|
|
|
buffer's major mode is derived from MAJOR-MODE (as determined
|
2008-11-22 19:02:47 +00:00
|
|
|
|
by `derived-mode-p'), then all the variables in ALIST are
|
2008-05-19 22:36:09 +00:00
|
|
|
|
applied. A MAJOR-MODE of nil may be used to match any buffer.
|
|
|
|
|
`make-local-variable' is called for each variable before it is
|
|
|
|
|
set.
|
|
|
|
|
|
|
|
|
|
* If the element is of the form (DIRECTORY . LIST), and DIRECTORY
|
|
|
|
|
is an initial substring of the file's directory, then LIST is
|
|
|
|
|
applied by recursively following these rules."
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(let ((elt (assq class dir-locals-class-alist)))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(if elt
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(setcdr elt variables)
|
|
|
|
|
(push (cons class variables) dir-locals-class-alist))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defconst dir-locals-file ".dir-locals.el"
|
|
|
|
|
"File that contains directory-local variables.
|
|
|
|
|
It has to be constant to enforce uniform values
|
|
|
|
|
across different environments and users.")
|
|
|
|
|
|
|
|
|
|
(defun dir-locals-find-file (file)
|
2009-04-11 15:26:26 +00:00
|
|
|
|
"Find the directory-local variables for FILE.
|
|
|
|
|
This searches upward in the directory tree from FILE.
|
|
|
|
|
If the directory root of FILE has been registered in
|
|
|
|
|
`dir-locals-directory-cache' and the directory-local variables
|
|
|
|
|
file has not been modified, return the matching entry in
|
|
|
|
|
`dir-locals-directory-cache'.
|
|
|
|
|
Otherwise, if a directory-local variables file is found, return
|
|
|
|
|
the file name.
|
|
|
|
|
Otherwise, return nil."
|
2008-11-19 13:25:43 +00:00
|
|
|
|
(setq file (expand-file-name file))
|
2008-12-26 15:01:10 +00:00
|
|
|
|
(let* ((dir-locals-file-name
|
|
|
|
|
(if (eq system-type 'ms-dos)
|
|
|
|
|
(dosified-file-name dir-locals-file)
|
|
|
|
|
dir-locals-file))
|
|
|
|
|
(locals-file (locate-dominating-file file dir-locals-file-name))
|
|
|
|
|
(dir-elt nil))
|
2008-11-19 13:25:43 +00:00
|
|
|
|
;; `locate-dominating-file' may have abbreviated the name.
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(when locals-file
|
2008-12-26 15:01:10 +00:00
|
|
|
|
(setq locals-file (expand-file-name dir-locals-file-name locals-file)))
|
2009-04-11 15:26:26 +00:00
|
|
|
|
;; Find the best cached value in `dir-locals-directory-cache'.
|
|
|
|
|
(dolist (elt dir-locals-directory-cache)
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(when (and (eq t (compare-strings file nil (length (car elt))
|
2008-12-26 15:01:10 +00:00
|
|
|
|
(car elt) nil nil
|
|
|
|
|
(memq system-type
|
|
|
|
|
'(windows-nt cygwin ms-dos))))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(> (length (car elt)) (length (car dir-elt))))
|
|
|
|
|
(setq dir-elt elt)))
|
2009-04-11 15:26:26 +00:00
|
|
|
|
(let ((use-cache (and dir-elt
|
|
|
|
|
(or (null locals-file)
|
|
|
|
|
(<= (length (file-name-directory locals-file))
|
|
|
|
|
(length (car dir-elt)))))))
|
|
|
|
|
(if use-cache
|
|
|
|
|
;; Check the validity of the cache.
|
|
|
|
|
(if (and (file-readable-p (car dir-elt))
|
|
|
|
|
(or (null (nth 2 dir-elt))
|
|
|
|
|
(equal (nth 2 dir-elt)
|
|
|
|
|
(nth 5 (file-attributes (car dir-elt))))))
|
|
|
|
|
;; This cache entry is OK.
|
|
|
|
|
dir-elt
|
|
|
|
|
;; This cache entry is invalid; clear it.
|
|
|
|
|
(setq dir-locals-directory-cache
|
|
|
|
|
(delq dir-elt dir-locals-directory-cache))
|
|
|
|
|
locals-file)
|
|
|
|
|
locals-file))))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
|
|
|
|
|
(defun dir-locals-read-from-file (file)
|
|
|
|
|
"Load a variables FILE and register a new class and instance.
|
|
|
|
|
FILE is the name of the file holding the variables to apply.
|
|
|
|
|
The new class name is the same as the directory in which FILE
|
2008-05-19 22:36:09 +00:00
|
|
|
|
is found. Returns the new class name."
|
|
|
|
|
(with-temp-buffer
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(insert-file-contents file)
|
|
|
|
|
(let* ((dir-name (file-name-directory file))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(class-name (intern dir-name))
|
2009-04-29 03:02:54 +00:00
|
|
|
|
(variables (let ((read-circle nil))
|
|
|
|
|
(read (current-buffer)))))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(dir-locals-set-class-variables class-name variables)
|
2009-04-11 15:26:26 +00:00
|
|
|
|
(dir-locals-set-directory-class dir-name class-name
|
|
|
|
|
(nth 5 (file-attributes file)))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
class-name)))
|
|
|
|
|
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(defun hack-dir-local-variables ()
|
|
|
|
|
"Read per-directory local variables for the current buffer.
|
2009-07-19 16:55:16 +00:00
|
|
|
|
Store the directory-local variables in `dir-local-variables-alist'
|
|
|
|
|
and `file-local-variables-alist', without applying them."
|
2008-07-31 01:22:54 +00:00
|
|
|
|
(when (and enable-local-variables
|
2010-03-12 08:04:54 +00:00
|
|
|
|
(not (file-remote-p (or (buffer-file-name) default-directory))))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
;; Find the variables file.
|
2010-03-12 08:04:54 +00:00
|
|
|
|
(let ((variables-file (dir-locals-find-file (or (buffer-file-name) default-directory)))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(class nil)
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(dir-name nil))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(cond
|
2008-11-22 19:02:47 +00:00
|
|
|
|
((stringp variables-file)
|
2010-03-12 08:04:54 +00:00
|
|
|
|
(setq dir-name (if (buffer-file-name) (file-name-directory (buffer-file-name)) default-directory))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(setq class (dir-locals-read-from-file variables-file)))
|
|
|
|
|
((consp variables-file)
|
2009-04-11 15:26:26 +00:00
|
|
|
|
(setq dir-name (nth 0 variables-file))
|
|
|
|
|
(setq class (nth 1 variables-file))))
|
2008-05-19 22:36:09 +00:00
|
|
|
|
(when class
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(let ((variables
|
|
|
|
|
(dir-locals-collect-variables
|
|
|
|
|
(dir-locals-get-class-variables class) dir-name nil)))
|
|
|
|
|
(when variables
|
2009-07-19 16:55:16 +00:00
|
|
|
|
(dolist (elt variables)
|
2009-12-17 01:18:14 +00:00
|
|
|
|
(unless (memq (car elt) '(eval mode))
|
2009-07-19 16:55:16 +00:00
|
|
|
|
(setq dir-local-variables-alist
|
|
|
|
|
(assq-delete-all (car elt) dir-local-variables-alist)))
|
|
|
|
|
(push elt dir-local-variables-alist))
|
2008-11-22 19:02:47 +00:00
|
|
|
|
(hack-local-variables-filter variables dir-name)))))))
|
1992-10-12 04:45:53 +00:00
|
|
|
|
|
2010-03-12 08:04:54 +00:00
|
|
|
|
(defun hack-dir-local-variables-non-file-buffer ()
|
|
|
|
|
(hack-dir-local-variables)
|
|
|
|
|
(hack-local-variables-apply))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom change-major-mode-with-file-name t
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Non-nil means \\[write-file] should set the major mode from the file name.
|
1997-05-05 04:38:26 +00:00
|
|
|
|
However, the mode will not be changed if
|
|
|
|
|
\(1) a local variables list or the `-*-' line specifies a major mode, or
|
|
|
|
|
\(2) the current major mode is a \"special\" mode,
|
2007-02-11 02:28:57 +00:00
|
|
|
|
\ not suitable for ordinary files, or
|
1997-05-05 22:04:00 +00:00
|
|
|
|
\(3) the new file name does not particularly specify any mode."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'editing-basics)
|
1997-05-05 04:38:26 +00:00
|
|
|
|
|
1997-02-03 09:42:56 +00:00
|
|
|
|
(defun set-visited-file-name (filename &optional no-query along-with-file)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Change name of file visited in current buffer to FILENAME.
|
2005-12-27 22:54:13 +00:00
|
|
|
|
This also renames the buffer to correspond to the new file.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
The next time the buffer is saved it will go in the newly specified file.
|
2005-12-27 22:54:13 +00:00
|
|
|
|
FILENAME nil or an empty string means mark buffer as not visiting any file.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
Remember to delete the initial contents of the minibuffer
|
1996-06-29 19:50:56 +00:00
|
|
|
|
if you wish to pass an empty string as the argument.
|
|
|
|
|
|
|
|
|
|
The optional second argument NO-QUERY, if non-nil, inhibits asking for
|
1997-02-03 09:42:56 +00:00
|
|
|
|
confirmation in the case where another buffer is already visiting FILENAME.
|
|
|
|
|
|
|
|
|
|
The optional third argument ALONG-WITH-FILE, if non-nil, means that
|
|
|
|
|
the old visited file has been renamed to the new name FILENAME."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive "FSet visited file name: ")
|
1994-12-31 07:49:59 +00:00
|
|
|
|
(if (buffer-base-buffer)
|
|
|
|
|
(error "An indirect buffer cannot visit a file"))
|
1994-07-05 07:23:18 +00:00
|
|
|
|
(let (truename)
|
|
|
|
|
(if filename
|
|
|
|
|
(setq filename
|
|
|
|
|
(if (string-equal filename "")
|
|
|
|
|
nil
|
|
|
|
|
(expand-file-name filename))))
|
|
|
|
|
(if filename
|
|
|
|
|
(progn
|
|
|
|
|
(setq truename (file-truename filename))
|
|
|
|
|
(if find-file-visit-truename
|
|
|
|
|
(setq filename truename))))
|
2005-07-08 22:53:47 +00:00
|
|
|
|
(if filename
|
2005-07-10 14:42:02 +00:00
|
|
|
|
(let ((new-name (file-name-nondirectory filename)))
|
2005-07-08 22:53:47 +00:00
|
|
|
|
(if (string= new-name "")
|
|
|
|
|
(error "Empty file name"))))
|
1996-03-26 23:57:49 +00:00
|
|
|
|
(let ((buffer (and filename (find-buffer-visiting filename))))
|
1996-03-01 20:29:32 +00:00
|
|
|
|
(and buffer (not (eq buffer (current-buffer)))
|
1996-06-29 19:50:56 +00:00
|
|
|
|
(not no-query)
|
2006-11-13 10:24:55 +00:00
|
|
|
|
(not (y-or-n-p (format "A buffer is visiting %s; proceed? "
|
|
|
|
|
filename)))
|
1996-03-01 20:29:32 +00:00
|
|
|
|
(error "Aborted")))
|
1994-07-05 07:23:18 +00:00
|
|
|
|
(or (equal filename buffer-file-name)
|
|
|
|
|
(progn
|
|
|
|
|
(and filename (lock-buffer filename))
|
|
|
|
|
(unlock-buffer)))
|
|
|
|
|
(setq buffer-file-name filename)
|
|
|
|
|
(if filename ; make buffer name reflect filename.
|
|
|
|
|
(let ((new-name (file-name-nondirectory buffer-file-name)))
|
|
|
|
|
(setq default-directory (file-name-directory buffer-file-name))
|
2003-05-13 18:39:39 +00:00
|
|
|
|
;; If new-name == old-name, renaming would add a spurious <2>
|
|
|
|
|
;; and it's considered as a feature in rename-buffer.
|
1994-07-05 07:23:18 +00:00
|
|
|
|
(or (string= new-name (buffer-name))
|
|
|
|
|
(rename-buffer new-name t))))
|
|
|
|
|
(setq buffer-backed-up nil)
|
1997-02-03 09:42:56 +00:00
|
|
|
|
(or along-with-file
|
|
|
|
|
(clear-visited-file-modtime))
|
1995-10-24 22:14:39 +00:00
|
|
|
|
;; Abbreviate the file names of the buffer.
|
1994-07-05 22:36:54 +00:00
|
|
|
|
(if truename
|
1995-10-24 22:14:39 +00:00
|
|
|
|
(progn
|
|
|
|
|
(setq buffer-file-truename (abbreviate-file-name truename))
|
|
|
|
|
(if find-file-visit-truename
|
2003-07-27 19:54:09 +00:00
|
|
|
|
(setq buffer-file-name truename))))
|
1994-07-05 07:23:18 +00:00
|
|
|
|
(setq buffer-file-number
|
|
|
|
|
(if filename
|
1995-10-29 20:23:42 +00:00
|
|
|
|
(nthcdr 10 (file-attributes buffer-file-name))
|
1994-07-05 07:23:18 +00:00
|
|
|
|
nil)))
|
2002-06-23 21:16:38 +00:00
|
|
|
|
;; write-file-functions is normally used for things like ftp-find-file
|
1991-07-19 14:42:53 +00:00
|
|
|
|
;; that visit things that are not local files as if they were files.
|
|
|
|
|
;; Changing to visit an ordinary local file instead should flush the hook.
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(kill-local-variable 'write-file-functions)
|
1993-03-26 07:28:20 +00:00
|
|
|
|
(kill-local-variable 'local-write-file-hooks)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(kill-local-variable 'revert-buffer-function)
|
|
|
|
|
(kill-local-variable 'backup-inhibited)
|
1994-03-27 19:49:47 +00:00
|
|
|
|
;; If buffer was read-only because of version control,
|
|
|
|
|
;; that reason is gone now, so make it writable.
|
|
|
|
|
(if vc-mode
|
|
|
|
|
(setq buffer-read-only nil))
|
|
|
|
|
(kill-local-variable 'vc-mode)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
;; Turn off backup files for certain file names.
|
|
|
|
|
;; Since this is a permanent local, the major mode won't eliminate it.
|
1998-02-27 22:13:26 +00:00
|
|
|
|
(and buffer-file-name
|
2007-01-04 22:14:32 +00:00
|
|
|
|
backup-enable-predicate
|
1998-02-27 22:13:26 +00:00
|
|
|
|
(not (funcall backup-enable-predicate buffer-file-name))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(progn
|
|
|
|
|
(make-local-variable 'backup-inhibited)
|
|
|
|
|
(setq backup-inhibited t)))
|
1993-07-01 18:39:58 +00:00
|
|
|
|
(let ((oauto buffer-auto-save-file-name))
|
|
|
|
|
;; If auto-save was not already on, turn it on if appropriate.
|
|
|
|
|
(if (not buffer-auto-save-file-name)
|
|
|
|
|
(and buffer-file-name auto-save-default
|
|
|
|
|
(auto-save-mode t))
|
|
|
|
|
;; If auto save is on, start using a new name.
|
|
|
|
|
;; We deliberately don't rename or delete the old auto save
|
|
|
|
|
;; for the old visited file name. This is because perhaps
|
|
|
|
|
;; the user wants to save the new state and then compare with the
|
|
|
|
|
;; previous state from the auto save file.
|
|
|
|
|
(setq buffer-auto-save-file-name
|
|
|
|
|
(make-auto-save-file-name)))
|
|
|
|
|
;; Rename the old auto save file if any.
|
|
|
|
|
(and oauto buffer-auto-save-file-name
|
1993-07-01 20:33:56 +00:00
|
|
|
|
(file-exists-p oauto)
|
1993-07-01 18:39:58 +00:00
|
|
|
|
(rename-file oauto buffer-auto-save-file-name t)))
|
1997-02-03 09:42:56 +00:00
|
|
|
|
(and buffer-file-name
|
|
|
|
|
(not along-with-file)
|
1997-05-05 04:38:26 +00:00
|
|
|
|
(set-buffer-modified-p t))
|
|
|
|
|
;; Update the major mode, if the file name determines it.
|
|
|
|
|
(condition-case nil
|
|
|
|
|
;; Don't change the mode if it is special.
|
|
|
|
|
(or (not change-major-mode-with-file-name)
|
|
|
|
|
(get major-mode 'mode-class)
|
|
|
|
|
;; Don't change the mode if the local variable list specifies it.
|
|
|
|
|
(hack-local-variables t)
|
|
|
|
|
(set-auto-mode t))
|
|
|
|
|
(error nil)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-28 03:35:36 +00:00
|
|
|
|
(defun write-file (filename &optional confirm)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Write current buffer into file FILENAME.
|
1999-06-12 03:57:37 +00:00
|
|
|
|
This makes the buffer visit that file, and marks it as not modified.
|
1996-02-02 18:47:34 +00:00
|
|
|
|
|
1999-06-12 03:57:37 +00:00
|
|
|
|
If you specify just a directory name as FILENAME, that means to use
|
|
|
|
|
the default file name but in that directory. You can also yank
|
2004-01-14 14:20:45 +00:00
|
|
|
|
the default file name into the minibuffer to edit it, using \\<minibuffer-local-map>\\[next-history-element].
|
1999-06-12 03:57:37 +00:00
|
|
|
|
|
|
|
|
|
If the buffer is not already visiting a file, the default file name
|
|
|
|
|
for the output file is the buffer name.
|
|
|
|
|
|
|
|
|
|
If optional second arg CONFIRM is non-nil, this function
|
|
|
|
|
asks for confirmation before overwriting an existing file.
|
1997-05-28 03:35:36 +00:00
|
|
|
|
Interactively, confirmation is required unless you supply a prefix argument."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
;; (interactive "FWrite file: ")
|
|
|
|
|
(interactive
|
|
|
|
|
(list (if buffer-file-name
|
|
|
|
|
(read-file-name "Write file: "
|
2006-12-11 04:40:41 +00:00
|
|
|
|
nil nil nil nil)
|
1999-06-12 03:57:37 +00:00
|
|
|
|
(read-file-name "Write file: " default-directory
|
|
|
|
|
(expand-file-name
|
|
|
|
|
(file-name-nondirectory (buffer-name))
|
|
|
|
|
default-directory)
|
|
|
|
|
nil nil))
|
1997-05-28 03:35:36 +00:00
|
|
|
|
(not current-prefix-arg)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(or (null filename) (string-equal filename "")
|
1993-03-03 05:12:05 +00:00
|
|
|
|
(progn
|
|
|
|
|
;; If arg is just a directory,
|
1999-06-12 03:57:37 +00:00
|
|
|
|
;; use the default file name, but in that directory.
|
|
|
|
|
(if (file-directory-p filename)
|
1993-03-03 05:12:05 +00:00
|
|
|
|
(setq filename (concat (file-name-as-directory filename)
|
1999-06-12 03:57:37 +00:00
|
|
|
|
(file-name-nondirectory
|
|
|
|
|
(or buffer-file-name (buffer-name))))))
|
1995-04-10 04:49:13 +00:00
|
|
|
|
(and confirm
|
|
|
|
|
(file-exists-p filename)
|
|
|
|
|
(or (y-or-n-p (format "File `%s' exists; overwrite? " filename))
|
|
|
|
|
(error "Canceled")))
|
1996-10-26 18:12:01 +00:00
|
|
|
|
(set-visited-file-name filename (not confirm))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(set-buffer-modified-p t)
|
1997-11-20 22:00:57 +00:00
|
|
|
|
;; Make buffer writable if file is writable.
|
|
|
|
|
(and buffer-file-name
|
|
|
|
|
(file-writable-p buffer-file-name)
|
|
|
|
|
(setq buffer-read-only nil))
|
2005-11-14 22:19:28 +00:00
|
|
|
|
(save-buffer)
|
|
|
|
|
;; It's likely that the VC status at the new location is different from
|
|
|
|
|
;; the one at the old location.
|
|
|
|
|
(vc-find-file-hook))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun backup-buffer ()
|
|
|
|
|
"Make a backup of the disk file visited by the current buffer, if appropriate.
|
|
|
|
|
This is normally done before saving the buffer the first time.
|
1996-12-06 23:29:47 +00:00
|
|
|
|
|
|
|
|
|
A backup may be done by renaming or by copying; see documentation of
|
|
|
|
|
variable `make-backup-files'. If it's done by renaming, then the file is
|
2002-07-23 19:23:08 +00:00
|
|
|
|
no longer accessible under its old name.
|
|
|
|
|
|
|
|
|
|
The value is non-nil after a backup was made by renaming.
|
2010-04-21 03:02:58 +00:00
|
|
|
|
It has the form (MODES SELINUXCONTEXT BACKUPNAME).
|
2002-07-23 19:23:08 +00:00
|
|
|
|
MODES is the result of `file-modes' on the original
|
|
|
|
|
file; this means that the caller, after saving the buffer, should change
|
|
|
|
|
the modes of the new file to agree with the old modes.
|
2010-04-21 03:02:58 +00:00
|
|
|
|
SELINUXCONTEXT is the result of `file-selinux-context' on the original
|
|
|
|
|
file; this means that the caller, after saving the buffer, should change
|
|
|
|
|
the SELinux context of the new file to agree with the old context.
|
2002-07-23 19:23:08 +00:00
|
|
|
|
BACKUPNAME is the backup file name, which is the old file renamed."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(if (and make-backup-files (not backup-inhibited)
|
|
|
|
|
(not buffer-backed-up)
|
|
|
|
|
(file-exists-p buffer-file-name)
|
|
|
|
|
(memq (aref (elt (file-attributes buffer-file-name) 8) 0)
|
|
|
|
|
'(?- ?l)))
|
|
|
|
|
(let ((real-file-name buffer-file-name)
|
|
|
|
|
backup-info backupname targets setmodes)
|
|
|
|
|
;; If specified name is a symbolic link, chase it to the target.
|
|
|
|
|
;; Thus we make the backups in the directory where the real file is.
|
1993-05-29 20:00:45 +00:00
|
|
|
|
(setq real-file-name (file-chase-links real-file-name))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(setq backup-info (find-backup-file-name real-file-name)
|
|
|
|
|
backupname (car backup-info)
|
|
|
|
|
targets (cdr backup-info))
|
2001-05-11 20:22:46 +00:00
|
|
|
|
;; (if (file-directory-p buffer-file-name)
|
|
|
|
|
;; (error "Cannot save buffer in directory %s" buffer-file-name))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(if backup-info
|
|
|
|
|
(condition-case ()
|
|
|
|
|
(let ((delete-old-versions
|
|
|
|
|
;; If have old versions to maybe delete,
|
|
|
|
|
;; ask the user to confirm now, before doing anything.
|
|
|
|
|
;; But don't actually delete til later.
|
|
|
|
|
(and targets
|
|
|
|
|
(or (eq delete-old-versions t) (eq delete-old-versions nil))
|
|
|
|
|
(or delete-old-versions
|
|
|
|
|
(y-or-n-p (format "Delete excess backup versions of %s? "
|
2002-09-26 22:00:22 +00:00
|
|
|
|
real-file-name)))))
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(modes (file-modes buffer-file-name))
|
|
|
|
|
(context (file-selinux-context buffer-file-name)))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
;; Actually write the back up file.
|
|
|
|
|
(condition-case ()
|
|
|
|
|
(if (or file-precious-flag
|
2000-10-04 17:16:59 +00:00
|
|
|
|
; (file-symlink-p buffer-file-name)
|
1995-01-12 21:05:07 +00:00
|
|
|
|
backup-by-copying
|
2002-09-26 22:00:22 +00:00
|
|
|
|
;; Don't rename a suid or sgid file.
|
2003-01-01 16:55:11 +00:00
|
|
|
|
(and modes (< 0 (logand modes #o6000)))
|
2005-03-19 13:30:10 +00:00
|
|
|
|
(not (file-writable-p (file-name-directory real-file-name)))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(and backup-by-copying-when-linked
|
|
|
|
|
(> (file-nlinks real-file-name) 1))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(and (or backup-by-copying-when-mismatch
|
|
|
|
|
(integerp backup-by-copying-when-privileged-mismatch))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(let ((attr (file-attributes real-file-name)))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(and (or backup-by-copying-when-mismatch
|
|
|
|
|
(and (integerp (nth 2 attr))
|
|
|
|
|
(integerp backup-by-copying-when-privileged-mismatch)
|
|
|
|
|
(<= (nth 2 attr) backup-by-copying-when-privileged-mismatch)))
|
|
|
|
|
(or (nth 9 attr)
|
|
|
|
|
(not (file-ownership-preserved-p real-file-name)))))))
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(backup-buffer-copy real-file-name backupname modes context)
|
1995-01-12 21:05:07 +00:00
|
|
|
|
;; rename-file should delete old backup.
|
|
|
|
|
(rename-file real-file-name backupname t)
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(setq setmodes (list modes context backupname)))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(file-error
|
|
|
|
|
;; If trouble writing the backup, write it in ~.
|
1996-01-01 22:51:51 +00:00
|
|
|
|
(setq backupname (expand-file-name
|
|
|
|
|
(convert-standard-filename
|
|
|
|
|
"~/%backup%~")))
|
|
|
|
|
(message "Cannot write backup file; backing up in %s"
|
2006-12-30 06:28:57 +00:00
|
|
|
|
backupname)
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(sleep-for 1)
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(backup-buffer-copy real-file-name backupname modes context)))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(setq buffer-backed-up t)
|
|
|
|
|
;; Now delete the old versions, if desired.
|
|
|
|
|
(if delete-old-versions
|
|
|
|
|
(while targets
|
|
|
|
|
(condition-case ()
|
|
|
|
|
(delete-file (car targets))
|
|
|
|
|
(file-error nil))
|
|
|
|
|
(setq targets (cdr targets))))
|
|
|
|
|
setmodes)
|
|
|
|
|
(file-error nil))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(defun backup-buffer-copy (from-name to-name modes context)
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(let ((umask (default-file-modes)))
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
;; Create temp files with strict access rights. It's easy to
|
|
|
|
|
;; loosen them later, whereas it's impossible to close the
|
|
|
|
|
;; time-window of loose permissions otherwise.
|
|
|
|
|
(set-default-file-modes ?\700)
|
2007-08-30 08:16:55 +00:00
|
|
|
|
(when (condition-case nil
|
|
|
|
|
;; Try to overwrite old backup first.
|
2007-10-21 10:48:28 +00:00
|
|
|
|
(copy-file from-name to-name t t t)
|
2007-08-30 08:16:55 +00:00
|
|
|
|
(error t))
|
|
|
|
|
(while (condition-case nil
|
|
|
|
|
(progn
|
|
|
|
|
(when (file-exists-p to-name)
|
|
|
|
|
(delete-file to-name))
|
2007-10-21 10:48:28 +00:00
|
|
|
|
(copy-file from-name to-name nil t t)
|
2007-08-30 08:16:55 +00:00
|
|
|
|
nil)
|
|
|
|
|
(file-already-exists t))
|
|
|
|
|
;; The file was somehow created by someone else between
|
|
|
|
|
;; `delete-file' and `copy-file', so let's try again.
|
|
|
|
|
;; rms says "I think there is also a possible race
|
|
|
|
|
;; condition for making backup files" (emacs-devel 20070821).
|
|
|
|
|
nil)))
|
2005-04-23 16:53:21 +00:00
|
|
|
|
;; Reset the umask.
|
|
|
|
|
(set-default-file-modes umask)))
|
2003-12-29 19:14:03 +00:00
|
|
|
|
(and modes
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(set-file-modes to-name (logand modes #o1777)))
|
|
|
|
|
(and context
|
|
|
|
|
(set-file-selinux-context to-name context)))
|
2002-09-26 22:00:22 +00:00
|
|
|
|
|
1992-09-13 04:35:22 +00:00
|
|
|
|
(defun file-name-sans-versions (name &optional keep-backup-version)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Return file NAME sans backup versions or strings.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
This is a separate procedure so your site-init or startup file can
|
1992-09-13 04:35:22 +00:00
|
|
|
|
redefine it.
|
|
|
|
|
If the optional argument KEEP-BACKUP-VERSION is non-nil,
|
|
|
|
|
we do not remove backup version numbers, only true file version numbers."
|
1994-04-22 23:59:24 +00:00
|
|
|
|
(let ((handler (find-file-name-handler name 'file-name-sans-versions)))
|
1992-09-13 04:35:22 +00:00
|
|
|
|
(if handler
|
|
|
|
|
(funcall handler 'file-name-sans-versions name keep-backup-version)
|
|
|
|
|
(substring name 0
|
2008-07-31 05:33:56 +00:00
|
|
|
|
(if keep-backup-version
|
|
|
|
|
(length name)
|
|
|
|
|
(or (string-match "\\.~[-[:alnum:]:#@^._]+~\\'" name)
|
|
|
|
|
(string-match "~\\'" name)
|
|
|
|
|
(length name)))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1994-09-22 04:15:33 +00:00
|
|
|
|
(defun file-ownership-preserved-p (file)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Return t if deleting FILE and rewriting it would preserve the owner."
|
1994-09-22 04:15:33 +00:00
|
|
|
|
(let ((handler (find-file-name-handler file 'file-ownership-preserved-p)))
|
|
|
|
|
(if handler
|
|
|
|
|
(funcall handler 'file-ownership-preserved-p file)
|
1995-05-22 20:00:17 +00:00
|
|
|
|
(let ((attributes (file-attributes file)))
|
1995-05-15 22:22:25 +00:00
|
|
|
|
;; Return t if the file doesn't exist, since it's true that no
|
|
|
|
|
;; information would be lost by an (attempted) delete and create.
|
|
|
|
|
(or (null attributes)
|
|
|
|
|
(= (nth 2 attributes) (user-uid)))))))
|
1994-09-22 04:15:33 +00:00
|
|
|
|
|
1994-09-19 04:32:41 +00:00
|
|
|
|
(defun file-name-sans-extension (filename)
|
|
|
|
|
"Return FILENAME sans final \"extension\".
|
2001-10-22 16:11:12 +00:00
|
|
|
|
The extension, in a file name, is the part that follows the last `.',
|
|
|
|
|
except that a leading `.', if any, doesn't count."
|
1994-09-19 04:32:41 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(let ((file (file-name-sans-versions (file-name-nondirectory filename)))
|
|
|
|
|
directory)
|
2001-10-22 16:11:12 +00:00
|
|
|
|
(if (and (string-match "\\.[^.]*\\'" file)
|
|
|
|
|
(not (eq 0 (match-beginning 0))))
|
1994-09-19 04:32:41 +00:00
|
|
|
|
(if (setq directory (file-name-directory filename))
|
2002-07-27 19:09:54 +00:00
|
|
|
|
;; Don't use expand-file-name here; if DIRECTORY is relative,
|
|
|
|
|
;; we don't want to expand it.
|
|
|
|
|
(concat directory (substring file 0 (match-beginning 0)))
|
1994-09-19 04:32:41 +00:00
|
|
|
|
(substring file 0 (match-beginning 0)))
|
|
|
|
|
filename))))
|
|
|
|
|
|
1996-10-13 14:00:48 +00:00
|
|
|
|
(defun file-name-extension (filename &optional period)
|
|
|
|
|
"Return FILENAME's final \"extension\".
|
2001-10-22 16:11:12 +00:00
|
|
|
|
The extension, in a file name, is the part that follows the last `.',
|
2006-05-17 22:54:35 +00:00
|
|
|
|
excluding version numbers and backup suffixes,
|
2001-10-22 16:11:12 +00:00
|
|
|
|
except that a leading `.', if any, doesn't count.
|
1996-10-13 14:00:48 +00:00
|
|
|
|
Return nil for extensionless file names such as `foo'.
|
|
|
|
|
Return the empty string for file names such as `foo.'.
|
|
|
|
|
|
|
|
|
|
If PERIOD is non-nil, then the returned value includes the period
|
|
|
|
|
that delimits the extension, and if FILENAME has no extension,
|
|
|
|
|
the value is \"\"."
|
|
|
|
|
(save-match-data
|
|
|
|
|
(let ((file (file-name-sans-versions (file-name-nondirectory filename))))
|
2001-10-22 16:11:12 +00:00
|
|
|
|
(if (and (string-match "\\.[^.]*\\'" file)
|
|
|
|
|
(not (eq 0 (match-beginning 0))))
|
1996-10-13 14:00:48 +00:00
|
|
|
|
(substring file (+ (match-beginning 0) (if period 0 1)))
|
|
|
|
|
(if period
|
|
|
|
|
"")))))
|
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defcustom make-backup-file-name-function nil
|
|
|
|
|
"A function to use instead of the default `make-backup-file-name'.
|
2005-06-10 14:02:21 +00:00
|
|
|
|
A value of nil gives the default `make-backup-file-name' behavior.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
|
2000-11-21 21:12:49 +00:00
|
|
|
|
This could be buffer-local to do something special for specific
|
2000-10-04 17:16:59 +00:00
|
|
|
|
files. If you define it, you may need to change `backup-file-name-p'
|
|
|
|
|
and `file-name-sans-versions' too.
|
|
|
|
|
|
|
|
|
|
See also `backup-directory-alist'."
|
|
|
|
|
:group 'backup
|
|
|
|
|
:type '(choice (const :tag "Default" nil)
|
|
|
|
|
(function :tag "Your function")))
|
|
|
|
|
|
|
|
|
|
(defcustom backup-directory-alist nil
|
|
|
|
|
"Alist of filename patterns and backup directory names.
|
|
|
|
|
Each element looks like (REGEXP . DIRECTORY). Backups of files with
|
|
|
|
|
names matching REGEXP will be made in DIRECTORY. DIRECTORY may be
|
|
|
|
|
relative or absolute. If it is absolute, so that all matching files
|
|
|
|
|
are backed up into the same directory, the file names in this
|
|
|
|
|
directory will be the full name of the file backed up with all
|
|
|
|
|
directory separators changed to `!' to prevent clashes. This will not
|
|
|
|
|
work correctly if your filesystem truncates the resulting name.
|
|
|
|
|
|
|
|
|
|
For the common case of all backups going into one directory, the alist
|
|
|
|
|
should contain a single element pairing \".\" with the appropriate
|
|
|
|
|
directory name.
|
|
|
|
|
|
|
|
|
|
If this variable is nil, or it fails to match a filename, the backup
|
|
|
|
|
is made in the original file's directory.
|
|
|
|
|
|
|
|
|
|
On MS-DOS filesystems without long names this variable is always
|
|
|
|
|
ignored."
|
|
|
|
|
:group 'backup
|
2001-03-30 11:04:05 +00:00
|
|
|
|
:type '(repeat (cons (regexp :tag "Regexp matching filename")
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(directory :tag "Backup directory name"))))
|
|
|
|
|
|
2001-11-24 23:59:28 +00:00
|
|
|
|
(defun normal-backup-enable-predicate (name)
|
|
|
|
|
"Default `backup-enable-predicate' function.
|
2005-01-29 17:28:00 +00:00
|
|
|
|
Checks for files in `temporary-file-directory',
|
|
|
|
|
`small-temporary-file-directory', and /tmp."
|
2001-11-24 23:59:28 +00:00
|
|
|
|
(not (or (let ((comp (compare-strings temporary-file-directory 0 nil
|
|
|
|
|
name 0 nil)))
|
|
|
|
|
;; Directory is under temporary-file-directory.
|
|
|
|
|
(and (not (eq comp t))
|
|
|
|
|
(< comp (- (length temporary-file-directory)))))
|
2005-01-29 17:28:00 +00:00
|
|
|
|
(let ((comp (compare-strings "/tmp" 0 nil
|
|
|
|
|
name 0 nil)))
|
|
|
|
|
;; Directory is under /tmp.
|
|
|
|
|
(and (not (eq comp t))
|
|
|
|
|
(< comp (- (length "/tmp")))))
|
2001-11-24 23:59:28 +00:00
|
|
|
|
(if small-temporary-file-directory
|
|
|
|
|
(let ((comp (compare-strings small-temporary-file-directory
|
|
|
|
|
0 nil
|
|
|
|
|
name 0 nil)))
|
|
|
|
|
;; Directory is under small-temporary-file-directory.
|
|
|
|
|
(and (not (eq comp t))
|
|
|
|
|
(< comp (- (length small-temporary-file-directory)))))))))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun make-backup-file-name (file)
|
|
|
|
|
"Create the non-numeric backup file name for FILE.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
Normally this will just be the file's name with `~' appended.
|
|
|
|
|
Customization hooks are provided as follows.
|
|
|
|
|
|
|
|
|
|
If the variable `make-backup-file-name-function' is non-nil, its value
|
|
|
|
|
should be a function which will be called with FILE as its argument;
|
|
|
|
|
the resulting name is used.
|
|
|
|
|
|
|
|
|
|
Otherwise a match for FILE is sought in `backup-directory-alist'; see
|
|
|
|
|
the documentation of that variable. If the directory for the backup
|
|
|
|
|
doesn't exist, it is created."
|
|
|
|
|
(if make-backup-file-name-function
|
|
|
|
|
(funcall make-backup-file-name-function file)
|
|
|
|
|
(if (and (eq system-type 'ms-dos)
|
|
|
|
|
(not (msdos-long-file-names)))
|
|
|
|
|
(let ((fn (file-name-nondirectory file)))
|
|
|
|
|
(concat (file-name-directory file)
|
|
|
|
|
(or (and (string-match "\\`[^.]+\\'" fn)
|
|
|
|
|
(concat (match-string 0 fn) ".~"))
|
|
|
|
|
(and (string-match "\\`[^.]+\\.\\(..?\\)?" fn)
|
|
|
|
|
(concat (match-string 0 fn) "~")))))
|
|
|
|
|
(concat (make-backup-file-name-1 file) "~"))))
|
|
|
|
|
|
|
|
|
|
(defun make-backup-file-name-1 (file)
|
|
|
|
|
"Subroutine of `make-backup-file-name' and `find-backup-file-name'."
|
|
|
|
|
(let ((alist backup-directory-alist)
|
2006-12-30 06:28:57 +00:00
|
|
|
|
elt backup-directory abs-backup-directory)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(while alist
|
|
|
|
|
(setq elt (pop alist))
|
|
|
|
|
(if (string-match (car elt) file)
|
|
|
|
|
(setq backup-directory (cdr elt)
|
|
|
|
|
alist nil)))
|
2006-12-17 18:03:26 +00:00
|
|
|
|
;; If backup-directory is relative, it should be relative to the
|
|
|
|
|
;; file's directory. By expanding explicitly here, we avoid
|
|
|
|
|
;; depending on default-directory.
|
|
|
|
|
(if backup-directory
|
2006-12-30 06:28:57 +00:00
|
|
|
|
(setq abs-backup-directory
|
|
|
|
|
(expand-file-name backup-directory
|
|
|
|
|
(file-name-directory file))))
|
|
|
|
|
(if (and abs-backup-directory (not (file-exists-p abs-backup-directory)))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(condition-case nil
|
2006-12-30 06:28:57 +00:00
|
|
|
|
(make-directory abs-backup-directory 'parents)
|
|
|
|
|
(file-error (setq backup-directory nil
|
|
|
|
|
abs-backup-directory nil))))
|
2002-09-09 19:23:37 +00:00
|
|
|
|
(if (null backup-directory)
|
|
|
|
|
file
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(if (file-name-absolute-p backup-directory)
|
|
|
|
|
(progn
|
2003-01-31 15:24:20 +00:00
|
|
|
|
(when (memq system-type '(windows-nt ms-dos cygwin))
|
2002-08-28 22:16:42 +00:00
|
|
|
|
;; Normalize DOSish file names: downcase the drive
|
|
|
|
|
;; letter, if any, and replace the leading "x:" with
|
|
|
|
|
;; "/drive_x".
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(or (file-name-absolute-p file)
|
|
|
|
|
(setq file (expand-file-name file))) ; make defaults explicit
|
|
|
|
|
;; Replace any invalid file-name characters (for the
|
|
|
|
|
;; case of backing up remote files).
|
2000-10-23 17:40:16 +00:00
|
|
|
|
(setq file (expand-file-name (convert-standard-filename file)))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(if (eq (aref file 1) ?:)
|
2002-08-28 22:16:42 +00:00
|
|
|
|
(setq file (concat "/"
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"drive_"
|
|
|
|
|
(char-to-string (downcase (aref file 0)))
|
2002-08-28 22:16:42 +00:00
|
|
|
|
(if (eq (aref file 2) ?/)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
""
|
2002-08-28 22:16:42 +00:00
|
|
|
|
"/")
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(substring file 2)))))
|
|
|
|
|
;; Make the name unique by substituting directory
|
|
|
|
|
;; separators. It may not really be worth bothering about
|
|
|
|
|
;; doubling `!'s in the original name...
|
|
|
|
|
(expand-file-name
|
|
|
|
|
(subst-char-in-string
|
2002-08-28 22:16:42 +00:00
|
|
|
|
?/ ?!
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(replace-regexp-in-string "!" "!!" file))
|
|
|
|
|
backup-directory))
|
|
|
|
|
(expand-file-name (file-name-nondirectory file)
|
2006-12-30 06:28:57 +00:00
|
|
|
|
(file-name-as-directory abs-backup-directory))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun backup-file-name-p (file)
|
|
|
|
|
"Return non-nil if FILE is a backup file name (numeric or not).
|
|
|
|
|
This is a separate function so you can redefine it for customization.
|
|
|
|
|
You may need to redefine `file-name-sans-versions' as well."
|
1995-12-19 21:30:13 +00:00
|
|
|
|
(string-match "~\\'" file))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-10 05:44:56 +00:00
|
|
|
|
(defvar backup-extract-version-start)
|
|
|
|
|
|
1992-07-28 19:38:08 +00:00
|
|
|
|
;; This is used in various files.
|
1999-07-13 03:39:33 +00:00
|
|
|
|
;; The usage of backup-extract-version-start is not very clean,
|
|
|
|
|
;; but I can't see a good alternative, so as of now I am leaving it alone.
|
1992-07-28 19:38:08 +00:00
|
|
|
|
(defun backup-extract-version (fn)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Given the name of a numeric backup file, FN, return the backup number.
|
1997-05-10 05:44:56 +00:00
|
|
|
|
Uses the free variable `backup-extract-version-start', whose value should be
|
1992-07-28 19:38:08 +00:00
|
|
|
|
the index in the name where the version number begins."
|
2008-07-02 13:19:07 +00:00
|
|
|
|
(if (and (string-match "[0-9]+~/?$" fn backup-extract-version-start)
|
1997-05-10 05:44:56 +00:00
|
|
|
|
(= (match-beginning 0) backup-extract-version-start))
|
2005-05-16 11:34:49 +00:00
|
|
|
|
(string-to-number (substring fn backup-extract-version-start -1))
|
1992-07-28 19:38:08 +00:00
|
|
|
|
0))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun find-backup-file-name (fn)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Find a file name for a backup file FN, and suggestions for deletions.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
Value is a list whose car is the name for the backup file
|
2000-10-04 17:16:59 +00:00
|
|
|
|
and whose cdr is a list of old versions to consider deleting now.
|
|
|
|
|
If the value is nil, don't make a backup.
|
|
|
|
|
Uses `backup-directory-alist' in the same way as does
|
|
|
|
|
`make-backup-file-name'."
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(let ((handler (find-file-name-handler fn 'find-backup-file-name)))
|
|
|
|
|
;; Run a handler for this function so that ange-ftp can refuse to do it.
|
|
|
|
|
(if handler
|
|
|
|
|
(funcall handler 'find-backup-file-name fn)
|
2000-10-07 18:49:14 +00:00
|
|
|
|
(if (or (eq version-control 'never)
|
|
|
|
|
;; We don't support numbered backups on plain MS-DOS
|
|
|
|
|
;; when long file names are unavailable.
|
|
|
|
|
(and (eq system-type 'ms-dos)
|
|
|
|
|
(not (msdos-long-file-names))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(list (make-backup-file-name fn))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(let* ((basic-name (make-backup-file-name-1 fn))
|
|
|
|
|
(base-versions (concat (file-name-nondirectory basic-name)
|
|
|
|
|
".~"))
|
1997-05-10 05:44:56 +00:00
|
|
|
|
(backup-extract-version-start (length base-versions))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(high-water-mark 0)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(number-to-delete 0)
|
|
|
|
|
possibilities deserve-versions-p versions)
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(condition-case ()
|
|
|
|
|
(setq possibilities (file-name-all-completions
|
|
|
|
|
base-versions
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(file-name-directory basic-name))
|
|
|
|
|
versions (sort (mapcar #'backup-extract-version
|
|
|
|
|
possibilities)
|
|
|
|
|
#'<)
|
1995-01-12 21:05:07 +00:00
|
|
|
|
high-water-mark (apply 'max 0 versions)
|
|
|
|
|
deserve-versions-p (or version-control
|
|
|
|
|
(> high-water-mark 0))
|
|
|
|
|
number-to-delete (- (length versions)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
kept-old-versions
|
|
|
|
|
kept-new-versions
|
|
|
|
|
-1))
|
|
|
|
|
(file-error (setq possibilities nil)))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(if (not deserve-versions-p)
|
2001-10-30 00:23:32 +00:00
|
|
|
|
(list (make-backup-file-name fn))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(cons (format "%s.~%d~" basic-name (1+ high-water-mark))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(if (and (> number-to-delete 0)
|
|
|
|
|
;; Delete nothing if there is overflow
|
|
|
|
|
;; in the number of versions to keep.
|
|
|
|
|
(>= (+ kept-new-versions kept-old-versions -1) 0))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(mapcar (lambda (n)
|
|
|
|
|
(format "%s.~%d~" basic-name n))
|
1995-01-12 21:05:07 +00:00
|
|
|
|
(let ((v (nthcdr kept-old-versions versions)))
|
|
|
|
|
(rplacd (nthcdr (1- number-to-delete) v) ())
|
|
|
|
|
v))))))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun file-nlinks (filename)
|
|
|
|
|
"Return number of names file FILENAME has."
|
|
|
|
|
(car (cdr (file-attributes filename))))
|
1992-09-27 02:25:31 +00:00
|
|
|
|
|
2003-03-29 15:31:07 +00:00
|
|
|
|
;; (defun file-relative-name (filename &optional directory)
|
|
|
|
|
;; "Convert FILENAME to be relative to DIRECTORY (default: `default-directory').
|
|
|
|
|
;; This function returns a relative file name which is equivalent to FILENAME
|
|
|
|
|
;; when used with that default directory as the default.
|
|
|
|
|
;; If this is impossible (which can happen on MSDOS and Windows
|
|
|
|
|
;; when the file name and directory use different drive names)
|
|
|
|
|
;; then it returns FILENAME."
|
|
|
|
|
;; (save-match-data
|
|
|
|
|
;; (let ((fname (expand-file-name filename)))
|
|
|
|
|
;; (setq directory (file-name-as-directory
|
|
|
|
|
;; (expand-file-name (or directory default-directory))))
|
|
|
|
|
;; ;; On Microsoft OSes, if FILENAME and DIRECTORY have different
|
|
|
|
|
;; ;; drive names, they can't be relative, so return the absolute name.
|
|
|
|
|
;; (if (and (or (eq system-type 'ms-dos)
|
|
|
|
|
;; (eq system-type 'cygwin)
|
|
|
|
|
;; (eq system-type 'windows-nt))
|
|
|
|
|
;; (not (string-equal (substring fname 0 2)
|
|
|
|
|
;; (substring directory 0 2))))
|
|
|
|
|
;; filename
|
|
|
|
|
;; (let ((ancestor ".")
|
|
|
|
|
;; (fname-dir (file-name-as-directory fname)))
|
|
|
|
|
;; (while (and (not (string-match (concat "^" (regexp-quote directory)) fname-dir))
|
|
|
|
|
;; (not (string-match (concat "^" (regexp-quote directory)) fname)))
|
|
|
|
|
;; (setq directory (file-name-directory (substring directory 0 -1))
|
|
|
|
|
;; ancestor (if (equal ancestor ".")
|
|
|
|
|
;; ".."
|
|
|
|
|
;; (concat "../" ancestor))))
|
|
|
|
|
;; ;; Now ancestor is empty, or .., or ../.., etc.
|
|
|
|
|
;; (if (string-match (concat "^" (regexp-quote directory)) fname)
|
|
|
|
|
;; ;; We matched within FNAME's directory part.
|
|
|
|
|
;; ;; Add the rest of FNAME onto ANCESTOR.
|
|
|
|
|
;; (let ((rest (substring fname (match-end 0))))
|
|
|
|
|
;; (if (and (equal ancestor ".")
|
|
|
|
|
;; (not (equal rest "")))
|
|
|
|
|
;; ;; But don't bother with ANCESTOR if it would give us `./'.
|
|
|
|
|
;; rest
|
|
|
|
|
;; (concat (file-name-as-directory ancestor) rest)))
|
|
|
|
|
;; ;; We matched FNAME's directory equivalent.
|
|
|
|
|
;; ancestor))))))
|
|
|
|
|
|
1992-09-27 02:25:31 +00:00
|
|
|
|
(defun file-relative-name (filename &optional directory)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
"Convert FILENAME to be relative to DIRECTORY (default: `default-directory').
|
1997-04-11 01:47:41 +00:00
|
|
|
|
This function returns a relative file name which is equivalent to FILENAME
|
|
|
|
|
when used with that default directory as the default.
|
2003-03-29 15:31:07 +00:00
|
|
|
|
If FILENAME and DIRECTORY lie on different machines or on different drives
|
2005-11-26 15:52:10 +00:00
|
|
|
|
on a DOS/Windows machine, it returns FILENAME in expanded form."
|
1997-02-05 01:32:44 +00:00
|
|
|
|
(save-match-data
|
2003-03-29 15:31:07 +00:00
|
|
|
|
(setq directory
|
|
|
|
|
(file-name-as-directory (expand-file-name (or directory
|
|
|
|
|
default-directory))))
|
|
|
|
|
(setq filename (expand-file-name filename))
|
2004-06-26 14:41:13 +00:00
|
|
|
|
(let ((fremote (file-remote-p filename))
|
|
|
|
|
(dremote (file-remote-p directory)))
|
2003-03-31 16:05:50 +00:00
|
|
|
|
(if ;; Conditions for separate trees
|
|
|
|
|
(or
|
|
|
|
|
;; Test for different drives on DOS/Windows
|
|
|
|
|
(and
|
2004-03-26 15:04:35 +00:00
|
|
|
|
;; Should `cygwin' really be included here? --stef
|
2003-03-31 16:05:50 +00:00
|
|
|
|
(memq system-type '(ms-dos cygwin windows-nt))
|
2004-03-26 15:04:35 +00:00
|
|
|
|
(not (eq t (compare-strings filename 0 2 directory 0 2))))
|
2003-03-31 16:05:50 +00:00
|
|
|
|
;; Test for different remote file system identification
|
2004-06-26 14:41:13 +00:00
|
|
|
|
(not (equal fremote dremote)))
|
1997-05-10 05:44:56 +00:00
|
|
|
|
filename
|
2003-03-29 15:31:07 +00:00
|
|
|
|
(let ((ancestor ".")
|
|
|
|
|
(filename-dir (file-name-as-directory filename)))
|
2004-03-26 15:04:35 +00:00
|
|
|
|
(while (not
|
|
|
|
|
(or
|
|
|
|
|
(eq t (compare-strings filename-dir nil (length directory)
|
|
|
|
|
directory nil nil case-fold-search))
|
|
|
|
|
(eq t (compare-strings filename nil (length directory)
|
|
|
|
|
directory nil nil case-fold-search))))
|
2003-03-29 15:31:07 +00:00
|
|
|
|
(setq directory (file-name-directory (substring directory 0 -1))
|
1997-06-27 09:04:14 +00:00
|
|
|
|
ancestor (if (equal ancestor ".")
|
|
|
|
|
".."
|
|
|
|
|
(concat "../" ancestor))))
|
2003-03-29 15:31:07 +00:00
|
|
|
|
;; Now ancestor is empty, or .., or ../.., etc.
|
2004-03-26 15:04:35 +00:00
|
|
|
|
(if (eq t (compare-strings filename nil (length directory)
|
|
|
|
|
directory nil nil case-fold-search))
|
2003-03-29 15:31:07 +00:00
|
|
|
|
;; We matched within FILENAME's directory part.
|
|
|
|
|
;; Add the rest of FILENAME onto ANCESTOR.
|
2004-03-26 16:21:03 +00:00
|
|
|
|
(let ((rest (substring filename (length directory))))
|
2003-03-29 15:31:07 +00:00
|
|
|
|
(if (and (equal ancestor ".") (not (equal rest "")))
|
1997-06-27 09:04:14 +00:00
|
|
|
|
;; But don't bother with ANCESTOR if it would give us `./'.
|
|
|
|
|
rest
|
|
|
|
|
(concat (file-name-as-directory ancestor) rest)))
|
2003-03-29 15:31:07 +00:00
|
|
|
|
;; We matched FILENAME's directory equivalent.
|
|
|
|
|
ancestor))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun save-buffer (&optional args)
|
2005-12-09 16:44:18 +00:00
|
|
|
|
"Save current buffer in visited file if modified.
|
|
|
|
|
Variations are described below.
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
By default, makes the previous version into a backup file
|
|
|
|
|
if previously requested or if this is the first save.
|
2005-03-19 15:11:07 +00:00
|
|
|
|
Prefixed with one \\[universal-argument], marks this version
|
1991-07-19 14:42:53 +00:00
|
|
|
|
to become a backup when the next save is done.
|
2005-03-19 15:11:07 +00:00
|
|
|
|
Prefixed with two \\[universal-argument]'s,
|
1991-07-19 14:42:53 +00:00
|
|
|
|
unconditionally makes the previous version into a backup file.
|
2005-03-19 15:11:07 +00:00
|
|
|
|
Prefixed with three \\[universal-argument]'s, marks this version
|
1995-12-23 07:34:59 +00:00
|
|
|
|
to become a backup when the next save is done,
|
|
|
|
|
and unconditionally makes the previous version into a backup file.
|
|
|
|
|
|
2005-03-19 15:11:07 +00:00
|
|
|
|
With a numeric argument of 0, never make the previous version
|
|
|
|
|
into a backup file.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
If a file's name is FOO, the names of its numbered backup versions are
|
|
|
|
|
FOO.~i~ for various integers i. A non-numbered backup file is called FOO~.
|
|
|
|
|
Numeric backups (rather than FOO~) will be made if value of
|
|
|
|
|
`version-control' is not the atom `never' and either there are already
|
|
|
|
|
numeric versions of the file being backed up, or `version-control' is
|
|
|
|
|
non-nil.
|
|
|
|
|
We don't want excessive versions piling up, so there are variables
|
|
|
|
|
`kept-old-versions', which tells Emacs how many oldest versions to keep,
|
|
|
|
|
and `kept-new-versions', which tells how many newest versions to keep.
|
|
|
|
|
Defaults are 2 old versions and 2 new.
|
|
|
|
|
`dired-kept-versions' controls dired's clean-directory (.) command.
|
1994-07-06 21:34:31 +00:00
|
|
|
|
If `delete-old-versions' is nil, system will query user
|
1998-07-12 03:14:44 +00:00
|
|
|
|
before trimming versions. Otherwise it does it silently.
|
|
|
|
|
|
1998-10-08 02:20:26 +00:00
|
|
|
|
If `vc-make-backup-files' is nil, which is the default,
|
|
|
|
|
no backup files are made for files managed by version control.
|
|
|
|
|
(This is because the version control system itself records previous versions.)
|
|
|
|
|
|
1998-07-12 03:14:44 +00:00
|
|
|
|
See the subroutine `basic-save-buffer' for more information."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive "p")
|
|
|
|
|
(let ((modp (buffer-modified-p))
|
1994-08-06 03:19:35 +00:00
|
|
|
|
(make-backup-files (or (and make-backup-files (not (eq args 0)))
|
|
|
|
|
(memq args '(16 64)))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(and modp (memq args '(16 64)) (setq buffer-backed-up nil))
|
2009-02-07 10:25:06 +00:00
|
|
|
|
;; We used to display the message below only for files > 50KB, but
|
|
|
|
|
;; then Rmail-mbox never displays it due to buffer swapping. If
|
|
|
|
|
;; the test is ever re-introduced, be sure to handle saving of
|
|
|
|
|
;; Rmail files.
|
|
|
|
|
(if (and modp (buffer-file-name))
|
2001-01-31 13:53:37 +00:00
|
|
|
|
(message "Saving file %s..." (buffer-file-name)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(basic-save-buffer)
|
|
|
|
|
(and modp (memq args '(4 64)) (setq buffer-backed-up nil))))
|
|
|
|
|
|
|
|
|
|
(defun delete-auto-save-file-if-necessary (&optional force)
|
|
|
|
|
"Delete auto-save file for current buffer if `delete-auto-save-files' is t.
|
|
|
|
|
Normally delete only if the file was written by this Emacs since
|
|
|
|
|
the last real save, but optional arg FORCE non-nil means delete anyway."
|
|
|
|
|
(and buffer-auto-save-file-name delete-auto-save-files
|
|
|
|
|
(not (string= buffer-file-name buffer-auto-save-file-name))
|
|
|
|
|
(or force (recent-auto-save-p))
|
|
|
|
|
(progn
|
|
|
|
|
(condition-case ()
|
|
|
|
|
(delete-file buffer-auto-save-file-name)
|
|
|
|
|
(file-error nil))
|
|
|
|
|
(set-buffer-auto-saved))))
|
|
|
|
|
|
1999-01-12 22:20:25 +00:00
|
|
|
|
(defvar auto-save-hook nil
|
|
|
|
|
"Normal hook run just before auto-saving.")
|
|
|
|
|
|
2004-01-05 18:17:41 +00:00
|
|
|
|
(defcustom before-save-hook nil
|
|
|
|
|
"Normal hook that is run before a buffer is saved to its file."
|
2004-06-13 21:32:14 +00:00
|
|
|
|
:options '(copyright-update time-stamp)
|
2004-01-05 18:17:41 +00:00
|
|
|
|
:type 'hook
|
|
|
|
|
:group 'files)
|
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defcustom after-save-hook nil
|
|
|
|
|
"Normal hook that is run after a buffer is saved to its file."
|
|
|
|
|
:options '(executable-make-buffer-file-executable-if-script-p)
|
|
|
|
|
:type 'hook
|
|
|
|
|
:group 'files)
|
1995-08-28 15:15:28 +00:00
|
|
|
|
|
1998-05-11 01:33:54 +00:00
|
|
|
|
(defvar save-buffer-coding-system nil
|
|
|
|
|
"If non-nil, use this coding system for saving the buffer.
|
|
|
|
|
More precisely, use this coding system in place of the
|
|
|
|
|
value of `buffer-file-coding-system', when saving the buffer.
|
|
|
|
|
Calling `write-region' for any purpose other than saving the buffer
|
|
|
|
|
will still use `buffer-file-coding-system'; this variable has no effect
|
|
|
|
|
in such cases.")
|
|
|
|
|
|
1998-07-24 10:43:29 +00:00
|
|
|
|
(make-variable-buffer-local 'save-buffer-coding-system)
|
|
|
|
|
(put 'save-buffer-coding-system 'permanent-local t)
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun basic-save-buffer ()
|
1995-08-28 15:15:28 +00:00
|
|
|
|
"Save the current buffer in its visited file, if it has been modified.
|
2002-06-23 21:16:38 +00:00
|
|
|
|
The hooks `write-contents-functions' and `write-file-functions' get a chance
|
|
|
|
|
to do the job of saving; if they do not, then the buffer is saved in
|
2005-07-18 15:23:04 +00:00
|
|
|
|
the visited file in the usual way.
|
2004-01-05 18:17:41 +00:00
|
|
|
|
Before and after saving the buffer, this function runs
|
|
|
|
|
`before-save-hook' and `after-save-hook', respectively."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive)
|
1998-03-05 04:00:53 +00:00
|
|
|
|
(save-current-buffer
|
1994-12-31 07:49:59 +00:00
|
|
|
|
;; In an indirect buffer, save its base buffer instead.
|
|
|
|
|
(if (buffer-base-buffer)
|
|
|
|
|
(set-buffer (buffer-base-buffer)))
|
|
|
|
|
(if (buffer-modified-p)
|
|
|
|
|
(let ((recent-save (recent-auto-save-p))
|
2003-04-17 21:15:04 +00:00
|
|
|
|
setmodes)
|
1994-12-31 07:49:59 +00:00
|
|
|
|
;; If buffer has no file name, ask user for one.
|
|
|
|
|
(or buffer-file-name
|
1995-08-19 17:01:27 +00:00
|
|
|
|
(let ((filename
|
|
|
|
|
(expand-file-name
|
|
|
|
|
(read-file-name "File to save in: ") nil)))
|
2007-03-20 09:37:57 +00:00
|
|
|
|
(if (file-exists-p filename)
|
|
|
|
|
(if (file-directory-p filename)
|
|
|
|
|
;; Signal an error if the user specified the name of an
|
|
|
|
|
;; existing directory.
|
|
|
|
|
(error "%s is a directory" filename)
|
|
|
|
|
(unless (y-or-n-p (format "File `%s' exists; overwrite? "
|
|
|
|
|
filename))
|
|
|
|
|
(error "Canceled")))
|
|
|
|
|
;; Signal an error if the specified name refers to a
|
|
|
|
|
;; non-existing directory.
|
|
|
|
|
(let ((dir (file-name-directory filename)))
|
|
|
|
|
(unless (file-directory-p dir)
|
|
|
|
|
(if (file-exists-p dir)
|
|
|
|
|
(error "%s is not a directory" dir)
|
|
|
|
|
(error "%s: no such directory" dir)))))
|
1995-08-19 17:01:27 +00:00
|
|
|
|
(set-visited-file-name filename)))
|
1994-12-31 07:49:59 +00:00
|
|
|
|
(or (verify-visited-file-modtime (current-buffer))
|
|
|
|
|
(not (file-exists-p buffer-file-name))
|
|
|
|
|
(yes-or-no-p
|
|
|
|
|
(format "%s has changed since visited or saved. Save anyway? "
|
|
|
|
|
(file-name-nondirectory buffer-file-name)))
|
|
|
|
|
(error "Save not confirmed"))
|
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
1998-03-05 04:00:53 +00:00
|
|
|
|
(save-excursion
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(and (> (point-max) (point-min))
|
2000-11-16 17:04:27 +00:00
|
|
|
|
(not find-file-literally)
|
1998-03-05 04:00:53 +00:00
|
|
|
|
(/= (char-after (1- (point-max))) ?\n)
|
|
|
|
|
(not (and (eq selective-display t)
|
|
|
|
|
(= (char-after (1- (point-max))) ?\r)))
|
|
|
|
|
(or (eq require-final-newline t)
|
2004-12-31 14:48:12 +00:00
|
|
|
|
(eq require-final-newline 'visit-save)
|
1998-03-05 04:00:53 +00:00
|
|
|
|
(and require-final-newline
|
|
|
|
|
(y-or-n-p
|
|
|
|
|
(format "Buffer %s does not end in newline. Add one? "
|
|
|
|
|
(buffer-name)))))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(insert ?\n))))
|
2000-10-04 09:55:21 +00:00
|
|
|
|
;; Support VC version backups.
|
|
|
|
|
(vc-before-save)
|
2004-01-05 18:17:41 +00:00
|
|
|
|
(run-hooks 'before-save-hook)
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(or (run-hook-with-args-until-success 'write-contents-functions)
|
1994-12-31 07:49:59 +00:00
|
|
|
|
(run-hook-with-args-until-success 'local-write-file-hooks)
|
2002-06-23 21:16:38 +00:00
|
|
|
|
(run-hook-with-args-until-success 'write-file-functions)
|
2002-01-04 02:13:37 +00:00
|
|
|
|
;; If a hook returned t, file is already "written".
|
|
|
|
|
;; Otherwise, write it the usual way now.
|
|
|
|
|
(setq setmodes (basic-save-buffer-1)))
|
1997-10-19 20:20:15 +00:00
|
|
|
|
;; Now we have saved the current buffer. Let's make sure
|
|
|
|
|
;; that buffer-file-coding-system is fixed to what
|
|
|
|
|
;; actually used for saving by binding it locally.
|
1998-05-11 01:33:54 +00:00
|
|
|
|
(if save-buffer-coding-system
|
|
|
|
|
(setq save-buffer-coding-system last-coding-system-used)
|
|
|
|
|
(setq buffer-file-coding-system last-coding-system-used))
|
1995-10-29 20:23:42 +00:00
|
|
|
|
(setq buffer-file-number
|
|
|
|
|
(nthcdr 10 (file-attributes buffer-file-name)))
|
1994-12-31 07:49:59 +00:00
|
|
|
|
(if setmodes
|
|
|
|
|
(condition-case ()
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(progn
|
|
|
|
|
(set-file-modes buffer-file-name (car setmodes))
|
|
|
|
|
(set-file-selinux-context buffer-file-name (nth 1 setmodes)))
|
1994-12-31 07:49:59 +00:00
|
|
|
|
(error nil))))
|
|
|
|
|
;; If the auto-save file was recent before this command,
|
|
|
|
|
;; delete it now.
|
|
|
|
|
(delete-auto-save-file-if-necessary recent-save)
|
1995-08-22 19:06:19 +00:00
|
|
|
|
;; Support VC `implicit' locking.
|
|
|
|
|
(vc-after-save)
|
1994-12-31 07:49:59 +00:00
|
|
|
|
(run-hooks 'after-save-hook))
|
|
|
|
|
(message "(No changes need to be saved)"))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1994-03-29 06:59:50 +00:00
|
|
|
|
;; This does the "real job" of writing a buffer into its visited file
|
|
|
|
|
;; and making a backup file. This is what is normally done
|
2002-06-23 21:16:38 +00:00
|
|
|
|
;; but inhibited if one of write-file-functions returns non-nil.
|
2010-04-21 03:02:58 +00:00
|
|
|
|
;; It returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer.
|
1994-03-29 06:59:50 +00:00
|
|
|
|
(defun basic-save-buffer-1 ()
|
2005-01-03 02:42:25 +00:00
|
|
|
|
(prog1
|
|
|
|
|
(if save-buffer-coding-system
|
|
|
|
|
(let ((coding-system-for-write save-buffer-coding-system))
|
|
|
|
|
(basic-save-buffer-2))
|
1998-07-24 10:43:29 +00:00
|
|
|
|
(basic-save-buffer-2))
|
2009-03-03 01:58:22 +00:00
|
|
|
|
(if buffer-file-coding-system-explicit
|
|
|
|
|
(setcar buffer-file-coding-system-explicit last-coding-system-used)
|
|
|
|
|
(setq buffer-file-coding-system-explicit
|
|
|
|
|
(cons last-coding-system-used nil)))))
|
1998-07-24 10:43:29 +00:00
|
|
|
|
|
2010-04-21 03:02:58 +00:00
|
|
|
|
;; This returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer.
|
1998-07-24 10:43:29 +00:00
|
|
|
|
(defun basic-save-buffer-2 ()
|
|
|
|
|
(let (tempsetmodes setmodes)
|
1994-03-29 06:59:50 +00:00
|
|
|
|
(if (not (file-writable-p buffer-file-name))
|
|
|
|
|
(let ((dir (file-name-directory buffer-file-name)))
|
|
|
|
|
(if (not (file-directory-p dir))
|
1997-07-16 05:30:34 +00:00
|
|
|
|
(if (file-exists-p dir)
|
|
|
|
|
(error "%s is not a directory" dir)
|
2007-03-19 05:40:20 +00:00
|
|
|
|
(error "%s: no such directory" dir))
|
1994-03-29 06:59:50 +00:00
|
|
|
|
(if (not (file-exists-p buffer-file-name))
|
|
|
|
|
(error "Directory %s write-protected" dir)
|
|
|
|
|
(if (yes-or-no-p
|
|
|
|
|
(format "File %s is write-protected; try to save anyway? "
|
|
|
|
|
(file-name-nondirectory
|
|
|
|
|
buffer-file-name)))
|
|
|
|
|
(setq tempsetmodes t)
|
|
|
|
|
(error "Attempt to save to a file which you aren't allowed to write"))))))
|
|
|
|
|
(or buffer-backed-up
|
|
|
|
|
(setq setmodes (backup-buffer)))
|
2008-11-29 19:04:14 +00:00
|
|
|
|
(let* ((dir (file-name-directory buffer-file-name))
|
|
|
|
|
(dir-writable (file-writable-p dir)))
|
|
|
|
|
(if (or (and file-precious-flag dir-writable)
|
|
|
|
|
(and break-hardlink-on-save
|
|
|
|
|
(> (file-nlinks buffer-file-name) 1)
|
|
|
|
|
(or dir-writable
|
|
|
|
|
(error (concat (format
|
|
|
|
|
"Directory %s write-protected; " dir)
|
|
|
|
|
"cannot break hardlink when saving")))))
|
|
|
|
|
;; Write temp name, then rename it.
|
1994-07-27 18:55:38 +00:00
|
|
|
|
;; This requires write access to the containing dir,
|
|
|
|
|
;; which is why we don't try it if we don't have that access.
|
|
|
|
|
(let ((realname buffer-file-name)
|
2005-04-23 16:53:21 +00:00
|
|
|
|
tempname succeed
|
|
|
|
|
(umask (default-file-modes))
|
1994-09-20 04:27:40 +00:00
|
|
|
|
(old-modtime (visited-file-modtime)))
|
2005-04-23 16:53:21 +00:00
|
|
|
|
;; Create temp files with strict access rights. It's easy to
|
|
|
|
|
;; loosen them later, whereas it's impossible to close the
|
|
|
|
|
;; time-window of loose permissions otherwise.
|
1994-07-27 18:55:38 +00:00
|
|
|
|
(unwind-protect
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(progn
|
|
|
|
|
(clear-visited-file-modtime)
|
|
|
|
|
(set-default-file-modes ?\700)
|
|
|
|
|
;; Try various temporary names.
|
|
|
|
|
;; This code follows the example of make-temp-file,
|
|
|
|
|
;; but it calls write-region in the appropriate way
|
|
|
|
|
;; for saving the buffer.
|
|
|
|
|
(while (condition-case ()
|
|
|
|
|
(progn
|
|
|
|
|
(setq tempname
|
|
|
|
|
(make-temp-name
|
|
|
|
|
(expand-file-name "tmp" dir)))
|
2008-05-28 12:36:15 +00:00
|
|
|
|
;; Pass in nil&nil rather than point-min&max
|
|
|
|
|
;; cause we're saving the whole buffer.
|
|
|
|
|
;; write-region-annotate-functions may use it.
|
|
|
|
|
(write-region nil nil
|
2005-04-23 16:53:21 +00:00
|
|
|
|
tempname nil realname
|
|
|
|
|
buffer-file-truename 'excl)
|
|
|
|
|
nil)
|
|
|
|
|
(file-already-exists t))
|
|
|
|
|
;; The file was somehow created by someone else between
|
|
|
|
|
;; `make-temp-name' and `write-region', let's try again.
|
|
|
|
|
nil)
|
|
|
|
|
(setq succeed t))
|
|
|
|
|
;; Reset the umask.
|
|
|
|
|
(set-default-file-modes umask)
|
|
|
|
|
;; If we failed, restore the buffer's modtime.
|
|
|
|
|
(unless succeed
|
|
|
|
|
(set-visited-file-modtime old-modtime)))
|
|
|
|
|
;; Since we have created an entirely new file,
|
|
|
|
|
;; make sure it gets the right permission bits set.
|
2006-06-16 15:14:40 +00:00
|
|
|
|
(setq setmodes (or setmodes
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(list (or (file-modes buffer-file-name)
|
2006-06-19 21:48:41 +00:00
|
|
|
|
(logand ?\666 umask))
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(file-selinux-context buffer-file-name)
|
2006-06-16 15:14:40 +00:00
|
|
|
|
buffer-file-name)))
|
1994-07-27 18:55:38 +00:00
|
|
|
|
;; We succeeded in writing the temp file,
|
|
|
|
|
;; so rename it.
|
|
|
|
|
(rename-file tempname buffer-file-name t))
|
|
|
|
|
;; If file not writable, see if we can make it writable
|
|
|
|
|
;; temporarily while we write it.
|
|
|
|
|
;; But no need to do so if we have just backed it up
|
|
|
|
|
;; (setmodes is set) because that says we're superseding.
|
|
|
|
|
(cond ((and tempsetmodes (not setmodes))
|
|
|
|
|
;; Change the mode back, after writing.
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(setq setmodes (list (file-modes buffer-file-name)
|
|
|
|
|
(file-selinux-context buffer-file-name)
|
|
|
|
|
buffer-file-name))
|
|
|
|
|
(set-file-modes buffer-file-name (logior (car setmodes) 128))
|
|
|
|
|
(set-file-selinux-context buffer-file-name (nth 1 setmodes)))))
|
2002-07-23 19:23:08 +00:00
|
|
|
|
(let (success)
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
2008-05-28 12:36:15 +00:00
|
|
|
|
;; Pass in nil&nil rather than point-min&max to indicate
|
|
|
|
|
;; we're saving the buffer rather than just a region.
|
|
|
|
|
;; write-region-annotate-functions may make us of it.
|
|
|
|
|
(write-region nil nil
|
2002-07-23 19:23:08 +00:00
|
|
|
|
buffer-file-name nil t buffer-file-truename)
|
|
|
|
|
(setq success t))
|
|
|
|
|
;; If we get an error writing the new file, and we made
|
|
|
|
|
;; the backup by renaming, undo the backing-up.
|
|
|
|
|
(and setmodes (not success)
|
2006-01-06 11:55:35 +00:00
|
|
|
|
(progn
|
2010-04-21 03:02:58 +00:00
|
|
|
|
(rename-file (nth 2 setmodes) buffer-file-name t)
|
|
|
|
|
(setq buffer-backed-up nil))))))
|
1994-03-29 06:59:50 +00:00
|
|
|
|
setmodes))
|
|
|
|
|
|
2002-09-02 00:11:41 +00:00
|
|
|
|
(defun diff-buffer-with-file (&optional buffer)
|
|
|
|
|
"View the differences between BUFFER and its associated file.
|
2002-09-10 16:48:52 +00:00
|
|
|
|
This requires the external program `diff' to be in your `exec-path'."
|
2002-09-02 00:11:41 +00:00
|
|
|
|
(interactive "bBuffer: ")
|
2002-09-10 16:48:52 +00:00
|
|
|
|
(with-current-buffer (get-buffer (or buffer (current-buffer)))
|
2002-09-13 20:22:29 +00:00
|
|
|
|
(if (and buffer-file-name
|
|
|
|
|
(file-exists-p buffer-file-name))
|
|
|
|
|
(let ((tempfile (make-temp-file "buffer-content-")))
|
|
|
|
|
(unwind-protect
|
2008-05-28 17:35:34 +00:00
|
|
|
|
(progn
|
|
|
|
|
(write-region nil nil tempfile nil 'nomessage)
|
2002-09-13 20:22:29 +00:00
|
|
|
|
(diff buffer-file-name tempfile nil t)
|
|
|
|
|
(sit-for 0))
|
|
|
|
|
(when (file-exists-p tempfile)
|
|
|
|
|
(delete-file tempfile))))
|
|
|
|
|
(message "Buffer %s has no associated file on disc" (buffer-name))
|
|
|
|
|
;; Display that message for 1 second so that user can read it
|
|
|
|
|
;; in the minibuffer.
|
|
|
|
|
(sit-for 1)))
|
|
|
|
|
;; return always nil, so that save-buffers-kill-emacs will not move
|
|
|
|
|
;; over to the next unsaved buffer when calling `d'.
|
|
|
|
|
nil)
|
2002-09-02 00:11:41 +00:00
|
|
|
|
|
|
|
|
|
(defvar save-some-buffers-action-alist
|
2008-06-11 01:47:48 +00:00
|
|
|
|
`((?\C-r
|
|
|
|
|
,(lambda (buf)
|
|
|
|
|
(if (not enable-recursive-minibuffers)
|
|
|
|
|
(progn (display-buffer buf)
|
|
|
|
|
(setq other-window-scroll-buffer buf))
|
|
|
|
|
(view-buffer buf (lambda (_) (exit-recursive-edit)))
|
|
|
|
|
(recursive-edit))
|
|
|
|
|
;; Return nil to ask about BUF again.
|
|
|
|
|
nil)
|
2009-10-30 02:00:11 +00:00
|
|
|
|
,(purecopy "view this buffer"))
|
2008-06-11 01:47:48 +00:00
|
|
|
|
(?d ,(lambda (buf)
|
2009-06-17 15:06:25 +00:00
|
|
|
|
(if (null (buffer-file-name buf))
|
2008-06-11 01:47:48 +00:00
|
|
|
|
(message "Not applicable: no file")
|
|
|
|
|
(save-window-excursion (diff-buffer-with-file buf))
|
|
|
|
|
(if (not enable-recursive-minibuffers)
|
|
|
|
|
(progn (display-buffer (get-buffer-create "*Diff*"))
|
|
|
|
|
(setq other-window-scroll-buffer "*Diff*"))
|
|
|
|
|
(view-buffer (get-buffer-create "*Diff*")
|
|
|
|
|
(lambda (_) (exit-recursive-edit)))
|
|
|
|
|
(recursive-edit)))
|
|
|
|
|
;; Return nil to ask about BUF again.
|
|
|
|
|
nil)
|
2009-10-30 02:00:11 +00:00
|
|
|
|
,(purecopy "view changes in this buffer")))
|
2002-09-02 00:11:41 +00:00
|
|
|
|
"ACTION-ALIST argument used in call to `map-y-or-n-p'.")
|
(enable-local-variables, enable-local-eval)
(safe-local-variable-values, safe-local-eval-forms): Mark as risky in
the defcustoms.
(auto-mode-alist, ignored-local-variables)
(save-some-buffers-action-alist): Move risky declarations to the
definitions.
(dabbrev-case-fold-search, dabbrev-case-replace, display-time-string)
(font-lock-defaults, format-alist, imenu--index-alist)
(imenu-generic-expression, input-method-alist, minor-mode-alist)
(mode-line-buffer-identification, mode-line-client, mode-line-modes)
(mode-line-modified, mode-line-mule-info, mode-line-position)
(mode-line-process, mode-line-remote, outline-level)
(parse-time-rules, rmail-output-file-alist)
(special-display-buffer-names, vc-mode):
Move risky declarations to the relevant files.
2009-08-26 03:08:33 +00:00
|
|
|
|
(put 'save-some-buffers-action-alist 'risky-local-variable t)
|
2002-09-02 00:11:41 +00:00
|
|
|
|
|
2004-12-27 17:18:28 +00:00
|
|
|
|
(defvar buffer-save-without-query nil
|
|
|
|
|
"Non-nil means `save-some-buffers' should save this buffer without asking.")
|
|
|
|
|
(make-variable-buffer-local 'buffer-save-without-query)
|
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defun save-some-buffers (&optional arg pred)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Save some modified file-visiting buffers. Asks user about each one.
|
2002-09-02 00:11:41 +00:00
|
|
|
|
You can answer `y' to save, `n' not to save, `C-r' to look at the
|
|
|
|
|
buffer in question with `view-buffer' before deciding or `d' to
|
2005-03-25 13:33:31 +00:00
|
|
|
|
view the differences using `diff-buffer-with-file'.
|
2002-07-07 09:21:52 +00:00
|
|
|
|
|
1991-10-31 08:30:58 +00:00
|
|
|
|
Optional argument (the prefix) non-nil means save all with no questions.
|
2000-10-04 17:16:59 +00:00
|
|
|
|
Optional second argument PRED determines which buffers are considered:
|
|
|
|
|
If PRED is nil, all the file-visiting buffers are considered.
|
|
|
|
|
If PRED is t, then certain non-file buffers will also be considered.
|
|
|
|
|
If PRED is a zero-argument function, it indicates for each buffer whether
|
2002-09-02 00:11:41 +00:00
|
|
|
|
to consider it or not when called with that buffer current.
|
|
|
|
|
|
|
|
|
|
See `save-some-buffers-action-alist' if you want to
|
|
|
|
|
change the additional actions you can take on files."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive "P")
|
1992-07-28 23:26:57 +00:00
|
|
|
|
(save-window-excursion
|
2004-12-27 17:18:28 +00:00
|
|
|
|
(let* (queried some-automatic
|
|
|
|
|
files-done abbrevs-done)
|
|
|
|
|
(dolist (buffer (buffer-list))
|
|
|
|
|
;; First save any buffers that we're supposed to save unconditionally.
|
|
|
|
|
;; That way the following code won't ask about them.
|
|
|
|
|
(with-current-buffer buffer
|
|
|
|
|
(when (and buffer-save-without-query (buffer-modified-p))
|
|
|
|
|
(setq some-automatic t)
|
|
|
|
|
(save-buffer))))
|
|
|
|
|
;; Ask about those buffers that merit it,
|
|
|
|
|
;; and record the number thus saved.
|
|
|
|
|
(setq files-done
|
1995-12-24 09:25:19 +00:00
|
|
|
|
(map-y-or-n-p
|
2008-06-11 01:47:48 +00:00
|
|
|
|
(lambda (buffer)
|
2008-12-09 23:43:11 +00:00
|
|
|
|
;; Note that killing some buffers may kill others via
|
|
|
|
|
;; hooks (e.g. Rmail and its viewing buffer).
|
|
|
|
|
(and (buffer-live-p buffer)
|
|
|
|
|
(buffer-modified-p buffer)
|
2008-06-11 01:47:48 +00:00
|
|
|
|
(not (buffer-base-buffer buffer))
|
|
|
|
|
(or
|
|
|
|
|
(buffer-file-name buffer)
|
|
|
|
|
(and pred
|
|
|
|
|
(progn
|
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(and buffer-offer-save (> (buffer-size) 0)))))
|
|
|
|
|
(or (not (functionp pred))
|
|
|
|
|
(with-current-buffer buffer (funcall pred)))
|
|
|
|
|
(if arg
|
|
|
|
|
t
|
|
|
|
|
(setq queried t)
|
|
|
|
|
(if (buffer-file-name buffer)
|
|
|
|
|
(format "Save file %s? "
|
|
|
|
|
(buffer-file-name buffer))
|
|
|
|
|
(format "Save buffer %s? "
|
|
|
|
|
(buffer-name buffer))))))
|
|
|
|
|
(lambda (buffer)
|
|
|
|
|
(with-current-buffer buffer
|
|
|
|
|
(save-buffer)))
|
|
|
|
|
(buffer-list)
|
1995-12-24 09:25:19 +00:00
|
|
|
|
'("buffer" "buffers" "save")
|
2002-09-02 00:11:41 +00:00
|
|
|
|
save-some-buffers-action-alist))
|
2005-02-09 15:50:47 +00:00
|
|
|
|
;; Maybe to save abbrevs, and record whether
|
2004-12-27 17:18:28 +00:00
|
|
|
|
;; we either saved them or asked to.
|
|
|
|
|
(and save-abbrevs abbrevs-changed
|
|
|
|
|
(progn
|
|
|
|
|
(if (or arg
|
|
|
|
|
(eq save-abbrevs 'silently)
|
|
|
|
|
(y-or-n-p (format "Save abbrevs in %s? "
|
|
|
|
|
abbrev-file-name)))
|
|
|
|
|
(write-abbrev-file nil))
|
|
|
|
|
;; Don't keep bothering user if he says no.
|
|
|
|
|
(setq abbrevs-changed nil)
|
|
|
|
|
(setq abbrevs-done t)))
|
1995-12-24 09:25:19 +00:00
|
|
|
|
(or queried (> files-done 0) abbrevs-done
|
2004-12-27 17:18:28 +00:00
|
|
|
|
(message (if some-automatic
|
|
|
|
|
"(Some special files were saved without asking)"
|
|
|
|
|
"(No files need saving)"))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun not-modified (&optional arg)
|
|
|
|
|
"Mark current buffer as unmodified, not needing to be saved.
|
2008-11-14 13:05:18 +00:00
|
|
|
|
With prefix ARG, mark buffer as modified, so \\[save-buffer] will save.
|
1995-01-15 10:59:20 +00:00
|
|
|
|
|
|
|
|
|
It is not a good idea to use this function in Lisp programs, because it
|
|
|
|
|
prints a message in the minibuffer. Instead, use `set-buffer-modified-p'."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(message (if arg "Modification-flag set"
|
|
|
|
|
"Modification-flag cleared"))
|
|
|
|
|
(set-buffer-modified-p arg))
|
|
|
|
|
|
|
|
|
|
(defun toggle-read-only (&optional arg)
|
2008-12-04 06:13:19 +00:00
|
|
|
|
"Change whether this buffer is read-only.
|
2007-08-08 07:40:09 +00:00
|
|
|
|
With prefix argument ARG, make the buffer read-only if ARG is
|
2008-12-04 06:13:19 +00:00
|
|
|
|
positive, otherwise make it writable. If buffer is read-only
|
2007-08-08 07:40:09 +00:00
|
|
|
|
and `view-read-only' is non-nil, enter view mode."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive "P")
|
2003-01-31 15:24:20 +00:00
|
|
|
|
(if (and arg
|
2002-07-16 17:40:37 +00:00
|
|
|
|
(if (> (prefix-numeric-value arg) 0) buffer-read-only
|
|
|
|
|
(not buffer-read-only))) ; If buffer-read-only is set correctly,
|
|
|
|
|
nil ; do nothing.
|
|
|
|
|
;; Toggle.
|
|
|
|
|
(cond
|
|
|
|
|
((and buffer-read-only view-mode)
|
|
|
|
|
(View-exit-and-edit)
|
|
|
|
|
(make-local-variable 'view-read-only)
|
|
|
|
|
(setq view-read-only t)) ; Must leave view mode.
|
|
|
|
|
((and (not buffer-read-only) view-read-only
|
2003-04-17 21:15:04 +00:00
|
|
|
|
;; If view-mode is already active, `view-mode-enter' is a nop.
|
|
|
|
|
(not view-mode)
|
2002-07-16 17:40:37 +00:00
|
|
|
|
(not (eq (get major-mode 'mode-class) 'special)))
|
|
|
|
|
(view-mode-enter))
|
|
|
|
|
(t (setq buffer-read-only (not buffer-read-only))
|
|
|
|
|
(force-mode-line-update)))
|
|
|
|
|
(if (vc-backend buffer-file-name)
|
2005-09-18 12:25:02 +00:00
|
|
|
|
(message "%s" (substitute-command-keys
|
2002-07-20 22:02:57 +00:00
|
|
|
|
(concat "File is under version-control; "
|
|
|
|
|
"use \\[vc-next-action] to check in/out"))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-28 03:35:36 +00:00
|
|
|
|
(defun insert-file (filename)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Insert contents of file FILENAME into buffer after point.
|
|
|
|
|
Set mark after the inserted text.
|
|
|
|
|
|
|
|
|
|
This function is meant for the user to run interactively.
|
|
|
|
|
Don't call it from programs! Use `insert-file-contents' instead.
|
|
|
|
|
\(Its calling sequence is different; see its documentation)."
|
1997-05-28 03:35:36 +00:00
|
|
|
|
(interactive "*fInsert file: ")
|
2002-11-05 07:21:14 +00:00
|
|
|
|
(insert-file-1 filename #'insert-file-contents))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-28 03:35:36 +00:00
|
|
|
|
(defun append-to-file (start end filename)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
"Append the contents of the region to the end of file FILENAME.
|
|
|
|
|
When called from a function, expects three arguments,
|
2009-04-08 14:06:45 +00:00
|
|
|
|
START, END and FILENAME. START and END are normally buffer positions
|
|
|
|
|
specifying the part of the buffer to write.
|
|
|
|
|
If START is nil, that means to use the entire buffer contents.
|
|
|
|
|
If START is a string, then output that string to the file
|
|
|
|
|
instead of any buffer contents; END is ignored.
|
|
|
|
|
|
|
|
|
|
This does character code conversion and applies annotations
|
|
|
|
|
like `write-region' does."
|
1997-05-28 03:35:36 +00:00
|
|
|
|
(interactive "r\nFAppend to file: ")
|
|
|
|
|
(write-region start end filename t))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun file-newest-backup (filename)
|
|
|
|
|
"Return most recent backup file for FILENAME or nil if no backups exist."
|
2000-10-04 17:16:59 +00:00
|
|
|
|
;; `make-backup-file-name' will get us the right directory for
|
|
|
|
|
;; ordinary or numeric backups. It might create a directory for
|
|
|
|
|
;; backups as a side-effect, according to `backup-directory-alist'.
|
2002-05-22 23:29:58 +00:00
|
|
|
|
(let* ((filename (file-name-sans-versions
|
2003-08-24 15:19:42 +00:00
|
|
|
|
(make-backup-file-name (expand-file-name filename))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(file (file-name-nondirectory filename))
|
|
|
|
|
(dir (file-name-directory filename))
|
|
|
|
|
(comp (file-name-all-completions file dir))
|
1996-04-03 05:55:12 +00:00
|
|
|
|
(newest nil)
|
|
|
|
|
tem)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(while comp
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(setq tem (pop comp))
|
1996-04-03 05:55:12 +00:00
|
|
|
|
(cond ((and (backup-file-name-p tem)
|
|
|
|
|
(string= (file-name-sans-versions tem) file))
|
|
|
|
|
(setq tem (concat dir tem))
|
|
|
|
|
(if (or (null newest)
|
|
|
|
|
(file-newer-than-file-p tem newest))
|
|
|
|
|
(setq newest tem)))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
newest))
|
|
|
|
|
|
|
|
|
|
(defun rename-uniquely ()
|
|
|
|
|
"Rename current buffer to a similar name not already taken.
|
|
|
|
|
This function is useful for creating multiple shell process buffers
|
|
|
|
|
or multiple mail buffers, etc."
|
|
|
|
|
(interactive)
|
1995-04-24 14:59:22 +00:00
|
|
|
|
(save-match-data
|
1997-11-07 21:44:16 +00:00
|
|
|
|
(let ((base-name (buffer-name)))
|
|
|
|
|
(and (string-match "<[0-9]+>\\'" base-name)
|
|
|
|
|
(not (and buffer-file-name
|
|
|
|
|
(string= base-name
|
|
|
|
|
(file-name-nondirectory buffer-file-name))))
|
|
|
|
|
;; If the existing buffer name has a <NNN>,
|
|
|
|
|
;; which isn't part of the file name (if any),
|
|
|
|
|
;; then get rid of that.
|
|
|
|
|
(setq base-name (substring base-name 0 (match-beginning 0))))
|
|
|
|
|
(rename-buffer (generate-new-buffer-name base-name))
|
1995-04-25 22:22:21 +00:00
|
|
|
|
(force-mode-line-update))))
|
1991-10-31 08:30:58 +00:00
|
|
|
|
|
1992-11-03 07:07:02 +00:00
|
|
|
|
(defun make-directory (dir &optional parents)
|
1993-06-12 06:54:14 +00:00
|
|
|
|
"Create the directory DIR and any nonexistent parent dirs.
|
2008-03-14 17:14:09 +00:00
|
|
|
|
If DIR already exists as a directory, signal an error, unless PARENTS is set.
|
2007-07-03 02:52:32 +00:00
|
|
|
|
|
1993-06-12 06:54:14 +00:00
|
|
|
|
Interactively, the default choice of directory to create
|
|
|
|
|
is the current default directory for file names.
|
1996-01-04 23:34:55 +00:00
|
|
|
|
That is useful when you have visited a file in a nonexistent directory.
|
1993-06-12 06:54:14 +00:00
|
|
|
|
|
|
|
|
|
Noninteractively, the second (optional) argument PARENTS says whether
|
2003-06-03 11:08:25 +00:00
|
|
|
|
to create parent directories if they don't exist. Interactively,
|
|
|
|
|
this happens by default."
|
1993-06-12 06:54:14 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(list (read-file-name "Make directory: " default-directory default-directory
|
|
|
|
|
nil nil)
|
|
|
|
|
t))
|
2002-09-09 19:23:37 +00:00
|
|
|
|
;; If default-directory is a remote directory,
|
|
|
|
|
;; make sure we find its make-directory handler.
|
|
|
|
|
(setq dir (expand-file-name dir))
|
1994-04-22 23:59:24 +00:00
|
|
|
|
(let ((handler (find-file-name-handler dir 'make-directory)))
|
1992-11-03 07:07:02 +00:00
|
|
|
|
(if handler
|
|
|
|
|
(funcall handler 'make-directory dir parents)
|
|
|
|
|
(if (not parents)
|
|
|
|
|
(make-directory-internal dir)
|
|
|
|
|
(let ((dir (directory-file-name (expand-file-name dir)))
|
|
|
|
|
create-list)
|
2009-02-17 14:27:28 +00:00
|
|
|
|
(while (and (not (file-exists-p dir))
|
|
|
|
|
;; If directory is its own parent, then we can't
|
|
|
|
|
;; keep looping forever
|
|
|
|
|
(not (equal dir
|
|
|
|
|
(directory-file-name
|
|
|
|
|
(file-name-directory dir)))))
|
1995-12-24 09:25:19 +00:00
|
|
|
|
(setq create-list (cons dir create-list)
|
1992-11-03 07:07:02 +00:00
|
|
|
|
dir (directory-file-name (file-name-directory dir))))
|
|
|
|
|
(while create-list
|
|
|
|
|
(make-directory-internal (car create-list))
|
|
|
|
|
(setq create-list (cdr create-list))))))))
|
2009-10-01 15:04:22 +00:00
|
|
|
|
|
2009-10-05 07:44:01 +00:00
|
|
|
|
(defconst directory-files-no-dot-files-regexp
|
|
|
|
|
"^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"
|
|
|
|
|
"Regexp of file names excluging \".\" an \"..\".")
|
|
|
|
|
|
2009-10-01 15:04:22 +00:00
|
|
|
|
(defun delete-directory (directory &optional recursive)
|
|
|
|
|
"Delete the directory named DIRECTORY. Does not follow symlinks.
|
|
|
|
|
If RECURSIVE is non-nil, all files in DIRECTORY are deleted as well."
|
|
|
|
|
(interactive
|
|
|
|
|
(let ((dir (expand-file-name
|
|
|
|
|
(read-file-name
|
|
|
|
|
"Delete directory: "
|
|
|
|
|
default-directory default-directory nil nil))))
|
|
|
|
|
(list dir
|
2009-10-05 07:44:01 +00:00
|
|
|
|
(if (directory-files dir nil directory-files-no-dot-files-regexp)
|
2009-10-01 15:04:22 +00:00
|
|
|
|
(y-or-n-p
|
|
|
|
|
(format "Directory `%s' is not empty, really delete? " dir))
|
|
|
|
|
nil))))
|
2009-10-04 12:14:05 +00:00
|
|
|
|
;; If default-directory is a remote directory, make sure we find its
|
|
|
|
|
;; delete-directory handler.
|
2009-10-01 15:04:22 +00:00
|
|
|
|
(setq directory (directory-file-name (expand-file-name directory)))
|
|
|
|
|
(let ((handler (find-file-name-handler directory 'delete-directory)))
|
2010-01-27 03:17:23 +00:00
|
|
|
|
(cond
|
|
|
|
|
(handler
|
|
|
|
|
(funcall handler 'delete-directory directory recursive))
|
|
|
|
|
(delete-by-moving-to-trash
|
|
|
|
|
;; Only move non-empty dir to trash if recursive deletion was
|
|
|
|
|
;; requested. This mimics the non-`delete-by-moving-to-trash'
|
|
|
|
|
;; case, where the operation fails in delete-directory-internal.
|
|
|
|
|
;; As `move-file-to-trash' trashes directories (empty or
|
|
|
|
|
;; otherwise) as a unit, we do not need to recurse here.
|
|
|
|
|
(if (and (not recursive)
|
|
|
|
|
;; Check if directory is empty apart from "." and "..".
|
|
|
|
|
(directory-files
|
|
|
|
|
directory 'full directory-files-no-dot-files-regexp))
|
|
|
|
|
(error "Directory is not empty, not moving to trash")
|
|
|
|
|
(move-file-to-trash directory)))
|
|
|
|
|
;; Otherwise, call outselves recursively if needed.
|
|
|
|
|
(t
|
2009-10-01 15:04:22 +00:00
|
|
|
|
(if (and recursive (not (file-symlink-p directory)))
|
2010-01-27 03:17:23 +00:00
|
|
|
|
(mapc (lambda (file)
|
|
|
|
|
;; This test is equivalent to
|
|
|
|
|
;; (and (file-directory-p fn) (not (file-symlink-p fn)))
|
|
|
|
|
;; but more efficient
|
|
|
|
|
(if (eq t (car (file-attributes file)))
|
|
|
|
|
(delete-directory file recursive)
|
|
|
|
|
(delete-file file)))
|
|
|
|
|
;; We do not want to delete "." and "..".
|
|
|
|
|
(directory-files
|
2010-01-27 03:36:36 +00:00
|
|
|
|
directory 'full directory-files-no-dot-files-regexp)))
|
|
|
|
|
(delete-directory-internal directory)))))
|
2009-10-01 15:04:22 +00:00
|
|
|
|
|
2009-10-05 07:44:01 +00:00
|
|
|
|
(defun copy-directory (directory newname &optional keep-time parents)
|
2009-10-04 12:14:05 +00:00
|
|
|
|
"Copy DIRECTORY to NEWNAME. Both args must be strings.
|
|
|
|
|
If NEWNAME names an existing directory, copy DIRECTORY as subdirectory there.
|
|
|
|
|
|
|
|
|
|
This function always sets the file modes of the output files to match
|
|
|
|
|
the corresponding input file.
|
|
|
|
|
|
|
|
|
|
The third arg KEEP-TIME non-nil means give the output files the same
|
|
|
|
|
last-modified time as the old ones. (This works on only some systems.)
|
|
|
|
|
|
|
|
|
|
A prefix arg makes KEEP-TIME non-nil.
|
|
|
|
|
|
|
|
|
|
Noninteractively, the last argument PARENTS says whether to
|
|
|
|
|
create parent directories if they don't exist. Interactively,
|
|
|
|
|
this happens by default."
|
|
|
|
|
(interactive
|
|
|
|
|
(let ((dir (read-directory-name
|
|
|
|
|
"Copy directory: " default-directory default-directory t nil)))
|
|
|
|
|
(list dir
|
|
|
|
|
(read-file-name
|
|
|
|
|
(format "Copy directory %s to: " dir)
|
|
|
|
|
default-directory default-directory nil nil)
|
2009-10-05 07:44:01 +00:00
|
|
|
|
current-prefix-arg t)))
|
2009-10-04 12:14:05 +00:00
|
|
|
|
;; If default-directory is a remote directory, make sure we find its
|
|
|
|
|
;; copy-directory handler.
|
|
|
|
|
(let ((handler (or (find-file-name-handler directory 'copy-directory)
|
|
|
|
|
(find-file-name-handler newname 'copy-directory))))
|
|
|
|
|
(if handler
|
2009-10-05 07:44:01 +00:00
|
|
|
|
(funcall handler 'copy-directory directory newname keep-time parents)
|
2009-10-04 12:14:05 +00:00
|
|
|
|
|
|
|
|
|
;; Compute target name.
|
|
|
|
|
(setq directory (directory-file-name (expand-file-name directory))
|
|
|
|
|
newname (directory-file-name (expand-file-name newname)))
|
|
|
|
|
(if (not (file-directory-p newname)) (make-directory newname parents))
|
2009-10-05 07:44:01 +00:00
|
|
|
|
|
2009-10-04 12:14:05 +00:00
|
|
|
|
;; Copy recursively.
|
|
|
|
|
(mapc
|
|
|
|
|
(lambda (file)
|
2010-01-12 21:59:05 +00:00
|
|
|
|
(let ((target (expand-file-name
|
2010-04-20 22:28:26 +00:00
|
|
|
|
(file-name-nondirectory file) newname))
|
|
|
|
|
(attrs (file-attributes file)))
|
|
|
|
|
(cond ((file-directory-p file)
|
|
|
|
|
(copy-directory file target keep-time parents))
|
|
|
|
|
((stringp (car attrs)) ; Symbolic link
|
|
|
|
|
(make-symbolic-link (car attrs) target t))
|
|
|
|
|
(t
|
|
|
|
|
(copy-file file target t keep-time)))))
|
2010-01-12 21:59:05 +00:00
|
|
|
|
;; We do not want to copy "." and "..".
|
2009-10-05 07:44:01 +00:00
|
|
|
|
(directory-files directory 'full directory-files-no-dot-files-regexp))
|
2009-10-04 12:14:05 +00:00
|
|
|
|
|
|
|
|
|
;; Set directory attributes.
|
|
|
|
|
(set-file-modes newname (file-modes directory))
|
|
|
|
|
(if keep-time
|
2009-10-05 07:44:01 +00:00
|
|
|
|
(set-file-times newname (nth 5 (file-attributes directory)))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(put 'revert-buffer-function 'permanent-local t)
|
|
|
|
|
(defvar revert-buffer-function nil
|
1994-07-06 23:03:47 +00:00
|
|
|
|
"Function to use to revert this buffer, or nil to do the default.
|
|
|
|
|
The function receives two arguments IGNORE-AUTO and NOCONFIRM,
|
|
|
|
|
which are the arguments that `revert-buffer' received.")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(put 'revert-buffer-insert-file-contents-function 'permanent-local t)
|
|
|
|
|
(defvar revert-buffer-insert-file-contents-function nil
|
|
|
|
|
"Function to use to insert contents when reverting this buffer.
|
|
|
|
|
Gets two args, first the nominal file name to use,
|
1999-07-05 22:49:45 +00:00
|
|
|
|
and second, t if reading the auto-save file.
|
|
|
|
|
|
|
|
|
|
The function you specify is responsible for updating (or preserving) point.")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2004-03-27 01:08:15 +00:00
|
|
|
|
(defvar buffer-stale-function nil
|
|
|
|
|
"Function to check whether a non-file buffer needs reverting.
|
|
|
|
|
This should be a function with one optional argument NOCONFIRM.
|
2005-04-23 16:53:21 +00:00
|
|
|
|
Auto Revert Mode passes t for NOCONFIRM. The function should return
|
2004-04-01 01:20:20 +00:00
|
|
|
|
non-nil if the buffer should be reverted. A return value of
|
|
|
|
|
`fast' means that the need for reverting was not checked, but
|
|
|
|
|
that reverting the buffer is fast. The buffer is current when
|
|
|
|
|
this function is called.
|
2004-03-27 01:08:15 +00:00
|
|
|
|
|
2004-03-27 04:05:23 +00:00
|
|
|
|
The idea behind the NOCONFIRM argument is that it should be
|
|
|
|
|
non-nil if the buffer is going to be reverted without asking the
|
|
|
|
|
user. In such situations, one has to be careful with potentially
|
2004-06-16 01:34:15 +00:00
|
|
|
|
time consuming operations.
|
|
|
|
|
|
|
|
|
|
For more information on how this variable is used by Auto Revert mode,
|
2006-05-06 14:37:04 +00:00
|
|
|
|
see Info node `(emacs)Supporting additional buffers'.")
|
2004-03-27 01:08:15 +00:00
|
|
|
|
|
1995-05-29 19:42:42 +00:00
|
|
|
|
(defvar before-revert-hook nil
|
|
|
|
|
"Normal hook for `revert-buffer' to run before reverting.
|
|
|
|
|
If `revert-buffer-function' is used to override the normal revert
|
|
|
|
|
mechanism, this hook is not used.")
|
|
|
|
|
|
|
|
|
|
(defvar after-revert-hook nil
|
|
|
|
|
"Normal hook for `revert-buffer' to run after reverting.
|
|
|
|
|
Note that the hook value that it runs is the value that was in effect
|
|
|
|
|
before reverting; that makes a difference if you have buffer-local
|
|
|
|
|
hook functions.
|
|
|
|
|
|
|
|
|
|
If `revert-buffer-function' is used to override the normal revert
|
|
|
|
|
mechanism, this hook is not used.")
|
|
|
|
|
|
1998-10-20 18:48:06 +00:00
|
|
|
|
(defvar revert-buffer-internal-hook)
|
|
|
|
|
|
1995-12-25 21:05:31 +00:00
|
|
|
|
(defun revert-buffer (&optional ignore-auto noconfirm preserve-modes)
|
1996-11-09 09:04:52 +00:00
|
|
|
|
"Replace current buffer text with the text of the visited file on disk.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
This undoes all changes since the file was visited or saved.
|
1992-04-04 05:55:39 +00:00
|
|
|
|
With a prefix argument, offer to revert from latest auto-save file, if
|
|
|
|
|
that is more recent than the visited file.
|
1993-02-22 14:17:16 +00:00
|
|
|
|
|
2007-12-12 11:25:21 +00:00
|
|
|
|
This command also implements an interface for special buffers
|
|
|
|
|
that contain text which doesn't come from a file, but reflects
|
|
|
|
|
some other data instead (e.g. Dired buffers, `buffer-list'
|
2008-11-14 13:05:18 +00:00
|
|
|
|
buffers). This is done via the variable `revert-buffer-function'.
|
|
|
|
|
In these cases, it should reconstruct the buffer contents from the
|
|
|
|
|
appropriate data.
|
1996-11-09 09:04:52 +00:00
|
|
|
|
|
1995-03-08 03:43:34 +00:00
|
|
|
|
When called from Lisp, the first argument is IGNORE-AUTO; only offer
|
1993-02-22 14:17:16 +00:00
|
|
|
|
to revert from the auto-save file when this is nil. Note that the
|
|
|
|
|
sense of this argument is the reverse of the prefix argument, for the
|
|
|
|
|
sake of backward compatibility. IGNORE-AUTO is optional, defaulting
|
|
|
|
|
to nil.
|
|
|
|
|
|
2008-11-14 13:05:18 +00:00
|
|
|
|
Optional second argument NOCONFIRM means don't ask for confirmation
|
|
|
|
|
at all. \(The variable `revert-without-query' offers another way to
|
2006-02-11 18:42:56 +00:00
|
|
|
|
revert buffers without querying for confirmation.)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1996-08-20 21:22:41 +00:00
|
|
|
|
Optional third argument PRESERVE-MODES non-nil means don't alter
|
|
|
|
|
the files modes. Normally we reinitialize them using `normal-mode'.
|
|
|
|
|
|
1992-04-04 05:55:39 +00:00
|
|
|
|
If the value of `revert-buffer-function' is non-nil, it is called to
|
1996-11-09 09:04:52 +00:00
|
|
|
|
do all the work for this command. Otherwise, the hooks
|
|
|
|
|
`before-revert-hook' and `after-revert-hook' are run at the beginning
|
|
|
|
|
and the end, and if `revert-buffer-insert-file-contents-function' is
|
|
|
|
|
non-nil, it is called instead of rereading visited file contents."
|
1994-01-18 19:13:11 +00:00
|
|
|
|
|
1993-02-22 14:17:16 +00:00
|
|
|
|
;; I admit it's odd to reverse the sense of the prefix argument, but
|
|
|
|
|
;; there is a lot of code out there which assumes that the first
|
|
|
|
|
;; argument should be t to avoid consulting the auto-save file, and
|
|
|
|
|
;; there's no straightforward way to encourage authors to notice a
|
|
|
|
|
;; reversal of the argument sense. So I'm just changing the user
|
|
|
|
|
;; interface, but leaving the programmatic interface the same.
|
1995-02-28 06:24:08 +00:00
|
|
|
|
(interactive (list (not current-prefix-arg)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(if revert-buffer-function
|
1993-02-22 14:17:16 +00:00
|
|
|
|
(funcall revert-buffer-function ignore-auto noconfirm)
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(with-current-buffer (or (buffer-base-buffer (current-buffer))
|
|
|
|
|
(current-buffer))
|
|
|
|
|
(let* ((auto-save-p (and (not ignore-auto)
|
|
|
|
|
(recent-auto-save-p)
|
|
|
|
|
buffer-auto-save-file-name
|
|
|
|
|
(file-readable-p buffer-auto-save-file-name)
|
|
|
|
|
(y-or-n-p
|
|
|
|
|
"Buffer has been auto-saved recently. Revert from auto-save file? ")))
|
|
|
|
|
(file-name (if auto-save-p
|
|
|
|
|
buffer-auto-save-file-name
|
|
|
|
|
buffer-file-name)))
|
|
|
|
|
(cond ((null file-name)
|
|
|
|
|
(error "Buffer does not seem to be associated with any file"))
|
|
|
|
|
((or noconfirm
|
|
|
|
|
(and (not (buffer-modified-p))
|
2006-02-11 18:42:56 +00:00
|
|
|
|
(catch 'found
|
|
|
|
|
(dolist (regexp revert-without-query)
|
|
|
|
|
(when (string-match regexp file-name)
|
|
|
|
|
(throw 'found t)))))
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(yes-or-no-p (format "Revert buffer from file %s? "
|
|
|
|
|
file-name)))
|
|
|
|
|
(run-hooks 'before-revert-hook)
|
|
|
|
|
;; If file was backed up but has changed since,
|
2009-10-21 20:03:57 +00:00
|
|
|
|
;; we should make another backup.
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(and (not auto-save-p)
|
|
|
|
|
(not (verify-visited-file-modtime (current-buffer)))
|
|
|
|
|
(setq buffer-backed-up nil))
|
|
|
|
|
;; Effectively copy the after-revert-hook status,
|
|
|
|
|
;; since after-find-file will clobber it.
|
|
|
|
|
(let ((global-hook (default-value 'after-revert-hook))
|
2006-02-11 18:42:56 +00:00
|
|
|
|
(local-hook (when (local-variable-p 'after-revert-hook)
|
|
|
|
|
after-revert-hook))
|
|
|
|
|
(inhibit-read-only t))
|
|
|
|
|
(cond
|
|
|
|
|
(revert-buffer-insert-file-contents-function
|
|
|
|
|
(unless (eq buffer-undo-list t)
|
|
|
|
|
;; Get rid of all undo records for this buffer.
|
|
|
|
|
(setq buffer-undo-list nil))
|
|
|
|
|
;; Don't make undo records for the reversion.
|
|
|
|
|
(let ((buffer-undo-list t))
|
|
|
|
|
(funcall revert-buffer-insert-file-contents-function
|
|
|
|
|
file-name auto-save-p)))
|
|
|
|
|
((not (file-exists-p file-name))
|
|
|
|
|
(error (if buffer-file-number
|
|
|
|
|
"File %s no longer exists!"
|
|
|
|
|
"Cannot revert nonexistent file %s")
|
|
|
|
|
file-name))
|
2006-11-28 02:20:32 +00:00
|
|
|
|
((not (file-readable-p file-name))
|
|
|
|
|
(error (if buffer-file-number
|
|
|
|
|
"File %s no longer readable!"
|
|
|
|
|
"Cannot revert unreadable file %s")
|
|
|
|
|
file-name))
|
2006-02-11 18:42:56 +00:00
|
|
|
|
(t
|
|
|
|
|
;; Bind buffer-file-name to nil
|
|
|
|
|
;; so that we don't try to lock the file.
|
|
|
|
|
(let ((buffer-file-name nil))
|
|
|
|
|
(or auto-save-p
|
|
|
|
|
(unlock-buffer)))
|
|
|
|
|
(widen)
|
|
|
|
|
(let ((coding-system-for-read
|
|
|
|
|
;; Auto-saved file should be read by Emacs'
|
|
|
|
|
;; internal coding.
|
|
|
|
|
(if auto-save-p 'auto-save-coding
|
|
|
|
|
(or coding-system-for-read
|
2009-03-03 01:58:22 +00:00
|
|
|
|
(and
|
|
|
|
|
buffer-file-coding-system-explicit
|
|
|
|
|
(car buffer-file-coding-system-explicit))))))
|
2006-10-30 07:40:14 +00:00
|
|
|
|
(if (and (not enable-multibyte-characters)
|
2006-11-10 01:16:26 +00:00
|
|
|
|
coding-system-for-read
|
2006-10-30 07:40:14 +00:00
|
|
|
|
(not (memq (coding-system-base
|
|
|
|
|
coding-system-for-read)
|
|
|
|
|
'(no-conversion raw-text))))
|
|
|
|
|
;; As a coding system suitable for multibyte
|
|
|
|
|
;; buffer is specified, make the current
|
|
|
|
|
;; buffer multibyte.
|
|
|
|
|
(set-buffer-multibyte t))
|
|
|
|
|
|
2006-02-11 18:42:56 +00:00
|
|
|
|
;; This force after-insert-file-set-coding
|
|
|
|
|
;; (called from insert-file-contents) to set
|
|
|
|
|
;; buffer-file-coding-system to a proper value.
|
|
|
|
|
(kill-local-variable 'buffer-file-coding-system)
|
|
|
|
|
|
|
|
|
|
;; Note that this preserves point in an intelligent way.
|
|
|
|
|
(if preserve-modes
|
|
|
|
|
(let ((buffer-file-format buffer-file-format))
|
|
|
|
|
(insert-file-contents file-name (not auto-save-p)
|
|
|
|
|
nil nil t))
|
|
|
|
|
(insert-file-contents file-name (not auto-save-p)
|
2007-12-12 01:18:26 +00:00
|
|
|
|
nil nil t)))))
|
2005-04-23 16:53:21 +00:00
|
|
|
|
;; Recompute the truename in case changes in symlinks
|
|
|
|
|
;; have changed the truename.
|
|
|
|
|
(setq buffer-file-truename
|
|
|
|
|
(abbreviate-file-name (file-truename buffer-file-name)))
|
|
|
|
|
(after-find-file nil nil t t preserve-modes)
|
|
|
|
|
;; Run after-revert-hook as it was before we reverted.
|
|
|
|
|
(setq-default revert-buffer-internal-hook global-hook)
|
2006-02-11 18:42:56 +00:00
|
|
|
|
(if local-hook
|
2005-04-23 16:53:21 +00:00
|
|
|
|
(set (make-local-variable 'revert-buffer-internal-hook)
|
|
|
|
|
local-hook)
|
|
|
|
|
(kill-local-variable 'revert-buffer-internal-hook))
|
|
|
|
|
(run-hooks 'revert-buffer-internal-hook))
|
|
|
|
|
t))))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2002-08-15 20:08:24 +00:00
|
|
|
|
(defun recover-this-file ()
|
|
|
|
|
"Recover the visited file--get contents from its last auto-save file."
|
|
|
|
|
(interactive)
|
|
|
|
|
(recover-file buffer-file-name))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun recover-file (file)
|
|
|
|
|
"Visit file FILE, but get contents from its last auto-save file."
|
1995-02-10 06:29:31 +00:00
|
|
|
|
;; Actually putting the file name in the minibuffer should be used
|
|
|
|
|
;; only rarely.
|
|
|
|
|
;; Not just because users often use the default.
|
1995-12-06 11:59:55 +00:00
|
|
|
|
(interactive "FRecover file: ")
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(setq file (expand-file-name file))
|
1994-02-16 18:23:16 +00:00
|
|
|
|
(if (auto-save-file-name-p (file-name-nondirectory file))
|
2003-04-14 20:48:44 +00:00
|
|
|
|
(error "%s is an auto-save file" (abbreviate-file-name file)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(let ((file-name (let ((buffer-file-name file))
|
|
|
|
|
(make-auto-save-file-name))))
|
1995-08-13 16:48:13 +00:00
|
|
|
|
(cond ((if (file-exists-p file)
|
|
|
|
|
(not (file-newer-than-file-p file-name file))
|
|
|
|
|
(not (file-exists-p file-name)))
|
2003-04-14 20:48:44 +00:00
|
|
|
|
(error "Auto-save file %s not current"
|
|
|
|
|
(abbreviate-file-name file-name)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
((save-window-excursion
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(with-output-to-temp-buffer "*Directory*"
|
|
|
|
|
(buffer-disable-undo standard-output)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(let ((switches dired-listing-switches))
|
|
|
|
|
(if (file-symlink-p file)
|
|
|
|
|
(setq switches (concat switches "L")))
|
|
|
|
|
(set-buffer standard-output)
|
2000-12-21 14:44:35 +00:00
|
|
|
|
;; Use insert-directory-safely, not insert-directory,
|
|
|
|
|
;; because these files might not exist. In particular,
|
|
|
|
|
;; FILE might not exist if the auto-save file was for
|
|
|
|
|
;; a buffer that didn't visit a file, such as "*mail*".
|
|
|
|
|
;; The code in v20.x called `ls' directly, so we need
|
|
|
|
|
;; to emulate what `ls' did in that case.
|
|
|
|
|
(insert-directory-safely file switches)
|
|
|
|
|
(insert-directory-safely file-name switches))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(yes-or-no-p (format "Recover auto save file %s? " file-name)))
|
|
|
|
|
(switch-to-buffer (find-file-noselect file t))
|
2006-02-11 18:42:56 +00:00
|
|
|
|
(let ((inhibit-read-only t)
|
1999-05-24 02:09:27 +00:00
|
|
|
|
;; Keep the current buffer-file-coding-system.
|
|
|
|
|
(coding-system buffer-file-coding-system)
|
2006-05-16 03:35:46 +00:00
|
|
|
|
;; Auto-saved file should be read with special coding.
|
2003-05-31 02:00:26 +00:00
|
|
|
|
(coding-system-for-read 'auto-save-coding))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(erase-buffer)
|
1999-05-24 02:09:27 +00:00
|
|
|
|
(insert-file-contents file-name nil)
|
|
|
|
|
(set-buffer-file-coding-system coding-system))
|
1992-09-24 07:23:59 +00:00
|
|
|
|
(after-find-file nil nil t))
|
1997-04-21 04:48:47 +00:00
|
|
|
|
(t (error "Recover-file cancelled")))))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1995-05-07 18:39:02 +00:00
|
|
|
|
(defun recover-session ()
|
1995-04-30 19:46:44 +00:00
|
|
|
|
"Recover auto save files from a previous Emacs session.
|
|
|
|
|
This command first displays a Dired buffer showing you the
|
|
|
|
|
previous sessions that you could recover from.
|
|
|
|
|
To choose one, move point to the proper line and then type C-c C-c.
|
|
|
|
|
Then you'll be asked about a number of files to recover."
|
|
|
|
|
(interactive)
|
1996-10-02 10:26:51 +00:00
|
|
|
|
(if (null auto-save-list-file-prefix)
|
|
|
|
|
(error "You set `auto-save-list-file-prefix' to disable making session files"))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(let ((dir (file-name-directory auto-save-list-file-prefix)))
|
|
|
|
|
(unless (file-directory-p dir)
|
2003-03-14 22:38:46 +00:00
|
|
|
|
(make-directory dir t))
|
|
|
|
|
(unless (directory-files dir nil
|
|
|
|
|
(concat "\\`" (regexp-quote
|
|
|
|
|
(file-name-nondirectory
|
|
|
|
|
auto-save-list-file-prefix)))
|
|
|
|
|
t)
|
|
|
|
|
(error "No previous sessions to recover")))
|
1995-12-28 19:24:16 +00:00
|
|
|
|
(let ((ls-lisp-support-shell-wildcards t))
|
1997-03-22 03:42:32 +00:00
|
|
|
|
(dired (concat auto-save-list-file-prefix "*")
|
|
|
|
|
(concat dired-listing-switches "t")))
|
1999-01-04 11:57:27 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(or (looking-at " Move to the session you want to recover,")
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
;; Each line starts with a space
|
|
|
|
|
;; so that Font Lock mode won't highlight the first character.
|
|
|
|
|
(insert " Move to the session you want to recover,\n"
|
|
|
|
|
" then type C-c C-c to select it.\n\n"
|
|
|
|
|
" You can also delete some of these files;\n"
|
|
|
|
|
" type d on a line to mark that file for deletion.\n\n"))))
|
1995-04-30 19:46:44 +00:00
|
|
|
|
(use-local-map (nconc (make-sparse-keymap) (current-local-map)))
|
1995-06-01 23:18:04 +00:00
|
|
|
|
(define-key (current-local-map) "\C-c\C-c" 'recover-session-finish))
|
1995-04-30 19:46:44 +00:00
|
|
|
|
|
1995-06-01 23:18:04 +00:00
|
|
|
|
(defun recover-session-finish ()
|
1995-04-30 19:46:44 +00:00
|
|
|
|
"Choose one saved session to recover auto-save files from.
|
|
|
|
|
This command is used in the special Dired buffer created by
|
1995-06-01 23:18:04 +00:00
|
|
|
|
\\[recover-session]."
|
1995-04-30 19:46:44 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
;; Get the name of the session file to recover from.
|
|
|
|
|
(let ((file (dired-get-filename))
|
1995-10-04 18:34:14 +00:00
|
|
|
|
files
|
1995-04-30 19:46:44 +00:00
|
|
|
|
(buffer (get-buffer-create " *recover*")))
|
1998-05-16 03:38:20 +00:00
|
|
|
|
(dired-unmark 1)
|
1995-08-01 23:34:53 +00:00
|
|
|
|
(dired-do-flagged-delete t)
|
1995-04-30 19:46:44 +00:00
|
|
|
|
(unwind-protect
|
2010-02-28 01:11:15 +00:00
|
|
|
|
(with-current-buffer buffer
|
1995-04-30 19:46:44 +00:00
|
|
|
|
;; Read in the auto-save-list file.
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(insert-file-contents file)
|
1995-10-04 18:34:14 +00:00
|
|
|
|
;; Loop thru the text of that file
|
|
|
|
|
;; and get out the names of the files to recover.
|
|
|
|
|
(while (not (eobp))
|
|
|
|
|
(let (thisfile autofile)
|
|
|
|
|
(if (eolp)
|
|
|
|
|
;; This is a pair of lines for a non-file-visiting buffer.
|
|
|
|
|
;; Get the auto-save file name and manufacture
|
|
|
|
|
;; a "visited file name" from that.
|
|
|
|
|
(progn
|
|
|
|
|
(forward-line 1)
|
2003-06-16 21:24:07 +00:00
|
|
|
|
;; If there is no auto-save file name, the
|
|
|
|
|
;; auto-save-list file is probably corrupted.
|
|
|
|
|
(unless (eolp)
|
|
|
|
|
(setq autofile
|
|
|
|
|
(buffer-substring-no-properties
|
|
|
|
|
(point)
|
2006-07-02 14:26:53 +00:00
|
|
|
|
(line-end-position)))
|
2003-06-16 21:24:07 +00:00
|
|
|
|
(setq thisfile
|
|
|
|
|
(expand-file-name
|
|
|
|
|
(substring
|
|
|
|
|
(file-name-nondirectory autofile)
|
|
|
|
|
1 -1)
|
|
|
|
|
(file-name-directory autofile))))
|
1995-10-04 18:34:14 +00:00
|
|
|
|
(forward-line 1))
|
|
|
|
|
;; This pair of lines is a file-visiting
|
|
|
|
|
;; buffer. Use the visited file name.
|
|
|
|
|
(progn
|
|
|
|
|
(setq thisfile
|
|
|
|
|
(buffer-substring-no-properties
|
|
|
|
|
(point) (progn (end-of-line) (point))))
|
|
|
|
|
(forward-line 1)
|
|
|
|
|
(setq autofile
|
|
|
|
|
(buffer-substring-no-properties
|
|
|
|
|
(point) (progn (end-of-line) (point))))
|
|
|
|
|
(forward-line 1)))
|
|
|
|
|
;; Ignore a file if its auto-save file does not exist now.
|
2003-06-16 21:24:07 +00:00
|
|
|
|
(if (and autofile (file-exists-p autofile))
|
1995-10-04 18:34:14 +00:00
|
|
|
|
(setq files (cons thisfile files)))))
|
|
|
|
|
(setq files (nreverse files))
|
1995-08-13 16:48:13 +00:00
|
|
|
|
;; The file contains a pair of line for each auto-saved buffer.
|
|
|
|
|
;; The first line of the pair contains the visited file name
|
|
|
|
|
;; or is empty if the buffer was not visiting a file.
|
|
|
|
|
;; The second line is the auto-save file name.
|
1995-10-04 18:34:14 +00:00
|
|
|
|
(if files
|
|
|
|
|
(map-y-or-n-p "Recover %s? "
|
|
|
|
|
(lambda (file)
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(save-excursion (recover-file file))
|
1995-12-24 09:25:19 +00:00
|
|
|
|
(error
|
1995-10-04 18:34:14 +00:00
|
|
|
|
"Failed to recover `%s'" file)))
|
|
|
|
|
files
|
|
|
|
|
'("file" "files" "recover"))
|
|
|
|
|
(message "No files can be recovered from this session now")))
|
1995-04-30 19:46:44 +00:00
|
|
|
|
(kill-buffer buffer))))
|
|
|
|
|
|
2007-06-03 18:51:42 +00:00
|
|
|
|
(defun kill-buffer-ask (buffer)
|
2008-11-14 13:05:18 +00:00
|
|
|
|
"Kill BUFFER if confirmed."
|
2007-06-03 18:51:42 +00:00
|
|
|
|
(when (yes-or-no-p
|
|
|
|
|
(format "Buffer %s %s. Kill? " (buffer-name buffer)
|
|
|
|
|
(if (buffer-modified-p buffer)
|
|
|
|
|
"HAS BEEN EDITED" "is unmodified")))
|
|
|
|
|
(kill-buffer buffer)))
|
|
|
|
|
|
1996-08-29 01:27:18 +00:00
|
|
|
|
(defun kill-some-buffers (&optional list)
|
2003-12-29 14:04:31 +00:00
|
|
|
|
"Kill some buffers. Asks the user whether to kill each one of them.
|
2004-11-01 07:56:17 +00:00
|
|
|
|
Non-interactively, if optional argument LIST is non-nil, it
|
2003-12-29 14:04:31 +00:00
|
|
|
|
specifies the list of buffers to kill, asking for approval for each one."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive)
|
1996-08-29 01:27:18 +00:00
|
|
|
|
(if (null list)
|
|
|
|
|
(setq list (buffer-list)))
|
|
|
|
|
(while list
|
|
|
|
|
(let* ((buffer (car list))
|
|
|
|
|
(name (buffer-name buffer)))
|
2005-07-08 22:53:47 +00:00
|
|
|
|
(and name ; Can be nil for an indirect buffer
|
|
|
|
|
; if we killed the base buffer.
|
|
|
|
|
(not (string-equal name ""))
|
2005-07-20 01:57:49 +00:00
|
|
|
|
(/= (aref name 0) ?\s)
|
2007-06-03 18:51:42 +00:00
|
|
|
|
(kill-buffer-ask buffer)))
|
1996-08-29 01:27:18 +00:00
|
|
|
|
(setq list (cdr list))))
|
2007-06-03 18:51:42 +00:00
|
|
|
|
|
|
|
|
|
(defun kill-matching-buffers (regexp &optional internal-too)
|
2008-11-14 13:05:18 +00:00
|
|
|
|
"Kill buffers whose name matches the specified REGEXP.
|
2007-06-03 18:51:42 +00:00
|
|
|
|
The optional second argument indicates whether to kill internal buffers too."
|
|
|
|
|
(interactive "sKill buffers matching this regular expression: \nP")
|
|
|
|
|
(dolist (buffer (buffer-list))
|
|
|
|
|
(let ((name (buffer-name buffer)))
|
|
|
|
|
(when (and name (not (string-equal name ""))
|
|
|
|
|
(or internal-too (/= (aref name 0) ?\s))
|
|
|
|
|
(string-match regexp name))
|
|
|
|
|
(kill-buffer-ask buffer)))))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun rename-auto-save-file ()
|
|
|
|
|
"Adjust current buffer's auto save file name for current conditions.
|
|
|
|
|
Also rename any existing auto save file, if it was made in this session."
|
|
|
|
|
(let ((osave buffer-auto-save-file-name))
|
|
|
|
|
(setq buffer-auto-save-file-name
|
|
|
|
|
(make-auto-save-file-name))
|
|
|
|
|
(if (and osave buffer-auto-save-file-name
|
|
|
|
|
(not (string= buffer-auto-save-file-name buffer-file-name))
|
|
|
|
|
(not (string= buffer-auto-save-file-name osave))
|
|
|
|
|
(file-exists-p osave)
|
|
|
|
|
(recent-auto-save-p))
|
|
|
|
|
(rename-file osave buffer-auto-save-file-name t))))
|
|
|
|
|
|
|
|
|
|
(defun make-auto-save-file-name ()
|
|
|
|
|
"Return file name to use for auto-saves of current buffer.
|
|
|
|
|
Does not consider `auto-save-visited-file-name' as that variable is checked
|
|
|
|
|
before calling this function. You can redefine this for customization.
|
|
|
|
|
See also `auto-save-file-name-p'."
|
|
|
|
|
(if buffer-file-name
|
2005-08-30 22:41:02 +00:00
|
|
|
|
(let ((handler (find-file-name-handler buffer-file-name
|
|
|
|
|
'make-auto-save-file-name)))
|
|
|
|
|
(if handler
|
|
|
|
|
(funcall handler 'make-auto-save-file-name)
|
|
|
|
|
(let ((list auto-save-file-name-transforms)
|
|
|
|
|
(filename buffer-file-name)
|
|
|
|
|
result uniq)
|
|
|
|
|
;; Apply user-specified translations
|
|
|
|
|
;; to the file name.
|
|
|
|
|
(while (and list (not result))
|
|
|
|
|
(if (string-match (car (car list)) filename)
|
|
|
|
|
(setq result (replace-match (cadr (car list)) t nil
|
|
|
|
|
filename)
|
|
|
|
|
uniq (car (cddr (car list)))))
|
|
|
|
|
(setq list (cdr list)))
|
|
|
|
|
(if result
|
|
|
|
|
(if uniq
|
|
|
|
|
(setq filename (concat
|
|
|
|
|
(file-name-directory result)
|
|
|
|
|
(subst-char-in-string
|
|
|
|
|
?/ ?!
|
|
|
|
|
(replace-regexp-in-string "!" "!!"
|
|
|
|
|
filename))))
|
|
|
|
|
(setq filename result)))
|
|
|
|
|
(setq result
|
|
|
|
|
(if (and (eq system-type 'ms-dos)
|
|
|
|
|
(not (msdos-long-file-names)))
|
|
|
|
|
;; We truncate the file name to DOS 8+3 limits
|
|
|
|
|
;; before doing anything else, because the regexp
|
|
|
|
|
;; passed to string-match below cannot handle
|
|
|
|
|
;; extensions longer than 3 characters, multiple
|
|
|
|
|
;; dots, and other atrocities.
|
|
|
|
|
(let ((fn (dos-8+3-filename
|
|
|
|
|
(file-name-nondirectory buffer-file-name))))
|
|
|
|
|
(string-match
|
|
|
|
|
"\\`\\([^.]+\\)\\(\\.\\(..?\\)?.?\\|\\)\\'"
|
|
|
|
|
fn)
|
|
|
|
|
(concat (file-name-directory buffer-file-name)
|
|
|
|
|
"#" (match-string 1 fn)
|
|
|
|
|
"." (match-string 3 fn) "#"))
|
|
|
|
|
(concat (file-name-directory filename)
|
|
|
|
|
"#"
|
|
|
|
|
(file-name-nondirectory filename)
|
|
|
|
|
"#")))
|
|
|
|
|
;; Make sure auto-save file names don't contain characters
|
|
|
|
|
;; invalid for the underlying filesystem.
|
2006-07-29 12:05:28 +00:00
|
|
|
|
(if (and (memq system-type '(ms-dos windows-nt cygwin))
|
2005-08-30 22:41:02 +00:00
|
|
|
|
;; Don't modify remote (ange-ftp) filenames
|
|
|
|
|
(not (string-match "^/\\w+@[-A-Za-z0-9._]+:" result)))
|
|
|
|
|
(convert-standard-filename result)
|
|
|
|
|
result))))
|
1994-06-17 21:42:34 +00:00
|
|
|
|
|
|
|
|
|
;; Deal with buffers that don't have any associated files. (Mail
|
|
|
|
|
;; mode tends to create a good number of these.)
|
|
|
|
|
|
1994-06-15 02:43:39 +00:00
|
|
|
|
(let ((buffer-name (buffer-name))
|
2002-05-14 05:36:44 +00:00
|
|
|
|
(limit 0)
|
2002-06-11 19:25:48 +00:00
|
|
|
|
file-name)
|
2008-02-26 16:52:02 +00:00
|
|
|
|
;; Restrict the characters used in the file name to those which
|
|
|
|
|
;; are known to be safe on all filesystems, url-encoding the
|
|
|
|
|
;; rest.
|
|
|
|
|
;; We do this on all platforms, because even if we are not
|
|
|
|
|
;; running on DOS/Windows, the current directory may be on a
|
|
|
|
|
;; mounted VFAT filesystem, such as a USB memory stick.
|
|
|
|
|
(while (string-match "[^A-Za-z0-9-_.~#+]" buffer-name limit)
|
1997-03-29 00:32:54 +00:00
|
|
|
|
(let* ((character (aref buffer-name (match-beginning 0)))
|
|
|
|
|
(replacement
|
2008-02-26 16:52:02 +00:00
|
|
|
|
;; For multibyte characters, this will produce more than
|
|
|
|
|
;; 2 hex digits, so is not true URL encoding.
|
|
|
|
|
(format "%%%02X" character)))
|
1997-03-29 00:32:54 +00:00
|
|
|
|
(setq buffer-name (replace-match replacement t t buffer-name))
|
|
|
|
|
(setq limit (1+ (match-end 0)))))
|
1996-09-01 00:20:33 +00:00
|
|
|
|
;; Generate the file name.
|
2002-05-14 05:36:44 +00:00
|
|
|
|
(setq file-name
|
|
|
|
|
(make-temp-file
|
|
|
|
|
(let ((fname
|
|
|
|
|
(expand-file-name
|
|
|
|
|
(format "#%s#" buffer-name)
|
|
|
|
|
;; Try a few alternative directories, to get one we can
|
|
|
|
|
;; write it.
|
|
|
|
|
(cond
|
|
|
|
|
((file-writable-p default-directory) default-directory)
|
|
|
|
|
((file-writable-p "/var/tmp/") "/var/tmp/")
|
|
|
|
|
("~/")))))
|
2006-07-29 12:05:28 +00:00
|
|
|
|
(if (and (memq system-type '(ms-dos windows-nt cygwin))
|
2002-05-14 05:36:44 +00:00
|
|
|
|
;; Don't modify remote (ange-ftp) filenames
|
|
|
|
|
(not (string-match "^/\\w+@[-A-Za-z0-9._]+:" fname)))
|
|
|
|
|
;; The call to convert-standard-filename is in case
|
|
|
|
|
;; buffer-name includes characters not allowed by the
|
|
|
|
|
;; DOS/Windows filesystems. make-temp-file writes to the
|
|
|
|
|
;; file it creates, so we must fix the file name _before_
|
|
|
|
|
;; make-temp-file is called.
|
|
|
|
|
(convert-standard-filename fname)
|
|
|
|
|
fname))
|
|
|
|
|
nil "#"))
|
|
|
|
|
;; make-temp-file creates the file,
|
|
|
|
|
;; but we don't want it to exist until we do an auto-save.
|
|
|
|
|
(condition-case ()
|
|
|
|
|
(delete-file file-name)
|
|
|
|
|
(file-error nil))
|
|
|
|
|
file-name)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(defun auto-save-file-name-p (filename)
|
|
|
|
|
"Return non-nil if FILENAME can be yielded by `make-auto-save-file-name'.
|
|
|
|
|
FILENAME should lack slashes. You can redefine this for customization."
|
|
|
|
|
(string-match "^#.*#$" filename))
|
|
|
|
|
|
1995-12-28 19:24:16 +00:00
|
|
|
|
(defun wildcard-to-regexp (wildcard)
|
|
|
|
|
"Given a shell file name pattern WILDCARD, return an equivalent regexp.
|
2007-08-08 07:40:09 +00:00
|
|
|
|
The generated regexp will match a filename only if the filename
|
1995-12-28 19:24:16 +00:00
|
|
|
|
matches that wildcard according to shell rules. Only wildcards known
|
|
|
|
|
by `sh' are supported."
|
|
|
|
|
(let* ((i (string-match "[[.*+\\^$?]" wildcard))
|
|
|
|
|
;; Copy the initial run of non-special characters.
|
|
|
|
|
(result (substring wildcard 0 i))
|
|
|
|
|
(len (length wildcard)))
|
|
|
|
|
;; If no special characters, we're almost done.
|
|
|
|
|
(if i
|
|
|
|
|
(while (< i len)
|
|
|
|
|
(let ((ch (aref wildcard i))
|
|
|
|
|
j)
|
|
|
|
|
(setq
|
|
|
|
|
result
|
|
|
|
|
(concat result
|
|
|
|
|
(cond
|
1996-11-09 09:04:52 +00:00
|
|
|
|
((and (eq ch ?\[)
|
|
|
|
|
(< (1+ i) len)
|
|
|
|
|
(eq (aref wildcard (1+ i)) ?\]))
|
|
|
|
|
"\\[")
|
1995-12-28 19:24:16 +00:00
|
|
|
|
((eq ch ?\[) ; [...] maps to regexp char class
|
|
|
|
|
(progn
|
|
|
|
|
(setq i (1+ i))
|
|
|
|
|
(concat
|
|
|
|
|
(cond
|
|
|
|
|
((eq (aref wildcard i) ?!) ; [!...] -> [^...]
|
|
|
|
|
(progn
|
|
|
|
|
(setq i (1+ i))
|
|
|
|
|
(if (eq (aref wildcard i) ?\])
|
|
|
|
|
(progn
|
|
|
|
|
(setq i (1+ i))
|
|
|
|
|
"[^]")
|
|
|
|
|
"[^")))
|
|
|
|
|
((eq (aref wildcard i) ?^)
|
|
|
|
|
;; Found "[^". Insert a `\0' character
|
|
|
|
|
;; (which cannot happen in a filename)
|
|
|
|
|
;; into the character class, so that `^'
|
|
|
|
|
;; is not the first character after `[',
|
|
|
|
|
;; and thus non-special in a regexp.
|
|
|
|
|
(progn
|
|
|
|
|
(setq i (1+ i))
|
|
|
|
|
"[\000^"))
|
|
|
|
|
((eq (aref wildcard i) ?\])
|
|
|
|
|
;; I don't think `]' can appear in a
|
|
|
|
|
;; character class in a wildcard, but
|
|
|
|
|
;; let's be general here.
|
|
|
|
|
(progn
|
|
|
|
|
(setq i (1+ i))
|
|
|
|
|
"[]"))
|
|
|
|
|
(t "["))
|
|
|
|
|
(prog1 ; copy everything upto next `]'.
|
|
|
|
|
(substring wildcard
|
|
|
|
|
i
|
|
|
|
|
(setq j (string-match
|
|
|
|
|
"]" wildcard i)))
|
|
|
|
|
(setq i (if j (1- j) (1- len)))))))
|
|
|
|
|
((eq ch ?.) "\\.")
|
|
|
|
|
((eq ch ?*) "[^\000]*")
|
|
|
|
|
((eq ch ?+) "\\+")
|
|
|
|
|
((eq ch ?^) "\\^")
|
|
|
|
|
((eq ch ?$) "\\$")
|
|
|
|
|
((eq ch ?\\) "\\\\") ; probably cannot happen...
|
|
|
|
|
((eq ch ??) "[^\000]")
|
|
|
|
|
(t (char-to-string ch)))))
|
|
|
|
|
(setq i (1+ i)))))
|
|
|
|
|
;; Shell wildcards should match the entire filename,
|
|
|
|
|
;; not its part. Make the regexp say so.
|
|
|
|
|
(concat "\\`" result "\\'")))
|
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom list-directory-brief-switches
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(purecopy "-CF")
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Switches for `list-directory' to pass to `ls' for brief listing."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'string
|
|
|
|
|
:group 'dired)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1997-05-05 22:04:00 +00:00
|
|
|
|
(defcustom list-directory-verbose-switches
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(purecopy "-l")
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Switches for `list-directory' to pass to `ls' for verbose listing."
|
1997-05-05 22:04:00 +00:00
|
|
|
|
:type 'string
|
|
|
|
|
:group 'dired)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
1998-10-16 19:20:55 +00:00
|
|
|
|
(defun file-expand-wildcards (pattern &optional full)
|
|
|
|
|
"Expand wildcard pattern PATTERN.
|
1998-12-26 05:14:48 +00:00
|
|
|
|
This returns a list of file names which match the pattern.
|
|
|
|
|
|
2004-05-11 17:32:44 +00:00
|
|
|
|
If PATTERN is written as an absolute file name,
|
1998-12-26 05:14:48 +00:00
|
|
|
|
the values are absolute also.
|
|
|
|
|
|
|
|
|
|
If PATTERN is written as a relative file name, it is interpreted
|
|
|
|
|
relative to the current default directory, `default-directory'.
|
|
|
|
|
The file names returned are normally also relative to the current
|
|
|
|
|
default directory. However, if FULL is non-nil, they are absolute."
|
2002-04-01 03:45:25 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(let* ((nondir (file-name-nondirectory pattern))
|
|
|
|
|
(dirpart (file-name-directory pattern))
|
|
|
|
|
;; A list of all dirs that DIRPART specifies.
|
|
|
|
|
;; This can be more than one dir
|
|
|
|
|
;; if DIRPART contains wildcards.
|
2009-12-17 13:18:03 +00:00
|
|
|
|
(dirs (if (and dirpart
|
|
|
|
|
(string-match "[[*?]"
|
|
|
|
|
(or (file-remote-p dirpart 'localname)
|
|
|
|
|
dirpart)))
|
2002-04-01 03:45:25 +00:00
|
|
|
|
(mapcar 'file-name-as-directory
|
|
|
|
|
(file-expand-wildcards (directory-file-name dirpart)))
|
|
|
|
|
(list dirpart)))
|
|
|
|
|
contents)
|
|
|
|
|
(while dirs
|
|
|
|
|
(when (or (null (car dirs)) ; Possible if DIRPART is not wild.
|
|
|
|
|
(file-directory-p (directory-file-name (car dirs))))
|
|
|
|
|
(let ((this-dir-contents
|
|
|
|
|
;; Filter out "." and ".."
|
|
|
|
|
(delq nil
|
|
|
|
|
(mapcar #'(lambda (name)
|
|
|
|
|
(unless (string-match "\\`\\.\\.?\\'"
|
|
|
|
|
(file-name-nondirectory name))
|
|
|
|
|
name))
|
|
|
|
|
(directory-files (or (car dirs) ".") full
|
|
|
|
|
(wildcard-to-regexp nondir))))))
|
|
|
|
|
(setq contents
|
|
|
|
|
(nconc
|
|
|
|
|
(if (and (car dirs) (not full))
|
|
|
|
|
(mapcar (function (lambda (name) (concat (car dirs) name)))
|
|
|
|
|
this-dir-contents)
|
|
|
|
|
this-dir-contents)
|
|
|
|
|
contents))))
|
|
|
|
|
(setq dirs (cdr dirs)))
|
|
|
|
|
contents)))
|
1998-10-16 19:20:55 +00:00
|
|
|
|
|
2009-12-17 13:18:03 +00:00
|
|
|
|
;; Let Tramp know that `file-expand-wildcards' does not need an advice.
|
|
|
|
|
(provide 'files '(remote-wildcards))
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun list-directory (dirname &optional verbose)
|
|
|
|
|
"Display a list of files in or matching DIRNAME, a la `ls'.
|
|
|
|
|
DIRNAME is globbed by the shell if necessary.
|
|
|
|
|
Prefix arg (second arg if noninteractive) means supply -l switch to `ls'.
|
|
|
|
|
Actions controlled by variables `list-directory-brief-switches'
|
|
|
|
|
and `list-directory-verbose-switches'."
|
|
|
|
|
(interactive (let ((pfx current-prefix-arg))
|
|
|
|
|
(list (read-file-name (if pfx "List directory (verbose): "
|
|
|
|
|
"List directory (brief): ")
|
|
|
|
|
nil default-directory nil)
|
|
|
|
|
pfx)))
|
|
|
|
|
(let ((switches (if verbose list-directory-verbose-switches
|
2002-03-18 04:30:45 +00:00
|
|
|
|
list-directory-brief-switches))
|
|
|
|
|
buffer)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(or dirname (setq dirname default-directory))
|
|
|
|
|
(setq dirname (expand-file-name dirname))
|
|
|
|
|
(with-output-to-temp-buffer "*Directory*"
|
2002-03-18 04:30:45 +00:00
|
|
|
|
(setq buffer standard-output)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(buffer-disable-undo standard-output)
|
|
|
|
|
(princ "Directory ")
|
|
|
|
|
(princ dirname)
|
|
|
|
|
(terpri)
|
* x-dnd.el (x-dnd-maybe-call-test-function):
* window.el (split-window-vertically):
* whitespace.el (whitespace-help-on):
* vc-rcs.el (vc-rcs-consult-headers):
* userlock.el (ask-user-about-lock-help)
(ask-user-about-supersession-help):
* type-break.el (type-break-force-mode-line-update):
* time-stamp.el (time-stamp-conv-warn):
* terminal.el (te-set-output-log, te-more-break, te-filter)
(te-sentinel,terminal-emulator):
* term.el (make-term, term-exec, term-sentinel, term-read-input-ring)
(term-write-input-ring, term-check-source, term-start-output-log):
(term-display-buffer-line, term-dynamic-list-completions):
(term-ansi-make-term, serial-term):
* subr.el (selective-display):
* strokes.el (strokes-xpm-to-compressed-string, strokes-decode-buffer)
(strokes-encode-buffer, strokes-xpm-for-compressed-string):
* speedbar.el (speedbar-buffers-tail-notes, speedbar-buffers-item-info)
(speedbar-reconfigure-keymaps, speedbar-add-localized-speedbar-support)
(speedbar-remove-localized-speedbar-support)
(speedbar-set-mode-line-format, speedbar-create-tag-hierarchy)
(speedbar-update-special-contents, speedbar-buffer-buttons-engine)
(speedbar-buffers-line-directory):
* simple.el (shell-command-on-region, append-to-buffer)
(prepend-to-buffer):
* shadowfile.el (shadow-save-todo-file):
* scroll-bar.el (scroll-bar-set-window-start, scroll-bar-drag-1)
(scroll-bar-maybe-set-window-start):
* sb-image.el (speedbar-image-dump):
* saveplace.el (save-place-alist-to-file, save-places-to-alist)
(load-save-place-alist-from-file):
* ps-samp.el (ps-print-message-from-summary):
* ps-print.el (ps-flush-output, ps-insert-file, ps-get-boundingbox)
(ps-background-image, ps-begin-job, ps-do-despool):
* ps-bdf.el (bdf-find-file, bdf-read-font-info):
* printing.el (pr-interface, pr-ps-file-print, pr-find-buffer-visiting)
(pr-ps-message-from-summary, pr-lpr-message-from-summary):
(pr-call-process, pr-file-list, pr-interface-save):
* novice.el (disabled-command-function)
(enable-command, disable-command):
* mouse.el (mouse-buffer-menu-alist):
* mouse-copy.el (mouse-kill-preserving-secondary):
* macros.el (kbd-macro-query):
* ledit.el (ledit-go-to-lisp, ledit-go-to-liszt):
* informat.el (batch-info-validate):
* ido.el (ido-copy-current-word, ido-initiate-auto-merge):
* hippie-exp.el (try-expand-dabbrev-visible):
* help-mode.el (help-make-xrefs):
* help-fns.el (describe-variable):
* generic-x.el (bat-generic-mode-run-as-comint):
* finder.el (finder-mouse-select):
* find-dired.el (find-dired-sentinel):
* filesets.el (filesets-file-close):
* files.el (list-directory):
* faces.el (list-faces-display, describe-face):
* facemenu.el (list-colors-display):
* ezimage.el (ezimage-image-association-dump, ezimage-image-dump):
* epg.el (epg--process-filter, epg-cancel):
* epa.el (epa--marked-keys, epa--select-keys, epa-display-info)
(epa--read-signature-type):
* emerge.el (emerge-copy-as-kill-A, emerge-copy-as-kill-B)
(emerge-file-names):
* ehelp.el (electric-helpify):
* ediff.el (ediff-regions-wordwise, ediff-regions-linewise):
* ediff-vers.el (rcs-ediff-view-revision):
* ediff-util.el (ediff-setup):
* ediff-mult.el (ediff-append-custom-diff):
* ediff-diff.el (ediff-exec-process, ediff-process-sentinel)
(ediff-wordify):
* echistory.el (Electric-command-history-redo-expression):
* dos-w32.el (find-file-not-found-set-buffer-file-coding-system):
* disp-table.el (describe-display-table):
* dired.el (dired-find-buffer-nocreate):
* dired-aux.el (dired-rename-subdir, dired-dwim-target-directory):
* dabbrev.el (dabbrev--same-major-mode-p):
* chistory.el (list-command-history):
* apropos.el (apropos-documentation):
* allout.el (allout-obtain-passphrase):
(allout-copy-exposed-to-buffer):
(allout-verify-passphrase): Use with-current-buffer.
2009-11-13 22:19:45 +00:00
|
|
|
|
(with-current-buffer "*Directory*"
|
1992-09-13 04:35:22 +00:00
|
|
|
|
(let ((wildcard (not (file-directory-p dirname))))
|
2002-03-18 04:30:45 +00:00
|
|
|
|
(insert-directory dirname switches wildcard (not wildcard)))))
|
|
|
|
|
;; Finishing with-output-to-temp-buffer seems to clobber default-directory.
|
|
|
|
|
(with-current-buffer buffer
|
|
|
|
|
(setq default-directory
|
|
|
|
|
(if (file-directory-p dirname)
|
|
|
|
|
(file-name-as-directory dirname)
|
|
|
|
|
(file-name-directory dirname))))))
|
1992-09-13 04:35:22 +00:00
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(defun shell-quote-wildcard-pattern (pattern)
|
|
|
|
|
"Quote characters special to the shell in PATTERN, leave wildcards alone.
|
|
|
|
|
|
|
|
|
|
PATTERN is assumed to represent a file-name wildcard suitable for the
|
2009-03-28 12:27:52 +00:00
|
|
|
|
underlying filesystem. For Unix and GNU/Linux, each character from the
|
|
|
|
|
set [ \\t\\n;<>&|()'\"#$] is quoted with a backslash; for DOS/Windows, all
|
2000-10-04 17:16:59 +00:00
|
|
|
|
the parts of the pattern which don't include wildcard characters are
|
|
|
|
|
quoted with double quotes.
|
2009-03-28 12:27:52 +00:00
|
|
|
|
|
|
|
|
|
This function leaves alone existing quote characters (\\ on Unix and \"
|
|
|
|
|
on Windows), so PATTERN can use them to quote wildcard characters that
|
|
|
|
|
need to be passed verbatim to shell commands."
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(cond
|
2003-01-31 15:24:20 +00:00
|
|
|
|
((memq system-type '(ms-dos windows-nt cygwin))
|
2000-10-04 17:16:59 +00:00
|
|
|
|
;; DOS/Windows don't allow `"' in file names. So if the
|
|
|
|
|
;; argument has quotes, we can safely assume it is already
|
|
|
|
|
;; quoted by the caller.
|
|
|
|
|
(if (or (string-match "[\"]" pattern)
|
|
|
|
|
;; We quote [&()#$'] in case their shell is a port of a
|
|
|
|
|
;; Unixy shell. We quote [,=+] because stock DOS and
|
|
|
|
|
;; Windows shells require that in some cases, such as
|
|
|
|
|
;; passing arguments to batch files that use positional
|
|
|
|
|
;; arguments like %1.
|
|
|
|
|
(not (string-match "[ \t;&()#$',=+]" pattern)))
|
|
|
|
|
pattern
|
|
|
|
|
(let ((result "\"")
|
|
|
|
|
(beg 0)
|
|
|
|
|
end)
|
|
|
|
|
(while (string-match "[*?]+" pattern beg)
|
|
|
|
|
(setq end (match-beginning 0)
|
|
|
|
|
result (concat result (substring pattern beg end)
|
|
|
|
|
"\""
|
|
|
|
|
(substring pattern end (match-end 0))
|
|
|
|
|
"\"")
|
|
|
|
|
beg (match-end 0)))
|
|
|
|
|
(concat result (substring pattern beg) "\""))))
|
|
|
|
|
(t
|
|
|
|
|
(let ((beg 0))
|
2008-02-25 17:42:13 +00:00
|
|
|
|
(while (string-match "[ \t\n;<>&|()'\"#$]" pattern beg)
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(setq pattern
|
|
|
|
|
(concat (substring pattern 0 (match-beginning 0))
|
|
|
|
|
"\\"
|
|
|
|
|
(substring pattern (match-beginning 0)))
|
|
|
|
|
beg (1+ (match-end 0)))))
|
|
|
|
|
pattern))))
|
|
|
|
|
|
|
|
|
|
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(defvar insert-directory-program (purecopy "ls")
|
1992-09-13 04:35:22 +00:00
|
|
|
|
"Absolute or relative name of the `ls' program used by `insert-directory'.")
|
|
|
|
|
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(defcustom directory-free-space-program (purecopy "df")
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Program to get the amount of free space on a file system.
|
2001-12-18 19:35:09 +00:00
|
|
|
|
We assume the output has the format of `df'.
|
|
|
|
|
The value of this variable must be just a command name or file name;
|
|
|
|
|
if you want to specify options, use `directory-free-space-args'.
|
|
|
|
|
|
2001-12-21 15:20:42 +00:00
|
|
|
|
A value of nil disables this feature.
|
|
|
|
|
|
|
|
|
|
If the function `file-system-info' is defined, it is always used in
|
|
|
|
|
preference to the program given by this variable."
|
2001-12-18 19:35:09 +00:00
|
|
|
|
:type '(choice (string :tag "Program") (const :tag "None" nil))
|
|
|
|
|
:group 'dired)
|
|
|
|
|
|
2002-06-30 14:42:19 +00:00
|
|
|
|
(defcustom directory-free-space-args
|
* textmodes/tex-mode.el (tex-alt-dvi-print-command)
(tex-dvi-print-command, tex-bibtex-command, tex-start-commands)
(tex-start-options, slitex-run-command, latex-run-command)
(tex-run-command, tex-directory):
* textmodes/ispell.el (ispell-html-skip-alists)
(ispell-tex-skip-alists, ispell-tex-skip-alists):
* textmodes/fill.el (adaptive-fill-first-line-regexp):
(adaptive-fill-regexp):
* textmodes/dns-mode.el (auto-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/etags.el (tags-compression-info-list):
* progmodes/etags.el (tags-file-name):
* net/browse-url.el (browse-url-galeon-program)
(browse-url-firefox-program):
* mail/sendmail.el (mail-signature-file)
(mail-citation-prefix-regexp):
* international/mule-conf.el (eight-bit):
* international/latexenc.el (latex-inputenc-coding-alist):
* international/fontset.el (x-pixel-size-width-font-regexp):
* emacs-lisp/warnings.el (warning-type-format):
* emacs-lisp/trace.el (trace-buffer):
* emacs-lisp/lisp-mode.el (lisp-interaction-mode-map)
(emacs-lisp-mode-map):
* calendar/holidays.el (holiday-solar-holidays)
(holiday-bahai-holidays, holiday-islamic-holidays)
(holiday-christian-holidays, holiday-hebrew-holidays)
(hebrew-holidays-4, hebrew-holidays-3, hebrew-holidays-2)
(hebrew-holidays-1, holiday-oriental-holidays)
(holiday-general-holidays):
* x-dnd.el (x-dnd-known-types):
* tool-bar.el (tool-bar):
* startup.el (site-run-file):
* shell.el (shell-dumb-shell-regexp):
* rfn-eshadow.el (file-name-shadow-tty-properties)
(file-name-shadow-properties):
* paths.el (remote-shell-program, news-directory):
* mouse.el ([C-down-mouse-3]):
* menu-bar.el (menu-bar-tools-menu):
* jka-cmpr-hook.el (jka-compr-load-suffixes)
(jka-compr-mode-alist-additions, jka-compr-compression-info-list)
(jka-compr-compression-info-list):
* isearch.el (search-whitespace-regexp):
* image-file.el (image-file-name-extensions):
* find-dired.el (find-ls-option):
* files.el (directory-listing-before-filename-regexp)
(directory-free-space-args, insert-directory-program)
(list-directory-brief-switches, magic-fallback-mode-alist)
(magic-fallback-mode-alist, auto-mode-interpreter-regexp)
(automount-dir-prefix):
* faces.el (face-x-resources, x-font-regexp, x-font-regexp-head)
(x-font-regexp-slant, x-font-regexp-weight, face-x-resources)
(face-font-registry-alternatives, face-font-registry-alternatives)
(face-font-family-alternatives):
* facemenu.el (facemenu-add-new-face, facemenu-background-menu)
(facemenu-foreground-menu, facemenu-face-menu):
* epa-hook.el (epa-file-name-regexp):
* dnd.el (dnd-protocol-alist):
* textmodes/rst.el (auto-mode-alist):
* button.el (default-button): Purecopy strings.
2009-11-06 05:16:23 +00:00
|
|
|
|
(purecopy (if (eq system-type 'darwin) "-k" "-Pk"))
|
2006-07-16 04:28:10 +00:00
|
|
|
|
"Options to use when running `directory-free-space-program'."
|
2001-12-18 19:35:09 +00:00
|
|
|
|
:type 'string
|
|
|
|
|
:group 'dired)
|
|
|
|
|
|
2001-12-21 15:20:42 +00:00
|
|
|
|
(defun get-free-disk-space (dir)
|
2005-07-20 01:57:49 +00:00
|
|
|
|
"Return the amount of free space on directory DIR's file system.
|
2001-12-21 15:20:42 +00:00
|
|
|
|
The result is a string that gives the number of free 1KB blocks,
|
2005-07-20 01:57:49 +00:00
|
|
|
|
or nil if the system call or the program which retrieve the information
|
2007-01-30 20:23:38 +00:00
|
|
|
|
fail. It returns also nil when DIR is a remote directory.
|
2001-12-21 15:20:42 +00:00
|
|
|
|
|
|
|
|
|
This function calls `file-system-info' if it is available, or invokes the
|
|
|
|
|
program specified by `directory-free-space-program' if that is non-nil."
|
2009-08-16 00:31:28 +00:00
|
|
|
|
(unless (file-remote-p dir)
|
2007-01-30 20:23:38 +00:00
|
|
|
|
;; Try to find the number of free blocks. Non-Posix systems don't
|
|
|
|
|
;; always have df, but might have an equivalent system call.
|
|
|
|
|
(if (fboundp 'file-system-info)
|
|
|
|
|
(let ((fsinfo (file-system-info dir)))
|
|
|
|
|
(if fsinfo
|
|
|
|
|
(format "%.0f" (/ (nth 2 fsinfo) 1024))))
|
2009-08-29 14:58:15 +00:00
|
|
|
|
(setq dir (expand-file-name dir))
|
2007-01-30 20:23:38 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(when (and directory-free-space-program
|
2009-08-16 00:31:28 +00:00
|
|
|
|
;; Avoid failure if the default directory does
|
|
|
|
|
;; not exist (Bug#2631, Bug#3911).
|
2009-08-29 15:33:27 +00:00
|
|
|
|
(let ((default-directory "/"))
|
2009-03-15 02:31:45 +00:00
|
|
|
|
(eq (call-process directory-free-space-program
|
2007-01-30 20:23:38 +00:00
|
|
|
|
nil t nil
|
|
|
|
|
directory-free-space-args
|
2009-03-15 02:31:45 +00:00
|
|
|
|
dir)
|
|
|
|
|
0)))
|
2007-01-30 20:23:38 +00:00
|
|
|
|
;; Usual format is a header line followed by a line of
|
|
|
|
|
;; numbers.
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(forward-line 1)
|
|
|
|
|
(if (not (eobp))
|
|
|
|
|
(progn
|
|
|
|
|
;; Move to the end of the "available blocks" number.
|
|
|
|
|
(skip-chars-forward "^ \t")
|
|
|
|
|
(forward-word 3)
|
|
|
|
|
;; Copy it into AVAILABLE.
|
|
|
|
|
(let ((end (point)))
|
|
|
|
|
(forward-word -1)
|
|
|
|
|
(buffer-substring (point) end))))))))))
|
2001-12-21 15:20:42 +00:00
|
|
|
|
|
2005-10-23 12:17:28 +00:00
|
|
|
|
;; The following expression replaces `dired-move-to-filename-regexp'.
|
|
|
|
|
(defvar directory-listing-before-filename-regexp
|
|
|
|
|
(let* ((l "\\([A-Za-z]\\|[^\0-\177]\\)")
|
|
|
|
|
(l-or-quote "\\([A-Za-z']\\|[^\0-\177]\\)")
|
|
|
|
|
;; In some locales, month abbreviations are as short as 2 letters,
|
|
|
|
|
;; and they can be followed by ".".
|
|
|
|
|
;; In Breton, a month name can include a quote character.
|
|
|
|
|
(month (concat l-or-quote l-or-quote "+\\.?"))
|
|
|
|
|
(s " ")
|
|
|
|
|
(yyyy "[0-9][0-9][0-9][0-9]")
|
|
|
|
|
(dd "[ 0-3][0-9]")
|
|
|
|
|
(HH:MM "[ 0-2][0-9][:.][0-5][0-9]")
|
|
|
|
|
(seconds "[0-6][0-9]\\([.,][0-9]+\\)?")
|
|
|
|
|
(zone "[-+][0-2][0-9][0-5][0-9]")
|
|
|
|
|
(iso-mm-dd "[01][0-9]-[0-3][0-9]")
|
|
|
|
|
(iso-time (concat HH:MM "\\(:" seconds "\\( ?" zone "\\)?\\)?"))
|
|
|
|
|
(iso (concat "\\(\\(" yyyy "-\\)?" iso-mm-dd "[ T]" iso-time
|
|
|
|
|
"\\|" yyyy "-" iso-mm-dd "\\)"))
|
|
|
|
|
(western (concat "\\(" month s "+" dd "\\|" dd "\\.?" s month "\\)"
|
|
|
|
|
s "+"
|
|
|
|
|
"\\(" HH:MM "\\|" yyyy "\\)"))
|
|
|
|
|
(western-comma (concat month s "+" dd "," s "+" yyyy))
|
|
|
|
|
;; Japanese MS-Windows ls-lisp has one-digit months, and
|
|
|
|
|
;; omits the Kanji characters after month and day-of-month.
|
|
|
|
|
;; On Mac OS X 10.3, the date format in East Asian locales is
|
|
|
|
|
;; day-of-month digits followed by month digits.
|
|
|
|
|
(mm "[ 0-1]?[0-9]")
|
|
|
|
|
(east-asian
|
|
|
|
|
(concat "\\(" mm l "?" s dd l "?" s "+"
|
|
|
|
|
"\\|" dd s mm s "+" "\\)"
|
|
|
|
|
"\\(" HH:MM "\\|" yyyy l "?" "\\)")))
|
|
|
|
|
;; The "[0-9]" below requires the previous column to end in a digit.
|
|
|
|
|
;; This avoids recognizing `1 may 1997' as a date in the line:
|
|
|
|
|
;; -r--r--r-- 1 may 1997 1168 Oct 19 16:49 README
|
|
|
|
|
|
|
|
|
|
;; The "[BkKMGTPEZY]?" below supports "ls -alh" output.
|
2010-02-21 21:12:46 +00:00
|
|
|
|
|
|
|
|
|
;; For non-iso date formats, we add the ".*" in order to find
|
|
|
|
|
;; the last possible match. This avoids recognizing
|
|
|
|
|
;; `jservice 10 1024' as a date in the line:
|
2005-10-23 12:17:28 +00:00
|
|
|
|
;; drwxr-xr-x 3 jservice 10 1024 Jul 2 1997 esg-host
|
|
|
|
|
|
|
|
|
|
;; vc dired listings provide the state or blanks between file
|
|
|
|
|
;; permissions and date. The state is always surrounded by
|
|
|
|
|
;; parantheses:
|
|
|
|
|
;; -rw-r--r-- (modified) 2005-10-22 21:25 files.el
|
|
|
|
|
;; This is not supported yet.
|
2010-02-21 21:12:46 +00:00
|
|
|
|
(purecopy (concat "\\([0-9][BkKMGTPEZY]? " iso
|
|
|
|
|
"\\|.*[0-9][BkKMGTPEZY]? "
|
|
|
|
|
"\\(" western "\\|" western-comma "\\|" east-asian "\\)"
|
|
|
|
|
"\\) +")))
|
2005-10-23 12:17:28 +00:00
|
|
|
|
"Regular expression to match up to the file name in a directory listing.
|
|
|
|
|
The default value is designed to recognize dates and times
|
|
|
|
|
regardless of the language.")
|
2001-12-21 15:20:42 +00:00
|
|
|
|
|
2004-12-27 17:18:28 +00:00
|
|
|
|
(defvar insert-directory-ls-version 'unknown)
|
|
|
|
|
|
1992-09-13 04:35:22 +00:00
|
|
|
|
;; insert-directory
|
|
|
|
|
;; - must insert _exactly_one_line_ describing FILE if WILDCARD and
|
|
|
|
|
;; FULL-DIRECTORY-P is nil.
|
|
|
|
|
;; The single line of output must display FILE's name as it was
|
|
|
|
|
;; given, namely, an absolute path name.
|
|
|
|
|
;; - must insert exactly one line for each file if WILDCARD or
|
|
|
|
|
;; FULL-DIRECTORY-P is t, plus one optional "total" line
|
|
|
|
|
;; before the file lines, plus optional text after the file lines.
|
|
|
|
|
;; Lines are delimited by "\n", so filenames containing "\n" are not
|
|
|
|
|
;; allowed.
|
|
|
|
|
;; File lines should display the basename.
|
|
|
|
|
;; - must be consistent with
|
|
|
|
|
;; - functions dired-move-to-filename, (these two define what a file line is)
|
|
|
|
|
;; dired-move-to-end-of-filename,
|
|
|
|
|
;; dired-between-files, (shortcut for (not (dired-move-to-filename)))
|
|
|
|
|
;; dired-insert-headerline
|
|
|
|
|
;; dired-after-subdir-garbage (defines what a "total" line is)
|
|
|
|
|
;; - variable dired-subdir-regexp
|
2002-09-22 13:01:10 +00:00
|
|
|
|
;; - may be passed "--dired" as the first argument in SWITCHES.
|
|
|
|
|
;; Filename handlers might have to remove this switch if their
|
|
|
|
|
;; "ls" command does not support it.
|
1992-09-13 04:35:22 +00:00
|
|
|
|
(defun insert-directory (file switches &optional wildcard full-directory-p)
|
1993-07-18 06:40:09 +00:00
|
|
|
|
"Insert directory listing for FILE, formatted according to SWITCHES.
|
1992-09-13 04:35:22 +00:00
|
|
|
|
Leaves point after the inserted text.
|
2004-03-21 04:40:38 +00:00
|
|
|
|
SWITCHES may be a string of options, or a list of strings
|
|
|
|
|
representing individual options.
|
1992-09-13 04:35:22 +00:00
|
|
|
|
Optional third arg WILDCARD means treat FILE as shell wildcard.
|
|
|
|
|
Optional fourth arg FULL-DIRECTORY-P means file is a directory and
|
|
|
|
|
switches do not contain `d', so that a full listing is expected.
|
|
|
|
|
|
|
|
|
|
This works by running a directory listing program
|
1993-02-20 06:23:08 +00:00
|
|
|
|
whose name is in the variable `insert-directory-program'.
|
2004-03-21 04:40:38 +00:00
|
|
|
|
If WILDCARD, it also runs the shell specified by `shell-file-name'.
|
|
|
|
|
|
2004-04-17 01:46:53 +00:00
|
|
|
|
When SWITCHES contains the long `--dired' option, this function
|
2004-03-21 04:40:38 +00:00
|
|
|
|
treats it specially, for the sake of dired. However, the
|
|
|
|
|
normally equivalent short `-D' option is just passed on to
|
|
|
|
|
`insert-directory-program', as any other option."
|
1994-05-28 12:33:08 +00:00
|
|
|
|
;; We need the directory in order to find the right handler.
|
2000-08-17 12:08:26 +00:00
|
|
|
|
(let ((handler (find-file-name-handler (expand-file-name file)
|
|
|
|
|
'insert-directory)))
|
2001-12-03 00:02:52 +00:00
|
|
|
|
(if handler
|
1992-09-13 04:35:22 +00:00
|
|
|
|
(funcall handler 'insert-directory file switches
|
|
|
|
|
wildcard full-directory-p)
|
2003-04-17 21:15:04 +00:00
|
|
|
|
(let (result (beg (point)))
|
2001-12-03 00:02:52 +00:00
|
|
|
|
|
|
|
|
|
;; Read the actual directory using `insert-directory-program'.
|
|
|
|
|
;; RESULT gets the status code.
|
2003-01-23 05:59:47 +00:00
|
|
|
|
(let* (;; We at first read by no-conversion, then after
|
|
|
|
|
;; putting text property `dired-filename, decode one
|
|
|
|
|
;; bunch by one to preserve that property.
|
|
|
|
|
(coding-system-for-read 'no-conversion)
|
|
|
|
|
;; This is to control encoding the arguments in call-process.
|
2003-01-31 15:24:20 +00:00
|
|
|
|
(coding-system-for-write
|
2002-07-09 02:42:06 +00:00
|
|
|
|
(and enable-multibyte-characters
|
|
|
|
|
(or file-name-coding-system
|
2003-01-23 05:59:47 +00:00
|
|
|
|
default-file-name-coding-system))))
|
2001-12-03 00:02:52 +00:00
|
|
|
|
(setq result
|
|
|
|
|
(if wildcard
|
|
|
|
|
;; Run ls in the directory part of the file pattern
|
|
|
|
|
;; using the last component as argument.
|
|
|
|
|
(let ((default-directory
|
|
|
|
|
(if (file-name-absolute-p file)
|
|
|
|
|
(file-name-directory file)
|
|
|
|
|
(file-name-directory (expand-file-name file))))
|
|
|
|
|
(pattern (file-name-nondirectory file)))
|
|
|
|
|
(call-process
|
|
|
|
|
shell-file-name nil t nil
|
|
|
|
|
"-c"
|
|
|
|
|
(concat (if (memq system-type '(ms-dos windows-nt))
|
|
|
|
|
""
|
|
|
|
|
"\\") ; Disregard Unix shell aliases!
|
|
|
|
|
insert-directory-program
|
|
|
|
|
" -d "
|
|
|
|
|
(if (stringp switches)
|
|
|
|
|
switches
|
|
|
|
|
(mapconcat 'identity switches " "))
|
|
|
|
|
" -- "
|
|
|
|
|
;; Quote some characters that have
|
|
|
|
|
;; special meanings in shells; but
|
|
|
|
|
;; don't quote the wildcards--we want
|
|
|
|
|
;; them to be special. We also
|
|
|
|
|
;; currently don't quote the quoting
|
|
|
|
|
;; characters in case people want to
|
|
|
|
|
;; use them explicitly to quote
|
|
|
|
|
;; wildcard characters.
|
|
|
|
|
(shell-quote-wildcard-pattern pattern))))
|
|
|
|
|
;; SunOS 4.1.3, SVr4 and others need the "." to list the
|
|
|
|
|
;; directory if FILE is a symbolic link.
|
2010-02-14 09:23:52 +00:00
|
|
|
|
(unless full-directory-p
|
|
|
|
|
(setq switches
|
|
|
|
|
(if (stringp switches)
|
|
|
|
|
(concat switches " -d")
|
|
|
|
|
(add-to-list 'switches "-d" 'append))))
|
2001-12-03 00:02:52 +00:00
|
|
|
|
(apply 'call-process
|
|
|
|
|
insert-directory-program nil t nil
|
|
|
|
|
(append
|
|
|
|
|
(if (listp switches) switches
|
|
|
|
|
(unless (equal switches "")
|
|
|
|
|
;; Split the switches at any spaces so we can
|
|
|
|
|
;; pass separate options as separate args.
|
|
|
|
|
(split-string switches)))
|
|
|
|
|
;; Avoid lossage if FILE starts with `-'.
|
|
|
|
|
'("--")
|
|
|
|
|
(progn
|
|
|
|
|
(if (string-match "\\`~" file)
|
|
|
|
|
(setq file (expand-file-name file)))
|
|
|
|
|
(list
|
|
|
|
|
(if full-directory-p
|
|
|
|
|
(concat (file-name-as-directory file) ".")
|
|
|
|
|
file))))))))
|
|
|
|
|
|
2004-12-27 17:18:28 +00:00
|
|
|
|
;; If we got "//DIRED//" in the output, it means we got a real
|
|
|
|
|
;; directory listing, even if `ls' returned nonzero.
|
|
|
|
|
;; So ignore any errors.
|
|
|
|
|
(when (if (stringp switches)
|
|
|
|
|
(string-match "--dired\\>" switches)
|
|
|
|
|
(member "--dired" switches))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(forward-line -2)
|
|
|
|
|
(when (looking-at "//SUBDIRED//")
|
|
|
|
|
(forward-line -1))
|
|
|
|
|
(if (looking-at "//DIRED//")
|
|
|
|
|
(setq result 0))))
|
|
|
|
|
|
|
|
|
|
(when (and (not (eq 0 result))
|
|
|
|
|
(eq insert-directory-ls-version 'unknown))
|
|
|
|
|
;; The first time ls returns an error,
|
|
|
|
|
;; find the version numbers of ls,
|
|
|
|
|
;; and set insert-directory-ls-version
|
|
|
|
|
;; to > if it is more than 5.2.1, < if it is less, nil if it
|
|
|
|
|
;; is equal or if the info cannot be obtained.
|
|
|
|
|
;; (That can mean it isn't GNU ls.)
|
|
|
|
|
(let ((version-out
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(call-process "ls" nil t nil "--version")
|
|
|
|
|
(buffer-string))))
|
|
|
|
|
(if (string-match "ls (.*utils) \\([0-9.]*\\)$" version-out)
|
|
|
|
|
(let* ((version (match-string 1 version-out))
|
|
|
|
|
(split (split-string version "[.]"))
|
2005-05-16 11:34:49 +00:00
|
|
|
|
(numbers (mapcar 'string-to-number split))
|
2004-12-27 17:18:28 +00:00
|
|
|
|
(min '(5 2 1))
|
|
|
|
|
comparison)
|
|
|
|
|
(while (and (not comparison) (or numbers min))
|
|
|
|
|
(cond ((null min)
|
|
|
|
|
(setq comparison '>))
|
|
|
|
|
((null numbers)
|
|
|
|
|
(setq comparison '<))
|
|
|
|
|
((> (car numbers) (car min))
|
|
|
|
|
(setq comparison '>))
|
|
|
|
|
((< (car numbers) (car min))
|
|
|
|
|
(setq comparison '<))
|
|
|
|
|
(t
|
|
|
|
|
(setq numbers (cdr numbers)
|
|
|
|
|
min (cdr min)))))
|
|
|
|
|
(setq insert-directory-ls-version (or comparison '=)))
|
|
|
|
|
(setq insert-directory-ls-version nil))))
|
|
|
|
|
|
|
|
|
|
;; For GNU ls versions 5.2.2 and up, ignore minor errors.
|
|
|
|
|
(when (and (eq 1 result) (eq insert-directory-ls-version '>))
|
|
|
|
|
(setq result 0))
|
|
|
|
|
|
2001-12-03 00:02:52 +00:00
|
|
|
|
;; If `insert-directory-program' failed, signal an error.
|
2004-01-03 12:12:01 +00:00
|
|
|
|
(unless (eq 0 result)
|
2004-04-17 19:58:19 +00:00
|
|
|
|
;; Delete the error message it may have output.
|
|
|
|
|
(delete-region beg (point))
|
2004-01-03 12:12:01 +00:00
|
|
|
|
;; On non-Posix systems, we cannot open a directory, so
|
|
|
|
|
;; don't even try, because that will always result in
|
|
|
|
|
;; the ubiquitous "Access denied". Instead, show the
|
|
|
|
|
;; command line so the user can try to guess what went wrong.
|
|
|
|
|
(if (and (file-directory-p file)
|
|
|
|
|
(memq system-type '(ms-dos windows-nt)))
|
|
|
|
|
(error
|
|
|
|
|
"Reading directory: \"%s %s -- %s\" exited with status %s"
|
|
|
|
|
insert-directory-program
|
|
|
|
|
(if (listp switches) (concat switches) switches)
|
|
|
|
|
file result)
|
|
|
|
|
;; Unix. Access the file to get a suitable error.
|
|
|
|
|
(access-file file "Reading directory")
|
|
|
|
|
(error "Listing directory failed but `access-file' worked")))
|
2001-12-03 00:02:52 +00:00
|
|
|
|
|
2004-03-21 04:40:38 +00:00
|
|
|
|
(when (if (stringp switches)
|
|
|
|
|
(string-match "--dired\\>" switches)
|
|
|
|
|
(member "--dired" switches))
|
2005-01-23 20:44:12 +00:00
|
|
|
|
;; The following overshoots by one line for an empty
|
|
|
|
|
;; directory listed with "--dired", but without "-a"
|
|
|
|
|
;; switch, where the ls output contains a
|
|
|
|
|
;; "//DIRED-OPTIONS//" line, but no "//DIRED//" line.
|
|
|
|
|
;; We take care of that case later.
|
2002-07-02 18:58:29 +00:00
|
|
|
|
(forward-line -2)
|
2002-10-14 15:19:49 +00:00
|
|
|
|
(when (looking-at "//SUBDIRED//")
|
|
|
|
|
(delete-region (point) (progn (forward-line 1) (point)))
|
|
|
|
|
(forward-line -1))
|
2005-01-23 20:44:12 +00:00
|
|
|
|
(if (looking-at "//DIRED//")
|
|
|
|
|
(let ((end (line-end-position))
|
|
|
|
|
(linebeg (point))
|
|
|
|
|
error-lines)
|
|
|
|
|
;; Find all the lines that are error messages,
|
|
|
|
|
;; and record the bounds of each one.
|
|
|
|
|
(goto-char beg)
|
|
|
|
|
(while (< (point) linebeg)
|
|
|
|
|
(or (eql (following-char) ?\s)
|
|
|
|
|
(push (list (point) (line-end-position)) error-lines))
|
|
|
|
|
(forward-line 1))
|
|
|
|
|
(setq error-lines (nreverse error-lines))
|
|
|
|
|
;; Now read the numeric positions of file names.
|
|
|
|
|
(goto-char linebeg)
|
|
|
|
|
(forward-word 1)
|
|
|
|
|
(forward-char 3)
|
|
|
|
|
(while (< (point) end)
|
|
|
|
|
(let ((start (insert-directory-adj-pos
|
|
|
|
|
(+ beg (read (current-buffer)))
|
|
|
|
|
error-lines))
|
|
|
|
|
(end (insert-directory-adj-pos
|
2004-12-27 17:18:28 +00:00
|
|
|
|
(+ beg (read (current-buffer)))
|
2005-01-23 20:44:12 +00:00
|
|
|
|
error-lines)))
|
2005-07-20 01:57:49 +00:00
|
|
|
|
(if (memq (char-after end) '(?\n ?\s))
|
2005-01-23 20:44:12 +00:00
|
|
|
|
;; End is followed by \n or by " -> ".
|
|
|
|
|
(put-text-property start end 'dired-filename t)
|
|
|
|
|
;; It seems that we can't trust ls's output as to
|
|
|
|
|
;; byte positions of filenames.
|
|
|
|
|
(put-text-property beg (point) 'dired-filename nil)
|
|
|
|
|
(end-of-line))))
|
|
|
|
|
(goto-char end)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(delete-region (point) (progn (forward-line 1) (point))))
|
|
|
|
|
;; Take care of the case where the ls output contains a
|
|
|
|
|
;; "//DIRED-OPTIONS//"-line, but no "//DIRED//"-line
|
|
|
|
|
;; and we went one line too far back (see above).
|
|
|
|
|
(forward-line 1))
|
|
|
|
|
(if (looking-at "//DIRED-OPTIONS//")
|
|
|
|
|
(delete-region (point) (progn (forward-line 1) (point)))))
|
2002-07-02 18:58:29 +00:00
|
|
|
|
|
2003-01-23 05:59:47 +00:00
|
|
|
|
;; Now decode what read if necessary.
|
2003-03-12 08:02:32 +00:00
|
|
|
|
(let ((coding (or coding-system-for-read
|
|
|
|
|
file-name-coding-system
|
|
|
|
|
default-file-name-coding-system
|
|
|
|
|
'undecided))
|
2003-05-24 20:16:33 +00:00
|
|
|
|
coding-no-eol
|
2003-01-23 05:59:47 +00:00
|
|
|
|
val pos)
|
2003-03-12 08:02:32 +00:00
|
|
|
|
(when (and enable-multibyte-characters
|
|
|
|
|
(not (memq (coding-system-base coding)
|
|
|
|
|
'(raw-text no-conversion))))
|
|
|
|
|
;; If no coding system is specified or detection is
|
|
|
|
|
;; requested, detect the coding.
|
|
|
|
|
(if (eq (coding-system-base coding) 'undecided)
|
|
|
|
|
(setq coding (detect-coding-region beg (point) t)))
|
|
|
|
|
(if (not (eq (coding-system-base coding) 'undecided))
|
|
|
|
|
(save-restriction
|
2003-05-24 20:16:33 +00:00
|
|
|
|
(setq coding-no-eol
|
|
|
|
|
(coding-system-change-eol-conversion coding 'unix))
|
2003-03-12 08:02:32 +00:00
|
|
|
|
(narrow-to-region beg (point))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(while (not (eobp))
|
|
|
|
|
(setq pos (point)
|
|
|
|
|
val (get-text-property (point) 'dired-filename))
|
|
|
|
|
(goto-char (next-single-property-change
|
|
|
|
|
(point) 'dired-filename nil (point-max)))
|
2003-05-24 20:16:33 +00:00
|
|
|
|
;; Force no eol conversion on a file name, so
|
|
|
|
|
;; that CR is preserved.
|
|
|
|
|
(decode-coding-region pos (point)
|
|
|
|
|
(if val coding-no-eol coding))
|
2003-03-12 08:02:32 +00:00
|
|
|
|
(if val
|
|
|
|
|
(put-text-property pos (point)
|
|
|
|
|
'dired-filename t)))))))
|
2003-01-23 05:59:47 +00:00
|
|
|
|
|
2002-12-08 13:20:42 +00:00
|
|
|
|
(if full-directory-p
|
|
|
|
|
;; Try to insert the amount of free space.
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char beg)
|
|
|
|
|
;; First find the line to put it on.
|
|
|
|
|
(when (re-search-forward "^ *\\(total\\)" nil t)
|
|
|
|
|
(let ((available (get-free-disk-space ".")))
|
|
|
|
|
(when available
|
|
|
|
|
;; Replace "total" with "used", to avoid confusion.
|
|
|
|
|
(replace-match "total used in directory" nil nil nil 1)
|
|
|
|
|
(end-of-line)
|
2008-07-31 05:33:56 +00:00
|
|
|
|
(insert " available " available))))))))))
|
2000-07-18 14:18:03 +00:00
|
|
|
|
|
2004-12-27 17:18:28 +00:00
|
|
|
|
(defun insert-directory-adj-pos (pos error-lines)
|
2004-12-27 17:29:34 +00:00
|
|
|
|
"Convert `ls --dired' file name position value POS to a buffer position.
|
2004-12-27 17:18:28 +00:00
|
|
|
|
File name position values returned in ls --dired output
|
|
|
|
|
count only stdout; they don't count the error messages sent to stderr.
|
|
|
|
|
So this function converts to them to real buffer positions.
|
|
|
|
|
ERROR-LINES is a list of buffer positions of error message lines,
|
|
|
|
|
of the form (START END)."
|
|
|
|
|
(while (and error-lines (< (caar error-lines) pos))
|
|
|
|
|
(setq pos (+ pos (- (nth 1 (car error-lines)) (nth 0 (car error-lines)))))
|
|
|
|
|
(pop error-lines))
|
|
|
|
|
pos)
|
|
|
|
|
|
2000-12-21 14:44:35 +00:00
|
|
|
|
(defun insert-directory-safely (file switches
|
|
|
|
|
&optional wildcard full-directory-p)
|
|
|
|
|
"Insert directory listing for FILE, formatted according to SWITCHES.
|
|
|
|
|
|
|
|
|
|
Like `insert-directory', but if FILE does not exist, it inserts a
|
|
|
|
|
message to that effect instead of signaling an error."
|
|
|
|
|
(if (file-exists-p file)
|
|
|
|
|
(insert-directory file switches wildcard full-directory-p)
|
|
|
|
|
;; Simulate the message printed by `ls'.
|
|
|
|
|
(insert (format "%s: No such file or directory\n" file))))
|
|
|
|
|
|
1994-02-24 04:00:41 +00:00
|
|
|
|
(defvar kill-emacs-query-functions nil
|
1994-05-26 01:11:06 +00:00
|
|
|
|
"Functions to call with no arguments to query about killing Emacs.
|
1995-03-02 19:36:40 +00:00
|
|
|
|
If any of these functions returns nil, killing Emacs is cancelled.
|
2007-10-26 14:26:18 +00:00
|
|
|
|
`save-buffers-kill-emacs' calls these functions, but `kill-emacs',
|
|
|
|
|
the low level primitive, does not. See also `kill-emacs-hook'.")
|
1994-02-24 04:00:41 +00:00
|
|
|
|
|
2001-01-10 20:19:16 +00:00
|
|
|
|
(defcustom confirm-kill-emacs nil
|
2001-01-29 17:06:56 +00:00
|
|
|
|
"How to ask for confirmation when leaving Emacs.
|
|
|
|
|
If nil, the default, don't ask at all. If the value is non-nil, it should
|
|
|
|
|
be a predicate function such as `yes-or-no-p'."
|
2001-01-10 20:19:16 +00:00
|
|
|
|
:type '(choice (const :tag "Ask with yes-or-no-p" yes-or-no-p)
|
|
|
|
|
(const :tag "Ask with y-or-n-p" y-or-n-p)
|
|
|
|
|
(const :tag "Don't confirm" nil))
|
2004-05-01 03:51:49 +00:00
|
|
|
|
:group 'convenience
|
2001-01-10 20:19:16 +00:00
|
|
|
|
:version "21.1")
|
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(defun save-buffers-kill-emacs (&optional arg)
|
|
|
|
|
"Offer to save each buffer, then kill this Emacs process.
|
2008-11-14 13:05:18 +00:00
|
|
|
|
With prefix ARG, silently save all file-visiting buffers, then kill."
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(save-some-buffers arg t)
|
|
|
|
|
(and (or (not (memq t (mapcar (function
|
|
|
|
|
(lambda (buf) (and (buffer-file-name buf)
|
|
|
|
|
(buffer-modified-p buf))))
|
|
|
|
|
(buffer-list))))
|
|
|
|
|
(yes-or-no-p "Modified buffers exist; exit anyway? "))
|
|
|
|
|
(or (not (fboundp 'process-list))
|
2008-07-31 05:33:56 +00:00
|
|
|
|
;; process-list is not defined on MSDOS.
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(let ((processes (process-list))
|
|
|
|
|
active)
|
|
|
|
|
(while processes
|
2002-03-17 20:30:19 +00:00
|
|
|
|
(and (memq (process-status (car processes)) '(run stop open listen))
|
|
|
|
|
(process-query-on-exit-flag (car processes))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(setq active t))
|
|
|
|
|
(setq processes (cdr processes)))
|
|
|
|
|
(or (not active)
|
2002-03-17 20:30:19 +00:00
|
|
|
|
(list-processes t)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(yes-or-no-p "Active processes exist; kill them and exit anyway? "))))
|
1994-02-24 04:00:41 +00:00
|
|
|
|
;; Query the user for other things, perhaps.
|
1994-12-24 16:41:31 +00:00
|
|
|
|
(run-hook-with-args-until-failure 'kill-emacs-query-functions)
|
2001-01-10 20:19:16 +00:00
|
|
|
|
(or (null confirm-kill-emacs)
|
|
|
|
|
(funcall confirm-kill-emacs "Really exit Emacs? "))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(kill-emacs)))
|
2005-11-19 19:17:56 +00:00
|
|
|
|
|
Rename `struct device' to `struct terminal'. Rename some terminal-related functions similarly.
* src/termhooks.h (struct device): Rename to `terminal'. Rename member
`next_device' to `next_terminal'.
(device_list): Rename to `terminal_list'.
(FRAME_DEVICE): Rename to `FRAME_TERMINAL'.
(DEVICE_TERMINAL_CODING): Rename to `TERMINAL_TERMINAL_CODING'.
(TERMINAL_KEYBOARD_CODING): Rename to `TERMINAL_KEYBOARD_CODING'.
(DEVICE_ACTIVE_P): Rename to `TERMINAL_ACTIVE_P'.
Update declarations and macro definitions.
* src/termchar.h (tty_display_info): Rename member `device' to `terminal'.
(FRAME_TTY): Update for renames.
* src/xterm.h (x_display_info): Rename member `device' to `terminal'.
* src/frame.h (frame): Rename `device' member to `terminal'.
(FRAME_KBOARD, FRAME_LIVE_P, Qdevice, Qdisplay_live_p):
Update for renames.
* src/lisp.h (set_process_environment): Rename to `set_global_environment'.
(device): Rename to `terminal'.
* src/dispextern.h: Update declarations and macro definitions.
* src/terminal.c (device_list): Rename to `terminal_list'.
(next_device_id): Rename to `next_terminal_id'.
(initial_device): Rename to `initial_terminal'.
(get_device): Rename to `get_terminal'.
(create_device): Rename to `create_terminal'.
(mark_devices): Rename to `mark_terminals'.
(delete_device): Rename to `delete_terminal'.
(Fdelete_display): Rename to `Fdelete_terminal'.
(Fframe_terminal): Move here from frame.c.
(Fdisplay_live_p): Rename to `Fterminal_live_p'.
(Fdisplay_list): Rename to `Fterminal_list'.
(Fdisplay_name): Rename to `Fterminal_name'.
(init_initial_device): Rename to `init_initial_terminal'.
(delete_initial_device): Rename to `delete_initial_terminal'.
(ring_bell, update_begin, update_end, set_terminal_window)
(cursor_to, raw_cursor_to, clear_to_end, clear_frame)
(clear_end_of_line, write_glyphs, insert_glyphs, delete_glyphs)
(ins_del_lines, get_terminal_param, store_terminal_param)
(Fterminal_parameters, Fterminal_parameter)
(Fmodify_terminal_parameters, Fset_terminal_parameter)
(syms_of_terminal): Update for renames.
* src/term.c (get_tty_device): Rename to `get_tty_terminal'. Update.
(Fdisplay_tty_type): Rename to `Ftty_type'.
(Fdisplay_controlling_tty_p): Rename to `Fcontrolling_tty_p'.
(delete_tty, tty_set_terminal_modes, tty_reset_terminal_modes)
(Ftty_display_color_p, Ftty_display_color_cells, get_named_tty)
(Ftty_no_underline, Fsuspend_tty, Fresume_tty, create_tty_output)
(init_tty, maybe_fatal, delete_tty, syms_of_term): Update for rename.
* src/frame.c (Qdevice): Rename to `Qterminal'.
(Qdisplay_live_p): Rename to `Qterminal_live_p'.
(terminal_frame_count): Rename to `tty_frame_count'.
(Fframe_display): Move to terminal.c, rename to `Fframe_terminal'.
(make_frame_without_minibuffer, make_initial_frame)
(make_terminal_frame, Fmodify_frame_parameters)
(do_switch_frame, Fdelete_frame, Fmouse_position)
(Fmouse_pixel_position, Fraise_frame, Flower_frame)
(Fredirect_frame_focus, set_term_frame_name, syms_of_frame):
Update for renames.
* src/xdisp.c (message2_nolog, message3_nolog, redisplay_internal)
(set_vertical_scroll_bar, redisplay_window, check_x_display_info)
(x_set_scroll_bar_foreground, x_set_scroll_bar_background)
(Fx_create_frame, Fxw_display_color_p, Fx_display_grayscale_p)
(Fx_display_pixel_width, Fx_display_pixel_height)
(Fx_display_planes, Fx_display_color_cells)
(Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
(Fx_display_screens, Fx_display_mm_height, Fx_display_mm_width)
(Fx_display_backing_store, Fx_display_visual_class)
(Fx_display_save_under, Fx_close_connection, x_create_tip_frame):
Update for renames.
* xterm.c (handle_one_xevent): Initialize `f' to NULL.
(x_delete_device): Rename to `x_delete_terminal'.
(x_create_device): Rename to `x_create_terminal'.
(XTset_terminal_modes, XTreset_terminal_modes)
(XTread_socket, x_connection_closed, x_term_init)
(x_term_init, x_delete_display): Update for renames.
* src/dispnew.c (Fredraw_frame, Fsend_string_to_terminal)
(Fsend_string_to_terminal, init_display): Update for renames.
* src/keyboard.c (push_frame_kboard, pop_kboard, pop_kboard)
(kbd_buffer_get_event, read_avail_input, tty_read_avail_input)
(interrupt_signal, Fset_output_flow_control)
(Fset_input_meta_mode, Fset_quit_char, delete_kboard)
(syms_of_keyboard): Update for renames.
* src/alloc.c (mark_devices): Update declaration.
(Fgarbage_collect): Update for renames.
* src/coding.c (Fset_terminal_coding_system_internal)
(Fterminal_coding_system4)
(Fset_keyboard_coding_system_internal)
(Fkeyboard_coding_system): Update for renames.
* src/data.c (Fterminal_local_value, Fset_terminal_local_value):
Update for renames.
* src/minibuf.c (read_minibuf): Update for renames.
* src/sysdep.c (init_sys_modes, reset_sys_modes): Update for renames.
* xselect.c (x_handle_selection_clear): Update for renames.
* lisp/files.el (save-buffers-kill-display): Rename to `save-buffers-kill-terminal'.
(save-buffers-kill-terminal, ctl-x-map): Update for renames.
* frame.el (make-frame): Rename 'device frame parameter to 'terminal. Update.
(frames-on-display-list, framep-on-display, suspend-frame): Update for renames.
(selected-display): Rename to `selected-terminal'.
* server.el (server-save-buffers-kill-display): Rename to
`server-save-buffers-kill-terminal'.
(server-delete-client, server-handle-delete-frame)
(server-handle-suspend-tty, server-process-filter)
(server-switch-buffer): Update for renames.
* startup.el (normal-splash-screen, normal-splash-screen): Update for renames.
* talk.el (talk): Update for renames.
* termdev.el (terminal-id): Update for renames.
* xt-mouse.el (turn-on-xterm-mouse-tracking-on-terminal)
(turn-off-xterm-mouse-tracking-on-terminal)
(xterm-mouse-handle-delete-frame): Update for renames.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-471
2005-12-29 18:20:26 +00:00
|
|
|
|
(defun save-buffers-kill-terminal (&optional arg)
|
2005-11-19 19:17:56 +00:00
|
|
|
|
"Offer to save each buffer, then kill the current connection.
|
|
|
|
|
If the current frame has no client, kill Emacs itself.
|
|
|
|
|
|
2008-11-14 13:05:18 +00:00
|
|
|
|
With prefix ARG, silently save all file-visiting buffers, then kill.
|
2005-11-19 19:17:56 +00:00
|
|
|
|
|
|
|
|
|
If emacsclient was started with a list of filenames to edit, then
|
|
|
|
|
only these files will be asked to be saved."
|
|
|
|
|
(interactive "P")
|
2009-01-11 16:45:52 +00:00
|
|
|
|
(if (frame-parameter (selected-frame) 'client)
|
|
|
|
|
(server-save-buffers-kill-terminal arg)
|
|
|
|
|
(save-buffers-kill-emacs arg)))
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
2000-10-04 17:16:59 +00:00
|
|
|
|
;; We use /: as a prefix to "quote" a file name
|
1996-10-04 05:10:54 +00:00
|
|
|
|
;; so that magic file name handlers will not apply to it.
|
|
|
|
|
|
|
|
|
|
(setq file-name-handler-alist
|
2009-11-12 06:55:39 +00:00
|
|
|
|
(cons (cons (purecopy "\\`/:") 'file-name-non-special)
|
1996-10-04 05:10:54 +00:00
|
|
|
|
file-name-handler-alist))
|
|
|
|
|
|
|
|
|
|
;; We depend on being the last handler on the list,
|
|
|
|
|
;; so that anything else which does need handling
|
|
|
|
|
;; has been handled already.
|
|
|
|
|
;; So it is safe for us to inhibit *all* magic file name handlers.
|
|
|
|
|
|
|
|
|
|
(defun file-name-non-special (operation &rest arguments)
|
|
|
|
|
(let ((file-name-handler-alist nil)
|
1997-10-19 21:02:27 +00:00
|
|
|
|
(default-directory
|
|
|
|
|
(if (eq operation 'insert-directory)
|
|
|
|
|
(directory-file-name
|
2000-10-04 17:16:59 +00:00
|
|
|
|
(expand-file-name
|
1997-10-19 21:02:27 +00:00
|
|
|
|
(unhandled-file-name-directory default-directory)))
|
|
|
|
|
default-directory))
|
1996-10-04 05:10:54 +00:00
|
|
|
|
;; Get a list of the indices of the args which are file names.
|
|
|
|
|
(file-arg-indices
|
|
|
|
|
(cdr (or (assq operation
|
2004-05-27 20:23:31 +00:00
|
|
|
|
;; The first six are special because they
|
1996-10-04 05:10:54 +00:00
|
|
|
|
;; return a file name. We want to include the /:
|
|
|
|
|
;; in the return value.
|
|
|
|
|
;; So just avoid stripping it in the first place.
|
|
|
|
|
'((expand-file-name . nil)
|
|
|
|
|
(file-name-directory . nil)
|
|
|
|
|
(file-name-as-directory . nil)
|
|
|
|
|
(directory-file-name . nil)
|
2002-02-06 15:29:29 +00:00
|
|
|
|
(file-name-sans-versions . nil)
|
2004-05-27 20:23:31 +00:00
|
|
|
|
(find-backup-file-name . nil)
|
2002-02-06 15:29:29 +00:00
|
|
|
|
;; `identity' means just return the first arg
|
2004-05-22 07:40:41 +00:00
|
|
|
|
;; not stripped of its quoting.
|
|
|
|
|
(substitute-in-file-name identity)
|
2004-05-27 20:23:31 +00:00
|
|
|
|
;; `add' means add "/:" to the result.
|
|
|
|
|
(file-truename add 0)
|
|
|
|
|
;; `quote' means add "/:" to buffer-file-name.
|
|
|
|
|
(insert-file-contents quote 0)
|
|
|
|
|
;; `unquote-then-quote' means set buffer-file-name
|
|
|
|
|
;; temporarily to unquoted filename.
|
|
|
|
|
(verify-visited-file-modtime unquote-then-quote)
|
|
|
|
|
;; List the arguments which are filenames.
|
2002-04-19 16:27:09 +00:00
|
|
|
|
(file-name-completion 1)
|
|
|
|
|
(file-name-all-completions 1)
|
2004-05-27 20:23:31 +00:00
|
|
|
|
(write-region 2 5)
|
1996-10-04 05:10:54 +00:00
|
|
|
|
(rename-file 0 1)
|
|
|
|
|
(copy-file 0 1)
|
|
|
|
|
(make-symbolic-link 0 1)
|
|
|
|
|
(add-name-to-file 0 1)))
|
|
|
|
|
;; For all other operations, treat the first argument only
|
|
|
|
|
;; as the file name.
|
|
|
|
|
'(nil 0))))
|
2004-05-22 07:40:41 +00:00
|
|
|
|
method
|
1996-10-04 05:10:54 +00:00
|
|
|
|
;; Copy ARGUMENTS so we can replace elements in it.
|
|
|
|
|
(arguments (copy-sequence arguments)))
|
2004-05-22 07:40:41 +00:00
|
|
|
|
(if (symbolp (car file-arg-indices))
|
|
|
|
|
(setq method (pop file-arg-indices)))
|
|
|
|
|
;; Strip off the /: from the file names that have it.
|
1996-10-04 05:10:54 +00:00
|
|
|
|
(save-match-data
|
1997-05-30 06:38:56 +00:00
|
|
|
|
(while (consp file-arg-indices)
|
1997-10-19 20:34:22 +00:00
|
|
|
|
(let ((pair (nthcdr (car file-arg-indices) arguments)))
|
|
|
|
|
(and (car pair)
|
|
|
|
|
(string-match "\\`/:" (car pair))
|
|
|
|
|
(setcar pair
|
|
|
|
|
(if (= (length (car pair)) 2)
|
|
|
|
|
"/"
|
|
|
|
|
(substring (car pair) 2)))))
|
1996-10-04 05:10:54 +00:00
|
|
|
|
(setq file-arg-indices (cdr file-arg-indices))))
|
2004-05-22 07:40:41 +00:00
|
|
|
|
(cond ((eq method 'identity)
|
|
|
|
|
(car arguments))
|
2004-05-27 20:23:31 +00:00
|
|
|
|
((eq method 'add)
|
2004-05-22 07:40:41 +00:00
|
|
|
|
(concat "/:" (apply operation arguments)))
|
2004-05-27 20:23:31 +00:00
|
|
|
|
((eq method 'quote)
|
2005-08-09 13:35:12 +00:00
|
|
|
|
(unwind-protect
|
|
|
|
|
(apply operation arguments)
|
2004-05-27 20:23:31 +00:00
|
|
|
|
(setq buffer-file-name (concat "/:" buffer-file-name))))
|
|
|
|
|
((eq method 'unquote-then-quote)
|
|
|
|
|
(let (res)
|
|
|
|
|
(setq buffer-file-name (substring buffer-file-name 2))
|
|
|
|
|
(setq res (apply operation arguments))
|
|
|
|
|
(setq buffer-file-name (concat "/:" buffer-file-name))
|
|
|
|
|
res))
|
2004-05-22 07:40:41 +00:00
|
|
|
|
(t
|
|
|
|
|
(apply operation arguments)))))
|
1996-10-04 05:10:54 +00:00
|
|
|
|
|
2007-09-10 09:51:44 +00:00
|
|
|
|
;; Symbolic modes and read-file-modes.
|
|
|
|
|
|
|
|
|
|
(defun file-modes-char-to-who (char)
|
2008-10-18 18:41:32 +00:00
|
|
|
|
"Convert CHAR to a numeric bit-mask for extracting mode bits.
|
|
|
|
|
CHAR is in [ugoa] and represents the category of users (Owner, Group,
|
|
|
|
|
Others, or All) for whom to produce the mask.
|
|
|
|
|
The bit-mask that is returned extracts from mode bits the access rights
|
|
|
|
|
for the specified category of users."
|
2007-09-10 09:51:44 +00:00
|
|
|
|
(cond ((= char ?u) #o4700)
|
|
|
|
|
((= char ?g) #o2070)
|
|
|
|
|
((= char ?o) #o1007)
|
|
|
|
|
((= char ?a) #o7777)
|
|
|
|
|
(t (error "%c: bad `who' character" char))))
|
|
|
|
|
|
|
|
|
|
(defun file-modes-char-to-right (char &optional from)
|
2008-10-18 18:41:32 +00:00
|
|
|
|
"Convert CHAR to a numeric value of mode bits.
|
|
|
|
|
CHAR is in [rwxXstugo] and represents symbolic access permissions.
|
|
|
|
|
If CHAR is in [Xugo], the value is taken from FROM (or 0 if omitted)."
|
2007-09-10 09:51:44 +00:00
|
|
|
|
(or from (setq from 0))
|
|
|
|
|
(cond ((= char ?r) #o0444)
|
|
|
|
|
((= char ?w) #o0222)
|
|
|
|
|
((= char ?x) #o0111)
|
|
|
|
|
((= char ?s) #o1000)
|
|
|
|
|
((= char ?t) #o6000)
|
|
|
|
|
;; Rights relative to the previous file modes.
|
|
|
|
|
((= char ?X) (if (= (logand from #o111) 0) 0 #o0111))
|
|
|
|
|
((= char ?u) (let ((uright (logand #o4700 from)))
|
|
|
|
|
(+ uright (/ uright #o10) (/ uright #o100))))
|
|
|
|
|
((= char ?g) (let ((gright (logand #o2070 from)))
|
|
|
|
|
(+ gright (/ gright #o10) (* gright #o10))))
|
|
|
|
|
((= char ?o) (let ((oright (logand #o1007 from)))
|
|
|
|
|
(+ oright (* oright #o10) (* oright #o100))))
|
|
|
|
|
(t (error "%c: bad right character" char))))
|
|
|
|
|
|
|
|
|
|
(defun file-modes-rights-to-number (rights who-mask &optional from)
|
2008-10-18 18:41:32 +00:00
|
|
|
|
"Convert a symbolic mode string specification to an equivalent number.
|
2009-03-21 15:53:29 +00:00
|
|
|
|
RIGHTS is the symbolic mode spec, it should match \"([+=-][rwxXstugo]*)+\".
|
2008-10-18 18:41:32 +00:00
|
|
|
|
WHO-MASK is the bit-mask specifying the category of users to which to
|
|
|
|
|
apply the access permissions. See `file-modes-char-to-who'.
|
|
|
|
|
FROM (or 0 if nil) gives the mode bits on which to base permissions if
|
|
|
|
|
RIGHTS request to add, remove, or set permissions based on existing ones,
|
|
|
|
|
as in \"og+rX-w\"."
|
2007-09-10 09:51:44 +00:00
|
|
|
|
(let* ((num-rights (or from 0))
|
|
|
|
|
(list-rights (string-to-list rights))
|
|
|
|
|
(op (pop list-rights)))
|
|
|
|
|
(while (memq op '(?+ ?- ?=))
|
|
|
|
|
(let ((num-right 0)
|
|
|
|
|
char-right)
|
|
|
|
|
(while (memq (setq char-right (pop list-rights))
|
|
|
|
|
'(?r ?w ?x ?X ?s ?t ?u ?g ?o))
|
|
|
|
|
(setq num-right
|
|
|
|
|
(logior num-right
|
|
|
|
|
(file-modes-char-to-right char-right num-rights))))
|
|
|
|
|
(setq num-right (logand who-mask num-right)
|
|
|
|
|
num-rights
|
|
|
|
|
(cond ((= op ?+) (logior num-rights num-right))
|
|
|
|
|
((= op ?-) (logand num-rights (lognot num-right)))
|
|
|
|
|
(t (logior (logand num-rights (lognot who-mask)) num-right)))
|
|
|
|
|
op char-right)))
|
|
|
|
|
num-rights))
|
|
|
|
|
|
|
|
|
|
(defun file-modes-symbolic-to-number (modes &optional from)
|
|
|
|
|
"Convert symbolic file modes to numeric file modes.
|
|
|
|
|
MODES is the string to convert, it should match
|
2009-03-21 15:53:29 +00:00
|
|
|
|
\"[ugoa]*([+-=][rwxXstugo]*)+,...\".
|
2007-09-10 09:51:44 +00:00
|
|
|
|
See (info \"(coreutils)File permissions\") for more information on this
|
|
|
|
|
notation.
|
2008-10-18 18:41:32 +00:00
|
|
|
|
FROM (or 0 if nil) gives the mode bits on which to base permissions if
|
|
|
|
|
MODES request to add, remove, or set permissions based on existing ones,
|
|
|
|
|
as in \"og+rX-w\"."
|
2007-09-10 09:51:44 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(let ((case-fold-search nil)
|
|
|
|
|
(num-modes (or from 0)))
|
|
|
|
|
(while (/= (string-to-char modes) 0)
|
2009-03-21 15:53:29 +00:00
|
|
|
|
(if (string-match "^\\([ugoa]*\\)\\([+=-][rwxXstugo]*\\)+\\(,\\|\\)" modes)
|
2007-09-10 09:51:44 +00:00
|
|
|
|
(let ((num-who (apply 'logior 0
|
|
|
|
|
(mapcar 'file-modes-char-to-who
|
|
|
|
|
(match-string 1 modes)))))
|
|
|
|
|
(when (= num-who 0)
|
|
|
|
|
(setq num-who (default-file-modes)))
|
|
|
|
|
(setq num-modes
|
|
|
|
|
(file-modes-rights-to-number (substring modes (match-end 1))
|
|
|
|
|
num-who num-modes)
|
|
|
|
|
modes (substring modes (match-end 3))))
|
|
|
|
|
(error "Parse error in modes near `%s'" (substring modes 0))))
|
|
|
|
|
num-modes)))
|
|
|
|
|
|
|
|
|
|
(defun read-file-modes (&optional prompt orig-file)
|
2008-10-18 18:41:32 +00:00
|
|
|
|
"Read file modes in octal or symbolic notation and return its numeric value.
|
2007-09-10 09:51:44 +00:00
|
|
|
|
PROMPT is used as the prompt, default to `File modes (octal or symbolic): '.
|
2008-10-18 18:41:32 +00:00
|
|
|
|
ORIG-FILE is the name of a file on whose mode bits to base returned
|
|
|
|
|
permissions if what user types requests to add, remove, or set permissions
|
|
|
|
|
based on existing mode bits, as in \"og+rX-w\"."
|
2007-09-10 09:51:44 +00:00
|
|
|
|
(let* ((modes (or (if orig-file (file-modes orig-file) 0)
|
|
|
|
|
(error "File not found")))
|
2008-07-31 17:18:06 +00:00
|
|
|
|
(modestr (and (stringp orig-file)
|
|
|
|
|
(nth 8 (file-attributes orig-file))))
|
|
|
|
|
(default
|
|
|
|
|
(and (stringp modestr)
|
|
|
|
|
(string-match "^.\\(...\\)\\(...\\)\\(...\\)$" modestr)
|
|
|
|
|
(replace-regexp-in-string
|
|
|
|
|
"-" ""
|
|
|
|
|
(format "u=%s,g=%s,o=%s"
|
|
|
|
|
(match-string 1 modestr)
|
|
|
|
|
(match-string 2 modestr)
|
|
|
|
|
(match-string 3 modestr)))))
|
|
|
|
|
(value (read-string (or prompt "File modes (octal or symbolic): ")
|
|
|
|
|
nil nil default)))
|
2007-09-10 09:51:44 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
(if (string-match "^[0-7]+" value)
|
|
|
|
|
(string-to-number value 8)
|
|
|
|
|
(file-modes-symbolic-to-number value modes)))))
|
|
|
|
|
|
2008-07-02 13:19:07 +00:00
|
|
|
|
|
2008-10-18 18:41:32 +00:00
|
|
|
|
;; Trashcan handling.
|
2009-06-28 04:54:06 +00:00
|
|
|
|
(defcustom trash-directory nil
|
2008-07-02 13:19:07 +00:00
|
|
|
|
"Directory for `move-file-to-trash' to move files and directories to.
|
2009-06-28 04:54:06 +00:00
|
|
|
|
This directory is only used when the function `system-move-file-to-trash'
|
|
|
|
|
is not defined.
|
|
|
|
|
Relative paths are interpreted relative to `default-directory'.
|
|
|
|
|
If the value is nil, Emacs uses a freedesktop.org-style trashcan."
|
2009-06-28 16:09:46 +00:00
|
|
|
|
:type '(choice (const nil) directory)
|
2008-07-02 13:19:07 +00:00
|
|
|
|
:group 'auto-save
|
2009-06-28 04:54:06 +00:00
|
|
|
|
:version "23.2")
|
|
|
|
|
|
|
|
|
|
(defvar trash--hexify-table)
|
2008-07-02 13:19:07 +00:00
|
|
|
|
|
|
|
|
|
(declare-function system-move-file-to-trash "w32fns.c" (filename))
|
|
|
|
|
|
|
|
|
|
(defun move-file-to-trash (filename)
|
2009-06-28 04:54:06 +00:00
|
|
|
|
"Move the file (or directory) named FILENAME to the trash.
|
|
|
|
|
When `delete-by-moving-to-trash' is non-nil, this function is
|
|
|
|
|
called by `delete-file' and `delete-directory' instead of
|
|
|
|
|
deleting files outright.
|
|
|
|
|
|
|
|
|
|
If the function `system-move-file-to-trash' is defined, call it
|
|
|
|
|
with FILENAME as an argument.
|
|
|
|
|
Otherwise, if `trash-directory' is non-nil, move FILENAME to that
|
|
|
|
|
directory.
|
|
|
|
|
Otherwise, trash FILENAME using the freedesktop.org conventions,
|
|
|
|
|
like the GNOME, KDE and XFCE desktop environments. Emacs only
|
|
|
|
|
moves files to \"home trash\", ignoring per-volume trashcans."
|
2008-07-02 13:19:07 +00:00
|
|
|
|
(interactive "fMove file to trash: ")
|
2009-06-28 04:54:06 +00:00
|
|
|
|
(cond (trash-directory
|
|
|
|
|
;; If `trash-directory' is non-nil, move the file there.
|
|
|
|
|
(let* ((trash-dir (expand-file-name trash-directory))
|
|
|
|
|
(fn (directory-file-name (expand-file-name filename)))
|
|
|
|
|
(new-fn (expand-file-name (file-name-nondirectory fn)
|
|
|
|
|
trash-dir)))
|
|
|
|
|
;; We can't trash a parent directory of trash-directory.
|
|
|
|
|
(if (string-match fn trash-dir)
|
|
|
|
|
(error "Trash directory `%s' is a subdirectory of `%s'"
|
|
|
|
|
trash-dir filename))
|
|
|
|
|
(unless (file-directory-p trash-dir)
|
|
|
|
|
(make-directory trash-dir t))
|
|
|
|
|
;; Ensure that the trashed file-name is unique.
|
|
|
|
|
(if (file-exists-p new-fn)
|
|
|
|
|
(let ((version-control t)
|
|
|
|
|
(backup-directory-alist nil))
|
|
|
|
|
(setq new-fn (car (find-backup-file-name new-fn)))))
|
|
|
|
|
(let (delete-by-moving-to-trash)
|
|
|
|
|
(rename-file fn new-fn))))
|
|
|
|
|
;; If `system-move-file-to-trash' is defined, use it.
|
|
|
|
|
((fboundp 'system-move-file-to-trash)
|
|
|
|
|
(system-move-file-to-trash filename))
|
|
|
|
|
;; Otherwise, use the freedesktop.org method, as specified at
|
|
|
|
|
;; http://freedesktop.org/wiki/Specifications/trash-spec
|
|
|
|
|
(t
|
|
|
|
|
(let* ((xdg-data-dir
|
|
|
|
|
(directory-file-name
|
|
|
|
|
(expand-file-name "Trash"
|
|
|
|
|
(or (getenv "XDG_DATA_HOME")
|
|
|
|
|
"~/.local/share"))))
|
|
|
|
|
(trash-files-dir (expand-file-name "files" xdg-data-dir))
|
|
|
|
|
(trash-info-dir (expand-file-name "info" xdg-data-dir))
|
|
|
|
|
(fn (directory-file-name (expand-file-name filename))))
|
|
|
|
|
|
|
|
|
|
;; Check if we have permissions to delete.
|
|
|
|
|
(unless (file-writable-p (directory-file-name
|
|
|
|
|
(file-name-directory fn)))
|
|
|
|
|
(error "Cannot move %s to trash: Permission denied" filename))
|
|
|
|
|
;; The trashed file cannot be the trash dir or its parent.
|
|
|
|
|
(if (string-match fn trash-files-dir)
|
|
|
|
|
(error "The trash directory %s is a subdirectory of %s"
|
|
|
|
|
trash-files-dir filename))
|
|
|
|
|
(if (string-match fn trash-info-dir)
|
|
|
|
|
(error "The trash directory %s is a subdirectory of %s"
|
|
|
|
|
trash-info-dir filename))
|
|
|
|
|
|
|
|
|
|
;; Ensure that the trash directory exists; otherwise, create it.
|
|
|
|
|
(let ((saved-default-file-modes (default-file-modes)))
|
|
|
|
|
(set-default-file-modes ?\700)
|
|
|
|
|
(unless (file-exists-p trash-files-dir)
|
|
|
|
|
(make-directory trash-files-dir t))
|
|
|
|
|
(unless (file-exists-p trash-info-dir)
|
|
|
|
|
(make-directory trash-info-dir t))
|
|
|
|
|
(set-default-file-modes saved-default-file-modes))
|
|
|
|
|
|
|
|
|
|
;; Try to move to trash with .trashinfo undo information
|
|
|
|
|
(save-excursion
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(set-buffer-file-coding-system 'utf-8-unix)
|
|
|
|
|
(insert "[Trash Info]\nPath=")
|
|
|
|
|
;; Perform url-encoding on FN. For compatibility with
|
|
|
|
|
;; other programs (e.g. XFCE Thunar), allow literal "/"
|
|
|
|
|
;; for path separators.
|
|
|
|
|
(unless (boundp 'trash--hexify-table)
|
|
|
|
|
(setq trash--hexify-table (make-vector 256 nil))
|
|
|
|
|
(let ((unreserved-chars
|
|
|
|
|
(list ?/ ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m
|
|
|
|
|
?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z ?A
|
|
|
|
|
?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O
|
|
|
|
|
?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z ?0 ?1 ?2
|
|
|
|
|
?3 ?4 ?5 ?6 ?7 ?8 ?9 ?- ?_ ?. ?! ?~ ?* ?'
|
|
|
|
|
?\( ?\))))
|
|
|
|
|
(dotimes (byte 256)
|
|
|
|
|
(aset trash--hexify-table byte
|
|
|
|
|
(if (memq byte unreserved-chars)
|
|
|
|
|
(char-to-string byte)
|
|
|
|
|
(format "%%%02x" byte))))))
|
|
|
|
|
(mapc (lambda (byte)
|
|
|
|
|
(insert (aref trash--hexify-table byte)))
|
|
|
|
|
(if (multibyte-string-p fn)
|
|
|
|
|
(encode-coding-string fn 'utf-8)
|
|
|
|
|
fn))
|
|
|
|
|
(insert "\nDeletionDate="
|
|
|
|
|
(format-time-string "%Y-%m-%dT%T")
|
|
|
|
|
"\n")
|
|
|
|
|
|
|
|
|
|
;; Attempt to make .trashinfo file, trying up to 5
|
|
|
|
|
;; times. The .trashinfo file is opened with O_EXCL,
|
|
|
|
|
;; as per trash-spec 0.7, even if that can be a problem
|
|
|
|
|
;; on old NFS versions...
|
|
|
|
|
(let* ((tries 5)
|
|
|
|
|
(base-fn (expand-file-name
|
|
|
|
|
(file-name-nondirectory fn)
|
|
|
|
|
trash-files-dir))
|
|
|
|
|
(new-fn base-fn)
|
|
|
|
|
success info-fn)
|
|
|
|
|
(while (> tries 0)
|
|
|
|
|
(setq info-fn (expand-file-name
|
|
|
|
|
(concat (file-name-nondirectory new-fn)
|
|
|
|
|
".trashinfo")
|
|
|
|
|
trash-info-dir))
|
|
|
|
|
(unless (condition-case nil
|
|
|
|
|
(progn
|
|
|
|
|
(write-region nil nil info-fn nil
|
|
|
|
|
'quiet info-fn 'excl)
|
|
|
|
|
(setq tries 0 success t))
|
|
|
|
|
(file-already-exists nil))
|
|
|
|
|
(setq tries (1- tries))
|
|
|
|
|
;; Uniqify new-fn. (Some file managers do not
|
|
|
|
|
;; like Emacs-style backup file names---e.g. bug
|
|
|
|
|
;; 170956 in Konqueror bug tracker.)
|
|
|
|
|
(setq new-fn (make-temp-name (concat base-fn "_")))))
|
|
|
|
|
(unless success
|
|
|
|
|
(error "Cannot move %s to trash: Lock failed" filename))
|
|
|
|
|
|
|
|
|
|
;; Finally, try to move the file to the trashcan.
|
|
|
|
|
(let ((delete-by-moving-to-trash nil))
|
|
|
|
|
(rename-file fn new-fn)))))))))
|
2008-07-02 13:19:07 +00:00
|
|
|
|
|
2007-09-10 09:51:44 +00:00
|
|
|
|
|
1991-07-19 14:42:53 +00:00
|
|
|
|
(define-key ctl-x-map "\C-f" 'find-file)
|
|
|
|
|
(define-key ctl-x-map "\C-r" 'find-file-read-only)
|
|
|
|
|
(define-key ctl-x-map "\C-v" 'find-alternate-file)
|
|
|
|
|
(define-key ctl-x-map "\C-s" 'save-buffer)
|
|
|
|
|
(define-key ctl-x-map "s" 'save-some-buffers)
|
|
|
|
|
(define-key ctl-x-map "\C-w" 'write-file)
|
|
|
|
|
(define-key ctl-x-map "i" 'insert-file)
|
|
|
|
|
(define-key esc-map "~" 'not-modified)
|
|
|
|
|
(define-key ctl-x-map "\C-d" 'list-directory)
|
Rename `struct device' to `struct terminal'. Rename some terminal-related functions similarly.
* src/termhooks.h (struct device): Rename to `terminal'. Rename member
`next_device' to `next_terminal'.
(device_list): Rename to `terminal_list'.
(FRAME_DEVICE): Rename to `FRAME_TERMINAL'.
(DEVICE_TERMINAL_CODING): Rename to `TERMINAL_TERMINAL_CODING'.
(TERMINAL_KEYBOARD_CODING): Rename to `TERMINAL_KEYBOARD_CODING'.
(DEVICE_ACTIVE_P): Rename to `TERMINAL_ACTIVE_P'.
Update declarations and macro definitions.
* src/termchar.h (tty_display_info): Rename member `device' to `terminal'.
(FRAME_TTY): Update for renames.
* src/xterm.h (x_display_info): Rename member `device' to `terminal'.
* src/frame.h (frame): Rename `device' member to `terminal'.
(FRAME_KBOARD, FRAME_LIVE_P, Qdevice, Qdisplay_live_p):
Update for renames.
* src/lisp.h (set_process_environment): Rename to `set_global_environment'.
(device): Rename to `terminal'.
* src/dispextern.h: Update declarations and macro definitions.
* src/terminal.c (device_list): Rename to `terminal_list'.
(next_device_id): Rename to `next_terminal_id'.
(initial_device): Rename to `initial_terminal'.
(get_device): Rename to `get_terminal'.
(create_device): Rename to `create_terminal'.
(mark_devices): Rename to `mark_terminals'.
(delete_device): Rename to `delete_terminal'.
(Fdelete_display): Rename to `Fdelete_terminal'.
(Fframe_terminal): Move here from frame.c.
(Fdisplay_live_p): Rename to `Fterminal_live_p'.
(Fdisplay_list): Rename to `Fterminal_list'.
(Fdisplay_name): Rename to `Fterminal_name'.
(init_initial_device): Rename to `init_initial_terminal'.
(delete_initial_device): Rename to `delete_initial_terminal'.
(ring_bell, update_begin, update_end, set_terminal_window)
(cursor_to, raw_cursor_to, clear_to_end, clear_frame)
(clear_end_of_line, write_glyphs, insert_glyphs, delete_glyphs)
(ins_del_lines, get_terminal_param, store_terminal_param)
(Fterminal_parameters, Fterminal_parameter)
(Fmodify_terminal_parameters, Fset_terminal_parameter)
(syms_of_terminal): Update for renames.
* src/term.c (get_tty_device): Rename to `get_tty_terminal'. Update.
(Fdisplay_tty_type): Rename to `Ftty_type'.
(Fdisplay_controlling_tty_p): Rename to `Fcontrolling_tty_p'.
(delete_tty, tty_set_terminal_modes, tty_reset_terminal_modes)
(Ftty_display_color_p, Ftty_display_color_cells, get_named_tty)
(Ftty_no_underline, Fsuspend_tty, Fresume_tty, create_tty_output)
(init_tty, maybe_fatal, delete_tty, syms_of_term): Update for rename.
* src/frame.c (Qdevice): Rename to `Qterminal'.
(Qdisplay_live_p): Rename to `Qterminal_live_p'.
(terminal_frame_count): Rename to `tty_frame_count'.
(Fframe_display): Move to terminal.c, rename to `Fframe_terminal'.
(make_frame_without_minibuffer, make_initial_frame)
(make_terminal_frame, Fmodify_frame_parameters)
(do_switch_frame, Fdelete_frame, Fmouse_position)
(Fmouse_pixel_position, Fraise_frame, Flower_frame)
(Fredirect_frame_focus, set_term_frame_name, syms_of_frame):
Update for renames.
* src/xdisp.c (message2_nolog, message3_nolog, redisplay_internal)
(set_vertical_scroll_bar, redisplay_window, check_x_display_info)
(x_set_scroll_bar_foreground, x_set_scroll_bar_background)
(Fx_create_frame, Fxw_display_color_p, Fx_display_grayscale_p)
(Fx_display_pixel_width, Fx_display_pixel_height)
(Fx_display_planes, Fx_display_color_cells)
(Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
(Fx_display_screens, Fx_display_mm_height, Fx_display_mm_width)
(Fx_display_backing_store, Fx_display_visual_class)
(Fx_display_save_under, Fx_close_connection, x_create_tip_frame):
Update for renames.
* xterm.c (handle_one_xevent): Initialize `f' to NULL.
(x_delete_device): Rename to `x_delete_terminal'.
(x_create_device): Rename to `x_create_terminal'.
(XTset_terminal_modes, XTreset_terminal_modes)
(XTread_socket, x_connection_closed, x_term_init)
(x_term_init, x_delete_display): Update for renames.
* src/dispnew.c (Fredraw_frame, Fsend_string_to_terminal)
(Fsend_string_to_terminal, init_display): Update for renames.
* src/keyboard.c (push_frame_kboard, pop_kboard, pop_kboard)
(kbd_buffer_get_event, read_avail_input, tty_read_avail_input)
(interrupt_signal, Fset_output_flow_control)
(Fset_input_meta_mode, Fset_quit_char, delete_kboard)
(syms_of_keyboard): Update for renames.
* src/alloc.c (mark_devices): Update declaration.
(Fgarbage_collect): Update for renames.
* src/coding.c (Fset_terminal_coding_system_internal)
(Fterminal_coding_system4)
(Fset_keyboard_coding_system_internal)
(Fkeyboard_coding_system): Update for renames.
* src/data.c (Fterminal_local_value, Fset_terminal_local_value):
Update for renames.
* src/minibuf.c (read_minibuf): Update for renames.
* src/sysdep.c (init_sys_modes, reset_sys_modes): Update for renames.
* xselect.c (x_handle_selection_clear): Update for renames.
* lisp/files.el (save-buffers-kill-display): Rename to `save-buffers-kill-terminal'.
(save-buffers-kill-terminal, ctl-x-map): Update for renames.
* frame.el (make-frame): Rename 'device frame parameter to 'terminal. Update.
(frames-on-display-list, framep-on-display, suspend-frame): Update for renames.
(selected-display): Rename to `selected-terminal'.
* server.el (server-save-buffers-kill-display): Rename to
`server-save-buffers-kill-terminal'.
(server-delete-client, server-handle-delete-frame)
(server-handle-suspend-tty, server-process-filter)
(server-switch-buffer): Update for renames.
* startup.el (normal-splash-screen, normal-splash-screen): Update for renames.
* talk.el (talk): Update for renames.
* termdev.el (terminal-id): Update for renames.
* xt-mouse.el (turn-on-xterm-mouse-tracking-on-terminal)
(turn-off-xterm-mouse-tracking-on-terminal)
(xterm-mouse-handle-delete-frame): Update for renames.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-471
2005-12-29 18:20:26 +00:00
|
|
|
|
(define-key ctl-x-map "\C-c" 'save-buffers-kill-terminal)
|
2002-07-16 17:40:37 +00:00
|
|
|
|
(define-key ctl-x-map "\C-q" 'toggle-read-only)
|
1991-07-19 14:42:53 +00:00
|
|
|
|
|
|
|
|
|
(define-key ctl-x-4-map "f" 'find-file-other-window)
|
|
|
|
|
(define-key ctl-x-4-map "r" 'find-file-read-only-other-window)
|
|
|
|
|
(define-key ctl-x-4-map "\C-f" 'find-file-other-window)
|
|
|
|
|
(define-key ctl-x-4-map "b" 'switch-to-buffer-other-window)
|
1992-07-22 23:07:07 +00:00
|
|
|
|
(define-key ctl-x-4-map "\C-o" 'display-buffer)
|
1991-10-31 08:30:58 +00:00
|
|
|
|
|
1992-07-15 02:24:58 +00:00
|
|
|
|
(define-key ctl-x-5-map "b" 'switch-to-buffer-other-frame)
|
|
|
|
|
(define-key ctl-x-5-map "f" 'find-file-other-frame)
|
|
|
|
|
(define-key ctl-x-5-map "\C-f" 'find-file-other-frame)
|
|
|
|
|
(define-key ctl-x-5-map "r" 'find-file-read-only-other-frame)
|
2006-03-24 13:59:22 +00:00
|
|
|
|
(define-key ctl-x-5-map "\C-o" 'display-buffer-other-frame)
|
1992-05-30 23:54:21 +00:00
|
|
|
|
|
2005-05-11 16:24:55 +00:00
|
|
|
|
;; arch-tag: bc68d3ea-19ca-468b-aac6-3a4a7766101f
|
1992-05-30 23:54:21 +00:00
|
|
|
|
;;; files.el ends here
|