This should do more or less what you request.
(defun dired-duplicate-this-file ()
"Duplicate file on this line."
(interactive)
(let* ((this (dired-get-filename t))
(ctr 1)
(new (format "%s[%d]" this ctr)))
(while (file-exists-p new)
(setq ctr (1+ ctr)
new (format "%s[%d]" this ctr)))
(dired-copy-file this new nil))
(revert-buffer))
That copies a file foo
to foo[1]
, or foo[2]
if foo[1]
exists, etc.
If you want a different naming convention, e.g., foo Copy
, foo Copy (2)
, etc. then use something like this:
(defun dired-duplicate-this-file ()
"Duplicate file on this line."
(interactive)
(let* ((this (dired-get-filename t))
(ctr 1)
(new (format "%s Copy" this)))
(while (file-exists-p new)
(setq ctr (1+ ctr)
new (format "%s Copy (%d)" this ctr)))
(dired-copy-file this new nil))
(revert-buffer))
Of course, if you duplicate a file such as foo[2]
or foo Copy (2)
then you'll get files named like foo[2][1]
, foo[2][2]
, ... or foo Copy (2) Copy
, foo Copy (2) Copy (2)
, ...
And if your file has an extension, such as .txt
, then the new name will be something like foo.txt[1]
or foo.txt Copy
. Not sure if that's what you want. If not, you can use functions file-name-sans-extension
and file-name-extension
to move the extension after the number (if that's what you want), so you get foo[1].txt
or foo Copy.txt
. It all depends on what you want.
Function format
lets you specify the form you want. See C-h f format
for info.