diff options
| author | Tino Calancha | 2018-08-02 13:20:46 +0900 |
|---|---|---|
| committer | Tino Calancha | 2018-08-02 13:20:46 +0900 |
| commit | e65ec81fc3e556719fae8d8b4b42f571c7e9f4fc (patch) | |
| tree | 9a7f094620535b860c27b0f1763ebd1e33ba0163 | |
| parent | d216d7d248199aa6c99cd642116717c5b301ae6d (diff) | |
| download | emacs-e65ec81fc3e556719fae8d8b4b42f571c7e9f4fc.tar.gz emacs-e65ec81fc3e556719fae8d8b4b42f571c7e9f4fc.zip | |
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.
| -rw-r--r-- | doc/emacs/dired.texi | 5 | ||||
| -rw-r--r-- | doc/lispref/files.texi | 8 | ||||
| -rw-r--r-- | etc/NEWS | 8 | ||||
| -rw-r--r-- | lisp/dired-aux.el | 37 | ||||
| -rw-r--r-- | lisp/dired.el | 3 | ||||
| -rw-r--r-- | lisp/files.el | 15 |
6 files changed, 70 insertions, 6 deletions
diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 007a943714a..1b03a3967aa 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi | |||
| @@ -1468,6 +1468,11 @@ rotation is lossless, and uses an external utility called | |||
| 1468 | directory's name, and creates that directory. It signals an error if | 1468 | directory's name, and creates that directory. It signals an error if |
| 1469 | the directory already exists. | 1469 | the directory already exists. |
| 1470 | 1470 | ||
| 1471 | @findex dired-create-empty-file | ||
| 1472 | The command (@code{dired-create-empty-file}) reads a | ||
| 1473 | file name, and creates that file. It signals an error if | ||
| 1474 | the file already exists. | ||
| 1475 | |||
| 1471 | @cindex searching multiple files via Dired | 1476 | @cindex searching multiple files via Dired |
| 1472 | @kindex M-s a C-s @r{(Dired)} | 1477 | @kindex M-s a C-s @r{(Dired)} |
| 1473 | @kindex M-s a M-C-s @r{(Dired)} | 1478 | @kindex M-s a M-C-s @r{(Dired)} |
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 068cf054437..25fabe1ea5b 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi | |||
| @@ -3005,10 +3005,16 @@ This command creates a directory named @var{dirname}. If | |||
| 3005 | @var{parents} is non-@code{nil}, as is always the case in an | 3005 | @var{parents} is non-@code{nil}, as is always the case in an |
| 3006 | interactive call, that means to create the parent directories first, | 3006 | interactive call, that means to create the parent directories first, |
| 3007 | if they don't already exist. | 3007 | if they don't already exist. |
| 3008 | |||
| 3009 | @code{mkdir} is an alias for this. | 3008 | @code{mkdir} is an alias for this. |
| 3010 | @end deffn | 3009 | @end deffn |
| 3011 | 3010 | ||
| 3011 | @deffn Command make-empty-file filename &optional parents | ||
| 3012 | This command creates an empty file named @var{filename}. | ||
| 3013 | As @code{make-directory}, this command creates parent directories | ||
| 3014 | if @var{parents} is non-@code{nil}. | ||
| 3015 | If @var{filename} already exists, this command signals an error. | ||
| 3016 | @end deffn | ||
| 3017 | |||
| 3012 | @deffn Command copy-directory dirname newname &optional keep-time parents copy-contents | 3018 | @deffn Command copy-directory dirname newname &optional keep-time parents copy-contents |
| 3013 | This command copies the directory named @var{dirname} to | 3019 | This command copies the directory named @var{dirname} to |
| 3014 | @var{newname}. If @var{newname} is a directory name, | 3020 | @var{newname}. If @var{newname} is a directory name, |
| @@ -185,6 +185,9 @@ This triggers to search the program on the remote host as indicated by | |||
| 185 | 185 | ||
| 186 | * Editing Changes in Emacs 27.1 | 186 | * Editing Changes in Emacs 27.1 |
| 187 | 187 | ||
| 188 | +++ | ||
| 189 | ** New command 'make-empty-file'. | ||
| 190 | |||
| 188 | --- | 191 | --- |
| 189 | ** New variable 'x-wait-for-event-timeout'. | 192 | ** New variable 'x-wait-for-event-timeout'. |
| 190 | This controls how long Emacs will wait for updates to the graphical | 193 | This controls how long Emacs will wait for updates to the graphical |
| @@ -222,6 +225,11 @@ navigation and editing of large files. | |||
| 222 | 225 | ||
| 223 | * Changes in Specialized Modes and Packages in Emacs 27.1 | 226 | * Changes in Specialized Modes and Packages in Emacs 27.1 |
| 224 | 227 | ||
| 228 | +++ | ||
| 229 | ** Dired | ||
| 230 | |||
| 231 | *** New command 'dired-create-empty-file'. | ||
| 232 | |||
| 225 | ** Change Logs and VC | 233 | ** Change Logs and VC |
| 226 | 234 | ||
| 227 | *** Recording ChangeLog entries doesn't require an actual file. | 235 | *** Recording ChangeLog entries doesn't require an actual file. |
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 925a7d50d6f..21ee50ce5cd 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el | |||
| @@ -1989,6 +1989,19 @@ Optional arg HOW-TO determines how to treat the target. | |||
| 1989 | dired-dirs))) | 1989 | dired-dirs))) |
| 1990 | 1990 | ||
| 1991 | 1991 | ||
| 1992 | |||
| 1993 | ;; We use this function in `dired-create-directory' and | ||
| 1994 | ;; `dired-create-empty-file'; the return value is the new entry | ||
| 1995 | ;; in the updated Dired buffer. | ||
| 1996 | (defun dired--find-topmost-parent-dir (filename) | ||
| 1997 | "Return the topmost nonexistent parent dir of FILENAME. | ||
| 1998 | FILENAME is a full file name." | ||
| 1999 | (let ((try filename) new) | ||
| 2000 | (while (and try (not (file-exists-p try)) (not (equal new try))) | ||
| 2001 | (setq new try | ||
| 2002 | try (directory-file-name (file-name-directory try)))) | ||
| 2003 | new)) | ||
| 2004 | |||
| 1992 | ;;;###autoload | 2005 | ;;;###autoload |
| 1993 | (defun dired-create-directory (directory) | 2006 | (defun dired-create-directory (directory) |
| 1994 | "Create a directory called DIRECTORY. | 2007 | "Create a directory called DIRECTORY. |
| @@ -1997,18 +2010,32 @@ If DIRECTORY already exists, signal an error." | |||
| 1997 | (interactive | 2010 | (interactive |
| 1998 | (list (read-file-name "Create directory: " (dired-current-directory)))) | 2011 | (list (read-file-name "Create directory: " (dired-current-directory)))) |
| 1999 | (let* ((expanded (directory-file-name (expand-file-name directory))) | 2012 | (let* ((expanded (directory-file-name (expand-file-name directory))) |
| 2000 | (try expanded) new) | 2013 | new) |
| 2001 | (if (file-exists-p expanded) | 2014 | (if (file-exists-p expanded) |
| 2002 | (error "Cannot create directory %s: file exists" expanded)) | 2015 | (error "Cannot create directory %s: file exists" expanded)) |
| 2003 | ;; Find the topmost nonexistent parent dir (variable `new') | 2016 | (setq new (dired--find-topmost-parent-dir expanded)) |
| 2004 | (while (and try (not (file-exists-p try)) (not (equal new try))) | ||
| 2005 | (setq new try | ||
| 2006 | try (directory-file-name (file-name-directory try)))) | ||
| 2007 | (make-directory expanded t) | 2017 | (make-directory expanded t) |
| 2008 | (when new | 2018 | (when new |
| 2009 | (dired-add-file new) | 2019 | (dired-add-file new) |
| 2010 | (dired-move-to-filename)))) | 2020 | (dired-move-to-filename)))) |
| 2011 | 2021 | ||
| 2022 | ;;;###autoload | ||
| 2023 | (defun dired-create-empty-file (file) | ||
| 2024 | "Create an empty file called FILE. | ||
| 2025 | Add a new entry for the new file in the Dired buffer. | ||
| 2026 | Parent directories of FILE are created as needed. | ||
| 2027 | If FILE already exists, signal an error." | ||
| 2028 | (interactive (list (read-file-name "Create empty file: "))) | ||
| 2029 | (let* ((expanded (expand-file-name file)) | ||
| 2030 | new) | ||
| 2031 | (if (file-exists-p expanded) | ||
| 2032 | (error "Cannot create file %s: file exists" expanded)) | ||
| 2033 | (setq new (dired--find-topmost-parent-dir expanded)) | ||
| 2034 | (make-empty-file file 'parents) | ||
| 2035 | (when new | ||
| 2036 | (dired-add-file new) | ||
| 2037 | (dired-move-to-filename)))) | ||
| 2038 | |||
| 2012 | (defun dired-into-dir-with-symlinks (target) | 2039 | (defun dired-into-dir-with-symlinks (target) |
| 2013 | (and (file-directory-p target) | 2040 | (and (file-directory-p target) |
| 2014 | (not (file-symlink-p target)))) | 2041 | (not (file-symlink-p target)))) |
diff --git a/lisp/dired.el b/lisp/dired.el index 1348df6934b..26a7449e039 100644 --- a/lisp/dired.el +++ b/lisp/dired.el | |||
| @@ -1802,6 +1802,9 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." | |||
| 1802 | (define-key map [menu-bar immediate create-directory] | 1802 | (define-key map [menu-bar immediate create-directory] |
| 1803 | '(menu-item "Create Directory..." dired-create-directory | 1803 | '(menu-item "Create Directory..." dired-create-directory |
| 1804 | :help "Create a directory")) | 1804 | :help "Create a directory")) |
| 1805 | (define-key map [menu-bar immediate create-empty-file] | ||
| 1806 | '(menu-item "Create Empty file..." dired-create-empty-file | ||
| 1807 | :help "Create an empty file")) | ||
| 1805 | (define-key map [menu-bar immediate wdired-mode] | 1808 | (define-key map [menu-bar immediate wdired-mode] |
| 1806 | '(menu-item "Edit File Names" wdired-change-to-wdired-mode | 1809 | '(menu-item "Edit File Names" wdired-change-to-wdired-mode |
| 1807 | :help "Put a Dired buffer in a mode in which filenames are editable" | 1810 | :help "Put a Dired buffer in a mode in which filenames are editable" |
diff --git a/lisp/files.el b/lisp/files.el index 6e4f6ca51b9..8057def5259 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -5519,6 +5519,21 @@ raised." | |||
| 5519 | (dolist (dir create-list) | 5519 | (dolist (dir create-list) |
| 5520 | (files--ensure-directory dir))))))) | 5520 | (files--ensure-directory dir))))))) |
| 5521 | 5521 | ||
| 5522 | (defun make-empty-file (filename &optional parents) | ||
| 5523 | "Create an empty file FILENAME. | ||
| 5524 | Optional arg PARENTS, if non-nil then creates parent dirs as needed. | ||
| 5525 | |||
| 5526 | If called interactively, then PARENTS is non-nil." | ||
| 5527 | (interactive | ||
| 5528 | (let ((filename (read-file-name "Create empty file: "))) | ||
| 5529 | (list filename t))) | ||
| 5530 | (when (and (file-exists-p filename) (null parents)) | ||
| 5531 | (signal 'file-already-exists `("File exists" ,filename))) | ||
| 5532 | (let ((paren-dir (file-name-directory filename))) | ||
| 5533 | (when (and paren-dir (not (file-exists-p paren-dir))) | ||
| 5534 | (make-directory paren-dir parents))) | ||
| 5535 | (write-region "" nil filename nil 0)) | ||
| 5536 | |||
| 5522 | (defconst directory-files-no-dot-files-regexp | 5537 | (defconst directory-files-no-dot-files-regexp |
| 5523 | "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*" | 5538 | "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*" |
| 5524 | "Regexp matching any file name except \".\" and \"..\".") | 5539 | "Regexp matching any file name except \".\" and \"..\".") |