22

I'm bored of looking up key names for the kbd function, is there a way to automatically insert the correct key name just by pressing the key?

So for example I want something to do this: I'm typing

(local-set-key |

I run magical-insert-kbd-command, press f6 and I get

(local-set-key (kbd "<f6>") |
dshepherd
  • 1,281
  • 6
  • 18

2 Answers2

21

Not sure exactly what you are asking. But C-h k followed by hitting the key shows you exactly what string you need to pass to kbd. For example, C-h k f6 shows you <f6>.

Here is a command that does what you want, I guess and binds the result to C-c c:

(defun foo (key)
  (interactive "kKey: ")
  (insert (format "(kbd %S)" (key-description key))))

(global-set-key (kbd "C-c c") 'foo)

Then type:

(local-set-key C-c c

That prompts you to use a key. If you hit the F6 key then you get this:

(local-set-key (kbd "<f6>") 

[Updated per suggestion by @HaraldHancheOlsen: Changed "(kbd \"%s\")" to ".](kbd %S)"

Drew
  • 75,699
  • 9
  • 109
  • 225
  • Perfect, thanks!. The main thing I was missing was missing the `key-description` function. – dshepherd Jun 04 '15 at 21:56
  • But OP is right that it would be a useful to have a function that automatically placed the keybinding in the kill ring. – incandescentman Jun 27 '15 at 06:44
  • 1
    @incandescentman: Huh? Where does the OP say anything about the *kill ring*? And just what do you mean by the "keybinding" in that sentence? A key binding is not a string, which is what the `kill-ring` contains. Do you mean the `key-description` string? or the return value of the above `format` sexp? Anyway, it should be clear how to modify the command I gave, to add either of those to the `kill-ring` (just use `kill-new`). – Drew Jun 27 '15 at 15:48
  • "automatically insert." If I understand correctly, the solution above only displays the keybinding (e.g. `kbd `) but does not insert it into an init file. (You'd have to do the additional step of copy/paste.) Maybe I misunderstood. For my own personal use case, I would find it useful to have a way to query the syntax for a keybinding (e.g. is the syntax `M-RET` or `M-` or what?) and automatically place that string in the kill ring/pasteboard, so that I could then paste the keybinding into my init file when writing a line like `(define-key map (kbd "") 'org-return)`. – incandescentman Jun 27 '15 at 20:46
  • 1
    Yes, you misunderstood. (But there was also a typo in the key-binding sexp: I forgot to use `kbd` in the `global-set-key` sexp - corrected now.) Command `foo` (which the `global-set-key` sexp binds to `C-c c`) reads a key sequence and then inserts, at point of the current buffer, the proper `kbd` sexp for it. If you use `C-c c` in your init file, after `(local-set-key `, then it inserts the `kbd` sexp you need for the key it reads. – Drew Jun 27 '15 at 20:46
  • @incandescentman: See my previous comment. I think the code should do what you want. You want to be able to hit the key to see what the correponding `kbd` sexp would be. It does that. It inserts that sexp in the current buffer at point. – Drew Jun 27 '15 at 21:00
  • Nice. but I think using `(format "(kbd %S) …)"` is more robust. It will escape any `"` (or backslashes, etc.) in the key sequence provided. – Harald Hanche-Olsen Jun 29 '15 at 14:15
  • @HaraldHanche-Olsen: Good point! I've updated the answer accordingly. – Drew Jun 29 '15 at 15:26
  • @Drew In my config, I named the function `keybinding-read-and-insert`. – incandescentman Jul 09 '15 at 16:33
7

If you use M-x local-set-key to do your keybinding interactively, you can use C-x ESC ESC (repeat-complex-command) to get a Lisp expression that you can paste into your config. It probably won't use friendly (kbd ...)-style descriptions, though.

Sacha Chua
  • 716
  • 5
  • 5
  • Neat. I tend to use `define-key` though actually, it seems simpler to just define the key outright than to set up a hook to call a function to define the key. – dshepherd Jun 05 '15 at 15:05