4

I've got a few functions in api-wrap.el that I'll refer to as 'macro code', here simplified to clarify the question:

  • function (generate-form prefix kind &rest args) returns an unevaluated form that would define a new specific function
  • macro (generate-macros prefix &rest args) loops over PUT, GET, etc. and defines macros that use generate-form as a definition

So, calling order: generate-macros creates macros (here called factories) that dip into generate-form to create the definition. These factory-macros are what actually defines each target function in application code.

Finally, the question: when I define one of these target functions in application code, I get a docstring that looks like the following

some-awesomely-generated-function is a Lisp function.

I don't get any link to where the function was defined in application code like I would if I was describing a normally-defined function. The same applies for the macros generated by generate-macros, though I'm less concerned for those.

I don't get any link to where the function was defined like I would if I was describing a normally-defined function. How can I declare where these functions are actually created, i.e., at macro-use?

If my explanation is unclear, refer to the real generate-form and generate-macros code; each function is well-documented.

3
  • 1
    Good question. It could be simplified a lot, I think: there are lots of layers that don't need to be part of the essential question. I think the same problem occurs with any generation and subsequent evaluation of defuns. (But this doesn't mean you need to simplify the question. Just sayin'.)
    – Drew
    Commented Feb 25, 2017 at 17:38
  • @Drew Ah! I've been having a hard time identifying the nugget. (I've still not recovered from last night's lisp marathon.) Thanks! I've added an MWE. Commented Feb 25, 2017 at 17:46
  • @Drew 'minimal working example'. Yours didn't reproduce and, oddly enough, even my minimal working example isn't working anymore – I'm getting the correct link in the help buffer. I'm editing it out. Commented Feb 25, 2017 at 17:58

2 Answers 2

3

I think, you can do one of two things:

Define your own type to search for via find-func.el. This is how it's done in ert.el (Search for current-load-list and find-function-regexp-alist.) But I don't think that this will work with help-mode buffers, i.e. no linkage.

Or extend find-function-regexp: Ordinarily this variable evaluates to a regexp to search for, so you could try to extend it, such that it also matches your macro constructs. If that's not possible: The value of (cdr (assq nil find-function-regexp-alist)) may also be a function. In this case you need to somehow determine that the search is about one of your symbols and do it; or fallback to the search for a ordinary function. add-function may be helpful here, if you care for scalability:

(defun find-function-search-function-default (symbol)
  ;;Perform regular search here.
  )

(defun find-my-function (next symbol)
  (if (not (my-function-p symbol))
      (funcall next symbol)
    (search-my-function-in-current-buffer)))

(unless (functionp (cdr (assq nil find-function-regexp-alist)))
  (setcdr (assq nil find-function-regexp-alist) #'find-function-search-function-default))

(add-function :around (cdr (assq nil find-function-regexp-alist)) #'find-my-function)
0

Normally, you should get a link to the right file if you load the file. If you instead evaluate the expression with C-x C-e or C-M-x, then indeed Emacs won't remember where the definition took place.

Note that Emacs only remembers the file name, so when you click on the link, it will try to guess where is the definition within the file (basically by looking for the function's name), and in your case it will likely fail, but it should at least get you to the right file.

2
  • 2
    Is there any way to teach emacs how to guess the definition location? Commented Feb 25, 2017 at 19:54
  • Yes, via find-function-regexp-alist, but it's not very convenient.
    – Stefan
    Commented Feb 26, 2017 at 2:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.