Closed jcguu95 closed 1 year ago
I think the problem is with the async nature of the function you wrote. Most likely what happens is that you call dired-do-redisplay
before the file is deleted. So the file is included in the directory listing. However it get deleted before the file is accessed to get some extra information about it.
If you want to use such an async function, the proper way would be to use make-process
with a sentinel that call dired-do-redisplay
when the process actually finishes.
If the problem is not async command, you might need to revert buffer after deletion instead of dired-do-redisplay
.
Thanks for your hint. I need to use sentinel and #'revert-buffer
indeed.
For those who are curious, here's the code I use at the end.
(defun dired/funcall-on-marked-files (fn)
(let ((files (dired-get-marked-files
t current-prefix-arg nil nil t)))
(funcall fn files)))
(defun dired/async/trash-marked-files ()
"Interactively trash-put dired marked files."
(interactive)
(cl-flet ((async/trash-files
(files)
(let ((command `("trash-put"
,@(mapcar (lambda (x)
(format "%s" x))
files))))
(message (format "Running command: %S" command))
;; more sophisticated than #'async-shell-command
(make-process
:name "dired/async-trash-marked-files"
:command command
:buffer (get-buffer "*Messages*")
:sentinel (lambda (proc type)
(declare (ignore (proc type)))
(revert-buffer))))))
(dired/funcall-on-marked-files #'async/trash-files)))
:sentinel (lambda (proc type) (declare (ignore (proc type))) (revert-buffer))))))
This is a bit dangerous for long running async commands since if you switch buffer for whatever reason before the command finishes, wrong buffer will be reverted. It is better to let bind the current buffer at the start and then do,
(with-current-buffer buf (revert-buffer))
Where buf
is the let bound symbol.
@aikrahguzar I see what you mean. But it seems that the sentinel has its own environment.
For example, the following code invokes an error when the sentinel is activated, as it still doesn't know what buf
means.
(defun dired/async/arXiv-helper-on-marked-files ()
"Interactively apply arXiv helper on dired marked files."
(interactive)
(cl-flet ((async/arXiv-helper-on-files
(files)
(let ((buf (current-buffer))
(command `("arXiv-helper" "-im"
,@(mapcar (lambda (x)
(format "%s" x))
files))))
(message (format "Running command: %S" command))
;; more sophisticated than #'async-shell-command
(make-process
:name "dired/async/arXiv-helper-on-marked-files"
:command command
:buffer (get-buffer "*Messages*")
:sentinel (lambda (proc type)
(declare (ignore (proc type)))
(with-current-buffer buf
(revert-buffer)))))))
(dired/funcall-on-marked-files #'async/arXiv-helper-on-files)))
@aikrahguzar I see what you mean. But it seems that the sentinel has its own environment.
For example, the following code invokes an error when the sentinel is activated, as it still doesn't know what
buf
means.
The issue is probably that you don't have lexical binding in the buffer where you are defining these. Adding
;; -*- lexical-binding: t; -*-
at the top of the file and reverting it should fix this.
Thank you for the bug report
dirvish
related packages.emacs -Q
.Bug description
I have a customize function to delete marked files at point. After that's done successfully, most of the time the entries do not get removed from dired immediately. The correct function to reload/redisplay the dired buffer seems to be
dired-do-redisplay
. However, when run that function right after deleting something (in this example,/tmp/virtual-machine.pdf
), I get the error as follows.Steps to reproduce
dired/async-trash-marked-files
.dired-do-redisplay
.Expected behavior
It's better to have the entry removed once its corresponding file is moved away (ranger does that).
When we called
dired-do-redisplay
, the entry should be away, and there shouldn't be any error.OS
MacOS
Emacs Version
28
Emacs Configurations
doomemacs
Error callstack