all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#24150: 25.1.50; New command: dired-create-empty-file
@ 2016-08-04 13:25 Tino Calancha
  2016-08-04 13:54 ` Clément Pit--Claudel
                   ` (5 more replies)
  0 siblings, 6 replies; 38+ messages in thread
From: Tino Calancha @ 2016-08-04 13:25 UTC (permalink / raw)
  To: 24150


Hi all,

It might be useful having a Dired command creating
an empty file with a name provided by the user; something
like 'dired-create-directory' ('+') but for files.

Following patch propose a new command 'dired-create-empty-file'
bound to 'M-+'.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 96b5bfe9f33e7fea5296f83649dd4b6a48bafb06 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Thu, 4 Aug 2016 22:07:00 +0900
Subject: [PATCH] New command dired-create-empty-file

* lisp/dired-aux.el (dired--create-empty-file-or-directory):
New macro to create a new empty file or directory.
(dired-create-directory): Use it.
(dired-create-empty-file): New command; as 'dired-create-directory'
but it creates an empty file instead of a dir.
* lisp/dired.el (dired-mode-map): Bind 'dired-create-empty-file'
to 'M-+'.
* doc/emacs/dired.texi: Document the new command in the manual.
* etc/NEWS: Add entry for this new feature.
---
  doc/emacs/dired.texi |  6 ++++++
  etc/NEWS             |  5 +++++
  lisp/dired-aux.el    | 50 
++++++++++++++++++++++++++++++++++++--------------
  lisp/dired.el        |  1 +
  4 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 2cda51a..c2de114 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1410,6 +1410,12 @@ Misc Dired Features
  directory name, and creates that directory.  It signals an error if
  the directory already exists.

+@kindex M-+ @r{(Dired)}
+@findex dired-create-empty-file
+  The command @kbd{M-+} (@code{dired-create-empty-file}) reads a
+file name, and creates an empty file with that name.  It signals
+an error if the file already exists.
+
  @cindex searching multiple files via Dired
  @kindex M-s a C-s @r{(Dired)}
  @kindex M-s a M-C-s @r{(Dired)}
diff --git a/etc/NEWS b/etc/NEWS
index fadf4c2..394b9f8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -249,6 +249,11 @@ whose content matches a regexp; bound to '% g'.
  ** Dired

  +++
+*** A new command 'dired-create-empty-file' similar as
+'dired-create-directory' but it creates a new empty file;
+bound to 'M-+'.
+
++++
  *** A New option 'dired-always-read-filesystem' default to nil.
  If non-nil, buffers visiting files are reverted before search them;
  for instance, in 'dired-mark-files-containing-regexp' a non-nil value
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 4732d9c..84b0c35 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1888,24 +1888,46 @@ dired-dwim-target-defaults
        dired-dirs)))


