Improve the *Help* output for compiler macros and the like

* doc/lispref/functions.texi (Advice and Byte Code): New node.

* lisp/help-fns.el (help-fns--compiler-macro): Also output data on
other byte compilation things, and link to the manual (bug#23264).
This commit is contained in:
Lars Ingebrigtsen 2022-05-14 04:06:32 +02:00
commit 5f7dd959c2
3 changed files with 56 additions and 4 deletions

View file

@ -592,6 +592,7 @@ Advising Emacs Lisp Functions
* Advising Named Functions:: Advising named functions.
* Advice Combinators:: Ways to compose advice.
* Porting Old Advice:: Adapting code using the old defadvice.
* Advice and Byte Code:: Not all functions can be advised.
Macros

View file

@ -1717,6 +1717,7 @@ ways to do it. The added function is also called a piece of @emph{advice}.
* Advising Named Functions:: Advising named functions.
* Advice Combinators:: Ways to compose advice.
* Porting Old Advice:: Adapting code using the old defadvice.
* Advice and Byte Code:: Not all functions can be advised.
@end menu
@node Core Advising Primitives
@ -2138,6 +2139,38 @@ changing @code{ad-return-value}, whereas new @code{:after} advice cannot, so
when porting such old @code{after} advice, you'll need to turn it into new
@code{:around} or @code{:filter-return} advice instead.
@c This is its own node because we link to it from *Help* buffers.
@node Advice and Byte Code
@subsection Advice and Byte Code
@cindex compiler macros, advising
@cindex @code{byte-compile}, advising
@cindex @code{byte-optimizer}, advising
Not all functions can be reliably advised. The byte compiler may
choose to replace a call to a function with a sequence of instructions
that doesn't include the function call to the function you were
interested in altering.
This usually happens due to one of the three following mechanisms:
@table @dfn
@item @code{byte-compile} properties
If function @var{symbol} has a @code{byte-compile} property, that
property will be used instead of @var{symbol}'s definition.
@xref{Compilation Functions}.
@item @code{byte-optimize} properties
If function @var{symbol} has a @code{byte-compile} property, the byte
compiler may rewrite the function arguments, or decide to use a
different function altogether.
@item compiler macros
Compiler macros are defined using a special @code{declare} form. This
tells the compiler to use the defined @dfn{expander} as an
optimization function, and it can return a new expression to use
instead of the function call. @xref{Declare Form}.
@end table
@node Obsolete Functions
@section Declaring Functions Obsolete
@cindex obsolete functions

View file

@ -614,9 +614,18 @@ the C sources, too."
menus))
(defun help-fns--compiler-macro (function)
(let ((handler (function-get function 'compiler-macro)))
(pcase-dolist (`(,type . ,handler)
(list (cons "compiler macro"
(function-get function 'compiler-macro))
(cons "`byte-compile' property"
(function-get function 'byte-compile))
(cons "byte-code optimizer"
(function-get function 'byte-optimizer))))
(when handler
(insert " This function has a compiler macro")
(if (bolp)
(insert " This function has a ")
(insert " and a "))
(insert type)
(if (symbolp handler)
(progn
(insert (format-message " `%s'" handler))
@ -631,8 +640,17 @@ the C sources, too."
(save-excursion
(re-search-backward (substitute-command-keys "`\\([^`']+\\)'")
nil t)
(help-xref-button 1 'help-function-cmacro function lib)))))
(insert ".\n"))))
(help-xref-button 1 'help-function-cmacro function lib)))))))
(unless (bolp)
(insert ". See "
(buttonize "the manual"
(lambda (_) (info "(elisp)Advice and Byte Code")))
" for details.\n")
(save-restriction
(let ((fill-prefix " "))
(narrow-to-region (line-beginning-position -1) (point))
(fill-region (point-min) (point-max)))
(goto-char (point-max)))))
(defun help-fns--signature (function doc real-def real-function buffer)
"Insert usage at point and return docstring. With highlighting."