unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* patch: write-file to arbitrary target directory
@ 2007-11-17  1:09 Eduard Wiebe
  2007-11-17  1:34 ` Juri Linkov
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Eduard Wiebe @ 2007-11-17  1:09 UTC (permalink / raw)
  To: emacs-devel


 Hello,

This patch improves 'write-file' by creating  all parent directories of
target file (in spirit of proposal by Juri[1]).

Any comments?

Index: files.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/files.el,v
retrieving revision 1.941
diff -c -r1.941 files.el
*** files.el	16 Nov 2007 08:03:45 -0000	1.941
--- files.el	16 Nov 2007 23:51:19 -0000
***************
*** 3086,3099 ****
     (list (if buffer-file-name
  	     (read-file-name "Write file: "
  			     nil nil nil nil)
! 	   (read-file-name "Write file: " default-directory
! 			   (expand-file-name
! 			    (file-name-nondirectory (buffer-name))
! 			    default-directory)
! 			   nil nil))
  	 (not current-prefix-arg)))
    (or (null filename) (string-equal filename "")
        (progn
  	;; If arg is just a directory,
  	;; use the default file name, but in that directory.
  	(if (file-directory-p filename)
--- 3086,3107 ----
     (list (if buffer-file-name
  	     (read-file-name "Write file: "
  			     nil nil nil nil)
! 	   (let ((dir  (file-name-directory (buffer-name)))
! 		 (file (file-name-nondirectory (buffer-name))))
! 	     (read-file-name "Write file: "
! 			     dir (expand-file-name file dir) nil file)))
  	 (not current-prefix-arg)))
    (or (null filename) (string-equal filename "")
        (progn
+ 	;; If directory of file is not existent, create it with all parents.
+ 	(let ((dir (file-name-directory filename)))
+ 	  (when (and dir (not (file-exists-p dir)))
+ 	    (and confirm
+ 		 (or (y-or-n-p
+ 		      (format "Directory `%s' does not exists; create? " dir))
+ 		     (error "Canceled")))
+ 	    (make-directory dir 'parents)))
+ 
  	;; If arg is just a directory,
  	;; use the default file name, but in that directory.
  	(if (file-directory-p filename)


-------
[1]  http://article.gmane.org/gmane.emacs.devel/82779/match=dired+create+directory+arbitrary+depth

-- 
Eduard Wiebe

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  1:09 patch: write-file to arbitrary target directory Eduard Wiebe
@ 2007-11-17  1:34 ` Juri Linkov
  2007-11-17  4:28 ` Stefan Monnier
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 16+ messages in thread
From: Juri Linkov @ 2007-11-17  1:34 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

> This patch improves 'write-file' by creating  all parent directories of
> target file (in spirit of proposal by Juri[1]).
>
> Any comments?

I think this patch is useful.  Perhaps, the same y-or-n-p question
"Directory `%s' does not exists; create? " should be asked also in
`after-find-file' (with a call to `make-directory') instead of displaying
"Use M-x make-directory RET RET to create the directory and its parents"
because typing `y' as an answer to this question is less to type than
`M-x make-directory RET RET'.

-- 
Juri Linkov
http://www.jurta.org/emacs/

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  1:09 patch: write-file to arbitrary target directory Eduard Wiebe
  2007-11-17  1:34 ` Juri Linkov
@ 2007-11-17  4:28 ` Stefan Monnier
  2007-11-17  9:22   ` Eli Zaretskii
  2007-11-17 23:31   ` Richard Stallman
  2007-11-17  9:34 ` martin rudalics
  2007-11-17 17:42 ` Richard Stallman
  3 siblings, 2 replies; 16+ messages in thread
From: Stefan Monnier @ 2007-11-17  4:28 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

> This patch improves 'write-file' by creating  all parent directories of
> target file (in spirit of proposal by Juri[1]).

Please place this functionality in the `interactive' form, not in the
main body.


        Stefan

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  4:28 ` Stefan Monnier
@ 2007-11-17  9:22   ` Eli Zaretskii
  2007-11-17 13:14     ` Eduard Wiebe
  2007-11-17 23:31   ` Richard Stallman
  1 sibling, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2007-11-17  9:22 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: usenet, emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Fri, 16 Nov 2007 23:28:41 -0500
> Cc: emacs-devel@gnu.org
> 
> > This patch improves 'write-file' by creating  all parent directories of
> > target file (in spirit of proposal by Juri[1]).
> 
> Please place this functionality in the `interactive' form, not in the
> main body.

Exactly.  Or do something else to make sure these questions are not
popped up in non-interactive invocations, because users of these
routines do not expect any questions asked.

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  1:09 patch: write-file to arbitrary target directory Eduard Wiebe
  2007-11-17  1:34 ` Juri Linkov
  2007-11-17  4:28 ` Stefan Monnier
@ 2007-11-17  9:34 ` martin rudalics
  2007-11-17 13:15   ` Eduard Wiebe
  2007-11-17 17:42 ` Richard Stallman
  3 siblings, 1 reply; 16+ messages in thread
From: martin rudalics @ 2007-11-17  9:34 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

+ 		      (format "Directory `%s' does not exists; create? " dir))

should be

+ 		      (format "Directory `%s' does not exist; create? " dir))

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17 13:14     ` Eduard Wiebe
@ 2007-11-17 12:36       ` Eli Zaretskii
  2007-11-17 13:03         ` Thien-Thi Nguyen
  2007-11-17 22:04         ` Eduard Wiebe
  0 siblings, 2 replies; 16+ messages in thread
From: Eli Zaretskii @ 2007-11-17 12:36 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

> From: Eduard Wiebe <usenet@pusto.de>
> Date: Sat, 17 Nov 2007 14:14:24 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > Exactly.  Or do something else to make sure these questions are not
> > popped up in non-interactive invocations, because users of these
> > routines do not expect any questions asked.
> 
> Simple non-interactive call ala (write-file "path/to/not/file"), with
> 'confirm' parameter is nil, behaviors as expected. Have i overlooked
> something?

I think you overload the purpose of `confirm' with usage it wasn't
invented for, but if others don't object, I won't fight.

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17 12:36       ` Eli Zaretskii
@ 2007-11-17 13:03         ` Thien-Thi Nguyen
  2007-11-17 22:04         ` Eduard Wiebe
  1 sibling, 0 replies; 16+ messages in thread
From: Thien-Thi Nguyen @ 2007-11-17 13:03 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

() Eli Zaretskii <eliz@gnu.org>
() Sat, 17 Nov 2007 14:36:31 +0200

   I think you overload the purpose of `confirm' with usage it
   wasn't invented for, but if others don't object, I won't fight.

i think CONFIRM's meaning should not be expanded to include
parent directory creation.  furthermore, i wonder how the change
behaves when the filesystem is remote (tramp), and in the presence
of other special filename handling.

thi

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  9:22   ` Eli Zaretskii
@ 2007-11-17 13:14     ` Eduard Wiebe
  2007-11-17 12:36       ` Eli Zaretskii
  0 siblings, 1 reply; 16+ messages in thread
From: Eduard Wiebe @ 2007-11-17 13:14 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

> Exactly.  Or do something else to make sure these questions are not
> popped up in non-interactive invocations, because users of these
> routines do not expect any questions asked.

Simple non-interactive call ala (write-file "path/to/not/file"), with
'confirm' parameter is nil, behaviors as expected. Have i overlooked
something?

-- 
Eduard Wiebe

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  9:34 ` martin rudalics
@ 2007-11-17 13:15   ` Eduard Wiebe
  0 siblings, 0 replies; 16+ messages in thread
From: Eduard Wiebe @ 2007-11-17 13:15 UTC (permalink / raw)
  To: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> + 		      (format "Directory `%s' does not exists; create? " dir))
