Re: [19.25, efs 1.9] dired-handler-fn
sandy@ibm550.sissa.it
Mon, 18 Jul 1994 13:11:11 +0200
>>>>> On Mon, 18 Jul 94 11:39:57 BST,
Denis Howe <dbh@doc.ic.ac.uk> said:
> I bet you can't optimise it more than this:
> (defun dired-handler-fn (op &rest args)
> "Not the real one."
> (let ((inhibit-file-name-handlers
> (cons 'dired-handler-fn
> (and (eq inhibit-file-name-operation op)
> inhibit-file-name-handlers)))
> (inhibit-file-name-operation op))
> (apply op args)
> ;; DO ABSOLUTELY NOTHING.
> ))
No. ;-)
> Even compiled with the optimising byte-compiler this still gives a
> noticable delay.
I'm still puzzled by the delay that you see. For eg, on Emacs 18,
with all file-name-handler stuff in lisp overloads, I notice no delay.
I wonder if maybe while recursing, some file system calls are being
done somewhere and your NFS is a little slow? I don't usually use
NFS, so my disk access is fast. I'm not saying that the problem is in
your setup, but that maybe the problem is not the recursion per se,
but what emacs is doing while it recurses.
> On the other hand, this:
> (defun dired-handler-fn (op &rest args)
> "Update dired buffers after a file operation."
> (dired-check-file-name-handler-alist)
> (let* ((file-name-handler-alist ; Remove myself
> (delq nil (mapcar
> (function
> (lambda (x) (and (not (eq (cdr x) 'dired-handler-fn)) x)))
> file-name-handler-alist)))
> (result (apply op args)) ; Just do it!
> (dired-omit-silent t))
> (cond
> ((eq op 'copy-file)
> (dired-relist-file (expand-file-name (nth 1 args))))
> ((eq op 'rename-file)
> (dired-remove-file (expand-file-name (car args)))
> (dired-relist-file (expand-file-name (nth 1 args))))
> ((memq op '(add-name-to-file make-symbolic-link))
> (dired-relist-file (expand-file-name (nth 1 args))))
> ((eq op 'write-region)
> (dired-relist-file (expand-file-name (nth 2 args))))
> ((eq op 'delete-file)
> (dired-remove-file (expand-file-name (car args))))
> ((memq op '(delete-directory dired-recursive-delete-directory))
> (dired-remove-file (directory-file-name (car args))))
> ((memq op '(make-directory-internal set-file-modes))
> (dired-relist-file (expand-file-name (car args)))))
> result))
> is acceptably fast.
It may be fast, but it's buggy. If the OPERATION does non-trivial
things recursively that affect dired buffers, dired should know about
it.
> I don't think file name handlers are really supposed to modify
> file-name-handler-alist like this but neither do I think the current
> inhibition scheme (inhibit-file-name-{handlers,operation}) is ideal
> for dired-handler-fn.
I don't know about ideal, but dired-handler-fn needs to call the
original OPERATION recursively. The inhibit-... variables were
developed by Richard after an extensive (nearly a month) discussion
between Richard, other people (Jamie, Noah, Roland, Jay, and Andy were
in the loop), and myself. If there are better ideas out there, we
didn't find them. Note, this isn't a simple problem, and a lot of the
first guesses at what to do were buggy.
efs-1.7 (never got beyond alpha test, as it was used to check out the
new file-name-handler-alist stuff) had almost exactly what you wrote
for the dired-handler-fn. It didn't work. Yes, it worked in the
short term, but in the long term I noticed a lot of bugs.
> dired-handler-fn only really wants to hear about each file name *once*
No, this is not true. dired-handler-fn needs to know about every
write to disk, whether it's inside another op or not.
Supporting predicates (once again on my favourite theme;-) would avoid
handler functions recursing for operations about which they are not
interested. It would allow them to recurse for interesting ops
though, and this is needed.
--sandy