Function: vc-delete-file

vc-delete-file is an autoloaded, interactive and byte-compiled function defined in vc.el.gz.

Signature

(vc-delete-file FILE-OR-FILES &optional NOCONFIRM)

Documentation

Delete file and mark it as such in the version control system.

If called interactively, read FILE-OR-FILES, defaulting to the current buffer's file name if it's under version control. When called from Lisp, FILE-OR-FILES can be a file name or a list of file names. When called from Lisp, optional argument NOCONFIRM non-nil means don't prompt to confirm deletion. For some VCS, FILE-OR-FILES can include directories. These are recursively deleted.

View in manual

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/vc/vc.el.gz
;;;###autoload
(defun vc-delete-file (file-or-files &optional noconfirm)
  "Delete file and mark it as such in the version control system.
If called interactively, read FILE-OR-FILES, defaulting to the current
buffer's file name if it's under version control.
When called from Lisp, FILE-OR-FILES can be a file name or a list of
file names.
When called from Lisp, optional argument NOCONFIRM non-nil means don't
prompt to confirm deletion.
For some VCS, FILE-OR-FILES can include directories.
These are recursively deleted."
  (interactive (list (read-file-name "VC delete file: " nil
                                     (and (vc-backend buffer-file-name)
                                          buffer-file-name)
                                     t)))
  (setq file-or-files (mapcar #'expand-file-name (ensure-list file-or-files)))
  (dolist (file file-or-files)
    (let ((buf (get-file-buffer file))
          (backend (if (file-directory-p file)
                       (vc-responsible-backend file)
                     (vc-backend file))))
      (unless (or (not backend)
                  (vc-find-backend-function backend 'delete-file))
        (error "Deleting files under %s is not supported in VC" backend))
      (when (and buf (buffer-modified-p buf))
        (error "Please save or undo your changes before deleting %s" file))
      (let ((state (vc-state file)))
        (when (eq state 'edited)
          (error "Please commit or undo your changes before deleting %s" file))
        (when (eq state 'conflict)
          (error "Please resolve the conflicts before deleting %s" file)))))
  (unless (or noconfirm
              (y-or-n-p (if (cdr file-or-files)
                            (format "Really want to delete these %d files? "
                                    (length file-or-files))
                          (format "Really want to delete %s? "
                                  (file-name-nondirectory (car file-or-files))))))
    (error "Abort!"))
  (let ((post-backend-deletion
         ;; Things to do after calling the backend's `delete-file' or
         ;; `delete-files' function on FILE, or after determing we're
         ;; not going to call any such function.
         (lambda (file)
           ;; For the case of unregistered files, or if the backend
           ;; didn't actually delete the file.
           (when-let* ((attrs (file-attributes file)))
             (if (eq t (car attrs))
                 (delete-directory file 'recursive)
               (delete-file file)))
           ;; Forget what VC knew about the file.
           (vc-file-clearprops file)
           ;; Make sure the buffer is killed and *vc-dir* buffers are
           ;; updated after this.
           (vc-resynch-buffer file nil t)))
        ;; Alist associating files to delete with their backends.
        deletions-by-backend)
    (dolist (file file-or-files)
      (let ((buf (get-file-buffer file))
            (backend (if (file-directory-p file)
                         (vc-responsible-backend file)
                       (vc-backend file))))
        (unless (or (file-directory-p file)
                    (null make-backup-files)
                    (backup-file-name-p file)
                    (not (file-exists-p file)))
          (with-current-buffer (or buf (find-file-noselect file))
            (let ((backup-inhibited nil))
	      (backup-buffer))))
        (if backend
            (push file (alist-get backend deletions-by-backend
                                  nil nil #'eq))
          (funcall post-backend-deletion file))))
    (pcase-dolist (`(,backend . ,files) deletions-by-backend)
      (if-let* ((fn (vc-find-backend-function backend 'delete-files)))
          (let ((default-directory (vc-root-dir backend)))
            (funcall fn files)
            (mapc post-backend-deletion files))
        (dolist (file files)
          ;; Changing default directory like this has the problem that
          ;; the containing directory for FILE may no longer exists if
          ;; all files within it are already `missing', say.  But this
          ;; command has always bound `default-directory' like this
          ;; before calling BACKEND's `delete-file' function, so keep it
          ;; for compatibility.  --spwhitton
          (let ((default-directory (file-name-directory file)))
            (vc-call-backend backend 'delete-file file))
          (funcall post-backend-deletion file))))))