diff options
Diffstat (limited to 'lisp/files.el')
-rw-r--r-- | lisp/files.el | 118 |
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 |