I'd like to advice `require' in order to show which package is making the call
to require another one.
I tried using (current-buffer) to get the name of the "source" package (i.e.,
the one which makes the `require' request), but that's wrong. Any idea how to
get the name of the "caller" package?
> From: "Sebastien Vauban" <wxhgmqzgw...@spammotel.com>
> Date: Sat, 17 Nov 2012 00:08:43 +0100
> I'd like to advice `require' in order to show which package is making the call
> to require another one.
> I tried using (current-buffer) to get the name of the "source" package (i.e.,
> the one which makes the `require' request), but that's wrong. Any idea how to
> get the name of the "caller" package?
Doesn't "C-h f require RET" give you that information?
<wxhgmqzgwmuf-geNee64TY+gS+FvcfC7...@public.gmane.org> writes:
> I tried using (current-buffer) to get the name of the "source" package (i.e.,
> the one which makes the `require' request), but that's wrong. Any idea how to
> get the name of the "caller" package?
>> I tried using (current-buffer) to get the name of the "source" package
>> (i.e., the one which makes the `require' request), but that's wrong. Any
>> idea how to get the name of the "caller" package?
> Check this out:
> C-h f find-lisp-object-file-name RET
I wasn't clear enough: what I'd like is that if, for example, helm-m-x.el contains
a require of helm.el, then (with my advice'd require), when requiring
helm-m-x, I'd see in the Messages:
helm-m-x.el is now requiring helm.el
So, I'm interested in the name of the package which contains require's of
other packages (and executes them).
That could be done statically on the file system, but I'd like to see the view
of "who called who" for my Emacs session.
On 2012-11-17, Bastien wrote:
>> I tried using (current-buffer) to get the name of the "source" package
>> (i.e., the one which makes the `require' request), but that's wrong. Any
>> idea how to get the name of the "caller" package?
> I wasn't clear enough: what I'd like is that if, for example, helm-m-x.el contains
> a require of helm.el, then (with my advice'd require), when requiring
> helm-m-x, I'd see in the Messages:
> helm-m-x.el is now requiring helm.el
> So, I'm interested in the name of the package which contains require's of
> other packages (and executes them).
And I will repeat what I asked: doesn't "C-h f require" gives you that
information?
Let me put here what it shows, with suitably emphasized portions that
should tell you what to do:
(require FEATURE &optional FILENAME NOERROR)
If feature FEATURE is not loaded, load it from FILENAME.
If FEATURE is not a member of the list `features', then the feature
is not loaded; so load the file FILENAME.
^^^^^^^^^^^^^^^^^^^^^^
If FILENAME is omitted, the printname of FEATURE is used as the file name,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ and `load' will try to load this name appended with the suffix `.elc' or
`.el', in that order. The name without appended suffix will not be used.
See `get-load-suffixes' for the complete list of suffixes.
If the optional third argument NOERROR is non-nil,
then return nil if the file is not found instead of signaling an error.
Normally the return value is FEATURE.
The normal messages at start and end of loading FILENAME are suppressed.
Since your defadvice has access to all the arguments of the call to
'require, you should be trivially able to see if FILENAME is
specified, and if not, use something like (symbol-name FEATURE) to
retrieve the file name.
() Eli Zaretskii <e...@gnu.org>
() Sat, 17 Nov 2012 12:11:09 +0200
Am I missing something?
Yes, the OP seeks a way to find "a" when a.el says ‘(require 'b)’.
That is, both vertices of the edge.
Probably ‘load-history’ is fine to walk for after-the-fact, and
‘current-buffer’ to chase for at-the-moment.
-- Thien-Thi Nguyen ..................................... GPG key: 4C807502
. NB: ttn at glug dot org is not me .
. (and has not been since 2007 or so) .
. ACCEPT NO SUBSTITUTES .
........... please send technical questions to mailing lists ...........
() Eli Zaretskii <e...@gnu.org>
() Sat, 17 Nov 2012 13:02:47 +0200
Sorry, I just couldn't imagine that someone will not know about
buffer-file-name and current-buffer.
To be fair, guessing those requires knowing something about how ‘load’
works. Emacs is buffer-centric so it ‘load’s by first populating a
buffer then ‘read’ing from it. Guile, as a counter-example, implements
‘load’ by ‘read’ing from a "port". Other systems might mmap(2) or talk
to a daemon or whatever.
I see that (info "(emacs) Lisp Libraries")
says only:
To "load" an Emacs Lisp file, type `M-x load-file'. This command reads
a file name using the minibuffer, and executes the contents of that
file as Emacs Lisp code. It is not necessary to visit the file first;
this command reads the file directly from disk, not from an existing
Emacs buffer.
In (info "(elisp) How Programs Do Loading")
there is a bit more:
Whatever the name under which the file is eventually found, and the
directory where Emacs found it, Emacs sets the value of the variable
`load-file-name' to that file's name.
[...]
When loading a source file (not compiled), `load' performs
character set translation just as Emacs would do when visiting the
file. *Note Coding Systems::.
but again, how ‘load’ actually does its job is never detailed. To my
ears, this is a just omission, and thus OP's question has some merit.
-- Thien-Thi Nguyen ..................................... GPG key: 4C807502
. NB: ttn at glug dot org is not me .
. (and has not been since 2007 or so) .
. ACCEPT NO SUBSTITUTES .
........... please send technical questions to mailing lists ...........
> I tried using (current-buffer) to get the name of the "source" package
> (i.e., the one which makes the `require' request), but that's
> wrong. Any idea how to get the name of the "caller" package?
> From: Stefan Monnier
> Sent: Monday, November 19, 2012 8:59 AM
> To: help-gnu-em...@gnu.org
> Subject: Re: Show who is requiring
> > I tried using (current-buffer) to get the name of the "source" package
> > (i.e., the one which makes the `require' request), but that's
> > wrong. Any idea how to get the name of the "caller" package?
> IIUC you want load-file-name.
How does this report the names of files that require another package?
Perhaps you assume the OP's scenario is that he has already loaded the packages that require?
My understanding of the request is the inverse: for some package PKG, he wants to find where it is used.
The OP wants a list of other packages that require PKG.
For example, from the 23.1 Lisp source, we have (grep -n):
> I'd like to advice `require' in order to show which package is making the call
> to require another one.
> I tried using (current-buffer) to get the name of the "source" package (i.e.,
> the one which makes the `require' request), but that's wrong. Any idea how to
> get the name of the "caller" package?
I think the `load-file-name' variable has that information.
>> > I tried using (current-buffer) to get the name of the "source" package
>> > (i.e., the one which makes the `require' request), but that's
>> > wrong. Any idea how to get the name of the "caller" package?
>> IIUC you want load-file-name.
> How does this report the names of files that require another package?
IIUC he has put an advice on `require', so in this advice,
`load-file-name' should contain the name of the code that's calling the
`require'.
Stefan Monnier wrote:
>>> > I tried using (current-buffer) to get the name of the "source" package
>>> > (i.e., the one which makes the `require' request), but that's
>>> > wrong. Any idea how to get the name of the "caller" package?
>>> IIUC you want load-file-name.
>> How does this report the names of files that require another package?
> IIUC he has put an advice on `require', so in this advice, `load-file-name'
> should contain the name of the code that's calling the `require'.
From your description, that's exactly what I'm after. I'll test and report.
My ultimate goal is to generate a Dotty graph of "who required who" among the
different packages I'm directly, or indirectly, requiring.
So, I need to output relations such as:
a.el -> b.el
b.el -> c.el
b.el -> d.el
...
Thanks to Drew and to Thien-Thi to point me to `load-history' as well... Quite
complex to read, and not exactly the same, but clearly useful.
"Sebastien Vauban" wrote:
> Stefan Monnier wrote:
>>>>> I tried using (current-buffer) to get the name of the "source" package
>>>>> (i.e., the one which makes the `require' request), but that's wrong. Any
>>>>> idea how to get the name of the "caller" package?
>>>> IIUC you want load-file-name.
>>> How does this report the names of files that require another package?
>> IIUC he has put an advice on `require', so in this advice, `load-file-name'
>> should contain the name of the code that's calling the `require'.
> From your description, that's exactly what I'm after. I'll test and report.
For some unknown reason (I mean: to me), `load-file-name' is sometimes nil,
like if the requires came out of nowhere:
"Sebastien Vauban" wrote:
> I tried using (current-buffer) to get the name of the "source" package
> (i.e., the one which makes the `require' request), but that's wrong. Any
> idea how to get the name of the "caller" package?
You could be interested by the first version of my "package tree":
"Sebastien Vauban" wrote:
> "Sebastien Vauban" wrote:
>> I tried using (current-buffer) to get the name of the "source" package
>> (i.e., the one which makes the `require' request), but that's wrong. Any
>> idea how to get the name of the "caller" package?
> You could be interested by the first version of my "package tree":
"Recursive" requires are not very common but do happen every once in
a while. It's usually better to restructure your code to avoid them,
but some authors don't want to bother (and the result is not always
really better because the resulting structure is a result of details of
implementation).
At other times it's because some functions defined are used during
compilation of the same file (e.g. they're used during
macro-expansion). You can sometimes avoid self-requiring by using
eval-and-compile instead (as does eieio.el, which uses eval-and-compile
on a very large part of itself).