4

My ace-jump-mode bindings don't seem to work when I'm editing in org-mode. This is how I define them in my .emacs.

(progn
  (require 'ace-jump-mode)                                                                                                                                                            
    (define-key global-map (kbd "C-c SPC") 'ace-jump-mode)                                                                                                                            
    (define-key global-map (kbd "C-c C-c SPC") 'ace-jump-char-mode)                                                                                                                   
    (define-key global-map (kbd "C-c C-c C-c SPC") 'ace-jump-line-mode)                                                                                                               
) 

Instead, when editing in org-mode, C-c SPC gives on the mini-buffer:

Not in table data field

... with the other bindings also failing (in different ways). I would prefer to disable these bindings from the org-mode commands they are bound to as I don't use them (for the time being at least).

If that's not possible, is it possible to instead only define alternative bindings for the ace-jump commands only when working in org-mode?

In general what is the "proper" way of addressing such clashes?

  • 1
    FYI: An alternative to (define-key global-map...) is (global-set-key...). – Drew Oct 14 '15 at 17:30
  • Major modes should not be redefining the C-c SPC keybinding, as this is reserved for minor modes. If the org-mode major mode is redefining it, it is a bug of that mode. – Tyler Oct 14 '15 at 17:35
  • @Tyler Why would you consider C-c SPC to be reserved for minor modes? C-c is a common prefix to use for mode-specific commands,and the Emacs info node on "Major Modes" mentions this. (https://www.gnu.org/software/emacs/manual/html_node/emacs/Major-Modes.html) – glucas Oct 14 '15 at 18:21
  • 1
    Answering my own question above. The Emacs Lisp manual says: "The key sequences bound in a major mode keymap should usually start with ‘C-c’, followed by a control character, a digit, or ‘{’, ‘}’, ‘<’, ‘>’, ‘:’ or ‘;’. The other punctuation characters are reserved for minor modes, and ordinary letters are reserved for users." – glucas Oct 14 '15 at 18:33

3 Answers3

7

Global map keys get overridden by major-mode and minor-mode keymaps.

There are a couple of ways to solve the problem specific to your case:

  1. Do not bind ace-jump-mode to C-c SPC. Instead bind it to something else that does not clash like C-c C-SPC.

    Many might recommend using this approach. If you use org-mode frequently, or might start using it frequently in future, you do not want your personal bindings clashing with the org-mode bindings :).

  2. As the C-c SPC in org-mode-map is overriding your binding in the global-map, you can bind that particular key in org-mode-map to nil. See here.

    (with-eval-after-load 'org
        (define-key org-mode-map (kbd "C-c SPC") nil))
    
  3. Do not bind ace-jump-mode in global-map but in your own minor-mode map or using something like use-package package's bind-key* or bind-keys* macro.


Above links are solutions to a prior question asked here on emacs.stackexchange,

Kaushal Modi
  • 25,651
  • 4
  • 80
  • 183
3

This solution requires installing the bind-key package (available on Melpa and also installed as dependency if you install use-package).

The concept of "context-aware" bindings is used here. The below code binds C-c SPC to org-table-blank-field in the org-mode-map; but only if org-at-table-p returns a non-nil value (i.e. when the point is inside an org table). You can learn more about context-aware bindings from here.

(bind-keys
 :map org-mode-map
 :filter (org-at-table-p)
  ("C-c SPC" . org-table-blank-field))

I would even go ahead and bind almost all org-table specific bindings using this :filter arg:

(bind-keys
 :map org-mode-map
 :filter (org-at-table-p)
  ("C-c ?" . org-table-field-info)
  ("C-c SPC" . org-table-blank-field)
  ("C-c +" . org-table-sum)
  ("C-c =" . org-table-eval-formula)
  ("C-c `" . org-table-edit-field)
  ("C-#" . org-table-rotate-recalc-marks)
  ("C-c }" . org-table-toggle-coordinate-overlays)
  ("C-c {" . org-table-toggle-formula-debugger))
Kaushal Modi
  • 25,651
  • 4
  • 80
  • 183
1

@kaushalmodi has already mentioned some very good solutions for your problem. I wanted to mention another alternative that I use.

If you do describe-key for C-c SPC in org-mode (C-hkC-cSPCRET), you will notice that it is bound to the command org-table-blank-field which is relevant only when you are in org-mode tables, basically useless in most part of an org-mode document.

As such we can define a DWIM command which checks if we are inside an org-mode table, in which case it runs org-table-blank-field otherwise it delegates to whatever command C-cSPC is bound to globally and bound that command to C-cSPC in org-mode.

Something like the following should work, if called with a prefix argument it unconditionally delegates to global binding for C-cSPC (ace-jump-mode in your case)

(defun my-dwim-org-table-blank-field ()
  (interactive)
  (call-interactively (if (and (not current-prefix-arg)
                               (org-at-table-p))
                          #'org-table-blank-field
                        (global-key-binding (kbd "C-c SPC")))))

(with-eval-after-load 'org
  (org-defkey org-mode-map (kbd "C-c SPC") #'my-dwim-org-table-blank-field))

The macro with-eval-after-load was introduced in Emacs v24.4, for older versions use the following form

(eval-after-load "org"
  '(org-defkey org-mode-map (kbd "C-c SPC") #'my-dwim-org-table-blank-field))
Kaushal Modi
  • 25,651
  • 4
  • 80
  • 183
Iqbal Ansari
  • 7,558
  • 1
  • 29
  • 31