`delete-directory`中的问题启用了`delete-by-removal-to-trash`

时间:2010-04-06 08:33:39

标签: emacs elisp dired

启用标记delete-directory的{​​{1}}函数存在奇怪的行为。它逐个删除文件,而不是将delete-by-removing-to-trash应用于目录。因此,emacs会在那里缓慢删除大目录 删除后垃圾箱中有很多文件,因此无法恢复目录。

实施例: 目录结构:

move-file-to-trash

删除ddd/ ccc/ 1.txt 后,垃圾箱中有三个文件:

ddd

而不是一个:

trash/
    ddd/
    ccc/
    1.txt
  • 这很慢,因为emacs递归遍历目录。
  • 我无法恢复已删除的目录。

我需要的是与trash/ ddd/ 完全相同的行为。但它应该是透明的(即直接模式下的'D x')。如何解决问题?作为临时解决方案,我看到了`delete-directory'的制作建议功能。

3 个答案:

答案 0 :(得分:1)

作为临时解决方法,我使用:

(setq delete-by-moving-to-trash t)

(defadvice dired-delete-file (around
                              activate-move-to-trash
                              activate
                              compile)
  (if delete-by-moving-to-trash
      (move-file-to-trash (ad-get-arg 0))
    ad-do-it))

答案 1 :(得分:1)

这是我的整个系统。如果你看看底部,你会看到与安德烈的defadvice几乎相同。

;;; trash-settings.el - Intelligent integration with system trash

;; Use the system trash, except for temp files and stuff
(require 'cl)

(defcustom system-trash-exclude-names
  nil
  "List of file names to exclude from system trash.
The names in this variable are matched only against the basename
of the file to be deleted."
  :type '(repeat string)
  :group 'trash)

(defcustom system-trash-exclude-paths
  nil
  "List of absolute paths to exclude from system trash.
If a path to a directory is excluded, then all the contents of that directory are also excluded."
  :type '(repeat string)
  :group 'trash)

(defcustom system-trash-exclude-matches
  nil
  "List of regexps or functions matching file names to exclude from system trash.
The matches are only applied against the file name, not the path."
  :type '(repeat (choice regexp function))
  :group 'trash)

(defcustom system-trash-exclude-path-matches
  nil
  "List of regexps or functions matching paths to exclude from system trash.
The matches are applied against the full path."
  :type '(repeat (choice regexp function))
  :group 'trash)

(defun call-process-discard-output (program &rest args)
  "Execute program with args without saving any output.
In particular, no temp files are created."
  (eval (append `(call-process ,program nil nil nil) args)))

(defun string-begins-with-p (string beginning)
  "Return t if and only if string begins with beginning"
  (string-match-p (concat "^" (regexp-quote beginning)) string))

(defun file-excluded-from-system-trash-p (path)
  "Returns non-nil if file name is excluded from trash."
  (let ((basename (file-name-nondirectory path)))
    (or
     (some (apply-partially 'string= basename)
           system-trash-exclude-names)
     (some (apply-partially 'string-begins-with-p path)
           system-trash-exclude-paths)
     (some (lambda (match)
             (funcall
              (cond ((stringp match) 'string-match-p)
                    ((functionp protected-match) 'funcall)
                    (t 'ignore))
              match
              basename))
           system-trash-exclude-matches)
     (some (lambda (match)
             (funcall
              (cond ((stringp match) 'string-match-p)
                    ((functionp protected-match) 'funcall)
                    (t 'ignore))
              match
              path))
           system-trash-exclude-path-matches))))

(defun trash-or-rm (filename)
  "Attempt to move a file to the trash. If this fails, simply delete it.
This guarantees that any deletable file will either be trashed or deleted.
If the file is excluded from the trash, it is simply deleted."
  (unless (file-excluded-from-system-trash-p filename)
    (ignore-errors
      (call-process-discard-output "gvfs-trash" filename)))
  (when (file-exists-p filename)
    (call-process-discard-output "rm" "-rf" filename)))

(defalias 'system-move-file-to-trash 'trash-or-rm)

(defadvice delete-directory (around no-recursive-trash activate)
  "When trashing a directory, there's no need to trash its contents first."
  (if delete-by-moving-to-trash
    (move-file-to-trash directory)
    ad-do-it))

(defadvice dired-delete-file (around no-recursive-trash activate)
  "When trashing a directory, there's no need to trash its contents first.
There's also no need to ask, because it's undoable."
  (if delete-by-moving-to-trash
      (move-file-to-trash file)
    ad-do-it))

编辑:我应该提一下,我上面的解决方案需要与GNOME相关联的gvfs-trash命令行程序。如果您不使用GNOME,可以使用trash-cli包中的trash替换它。

答案 2 :(得分:0)

我的“回答”是:M-x report-emacs-bug。 Bug报告可以帮助每个人Emacs Dev将确定是否存在实际错误,所涉及的每个人都将从报告中学习。