emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

file name handlers and Fload


From: Noah Friedman
Subject: file name handlers and Fload
Date: Fri, 08 Dec 2000 16:00:15 -0800 (PST)

This problem is still frequently biting me in emacs 21, and I am becoming
highly frustrated that setup hooks and the like don't run when they should.

The more I think about it, the more I think the right thing to do is use
the basename (i.e. file name sans directory or extension) of the loaded
file as the key into after-load-alist, and not to compare full file names.

Thoughts?
--- Begin Message --- Subject: emacs 20.4, file name handlers, and load Date: Thu, 21 Oct 1999 02:30:12 -0700 (PDT)
Emacs 20 has an obscure new feature in the handling of file names to load
that does not interact well with file name handlers and after-load-alist.

In the first attachment is the definition of dired-handler-fn, which is a
catch-all file name handler active whenever a dired buffer exists; it's
entry in file-name-handler-alist is

      ("." . dired-handler-fn)

This function comes from Dired 7.9, which is the version of dired which
goes together with EFS 1.16.  The reason it is so aggressive is that when a
dired buffer is active, it wants to have the opportunity to update dired
buffers automatically (and do other things) when some operation like
rename-file is performed.

The second attachment is my workaround using defadvice.  What it does is to
notice if the requested operation is `load' and if so, temporarily rebind
file-name-handler-alist with the entry for dired-handler-fn removed so that
the function `openp' will be less likely to find a handler for the full
name of the file that is looked up in load-path.  This insures that the
forms in after-load-alist will be evaluated.

What is the proper solution for all this?  My opinion is that Fload should
somehow keep track of the original `file' argument even if called
recursively via a file name handler with a fully-qualified file name.  That
way after-load-alist will retain its historical semantics.  But I'm not
sure of the cleanest way to do this.  The second best alternative I can
think of is always to strip the directory name and file extension from the
key to look up in after-load-alist.  I've never encountered a case where
someone deliberately keeps two files with the name name in the load-path
and want to have different after-load forms for each, so I think this would
be a safe thing to do.  But the first alternative would retain backward
compatibility if this is a concern.
(defun dired-handler-fn (op &rest args)
  ;; Function to update dired buffers after I/O.
  (prog1
      (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))
    (let ((dired-omit-silent t)
          (hf (get op 'dired)))
      (and hf (funcall hf args)))))
(defadvice dired-handler-fn (around workaround-remote-load activate)
  "Prevent Emacs 20.4 `Fload' from assuming that file is remote when this
handler is active.

This handler is only active when there is at least one dired buffer; when
the last dired buffer is killed, this handler is removed from
`file-name-handler-alist'.  This handler claims to handle every file when
it is active.

The primitive function `Fload' calls `openp' to look up the file name in
`load-path'.  Once `openp' finds the full name, it makes another call to
`Ffind_file_name_handler' to decide whether the file is \"remote\" or not;
if a handler is found, the file is considered remote and the function
returns the special value 0.  When `Fload' sees this value, it looks up the
file name handler on the full file name; in most cases that willl
ultimately bottom out in another call to `Fload' with the full file name as
the file to load because the file is actually local.

This is all well and good, but it ruins the ability to put expressions in
`Vafter_load_alist' and expect them to be evaluated, because the key in
this alist must exactly match the file name loaded.

I am not sure what the correct fix is here.  Perhaps `openp' is making too
naive a decision about local vs. remote files.  Perhaps `Fload' should
strip the directory name and file extension when doing its assoc on
`Vafter_load_alist', or at least keep track of the original user-specified
file name; a user who calls (load \"foo\") should have the after-load
forms for \"foo\" be evaluated even if the file is actually loaded by a
special handler \(e.g. ange-ftp\)."
  (cond ((eq (ad-get-arg 0) 'load)
         (let* ((file-name-handler-alist (copy-alist file-name-handler-alist))
                (elt (rassq 'dired-handler-fn file-name-handler-alist)))
           (setq file-name-handler-alist (delq elt file-name-handler-alist))
           ad-do-it))
        (t
         ad-do-it)))

--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]