summaryrefslogtreecommitdiff
path: root/lisp/files.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/files.el')
-rw-r--r--lisp/files.el118
1 files changed, 60 insertions, 58 deletions
diff --git a/lisp/files.el b/lisp/files.el
index 0e70d673e8e..177046ace0f 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -29,6 +29,8 @@
;;; Code:
+(eval-when-compile (require 'cl))
+
(defvar font-lock-keywords)
(defgroup backup nil
@@ -193,6 +195,7 @@ If the buffer is visiting a new file, the value is nil.")
(or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "/tmp"))))
"The directory for writing temporary files."
:group 'files
+ :initialize 'custom-initialize-delay
:type 'directory)
(defcustom small-temporary-file-directory
@@ -202,6 +205,7 @@ If non-nil, this directory is used instead of `temporary-file-directory'
by programs that create small temporary files. This is for systems that
have fast storage with limited space, such as a RAM disk."
:group 'files
+ :initialize 'custom-initialize-delay
:type '(choice (const nil) directory))
;; The system null device. (Should reference NULL_DEVICE from C.)
@@ -383,6 +387,7 @@ ignored."
:group 'auto-save
:type '(repeat (list (string :tag "Regexp") (string :tag "Replacement")
(boolean :tag "Uniquify")))
+ :initialize 'custom-initialize-delay
:version "21.1")
(defcustom save-abbrevs t
@@ -493,6 +498,7 @@ a -*- line.
The command \\[normal-mode], when used interactively,
always obeys file local variable specifications and the -*- line,
and ignores this variable."
+ :risky t
:type '(choice (const :tag "Query Unsafe" t)
(const :tag "Safe Only" :safe)
(const :tag "Do all" :all)
@@ -514,6 +520,7 @@ specified in a -*- line.")
The value can be t, nil or something else.
A value of t means obey `eval' variables.
A value of nil means ignore them; anything else means query."
+ :risky t
:type '(choice (const :tag "Obey" t)
(const :tag "Ignore" nil)
(other :tag "Query" other))
@@ -649,7 +656,7 @@ Directories are separated by occurrences of `path-separator'
(unless (file-executable-p dir)
(error "Cannot cd to %s: Permission denied" dir))
(setq default-directory dir)
- (set (make-local-variable 'list-buffers-directory) dir)))
+ (setq list-buffers-directory dir)))
(defun cd (dir)
"Make DIR become the current buffer's default directory.
@@ -714,24 +721,34 @@ one or more of those symbols."
(defun locate-file-completion-table (dirs suffixes string pred action)
"Do completion for file names passed to `locate-file'."
- (if (file-name-absolute-p string)
- (let ((read-file-name-predicate pred))
- (read-file-name-internal string nil action))
+ (cond
+ ((file-name-absolute-p string)
+ (let ((read-file-name-predicate pred))
+ (read-file-name-internal string nil action)))
+ ((eq (car-safe action) 'boundaries)
+ (let ((suffix (cdr action)))
+ (list* 'boundaries
+ (length (file-name-directory string))
+ (let ((x (file-name-directory suffix)))
+ (if x (1- (length x)) (length suffix))))))
+ (t
(let ((names nil)
(suffix (concat (regexp-opt suffixes t) "\\'"))
- (string-dir (file-name-directory string)))
+ (string-dir (file-name-directory string))
+ (string-file (file-name-nondirectory string)))
(dolist (dir dirs)
(unless dir
(setq dir default-directory))
(if string-dir (setq dir (expand-file-name string-dir dir)))
(when (file-directory-p dir)
(dolist (file (file-name-all-completions
- (file-name-nondirectory string) dir))
- (add-to-list 'names (if string-dir (concat string-dir file) file))
+ string-file dir))
+ (push file names)
(when (string-match suffix file)
(setq file (substring file 0 (match-beginning 0)))
- (push (if string-dir (concat string-dir file) file) names)))))
- (complete-with-action action names string pred))))
+ (push file names)))))
+ (completion-table-with-context
+ string-dir names string-file pred action)))))
(defun locate-file-completion (string path-and-suffixes action)
"Do completion for file names passed to `locate-file'.
@@ -1469,18 +1486,29 @@ killed."
t)))
(unless (run-hook-with-args-until-failure 'kill-buffer-query-functions)
(error "Aborted"))
- (when (and (buffer-modified-p) (buffer-file-name))
- (if (yes-or-no-p (format "Buffer %s is modified; kill anyway? "
- (buffer-name)))
- (unless (yes-or-no-p "Kill and replace the buffer without saving it? ")
- (error "Aborted"))
- (save-buffer)))
+ (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"))))
(let ((obuf (current-buffer))
(ofile buffer-file-name)
(onum buffer-file-number)
(odir dired-directory)
(otrue buffer-file-truename)
(oname (buffer-name)))
+ ;; 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.
(if (get-buffer " **lose**")
(kill-buffer " **lose**"))
(rename-buffer " **lose**")
@@ -1508,8 +1536,8 @@ killed."
(rename-buffer oname)))
(unless (eq (current-buffer) obuf)
(with-current-buffer obuf
- ;; We already asked; don't ask again.
- (let ((kill-buffer-query-functions))
+ ;; We already ran these; don't run them again.
+ (let (kill-buffer-query-functions kill-buffer-hook)
(kill-buffer obuf))))))
(defun create-file-buffer (filename)
@@ -2098,7 +2126,7 @@ not set local variables (though we do notice a mode specified with -*-.)
or from Lisp without specifying the optional argument FIND-FILE;
in that case, this function acts as if `enable-local-variables' were t."
(interactive)
- (funcall (or default-major-mode 'fundamental-mode))
+ (funcall (or (default-value 'major-mode) 'fundamental-mode))
(let ((enable-local-variables (or (not find-file) enable-local-variables)))
(report-errors "File mode specification error: %s"
(set-auto-mode))
@@ -2144,7 +2172,6 @@ since only a single case-insensitive search through the alist is made."
("\\.dtx\\'" . doctex-mode)
("\\.org\\'" . org-mode)
("\\.el\\'" . emacs-lisp-mode)
- ("Project\\.ede\\'" . emacs-lisp-mode)
("\\.\\(scm\\|stk\\|ss\\|sch\\)\\'" . scheme-mode)
("\\.l\\'" . lisp-mode)
("\\.li?sp\\'" . lisp-mode)
@@ -2152,13 +2179,14 @@ since only a single case-insensitive search through the alist is made."
("\\.for\\'" . fortran-mode)
("\\.p\\'" . pascal-mode)
("\\.pas\\'" . pascal-mode)
+ ("\\.\\(dpr\\|DPR\\)\\'" . delphi-mode)
("\\.ad[abs]\\'" . ada-mode)
("\\.ad[bs].dg\\'" . ada-mode)
("\\.\\([pP]\\([Llm]\\|erl\\|od\\)\\|al\\)\\'" . perl-mode)
("Imakefile\\'" . makefile-imake-mode)
("Makeppfile\\(?:\\.mk\\)?\\'" . makefile-makepp-mode) ; Put this before .mk
("\\.makepp\\'" . makefile-makepp-mode)
- ,@(if (memq system-type '(berkeley-unix next-mach darwin))
+ ,@(if (memq system-type '(berkeley-unix darwin))
'(("\\.mk\\'" . makefile-bsdmake-mode)
("GNUmakefile\\'" . makefile-gmake-mode)
("[Mm]akefile\\'" . makefile-bsdmake-mode))
@@ -2203,7 +2231,6 @@ since only a single case-insensitive search through the alist is made."
("\\.f9[05]\\'" . f90-mode)
("\\.indent\\.pro\\'" . fundamental-mode) ; to avoid idlwave-mode
("\\.\\(pro\\|PRO\\)\\'" . idlwave-mode)
- ("\\.srt\\'" . srecode-template-mode) ; in the CEDET library
("\\.prolog\\'" . prolog-mode)
("\\.tar\\'" . tar-mode)
;; The list of archive file extensions should be in sync with
@@ -2308,6 +2335,7 @@ appear in `auto-coding-alist' with `no-conversion' coding system.
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.")
+(put 'auto-mode-alist 'risky-local-variable t)
(defun conf-mode-maybe ()
"Select Conf mode or XML mode according to start of file."
@@ -2401,6 +2429,7 @@ If FUNCTION is nil, then it is not called. (That is a way of saying
(defvar magic-fallback-mode-alist
`((image-type-auto-detected-p . image-mode)
+ ("\\(PK00\\)?[P]K\003\004" . archive-mode) ; zip
;; The < comes before the groups (but the first) to reduce backtracking.
;; TODO: UTF-16 <?xml may be preceded by a BOM 0xff 0xfe or 0xfe 0xff.
;; We use [ \t\r\n] instead of `\\s ' to make regex overflow less likely.
@@ -2643,6 +2672,7 @@ Otherwise, return nil; point may be changed."
'(ignored-local-variables safe-local-variable-values
file-local-variables-alist dir-local-variables-alist)
"Variables to be ignored in a file's local variable spec.")
+(put 'ignored-local-variables 'risky-local-variable t)
(defvar hack-local-variables-hook nil
"Normal hook run after processing a file's local variables specs.
@@ -2653,14 +2683,18 @@ in order to initialize other data structure based on them.")
"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."
+ :risky t
:group 'find-file
:type 'alist)
-(defcustom safe-local-eval-forms '((add-hook 'write-file-hooks 'time-stamp))
+(defcustom safe-local-eval-forms
+ '((add-hook 'write-file-functions 'time-stamp)
+ (add-hook 'before-save-hooks 'time-stamp))
"Expressions that are considered safe in an `eval:' local variable.
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."
+ :risky t
:group 'find-file
:version "22.2"
:type '(repeat sexp))
@@ -2668,63 +2702,34 @@ asking you for confirmation."
;; Risky local variables:
(mapc (lambda (var) (put var 'risky-local-variable t))
'(after-load-alist
- auto-mode-alist
buffer-auto-save-file-name
buffer-file-name
buffer-file-truename
buffer-undo-list
- dabbrev-case-fold-search
- dabbrev-case-replace
debugger
default-text-properties
- display-time-string
- enable-local-eval
- enable-local-variables
eval
exec-directory
exec-path
file-name-handler-alist
- font-lock-defaults
- format-alist
frame-title-format
global-mode-string
header-line-format
icon-title-format
- ignored-local-variables
- imenu--index-alist
- imenu-generic-expression
inhibit-quit
- input-method-alist
load-path
max-lisp-eval-depth
max-specpdl-size
- minor-mode-alist
minor-mode-map-alist
minor-mode-overriding-map-alist
- mode-line-buffer-identification
mode-line-format
- mode-line-client
- mode-line-modes
- mode-line-modified
- mode-line-mule-info
- mode-line-position
- mode-line-process
- mode-line-remote
mode-name
- outline-level
overriding-local-map
overriding-terminal-local-map
- parse-time-rules
process-environment
- rmail-output-file-alist
- safe-local-variable-values
- safe-local-eval-forms
- save-some-buffers-action-alist
- special-display-buffer-names
standard-input
standard-output
- unread-command-events
- vc-mode))
+ unread-command-events))
;; Safe local variables:
;;
@@ -4401,6 +4406,7 @@ This requires the external program `diff' to be in your `exec-path'."
nil)
"view changes in this buffer"))
"ACTION-ALIST argument used in call to `map-y-or-n-p'.")
+(put 'save-some-buffers-action-alist 'risky-local-variable t)
(defvar buffer-save-without-query nil
"Non-nil means `save-some-buffers' should save this buffer without asking.")
@@ -5400,17 +5406,13 @@ program specified by `directory-free-space-program' if that is non-nil."
(let ((fsinfo (file-system-info dir)))
(if fsinfo
(format "%.0f" (/ (nth 2 fsinfo) 1024))))
+ (setq dir (expand-file-name dir))
(save-match-data
(with-temp-buffer
(when (and directory-free-space-program
;; Avoid failure if the default directory does
;; not exist (Bug#2631, Bug#3911).
- (let ((default-directory default-directory))
- (setq dir (expand-file-name dir))
- (unless (and (not (file-remote-p default-directory))
- (file-directory-p default-directory)
- (file-readable-p default-directory))
- (setq default-directory "/"))
+ (let ((default-directory "/"))
(eq (call-process directory-free-space-program
nil t nil
directory-free-space-args