:group 'auto-save)
(defcustom auto-save-file-name-transforms
- `(("\\`/[^/]*:\\(.+/\\)*\\(.*\\)"
+ `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'"
;; Don't put "\\2" inside expand-file-name, since it will be
;; transformed to "/2" on DOS/Windows.
,(concat temporary-file-directory "\\2") t))
(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))
(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."
+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')."
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.
\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)))
rawfile truename number))))))
(defun find-file-noselect-1 (buf filename nowarn rawfile truename number)
- (let ((inhibit-read-only t)
- error)
+ (let (error)
(with-current-buffer buf
(kill-local-variable 'find-file-literally)
;; Needed in case we are re-visiting the file with a different
;; text representation.
(kill-local-variable 'buffer-file-coding-system)
(kill-local-variable 'cursor-type)
- (erase-buffer)
+ (let ((inhibit-read-only t))
+ (erase-buffer))
(and (default-value 'enable-multibyte-characters)
(not rawfile)
(set-buffer-multibyte t))
(if rawfile
(condition-case ()
- (insert-file-contents-literally filename t)
+ (let ((inhibit-read-only t))
+ (insert-file-contents-literally filename t))
(file-error
(when (and (file-exists-p filename)
(not (file-readable-p filename)))
;; Unconditionally set error
(setq error t)))
(condition-case ()
- (insert-file-contents filename t)
+ (let ((inhibit-read-only t))
+ (insert-file-contents filename t))
(file-error
(when (and (file-exists-p filename)
(not (file-readable-p filename)))
("\\.g\\'" . antlr-mode)
("\\.ses\\'" . ses-mode)
("\\.orig\\'" nil t) ; from patch
+ ("\\.\\(soa\\|zone\\)\\'" . dns-mode)
("\\.in\\'" nil t)))
"Alist of filename patterns vs corresponding major mode functions.
Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL).
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.
(when (looking-at "//SUBDIRED//")
(delete-region (point) (progn (forward-line 1) (point)))
(forward-line -1))
- (let ((end (line-end-position)))
- (forward-word 1)
- (forward-char 3)
- (while (< (point) end)
- (let ((start (+ beg (read (current-buffer))))
- (end (+ beg (read (current-buffer)))))
- (if (= (char-after end) ?\n)
- (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 2) (point)))))
+ (if (looking-at "//DIRED//")
+ (let ((end (line-end-position)))
+ (forward-word 1)
+ (forward-char 3)
+ (while (< (point) end)
+ (let ((start (+ beg (read (current-buffer))))
+ (end (+ beg (read (current-buffer)))))
+ (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.
+ (put-text-property beg (point) 'dired-filename nil)
+ (end-of-line))))
+ (goto-char end)
+ (beginning-of-line)
+ (delete-region (point) (progn (forward-line 2) (point))))
+ (forward-line 1)
+ (if (looking-at "//DIRED-OPTIONS//")
+ (delete-region (point) (progn (forward-line 1) (point)))
+ (forward-line 1))))
;; Now decode what read if necessary.
(let ((coding (or coding-system-for-read
;; Get a list of the indices of the args which are file names.
(file-arg-indices
(cdr (or (assq operation
- ;; The first five are special because they
+ ;; The first six are special because they
;; return a file name. We want to include the /:
;; in the return value.
;; So just avoid stripping it in the first place.
(file-name-as-directory . nil)
(directory-file-name . nil)
(file-name-sans-versions . nil)
+ (find-backup-file-name . nil)
;; `identity' means just return the first arg
- ;; as stripped of its quoting.
- (substitute-in-file-name . identity)
+ ;; not stripped of its quoting.
+ (substitute-in-file-name identity)
+ ;; `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.
(file-name-completion 1)
(file-name-all-completions 1)
+ (write-region 2 5)
(rename-file 0 1)
(copy-file 0 1)
(make-symbolic-link 0 1)
;; For all other operations, treat the first argument only
;; as the file name.
'(nil 0))))
+ method
;; Copy ARGUMENTS so we can replace elements in it.
(arguments (copy-sequence arguments)))
- ;; Strip off the /: from the file names that have this handler.
+ (if (symbolp (car file-arg-indices))
+ (setq method (pop file-arg-indices)))
+ ;; Strip off the /: from the file names that have it.
(save-match-data
(while (consp file-arg-indices)
(let ((pair (nthcdr (car file-arg-indices) arguments)))
"/"
(substring (car pair) 2)))))
(setq file-arg-indices (cdr file-arg-indices))))
- (if (eq file-arg-indices 'identity)
- (car arguments)
- (apply operation arguments))))
+ (cond ((eq method 'identity)
+ (car arguments))
+ ((eq method 'add)
+ (concat "/:" (apply operation arguments)))
+ ((eq method 'quote)
+ (prog1 (apply operation arguments)
+ (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))
+ (t
+ (apply operation arguments)))))
\f
(define-key ctl-x-map "\C-f" 'find-file)
(define-key ctl-x-map "\C-r" 'find-file-read-only)