>
> should be
>
> + 		      (format "Directory `%s' does not exist; create? " dir))

Thanks.

-- 
Eduard Wiebe

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  1:09 patch: write-file to arbitrary target directory Eduard Wiebe
                   ` (2 preceding siblings ...)
  2007-11-17  9:34 ` martin rudalics
@ 2007-11-17 17:42 ` Richard Stallman
  2007-11-17 23:22   ` Eduard Wiebe
       [not found]   ` <861waobh7m.fsf@nirvana.pusto.de>
  3 siblings, 2 replies; 16+ messages in thread
From: Richard Stallman @ 2007-11-17 17:42 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

The change looks useful, but there may be a problem.

    ! 	   (let ((dir  (file-name-directory (buffer-name)))
    ! 		 (file (file-name-nondirectory (buffer-name))))

DIR will nearly always be nil, because buffer names normally
do not include directory parts.

Thus, not using default-directory here

    ! 	     (read-file-name "Write file: "
    ! 			     dir (expand-file-name file dir) nil file)))

seems like a bug.  What is the aim of that particular change?


Aside from that, it needs changes in the manual (maybe in more than
one place).

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17 12:36       ` Eli Zaretskii
  2007-11-17 13:03         ` Thien-Thi Nguyen
@ 2007-11-17 22:04         ` Eduard Wiebe
  1 sibling, 0 replies; 16+ messages in thread
