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,203
  • 3
  • 74
  • 179
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,203
  • 3
  • 74
  • 179
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,203
  • 3
  • 74
  • 179
Iqbal Ansari
  • 7,468
  • 1
  • 28
  • 31
  • I get: `Symbol's function definition is void: with-eval-after-load` – Marcus Junius Brutus Oct 19 '15 at 10:55
  • @MarcusJuniusBrutus Seems you are on an Emacs version older than 24.3, updated the answer – Iqbal Ansari Oct 19 '15 at 11:49
  • @MarcusJuniusBrutus If you cannot update to the latest emacs version, it might even be helpful to define the `with-eval-after-load` macro locally: http://www.lunaryorn.com/2013/06/25/introducing-with-eval-after-load.html Personally I prefer using this than the requirement to use quoted form for `eval-after-load`. – Kaushal Modi Oct 19 '15 at 11:53
  • @IqbalAnsari This is a great answer.. I might steal that idea and reimplement using the `:before-until` advice. – Kaushal Modi Oct 19 '15 at 11:56
  • @kaushalmodi Feel free to steal it :) – Iqbal Ansari Oct 19 '15 at 12:05
  • @IqbalAnsari [Done!](https://github.com/kaushalmodi/.emacs.d/blob/99494f2d974d5e1fbf038343ff391fce04761075/setup-files/setup-org.el#L245-L256) :) – Kaushal Modi Oct 19 '15 at 12:17
  • @kaushalmodi Cool, now I will steal it from your config ;) – Iqbal Ansari Oct 19 '15 at 12:26
  • @IqbalAnsari I recently discovered that this creates a buggy behavior when `org-table-blank-field` is called by some other function like `org-table-wrap-region` and if that function is called with a prefix. – Kaushal Modi May 23 '16 at 16:32
  • @IqbalAnsari Check out the new approach using context-aware bindings in [my other answer](http://emacs.stackexchange.com/a/22457/115). – Kaushal Modi May 23 '16 at 16:39