support directories in spacemacs/rename-file

1. Fix `short-name` for directories. Previously it was empty string.
2. Remove redundant check for existing buffer:
   1. `(get-buffer new-name)` always return `nil`, because `new-name` is a path
      to file, not a file name.
   2. `(find-file new-name)` handles this situation.
   3. `dired-rename-file` handles this situation as well.
3. Use `dired-rename-file` to do the dirty stuff.
   1. Renames files and directories.
   2. All associated buffers are updated. If you rename a directory, all buffers
      that were visiting files from that directory now visit files from new
      directory.
4. Properly handle recentf list update for directories - all files from the
   renamed directory are removed from recentf list and the same files but from
   new directory are added back.
This commit is contained in:
Boris Buliga 2018-10-18 10:44:50 +03:00
parent ff86c724b2
commit 69a1e056ff
No known key found for this signature in database
GPG Key ID: 027328150F064FA8
1 changed files with 39 additions and 24 deletions

View File

@ -275,32 +275,47 @@ Dedicated (locked) windows are left untouched."
When NEW-FILENAME is not specified, asks user for a new name.
Also renames associated buffer (if any exists), invalidates
projectile cache when it's possible and update recentf list."
Also renames associated buffers (if any exists), invalidates
projectile cache and updates recentf list."
(interactive "f")
(when (and filename (file-exists-p filename))
(let* ((buffer (find-buffer-visiting filename))
(short-name (file-name-nondirectory filename))
(new-name (if new-filename new-filename
(read-file-name
(format "Rename %s to: " short-name)))))
(cond ((get-buffer new-name)
(error "A buffer named '%s' already exists!" new-name))
(t
(let ((dir (file-name-directory new-name)))
(when (and (not (file-exists-p dir)) (yes-or-no-p (format "Create directory '%s'?" dir)))
(make-directory dir t)))
(rename-file filename new-name 1)
(when buffer
(kill-buffer buffer)
(find-file new-name))
(when (fboundp 'recentf-add-file)
(recentf-add-file new-name)
(recentf-remove-if-non-kept filename))
(when (and (configuration-layer/package-used-p 'projectile)
(projectile-project-p))
(call-interactively #'projectile-invalidate-cache))
(message "File '%s' successfully renamed to '%s'" short-name (file-name-nondirectory new-name)))))))
(let* ((is-dir (file-directory-p filename))
(short-name
(if is-dir
(file-name-base (directory-file-name filename))
(file-name-nondirectory filename)))
(new-filename
(if new-filename new-filename
(read-file-name
(format "Rename %s to: " short-name)))))
;; Rename filename to new-filename and error if new-filename already
;; exists. `dired-rename-file' handles renaming of directories and files.
;; It updates the name of all associated buffers.
(dired-rename-file filename new-filename nil)
;; Update recentf list.
(when (fboundp 'recentf-add-file)
(seq-map
(lambda (fp)
(recentf-add-file
(concat new-filename (string-remove-prefix filename fp)))
(recentf-remove-if-non-kept fp))
(seq-filter
(lambda (fp)
(string-prefix-p filename fp))
recentf-list)))
;; Invalidate projectile cache.
(when (and (configuration-layer/package-used-p 'projectile)
(projectile-project-p))
(call-interactively #'projectile-invalidate-cache))
;; Inform user about tremendous success.
(message "%s '%s' successfully renamed to '%s'"
(if is-dir "Directory" "File")
short-name
(file-name-nondirectory new-filename)))))
;; from magnars
(defun spacemacs/rename-current-buffer-file (&optional arg)