PJB on #CommonLisp (IRC.LIBERA.CHAT) greatly assisted and provided the below answer (which I have paraphrased so any mistakes are on my end):
Firstly, CL is a lisp-2 (actually, lisp-∞) and thus there may not be a single definition attached to a symbol. For example, which foo
is being referred to in the below?
(deftype foo () (member foo))
(defvar foo 'foo)
(defun foo () foo)
In addition, as an example, symbols may be defined in the REPL (no associated filename), so this is not a straightforward question that can be answered without making assumptions on the intent.
Now, when the behaviour of M-.
is satisfactory for your requirements, you could look in slime/swank what the implementation specific API is to do it.
This should point you to swank:find-definition-for-emacs
, which may be what you are after:
(swank:find-definitions-for-emacs "foo") #| -->
(("#'foo"
(:location (:file "/private/tmp/foo.lisp")
(:position 50)
(:snippet "(defun foo () foo)")))
("(type foo)"
(:location (:file "/private/tmp/foo.lisp")
(:position 1)
(:snippet "(deftype foo () '(member foo))")))
("(variable foo)"
(:location (:file "/private/tmp/foo.lisp")
(:position 32)
(:snippet "(defvar foo 'foo)"))))
Make sure to load swank
as a dependency in your .asd
files if you want to rely on the above.
EDIT: I also found the below very useful (and swank has a similar file for most implementations, so just go through each to see their equivalents):
https://github.com/slime/slime/blob/68c58c0194ff03cd147fcec99f0ee90ba9178875/swank/sbcl.lisp#L811
The function call (sb-introspect:find-definition-sources-by-name name type)
(name is a symbol, type is a keyword, e.g. :function - refer above link) returns the file in which a definition is stored, assuming you are using SBCL. More (SBCL) details also in:
https://github.com/sbcl/sbcl/blob/master/contrib/sb-introspect/introspect.lisp