From: Eduard Wiebe @ 2007-11-17 22:04 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

> I think you overload the purpose of `confirm' with usage it wasn't
> invented for, but if others don't object, I won't fight.

Yes, i see the point. Thank you for the hint.

-- 
Eduard Wiebe

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17 17:42 ` Richard Stallman
@ 2007-11-17 23:22   ` Eduard Wiebe
       [not found]   ` <861waobh7m.fsf@nirvana.pusto.de>
  1 sibling, 0 replies; 16+ messages in thread
From: Eduard Wiebe @ 2007-11-17 23:22 UTC (permalink / raw)
  To: emacs-devel

Richard Stallman <rms@gnu.org> writes:

> The change looks useful, but there may be a problem.
>
>     ! 	   (let ((dir  (file-name-directory (buffer-name)))
>     ! 		 (file (file-name-nondirectory (buffer-name))))
>
> DIR will nearly always be nil, because buffer names normally
> do not include directory parts.

Right. With 'ido' package user can create buffers with arbitrary names.

> Thus, not using default-directory here
>
>     ! 	     (read-file-name "Write file: "
>     ! 			     dir (expand-file-name file dir) nil file)))
>
> seems like a bug. 

I am not sure.

> What is the aim of that particular change?

Consider the case above, buffer has directory parts in name. By
calling 'write-file' i expect a proposal of directory name with these
directory parts of buffer name.

And if DIR is nil, read-file-name use 'default-directory' anyway.
(If i am not mistaken.)

> Aside from that, it needs changes in the manual (maybe in more than
> one place).

I try to identify these.

-- 
Eduard Wiebe

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

* Re: patch: write-file to arbitrary target directory
  2007-11-17  4:28 ` Stefan Monnier
  2007-11-17  9:22   ` Eli Zaretskii
@ 2007-11-17 23:31   ` Richard Stallman
  1 sibling, 0 replies; 16+ messages in thread
From: Richard Stallman @ 2007-11-17 23:31 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: usenet, emacs-devel

    > This patch improves 'write-file' by creating  all parent directories of
    > target file (in spirit of proposal by Juri[1]).

    Please place this functionality in the `interactive' form, not in the
    main body.

Are you suggesting it should create the directories
while reading the arguments?  That doesn't seem right.

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

