:type 'hook
:group 'files)
+(defcustom copy-directory-create-symlink nil
+ "This option influences the handling of symbolic links in `copy-directory'.
+If non-nil, `copy-directory' will create a symbolic link if the
+source directory is a symbolic link. If nil, it'll follow the
+symbolic link and copy the contents instead."
+ :type 'boolean
+ :version "28.1"
+ :group 'files)
+
(defvar-local save-buffer-coding-system nil
"If non-nil, use this coding system for saving the buffer.
More precisely, use this coding system in place of the
parent directories if they don't exist. Interactively, this
happens by default.
+If DIRECTORY is a symlink and `copy-directory-create-symlink' is
+non-nil, create a symlink with the same target as DIRECTORY.
+
If NEWNAME is a directory name, 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
(setq directory (directory-file-name (expand-file-name directory))
newname (expand-file-name newname))
- (cond ((not (directory-name-p newname))
- ;; If NEWNAME is not a directory name, create it;
- ;; that is where we will copy the files of DIRECTORY.
- (make-directory newname parents))
- ;; NEWNAME is a directory name. If COPY-CONTENTS is non-nil,
- ;; create NEWNAME if it is not already a directory;
- ;; otherwise, create NEWNAME/[DIRECTORY-BASENAME].
- ((if copy-contents
- (or parents (not (file-directory-p newname)))
- (setq newname (concat newname
- (file-name-nondirectory directory))))
- (make-directory (directory-file-name newname) parents))
- (t (setq follow t)))
-
- ;; Copy recursively.
- (dolist (file
- ;; We do not want to copy "." and "..".
- (directory-files directory 'full
- directory-files-no-dot-files-regexp))
- (let ((target (concat (file-name-as-directory newname)
- (file-name-nondirectory file)))
- (filetype (car (file-attributes file))))
- (cond
- ((eq filetype t) ; Directory but not a symlink.
- (copy-directory file target keep-time parents t))
- ((stringp filetype) ; Symbolic link
- (make-symbolic-link filetype target t))
- ((copy-file file target t keep-time)))))
-
- ;; Set directory attributes.
- (let ((modes (file-modes directory))
- (times (and keep-time (file-attribute-modification-time
- (file-attributes directory))))
- (follow-flag (unless follow 'nofollow)))
- (if modes (set-file-modes newname modes follow-flag))
- (if times (set-file-times newname times follow-flag))))))
+ ;; If DIRECTORY is a symlink, create a symlink with the same target.
+ (if (and (file-symlink-p directory)
+ copy-directory-create-symlink)
+ (let ((target (car (file-attributes directory))))
+ (if (directory-name-p newname)
+ (make-symbolic-link target
+ (concat newname
+ (file-name-nondirectory directory))
+ t)
+ (make-symbolic-link target newname t)))
+ ;; Else proceed to copy as a regular directory
+ (cond ((not (directory-name-p newname))
+ ;; If NEWNAME is not a directory name, create it;
+ ;; that is where we will copy the files of DIRECTORY.
+ (make-directory newname parents))
+ ;; NEWNAME is a directory name. If COPY-CONTENTS is non-nil,
+ ;; create NEWNAME if it is not already a directory;
+ ;; otherwise, create NEWNAME/[DIRECTORY-BASENAME].
+ ((if copy-contents
+ (or parents (not (file-directory-p newname)))
+ (setq newname (concat newname
+ (file-name-nondirectory directory))))
+ (make-directory (directory-file-name newname) parents))
+ (t (setq follow t)))
+
+ ;; Copy recursively.
+ (dolist (file
+ ;; We do not want to copy "." and "..".
+ (directory-files directory 'full
+ directory-files-no-dot-files-regexp))
+ (let ((target (concat (file-name-as-directory newname)
+ (file-name-nondirectory file)))
+ (filetype (car (file-attributes file))))
+ (cond
+ ((eq filetype t) ; Directory but not a symlink.
+ (copy-directory file target keep-time parents t))
+ ((stringp filetype) ; Symbolic link
+ (make-symbolic-link filetype target t))
+ ((copy-file file target t keep-time)))))
+
+ ;; Set directory attributes.
+ (let ((modes (file-modes directory))
+ (times (and keep-time (file-attribute-modification-time
+ (file-attributes directory))))
+ (follow-flag (unless follow 'nofollow)))
+ (if modes (set-file-modes newname modes follow-flag))
+ (if times (set-file-times newname times follow-flag)))))))
\f
;; At time of writing, only info uses this.