+(defmacro dired--create-empty-file-or-directory (fname &optional 
create-file)
+  "Create an empty file or directory called FNAME.
+If FNAME already exists, signal an error.
+Optional arg CREATE-FILE if non-nil, then create a file.  Otherwise 
create
+a directory. "
+  `(let* ((expanded (directory-file-name (expand-file-name ,fname)))
+          (parent (directory-file-name (file-name-directory expanded)))
+          (try expanded) new)
+     (when ,create-file
+       (setq try parent
+             new expanded))
+     (when (file-exists-p expanded)
+       (error "Cannot create file %s: file exists" expanded))
+     ;; Find the topmost nonexistent parent dir (variable `new')
+     (while (and try (not (file-exists-p try)) (not (equal new try)))
+       (setq new try
+             try (directory-file-name (file-name-directory try))))
+     (cond (,create-file
+            (unless (file-exists-p parent)
+              (make-directory parent t))
+            (write-region "" nil expanded nil 0))
+           (t
+            (make-directory expanded t)))
+     (when new
+       (dired-add-file new)
+       (dired-move-to-filename))))
+
  ;;;###autoload
  (defun dired-create-directory (directory)
    "Create a directory called DIRECTORY.
  If DIRECTORY already exists, signal an error."
-  (interactive
-   (list (read-file-name "Create directory: " 
(dired-current-directory))))
-  (let* ((expanded (directory-file-name (expand-file-name directory)))
-	 (try expanded) new)
-    (if (file-exists-p expanded)
-	(error "Cannot create directory %s: file exists" expanded))
-    ;; Find the topmost nonexistent parent dir (variable `new')
-    (while (and try (not (file-exists-p try)) (not (equal new try)))
-      (setq new try
-	    try (directory-file-name (file-name-directory try))))
-    (make-directory expanded t)
-    (when new
-      (dired-add-file new)
-      (dired-move-to-filename))))
+  (interactive (list (read-file-name "Create directory: ")))
+  (dired--create-empty-file-or-directory directory))
+
+;;;###autoload
+(defun dired-create-empty-file (file)
+  "Create an empty file called FILE.
+If FILE already exists, signal an error."
+  (interactive (list (read-file-name "Create empty file: ")))
+  (dired--create-empty-file-or-directory file 'create-file))

  (defun dired-into-dir-with-symlinks (target)
    (and (file-directory-p target)
diff --git a/lisp/dired.el b/lisp/dired.el
index 7ead087..df5a61c 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1554,6 +1554,7 @@ dired-mode-map
      (define-key map "x" 'dired-do-flagged-delete)
      (define-key map "y" 'dired-show-file-type)
      (define-key map "+" 'dired-create-directory)
+    (define-key map "\M-+" 'dired-create-empty-file)
      ;; moving
      (define-key map "<" 'dired-prev-dirline)
      (define-key map ">" 'dired-next-dirline)
-- 
2.8.1


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

In GNU Emacs 25.1.50 (x86_64-pc-linux-gnu, GTK+ Version 3.20.6)
  of 2016-08-03 built
Repository revision: 7f9721d3990155bae83e4e4840f0ff4913868d50






^ permalink raw reply related	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-04 13:25 bug#24150: 25.1.50; New command: dired-create-empty-file Tino Calancha
@ 2016-08-04 13:54 ` Clément Pit--Claudel
  2016-08-04 16:29 ` Leo Liu
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 38+ messages in thread
From: Clément Pit--Claudel @ 2016-08-04 13:54 UTC (permalink / raw)
  To: 24150


[-- Attachment #1.1: Type: text/plain, Size: 1840 bytes --]

On 2016-08-04 09:25, Tino Calancha wrote:
> Hi all,

Hi Tino,

> It might be useful having a Dired command creating
> an empty file with a name provided by the user; something
> like 'dired-create-directory' ('+') but for files.

Neat idea; that's like `touch', right?

> Following patch propose a new command 'dired-create-empty-file'
> bound to 'M-+'.

I've added comments inline below.

> +@kindex M-+ @r{(Dired)}
> +@findex dired-create-empty-file
> +  The command @kbd{M-+} (@code{dired-create-empty-file}) reads a
> +file name, and creates an empty file with that name.  It signals
> +an error if the file already exists.

Ah, so it's different from touch. Is there already a command in dired that sets the access and modification time of a file? If not, maybe this command could do it? I'm not sure it's useful to have the command fail if the file exists. If you go that, maybe renaming the command to eg dired-touch would be useful? Although I see the parallel with dired-create-directory, so maybe it's fine.

>  +++
> +*** A new command 'dired-create-empty-file' similar as
> +'dired-create-directory' but it creates a new empty file;
> +bound to 'M-+'.

I think there's a slight problem with this sentence.  Maybe

*** New command 'dired-create-empty-file' (similar to
'dired-create-directory') creates a new empty file;
bound to 'M-+'.

> +(defmacro dired--create-empty-file-or-directory (fname &optional create-file)
> +  "Create an empty file or directory called FNAME.
> +If FNAME already exists, signal an error.
> +Optional arg CREATE-FILE if non-nil, then create a file.  Otherwise create
> +a directory. "

Do you think this could be a defun instead of a macro? 

> +    (define-key map "\M-+" 'dired-create-empty-file)
Is there a convention on using (kbd "M-+") vs "\M-+"?


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-04 13:25 bug#24150: 25.1.50; New command: dired-create-empty-file Tino Calancha
  2016-08-04 13:54 ` Clément Pit--Claudel
@ 2016-08-04 16:29 ` Leo Liu
  2016-08-04 17:13   ` Ted Zlatanov
  2016-08-05  6:03 ` Tino Calancha
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 38+ messages in thread
From: Leo Liu @ 2016-08-04 16:29 UTC (permalink / raw)
  To: 24150

> It might be useful having a Dired command creating an empty file with
> a name provided by the user; something like 'dired-create-directory'
> ('+') but for files.

My experience seems to suggest this is not a frequent command/feature.
In fact I can't remember ever wanting to create just an empty file in
past weeks. Historically people have been careful adding stuff to dired
unless they are generally useful.

Cheers,
Leo





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-04 16:29 ` Leo Liu
@ 2016-08-04 17:13   ` Ted Zlatanov
  2016-08-04 17:29     ` Drew Adams
  0 siblings, 1 reply; 38+ messages in thread
From: Ted Zlatanov @ 2016-08-04 17:13 UTC (permalink / raw)
  To: Leo Liu; +Cc: 24150

On Fri, 05 Aug 2016 00:29:59 +0800 Leo Liu <sdl.web@gmail.com> wrote: 

>> It might be useful having a Dired command creating an empty file with
>> a name provided by the user; something like 'dired-create-directory'
>> ('+') but for files.

LL> My experience seems to suggest this is not a frequent command/feature.
LL> In fact I can't remember ever wanting to create just an empty file in
LL> past weeks. Historically people have been careful adding stuff to dired
LL> unless they are generally useful.

I use dired+ and find `diredp-touch-this-file' useful sometimes. It
might be handy to have that available, with filename prompting, in the
core dired. But it's not a high-frequency command for me.

Ted





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-04 17:13   ` Ted Zlatanov
@ 2016-08-04 17:29     ` Drew Adams
  0 siblings, 0 replies; 38+ messages in thread
From: Drew Adams @ 2016-08-04 17:29 UTC (permalink / raw)
  To: Ted Zlatanov, Leo Liu; +Cc: 24150

> I use dired+ and find `diredp-touch-this-file' useful sometimes. It
> might be handy to have that available, with filename prompting, in the
> core dired. But it's not a high-frequency command for me.

Vanilla Emacs has `dired-do-touch', which is bound to `T'
by default.

Dired+ defines `diredp-touch-this-file', which just does
`dired-do-touch' on the file of the current line:
(dired-do-touch 1).

Just `T', with no files marked, gives you the same behavior
as `diredp-touch-this-file'.  The latter is a separate command
because it lets you touch (just) the current file regardless of
whether some files are marked.

Wrt this thread: The Dired touch commands are useful mainly for
updating the file-modified date.  But they do not read a file
name, so they cannot be used to create a new, empty file.

I'm not sure what the use cases are for creating a new, empty file,
but I don't think that using a touch command on any file listed in
Dired has the effect of creating another, new file.  You can use
`M-!' to run a `touch' operating-system command, of course, but
Dired does not currently offer anything for this, AFAIK.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-04 13:25 bug#24150: 25.1.50; New command: dired-create-empty-file Tino Calancha
  2016-08-04 13:54 ` Clément Pit--Claudel
  2016-08-04 16:29 ` Leo Liu
@ 2016-08-05  6:03 ` Tino Calancha
  2016-08-05 14:48   ` Drew Adams
  2016-08-05  6:07 ` Tino Calancha
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2016-08-05  6:03 UTC (permalink / raw)
  To: clement.pit; +Cc: 24150, tino.calancha

[-- Attachment #1: Type: text/plain, Size: 3875 bytes --]


On Thu, 4 Aug 2016, Clément Pit--Claudel wrote:

>Ah, so it's different from touch. Is there already a command in dired
>that sets the access and modification time of a file? If not, maybe
>this command could do it? I'm not sure it's useful to have the command
>fail if the file exists. If you go that, maybe renaming the command to
>eg dired-touch would be useful? Although I see the parallel with
>dired-create-directory, so maybe it's fine.

'dired-do-touch' doesn't create a new file.
I use to create an empty file with
M-! touch new-file RET
Note this creates a new file in the current directory; it
desn't create non existing parens, for instance:
M-! touch new-paren/new-file RET
;; touch: cannot touch 'new-paren/new-file': No such file or directory

The command i am suggesting is a partner of 'dired-create-directory':
it also creates the paren dirs.

>I think there's a slight problem with this sentence.  Maybe
>*** New command 'dired-create-empty-file' (similar to
>'dired-create-directory') creates a new empty file;
>bound to 'M-+'.
Thanks a lot!

> Do you think this could be a defun instead of a macro?
Of course, it should be a defun!
Following is the corrected patch to dired-aux.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 4732d9c..f95e74e 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1888,25 +1888,47 @@ dired-dwim-target-defaults
        dired-dirs)))


-;;;###autoload
-(defun dired-create-directory (directory)
-  "Create a directory called DIRECTORY.
-If DIRECTORY already exists, signal an error."
-  (interactive
-   (list (read-file-name "Create directory: " 
(dired-current-directory))))
-  (let* ((expanded (directory-file-name (expand-file-name directory)))
-	 (try expanded) new)
-    (if (file-exists-p expanded)
-	(error "Cannot create directory %s: file exists" expanded))
+(defun dired--create-empty-file-or-directory (fname &optional 
create-file)
+  "Create an empty file or directory called FNAME.
+If FNAME already exists, signal an error.
+Optional arg CREATE-FILE if non-nil, then create a file.  Otherwise 
create
+a directory. "
+  (let* ((expanded (directory-file-name (expand-file-name fname)))
+         (parent (directory-file-name (file-name-directory expanded)))
+         (try expanded) new)
+    (when create-file
+      (setq try parent
+            new expanded))
+    (when (file-exists-p expanded)
+      (error "Cannot create file %s: file exists" expanded))
      ;; Find the topmost nonexistent parent dir (variable `new')
      (while (and try (not (file-exists-p try)) (not (equal new try)))
        (setq new try
-	    try (directory-file-name (file-name-directory try))))
-    (make-directory expanded t)
+            try (directory-file-name (file-name-directory try))))
+    (cond (create-file
+           (unless (file-exists-p parent)
+             (make-directory parent t))
+           (write-region "" nil expanded nil 0))
+          (t
+           (make-directory expanded t)))
      (when new
        (dired-add-file new)
        (dired-move-to-filename))))

+;;;###autoload
+(defun dired-create-directory (directory)
+  "Create a directory called DIRECTORY.
+If DIRECTORY already exists, signal an error."
+  (interactive (list (read-file-name "Create directory: ")))
+  (dired--create-empty-file-or-directory directory))
+
+;;;###autoload
+(defun dired-create-empty-file (file)
+  "Create an empty file called FILE.
+If FILE already exists, signal an error."
+  (interactive (list (read-file-name "Create empty file: ")))
+  (dired--create-empty-file-or-directory file 'create-file))
+
  (defun dired-into-dir-with-symlinks (target)
    (and (file-directory-p target)
         (not (file-symlink-p target))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-04 13:25 bug#24150: 25.1.50; New command: dired-create-empty-file Tino Calancha
                   ` (2 preceding siblings ...)
  2016-08-05  6:03 ` Tino Calancha
@ 2016-08-05  6:07 ` Tino Calancha
  2017-05-03  8:23 ` Tino Calancha
  2017-07-03  4:51 ` bug#24150: 26.0.50; " Tino Calancha
  5 siblings, 0 replies; 38+ messages in thread
From: Tino Calancha @ 2016-08-05  6:07 UTC (permalink / raw)
  To: sdl.web; +Cc: 24150, tino.calancha


On Thu, 4 Aug 2016, Leo Liu wrote:
>My experience seems to suggest this is not a frequent command/feature.
>In fact I can't remember ever wanting to create just an empty file in
>past weeks.
My experience is the opposite: i need to create empty files from
Dired quite often.  This reflects the fact that Emacs is a piece of 
software
with a wide range of different users with different needs.

>Historically people have been careful adding stuff to dired
>unless they are generally useful.
That's why the suggested command is added on dired-aux.el not in dired.el
;;; dired-aux.el --- less commonly used parts of dired

;; Copyright (C) 1985-1986, 1992, 1994, 1998, 2000-2016 Free Software
;; Foundation, Inc.






^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-05  6:03 ` Tino Calancha
@ 2016-08-05 14:48   ` Drew Adams
  2016-08-06 12:38     ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Drew Adams @ 2016-08-05 14:48 UTC (permalink / raw)
  To: Tino Calancha, clement.pit; +Cc: 24150

> Note this creates a new file in the current directory; it
> desn't create non existing parens, for instance:
> M-! touch new-paren/new-file RET
> ;; touch: cannot touch 'new-paren/new-file': No such file or directory

I think you meant "parent", not "paren" (which is short for parenthesis).





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-05 14:48   ` Drew Adams
@ 2016-08-06 12:38     ` Tino Calancha
  0 siblings, 0 replies; 38+ messages in thread
From: Tino Calancha @ 2016-08-06 12:38 UTC (permalink / raw)
  To: Drew Adams; +Cc: Tino Calancha, clement.pit, 24150



On Fri, 5 Aug 2016, Drew Adams wrote:

>> Note this creates a new file in the current directory; it
>> desn't create non existing parens, for instance:
>> M-! touch new-paren/new-file RET
>> ;; touch: cannot touch 'new-paren/new-file': No such file or directory
>
> I think you meant "parent", not "paren" (which is short for parenthesis).
Sure, you are right.
Thanks for clarifying this Drew.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 25.1.50; New command: dired-create-empty-file
  2016-08-04 13:25 bug#24150: 25.1.50; New command: dired-create-empty-file Tino Calancha
                   ` (3 preceding siblings ...)
  2016-08-05  6:07 ` Tino Calancha
@ 2017-05-03  8:23 ` Tino Calancha
  2017-07-03  4:51 ` bug#24150: 26.0.50; " Tino Calancha
  5 siblings, 0 replies; 38+ messages in thread
From: Tino Calancha @ 2017-05-03  8:23 UTC (permalink / raw)
  To: 24150-done

Tino Calancha <tino.calancha@gmail.com> writes:

> Hi all,
>
> It might be useful having a Dired command creating
> an empty file with a name provided by the user; something
> like 'dired-create-directory' ('+') but for files.
It seems people is not interested on this feature, so i am closing the report.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2016-08-04 13:25 bug#24150: 25.1.50; New command: dired-create-empty-file Tino Calancha
                   ` (4 preceding siblings ...)
  2017-05-03  8:23 ` Tino Calancha
@ 2017-07-03  4:51 ` Tino Calancha
  2017-07-03 14:24   ` Eli Zaretskii
  2017-07-05 18:28   ` Eli Zaretskii
  5 siblings, 2 replies; 38+ messages in thread
From: Tino Calancha @ 2017-07-03  4:51 UTC (permalink / raw)
  To: 24150; +Cc: Ted Zlatanov, tino.calancha, Clément Pit--Claudel, Leo Liu


>> Hi all,
>>
>> It might be useful having a Dired command creating
>> an empty file with a name provided by the user; something
>> like 'dired-create-directory' ('+') but for files.
>It seems people is not interested on this feature, so i am closing the report.

After i found the following threads:

https://stackoverflow.com/questions/20300137/how-to-create-new-file-from-dired-mode
https://stackoverflow.com/questions/2592095/how-do-i-create-an-empty-file-in-emacs

and considering the significant number of views they have, i'd like to
reopen this issue.

1. In my config i've bound the new command to 'M-+'.

2. In the threads above they suggest the keybindings 'c' and '_'.

'c' is already bound to `dired-do-compress-to', so i propose to bind
the new command to '_' (unless you have a better proposal).

If there are no objections, i would like to apply the following patch
in a few days:

--8<-----------------------------cut here---------------start------------->8---
commit 2661c4957b9ef90a2282a697dc5db3fab7e252b8
Author: Tino Calancha <tino.calancha@gmail.com>
Date:   Mon Jul 3 13:36:09 2017 +0900

    New command dired-create-empty-file
    
    Add a dired command, similar to 'dired-create-directory', to create
    an empty file (Bug#24150).
    * lisp/dired-aux.el (dired--create-empty-file-or-directory): New defun.
    (dired-create-directory): Use it.
    (dired-create-empty-file): New command.
    * lisp/dired.el (dired-mode-map): Bind 'dired-create-empty-file' to '_'.
    * doc/emacs/dired.texi: Document the new command in the manual.
    ; * etc/NEWS: Announce it.  Fix a previous Dired entry.

diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 28cb51d88b..94a122e7eb 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1416,6 +1416,12 @@ Misc Dired Features
 directory name, and creates that directory.  It signals an error if
 the directory already exists.
 
+@kindex _ @r{(Dired)}
+@findex dired-create-empty-file
+  Likewise, @kbd{_} (@code{dired-create-empty-file}) reads a
+file name, and creates an empty file with that name.  It signals
+an error if the file already exists.
+
 @cindex searching multiple files via Dired
 @kindex M-s a C-s @r{(Dired)}
 @kindex M-s a M-C-s @r{(Dired)}
diff --git a/etc/NEWS b/etc/NEWS
index 39c88c60e7..69e8733d73 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -500,8 +500,12 @@ properties as intact as possible.
 * Changes in Specialized Modes and Packages in Emacs 26.1
 
 ** Dired
-You can now use '`?`' in 'dired-do-shell-command'; as ' ? ', it gets replaced
-by the current file name.
+
+*** New command 'dired-create-empty-file' (similar to
+'dired-create-directory') creates a new empty file; bound to '_'.
+
+*** You can now use '`?`' in 'dired-do-shell-command'; as ' ? ',
+it gets replaced by the current file name.
 
 *** html2text is now marked obsolete.
 
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index e454775858..9c3585d669 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1958,25 +1958,47 @@ dired-dwim-target-defaults
       dired-dirs)))
 
 \f
-;;;###autoload
-(defun dired-create-directory (directory)
-  "Create a directory called DIRECTORY.
-If DIRECTORY already exists, signal an error."
-  (interactive
-   (list (read-file-name "Create directory: " (dired-current-directory))))
-  (let* ((expanded (directory-file-name (expand-file-name directory)))
-	 (try expanded) new)
-    (if (file-exists-p expanded)
-	(error "Cannot create directory %s: file exists" expanded))
+(defun dired--create-empty-file-or-directory (fname &optional create-file)
+  "Create an empty file or directory called FNAME.
+If FNAME already exists, signal an error.
+Optional arg CREATE-FILE if non-nil, then create a file.  Otherwise create
+a directory. "
+  (let* ((expanded (directory-file-name (expand-file-name fname)))
+         (parent (directory-file-name (file-name-directory expanded)))
+         (try expanded) new)
+    (when create-file
+      (setq try parent
+            new expanded))
+    (when (file-exists-p expanded)
+      (error "Cannot create file %s: file exists" expanded))
     ;; Find the topmost nonexistent parent dir (variable `new')
     (while (and try (not (file-exists-p try)) (not (equal new try)))
       (setq new try
-	    try (directory-file-name (file-name-directory try))))
-    (make-directory expanded t)
+            try (directory-file-name (file-name-directory try))))
+    (cond (create-file
+           (unless (file-exists-p parent)
+             (make-directory parent t))
+           (write-region "" nil expanded nil 0))
+          (t
+           (make-directory expanded t)))
     (when new
       (dired-add-file new)
       (dired-move-to-filename))))
 
+;;;###autoload
+(defun dired-create-directory (directory)
+  "Create a directory called DIRECTORY.
+If DIRECTORY already exists, signal an error."
+  (interactive (list (read-file-name "Create directory: ")))
+  (dired--create-empty-file-or-directory directory))
+
+;;;###autoload
+(defun dired-create-empty-file (file)
+  "Create an empty file called FILE.
+If FILE already exists, signal an error."
+  (interactive (list (read-file-name "Create empty file: ")))
+  (dired--create-empty-file-or-directory file 'create-file))
+
 (defun dired-into-dir-with-symlinks (target)
   (and (file-directory-p target)
        (not (file-symlink-p target))))
diff --git a/lisp/dired.el b/lisp/dired.el
index 0c1f3e4af6..291c545e87 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1557,6 +1557,7 @@ dired-mode-map
     (define-key map "x" 'dired-do-flagged-delete)
     (define-key map "y" 'dired-show-file-type)
     (define-key map "+" 'dired-create-directory)
+    (define-key map "_" 'dired-create-empty-file)
     ;; moving
     (define-key map "<" 'dired-prev-dirline)
     (define-key map ">" 'dired-next-dirline)
--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 26.0.50 (build 7, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2017-07-03
Repository revision: bc3dcd524dfb5c889ed017c093eaf028596fc35c







^ permalink raw reply related	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-03  4:51 ` bug#24150: 26.0.50; " Tino Calancha
@ 2017-07-03 14:24   ` Eli Zaretskii
  2017-07-03 15:04     ` Tino Calancha
  2017-07-03 15:12     ` Drew Adams
  2017-07-05 18:28   ` Eli Zaretskii
  1 sibling, 2 replies; 38+ messages in thread
From: Eli Zaretskii @ 2017-07-03 14:24 UTC (permalink / raw)
  To: Tino Calancha; +Cc: tzz, 24150, sdl.web, clement.pit

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Mon, 03 Jul 2017 13:51:25 +0900
> Cc: Ted Zlatanov <tzz@lifelogs.com>, tino.calancha@gmail.com,
> 	Clément Pit--Claudel <clement.pit@gmail.com>,
> 	Leo Liu <sdl.web@gmail.com>
> 
> After i found the following threads:
> 
> https://stackoverflow.com/questions/20300137/how-to-create-new-file-from-dired-mode
> https://stackoverflow.com/questions/2592095/how-do-i-create-an-empty-file-in-emacs
> 
> and considering the significant number of views they have, i'd like to
> reopen this issue.
> 
> 1. In my config i've bound the new command to 'M-+'.
> 
> 2. In the threads above they suggest the keybindings 'c' and '_'.
> 
> 'c' is already bound to `dired-do-compress-to', so i propose to bind
> the new command to '_' (unless you have a better proposal).
> 
> If there are no objections, i would like to apply the following patch
> in a few days:

Thanks for working on this, Tino.

I have a few concerns that I'd like to raise before we agree on adding
this.

First, I think this might be mixing two separate requests: one is the
desire to start a new file from Dired, the other is to create an empty
file on disk.  I think these should be kept separate because they
serve 2 different needs; in particular, the latter is not related to
Dired in any way.

I have no issues with adding a Dired keybinding that would call
find-file without much ado.  I'm not sure whether it should be bound
to M-+ or to "C-u +", but I will defer to opinions of others on that.

But I don't think M-+ or whatever we bind that command to should
actually _create_ an empty file on disk.  This is not how Emacs works
with files; "C-x C-f" will not create a file until you save the
buffer.  That "+" actually creates a directory is IMO an exception
rather than the rule: nothing else makes sense with directories, since
users cannot type directory contents into a buffer and then save it,
at least not easily.

I do recognize a possible need for a function, or maybe even a
command, to create an empty disk file.  AFAIK, we don't have such a
function, although it's not hard to write.  But I think the use cases
for such a command are quite rare and niche cases, so I think we
shouldn't have a keybinding for it, not even in Dired.  Let users who
need this command frequently bind it to a key; with time, if it turns
out I'm wrong and these use cases are much more frequent, we can
decide on providing a binding by default.

So, to summarize my POV: (a) it's okay to add a Dired keybinding for
find-file; (b) let's add a command with no binding for creating an
empty file.

Thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-03 14:24   ` Eli Zaretskii
@ 2017-07-03 15:04     ` Tino Calancha
  2017-07-03 16:33       ` Eli Zaretskii
  2017-07-03 15:12     ` Drew Adams
  1 sibling, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2017-07-03 15:04 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tzz, clement.pit, Tino Calancha, sdl.web, 24150



On Mon, 3 Jul 2017, Eli Zaretskii wrote:

Thanks for your comprehensive replay.
You know, you are the boss, so i will do what you say i must do.  Anyway,
let me defend my point after your replay.
> First, I think this might be mixing two separate requests: one is the
> desire to start a new file from Dired, the other is to create an empty
> file on disk.  I think these should be kept separate because they
> serve 2 different needs; in particular, the latter is not related to
> Dired in any way.
Honestly, i don't see the point to add a new keybinding in Dired for 
`find-file' having already the global `C-x C-f'.  I think the 
people in the threads are all aware about `C-x C-f': they are not looking
for reduce `find-file' to just one key. 
To me, it seems that those people are demanding for fast 
creationg of an _empty_ new file in Dired.  At least is what i got after 
reading them.

> I have no issues with adding a Dired keybinding that would call
> find-file without much ado.  I'm not sure whether it should be bound
> to M-+ or to "C-u +", but I will defer to opinions of others on that.
>
> But I don't think M-+ or whatever we bind that command to should
> actually _create_ an empty file on disk.  This is not how Emacs works
> with files; "C-x C-f" will not create a file until you save the
> buffer.  That "+" actually creates a directory is IMO an exception
> rather than the rule: nothing else makes sense with directories, since
> users cannot type directory contents into a buffer and then save it,
> at least not easily.
Dired is a file/directory manager inside Emacs.  I could even imagine 
people whom uses Emacs just to use Dired, because I was one of those guys.
You are right, a command to create an empty file is not the usual way 
for Emacs, as an editor, but I consider perfectly reasonable/necessary to 
assign a keybinding in a file manager for such operation.  One person in 
the threads above mentioned he wished this feature when working in a 
python project.  I often felt the same when working in python projects.

> I do recognize a possible need for a function, or maybe even a
> command, to create an empty disk file.  AFAIK, we don't have such a
> function, although it's not hard to write.  But I think the use cases
> for such a command are quite rare and niche cases, so I think we
> shouldn't have a keybinding for it, not even in Dired.
Obviosly is disagree here.  I found it useful in my workflow, that's why i 
wrote the function and opened the issue.  Many people watched the threads,
that means is not such rare feature.
> Let users who
> need this command frequently bind it to a key; with time, if it turns
> out I'm wrong and these use cases are much more frequent, we can
> decide on providing a binding by default.
>
> So, to summarize my POV: (a) it's okay to add a Dired keybinding for
> find-file; (b) let's add a command with no binding for creating an
> empty file.
I don't find useful (a).
The (b), for the normal user not hacking the lisp sources, doesn't make
much difference:
M-! touch new-file RET
M-x my-create-empty-file RET
;; The only difference is that the second will create parents dirs as 
;; needed.

We shouldn't assume that most of Emacs users set up their own bindings.  I 
know many buddies loving Emacs, using it many hours per day for 
working, and they keep their defaults .emacs files.
They don't know elisp.  They just want everything comes built-in.
We must not defraud those people.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-03 14:24   ` Eli Zaretskii
  2017-07-03 15:04     ` Tino Calancha
@ 2017-07-03 15:12     ` Drew Adams
  1 sibling, 0 replies; 38+ messages in thread
From: Drew Adams @ 2017-07-03 15:12 UTC (permalink / raw)
  To: Eli Zaretskii, Tino Calancha; +Cc: tzz, 24150, clement.pit, sdl.web

> But I don't think M-+ or whatever we bind that command to...

If possible, please do not bind `M-+' to anything in Dired mode.

Dired+ binds `M-+' as a prefix key, for operations on marked
files and dirs gathered recursively from marked subdirs, across
all Dired buffers.

It has been in use for at least 5 years.  I think Tino is aware
of this, but I'm not sure.

Again, just a request.

FYI, these are the Dired-mode keys bound on prefix-key `M-+':

M-+ C-t         Prefix Command
M-+ C-t c       diredp-image-dired-comment-files-recursive
M-+ C-t d       diredp-image-dired-display-thumbs-recursive
M-+ C-t r       diredp-image-dired-delete-tag-recursive
M-+ C-t t       diredp-image-dired-tag-files-recursive

M-+ !           diredp-do-shell-command-recursive

M-+ %           Prefix Command
M-+ % c         diredp-capitalize-recursive
M-+ % l         diredp-downcase-recursive
M-+ % m         diredp-mark-files-regexp-recursive
M-+ % u         diredp-upcase-recursive

M-+ &           diredp-do-async-shell-command-recursive

M-+ *           Prefix Command
M-+ * %         diredp-mark-files-regexp-recursive
M-+ * *         diredp-mark-executables-recursive
M-+ * .         diredp-mark-extension-recursive
M-+ * /         diredp-mark-directories-recursive
M-+ * @         diredp-mark-symlinks-recursive
M-+ * B         diredp-mark-autofiles-recursive

M-+ :           Prefix Command
M-+ : d         diredp-do-decrypt-recursive
M-+ : e         diredp-do-encrypt-recursive
M-+ : s         diredp-do-sign-recursive
M-+ : v         diredp-do-verify-recursive

M-+ @           diredp-do-apply-function-recursive
M-+ A           diredp-do-search-recursive
M-+ C           diredp-do-copy-recursive
M-+ D           diredp-do-delete-recursive
M-+ F           diredp-do-find-marked-files-recursive
M-+ H           diredp-do-hardlink-recursive
M-+ M           diredp-do-chmod-recursive
M-+ P           diredp-do-print-recursive
M-+ Q           diredp-do-query-replace-regexp-recursive
M-+ R           diredp-do-move-recursive
M-+ S           diredp-do-symlink-recursive
M-+ Y           diredp-do-relsymlink-recursive





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-03 15:04     ` Tino Calancha
@ 2017-07-03 16:33       ` Eli Zaretskii
  2017-07-03 20:18         ` Thien-Thi Nguyen
  2017-07-07 13:13         ` Ted Zlatanov
  0 siblings, 2 replies; 38+ messages in thread
From: Eli Zaretskii @ 2017-07-03 16:33 UTC (permalink / raw)
  To: Tino Calancha; +Cc: tzz, 24150, sdl.web, clement.pit

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Tue, 4 Jul 2017 00:04:31 +0900 (JST)
> cc: Tino Calancha <tino.calancha@gmail.com>, 24150@debbugs.gnu.org, 
>     tzz@lifelogs.com, clement.pit@gmail.com, sdl.web@gmail.com
> 
> You know, you are the boss, so i will do what you say i must do.

I don't want to act "bossy" in this matter.  I just stated my opinion;
if I'm in the minority, so be it.

> Honestly, i don't see the point to add a new keybinding in Dired for 
> `find-file' having already the global `C-x C-f'.  I think the 
> people in the threads are all aware about `C-x C-f': they are not looking
> for reduce `find-file' to just one key. 

After reading those discussions, I thought people did want that, but
if I'm mistaken, I of course don't insist on such a binding in Dired.

> I don't find useful (a).

OK.

> The (b), for the normal user not hacking the lisp sources, doesn't make
> much difference:
> M-! touch new-file RET
> M-x my-create-empty-file RET
> ;; The only difference is that the second will create parents dirs as 
> ;; needed.

Like I said: I don't mind adding such a command.  It's only the need
for its keybinding in Dired that is IMO arguable.  What do others
think on this matter?

Thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-03 16:33       ` Eli Zaretskii
@ 2017-07-03 20:18         ` Thien-Thi Nguyen
  2017-07-07 13:13         ` Ted Zlatanov
  1 sibling, 0 replies; 38+ messages in thread
From: Thien-Thi Nguyen @ 2017-07-03 20:18 UTC (permalink / raw)
  To: 24150

[-- Attachment #1: Type: text/plain, Size: 716 bytes --]


() Eli Zaretskii <eliz@gnu.org>
() Mon, 03 Jul 2017 19:33:44 +0300

   Like I said: I don't mind adding such a command.  It's only
   the need for its keybinding in Dired that is IMO arguable.
   What do others think on this matter?

I think Dired offers good visual feedback on filesystem changes
and a Dired keybinding to this command would fit in just fine.
Out of the box keybindings make sharing keyboard macros easier.

-- 
Thien-Thi Nguyen -----------------------------------------------
 (defun responsep (query)
   (pcase (context query)
     (`(technical ,ml) (correctp ml))
     ...))                              748E A0E8 1CB8 A748 9BFA
--------------------------------------- 6CE4 6703 2224 4C80 7502

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-03  4:51 ` bug#24150: 26.0.50; " Tino Calancha
  2017-07-03 14:24   ` Eli Zaretskii
@ 2017-07-05 18:28   ` Eli Zaretskii
  2017-07-05 19:34     ` Drew Adams
  1 sibling, 1 reply; 38+ messages in thread
From: Eli Zaretskii @ 2017-07-05 18:28 UTC (permalink / raw)
  To: Tino Calancha; +Cc: tzz, 24150, sdl.web, clement.pit

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Mon, 03 Jul 2017 13:51:25 +0900
> Cc: Ted Zlatanov <tzz@lifelogs.com>, tino.calancha@gmail.com,
> 	Clément Pit--Claudel <clement.pit@gmail.com>,
> 	Leo Liu <sdl.web@gmail.com>
> 
> If there are no objections, i would like to apply the following patch
> in a few days:

If no one else chimes in until this weekend, please push, after taking
care of the few minor issues below:

>     (dired-create-empty-file): New command.

I'd prefer a non-Dired function, and I think files.el is a better
place for such a general function.

> +@kindex _ @r{(Dired)}
> +@findex dired-create-empty-file
> +  Likewise, @kbd{_} (@code{dired-create-empty-file}) reads a
> +file name, and creates an empty file with that name.  It signals
> +an error if the file already exists.

Please add here a @cindex entry about "create empty file".  Also, if
the command is going to be not Dired-specific, it should be described
in another section of the manual.

>  ** Dired
> -You can now use '`?`' in 'dired-do-shell-command'; as ' ? ', it gets replaced
> -by the current file name.
> +
> +*** New command 'dired-create-empty-file' (similar to
> +'dired-create-directory') creates a new empty file; bound to '_'.

Since this is documented in the manual, it should be marked with
"+++".  (Renaming the command affects this part as well.)

> +*** You can now use '`?`' in 'dired-do-shell-command'; as ' ? ',
> +it gets replaced by the current file name.

This looks unrelated.

> +    (when (file-exists-p expanded)
> +      (error "Cannot create file %s: file exists" expanded))

If the file is actually a directory, I think the error message should
say so.

Finally, how about some simple tests for this new command?

Thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-05 18:28   ` Eli Zaretskii
@ 2017-07-05 19:34     ` Drew Adams
  2017-07-07  5:36       ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Drew Adams @ 2017-07-05 19:34 UTC (permalink / raw)
  To: Eli Zaretskii, Tino Calancha; +Cc: tzz, 24150, clement.pit, sdl.web

> > +*** New command 'dired-create-empty-file' (similar to
> > +'dired-create-directory') creates a new empty file; bound to '_'.

FWIW:

I'd rather not see this command bound to a key.  How about just
putting it in a menu?

FWIW2:

I bind `_' to `dired-show-file-type' (dired-aux.el), which is bound
by default to `y'.  I bind `y' to a command that makes a relative
symbolic link to the file on the cursor line.  This is in keeping
with `Y' for `dired-do-relsymlink' and `%Y' for
`dired-do-relsymlink-regexp'.






^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-05 19:34     ` Drew Adams
@ 2017-07-07  5:36       ` Tino Calancha
  2017-07-07 11:11         ` Drew Adams
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2017-07-07  5:36 UTC (permalink / raw)
  To: Drew Adams; +Cc: Tino Calancha, tzz, clement.pit, 24150, sdl.web



On Wed, 5 Jul 2017, Drew Adams wrote:

>>> +*** New command 'dired-create-empty-file' (similar to
>>> +'dired-create-directory') creates a new empty file; bound to '_'.
>
> FWIW:
>
> I'd rather not see this command bound to a key.  How about just
> putting it in a menu?
That's a nice suggestion.  Thank you.
>
> FWIW2:
>
> I bind `_' to `dired-show-file-type' (dired-aux.el), which is bound
> by default to `y'.  I bind `y' to a command that makes a relative
> symbolic link to the file on the cursor line.  This is in keeping
> with `Y' for `dired-do-relsymlink' and `%Y' for
> `dired-do-relsymlink-regexp'.
After re-thinking the issue, i am reluctant to set a binding for
this: that could make clashes with Dired+, reducing discoverability
of useful features.

Having the command defined in Emacs means that users just need 1 line
in their config file to set their binding of choice.  That's cheap.

I will implement Eli's comments during this weekend and back here with
an updated patch.

Thank you





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-07  5:36       ` Tino Calancha
@ 2017-07-07 11:11         ` Drew Adams
  2018-07-10  7:01           ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Drew Adams @ 2017-07-07 11:11 UTC (permalink / raw)
  To: Tino Calancha; +Cc: tzz, 24150, sdl.web, clement.pit

> > FWIW:
> > I'd rather not see this command bound to a key.  How about just
> > putting it in a menu?
>
> That's a nice suggestion.  Thank you.
>
> > FWIW2:
> > I bind `_' to `dired-show-file-type' (dired-aux.el), which is bound
> > by default to `y'.  I bind `y' to a command that makes a relative
> > symbolic link to the file on the cursor line.  This is in keeping
> > with `Y' for `dired-do-relsymlink' and `%Y' for
> > `dired-do-relsymlink-regexp'.
>
> After re-thinking the issue, i am reluctant to set a binding for
> this: that could make clashes with Dired+, reducing discoverability
> of useful features.
> 
> Having the command defined in Emacs means that users just need 1 line
> in their config file to set their binding of choice.  That's cheap.

Thank you, Tino.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-03 16:33       ` Eli Zaretskii
  2017-07-03 20:18         ` Thien-Thi Nguyen
@ 2017-07-07 13:13         ` Ted Zlatanov
  2017-07-07 13:17           ` Drew Adams
  1 sibling, 1 reply; 38+ messages in thread
From: Ted Zlatanov @ 2017-07-07 13:13 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: sdl.web, Tino Calancha, clement.pit, 24150

On Mon, 03 Jul 2017 19:33:44 +0300 Eli Zaretskii <eliz@gnu.org> wrote: 

EZ> Like I said: I don't mind adding such a command.  It's only the need
EZ> for its keybinding in Dired that is IMO arguable.  What do others
EZ> think on this matter?

I'd find a Dired-local keybinding `+' to `find-file' useful.

I'd prefer to delay the disk activity to when I save the file. There's
very few cases where I want immediate disk activity, usually it's
undesirable. So the direct touch would not fit my workflow.

Ted





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-07 13:13         ` Ted Zlatanov
@ 2017-07-07 13:17           ` Drew Adams
  2017-07-07 13:31             ` Ted Zlatanov
  0 siblings, 1 reply; 38+ messages in thread
From: Drew Adams @ 2017-07-07 13:17 UTC (permalink / raw)
  To: Ted Zlatanov, Eli Zaretskii; +Cc: sdl.web, Tino Calancha, clement.pit, 24150

> I'd find a Dired-local keybinding `+' to `find-file' useful.

`+' is bound to `dired-create-directory' in `dired-aux.el'.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-07 13:17           ` Drew Adams
@ 2017-07-07 13:31             ` Ted Zlatanov
  0 siblings, 0 replies; 38+ messages in thread
From: Ted Zlatanov @ 2017-07-07 13:31 UTC (permalink / raw)
  To: Drew Adams; +Cc: 24150, Tino Calancha, clement.pit, sdl.web

On Fri, 7 Jul 2017 06:17:05 -0700 (PDT) Drew Adams <drew.adams@oracle.com> wrote: 

>> I'd find a Dired-local keybinding `+' to `find-file' useful.
DA> `+' is bound to `dired-create-directory' in `dired-aux.el'.

Thanks. Any short keystroke will do for me.

Ted





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2017-07-07 11:11         ` Drew Adams
@ 2018-07-10  7:01           ` Tino Calancha
  2018-07-10  7:42             ` Phil Sainty
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2018-07-10  7:01 UTC (permalink / raw)
  To: 24150; +Cc: tzz, clement.pit, Michael Albinus, sdl.web

Drew Adams <drew.adams@oracle.com> writes:

>> > FWIW:
>> > I'd rather not see this command bound to a key.  How about just
>> > putting it in a menu?
>>
>> That's a nice suggestion.  Thank you.

>> Having the command defined in Emacs means that users just need 1 line
>> in their config file to set their binding of choice.  That's cheap.
>
> Thank you, Tino.

I came to this issue again after a long time.
I redid my patch.
I have tested it in a remote machine.

IIRC, Eli wanted the command to be general, as `make-directory' its,
i.e., not been exclusive of dired, instead lying on files.el.

I did that.
In addition I also implemented one command in dired-aux.el.
It's worth to have it so that the dired buffer is updated, and you
see your new created file.

That is consistent with the current master branch:
* `make-directory' in files.el
* `dired-create-directory' in dired-aux.el

The patch adds the following:
* `make-empty-file' in files.el
* `dired-create-empty-file' in dired-aux.el

The patch adds an entry for the second command in the dired menu. No new keybinding.

I see many colleagues using similar command in other editors.  I would
like Emacs also have one.

Let's discuss this patch.

--8<-----------------------------cut here---------------start------------->8---
commit 099ac754a2222776c00a7bacab6dfda3a4fe9cb4
Author: Tino Calancha <tino.calancha@gmail.com>
Date:   Tue Jul 10 14:35:25 2018 +0900

    New commands to create an empty file
    
    Similarly as `create-directory', `dired-create-directory',
    the new commands create the parent dirs as needed.
    * lisp/dired-aux.el (dired-create-empty-file): New command.
    (dired--create-empty-file-or-directory):
    New defun extracted from `dired-create-directory'.
    (dired-create-directory, dired-create-empty-file): Use it.
    
    * lisp/files.el (make-empty-file): New command.
    (make--empty-file-or-directory):
    New function extracted from `make-directory'.
    
    (make-directory, make-empty-file): Use it.
    
    * lisp/dired.el (dired-mode-map): Add menu entry for `make-empty-file'.

diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 925a7d50d6..cd997ef17e 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1989,26 +1989,49 @@ dired-dwim-target-defaults
       dired-dirs)))
 
 \f
-;;;###autoload
-(defun dired-create-directory (directory)
-  "Create a directory called DIRECTORY.
-Parent directories of DIRECTORY are created as needed.
-If DIRECTORY already exists, signal an error."
-  (interactive
-   (list (read-file-name "Create directory: " (dired-current-directory))))
-  (let* ((expanded (directory-file-name (expand-file-name directory)))
-	 (try expanded) new)
-    (if (file-exists-p expanded)
-	(error "Cannot create directory %s: file exists" expanded))
+(defun dired--create-empty-file-or-directory (fname &optional create-file)
+  "Create an empty file or directory called FNAME.
+If FNAME already exists, signal an error.
+Optional arg CREATE-FILE if non-nil, then create a file.  Otherwise create
+a directory. "
+  (let* ((expanded (directory-file-name (expand-file-name fname)))
+         (parent (directory-file-name (file-name-directory expanded)))
+         (try expanded) new)
+    (when create-file
+      (setq try parent
+            new expanded))
+    (when (file-exists-p expanded)
+      (error "Cannot create file %s: file exists" expanded))
     ;; Find the topmost nonexistent parent dir (variable `new')
     (while (and try (not (file-exists-p try)) (not (equal new try)))
       (setq new try
-	    try (directory-file-name (file-name-directory try))))
-    (make-directory expanded t)
+            try (directory-file-name (file-name-directory try))))
+    (cond (create-file
+           (unless (file-exists-p parent)
+             (make-directory parent t))
+           (write-region "" nil expanded nil 0))
+          (t
+           (make-directory expanded t)))
     (when new
       (dired-add-file new)
       (dired-move-to-filename))))
 
+;;;###autoload
+(defun dired-create-directory (directory)
+  "Create a directory called DIRECTORY.
+Parent directories of DIRECTORY are created as needed.
+If DIRECTORY already exists, signal an error."
+  (interactive (list (read-file-name "Create directory: ")))
+  (dired--create-empty-file-or-directory directory))
+
+;;;###autoload
+(defun dired-create-empty-file (file)
+  "Create an empty file called FILE.
+Parent directories of DIRECTORY are created as needed.
+If FILE already exists, signal an error."
+  (interactive (list (read-file-name "Create empty file: ")))
+  (dired--create-empty-file-or-directory file 'create-file))
+
 (defun dired-into-dir-with-symlinks (target)
   (and (file-directory-p target)
        (not (file-symlink-p target))))
diff --git a/lisp/dired.el b/lisp/dired.el
index 1348df6934..090fa4ad1a 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1802,6 +1802,9 @@ dired-mode-map
     (define-key map [menu-bar immediate create-directory]
       '(menu-item "Create Directory..." dired-create-directory
 		  :help "Create a directory"))
+    (define-key map [menu-bar immediate make-empty-file]
+      '(menu-item "Create Empty file..." make-empty-file
+		  :help "Create an empty file"))
     (define-key map [menu-bar immediate wdired-mode]
       '(menu-item "Edit File Names" wdired-change-to-wdired-mode
 		  :help "Put a Dired buffer in a mode in which filenames are editable"
diff --git a/lisp/files.el b/lisp/files.el
index eabb3c0e06..31e67a2946 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5477,6 +5477,54 @@ files--ensure-directory
      (unless (file-directory-p dir)
        (signal (car err) (cdr err))))))
 
+(defun make--empty-file-or-directory (fname &optional parents empty-file)
+  ;; If default-directory is a remote directory,
+  ;; make sure we find its make-directory handler.
+  (setq fname (expand-file-name fname))
+  (let ((handler (find-file-name-handler fname 'make-directory)))
+    (cond (handler
+           (if (null empty-file)
+               (funcall handler 'make-directory fname parents)
+             ;; There is no tramp handler for `make-empty-file' yet.
+             ;; One work around is to create the file in 2 steps:
+             ;; first the parent dirs, second the file.
+             ;;
+             ;; If the new file is in the current directory we just
+             ;; need to call `write-region'.
+             (if (equal default-directory (file-name-directory fname))
+                 (write-region "" nil fname nil 0)
+               ;; We must create parents dirs first
+               (funcall handler 'make-directory (file-name-directory fname) parents)
+               (write-region "" nil fname nil 0))))
+          (t
+           (let ((create-fn (lambda (file)
+                              (write-region "" nil file nil 0))))
+             (if (not parents)
+                 (cond ((not empty-file) (make-directory-internal fname))
+                       (t (funcall create-fn fname)))
+               (let* ((expanded (directory-file-name (expand-file-name fname)))
+                      (try expanded)
+                      create-list new last)
+                 ;; new: topmost nonexistent parent dir.
+                 (while (and (not (file-exists-p try))
+                             ;; If directory is its own parent, then we can't
+                             ;; keep looping forever
+                             (not (equal new try)))
+                   (setq new try
+                         create-list (cons new create-list)
+                         try (directory-file-name (file-name-directory try))))
+                 (setq last (car (last create-list))
+                       create-list (nbutlast create-list))
+                 (while create-list
+                   (make-directory-internal (car create-list))
+                   (setq create-list (cdr create-list)))
+                 (when last
+                   (if (not empty-file) (make-directory-internal last)
+                     (funcall create-fn last)))
+                 (when (and new (derived-mode-p 'dired-mode) empty-file)
+                   (dired-add-file new)
+                   (dired-move-to-filename) nil))))))))
+
 (defun make-directory (dir &optional parents)
   "Create the directory DIR and optionally any nonexistent parent dirs.
 If DIR already exists as a directory, signal an error, unless
@@ -5496,28 +5544,17 @@ make-directory
    (list (read-file-name "Make directory: " default-directory default-directory
 			 nil nil)
 	 t))
-  ;; If default-directory is a remote directory,
-  ;; make sure we find its make-directory handler.
-  (setq dir (expand-file-name dir))
-  (let ((handler (find-file-name-handler dir 'make-directory)))
-    (if handler
-	(funcall handler 'make-directory dir parents)
-      (if (not parents)
-	  (make-directory-internal dir)
-	(let ((dir (directory-file-name (expand-file-name dir)))
-	      create-list parent)
-	  (while (progn
-		   (setq parent (directory-file-name
-				 (file-name-directory dir)))
-		   (condition-case ()
-		       (files--ensure-directory dir)
-		     (file-missing
-		      ;; Do not loop if root does not exist (Bug#2309).
-		      (not (string= dir parent)))))
-	    (setq create-list (cons dir create-list)
-		  dir parent))
-	  (dolist (dir create-list)
-            (files--ensure-directory dir)))))))
+  (make--empty-file-or-directory dir parents))
+
+(defun make-empty-file (fname &optional parents)
+  "Create an empty file FNAME.
+Optional arg PARENTS, if non-nil then creates parent dirs as needed.
+
+If called interactively, then PARENTS is non-nil."
+  (interactive
+   (let ((fname (read-file-name "Create empty file: ")))
+     (list fname t)))
+  (make--empty-file-or-directory fname parents 'empty-file))
 
 (defconst directory-files-no-dot-files-regexp
   "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"

--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 27.0.50 (build 5, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2018-07-10 built
Repository revision: cc74539a19229ee7e70055b00e8334bd6abc0841





^ permalink raw reply related	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-10  7:01           ` Tino Calancha
@ 2018-07-10  7:42             ` Phil Sainty
  2018-07-17  7:39               ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Phil Sainty @ 2018-07-10  7:42 UTC (permalink / raw)
  To: Tino Calancha
  Cc: bug-gnu-emacs, tzz, clement.pit, Michael Albinus, 24150, sdl.web

I've not followed this bug, but just wanted to comment that I've found
https://stackoverflow.com/a/18885461 (which I simply adapted from
`dired-create-directory') to be a remarkably convenient command over
the years.

I see that there are suggestions against binding it to a key, but I
would suggest using "_" as a binding in dired (which on a US keyboard
layout is directly beside "+" (with both being shift-modifier chords),
which is a binding that I immediately found easy to remember and use.


-Phil






^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-10  7:42             ` Phil Sainty
@ 2018-07-17  7:39               ` Tino Calancha
  2018-07-20  9:03                 ` Eli Zaretskii
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2018-07-17  7:39 UTC (permalink / raw)
  To: Phil Sainty
  Cc: bug-gnu-emacs, tino.calancha, tzz, clement.pit, Michael Albinus,
	24150, sdl.web

Phil Sainty <psainty@orcon.net.nz> writes:

> I've not followed this bug, but just wanted to comment that I've found
> https://stackoverflow.com/a/18885461 (which I simply adapted from
> `dired-create-directory') to be a remarkably convenient command over
> the years.
Thank you Phil!

your command does the thing well locally;  I've tested it in a
remote machine and it fails.
It is desirable that every Dired command work regardless of if the machine
is local or remote.
My patch handles the remote machine; not in the most efficient way but we
always could add a handler for the new command afterward.

> I see that there are suggestions against binding it to a key, but I
> would suggest using "_" as a binding in dired (which on a US keyboard
> layout is directly beside "+" (with both being shift-modifier chords),
> which is a binding that I immediately found easy to remember and use.
I use a Japanese keyboard but I sympathize with your suggestion,
after all, I have my own key binding for this feature.

My patch does not provide any binding after the discussion in this
thread.  It might be added later if needed.

At this stage, I am happy to focus the discussion on the acceptance
of the command itself.
I saw users of other editors very used to call a command to create
an empty file.  Sure, we write our own commands for such simple
things, but most of Emacs users don't write elisp: those people
expect this command already built-in.







^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-17  7:39               ` Tino Calancha
@ 2018-07-20  9:03                 ` Eli Zaretskii
  2018-07-23  3:57                   ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Eli Zaretskii @ 2018-07-20  9:03 UTC (permalink / raw)
  To: Tino Calancha
  Cc: bug-gnu-emacs-bounces+psainty=orcon.net.nz, tino.calancha,
	psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Tue, 17 Jul 2018 16:39:27 +0900
> Cc: bug-gnu-emacs <bug-gnu-emacs-bounces+psainty=orcon.net.nz@gnu.org>,
> 	tino.calancha@gmail.com, tzz@lifelogs.com, clement.pit@gmail.com,
> 	Michael Albinus <michael.albinus@gmx.de>, 24150@debbugs.gnu.org,
> 	sdl.web@gmail.com
> 
> At this stage, I am happy to focus the discussion on the acceptance
> of the command itself.

I think we all agree that such a command would be a good feature.

As for your (Tino's) patch, I was somewhat surprised to see how much
code you needed.  We have the capability of creating parent
directories in 'make-directory', so I thought all we'd need for
creating a new file is this two-step dance:

  . call make-directory to maybe create the file's parent directory
  . call write-region to create the file itself

What did I miss that needs so many lines of code?

The advantage of the above seems to be that we don't need any
refactoring to create the internal make--empty-file-or-directory
function.

Also, once we settle on the implementation, please don't forget NEWS
and the manuals.

Thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-20  9:03                 ` Eli Zaretskii
@ 2018-07-23  3:57                   ` Tino Calancha
  2018-07-27  8:39                     ` Eli Zaretskii
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2018-07-23  3:57 UTC (permalink / raw)
  To: Eli Zaretskii
  Cc: bug-gnu-emacs-bounces+psainty=orcon.net.nz, psainty, tzz,
	clement.pit, michael.albinus, 24150, sdl.web

Eli Zaretskii <eliz@gnu.org> writes:

> I was somewhat surprised to see how much
> code you needed.  We have the capability of creating parent
> directories in 'make-directory', so I thought all we'd need for
> creating a new file is this two-step dance:
>
>   . call make-directory to maybe create the file's parent directory
>   . call write-region to create the file itself
>
> What did I miss that needs so many lines of code?
Right.  Too much dance.
Updated the patch to follow your recomendation:

--8<-----------------------------cut here---------------start------------->8---
commit 700087e10f26359ed75b1cf2f23d72971eaafbca
Author: Tino Calancha <tino.calancha@gmail.com>
Date:   Mon Jul 23 12:49:47 2018 +0900

    New commands to create an empty file
    
    Similarly as `create-directory', `dired-create-directory',
    the new commands create the parent dirs as needed (Bug#24150).
    * lisp/files.el (make-empty-file): New command.
    
    * lisp/dired-aux.el (dired-create-empty-file): New command.
    (dired--find-topmost-parent-dir): New function extracted
    from `dired-create-directory'.
    (dired-create-directory, dired-create-empty-file): Use it.
    
    * lisp/dired.el (dired-mode-map):
    Add menu entry for `dired-create-empty-file'.
    
    * doc/emacs/dired.texi (Misc Dired Features)
    * doc/lispref/files.texi (Create/Delete Dirs): Update manual.
    ; * etc/NEWS: Announce the changes.

diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 007a943714..1b03a3967a 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1468,6 +1468,11 @@ Misc Dired Features
 directory's name, and creates that directory.  It signals an error if
 the directory already exists.
 
+@findex dired-create-empty-file
+  The command (@code{dired-create-empty-file}) reads a
+file name, and creates that file.  It signals an error if
+the file already exists.
+
 @cindex searching multiple files via Dired
 @kindex M-s a C-s @r{(Dired)}
 @kindex M-s a M-C-s @r{(Dired)}
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 068cf05443..c891349c59 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -3006,6 +3006,12 @@ Create/Delete Dirs
 interactive call, that means to create the parent directories first,
 if they don't already exist.
 
+@deffn Command make-empty-file filename &optional parents
+This command creates an empty file named @var{filename}.
+As @code{make-directory}, this command creates parent directories
+if @var{parents} is non-@code{nil}.
+If @var{filename} already exists, then this command signal an error.
+
 @code{mkdir} is an alias for this.
 @end deffn
 
diff --git a/etc/NEWS b/etc/NEWS
index 57b51f61b6..78fd7fd80d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -180,6 +180,9 @@ This triggers to search the program on the remote host as indicated by
 \f
 * Editing Changes in Emacs 27.1
 
++++
+** New command 'make-empty-file'.
+
 ---
 ** New variable 'x-wait-for-event-timeout'.
 This controls how long Emacs will wait for updates to the graphical
@@ -217,6 +220,11 @@ navigation and editing of large files.
 \f
 * Changes in Specialized Modes and Packages in Emacs 27.1
 
++++
+** Dired
+
+*** New command 'dired-create-empty-file'.
+
 ** Change Logs and VC
 
 *** Recording ChangeLog entries doesn't require an actual file.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 925a7d50d6..8fd6dcdea0 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1989,6 +1989,16 @@ dired-dwim-target-defaults
       dired-dirs)))
 
 \f
+
+(defun dired--find-topmost-parent-dir (filename)
+  "Return the topmost nonexistent parent dir of FILENAME.
+FILENAME is a full file name."
+  (let ((try filename) new)
+    (while (and try (not (file-exists-p try)) (not (equal new try)))
+      (setq new try
+	    try (directory-file-name (file-name-directory try))))
+    new))
+
 ;;;###autoload
 (defun dired-create-directory (directory)
   "Create a directory called DIRECTORY.
@@ -1997,18 +2007,31 @@ dired-create-directory
   (interactive
    (list (read-file-name "Create directory: " (dired-current-directory))))
   (let* ((expanded (directory-file-name (expand-file-name directory)))
-	 (try expanded) new)
+	 new)
     (if (file-exists-p expanded)
 	(error "Cannot create directory %s: file exists" expanded))
-    ;; Find the topmost nonexistent parent dir (variable `new')
-    (while (and try (not (file-exists-p try)) (not (equal new try)))
-      (setq new try
-	    try (directory-file-name (file-name-directory try))))
+    (setq new (dired--find-topmost-parent-dir expanded))
     (make-directory expanded t)
     (when new
       (dired-add-file new)
       (dired-move-to-filename))))
 
+;;;###autoload
+(defun dired-create-empty-file (file)
+  "Create an empty file called FILE.
+Parent directories of FILE are created as needed.
+If FILE already exists, signal an error."
+  (interactive (list (read-file-name "Create empty file: ")))
+  (let* ((expanded (expand-file-name file))
+         new)
+    (if (file-exists-p expanded)
+        (error "Cannot create file %s: file exists" expanded))
+    (setq new (dired--find-topmost-parent-dir expanded))
+    (make-empty-file file 'parents)
+    (when new
+      (dired-add-file new)
+      (dired-move-to-filename))))
+
 (defun dired-into-dir-with-symlinks (target)
   (and (file-directory-p target)
        (not (file-symlink-p target))))
diff --git a/lisp/dired.el b/lisp/dired.el
index 1348df6934..26a7449e03 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1802,6 +1802,9 @@ dired-mode-map
     (define-key map [menu-bar immediate create-directory]
       '(menu-item "Create Directory..." dired-create-directory
 		  :help "Create a directory"))
+    (define-key map [menu-bar immediate create-empty-file]
+      '(menu-item "Create Empty file..." dired-create-empty-file
+		  :help "Create an empty file"))
     (define-key map [menu-bar immediate wdired-mode]
       '(menu-item "Edit File Names" wdired-change-to-wdired-mode
 		  :help "Put a Dired buffer in a mode in which filenames are editable"
diff --git a/lisp/files.el b/lisp/files.el
index eabb3c0e06..0880ab8dc0 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5519,6 +5519,20 @@ make-directory
 	  (dolist (dir create-list)
             (files--ensure-directory dir)))))))
 
+(defun make-empty-file (filename &optional parents)
+  "Create an empty file FILENAME.
+Optional arg PARENTS, if non-nil then creates parent dirs as needed.
+
+If called interactively, then PARENTS is non-nil."
+  (interactive
+   (let ((filename (read-file-name "Create empty file: ")))
+     (list filename t)))
+  (let ((paren-dir (file-name-directory filename)))
+    (when paren-dir (make-directory paren-dir parents)))
+  (if (and (file-exists-p filename) (null parents))
+      (signal 'file-already-exists `("File exists" ,filename) )
+    (write-region "" nil filename nil 0)))
+
 (defconst directory-files-no-dot-files-regexp
   "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"
   "Regexp matching any file name except \".\" and \"..\".")

--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 27.0.50 (build 20, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2018-07-23
Repository revision: 8f3bca3ad513549af552b321aaca81e9e635857b
Windowing system distributor 'The X.Org Foundation', version 11.0.11902000
System Description: Debian GNU/Linux 9 (stretch)





^ permalink raw reply related	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-23  3:57                   ` Tino Calancha
@ 2018-07-27  8:39                     ` Eli Zaretskii
  2018-07-31  4:47                       ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Eli Zaretskii @ 2018-07-27  8:39 UTC (permalink / raw)
  To: Tino Calancha; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

> From: Tino Calancha <tino.calancha@gmail.com>
> Cc: bug-gnu-emacs-bounces+psainty=orcon.net.nz@gnu.org,  psainty@orcon.net.nz,  tzz@lifelogs.com,  clement.pit@gmail.com,  michael.albinus@gmx.de,  24150@debbugs.gnu.org,  sdl.web@gmail.com
> Date: Mon, 23 Jul 2018 12:57:09 +0900
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > I was somewhat surprised to see how much
> > code you needed.  We have the capability of creating parent
> > directories in 'make-directory', so I thought all we'd need for
> > creating a new file is this two-step dance:
> >
> >   . call make-directory to maybe create the file's parent directory
> >   . call write-region to create the file itself
> >
> > What did I miss that needs so many lines of code?
> Right.  Too much dance.
> Updated the patch to follow your recomendation:

Thanks, this is much better IMO.

> +@deffn Command make-empty-file filename &optional parents
> +This command creates an empty file named @var{filename}.
> +As @code{make-directory}, this command creates parent directories
> +if @var{parents} is non-@code{nil}.
> +If @var{filename} already exists, then this command signal an error.
                                                       ^^^^^^
"signals".  And I would drop the "then" part, it is not needed here.

> +(defun dired--find-topmost-parent-dir (filename)
> +  "Return the topmost nonexistent parent dir of FILENAME.
> +FILENAME is a full file name."
> +  (let ((try filename) new)
> +    (while (and try (not (file-exists-p try)) (not (equal new try)))
> +      (setq new try
> +	    try (directory-file-name (file-name-directory try))))
> +    new))

What is the purpose of using this function in dired-create-empty-file?
What you do with the result of this function doesn't seem to be
reflected in the doc string of dired-create-empty-file.

> +(defun make-empty-file (filename &optional parents)
> +  "Create an empty file FILENAME.
> +Optional arg PARENTS, if non-nil then creates parent dirs as needed.

"Optional arg PARENTS, if non-nil, means create parent dirs as needed."

> +If called interactively, then PARENTS is non-nil."
> +  (interactive
> +   (let ((filename (read-file-name "Create empty file: ")))
> +     (list filename t)))
> +  (let ((paren-dir (file-name-directory filename)))
> +    (when paren-dir (make-directory paren-dir parents)))
> +  (if (and (file-exists-p filename) (null parents))
> +      (signal 'file-already-exists `("File exists" ,filename) )

Shouldn't we check for file existing before creating the missing
parent directories?

Thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-27  8:39                     ` Eli Zaretskii
@ 2018-07-31  4:47                       ` Tino Calancha
  2018-07-31 16:20                         ` Eli Zaretskii
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2018-07-31  4:47 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

Eli Zaretskii <eliz@gnu.org> writes:

>> +@deffn Command make-empty-file filename &optional parents
>> +This command creates an empty file named @var{filename}.
>> +As @code{make-directory}, this command creates parent directories
>> +if @var{parents} is non-@code{nil}.
>> +If @var{filename} already exists, then this command signal an error.
>                                                        ^^^^^^
> "signals".  And I would drop the "then" part, it is not needed here.
Done! Thank you.

>> +(defun dired--find-topmost-parent-dir (filename)
>> +  "Return the topmost nonexistent parent dir of FILENAME.
>> +FILENAME is a full file name."
>> +  (let ((try filename) new)
>> +    (while (and try (not (file-exists-p try)) (not (equal new try)))
>> +      (setq new try
>> +	    try (directory-file-name (file-name-directory try))))
>> +    new))
>
> What is the purpose of using this function in dired-create-empty-file?
Same as in `dired-create-directory': to update the new entry in the Dired buffer.
I have extracted `dired--find-topmost-parent-dir' from `dired-create-directory'
to be DRY.
> What you do with the result of this function doesn't seem to be
> reflected in the doc string of dired-create-empty-file.
That's because `dired--find-topmost-parent-dir' is an internal function
(prefixed with 'dired--').  I don't think we need to detail in the docstring
what callers can do with the return value.  Even not having a docstring could
be OK: users don't need to know about this function.

Maybe we can add in a comment the purpose of this function.  What do you think?
I have added the following comment:
+;; We use this function in `dired-create-directory' and
+;; `dired-create-empty-file'; the return value is the new entry
+;; in the updated Dired buffer.
 (defun dired--find-topmost-parent-dir (filename)
   "Return the topmost nonexistent parent dir of FILENAME.


>> +(defun make-empty-file (filename &optional parents)
>> +  "Create an empty file FILENAME.
>> +Optional arg PARENTS, if non-nil then creates parent dirs as needed.
>
> "Optional arg PARENTS, if non-nil, means create parent dirs as needed."
>
>> +If called interactively, then PARENTS is non-nil."
>> +  (interactive
>> +   (let ((filename (read-file-name "Create empty file: ")))
>> +     (list filename t)))
>> +  (let ((paren-dir (file-name-directory filename)))
>> +    (when paren-dir (make-directory paren-dir parents)))
>> +  (if (and (file-exists-p filename) (null parents))
>> +      (signal 'file-already-exists `("File exists" ,filename) )
>
> Shouldn't we check for file existing before creating the missing
> parent directories?
Absolutely.  Thank you.

Updated patch:
--8<-----------------------------cut here---------------start------------->8---
commit 31d59e2770da0fbfe60808e91efaf7a275aa9b9e
Author: Tino Calancha <tino.calancha@gmail.com>
Date:   Tue Jul 31 13:26:43 2018 +0900

    New commands to create an empty file
    
    Similarly as `create-directory', `dired-create-directory',
    the new commands create the parent dirs as needed (Bug#24150).
    * lisp/files.el (make-empty-file): New command.
    
    * lisp/dired-aux.el (dired-create-empty-file): New command.
    (dired--find-topmost-parent-dir): New function extracted
    from `dired-create-directory'.
    (dired-create-directory, dired-create-empty-file): Use it.
    
    * lisp/dired.el (dired-mode-map):
    Add menu entry for `dired-create-empty-file'.
    
    * doc/emacs/dired.texi (Misc Dired Features)
    * doc/lispref/files.texi (Create/Delete Dirs): Update manual.
    ; * etc/NEWS: Announce the changes.

diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 007a943714..1b03a3967a 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1468,6 +1468,11 @@ Misc Dired Features
 directory's name, and creates that directory.  It signals an error if
 the directory already exists.
 
+@findex dired-create-empty-file
+  The command (@code{dired-create-empty-file}) reads a
+file name, and creates that file.  It signals an error if
+the file already exists.
+
 @cindex searching multiple files via Dired
 @kindex M-s a C-s @r{(Dired)}
 @kindex M-s a M-C-s @r{(Dired)}
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 068cf05443..536f0292f9 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -3006,6 +3006,12 @@ Create/Delete Dirs
 interactive call, that means to create the parent directories first,
 if they don't already exist.
 
+@deffn Command make-empty-file filename &optional parents
+This command creates an empty file named @var{filename}.
+As @code{make-directory}, this command creates parent directories
+if @var{parents} is non-@code{nil}.
+If @var{filename} already exists, this command signals an error.
+
 @code{mkdir} is an alias for this.
 @end deffn
 
diff --git a/etc/NEWS b/etc/NEWS
index f1ea835679..e129bff7a4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -185,6 +185,9 @@ This triggers to search the program on the remote host as indicated by
 \f
 * Editing Changes in Emacs 27.1
 
++++
+** New command 'make-empty-file'.
+
 ---
 ** New variable 'x-wait-for-event-timeout'.
 This controls how long Emacs will wait for updates to the graphical
@@ -222,6 +225,11 @@ navigation and editing of large files.
 \f
 * Changes in Specialized Modes and Packages in Emacs 27.1
 
++++
+** Dired
+
+*** New command 'dired-create-empty-file'.
+
 ** Change Logs and VC
 
 *** Recording ChangeLog entries doesn't require an actual file.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 925a7d50d6..35ac176195 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1989,6 +1989,19 @@ dired-dwim-target-defaults
       dired-dirs)))
 
 \f
+
+;; We use this function in `dired-create-directory' and
+;; `dired-create-empty-file'; the return value is the new entry
+;; in the updated Dired buffer.
+(defun dired--find-topmost-parent-dir (filename)
+  "Return the topmost nonexistent parent dir of FILENAME.
+FILENAME is a full file name."
+  (let ((try filename) new)
+    (while (and try (not (file-exists-p try)) (not (equal new try)))
+      (setq new try
+	    try (directory-file-name (file-name-directory try))))
+    new))
+
 ;;;###autoload
 (defun dired-create-directory (directory)
   "Create a directory called DIRECTORY.
@@ -1997,18 +2010,31 @@ dired-create-directory
   (interactive
    (list (read-file-name "Create directory: " (dired-current-directory))))
   (let* ((expanded (directory-file-name (expand-file-name directory)))
-	 (try expanded) new)
+	 new)
     (if (file-exists-p expanded)
 	(error "Cannot create directory %s: file exists" expanded))
-    ;; Find the topmost nonexistent parent dir (variable `new')
-    (while (and try (not (file-exists-p try)) (not (equal new try)))
-      (setq new try
-	    try (directory-file-name (file-name-directory try))))
+    (setq new (dired--find-topmost-parent-dir expanded))
     (make-directory expanded t)
     (when new
       (dired-add-file new)
       (dired-move-to-filename))))
 
+;;;###autoload
+(defun dired-create-empty-file (file)
+  "Create an empty file called FILE.
+Parent directories of FILE are created as needed.
+If FILE already exists, signal an error."
+  (interactive (list (read-file-name "Create empty file: ")))
+  (let* ((expanded (expand-file-name file))
+         new)
+    (if (file-exists-p expanded)
+        (error "Cannot create file %s: file exists" expanded))
+    (setq new (dired--find-topmost-parent-dir expanded))
+    (make-empty-file file 'parents)
+    (when new
+      (dired-add-file new)
+      (dired-move-to-filename))))
+
 (defun dired-into-dir-with-symlinks (target)
   (and (file-directory-p target)
        (not (file-symlink-p target))))
diff --git a/lisp/dired.el b/lisp/dired.el
index 1348df6934..26a7449e03 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1802,6 +1802,9 @@ dired-mode-map
     (define-key map [menu-bar immediate create-directory]
       '(menu-item "Create Directory..." dired-create-directory
 		  :help "Create a directory"))
+    (define-key map [menu-bar immediate create-empty-file]
+      '(menu-item "Create Empty file..." dired-create-empty-file
+		  :help "Create an empty file"))
     (define-key map [menu-bar immediate wdired-mode]
       '(menu-item "Edit File Names" wdired-change-to-wdired-mode
 		  :help "Put a Dired buffer in a mode in which filenames are editable"
diff --git a/lisp/files.el b/lisp/files.el
index 6e4f6ca51b..8057def525 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5519,6 +5519,21 @@ make-directory
 	  (dolist (dir create-list)
             (files--ensure-directory dir)))))))
 
+(defun make-empty-file (filename &optional parents)
+  "Create an empty file FILENAME.
+Optional arg PARENTS, if non-nil then creates parent dirs as needed.
+
+If called interactively, then PARENTS is non-nil."
+  (interactive
+   (let ((filename (read-file-name "Create empty file: ")))
+     (list filename t)))
+  (when (and (file-exists-p filename) (null parents))
+    (signal 'file-already-exists `("File exists" ,filename)))
+  (let ((paren-dir (file-name-directory filename)))
+    (when (and paren-dir (not (file-exists-p paren-dir)))
+      (make-directory paren-dir parents)))
+  (write-region "" nil filename nil 0))
+
 (defconst directory-files-no-dot-files-regexp
   "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"
   "Regexp matching any file name except \".\" and \"..\".")

--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 27.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2018-07-31
Repository revision: 63ef79329935b790b9c8107125bce66e1f272c2e





^ permalink raw reply related	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-31  4:47                       ` Tino Calancha
@ 2018-07-31 16:20                         ` Eli Zaretskii
  2018-08-01  5:16                           ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Eli Zaretskii @ 2018-07-31 16:20 UTC (permalink / raw)
  To: Tino Calancha; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

> From: Tino Calancha <tino.calancha@gmail.com>
> Cc: psainty@orcon.net.nz,  tzz@lifelogs.com,  clement.pit@gmail.com,  michael.albinus@gmx.de,  24150@debbugs.gnu.org,  sdl.web@gmail.com
> Date: Tue, 31 Jul 2018 13:47:30 +0900
> 
> >> +(defun dired--find-topmost-parent-dir (filename)
> >> +  "Return the topmost nonexistent parent dir of FILENAME.
> >> +FILENAME is a full file name."
> >> +  (let ((try filename) new)
> >> +    (while (and try (not (file-exists-p try)) (not (equal new try)))
> >> +      (setq new try
> >> +	    try (directory-file-name (file-name-directory try))))
> >> +    new))
> >
> > What is the purpose of using this function in dired-create-empty-file?
> Same as in `dired-create-directory': to update the new entry in the Dired buffer.
> I have extracted `dired--find-topmost-parent-dir' from `dired-create-directory'
> to be DRY.
> > What you do with the result of this function doesn't seem to be
> > reflected in the doc string of dired-create-empty-file.
> That's because `dired--find-topmost-parent-dir' is an internal function
> (prefixed with 'dired--').  I don't think we need to detail in the docstring
> what callers can do with the return value.  Even not having a docstring could
> be OK: users don't need to know about this function.

No, that's not what I meant.  I meant to say that if we call
dired--find-topmost-parent-dir to update the new entry in the Dired
buffer, then the doc string of dired-create-empty-file should say that
it does so.  Right now, the doc string says just this:

  Create an empty file called FILE.

It says nothing about Dired entries.

> I have added the following comment:
> +;; We use this function in `dired-create-directory' and
> +;; `dired-create-empty-file'; the return value is the new entry
> +;; in the updated Dired buffer.

That's fine.  But my comment was about the doc string of
dired-create-empty-file.

Otherwise, this LGTM, thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-07-31 16:20                         ` Eli Zaretskii
@ 2018-08-01  5:16                           ` Tino Calancha
  2018-08-01  6:24                             ` Eli Zaretskii
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2018-08-01  5:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

Eli Zaretskii <eliz@gnu.org> writes:

>
> No, that's not what I meant.  I meant to say that if we call
> dired--find-topmost-parent-dir to update the new entry in the Dired
> buffer, then the doc string of dired-create-empty-file should say that
> it does so.  Right now, the doc string says just this:
>
>   Create an empty file called FILE.
>
> It says nothing about Dired entries.
>
>> I have added the following comment:
>> +;; We use this function in `dired-create-directory' and
>> +;; `dired-create-empty-file'; the return value is the new entry
>> +;; in the updated Dired buffer.
>
> That's fine.  But my comment was about the doc string of
> dired-create-empty-file.
Ahhhh, I see.
Hummmm, I think we assume that Dired will add the new entry;
similarly as `dired-do-delete', which deletes the file and
the entry from the Dired buffer: in the docstring it's not mentioned
that this command drop the entry as well.
It's not mentioned in `dired-create-directory' either.

Every command prefixed with 'dired-' should add/drop buffer entries
automatically as needed.
I think this last sentence belongs to the manual more than the
docstrings (probably already there).





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-08-01  5:16                           ` Tino Calancha
@ 2018-08-01  6:24                             ` Eli Zaretskii
  2018-08-01  7:13                               ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Eli Zaretskii @ 2018-08-01  6:24 UTC (permalink / raw)
  To: Tino Calancha; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

> From: Tino Calancha <tino.calancha@gmail.com>
> Cc: psainty@orcon.net.nz,  tzz@lifelogs.com,  clement.pit@gmail.com,  michael.albinus@gmx.de,  24150@debbugs.gnu.org,  sdl.web@gmail.com
> Date: Wed, 01 Aug 2018 14:16:54 +0900
> 
> > That's fine.  But my comment was about the doc string of
> > dired-create-empty-file.
> Ahhhh, I see.
> Hummmm, I think we assume that Dired will add the new entry;
> similarly as `dired-do-delete', which deletes the file and
> the entry from the Dired buffer: in the docstring it's not mentioned
> that this command drop the entry as well.
> It's not mentioned in `dired-create-directory' either.
> 
> Every command prefixed with 'dired-' should add/drop buffer entries
> automatically as needed.
> I think this last sentence belongs to the manual more than the
> docstrings (probably already there).

Fair enough.

I think the doc strings do need to say that the file name is
added/modified in the Dired buffer, but that's a separate issue.
Maybe to make the doc string of dired-create-empty-file hint at that,
instead "create empty file" say something like "add an empty file to
the current directory"?





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-08-01  6:24                             ` Eli Zaretskii
@ 2018-08-01  7:13                               ` Tino Calancha
  2018-08-01  8:56                                 ` Eli Zaretskii
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2018-08-01  7:13 UTC (permalink / raw)
  To: Eli Zaretskii
  Cc: Tino Calancha, psainty, tzz, clement.pit, michael.albinus, 24150,
	sdl.web



> I think the doc strings do need to say that the file name is
> added/modified in the Dired buffer, but that's a separate issue.
> Maybe to make the doc string of dired-create-empty-file hint at that,
> instead "create empty file" say something like "add an empty file to
> the current directory"?
That could suggest that we just add an entry in Dired (not writing to 
disk).

How about following two (first with long forst line, second split it in 
2):

"Create an empty file called FILE, add a new entry for it in the Dired 
buffer.
Parent directories of FILE are created as needed.
If FILE already exists, signal an error."


"Create an empty file called FILE.
Add a new entry for it in the Dired buffer.
Parent directories of FILE are created as needed.
If FILE already exists, signal an error."





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-08-01  7:13                               ` Tino Calancha
@ 2018-08-01  8:56                                 ` Eli Zaretskii
  2018-08-01  9:31                                   ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Eli Zaretskii @ 2018-08-01  8:56 UTC (permalink / raw)
  To: Tino Calancha; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Wed, 1 Aug 2018 16:13:52 +0900 (JST)
> cc: Tino Calancha <tino.calancha@gmail.com>, psainty@orcon.net.nz, 
>     tzz@lifelogs.com, clement.pit@gmail.com, michael.albinus@gmx.de, 
>     24150@debbugs.gnu.org, sdl.web@gmail.com
> 
> > I think the doc strings do need to say that the file name is
> > added/modified in the Dired buffer, but that's a separate issue.
> > Maybe to make the doc string of dired-create-empty-file hint at that,
> > instead "create empty file" say something like "add an empty file to
> > the current directory"?
> That could suggest that we just add an entry in Dired (not writing to 
> disk).

No, I don't think so: "add a file to a directory" doesn't mention
Dired at all.  But if it confused you, maybe others could be confused
as well.

> How about following two (first with long forst line, second split it in 
> 2):
> 
> "Create an empty file called FILE, add a new entry for it in the Dired 
> buffer.
> Parent directories of FILE are created as needed.
> If FILE already exists, signal an error."
> 
> 
> "Create an empty file called FILE.
> Add a new entry for it in the Dired buffer.
> Parent directories of FILE are created as needed.
> If FILE already exists, signal an error."

The second one is better, IMO.  But instead of "it", I'd say "the new
file" or "the created file".

Thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-08-01  8:56                                 ` Eli Zaretskii
@ 2018-08-01  9:31                                   ` Tino Calancha
  2018-08-01 11:45                                     ` Eli Zaretskii
  0 siblings, 1 reply; 38+ messages in thread
From: Tino Calancha @ 2018-08-01  9:31 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

Eli Zaretskii <eliz@gnu.org> writes:

>> How about following two (first with long forst line, second split it in 
>> 2):
>> 
>> "Create an empty file called FILE, add a new entry for it in the Dired 
>> buffer.
>> Parent directories of FILE are created as needed.
>> If FILE already exists, signal an error."
>> 
>> 
>> "Create an empty file called FILE.
>> Add a new entry for it in the Dired buffer.
>> Parent directories of FILE are created as needed.
>> If FILE already exists, signal an error."
>
> The second one is better, IMO.  But instead of "it", I'd say "the new
> file" or "the created file".
OK, thank you.
I update the patch below.  As sooner I get the green light I will push
it to master.
--8<-----------------------------cut here---------------start------------->8---
commit 27a5a905dbd2e32a3b666febf970c45cc9c746a8
Author: Tino Calancha <tino.calancha@gmail.com>
Date:   Wed Aug 1 18:28:45 2018 +0900

    New commands to create an empty file
    
    Similarly as `create-directory', `dired-create-directory',
    the new commands create the parent dirs as needed (Bug#24150).
    * lisp/files.el (make-empty-file): New command.
    
    * lisp/dired-aux.el (dired-create-empty-file): New command.
    (dired--find-topmost-parent-dir): New function extracted
    from `dired-create-directory'.
    (dired-create-directory, dired-create-empty-file): Use it.
    
    * lisp/dired.el (dired-mode-map):
    Add menu entry for `dired-create-empty-file'.
    
    * doc/emacs/dired.texi (Misc Dired Features)
    * doc/lispref/files.texi (Create/Delete Dirs): Update manual.
    ; * etc/NEWS: Announce the changes.

diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 007a943714..1b03a3967a 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1468,6 +1468,11 @@ Misc Dired Features
 directory's name, and creates that directory.  It signals an error if
 the directory already exists.
 
+@findex dired-create-empty-file
+  The command (@code{dired-create-empty-file}) reads a
+file name, and creates that file.  It signals an error if
+the file already exists.
+
 @cindex searching multiple files via Dired
 @kindex M-s a C-s @r{(Dired)}
 @kindex M-s a M-C-s @r{(Dired)}
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 068cf05443..536f0292f9 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -3006,6 +3006,12 @@ Create/Delete Dirs
 interactive call, that means to create the parent directories first,
 if they don't already exist.
 
+@deffn Command make-empty-file filename &optional parents
+This command creates an empty file named @var{filename}.
+As @code{make-directory}, this command creates parent directories
+if @var{parents} is non-@code{nil}.
+If @var{filename} already exists, this command signals an error.
+
 @code{mkdir} is an alias for this.
 @end deffn
 
diff --git a/etc/NEWS b/etc/NEWS
index f1ea835679..e129bff7a4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -185,6 +185,9 @@ This triggers to search the program on the remote host as indicated by
 \f
 * Editing Changes in Emacs 27.1
 
++++
+** New command 'make-empty-file'.
+
 ---
 ** New variable 'x-wait-for-event-timeout'.
 This controls how long Emacs will wait for updates to the graphical
@@ -222,6 +225,11 @@ navigation and editing of large files.
 \f
 * Changes in Specialized Modes and Packages in Emacs 27.1
 
++++
+** Dired
+
+*** New command 'dired-create-empty-file'.
+
 ** Change Logs and VC
 
 *** Recording ChangeLog entries doesn't require an actual file.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 925a7d50d6..21ee50ce5c 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1989,6 +1989,19 @@ dired-dwim-target-defaults
       dired-dirs)))
 
 \f
+
+;; We use this function in `dired-create-directory' and
+;; `dired-create-empty-file'; the return value is the new entry
+;; in the updated Dired buffer.
+(defun dired--find-topmost-parent-dir (filename)
+  "Return the topmost nonexistent parent dir of FILENAME.
+FILENAME is a full file name."
+  (let ((try filename) new)
+    (while (and try (not (file-exists-p try)) (not (equal new try)))
+      (setq new try
+	    try (directory-file-name (file-name-directory try))))
+    new))
+
 ;;;###autoload
 (defun dired-create-directory (directory)
   "Create a directory called DIRECTORY.
@@ -1997,18 +2010,32 @@ dired-create-directory
   (interactive
    (list (read-file-name "Create directory: " (dired-current-directory))))
   (let* ((expanded (directory-file-name (expand-file-name directory)))
-	 (try expanded) new)
+	 new)
     (if (file-exists-p expanded)
 	(error "Cannot create directory %s: file exists" expanded))
-    ;; Find the topmost nonexistent parent dir (variable `new')
-    (while (and try (not (file-exists-p try)) (not (equal new try)))
-      (setq new try
-	    try (directory-file-name (file-name-directory try))))
+    (setq new (dired--find-topmost-parent-dir expanded))
     (make-directory expanded t)
     (when new
       (dired-add-file new)
       (dired-move-to-filename))))
 
+;;;###autoload
+(defun dired-create-empty-file (file)
+  "Create an empty file called FILE.
+ Add a new entry for the new file in the Dired buffer.
+ Parent directories of FILE are created as needed.
+ If FILE already exists, signal an error."
+  (interactive (list (read-file-name "Create empty file: ")))
+  (let* ((expanded (expand-file-name file))
+         new)
+    (if (file-exists-p expanded)
+        (error "Cannot create file %s: file exists" expanded))
+    (setq new (dired--find-topmost-parent-dir expanded))
+    (make-empty-file file 'parents)
+    (when new
+      (dired-add-file new)
+      (dired-move-to-filename))))
+
 (defun dired-into-dir-with-symlinks (target)
   (and (file-directory-p target)
        (not (file-symlink-p target))))
diff --git a/lisp/dired.el b/lisp/dired.el
index 1348df6934..26a7449e03 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1802,6 +1802,9 @@ dired-mode-map
     (define-key map [menu-bar immediate create-directory]
       '(menu-item "Create Directory..." dired-create-directory
 		  :help "Create a directory"))
+    (define-key map [menu-bar immediate create-empty-file]
+      '(menu-item "Create Empty file..." dired-create-empty-file
+		  :help "Create an empty file"))
     (define-key map [menu-bar immediate wdired-mode]
       '(menu-item "Edit File Names" wdired-change-to-wdired-mode
 		  :help "Put a Dired buffer in a mode in which filenames are editable"
diff --git a/lisp/files.el b/lisp/files.el
index 6e4f6ca51b..8057def525 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5519,6 +5519,21 @@ make-directory
 	  (dolist (dir create-list)
             (files--ensure-directory dir)))))))
 
+(defun make-empty-file (filename &optional parents)
+  "Create an empty file FILENAME.
+Optional arg PARENTS, if non-nil then creates parent dirs as needed.
+
+If called interactively, then PARENTS is non-nil."
+  (interactive
+   (let ((filename (read-file-name "Create empty file: ")))
+     (list filename t)))
+  (when (and (file-exists-p filename) (null parents))
+    (signal 'file-already-exists `("File exists" ,filename)))
+  (let ((paren-dir (file-name-directory filename)))
+    (when (and paren-dir (not (file-exists-p paren-dir)))
+      (make-directory paren-dir parents)))
+  (write-region "" nil filename nil 0))
+
 (defconst directory-files-no-dot-files-regexp
   "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"
   "Regexp matching any file name except \".\" and \"..\".")

--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 27.0.50 (build 9, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2018-08-01
Repository revision: e28a37438d4ba71cd8a053e956686ab29ff97b6a
Windowing system distributor 'The X.Org Foundation', version 11.0.11902000
System Description: Debian GNU/Linux 9 (stretch)





^ permalink raw reply related	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-08-01  9:31                                   ` Tino Calancha
@ 2018-08-01 11:45                                     ` Eli Zaretskii
  2018-08-02  4:34                                       ` Tino Calancha
  0 siblings, 1 reply; 38+ messages in thread
From: Eli Zaretskii @ 2018-08-01 11:45 UTC (permalink / raw)
  To: Tino Calancha; +Cc: psainty, tzz, clement.pit, michael.albinus, 24150, sdl.web

> From: Tino Calancha <tino.calancha@gmail.com>
> Cc: psainty@orcon.net.nz,  tzz@lifelogs.com,  clement.pit@gmail.com,  michael.albinus@gmx.de,  24150@debbugs.gnu.org,  sdl.web@gmail.com
> Date: Wed, 01 Aug 2018 18:31:36 +0900
> 
> I update the patch below.  As sooner I get the green light I will push
> it to master.

It's good to go, thanks.





^ permalink raw reply	[flat|nested] 38+ messages in thread

* bug#24150: 26.0.50; New command: dired-create-empty-file
  2018-08-01 11:45                                     ` Eli Zaretskii
@ 2018-08-02  4:34                                       ` Tino Calancha
  0 siblings, 0 replies; 38+ messages in thread
From: Tino Calancha @ 2018-08-02  4:34 UTC (permalink / raw)
  To: 24150-done

Eli Zaretskii <eliz@gnu.org> writes:

>> I update the patch below.  As sooner I get the green light I will push
>> it to master.
>
> It's good to go, thanks.
Pushed into master branch as commit 'New commands to create an empty file'
(e65ec81fc3e556719fae8d8b4b42f571c7e9f4fc)





^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2018-08-02  4:34 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-04 13:25 bug#24150: 25.1.50; New command: dired-create-empty-file Tino Calancha
2016-08-04 13:54 ` Clément Pit--Claudel
2016-08-04 16:29 ` Leo Liu
2016-08-04 17:13   ` Ted Zlatanov
2016-08-04 17:29     ` Drew Adams
2016-08-05  6:03 ` Tino Calancha
2016-08-05 14:48   ` Drew Adams
2016-08-06 12:38     ` Tino Calancha
2016-08-05  6:07 ` Tino Calancha
2017-05-03  8:23 ` Tino Calancha
2017-07-03  4:51 ` bug#24150: 26.0.50; " Tino Calancha
2017-07-03 14:24   ` Eli Zaretskii
2017-07-03 15:04     ` Tino Calancha
2017-07-03 16:33       ` Eli Zaretskii
2017-07-03 20:18         ` Thien-Thi Nguyen
2017-07-07 13:13         ` Ted Zlatanov
2017-07-07 13:17           ` Drew Adams
2017-07-07 13:31             ` Ted Zlatanov
2017-07-03 15:12     ` Drew Adams
2017-07-05 18:28   ` Eli Zaretskii
2017-07-05 19:34     ` Drew Adams
2017-07-07  5:36       ` Tino Calancha
2017-07-07 11:11         ` Drew Adams
2018-07-10  7:01           ` Tino Calancha
2018-07-10  7:42             ` Phil Sainty
2018-07-17  7:39               ` Tino Calancha
2018-07-20  9:03                 ` Eli Zaretskii
2018-07-23  3:57                   ` Tino Calancha
2018-07-27  8:39                     ` Eli Zaretskii
2018-07-31  4:47                       ` Tino Calancha
2018-07-31 16:20                         ` Eli Zaretskii
2018-08-01  5:16                           ` Tino Calancha
2018-08-01  6:24                             ` Eli Zaretskii
2018-08-01  7:13                               ` Tino Calancha
2018-08-01  8:56                                 ` Eli Zaretskii
2018-08-01  9:31                                   ` Tino Calancha
2018-08-01 11:45                                     ` Eli Zaretskii
2018-08-02  4:34                                       ` Tino Calancha

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.