Re: [19.25, efs 1.9] dired-handler-fn
Denis Howe (dbh@doc.ic.ac.uk)
Mon, 18 Jul 94 11:39:57 BST
Sandy decided:
> What I've decided to do for the next release is try my best to
> optimize the dired-handler-fn.
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.
))
Even compiled with the optimising byte-compiler this still gives a
noticable delay.
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.
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.
dired-handler-fn only really wants to hear about each file name *once*
but if the first op triggers some (recursive) sequence of ops then
dired-handler-fn gets called over and over again for the same file
name (or parts of it). The current inhibition scheme is only designed
to stop the same handler getting called again immediately as soon as
it tries to call the "real" op. This is essential to prevent an
infinite loop but doesn't stop multiple calls to the same handler.
Other kinds of handler would need to know about every op in a
recursive sequence so it would be wrong for them to remove themselves
from f-n-h-alist in this way but for dired's current purposes, I think
it is the Right Thing (and simple!).
This is orthogonal to (but much more important than) the other
optimisations we have been discussing - ie. removing d-h-fn from
f-n-h-alist when it is not needed and only calling handlers for
operations they are interested in.
A minor point: I think the current d-h-fn calls itself via
expand-file-name which is completely unnecessary. My version avoids
this.
--
Denis Howe <dbh@doc.ic.ac.uk>
Free On-Line Dictionary of Computing
WWW URL http://wombat.doc.ic.ac.uk/