Subject: bug#30660: mention describe-bindings on (info "(emacs) Keymaps")

From: Drew Adams <[email-masked]>
Date: Fri, 23 Aug 2019 18:46:19 -0700 (PDT)

> > Non-interactively:
> > * KEYMAP can be such a keymap variable or a keymap.
> > * Non-nil optional arg SEARCH-SYMBOLS-P means that if KEYMAP is not a
> >   symbol then search all variables for one whose value is KEYMAP."
> 
> Is the purpose of SEARCH-SYMBOLS-P just to allow for calling it like
> this:
>     (describe-keymap 'my-keymap t)
>     (describe-keymap my-keymap t)
> 
> And have it work automatically?  Or am I missing something?  Also see
> below.

KEYMAP can be a keymap, instead of a symbol.

(This was not the case originally.  I added handling
this case later, as it was requested and turned out
to be useful.  It's not rare to have a keymap object
ready-to-hand and without its variable.  This lets
you not only see the bindings but also identify the
keymap.)

If it's not a symbol there might still be a symbol
that has it as value.  Non-nil SEARCH-SYMBOLS-P
means try to find such a symbol.

If such a symbol is found then the help is better -
it tells you more about the keymap and its context,
by (1) providing its doc (in addition to listing the
key bindings) and even just (2) providing its name,
letting you know (typically) what mode or other
context defines it.

If the search finds no symbol with KEYMAP as its
value then the behavior is the same as if no search
was made (except for the time wasted on a failed
search): a symbol is generated for the map (just to
use the same code path).  The other difference is
that because you provided SEARCH-SYMBOLS-P you know
that a search turned up no symbol - more information.

> I admit that I find this code a bit hard to follow.  If I understand
> correctly, then most of this can be removed if we don't want to
> support SEARCH-SYMBOLS-P, and instead just require that the KEYMAP
> argument is a symbol.  Is that correct or am I missing something?

Who's "we"?  If a _user_ or calling code doesn't
want to search existing symbols then SEARCH-SYMBOLS-P
is supplied.  Nothing is lost by having it as a
behavior option, and something (quite a lot, actually)
is gained by making it available.  Putting a name on
a keymap object can be quite helpful.

The case where a user (or calling code) has a keymap
but no variable for it is not uncommon, even if it
is not the most common case.  Being able to find the
variable and see its doc is helpful.

> I'm sort of leaning towards simplifying this by removing the
> SEARCH-SYMBOLS-P argument, but I might not understand the use case
> here.  If I'm missing something, could you please briefly describe the
> use case for that and if and why it's important to keep?

See above.

> >   (let* ((name  (symbol-name keymap))
> >          (doc   (let ((raw-doc  (documentation-property keymap
> 'variable-documentation 'RAW)))
> >                   (substitute-command-keys raw-doc)))
> 
> Why not just say (documentation-property keymap 'variable-
> documentation)
> without the 'RAW argument?  That should have the same effect as
> passing the 'RAW argument and then calling substitute-command-keys on
> the result, AFAICT.

Yes; sorry.  My code uses `help-documentation-property'
and `help-substitute-command-keys'.  I too quickly
substituted the body of `help-documentation-property',
changing its occurrence of `help-substitute-command-keys'
to just `substitute-command-keys'.  None of `h-d-p' is
needed here if you don't have `h-s-c-k'.

IOW, if neither of those is available then yes, all
you need is (documentation-property keymap
'variable-documentation).  Sorry about that mistake.

You might want to take a look at the full code,
in help-fns+.el, to see what the differences are.
Some are to support older Emacs versions too, others
are to provide additional features.

> > (doc   (and (not (equal "" doc))  doc)))
> 
> Is this to allow us to simply say (when doc ...) below

Yes.  It makes DOC be either nil or real doc.

> instead of (when (not (equal "" doc)) ...)

[aka (unless (equal "" doc)...)]

No.  That's not the same.  That does `...' when doc
is nil.  The code should do `...' only when doc is
non-nil and not "".