From 10a7615b5d45bcd909bb03d67423b337dfe93b1e Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 6 Aug 2023 07:00:22 -0400 Subject: [PATCH] Separate filename-deletion mechanism from policy. src/fileio.c: (delete-file-internal) Renamed from delete-file, parallel to delete-directory-internal; policy code moved to Lisp. src/files.el: (delete-file) New function, holds policy logic. calls delete-file-internal. This is a pure refactoring step, delete-file's behavior is unchanged. But the C core is a little simpler now. --- lisp/files.el | 20 ++++++++++++++++++++ src/fileio.c | 40 +++++++++------------------------------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index f8867432000..84a8c308b09 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6352,6 +6352,26 @@ non-nil and if FN fails due to a missing file or directory." (apply fn args) (file-missing (or no-such (signal (car err) (cdr err)))))) +(defun delete-file (filename &optional trash) + "Delete file named FILENAME. If it is a symlink, remove the symlink. +If file has multiple names, it continues to exist with the other names.q +TRASH non-nil means to trash the file instead of deleting, provided +`delete-by-moving-to-trash' is non-nil. + +When called interactively, TRASH is t if no prefix argument is given. +With a prefix argument, TRASH is nil." + (interactive (list (read-file-name + (if (and delete-by-moving-to-trash (null current-prefix-arg)) + "Move file to trash: " "Delete file: ") + nil default-directory (confirm-nonexistent-file-or-buffer)) + (null current-prefix-arg))) + (if (and (file-directory-p filename) (not (file-symlink-p filename))) + (signal 'file-error (list "Removing old name: is a directory" filename))) + (let* ((filename (expand-file-name filename)) (handler (find-file-name-handler filename 'delete-file))) + (cond (handler (funcall handler 'delete-file filename trash)) + ((and delete-by-moving-to-trash trash) (move-file-to-trash filename)) + (t (delete-file-internal filename))))) + (defun delete-directory (directory &optional recursive trash) "Delete the directory named DIRECTORY. Does not follow symlinks. If RECURSIVE is non-nil, delete files in DIRECTORY as well, with diff --git a/src/fileio.c b/src/fileio.c index 63f4e698528..e49a4a3836b 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2462,38 +2462,13 @@ DEFUN ("delete-directory-internal", Fdelete_directory_internal, return Qnil; } -DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 2, - "(list (read-file-name \ - (if (and delete-by-moving-to-trash (null current-prefix-arg)) \ - \"Move file to trash: \" \"Delete file: \") \ - nil default-directory (confirm-nonexistent-file-or-buffer)) \ - (null current-prefix-arg))", +DEFUN ("delete-file-internal", Fdelete_file_internal, Sdelete_file_internal, 1, 1, 0, doc: /* Delete file named FILENAME. If it is a symlink, remove the symlink. -If file has multiple names, it continues to exist with the other names. -TRASH non-nil means to trash the file instead of deleting, provided -`delete-by-moving-to-trash' is non-nil. - -When called interactively, TRASH is t if no prefix argument is given. -With a prefix argument, TRASH is nil. */) - (Lisp_Object filename, Lisp_Object trash) +If file has multiple names, it continues to exist with the other names. */) + (Lisp_Object filename) { - Lisp_Object handler; Lisp_Object encoded_file; - if (!NILP (Ffile_directory_p (filename)) - && NILP (Ffile_symlink_p (filename))) - xsignal2 (Qfile_error, - build_string ("Removing old name: is a directory"), - filename); - filename = Fexpand_file_name (filename, Qnil); - - handler = Ffind_file_name_handler (filename, Qdelete_file); - if (!NILP (handler)) - return call3 (handler, Qdelete_file, filename, trash); - - if (delete_by_moving_to_trash && !NILP (trash)) - return call1 (Qmove_file_to_trash, filename); - encoded_file = ENCODE_FILE (filename); if (unlink (SSDATA (encoded_file)) != 0 && errno != ENOENT) @@ -2725,7 +2700,7 @@ This is what happens in interactive use with M-x. */) if (dirp) call2 (Qdelete_directory, file, Qt); else - Fdelete_file (file, Qnil); + call2 (Qdelete_file, file, Qnil); return unbind_to (count, Qnil); } @@ -6346,7 +6321,7 @@ syms_of_fileio (void) DEFSYM (Qcopy_file, "copy-file"); DEFSYM (Qmake_directory_internal, "make-directory-internal"); DEFSYM (Qmake_directory, "make-directory"); - DEFSYM (Qdelete_file, "delete-file"); + DEFSYM (Qdelete_file_internal, "delete-file-internal"); DEFSYM (Qfile_name_case_insensitive_p, "file-name-case-insensitive-p"); DEFSYM (Qrename_file, "rename-file"); DEFSYM (Qadd_name_to_file, "add-name-to-file"); @@ -6610,6 +6585,9 @@ This includes interactive calls to `delete-file' and delete_by_moving_to_trash = 0; DEFSYM (Qdelete_by_moving_to_trash, "delete-by-moving-to-trash"); + /* Lisp function for interactive file delete with trashing */ + DEFSYM (Qdelete_file, "delete-file"); + /* Lisp function for moving files to trash. */ DEFSYM (Qmove_file_to_trash, "move-file-to-trash"); @@ -6641,7 +6619,7 @@ This includes interactive calls to `delete-file' and defsubr (&Scopy_file); defsubr (&Smake_directory_internal); defsubr (&Sdelete_directory_internal); - defsubr (&Sdelete_file); + defsubr (&Sdelete_file_internal); defsubr (&Sfile_name_case_insensitive_p); defsubr (&Srename_file); defsubr (&Sadd_name_to_file); -- 2.39.2