8

I was reading through the projectile source file and they do the following:

(defvar projectile-command-map
  (let ((map (make-sparse-keymap)))
    ; define-keys
    map)
  "Keymap for Projectile commands after `projectile-keymap-prefix'.")
(fset 'projectile-command-map projectile-command-map)

Why do they do this? Is it for backwards compatibility?

Drew
  • 75,699
  • 9
  • 109
  • 225
Czipperz
  • 317
  • 2
  • 9
  • 1
    I'm very much aware of how keymaps work, yet I couldn't tell you why they do this. You might like to ask them. – Stefan May 15 '17 at 04:09

1 Answers1

10

fset sets a symbol's function definition.

Here, projectile-command-map is used as a prefix command. A prefix command is a symbol whose function definition is a keymap.

The definition of a prefix key is usually the keymap to use for looking up the following event. The definition can also be a Lisp symbol whose function definition is the following keymap; the effect is the same, but it provides a command name for the prefix key that can be used as a description of what the prefix key is for.

This can also be done with define-prefix-command.

What's a bit confusing here is that the same symbol, projectile-command-map, is being used for two purposes:

  • As a keymap
  • As a prefix command

Another example may be clearer:

(fset 'help-command help-map)

Here, help-command is clearly a prefix command, while help-map is a keymap.

Tianxiang Xiong
  • 3,848
  • 16
  • 27
  • See also `C-h f defalias` (similar to `fset`). See (elisp)[Prefix Keys](http://www.gnu.org/software/emacs/manual/html_node/elisp/Prefix-Keys.html) for info about prefix commands. – Drew May 12 '17 at 22:44
  • What's a bit confusing here is that the same symbol is being used for two purposes: prefix *keymap* and prefix *command*. It'd be clearer if they were two different symbols, as with [`help-command` and `help-map`](http://ergoemacs.org/emacs_manual/elisp/Help-Functions.html). – Tianxiang Xiong May 12 '17 at 22:59
  • Maybe so, but that's the most common way to do it (a cliche) - use the same symbol. (`grep` for `fset` in the Lisp sources, then `M-x flush offset` and search for `map`.) – Drew May 12 '17 at 23:47
  • 1
    It's common and I'd say the *recommended* way in order to avoid defining extra symbols, but it's confusing to those who don't have a good understanding of how keymaps work. I just made the comment to be more explicit for OP. – Tianxiang Xiong May 13 '17 at 00:35
  • Yes, I understand why you made the comment, and I agree it can be confusing. I don't think the reason is to avoid extra symbols. The reason is to have the same symbol enjoy both behaviors. It's a programming cliche, but the relation between the two (whether the same name or not) is documented as such. It is a *command*, so it can be bound to a key. But it is also a *variable*, so it can act as a keymap. This is Lisp-2. ;-) – Drew May 13 '17 at 04:31
  • That doesn't really clarify (to me) why they do it: why do they need this "command" and can't just use the corresponding keymap instead? – Stefan May 15 '17 at 04:10
  • I'd think it's because binding the keymap to a symbol rather than using it directly keeps the code cleaner. To use the keymap directly, you have to define it where it's used. – Tianxiang Xiong May 15 '17 at 05:19
  • The reason for this code is that it allows keymappings that bind to this map bind to the symbol rather than the value of the keymap. Then if the keymap variable changes to a different keymapping or the user does a `define-key` then it works properly. – Czipperz Jun 06 '17 at 05:32