"Value of the CDPATH environment variable, as a list.
Not actually set up until the first time you use it.")
-(defun parse-colon-path (cd-path)
+(defun parse-colon-path (search-path)
"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
+ (and search-path
(let (cd-list (cd-start 0) cd-colon)
- (setq cd-path (concat cd-path path-separator))
- (while (setq cd-colon (string-match path-separator cd-path cd-start))
+ (setq search-path (concat search-path path-separator))
+ (while (setq cd-colon (string-match path-separator search-path cd-start))
(setq cd-list
(nconc cd-list
(list (if (= cd-start cd-colon)
nil
(substitute-in-file-name
(file-name-as-directory
- (substring cd-path cd-start cd-colon)))))))
+ (substring search-path cd-start cd-colon)))))))
(setq cd-start (+ cd-colon 1)))
cd-list)))
`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
- (and (member cd-path '(nil ("./")))
- (null (getenv "CDPATH"))))))
- (if (file-name-absolute-p dir)
- (cd-absolute (expand-file-name dir))
- (if (null cd-path)
- (let ((trypath (parse-colon-path (getenv "CDPATH"))))
- (setq cd-path (or trypath (list "./")))))
- (if (not (catch 'found
- (mapc
- (function (lambda (x)
- (let ((f (expand-file-name (concat x dir))))
- (if (file-directory-p f)
- (progn
- (cd-absolute f)
- (throw 'found t))))))
- cd-path)
- nil))
- (error "No such directory found via CDPATH environment variable"))))
+ (list
+ ;; FIXME: There's a subtle bug in the completion below. Seems linked
+ ;; to a fundamental difficulty of implementing `predicate' correctly.
+ ;; The manifestation is that TAB may list non-directories in the case where
+ ;; those files also correspond to valid directories (if your cd-path is (A/
+ ;; B/) and you have A/a a file and B/a a directory, then both `a' and `a/'
+ ;; will be listed as valid completions).
+ ;; This is because `a' (listed because of A/a) is indeed a valid choice
+ ;; (which will lead to the use of B/a).
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (setq minibuffer-completion-table
+ (apply-partially #'locate-file-completion-table
+ cd-path nil))
+ (setq minibuffer-completion-predicate
+ (lambda (dir)
+ (locate-file dir cd-path nil
+ (lambda (f) (and (file-directory-p f) 'dir-ok))))))
+ (unless cd-path
+ (setq cd-path (or (parse-colon-path (getenv "CDPATH"))
+ (list "./"))))
+ (read-directory-name "Change default directory: "
+ default-directory default-directory
+ t))))
+ (unless cd-path
+ (setq cd-path (or (parse-colon-path (getenv "CDPATH"))
+ (list "./"))))
+ (cd-absolute
+ (or (locate-file dir cd-path nil
+ (lambda (f) (and (file-directory-p f) 'dir-ok)))
+ (error "No such directory found via CDPATH environment variable"))))
(defun load-file (file)
"Load the Lisp file named FILE."
file name when searching. If SUFFIXES is nil, it is equivalent to '(\"\").
Use '(\"/\") to disable PATH search, but still try the suffixes in SUFFIXES.
If non-nil, PREDICATE is used instead of `file-readable-p'.
+
+This function will normally skip directories, so if you want it to find
+directories, make sure the PREDICATE function returns `dir-ok' for them.
+
PREDICATE can also be an integer to pass to the `access' system call,
in which case file-name handlers are ignored. This usage is deprecated.
-
For compatibility, PREDICATE can also be one of the symbols
`executable', `readable', `writable', or `exists', or a list of
one or more of those symbols."
;; `name' in /home or in /.
(setq file (abbreviate-file-name file))
(let ((root nil)
- (prev-file file)
;; `user' is not initialized outside the loop because
;; `file' may not exist, so we may have to walk up part of the
- ;; hierarchy before we find the "initial UID".
- (user nil)
+ ;; hierarchy before we find the "initial UID". Note: currently unused
+ ;; (user nil)
try)
(while (not (or root
(null file)
(string-match locate-dominating-stop-dir-regexp file)))
(setq try (file-exists-p (expand-file-name name file)))
(cond (try (setq root file))
- ((equal file (setq prev-file file
- file (file-name-directory
+ ((equal file (setq file (file-name-directory
(directory-file-name file))))
(setq file nil))))
root))
time period between two checks.
Example:
- \(defun display-time-file-nonempty-p \(file)
- \(let \(\(remote-file-name-inhibit-cache \(- display-time-interval 5)))
- \(and \(file-exists-p file)
- \(< 0 \(nth 7 \(file-attributes \(file-chase-links file)))))))"
+ (defun display-time-file-nonempty-p (file)
+ (let ((remote-file-name-inhibit-cache (- display-time-interval 5)))
+ (and (file-exists-p file)
+ (< 0 (nth 7 (file-attributes (file-chase-links file)))))))"
:group 'files
:version "24.1"
:type `(choice
nil)))
(defun file-truename (filename &optional counter prev-dirs)
- "Return the truename of FILENAME, which should be absolute.
+ "Return the truename of FILENAME.
+If FILENAME is not absolute, first expands it against `default-directory'.
The truename of a file name is found by chasing symbolic links
both at the level of the file and at the level of the directories
containing it, until no links are left at any level.
(setq count (1+ count))))
newname))
+;; A handy function to display file sizes in human-readable form.
+;; See http://en.wikipedia.org/wiki/Kibibyte for the reference.
+(defun file-size-human-readable (file-size &optional flavor)
+ "Produce a string showing FILE-SIZE in human-readable form.
+
+Optional second argument FLAVOR controls the units and the display format:
+
+ If FLAVOR is nil or omitted, each kilobyte is 1024 bytes and the produced
+ suffixes are \"k\", \"M\", \"G\", \"T\", etc.
+ If FLAVOR is `si', each kilobyte is 1000 bytes and the produced suffixes
+ are \"k\", \"M\", \"G\", \"T\", etc.
+ If FLAVOR is `iec', each kilobyte is 1024 bytes and the produced suffixes
+ are \"KiB\", \"MiB\", \"GiB\", \"TiB\", etc."
+ (let ((power (if (or (null flavor) (eq flavor 'iec))
+ 1024.0
+ 1000.0))
+ (post-fixes
+ ;; none, kilo, mega, giga, tera, peta, exa, zetta, yotta
+ (list "" "k" "M" "G" "T" "P" "E" "Z" "Y")))
+ (while (and (>= file-size power) (cdr post-fixes))
+ (setq file-size (/ file-size power)
+ post-fixes (cdr post-fixes)))
+ (format (if (> (mod file-size 1.0) 0.05)
+ "%.1f%s%s"
+ "%.0f%s%s")
+ file-size
+ (if (and (eq flavor 'iec) (string= (car post-fixes) "k"))
+ "K"
+ (car post-fixes))
+ (if (eq flavor 'iec) "iB" ""))))
+
(defun make-temp-file (prefix &optional dir-flag suffix)
"Create a temporary file.
The returned file name (created by appending some random characters at the end
(interactive "BDisplay buffer in other frame: ")
(let ((pop-up-frames t)
same-window-buffer-names same-window-regexps
- (old-window (selected-window))
+ ;;(old-window (selected-window))
new-window)
(setq new-window (display-buffer buffer t))
;; This may have been here in order to prevent the new frame from hiding
(other-window 1)
(find-alternate-file filename wildcards))))
+(defvar kill-buffer-hook) ; from buffer.c
+
(defun find-alternate-file (filename &optional wildcards)
"Find file FILENAME, select its buffer, kill previous buffer.
If the current buffer now contains an empty file that you just visited
(not nonexistent)
;; It is confusing to ask whether to visit
;; non-literally if they have the file in
- ;; hexl-mode.
- (not (eq major-mode 'hexl-mode)))
+ ;; hexl-mode or image-mode.
+ (not (memq major-mode '(hexl-mode image-mode))))
(if (buffer-modified-p)
(if (y-or-n-p
(format
(inhibit-file-name-operation 'insert-file-contents))
(unwind-protect
(progn
- (fset 'find-buffer-file-type (lambda (filename) t))
+ (fset 'find-buffer-file-type (lambda (_filename) t))
(insert-file-contents filename visit beg end replace))
(if find-buffer-file-type-function
(fset 'find-buffer-file-type find-buffer-file-type-function)
(defvar find-file-literally nil
"Non-nil if this buffer was made by `find-file-literally' or equivalent.
-This is a permanent local.")
+This has the `permanent-local' property, which takes effect if you
+make the variable buffer-local.")
(put 'find-file-literally 'permanent-local t)
(defun find-file-literally (filename)
(confirm-nonexistent-file-or-buffer))))
(switch-to-buffer (find-file-noselect filename nil t)))
\f
-(defvar after-find-file-from-revert-buffer nil)
-
(defun after-find-file (&optional error warn noauto
- after-find-file-from-revert-buffer
+ _after-find-file-from-revert-buffer
nomodes)
"Called after finding a file and by the default revert function.
Sets buffer mode, parses local variables.
error in reading the file. WARN non-nil means warn if there
exists an auto-save file more recent than the visited file.
NOAUTO means don't mess with auto-save mode.
-Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER non-nil
- means this call was from `revert-buffer'.
+Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER is ignored
+\(see `revert-buffer-in-progress-p' for similar functionality).
Fifth arg NOMODES non-nil means don't alter the file's modes.
Finishes by calling the functions in `find-file-hook'
unless NOMODES is non-nil."
(message "%s" msg)
(or not-serious (sit-for 1 t))))
(when (and auto-save-default (not noauto))
- (auto-save-mode t)))
+ (auto-save-mode 1)))
;; Make people do a little extra work (C-x C-q)
;; before altering a backup file.
(when (backup-file-name-p buffer-file-name)
;; directives in that file. That way is discouraged since it
;; spreads out the definition of the initial value.
(mapcar
- 'purecopy-car
+ (lambda (elt)
+ (cons (purecopy (car elt)) (cdr elt)))
`(;; do this first, so that .html.pl is Polish html, not Perl
("\\.[sx]?html?\\(\\.[a-zA-Z_]+\\)?\\'" . html-mode)
("\\.svgz?\\'" . image-mode)
;; file. That way is discouraged since it spreads out the
;; definition of the initial value.
(mapcar
- 'purecopy-car
+ (lambda (l)
+ (cons (purecopy (car l)) (cdr l)))
'(("perl" . perl-mode)
("perl5" . perl-mode)
("miniperl" . perl-mode)
(min (point-max)
(+ (point-min) magic-mode-regexp-match-limit)))
(assoc-default nil magic-mode-alist
- (lambda (re dummy)
+ (lambda (re _dummy)
(if (functionp re)
(funcall re)
(looking-at re)))))))
(min (point-max)
(+ (point-min) magic-mode-regexp-match-limit)))
(assoc-default nil magic-fallback-mode-alist
- (lambda (re dummy)
+ (lambda (re _dummy)
(if (functionp re)
(funcall re)
(looking-at re)))))))
:type 'alist)
(defcustom safe-local-eval-forms
- '((add-hook 'write-file-functions 'time-stamp)
+ ;; This should be here at least as long as Emacs supports write-file-hooks.
+ '((add-hook 'write-file-hooks 'time-stamp)
+ (add-hook 'write-file-functions 'time-stamp)
(add-hook 'before-save-hook '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
asking you for confirmation."
:risky t
:group 'find-file
- :version "22.2"
+ :version "24.1" ; added write-file-hooks
:type '(repeat sexp))
;; Risky local variables:
;;
;; For variables defined in the C source code the declaration should go here:
-(mapc (lambda (pair)
- (put (car pair) 'safe-local-variable (cdr pair)))
- '((buffer-read-only . booleanp) ;; C source code
- (default-directory . stringp) ;; C source code
- (fill-column . integerp) ;; C source code
- (indent-tabs-mode . booleanp) ;; C source code
- (left-margin . integerp) ;; C source code
- (no-update-autoloads . booleanp)
- (tab-width . integerp) ;; C source code
- (truncate-lines . booleanp) ;; C source code
- (word-wrap . booleanp) ;; C source code
- (bidi-display-reordering . booleanp))) ;; C source code
+(dolist (pair
+ '((buffer-read-only . booleanp) ;; C source code
+ (default-directory . stringp) ;; C source code
+ (fill-column . integerp) ;; C source code
+ (indent-tabs-mode . booleanp) ;; C source code
+ (left-margin . integerp) ;; C source code
+ (no-update-autoloads . booleanp)
+ (lexical-binding . booleanp) ;; C source code
+ (tab-width . integerp) ;; C source code
+ (truncate-lines . booleanp) ;; C source code
+ (word-wrap . booleanp) ;; C source code
+ (bidi-display-reordering . booleanp))) ;; C source code
+ (put (car pair) 'safe-local-variable (cdr pair)))
(put 'bidi-paragraph-direction 'safe-local-variable
(lambda (v) (memq v '(nil right-to-left left-to-right))))
ALL-VARS is the list of all variables to be set up.
UNSAFE-VARS is the list of those that aren't marked as safe or risky.
RISKY-VARS is the list of those that are marked as risky.
-DIR-NAME is a directory name if these settings come from
-directory-local variables, or nil otherwise."
+If these settings come from directory-local variables, then
+DIR-NAME is the name of the associated directory. Otherwise it is nil."
(if noninteractive
nil
(save-window-excursion
`enable-local-eval', `enable-local-variables', and (if necessary)
user interaction. The results are added to
`file-local-variables-alist', without applying them.
-DIR-NAME is a directory name if these settings come from
- directory-local variables, or nil otherwise."
+If these settings come from directory-local variables, then
+DIR-NAME is the name of the associated directory. Otherwise it is nil."
;; Find those variables that we may want to save to
;; `safe-local-variable-values'.
(let (all-vars risky-vars unsafe-vars)
;; can't assure us that the value is safe.
(with-demoted-errors (funcall safep val))))))
-(defun risky-local-variable-p (sym &optional ignored)
+(defun risky-local-variable-p (sym &optional _ignored)
"Non-nil if SYM could be dangerous as a file-local variable.
It is dangerous if either of these conditions are met:
DIR is the name of the directory.
CLASS is the name of a variable class (a symbol).
MTIME is the recorded modification time of the directory-local
- variables file associated with this entry. This time is a list
- of two integers (the same format as `file-attributes'), and is
- used to test whether the cache entry is still valid.
- Alternatively, MTIME can be nil, which means the entry is always
- considered valid.")
+variables file associated with this entry. This time is a list
+of two integers (the same format as `file-attributes'), and is
+used to test whether the cache entry is still valid.
+Alternatively, MTIME can be nil, which means the entry is always
+considered valid.")
(defsubst dir-locals-get-class-variables (class)
"Return the variable list for CLASS."
(cdr entry) root variables))))
((or (not key)
(derived-mode-p key))
- (setq variables (dir-locals-collect-mode-variables
- (cdr entry) variables))))))
+ (let* ((alist (cdr entry))
+ (subdirs (assq 'subdirs alist)))
+ (if (or (not subdirs)
+ (progn
+ (setq alist (delq subdirs alist))
+ (cdr-safe subdirs))
+ ;; TODO someone might want to extend this to allow
+ ;; integer values for subdir, where N means
+ ;; variables apply to this directory and N levels
+ ;; below it (0 == nil).
+ (equal root default-directory))
+ (setq variables (dir-locals-collect-mode-variables
+ alist variables))))))))
(error
;; The file's content might be invalid (e.g. have a merge conflict), but
;; that shouldn't prevent the user from opening the file.
(defun dir-locals-find-file (file)
"Find the directory-local variables for FILE.
This searches upward in the directory tree from FILE.
-If the directory root of FILE has been registered in
- `dir-locals-directory-cache' and the directory-local variables
- file has not been modified, return the matching entry in
- `dir-locals-directory-cache'.
-Otherwise, if a directory-local variables file is found, return
- the file name.
-Otherwise, return nil."
+It stops at the first directory that has been registered in
+`dir-locals-directory-cache' or contains a `dir-locals-file'.
+If it finds an entry in the cache, it checks that it is valid.
+A cache entry with no modification time element (normally, one that
+has been assigned directly using `dir-locals-set-directory-class', not
+set from a file) is always valid.
+A cache entry based on a `dir-locals-file' is valid if the modification
+time stored in the cache matches the current file modification time.
+If not, the cache entry is cleared so that the file will be re-read.
+
+This function returns either nil (no directory local variables found),
+or the matching entry from `dir-locals-directory-cache' (a list),
+or the full path to the `dir-locals-file' (a string) in the case
+of no valid cache entry."
(setq file (expand-file-name file))
(let* ((dir-locals-file-name
(if (eq system-type 'ms-dos)
(locals-file (locate-dominating-file file dir-locals-file-name))
(dir-elt nil))
;; `locate-dominating-file' may have abbreviated the name.
- (when locals-file
- (setq locals-file (expand-file-name dir-locals-file-name locals-file)))
+ (if locals-file
+ (setq locals-file (expand-file-name dir-locals-file-name locals-file)))
;; Find the best cached value in `dir-locals-directory-cache'.
(dolist (elt dir-locals-directory-cache)
(when (and (eq t (compare-strings file nil (length (car elt))
'(windows-nt cygwin ms-dos))))
(> (length (car elt)) (length (car dir-elt))))
(setq dir-elt elt)))
- (let ((use-cache (and dir-elt
- (or (null locals-file)
- (<= (length (file-name-directory locals-file))
- (length (car dir-elt)))))))
- (if use-cache
- ;; Check the validity of the cache.
- (if (and (file-readable-p (car dir-elt))
- (or (null (nth 2 dir-elt))
+ (if (and dir-elt
+ (or (null locals-file)
+ (<= (length (file-name-directory locals-file))
+ (length (car dir-elt)))))
+ ;; Found a potential cache entry. Check validity.
+ ;; A cache entry with no MTIME is assumed to always be valid
+ ;; (ie, set directly, not from a dir-locals file).
+ ;; Note, we don't bother to check that there is a matching class
+ ;; element in dir-locals-class-alist, since that's done by
+ ;; dir-locals-set-directory-class.
+ (if (or (null (nth 2 dir-elt))
+ (let ((cached-file (expand-file-name dir-locals-file-name
+ (car dir-elt))))
+ (and (file-readable-p cached-file)
(equal (nth 2 dir-elt)
- (nth 5 (file-attributes (car dir-elt))))))
- ;; This cache entry is OK.
- dir-elt
- ;; This cache entry is invalid; clear it.
- (setq dir-locals-directory-cache
- (delq dir-elt dir-locals-directory-cache))
- locals-file)
- locals-file))))
+ (nth 5 (file-attributes cached-file))))))
+ ;; This cache entry is OK.
+ dir-elt
+ ;; This cache entry is invalid; clear it.
+ (setq dir-locals-directory-cache
+ (delq dir-elt dir-locals-directory-cache))
+ ;; Return the first existing dir-locals file. Might be the same
+ ;; as dir-elt's, might not (eg latter might have been deleted).
+ locals-file)
+ ;; No cache entry.
+ locals-file)))
(defun dir-locals-read-from-file (file)
"Load a variables FILE and register a new class and instance.
(dir-name nil))
(cond
((stringp variables-file)
- (setq dir-name (if (buffer-file-name)
- (file-name-directory (buffer-file-name))
- default-directory))
- (setq class (dir-locals-read-from-file variables-file)))
+ (setq dir-name (file-name-directory variables-file)
+ class (dir-locals-read-from-file variables-file)))
((consp variables-file)
(setq dir-name (nth 0 variables-file))
(setq class (nth 1 variables-file))))
(set-file-selinux-context to-name context)))
(defvar file-name-version-regexp
- "\\(?:~\\|\\.~[-[:alnum:]:#@^._]+~\\)"
+ "\\(?:~\\|\\.~[-[:alnum:]:#@^._]+\\(?:~[[:digit:]]+\\)?~\\)"
+ ;; The last ~[[:digit]]+ matches relative versions in git,
+ ;; e.g. `foo.js.~HEAD~1~'.
"Regular expression matching the backup/version part of a file name.
Used by `file-name-sans-versions'.")
(let ((handler (find-file-name-handler file 'file-ownership-preserved-p)))
(if handler
(funcall handler 'file-ownership-preserved-p file)
- (let ((attributes (file-attributes file)))
+ (let ((attributes (file-attributes file 'integer)))
;; Return t if the file doesn't exist, since it's true that no
;; information would be lost by an (attempted) delete and create.
(or (null attributes)
- (= (nth 2 attributes) (user-uid)))))))
+ (= (nth 2 attributes) (user-uid))
+ ;; Files created on Windows by Administrator (RID=500)
+ ;; have the Administrators group (RID=544) recorded as
+ ;; their owner. Rewriting them will still preserve the
+ ;; owner.
+ (and (eq system-type 'windows-nt)
+ (= (user-uid) 500) (= (nth 2 attributes) 544)))))))
(defun file-name-sans-extension (filename)
"Return FILENAME sans final \"extension\".
;; In an indirect buffer, save its base buffer instead.
(if (buffer-base-buffer)
(set-buffer (buffer-base-buffer)))
- (if (buffer-modified-p)
+ (if (or (buffer-modified-p)
+ ;; handle the case when no modification has been made but
+ ;; the file disappeared since visited
+ (and buffer-file-name
+ (not (file-exists-p buffer-file-name))))
(let ((recent-save (recent-auto-save-p))
setmodes)
;; If buffer has no file name, ask user for one.
buffer in question with `view-buffer' before deciding or `d' to
view the differences using `diff-buffer-with-file'.
+This command first saves any buffers where `buffer-save-without-query' is
+non-nil, without asking.
+
Optional argument (the prefix) non-nil means save all with no questions.
Optional second argument PRED determines which buffers are considered:
If PRED is nil, all the file-visiting buffers are considered.
change the additional actions you can take on files."
(interactive "P")
(save-window-excursion
- (let* (queried some-automatic
+ (let* (queried autosaved-buffers
files-done abbrevs-done)
(dolist (buffer (buffer-list))
;; First save any buffers that we're supposed to save unconditionally.
;; That way the following code won't ask about them.
(with-current-buffer buffer
(when (and buffer-save-without-query (buffer-modified-p))
- (setq some-automatic t)
+ (push (buffer-name) autosaved-buffers)
(save-buffer))))
;; Ask about those buffers that merit it,
;; and record the number thus saved.
(setq abbrevs-changed nil)
(setq abbrevs-done t)))
(or queried (> files-done 0) abbrevs-done
- (message (if some-automatic
- "(Some special files were saved without asking)"
- "(No files need saving)"))))))
+ (cond
+ ((null autosaved-buffers)
+ (message "(No files need saving)"))
+ ((= (length autosaved-buffers) 1)
+ (message "(Saved %s)" (car autosaved-buffers)))
+ (t
+ (message "(Saved %d files: %s)"
+ (length autosaved-buffers)
+ (mapconcat 'identity autosaved-buffers ", "))))))))
\f
(defun not-modified (&optional arg)
"Mark current buffer as unmodified, not needing to be saved.
(let* ((trashing (and delete-by-moving-to-trash
(null current-prefix-arg)))
(dir (expand-file-name
- (read-file-name
+ (read-directory-name
(if trashing
"Move directory to trash: "
"Delete directory: ")
directory 'full directory-files-no-dot-files-regexp)))
(delete-directory-internal directory)))))
-(defun copy-directory (directory newname &optional keep-time parents)
+(defun copy-directory (directory newname &optional keep-time parents copy-contents)
"Copy DIRECTORY to NEWNAME. Both args must be strings.
-If NEWNAME names an existing directory, copy DIRECTORY as subdirectory there.
-
This function always sets the file modes of the output files to match
the corresponding input file.
Noninteractively, the last argument PARENTS says whether to
create parent directories if they don't exist. Interactively,
-this happens by default."
+this happens by default.
+
+If NEWNAME names an existing directory, copy DIRECTORY as a
+subdirectory there. However, if called from Lisp with a non-nil
+optional argument COPY-CONTENTS, copy the contents of DIRECTORY
+directly into NEWNAME instead."
(interactive
(let ((dir (read-directory-name
"Copy directory: " default-directory default-directory t nil)))
(list dir
- (read-file-name
+ (read-directory-name
(format "Copy directory %s to: " dir)
default-directory default-directory nil nil)
- current-prefix-arg t)))
+ current-prefix-arg t nil)))
;; If default-directory is a remote directory, make sure we find its
;; copy-directory handler.
(let ((handler (or (find-file-name-handler directory 'copy-directory)
(setq directory (directory-file-name (expand-file-name directory))
newname (directory-file-name (expand-file-name newname)))
- (if (not (file-directory-p newname))
- ;; If NEWNAME is not an existing directory, create it; that
- ;; is where we will copy the files of DIRECTORY.
- (make-directory newname parents)
- ;; If NEWNAME is an existing directory, we will copy into
- ;; NEWNAME/[DIRECTORY-BASENAME].
- (setq newname (expand-file-name
- (file-name-nondirectory
- (directory-file-name directory))
- newname))
- (and (file-exists-p newname)
- (not (file-directory-p newname))
- (error "Cannot overwrite non-directory %s with a directory"
- newname))
- (make-directory newname t))
+ (cond ((not (file-directory-p newname))
+ ;; If NEWNAME is not an existing directory, create it;
+ ;; that is where we will copy the files of DIRECTORY.
+ (make-directory newname parents))
+ ;; If NEWNAME is an existing directory and COPY-CONTENTS
+ ;; is nil, copy into NEWNAME/[DIRECTORY-BASENAME].
+ ((not copy-contents)
+ (setq newname (expand-file-name
+ (file-name-nondirectory
+ (directory-file-name directory))
+ newname))
+ (and (file-exists-p newname)
+ (not (file-directory-p newname))
+ (error "Cannot overwrite non-directory %s with a directory"
+ newname))
+ (make-directory newname t)))
;; Copy recursively.
(dolist (file
If `revert-buffer-function' is used to override the normal revert
mechanism, this hook is not used.")
+(defvar revert-buffer-in-progress-p nil
+ "Non-nil if a `revert-buffer' operation is in progress, nil otherwise.
+This is true even if a `revert-buffer-function' is being used.")
+
(defvar revert-buffer-internal-hook)
(defun revert-buffer (&optional ignore-auto noconfirm preserve-modes)
to nil.
Optional second argument NOCONFIRM means don't ask for confirmation
-at all. \(The variable `revert-without-query' offers another way to
+at all. (The variable `revert-without-query' offers another way to
revert buffers without querying for confirmation.)
Optional third argument PRESERVE-MODES non-nil means don't alter
;; interface, but leaving the programmatic interface the same.
(interactive (list (not current-prefix-arg)))
(if revert-buffer-function
- (funcall revert-buffer-function ignore-auto noconfirm)
+ (let ((revert-buffer-in-progress-p t))
+ (funcall revert-buffer-function ignore-auto noconfirm))
(with-current-buffer (or (buffer-base-buffer (current-buffer))
(current-buffer))
- (let* ((auto-save-p (and (not ignore-auto)
+ (let* ((revert-buffer-in-progress-p t)
+ (auto-save-p (and (not ignore-auto)
(recent-auto-save-p)
buffer-auto-save-file-name
(file-readable-p buffer-auto-save-file-name)
;; have changed the truename.
(setq buffer-file-truename
(abbreviate-file-name (file-truename buffer-file-name)))
- (after-find-file nil nil t t preserve-modes)
+ (after-find-file nil nil t nil preserve-modes)
;; Run after-revert-hook as it was before we reverted.
(setq-default revert-buffer-internal-hook global-hook)
(if local-hook
Actions controlled by variables `list-directory-brief-switches'
and `list-directory-verbose-switches'."
(interactive (let ((pfx current-prefix-arg))
- (list (read-file-name (if pfx "List directory (verbose): "
+ (list (read-directory-name (if pfx "List directory (verbose): "
"List directory (brief): ")
nil default-directory nil)
pfx)))
(file-name-directory file)
(file-name-directory (expand-file-name file))))
(pattern (file-name-nondirectory file)))
+ ;; NB since switches is passed to the shell, be
+ ;; careful of malicious values, eg "-l;reboot".
+ ;; See eg dired-safe-switches-p.
(call-process
shell-file-name nil t nil
"-c"
(setq active t))
(setq processes (cdr processes)))
(or (not active)
- (list-processes t)
- (yes-or-no-p "Active processes exist; kill them and exit anyway? "))))
+ (progn (list-processes t)
+ (yes-or-no-p "Active processes exist; kill them and exit anyway? ")))))
;; Query the user for other things, perhaps.
(run-hook-with-args-until-failure 'kill-emacs-query-functions)
(or (null confirm-kill-emacs)