From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tino Calancha Newsgroups: gmane.emacs.bugs Subject: bug#28834: 25.1; dired-do-copy: allow to copy into a nonexistent directory Date: Mon, 16 Oct 2017 12:47:06 +0900 Message-ID: <87mv4r3gat.fsf@gmail.com> References: <006201d344da$d9316a50$8b943ef0$@gmail.com> <87shel2f93.fsf@gmail.com> <329916c9-5a00-4460-83db-f16b98e79edb@default> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1508125707 21846 195.159.176.226 (16 Oct 2017 03:48:27 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 16 Oct 2017 03:48:27 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: 28834@debbugs.gnu.org To: Drew Adams Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Oct 16 05:48:21 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e3wNu-00032z-5y for geb-bug-gnu-emacs@m.gmane.org; Mon, 16 Oct 2017 05:48:10 +0200 Original-Received: from localhost ([::1]:59202 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e3wNy-0002mL-C7 for geb-bug-gnu-emacs@m.gmane.org; Sun, 15 Oct 2017 23:48:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55416) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e3wNr-0002lp-Op for bug-gnu-emacs@gnu.org; Sun, 15 Oct 2017 23:48:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e3wNm-0001YG-NO for bug-gnu-emacs@gnu.org; Sun, 15 Oct 2017 23:48:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:33578) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e3wNm-0001YA-JL for bug-gnu-emacs@gnu.org; Sun, 15 Oct 2017 23:48:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1e3wNm-000217-A0 for bug-gnu-emacs@gnu.org; Sun, 15 Oct 2017 23:48:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Tino Calancha Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 16 Oct 2017 03:48:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 28834 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 28834-submit@debbugs.gnu.org id=B28834.15081256457704 (code B ref 28834); Mon, 16 Oct 2017 03:48:02 +0000 Original-Received: (at 28834) by debbugs.gnu.org; 16 Oct 2017 03:47:25 +0000 Original-Received: from localhost ([127.0.0.1]:42259 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e3wNA-00020C-HA for submit@debbugs.gnu.org; Sun, 15 Oct 2017 23:47:25 -0400 Original-Received: from mail-pg0-f65.google.com ([74.125.83.65]:47828) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e3wN7-0001zu-Em for 28834@debbugs.gnu.org; Sun, 15 Oct 2017 23:47:23 -0400 Original-Received: by mail-pg0-f65.google.com with SMTP id r25so5755334pgn.4 for <28834@debbugs.gnu.org>; Sun, 15 Oct 2017 20:47:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=qTPLcSSjNcSsqs7jcH97aFKuP2jc4v/xZmfOTUaAAmE=; b=jUhdiZ2dS0TP9kYp7RiACVylmfiDwpxttK7eBSjU5P9m2NTlnqlhzGM4w1JywVz8ag vv9hf0bbFrmaBYJz1s6XHuIMGETmpUEiL41mJgRem2UYP92bPBwldMhaB43YK+R05ZDi Nr3Bmjik5s3dv5B/FQIvF6Pmpkf5NYBNcIlr3ZgeV4s9dQCEdlAuxvIRM5XXX9ymtAWd APnbT2KfogKbrdLbDoPj6IiBkuok34l8TK+jID0Yst5q1i7oaNcATF54wr+wksSj7HJq 1E2Xa4zdm3mvpB0xbi1B8mzEhmdtXNpGlJP34JJiwR9k3m/ayOqssI2NxCvoF6RicTKF i5dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=qTPLcSSjNcSsqs7jcH97aFKuP2jc4v/xZmfOTUaAAmE=; b=RAz7lV9A7LiKQ4mCkwIjOaft7sljk64oWhAbQsktMrwxFEd+kX/Lf3MoynB8SuKs1B Nq8jZFmvfqSY/kp0OTt2MxWlnLqWcdHGh8/xW14o2j2LZerMX8tIb0e0V1oslxjm+0q9 LWl529I5WYh9XCFrfpgOT6QFjnz4VCZF1OROToaKdaSUaGFD4ZYeG8+zwLIdtJSM9Cqw WuUIhcs20ESpdEGUuYdtLH7bQ/4d6TUWBOs9tGnmbcREiYAfWNAROpdJkzlB9isSgIAq j7Ozm34z5vZbyok97l7G2WstrVyoIm3ID28YWJMmrny8ruNME8L4Y+y0V9cBK33OE/LQ SWKQ== X-Gm-Message-State: AMCzsaUsCMgJQ6gk1Zin+bocPu8MJFK93LqwEFQbEtamXwvaOmZzv8HL 1P+g9UPZgjZ0SOiYK2BnyEk= X-Google-Smtp-Source: AOwi7QAIVbVHIRAjn29tTfEYc5TfU4XLTRwmLAXm8ZeUh9NEqxsG7aC+LsrJGnXXJBWhPutZXmBf8Q== X-Received: by 10.99.107.73 with SMTP id g70mr6955411pgc.279.1508125634782; Sun, 15 Oct 2017 20:47:14 -0700 (PDT) Original-Received: from calancha-pc (203.191.218.133.dy.bbexcite.jp. [133.218.191.203]) by smtp.gmail.com with ESMTPSA id k10sm9616669pgq.92.2017.10.15.20.47.12 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 15 Oct 2017 20:47:14 -0700 (PDT) In-Reply-To: <329916c9-5a00-4460-83db-f16b98e79edb@default> (Drew Adams's message of "Sun, 15 Oct 2017 08:43:32 -0700 (PDT)") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:138495 Archived-At: Drew Adams writes: > The enhancement request is "It would be good if Emacs CAN > autocreate not exist directory when copy/move files." > > The operative word here is "CAN". > This can be done in various ways: > > 1. Have a different command, which users can bind in > place of the existing command. > > 2. Have a user option that controls whether Dired creates > missing dirs by default, i.e., without confirmation. > > 3. Have Dired ask whether to create missing directories. > > I think probably 2+3 would be good: have Dired prompt > when dirs are missing, but have an option that lets > users who never want to be prompted bypass prompting. > The option could be 3-valued: `always-prompt', > `always-create', `never-create' (or other names). Thank you for the explanation. Let's discuss the updated patch: --8<-----------------------------cut here---------------start------------->8--- commit b656651e9268f5dd646933b992bd37771c3e99ca Author: Tino Calancha Date: Mon Oct 16 12:41:41 2017 +0900 Allow to copy/rename file into a non-existent dir * lisp/dired-aux.el (dired-create-destination-dirs): New option. (dired--create-nonexistent-dirs): New defun. (dired-copy-file-recursive, dired-rename-file): Use it (Bug#28834). * lisp/dired-aux-tests.el (dired-test-bug28834): Add test. * doc/emacs/dired.texi (Operating on Files): Update manual. * etc/NEWS (Changes in Specialized Modes and Packages in Emacs 27.1) Announce this change. diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index db5dea329b..0f37ac60ac 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -646,6 +646,16 @@ Operating on Files Copy the specified files (@code{dired-do-copy}). The argument @var{new} is the directory to copy into, or (if copying a single file) the new name. This is like the shell command @code{cp}. +The option @var{dired-create-destination-dirs} controls whether Dired +should create non-existent directories in @var{new}. + +@videnx dired-create-destination-dirs +The option @code{dired-create-destination-dirs} controls whether Dired +should create non-existent directories in the destination while +copying/renaming files. The default value @code{never} means Dired +never creates such missing directories; the value @code{always}, +means Dired automatically creates them; the value @code{prompt} +means Dired asks you for confirmation before creating them. @vindex dired-copy-preserve-time If @code{dired-copy-preserve-time} is non-@code{nil}, then copying @@ -678,6 +688,9 @@ Operating on Files you rename several files, the argument @var{new} is the directory into which to move the files (this is like the shell command @command{mv}). +The option @var{dired-create-destination-dirs} controls whether Dired +should create non-existent directories in @var{new}. + Dired automatically changes the visited file name of buffers associated with renamed files so that they refer to the new names. diff --git a/etc/NEWS b/etc/NEWS index 716b0309a5..e5cec45426 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -56,6 +56,13 @@ whether '"' is also replaced in 'electric-quote-mode'. If non-nil, * Changes in Specialized Modes and Packages in Emacs 27.1 +** Dired + +--- +*** The new user option 'dired-create-destination-dirs' controls whether +'dired-do-copy' and 'dired-rename-file' must create non-existent +directories in the destination. + ** Edebug +++ diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 7e2252fcf1..0e415b7738 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1548,6 +1548,26 @@ dired-copy-file (declare-function make-symbolic-link "fileio.c") +(defcustom dired-create-destination-dirs 'never + "Whether Dired should create destination dirs when copying/removing files. +If never, don't create them. +If always, create them without ask. +If prompt, ask for user confirmation." + :type '(choice (const :tag "Never create non-existent dirs" never) + (const :tag "Always create non-existent dirs" always) + (const :tag "Ask for user confirmation" prompt)) + :group 'dired + :version "27.1") + +(defun dired--create-dirs (dir) + (unless (file-exists-p dir) + (pcase dired-create-destination-dirs + ('never nil) + ('always (dired-create-directory dir)) + ('prompt + (when (yes-or-no-p (format "Create destination dir '%s'? " dir)) + (dired-create-directory dir)))))) + (defun dired-copy-file-recursive (from to ok-flag &optional preserve-time top recursive) (when (and (eq t (car (file-attributes from))) @@ -1564,6 +1584,7 @@ dired-copy-file-recursive (if (stringp (car attrs)) ;; It is a symlink (make-symbolic-link (car attrs) to ok-flag) + (dired--create-dirs (file-name-directory to)) (copy-file from to ok-flag preserve-time)) (file-date-error (push (dired-make-relative from) @@ -1573,6 +1594,7 @@ dired-copy-file-recursive ;;;###autoload (defun dired-rename-file (file newname ok-if-already-exists) (dired-handle-overwrite newname) + (dired--create-dirs (file-name-directory newname)) (rename-file file newname ok-if-already-exists) ; error is caught in -create-files ;; Silently rename the visited file of any buffer visiting this file. (and (get-file-buffer file) diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el index d41feb1592..7778db0ea4 100644 --- a/test/lisp/dired-aux-tests.el +++ b/test/lisp/dired-aux-tests.el @@ -40,5 +40,34 @@ (should-not (dired-do-shell-command "ls ? ./`?`" nil files))) (delete-file foo)))) +(ert-deftest dired-test-bug28834 () + "test for https://debbugs.gnu.org/28834 ." + (let* ((from (make-temp-file "from")) + (foo (make-temp-file "foo" 'dir)) + (bar (file-name-as-directory (expand-file-name "bar" foo))) + (qux (file-name-as-directory (expand-file-name "qux" foo))) + (tmpdir temporary-file-directory) + (to-cp (expand-file-name "foo-cp" bar)) + (to-mv (expand-file-name "foo-mv" qux)) + (dired-create-destination-dirs 'always)) + (unwind-protect + (progn + (dired-copy-file-recursive from to-cp nil) + (should (file-exists-p to-cp)) + (dired-rename-file from to-mv nil) + (should (file-exists-p to-mv)) + ;; Repeat the same with `dired-create-destination-dirs' set to 'never. + (dired-rename-file to-mv from nil) + (delete-file to-cp) + (delete-directory bar) + (delete-directory qux) + (let ((dired-create-destination-dirs 'never)) + (should-error (dired-copy-file-recursive from to-cp nil)) + (should-error (dired-rename-file from to-mv nil)))) + ;; clean up + (delete-directory foo 'recursive) + (delete-file from)))) + + (provide 'dired-aux-tests) ;; dired-aux-tests.el ends here --8<-----------------------------cut here---------------end--------------->8--- In GNU Emacs 27.0.50 (build 11, x86_64-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-10-16 Repository revision: eed3a3d9e95d2c5346a23c9d92ca4e5848330183