(defvar write-contents-functions nil
"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
-and the rest are not called.
+and the rest are not called and neither are the functions in
+`write-file-functions'.
This variable is meant to be used for hooks that pertain to the
buffer's contents, not to the particular visited file; thus,
"*Control processing of the \"variable\" `eval' in a file's local variables.
The value can be t, nil or something else.
A value of t means obey `eval' variables;
-nil means ignore them; anything else means query.
-
-The command \\[normal-mode] always obeys local-variables lists
-and ignores this variable."
+nil means ignore them; anything else means query."
:type '(choice (const :tag "Obey" t)
(const :tag "Ignore" nil)
(other :tag "Query" other))
(apply op args))))
(defun convert-standard-filename (filename)
- "Convert a standard file's name to something suitable for the current OS.
-This function's standard definition is trivial; it just returns the argument.
-However, on some systems, the function is redefined with a definition
-that really does change some file names to canonicalize certain
-patterns and to guarantee valid names."
+ "Convert a standard file's name to something suitable for the OS.
+This means to guarantee valid names and perhaps to canonicalize
+certain patterns.
+
+This function's standard definition is trivial; it just returns
+the argument. However, on Windows and DOS, replace invalid
+characters. On DOS, make sure to obey the 8.3 limitations. On
+Windows, turn Cygwin names into native names, and also turn
+slashes into backslashes if the shell requires it (see
+`w32-shell-dos-semantics').
+
+See Info node `(elisp)Standard File Names' for more details."
filename)
(defun read-directory-name (prompt &optional dir default-dirname mustmatch initial)
Not actually set up until the first time you use it.")
(defun parse-colon-path (cd-path)
- "Explode a colon-separated search path into a list of directory names.
-\(For values of `colon' equal to `path-separator'.)"
+ "Explode a search path into a list of directory names.
+Directories are separated by occurrences of `path-separator'
+\(which is colon in GNU and GNU-like systems)."
;; We could use split-string here.
(and cd-path
(let (cd-list (cd-start 0) cd-colon)
(defun cd (dir)
"Make DIR become the current buffer's default directory.
-If your environment includes a `CDPATH' variable, try each one of that
-colon-separated list of directories when resolving a relative directory name."
+If your environment includes a `CDPATH' variable, try each one of
+that list of directories (separated by occurrences of
+`path-separator') when resolving a relative directory name.
+The path separator is colon in GNU and GNU-like systems."
(interactive
(list (read-directory-name "Change default directory: "
default-directory default-directory
(load library))
(defun file-remote-p (file)
- "Test whether FILE specifies a location on a remote system."
- (let ((handler (find-file-name-handler file 'file-local-copy)))
+ "Test whether FILE specifies a location on a remote system.
+Return an identification of the system if the location is indeed
+remote. The identification of the system may comprise a method
+to access the system and its hostname, amongst other things.
+
+For example, the filename \"/user@host:/foo\" specifies a location
+on the system \"/user@host:\"."
+ (let ((handler (find-file-name-handler file 'file-remote-p)))
(if handler
- (get handler 'file-remote-p))))
+ (funcall handler 'file-remote-p file)
+ nil)))
(defun file-local-copy (file)
"Copy the file FILE into a temporary file on this machine.
both at the level of the file and at the level of the directories
containing it, until no links are left at any level.
-\(fn FILENAME)"
+\(fn FILENAME)" ;; Don't document the optional arguments.
;; 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.
\f
(defun switch-to-buffer-other-window (buffer &optional norecord)
"Select buffer BUFFER in another window.
+If BUFFER does not identify an existing buffer, then this function
+creates a buffer with that name.
+
+When called from Lisp, BUFFER can be a buffer, a string \(a buffer name),
+or nil. If BUFFER is nil, then this function chooses a buffer
+using `other-buffer'.
Optional second arg NORECORD non-nil means
do not put this buffer at the front of the list of recently selected ones.
+This function returns the buffer it switched to.
This uses the function `display-buffer' as a subroutine; see its
documentation for additional customization information."
type M-n to pull it into the minibuffer.
Interactively, or if WILDCARDS is non-nil in a call from Lisp,
-expand wildcards (if any) and visit multiple files. Wildcard expansion
-can be suppressed by setting `find-file-wildcards'."
+expand wildcards (if any) and visit multiple files. You can
+suppress wildcard expansion by setting `find-file-wildcards'.
+
+To visit a file without any kind of conversion and without
+automatically choosing a major mode, use \\[find-file-literally]."
(interactive
(find-file-read-args "Find file: " nil))
(let ((value (find-file-noselect filename nil nil wildcards)))
(mapcar 'switch-to-buffer (cdr value)))
(switch-to-buffer-other-frame value))))
+(defun find-file-existing (filename &optional wildcards)
+ "Edit the existing file FILENAME.
+Like \\[find-file] but only allow files that exists."
+ (interactive (find-file-read-args "Find existing file: " t))
+ (unless (file-exists-p filename) (error "%s does not exist" filename))
+ (find-file filename wildcards)
+ (current-buffer))
+
(defun find-file-read-only (filename &optional wildcards)
"Edit file FILENAME but don't allow changes.
Like \\[find-file] but marks buffer as read-only.
When nil, never request confirmation."
:group 'files
:group 'find-file
+ :version "21.4"
:type '(choice integer (const :tag "Never request confirmation" nil)))
(defun find-file-noselect (filename &optional nowarn rawfile wildcards)
(mapc
(lambda (elt)
(cons (purecopy (car elt)) (cdr elt)))
- '(("\\.te?xt\\'" . text-mode)
- ("\\.tex\\'" . tex-mode)
+ '(;; do this first, so that .html.pl is Polish html, not Perl
+ ("\\.s?html?\\(\\.[a-zA-Z_]+\\)?\\'" . html-mode)
+ ("\\.te?xt\\'" . text-mode)
+ ("\\.[tT]e[xX]\\'" . tex-mode)
("\\.ins\\'" . tex-mode) ;Installation files for TeX packages.
("\\.ltx\\'" . latex-mode)
("\\.dtx\\'" . doctex-mode)
("\\.el\\'" . emacs-lisp-mode)
("\\.\\(scm\\|stk\\|ss\\|sch\\)\\'" . scheme-mode)
("\\.l\\'" . lisp-mode)
- ("\\.lisp\\'" . lisp-mode)
- ("\\.f\\'" . fortran-mode)
- ("\\.F\\'" . fortran-mode)
+ ("\\.li?sp\\'" . lisp-mode)
+ ("\\.[fF]\\'" . fortran-mode)
("\\.for\\'" . fortran-mode)
("\\.p\\'" . pascal-mode)
("\\.pas\\'" . pascal-mode)
("\\.ad[abs]\\'" . ada-mode)
("\\.ad[bs].dg\\'" . ada-mode)
- ("\\.\\([pP]\\([Llm]\\|erl\\)\\|al\\)\\'" . perl-mode)
- ("\\.s?html?\\'" . html-mode)
+ ("\\.\\([pP]\\([Llm]\\|erl\\|od\\)\\|al\\)\\'" . perl-mode)
("\\.mk\\'" . makefile-mode)
- ("\\(M\\|m\\|GNUm\\)akefile\\'" . makefile-mode)
+ ("\\([Mm]\\|GNUm\\)akep*file\\'" . makefile-mode)
("\\.am\\'" . makefile-mode) ;For Automake.
;; Less common extensions come here
;; so more common ones above are found faster.
("\\.texinfo\\'" . texinfo-mode)
("\\.te?xi\\'" . texinfo-mode)
- ("\\.s\\'" . asm-mode)
- ("\\.S\\'" . asm-mode)
+ ("\\.[sS]\\'" . asm-mode)
("\\.asm\\'" . asm-mode)
- ("ChangeLog\\'" . change-log-mode)
- ("change\\.log\\'" . change-log-mode)
- ("changelo\\'" . change-log-mode)
- ("ChangeLog\\.[0-9]+\\'" . change-log-mode)
- ;; for MSDOS and MS-Windows (which are case-insensitive)
- ("changelog\\'" . change-log-mode)
- ("changelog\\.[0-9]+\\'" . change-log-mode)
+ ("[cC]hange\\.?[lL]og?\\'" . change-log-mode)
+ ("[cC]hange[lL]og\\.[0-9]+\\'" . change-log-mode)
("\\$CHANGE_LOG\\$\\.TXT" . change-log-mode)
("\\.scm\\.[0-9]*\\'" . scheme-mode)
("\\.[ck]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode)
("\\(/\\|\\`\\)\\.\\(bash_logout\\|shrc\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode)
("\\(/\\|\\`\\)\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode)
("\\.m?spec\\'" . sh-mode)
- ("\\.mm\\'" . nroff-mode)
- ("\\.me\\'" . nroff-mode)
- ("\\.ms\\'" . nroff-mode)
+ ("\\.m[mes]\\'" . nroff-mode)
("\\.man\\'" . nroff-mode)
- ("\\.TeX\\'" . tex-mode)
("\\.sty\\'" . latex-mode)
- ("\\.cls\\'" . latex-mode) ;LaTeX 2e class
- ("\\.clo\\'" . latex-mode) ;LaTeX 2e class option
+ ("\\.cl[so]\\'" . latex-mode) ;LaTeX 2e class option
("\\.bbl\\'" . latex-mode)
("\\.bib\\'" . bibtex-mode)
("\\.sql\\'" . sql-mode)
- ("\\.m4\\'" . m4-mode)
- ("\\.mc\\'" . m4-mode)
+ ("\\.m[4c]\\'" . m4-mode)
("\\.mf\\'" . metafont-mode)
("\\.mp\\'" . metapost-mode)
("\\.vhdl?\\'" . vhdl-mode)
("\\.article\\'" . text-mode)
("\\.letter\\'" . text-mode)
- ("\\.tcl\\'" . tcl-mode)
+ ("\\.i?tcl\\'" . tcl-mode)
("\\.exp\\'" . tcl-mode)
- ("\\.itcl\\'" . tcl-mode)
("\\.itk\\'" . tcl-mode)
("\\.icn\\'" . icon-mode)
("\\.sim\\'" . simula-mode)
("\\.mss\\'" . scribe-mode)
- ("\\.f90\\'" . f90-mode)
- ("\\.f95\\'" . f90-mode)
+ ("\\.f9[05]\\'" . f90-mode)
("\\.indent\\.pro\\'" . fundamental-mode) ; to avoid idlwave-mode
("\\.pro\\'" . idlwave-mode)
- ("\\.lsp\\'" . lisp-mode)
("\\.prolog\\'" . prolog-mode)
("\\.tar\\'" . tar-mode)
("\\.\\(arc\\|zip\\|lzh\\|zoo\\|ear\\|jar\\|war\\)\\'" . archive-mode)
("\\`/tmp/fol/" . text-mode)
("\\.oak\\'" . scheme-mode)
("\\.sgml?\\'" . sgml-mode)
- ("\\.xml\\'" . sgml-mode)
- ("\\.xsl\\'" . sgml-mode)
+ ("\\.x[ms]l\\'" . xml-mode)
("\\.dtd\\'" . sgml-mode)
("\\.ds\\(ss\\)?l\\'" . dsssl-mode)
+ ("\\.js\\'" . java-mode) ; javascript-mode would be better
+ ("\\.x[bp]m\\'" . c-mode)
;; .emacs or .gnus or .viper following a directory delimiter in
;; Unix, MSDOG or VMS syntax.
("[]>:/\\]\\..*\\(emacs\\|gnus\\|viper\\)\\'" . emacs-lisp-mode)
("BROWSE\\'" . ebrowse-tree-mode)
("\\.ebrowse\\'" . ebrowse-tree-mode)
("#\\*mail\\*" . mail-mode)
+ ("\\.g\\'" . antlr-mode)
+ ("\\.ses\\'" . ses-mode)
+ ("\\.\\(soa\\|zone\\)\\'" . dns-mode)
+ ("\\.docbook\\'" . sgml-mode)
+ ("/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)
+ ("\\.ppd\\'" . conf-ppd-mode)
+ ("java.+\\.conf\\'" . conf-javaprop-mode)
+ ("\\.properties\\(?:\\.[a-zA-Z0-9._-]+\\)?\\'" . conf-javaprop-mode)
+ ;; *.cf, *.cfg, *.conf, *.config[.local|.de_DE.UTF8|...], */config
+ ("[/.]c\\(?:on\\)?f\\(?:i?g\\)?\\(?:\\.[a-zA-Z0-9._-]+\\)?\\'" . conf-mode)
+ ("\\`/etc/\\(?:DIR_COLORS\\|ethers\\|.?fstab\\|.*hosts\\|lesskey\\|login\\.?de\\(?:fs\\|vperm\\)\\|magic\\|mtab\\|pam\\.d/.*\\|permissions\\|protocols\\|rpc\\|services\\)\\'" . conf-space-mode)
+ ("\\`/etc/\\(?:acpid?/.+\\|aliases\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\)\\'" . conf-mode)
+ ;; 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
+ ("/\\.\\(?:enigma\\|gltron\\|gtk\\|hxplayer\\|net\\|neverball\\|qt/.+\\|realplayer\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-mode)
+ ("/\\.\\(?: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)
;; Get rid of any trailing .n.m and try again.
;; This is for files saved by cvs-merge that look like .#<file>.<rev>
;; 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.
- ("\\.~?[0-9]+\\.[0-9][-.0-9]*~?\\'" ignore t)
+ ("\\.~?[0-9]+\\.[0-9][-.0-9]*~?\\'" nil t)
;; 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.
("\\.[1-9]\\'" . nroff-mode)
- ("\\.g\\'" . antlr-mode)
- ("\\.ses\\'" . ses-mode)
- ("\\.orig\\'" nil t) ; from patch
- ("\\.in\\'" nil t)))
+ ("\\.\\(?:orig\\|in\\|[bB][aA][kK]\\)\\'" nil t)))
"Alist of filename patterns vs corresponding major mode functions.
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.)
regular expression. The mode is then determined as the mode associated
with that interpreter in `interpreter-mode-alist'.")
-(defun set-auto-mode (&optional just-from-file-name)
+(defvar magic-mode-alist
+ `(;; 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.
+ (,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)")
+ (comment-re (concat "\\(?:!--" incomment-re "*-->\\s *<\\)")))
+ (concat "\\(?:<\\?xml\\s +[^>]*>\\)?\\s *<"
+ comment-re "*"
+ "\\(?:!DOCTYPE\\s +[^>]*>\\s *<\\s *" comment-re "*\\)?"
+ "[Hh][Tt][Mm][Ll]")) . html-mode)
+ ;; These two must come after html, because they are more general:
+ ("<\\?xml " . xml-mode)
+ (,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)")
+ (comment-re (concat "\\(?:!--" incomment-re "*-->\\s *<\\)")))
+ (concat "\\s *<" comment-re "*!DOCTYPE ")) . sgml-mode)
+ ("%![^V]" . ps-mode)
+ ("# xmcd " . conf-unix-mode))
+ "Alist of buffer beginnings vs. corresponding major mode functions.
+Each element looks like (REGEXP . FUNCTION). FUNCTION will be
+called, unless it is nil (to allow `auto-mode-alist' to override).")
+
+(defun set-auto-mode (&optional keep-mode-if-same)
"Select major mode appropriate for current buffer.
-This checks for a -*- mode tag in the buffer's text,
-compares the filename against the entries in `auto-mode-alist',
-or checks the interpreter that runs this file against
-`interpreter-mode-alist'.
+
+This checks for a -*- mode tag in the buffer's text, checks the
+interpreter that runs this file against `interpreter-mode-alist',
+compares the buffer beginning against `magic-mode-alist', or
+compares the filename against the entries in `auto-mode-alist'.
It does not check for the `mode:' local variable in the
Local Variables section of the file; for that, use `hack-local-variables'.
If `enable-local-variables' is nil, this function does not check for a
-*- mode tag.
-If the optional argument JUST-FROM-FILE-NAME is non-nil,
-then we do not set anything but the major mode,
-and we don't even do that unless it would come from the file name."
+If the optional argument KEEP-MODE-IF-SAME is non-nil, then we
+only set the major mode, if that would change it."
;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
- (let (end done modes)
+ (let (end done mode modes)
+ ;; Find a -*- mode tag
(save-excursion
(goto-char (point-min))
(skip-chars-forward " \t\n")
(push (intern (concat (downcase (buffer-substring (point) end))
"-mode"))
modes))))
- ;; If we found modes to use, invoke them now,
- ;; outside the save-excursion.
- (unless just-from-file-name
- (dolist (mode (nreverse modes))
- (if (not (functionp mode))
- (message "Ignoring unknown mode `%s'" mode)
- (setq done t)
- (funcall mode))))
- ;; If we didn't find a mode from a -*- line, try using the file name.
- (if (and (not done) buffer-file-name)
- (let ((name buffer-file-name)
- (keep-going t))
- ;; Remove backup-suffixes from file name.
- (setq name (file-name-sans-versions name))
- (while keep-going
- (setq keep-going nil)
- (let ((alist auto-mode-alist)
- (mode nil))
- ;; Find first matching alist entry.
- (let ((case-fold-search
- (memq system-type '(vax-vms windows-nt cygwin))))
- (while (and (not mode) alist)
- (if (string-match (car (car alist)) name)
- (if (and (consp (cdr (car alist)))
- (nth 2 (car alist)))
- (setq mode (car (cdr (car alist)))
- name (substring name 0 (match-beginning 0))
- keep-going t)
- (setq mode (cdr (car alist))
- keep-going nil)))
- (setq alist (cdr alist))))
- (if mode
- ;; When JUST-FROM-FILE-NAME 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.
- (unless (and just-from-file-name (eq mode major-mode))
- (funcall mode))
- ;; If we can't deduce a mode from the file name,
- ;; 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.
- (let ((interpreter
- (save-excursion
- (goto-char (point-min))
- (if (looking-at auto-mode-interpreter-regexp)
- (match-string 2)
- "")))
- elt)
- ;; Map interpreter name to a mode.
- (setq elt (assoc (file-name-nondirectory interpreter)
- interpreter-mode-alist))
- (unless just-from-file-name
- (if elt
- (funcall (cdr elt))))))))))))
-
+ ;; If we found modes to use, invoke them now, outside the save-excursion.
+ (if modes
+ (catch 'nop
+ (dolist (mode (nreverse modes))
+ (if (not (functionp mode))
+ (message "Ignoring unknown mode `%s'" mode)
+ (setq done t)
+ (or (set-auto-mode-0 mode keep-mode-if-same)
+ ;; continuing would call minor modes again, toggling them off
+ (throw 'nop nil)))))
+ ;; 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.
+ (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))
+ ;; If we found an interpreter mode to use, invoke it now.
+ (if done
+ (set-auto-mode-0 (cdr done) keep-mode-if-same)))
+ ;; If we didn't, match the buffer beginning against magic-mode-alist.
+ (unless done
+ (if (setq done (save-excursion
+ (goto-char (point-min))
+ (assoc-default nil magic-mode-alist
+ (lambda (re dummy)
+ (looking-at re)))))
+ (set-auto-mode-0 done keep-mode-if-same)
+ ;; Compare the filename against the entries in auto-mode-alist.
+ (if buffer-file-name
+ (let ((name buffer-file-name))
+ ;; Remove backup-suffixes from file name.
+ (setq name (file-name-sans-versions name))
+ (while name
+ ;; Find first matching alist entry.
+ (let ((case-fold-search
+ (memq system-type '(vax-vms windows-nt cygwin))))
+ (if (and (setq mode (assoc-default name auto-mode-alist
+ 'string-match))
+ (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)))))))))
+
+;; 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.
+(defun set-auto-mode-0 (mode &optional keep-mode-if-same)
+ "Apply MODE and return it.
+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."
+ (when keep-mode-if-same
+ (while (symbolp (symbol-function mode))
+ (setq mode (symbol-function mode)))
+ (if (eq mode major-mode)
+ (setq mode nil)))
+ (when mode
+ (funcall mode)
+ mode))
(defun set-auto-mode-1 ()
"Find the -*- spec in the buffer.
buffer-file-name)
(concat "buffer "
(buffer-name))))))))))
- (let ((continue t)
- prefix prefixlen suffix beg
- mode-specified
+ (let (prefix prefixlen suffix beg
(enable-local-eval enable-local-eval))
;; The prefix is what comes before "local variables:" in its line.
;; The suffix is what comes after "local variables:" in its line.
(if prefix (setq prefixlen (length prefix)
prefix (regexp-quote prefix)))
(if suffix (setq suffix (concat (regexp-quote suffix) "$")))
- (while continue
- ;; Look at next local variable spec.
- (if selective-display (re-search-forward "[\n\C-m]")
- (forward-line 1))
- ;; Skip the prefix, if any.
- (if prefix
- (if (looking-at prefix)
- (forward-char prefixlen)
- (error "Local variables entry is missing the prefix")))
- ;; 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)))
- (var (read str))
- val)
- ;; Setting variable named "end" means end of list.
- (if (string-equal (downcase str) "end")
- (setq continue nil)
- ;; Otherwise read the variable value.
- (skip-chars-forward "^:")
- (forward-char 1)
- (setq val (read (current-buffer)))
- (skip-chars-backward "\n")
+ (forward-line 1)
+ (let ((startpos (point))
+ endpos
+ (thisbuf (current-buffer)))
+ (save-excursion
+ (if (not (re-search-forward
+ (concat (or prefix "")
+ "[ \t]*End:[ \t]*"
+ (or suffix ""))
+ nil t))
+ (error "Local variables list is not properly terminated"))
+ (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 any.
+ (if 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 any.
+ (if 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")
- (or (if suffix (looking-at suffix) (eolp))
- (error "Local variables entry is terminated incorrectly"))
- (if mode-only
- (if (eq var 'mode)
- (setq mode-specified t))
- ;; Set the variable. "Variables" mode and eval are funny.
- (hack-one-local-variable var val))))))))
+ (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)))
+ (var (read str))
+ val)
+ ;; Read the variable value.
+ (skip-chars-forward "^:")
+ (forward-char 1)
+ (setq val (read (current-buffer)))
+ (if mode-only
+ (if (eq var 'mode)
+ (setq mode-specified t))
+ ;; Set the variable. "Variables" mode and eval are funny.
+ (with-current-buffer thisbuf
+ (hack-one-local-variable var val))))
+ (forward-line 1)))))))
(unless mode-only
(run-hooks 'hack-local-variables-hook))
mode-specified))
-(defvar ignored-local-variables
- '(enable-local-eval)
+(defvar ignored-local-variables ()
"Variables to be ignored in a file's local variable spec.")
;; Get confirmation before setting these variables as locals in a file.
If VAL is nil or omitted, the question is whether any value might be
dangerous."
(let ((safep (get sym 'safe-local-variable)))
- (or (memq sym ignored-local-variables)
- (get sym 'risky-local-variable)
+ (or (get sym 'risky-local-variable)
(and (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$\\|-predicate$\\|font-lock-keywords$\\|font-lock-keywords-[0-9]+$\\|font-lock-syntactic-keywords$\\|-frame-alist$\\|-mode-alist$\\|-map$\\|-map-alist$"
(symbol-name sym))
(not safep))
((eq var 'coding)
;; We have already handled coding: tag in set-auto-coding.
nil)
+ ((memq var ignored-local-variables)
+ nil)
;; "Setting" eval means either eval it or do nothing.
;; Likewise for setting hook variables.
((risky-local-variable-p var val)
(file-name-as-directory (expand-file-name (or directory
default-directory))))
(setq filename (expand-file-name filename))
- (let ((hf (find-file-name-handler filename 'file-local-copy))
- (hd (find-file-name-handler directory 'file-local-copy)))
- (when (and hf (not (get hf 'file-remote-p))) (setq hf nil))
- (when (and hd (not (get hd 'file-remote-p))) (setq hd nil))
+ (let ((fremote (file-remote-p filename))
+ (dremote (file-remote-p directory)))
(if ;; Conditions for separate trees
(or
;; Test for different drives on DOS/Windows
;; Should `cygwin' really be included here? --stef
(memq system-type '(ms-dos cygwin windows-nt))
(not (eq t (compare-strings filename 0 2 directory 0 2))))
- ;; Test for different remote file handlers
- (not (eq hf hd))
;; Test for different remote file system identification
- (and
- hf
- (let ((re (car (rassq hf file-name-handler-alist))))
- (not
- (equal
- (and
- (string-match re filename)
- (substring filename 0 (match-end 0)))
- (and
- (string-match re directory)
- (substring directory 0 (match-end 0))))))))
+ (not (equal fremote dremote)))
filename
(let ((ancestor ".")
(filename-dir (file-name-as-directory filename)))
(defcustom before-save-hook nil
"Normal hook that is run before a buffer is saved to its file."
- :options '(copyright-update)
+ :options '(copyright-update time-stamp)
:type 'hook
:group 'files)
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
-time consuming operations.")
+time consuming operations.
+
+For more information on how this variable is used by Auto Revert mode,
+see Info node `(emacs-xtra)Supporting additional buffers'.")
(defvar before-revert-hook nil
"Normal hook for `revert-buffer' to run before reverting.
(defun kill-some-buffers (&optional list)
"Kill some buffers. Asks the user whether to kill each one of them.
-Non-interactively, if optional argument LIST is non-`nil', it
+Non-interactively, if optional argument LIST is non-nil, it
specifies the list of buffers to kill, asking for approval for each one."
(interactive)
(if (null list)
(while (< (point) end)
(let ((start (+ beg (read (current-buffer))))
(end (+ beg (read (current-buffer)))))
- (if (= (char-after end) ?\n)
+ (if (memq (char-after end) '(?\n ?\ ))
+ ;; 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.
(define-key ctl-x-map "i" 'insert-file)
(define-key esc-map "~" 'not-modified)
(define-key ctl-x-map "\C-d" 'list-directory)
-(define-key ctl-x-map "\C-c" 'save-buffers-kill-emacs)
+(define-key ctl-x-map "\C-c" 'server-save-buffers-kill-display)
(define-key ctl-x-map "\C-q" 'toggle-read-only)
(define-key ctl-x-4-map "f" 'find-file-other-window)