(defcustom enable-local-variables t
"*Control use of local variables in files you visit.
-The value can be t, nil or something else.
+The value can be t, nil, :safe, or something else.
A value of t means file local variables specifications are obeyed
-if all the specified variables are safe. If any variables are
-not safe, you will be queries before setting them.
-A value of nil means file local variables are ignored.
-Any other value means to always query.
+if all the specified variable values are safe; if any values are
+not safe, Emacs queries you, once, whether to set them all.
+\(When you say yes to certain values, they are remembered as safe.)
+
+:safe means set the safe variables, and ignore the rest.
+:all means set all variables, whether safe or not.
+ (Don't set it permanently to :all.)
+nil means always ignore the file local variables.
+
+Any other value means always query you once whether to set them all.
+\(When you say yes to certain values, they are remembered as safe, but
+this has no effect when `enable-local-variables' is \"something else\".)
This variable also controls use of major modes specified in
a -*- line.
The command \\[normal-mode], when used interactively,
always obeys file local variable specifications and the -*- line,
and ignores this variable."
- :type '(choice (const :tag "Obey" t)
+ :type '(choice (const :tag "Query Unsafe" t)
+ (const :tag "Safe Only" :safe)
+ (const :tag "Do all" :all)
(const :tag "Ignore" nil)
(other :tag "Query" other))
:group 'find-file)
(interactive
(list (completing-read "Load library: "
'locate-file-completion
- (cons load-path load-suffixes))))
+ (cons load-path (get-load-suffixes)))))
(load library))
(defun file-remote-p (file)
(pop-to-buffer buffer t norecord)
(raise-frame (window-frame (selected-window)))))
+(defun display-buffer-other-frame (buffer)
+ "Switch to buffer BUFFER in another frame.
+This uses the function `display-buffer' as a subroutine; see its
+documentation for additional customization information."
+ (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))
+ (lower-frame (window-frame new-window))
+ (make-frame-invisible (window-frame old-window))
+ (make-frame-visible (window-frame old-window))))
+
(defvar find-file-default nil
"Used within `find-file-read-args'.")
This function is called automatically from `find-file'. In that case,
we may set up the file-specified mode and local variables,
-depending on the value of `enable-local-variables': if it is t, we do;
-if it is nil, we don't; otherwise, we query.
+depending on the value of `enable-local-variables'.
In addition, if `local-enable-local-variables' is nil, we do
not set local variables (though we do notice a mode specified with -*-.)
;; `auto-coding-alist' with `no-conversion' coding system.
("\\.\\(arc\\|zip\\|lzh\\|zoo\\|[jew]ar\\|xpi\\)\\'" . archive-mode)
("\\.\\(ARC\\|ZIP\\|LZH\\|ZOO\\|[JEW]AR\\|XPI\\)\\'" . archive-mode)
- ("\\.sx[dmicw]\\'" . archive-mode) ; OpenOffice.org
+ ("\\.\\(sx[dmicw]\\|odt\\)\\'" . archive-mode) ; OpenOffice.org
;; Mailer puts message to be edited in
;; /tmp/Re.... or Message
("\\`/tmp/Re" . text-mode)
If the file name matches `inhibit-first-line-modes-regexps',
then `auto-mode-alist' is not processed.
+The extensions whose FUNCTION is `archive-mode' should also
+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.")
(setq end (point))
(goto-char beg)
end))))
+\f
+;;; Handling file local variables
+
+(defvar ignored-local-variables
+ '(ignored-local-variables safe-local-variable-values)
+ "Variables to be ignored in a file's local variable spec.")
+
+(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."
+ :group 'find-file
+ :type 'alist)
+
+(defcustom safe-local-eval-forms nil
+ "*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."
+ :group 'find-file
+ :version "22.1"
+ :type '(repeat sexp))
+
+;; 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-modes
+ mode-line-modified
+ mode-line-mule-info
+ mode-line-position
+ mode-line-process
+ 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))
+
+;; Safe local variables:
+;;
+;; 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:
+
+;; FIXME: Some variables should be moved according to the rules above.
+(let ((string-or-null (lambda (a) (or (stringp a) (null a)))))
+ (eval
+ `(mapc (lambda (pair)
+ (put (car pair) 'safe-local-variable (cdr pair)))
+ '((byte-compile-dynamic . t)
+ (byte-compile-dynamic-docstrings . t)
+ (byte-compile-warnings . t)
+ (c-basic-offset . integerp)
+ (c-file-style . stringp)
+ (c-indent-level . integerp)
+ (comment-column . integerp)
+ (compile-command . string-or-null-p)
+ (find-file-visit-truename . t)
+ (fill-column . integerp)
+ (fill-prefix . string-or-null-p)
+ (indent-tabs-mode . t)
+ (kept-old-versions . integerp)
+ (kept-new-versions . integerp)
+ (left-margin . t)
+ (no-byte-compile . t)
+ (no-update-autoloads . t)
+ (outline-regexp . string-or-null-p)
+ (tab-width . integerp) ;; C source code
+ (truncate-lines . t) ;; C source code
+ (version-control . t)))))
+
+(put 'c-set-style 'safe-local-eval-function t)
(defun hack-local-variables-confirm (vars unsafe-vars risky-vars)
(if noninteractive
(let ((name (if buffer-file-name
(file-name-nondirectory buffer-file-name)
(concat "buffer " (buffer-name))))
+ (offer-save (and (eq enable-local-variables t) unsafe-vars))
prompt char)
(save-window-excursion
(let ((buf (get-buffer-create "*Local Variables*")))
(insert "A local variables list is specified in " name ".")))
(insert "\n\nDo you want to apply it? You can type
y -- to apply the local variables list.
-n -- to ignore the local variables list.
-! -- to apply the local variables list, and mark these values (*) as
- safe (in the future, they can be set automatically.)\n\n")
+n -- to ignore the local variables list.")
+ (if offer-save
+ (insert "
+! -- to apply the local variables list, and permanently mark these
+ values (*) as safe (in the future, they will be set automatically.)\n\n")
+ (insert "\n\n"))
(dolist (elt vars)
(cond ((member elt unsafe-vars)
(insert " * "))
(insert " : ")
(princ (cdr elt) buf)
(insert "\n"))
- (if (< (line-number-at-pos) (window-body-height))
- (setq prompt "Please type y, n, or !: ")
- (goto-char (point-min))
- (setq prompt "Please type y, n, or !, or C-v to scroll: "))
- (let ((inhibit-quit t)
- (cursor-in-echo-area t)
+ (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))
+ (let ((cursor-in-echo-area t)
+ (exit-chars
+ (if offer-save '(?! ?y ?n ?\s ?\C-g) '(?y ?n ?\s ?\C-g)))
done)
(while (not done)
(message prompt)
(condition-case nil
(scroll-up)
(error (goto-char (point-min))))
- (setq done (memq (downcase char)
- '(?! ?y ?n ?\s ?\C-g))))))
- (if (= char ?\C-g)
- (setq quit-flag nil)))
+ (setq done (memq (downcase char) exit-chars))))))
(setq char (downcase char))
- (when (and (= char ?!) unsafe-vars)
+ (when (and offer-save (= char ?!) unsafe-vars)
(dolist (elt unsafe-vars)
(add-to-list 'safe-local-variable-values elt))
- (customize-save-variable
- 'safe-local-variable-values
- safe-local-variable-values))
+ ;; When this is called from desktop-restore-file-buffer,
+ ;; coding-system-for-read may be non-nil. Reset it before
+ ;; writing to .emacs.
+ (if (or custom-file user-init-file)
+ (let ((coding-system-for-read nil))
+ (customize-save-variable
+ 'safe-local-variable-values
+ safe-local-variable-values))))
(kill-buffer buf)
(or (= char ?!)
(= char ?\s)
mode-specified
result))))
-(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."
- :group 'find-file
- :type 'alist)
-
(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
(and (risky-local-variable-p var val)
(push elt risky-vars))
(push elt unsafe-vars))))
- (if (or (and (eq enable-local-variables t)
- (null unsafe-vars)
- (null risky-vars))
- (hack-local-variables-confirm
- result unsafe-vars risky-vars))
+ (if (eq enable-local-variables :safe)
+ ;; If caller wants only the safe variables,
+ ;; install only them.
(dolist (elt result)
- (hack-one-local-variable (car elt) (cdr elt)))))
+ (unless (or (memq (car elt) unsafe-vars)
+ (memq (car elt) risky-vars))
+ (hack-one-local-variable (car elt) (cdr elt))))
+ ;; Query, except in the case where all are known safe
+ ;; if the user wants no quuery in that case.
+ (if (or (and (eq enable-local-variables t)
+ (null unsafe-vars)
+ (null risky-vars))
+ (eq enable-local-variables :all)
+ (hack-local-variables-confirm
+ result unsafe-vars risky-vars))
+ (dolist (elt result)
+ (hack-one-local-variable (car elt) (cdr elt))))))
(run-hooks 'hack-local-variables-hook))))))
-(defvar ignored-local-variables
- '(ignored-local-variables safe-local-variable-values)
- "Variables to be ignored in a file's local variable spec.")
-
-;; Get confirmation before setting these variables as locals in a file.
-(put 'debugger 'risky-local-variable t)
-(put 'enable-local-eval 'risky-local-variable t)
-(put 'ignored-local-variables 'risky-local-variable t)
-(put 'ignored-local-variables 'safe-local-variable-values t)
-(put 'eval 'risky-local-variable t)
-(put 'file-name-handler-alist 'risky-local-variable t)
-(put 'inhibit-quit 'risky-local-variable t)
-(put 'minor-mode-alist 'risky-local-variable t)
-(put 'minor-mode-map-alist 'risky-local-variable t)
-(put 'minor-mode-overriding-map-alist 'risky-local-variable t)
-(put 'overriding-local-map 'risky-local-variable t)
-(put 'overriding-terminal-local-map 'risky-local-variable t)
-(put 'auto-mode-alist 'risky-local-variable t)
-(put 'after-load-alist 'risky-local-variable t)
-(put 'buffer-file-name 'risky-local-variable t)
-(put 'buffer-undo-list 'risky-local-variable t)
-(put 'buffer-auto-save-file-name 'risky-local-variable t)
-(put 'buffer-file-truename 'risky-local-variable t)
-(put 'default-text-properties 'risky-local-variable t)
-(put 'exec-path 'risky-local-variable t)
-(put 'load-path 'risky-local-variable t)
-(put 'exec-directory 'risky-local-variable t)
-(put 'process-environment 'risky-local-variable t)
-(put 'dabbrev-case-fold-search 'risky-local-variable t)
-(put 'dabbrev-case-replace 'risky-local-variable t)
-;; Don't wait for outline.el to be loaded, for the sake of outline-minor-mode.
-(put 'outline-level 'risky-local-variable t)
-(put 'rmail-output-file-alist 'risky-local-variable t)
-(put 'font-lock-defaults 'risky-local-variable t)
-(put 'special-display-buffer-names 'risky-local-variable t)
-(put 'frame-title-format 'risky-local-variable t)
-(put 'global-mode-string 'risky-local-variable t)
-(put 'header-line-format 'risky-local-variable t)
-(put 'icon-title-format 'risky-local-variable t)
-(put 'input-method-alist 'risky-local-variable t)
-(put 'format-alist 'risky-local-variable t)
-(put 'vc-mode 'risky-local-variable t)
-(put 'imenu-generic-expression 'risky-local-variable t)
-(put 'imenu--index-alist 'risky-local-variable t)
-(put 'standard-input 'risky-local-variable t)
-(put 'standard-output 'risky-local-variable t)
-(put 'unread-command-events 'risky-local-variable t)
-(put 'max-lisp-eval-depth 'risky-local-variable t)
-(put 'max-specpdl-size 'risky-local-variable t)
-(put 'mode-line-format 'risky-local-variable t)
-(put 'mode-line-modified 'risky-local-variable t)
-(put 'mode-line-mule-info 'risky-local-variable t)
-(put 'mode-line-buffer-identification 'risky-local-variable t)
-(put 'mode-line-modes 'risky-local-variable t)
-(put 'mode-line-position 'risky-local-variable t)
-(put 'mode-line-process 'risky-local-variable t)
-(put 'mode-name 'risky-local-variable t)
-(put 'display-time-string 'risky-local-variable t)
-(put 'parse-time-rules 'risky-local-variable t)
-
-;; Commonly-encountered local variables that are safe:
-(let ((string-or-null (lambda (a) (or (stringp a) (null a)))))
- (eval
- `(mapc (lambda (pair)
- (put (car pair) 'safe-local-variable (cdr pair)))
- '((byte-compile-dynamic . t)
- (c-basic-offset . integerp)
- (c-file-style . stringp)
- (c-indent-level . integerp)
- (comment-column . integerp)
- (compile-command . ,string-or-null)
- (fill-column . integerp)
- (fill-prefix . ,string-or-null)
- (indent-tabs-mode . t)
- (ispell-check-comments . (lambda (a)
- (or (null a)
- (eq t a)
- (eq 'exclusive a))))
- (ispell-local-dictionary . ,string-or-null)
- (kept-new-versions . integerp)
- (no-byte-compile . t)
- (no-update-autoloads . t)
- (outline-regexp . ,string-or-null)
- (page-delimiter . ,string-or-null)
- (paragraph-start . ,string-or-null)
- (paragraph-separate . ,string-or-null)
- (sentence-end . ,string-or-null)
- (sentence-end-double-space . t)
- (tab-width . integerp)
- (truncate-lines . t)
- (version-control . t)))))
-
(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:
-[0-9]+$\\|font-lock-syntactic-keywords$\\|-frame-alist$\\|-mode-alist$\\|\
-map$\\|-map-alist$" (symbol-name sym))))
-(defcustom safe-local-eval-forms nil
- "*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."
- :group 'find-file
- :version "22.1"
- :type '(repeat sexp))
-
-(put 'c-set-style 'safe-local-eval-function t)
-
(defun hack-one-local-variable-quotep (exp)
(and (consp exp) (eq (car exp) 'quote) (consp (cdr exp))))
(and (eq (car exp) 'put)
(hack-one-local-variable-quotep (nth 1 exp))
(hack-one-local-variable-quotep (nth 2 exp))
- (memq (nth 1 (nth 2 exp))
- '(lisp-indent-hook))
- ;; Only allow safe values of lisp-indent-hook;
- ;; not functions.
- (or (numberp (nth 3 exp))
- (equal (nth 3 exp) ''defun)))
+ (let ((prop (nth 1 (nth 2 exp))) (val (nth 3 exp)))
+ (cond ((eq prop 'lisp-indent-hook)
+ ;; Only allow safe values of lisp-indent-hook;
+ ;; not functions.
+ (or (numberp val) (equal val ''defun)))
+ ((eq prop 'edebug-form-spec)
+ ;; Only allow indirect form specs.
+ (edebug-basic-spec val)))))
;; Allow expressions that the user requested.
(member exp safe-local-eval-forms)
;; Certain functions can be allowed with safe arguments
(?d diff-buffer-with-file
"view changes in file"))
"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.")
(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)
+(define-key ctl-x-5-map "\C-o" 'display-buffer-other-frame)
;; arch-tag: bc68d3ea-19ca-468b-aac6-3a4a7766101f
;;; files.el ends here