10

I added a section binding to my config, but one key doesn't work.

:bind (("C-c a" . org-agenda)
       ("<f6>"  . org-capture)
       ("<M-S-return>" . org-insert-subheading))

These two keys (C-c a, f6) work as I expected.

If I check the M-S-return key binding via C-h k, the help will show the org-insert-todo-heading binding.

How do I bind M-S-return to org-insert-subheading?

Drew
  • 75,699
  • 9
  • 109
  • 225
dmin
  • 343
  • 2
  • 10
  • This looks like a duplicate. Could someone please check (and close if so)? And does it really matter whether `use-package` is used? Isn't this just a question about binding ``? – Drew Jun 24 '20 at 19:27
  • @Drew possibly more about when org-insert-todo-heading is bound to a key it might be after use-package if lazy loading occurs – mmmmmm Jun 24 '20 at 19:59
  • 3
    By default, the `:bind` mechanism in `use-package` uses the global map. It works fine for the first two, since `org-mode` does not touch them, but it doesn't work in the third case, because `org-mode` does touch that. And I'm pretty sure @Drew is right and I'm also pretty sure I 've answered a question similar to this, but for the life of me, I can't find it now... – NickD Jun 25 '20 at 03:49

3 Answers3

14

Thank you for telling me about the different types of maps.

The issue is as @NickD pointed out in their answer and the example use-package code puts all the bindings into the global map. ie org-mode puts the binding to <M-S-return> in org-mode-map so you need to use that map.

Because my configuration is based on use-package, it is more convenient for me to use this framework's approaches. So I added :map to my configuration and everything worked.

:bind (("C-c a" . org-agenda)
       ("<f6>"  . org-capture)
       :map org-mode-map
       ("<M-S-return>" . org-insert-subheading))
mtraceur
  • 184
  • 1
  • 10
dmin
  • 343
  • 2
  • 10
4

The mode sets up its own keymap which overrides the global map. The :bind mechanism creates a binding in the global map, but in an Org mode file, the key is looked up in the mode map before the global map, so you get the definition in the mode map.

The usual way to override this is by using the mode hook. Add to your init file the following code:

(eval-after-load 'org '(add-hook 'org-mode-hook (lambda () (define-key org-mode-map (kbd "<M-S-return>") #'org-insert-subheading))))

The mode hook (org-mode-hook in this case) is run at the end of the mode function (org-mode in this case). "Running" the hook executes each function in the hook. In this case, when the function call is evaluated, it calls define-key to redefine the given key ((kbd "<M-S-return>")) in the given keymap (org-mode-map) to the given command (#'org-insert-subheading). And that is done after the mode function has set up the mode map, so it overrides whatever the mode function did.

Hooks are an important customization method in Emacs: you should read the "Hooks" section of the manual (well, you should read the whole manual eventually). And BTW, you can get to the "Hooks" section of the manual in Emacs: C-h r i Hooks RET.

NickD
  • 27,023
  • 3
  • 23
  • 42
  • 2
    As you are saying that the unwanted map is not global but in org-mode-map then this can be set in use-package bind by giving that map explicitly – mmmmmm Jun 25 '20 at 15:06
  • @mmmmmm: I don't know much about `use-package` - feel free to add an answer (or edit my answer) to add information about how to do it in the use-package declaration. That might be a useful answer to have around. – NickD Jun 25 '20 at 15:32
  • 2
    see @dmin's answer https://emacs.stackexchange.com/a/59270/9874 – mmmmmm Jun 25 '20 at 15:58
  • Great - thanks! – NickD Jun 25 '20 at 16:30
0

You want M-S-<return>, not <M-S-return>.

db48x
  • 15,741
  • 1
  • 19
  • 23