* Re: patch: write-file to arbitrary target directory
       [not found]   ` <861waobh7m.fsf@nirvana.pusto.de>
@ 2007-11-18 13:01     ` Richard Stallman
  2007-11-19  0:01       ` Eduard Wiebe
  0 siblings, 1 reply; 16+ messages in thread
From: Richard Stallman @ 2007-11-18 13:01 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

    > The change looks useful, but there may be a problem.
    >
    >     ! 	   (let ((dir  (file-name-directory (buffer-name)))
    >     ! 		 (file (file-name-nondirectory (buffer-name))))
    >
    > DIR will nearly always be nil, because buffer names normally
    > do not include directory parts.

    Not necessarily. With 'ido' package user can create buffers with
    arbitrary names.

Of course one can do so.  My point is that the normal practice is not
to put the directory name in the buffer name.  Does this change have
any effect on that usual case?

    And if DIR is nil, read-file-name use 'default-directory' anyway.
    (If i am not mistaken.)

Please double-check.

If it works right for that reason, there should be a comment to
explain.

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

* Re: patch: write-file to arbitrary target directory
  2007-11-18 13:01     ` Richard Stallman
@ 2007-11-19  0:01       ` Eduard Wiebe
  2007-11-22  2:28         ` Richard Stallman
  0 siblings, 1 reply; 16+ messages in thread
From: Eduard Wiebe @ 2007-11-19  0:01 UTC (permalink / raw)
  To: emacs-devel

Richard Stallman <rms@gnu.org> writes:

> My point is that the normal practice is not to put the directory
> name in the buffer name.  Does this change have any effect on that
> usual case?

No. See below.

>     And if DIR is nil, read-file-name use 'default-directory'
>anyway.  (If i am not mistaken.)
>
> Please double-check.

It is so. Compare itself:

src/fileio.c:

DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0,
       doc: /* .... and `read-file-name-function'.  */)
     (prompt, dir, default_filename, mustmatch, initial, predicate)
     Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate;
{
  ...
    if (NILP (dir))
      dir = current_buffer->directory;

and src/buffer.c:


  DEFVAR_PER_BUFFER ("default-directory", &current_buffer->directory,
		     make_number (Lisp_String),
		     doc: /* ... */);

> If it works right for that reason, there should be a comment to
> explain.

I attached a new patch of function with some additional comments, and
for manual/docs. Please have a look a this.

Index: doc/emacs/files.texi
===================================================================
RCS file: /sources/emacs/emacs/doc/emacs/files.texi,v
retrieving revision 1.14
diff -u -r1.14 files.texi
--- doc/emacs/files.texi	20 Oct 2007 04:24:25 -0000	1.14
+++ doc/emacs/files.texi	18 Nov 2007 22:50:17 -0000
@@ -492,9 +492,10 @@
 (except that @kbd{C-x C-w} asks for confirmation if the file exists).
 @kbd{C-x C-s} used on a buffer that is not visiting a file has the
 same effect as @kbd{C-x C-w}; that is, it reads a file name, marks the
-buffer as visiting that file, and saves it there.  The default file name in
-a buffer that is not visiting a file is made by combining the buffer name
-with the buffer's default directory (@pxref{File Names}).
+buffer as visiting that file, and saves it there.  Is directory of file
+does not exist, you are asked for creating them. The default file
+name in a buffer that is not visiting a file is made by combining the
+buffer name with the buffer's default directory (@pxref{File Names}).
 
   If the new file name implies a major mode, then @kbd{C-x C-w} switches
 to that major mode, in most cases.  The command


Index: doc/lispref/files.texi
===================================================================
RCS file: /sources/emacs/emacs/doc/lispref/files.texi,v
retrieving revision 1.2
diff -u -r1.2 files.texi
--- doc/lispref/files.texi	6 Sep 2007 04:27:42 -0000	1.2
+++ doc/lispref/files.texi	18 Nov 2007 22:50:40 -0000
@@ -355,12 +355,13 @@
 @end deffn
 
 @deffn Command write-file filename &optional confirm
-@anchor{Definition of write-file}
-This function writes the current buffer into file @var{filename}, makes
-the buffer visit that file, and marks it not modified.  Then it renames
-the buffer based on @var{filename}, appending a string like @samp{<2>}
-if necessary to make a unique buffer name.  It does most of this work by
-calling @code{set-visited-file-name} (@pxref{Buffer File Name}) and
+@anchor{Definition of write-file} 
+This function writes the current buffer into file @var{filename},
+thereby creates all parent directories if necessary, makes the buffer
+visit that file, and marks it not modified.  Then it renames the buffer
+based on @var{filename}, appending a string like @samp{<2>} if necessary
+to make a unique buffer name.  It does most of this work by calling
+@code{set-visited-file-name} (@pxref{Buffer File Name}) and
 @code{save-buffer}.
 
 If @var{confirm} is non-@code{nil}, that means to ask for confirmation
@@ -370,7 +371,8 @@
 If @var{filename} is an existing directory, or a symbolic link to one,
 @code{write-file} uses the name of the visited file, in directory
 @var{filename}.  If the buffer is not visiting a file, it uses the
-buffer name instead.
+buffer name instead.  Interactively, the user is asked for
+creating of all parent directories of output file.
 @end deffn
 
   Saving a buffer runs several hooks.  It also performs format

Index: lisp/files.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/files.el,v
retrieving revision 1.941
diff -u -r1.941 files.el
--- lisp/files.el	16 Nov 2007 08:03:45 -0000	1.941
+++ lisp/files.el	18 Nov 2007 22:53:04 -0000
@@ -3075,8 +3075,10 @@
 the default file name but in that directory.  You can also yank
 the default file name into the minibuffer to edit it, using \\<minibuffer-local-map>\\[next-history-element].
 
-If the buffer is not already visiting a file, the default file name
-for the output file is the buffer name.
+If the buffer is not already visiting a file, the default file
+name for the output file is the buffer name. Are parent
+directories of output file not existent, the functon asks user
+for creating those.  Noninteractively this happens by default.
 
 If optional second arg CONFIRM is non-nil, this function
 asks for confirmation before overwriting an existing file.
@@ -3086,14 +3088,25 @@
    (list (if buffer-file-name
 	     (read-file-name "Write file: "
 			     nil nil nil nil)
-	   (read-file-name "Write file: " default-directory
-			   (expand-file-name
-			    (file-name-nondirectory (buffer-name))
-			    default-directory)
-			   nil nil))
+	   ;; If buffer name has directory parts, propose this
+	   ;; directory path for writing. Otherwise DIR is nil and we
+	   ;; use `default-directory' by default.
+	   (let ((dir  (file-name-directory (buffer-name)))
+		 (file (file-name-nondirectory (buffer-name))))
+	     (read-file-name "Write file: "
+			     dir (expand-file-name file dir) nil nil)))
 	 (not current-prefix-arg)))
   (or (null filename) (string-equal filename "")
       (progn
+	;; If directory of file is not existent, create it with all parents.
+	(let ((dir (file-name-directory filename)))
+	  (when (and dir (not (file-exists-p dir)))
+	    (and (interactive-p)
+		 (or (y-or-n-p
+		      (format "Directory `%s' does not exist; create? " dir))
+		     (error "Canceled")))
+	    (make-directory dir 'parents)))
+
 	;; If arg is just a directory,
 	;; use the default file name, but in that directory.
 	(if (file-directory-p filename)
   
Index: src/fileio.c
===================================================================
RCS file: /sources/emacs/emacs/src/fileio.c,v
retrieving revision 1.594
diff -u -r1.594 fileio.c
--- src/fileio.c	21 Oct 2007 10:53:16 -0000	1.594
+++ src/fileio.c	18 Nov 2007 22:54:52 -0000
@@ -6349,6 +6349,7 @@
 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0,
        doc: /* Read file name, prompting with PROMPT and completing in directory DIR.
 Value is not expanded---you must call `expand-file-name' yourself.
+(If DIR is omitted or nil, the `default-directory' is used.)
 Default name to DEFAULT-FILENAME if user exits the minibuffer with
 the same non-empty string that was inserted by this function.
  (If DEFAULT-FILENAME is omitted, the visited file name is used,
  
-- 
Eduard Wiebe

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

* Re: patch: write-file to arbitrary target directory
  2007-11-19  0:01       ` Eduard Wiebe
@ 2007-11-22  2:28         ` Richard Stallman
  0 siblings, 0 replies; 16+ messages in thread
From: Richard Stallman @ 2007-11-22  2:28 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

    >     And if DIR is nil, read-file-name use 'default-directory'
    >anyway.  (If i am not mistaken.)
    >
    > Please double-check.

    It is so. Compare itself:

Ok, I agree.

Is anyone opposed to installing this patch?


I attached a new patch of function with some additional comments, and
for manual/docs. Please have a look a this.

Index: doc/emacs/files.texi
===================================================================
RCS file: /sources/emacs/emacs/doc/emacs/files.texi,v
retrieving revision 1.14
diff -u -r1.14 files.texi
--- doc/emacs/files.texi	20 Oct 2007 04:24:25 -0000	1.14
+++ doc/emacs/files.texi	18 Nov 2007 22:50:17 -0000
@@ -492,9 +492,10 @@
 (except that @kbd{C-x C-w} asks for confirmation if the file exists).
 @kbd{C-x C-s} used on a buffer that is not visiting a file has the
 same effect as @kbd{C-x C-w}; that is, it reads a file name, marks the
-buffer as visiting that file, and saves it there.  The default file name in
-a buffer that is not visiting a file is made by combining the buffer name
-with the buffer's default directory (@pxref{File Names}).
+buffer as visiting that file, and saves it there.  Is directory of file
+does not exist, you are asked for creating them. The default file
+name in a buffer that is not visiting a file is made by combining the
+buffer name with the buffer's default directory (@pxref{File Names}).
 
   If the new file name implies a major mode, then @kbd{C-x C-w} switches
 to that major mode, in most cases.  The command


Index: doc/lispref/files.texi
===================================================================
RCS file: /sources/emacs/emacs/doc/lispref/files.texi,v
retrieving revision 1.2
diff -u -r1.2 files.texi
--- doc/lispref/files.texi	6 Sep 2007 04:27:42 -0000	1.2
+++ doc/lispref/files.texi	18 Nov 2007 22:50:40 -0000
@@ -355,12 +355,13 @@
 @end deffn
 
 @deffn Command write-file filename &optional confirm
-@anchor{Definition of write-file}
-This function writes the current buffer into file @var{filename}, makes
-the buffer visit that file, and marks it not modified.  Then it renames
-the buffer based on @var{filename}, appending a string like @samp{<2>}
-if necessary to make a unique buffer name.  It does most of this work by
-calling @code{set-visited-file-name} (@pxref{Buffer File Name}) and
+@anchor{Definition of write-file} 
+This function writes the current buffer into file @var{filename},
+thereby creates all parent directories if necessary, makes the buffer
+visit that file, and marks it not modified.  Then it renames the buffer
+based on @var{filename}, appending a string like @samp{<2>} if necessary
+to make a unique buffer name.  It does most of this work by calling
+@code{set-visited-file-name} (@pxref{Buffer File Name}) and
 @code{save-buffer}.
 
 If @var{confirm} is non-@code{nil}, that means to ask for confirmation
@@ -370,7 +371,8 @@
 If @var{filename} is an existing directory, or a symbolic link to one,
 @code{write-file} uses the name of the visited file, in directory
 @var{filename}.  If the buffer is not visiting a file, it uses the
-buffer name instead.
+buffer name instead.  Interactively, the user is asked for
+creating of all parent directories of output file.
 @end deffn
 
   Saving a buffer runs several hooks.  It also performs format

Index: lisp/files.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/files.el,v
retrieving revision 1.941
diff -u -r1.941 files.el
--- lisp/files.el	16 Nov 2007 08:03:45 -0000	1.941
+++ lisp/files.el	18 Nov 2007 22:53:04 -0000
@@ -3075,8 +3075,10 @@
 the default file name but in that directory.  You can also yank
 the default file name into the minibuffer to edit it, using \\<minibuffer-local-map>\\[next-history-element].
 
-If the buffer is not already visiting a file, the default file name
-for the output file is the buffer name.
+If the buffer is not already visiting a file, the default file
+name for the output file is the buffer name. Are parent
+directories of output file not existent, the functon asks user
+for creating those.  Noninteractively this happens by default.
 
 If optional second arg CONFIRM is non-nil, this function
 asks for confirmation before overwriting an existing file.
@@ -3086,14 +3088,25 @@
    (list (if buffer-file-name
 	     (read-file-name "Write file: "
 			     nil nil nil nil)
-	   (read-file-name "Write file: " default-directory
-			   (expand-file-name
-			    (file-name-nondirectory (buffer-name))
-			    default-directory)
-			   nil nil))
+	   ;; If buffer name has directory parts, propose this
+	   ;; directory path for writing. Otherwise DIR is nil and we
+	   ;; use `default-directory' by default.
+	   (let ((dir  (file-name-directory (buffer-name)))
+		 (file (file-name-nondirectory (buffer-name))))
+	     (read-file-name "Write file: "
+			     dir (expand-file-name file dir) nil nil)))
 	 (not current-prefix-arg)))
   (or (null filename) (string-equal filename "")
       (progn
+	;; If directory of file is not existent, create it with all parents.
+	(let ((dir (file-name-directory filename)))
+	  (when (and dir (not (file-exists-p dir)))
+	    (and (interactive-p)
+		 (or (y-or-n-p
+		      (format "Directory `%s' does not exist; create? " dir))
+		     (error "Canceled")))
+	    (make-directory dir 'parents)))
+
 	;; If arg is just a directory,
 	;; use the default file name, but in that directory.
 	(if (file-directory-p filename)
   
Index: src/fileio.c
===================================================================
RCS file: /sources/emacs/emacs/src/fileio.c,v
retrieving revision 1.594
diff -u -r1.594 fileio.c
--- src/fileio.c	21 Oct 2007 10:53:16 -0000	1.594
+++ src/fileio.c	18 Nov 2007 22:54:52 -0000
@@ -6349,6 +6349,7 @@
 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0,
        doc: /* Read file name, prompting with PROMPT and completing in directory DIR.
 Value is not expanded---you must call `expand-file-name' yourself.
+(If DIR is omitted or nil, the `default-directory' is used.)
 Default name to DEFAULT-FILENAME if user exits the minibuffer with
 the same non-empty string that was inserted by this function.
  (If DEFAULT-FILENAME is omitted, the visited file name is used,
  
-- 
Eduard Wiebe

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

end of thread, other threads:[~2007-11-22  2:28 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-17  1:09 patch: write-file to arbitrary target directory Eduard Wiebe
2007-11-17  1:34 ` Juri Linkov
2007-11-17  4:28 ` Stefan Monnier
2007-11-17  9:22   ` Eli Zaretskii
2007-11-17 13:14     ` Eduard Wiebe
2007-11-17 12:36       ` Eli Zaretskii
2007-11-17 13:03         ` Thien-Thi Nguyen
2007-11-17 22:04         ` Eduard Wiebe
2007-11-17 23:31   ` Richard Stallman
2007-11-17  9:34 ` martin rudalics
2007-11-17 13:15   ` Eduard Wiebe
2007-11-17 17:42 ` Richard Stallman
2007-11-17 23:22   ` Eduard Wiebe
     [not found]   ` <861waobh7m.fsf@nirvana.pusto.de>
2007-11-18 13:01     ` Richard Stallman
2007-11-19  0:01       ` Eduard Wiebe
2007-11-22  2:28         ` Richard Stallman

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).