2

I wanted to disable arrow keys in my Emacs to practice vim key bindings using EVIL mode. So instead of using global-unset-key as someone here on stackexchange suggested. I used the following code in my init file.

(global-set-key (kbd "<left>") (lambda() ( message "Use Vim keys: h for Left")))
(global-set-key (kbd "<right>") (lambda() (message "Use Vim keys: l for Right")))
(global-set-key (kbd "<up>") (lambda() (message "Use Vim keys: k for Up")))
(global-set-key (kbd "<down>") (lambda() (message "Use Vim keys: j for Down")))

For some reason these don't work inside org-mode. And also if I am not inside org-mode, It works but instead of the message like I want to give. I get the following error.

command-execute: Wrong type argument: commandp, (lambda nil (message "Use Vim keys: h for Left"))

Complete Beginner here. So fix along with some explanation of how things work is highly appreciated.

Edit: After the first answer I see that the error has vanished. But the whole thing doesn't work unless I type something. Not as soon as I enter Emacs. And the error is not specific to org-mode. It also works in org-mode after I type something. It doesn't work in normal-mode in EVIL.

Panch93
  • 265
  • 2
  • 8
  • I also tried adding a ' in front of the lambda functions. That didn't work too. Like (global-set-key (kbd "") '(lambda() ( message "Use Vim keys: h for Left"))) – Panch93 Sep 24 '17 at 08:06
  • 2
    Local mode bindings trump global bindings. Any mode that redefines arrow keys would override your global definition. Org mode would be probably even harder to redefine (I'm not sure though) because keys may be defined on several levels. Anyhow, try making your setting local by moving it to `org-mode-hook` and using `local-set-key` instead. – wvxvw Sep 24 '17 at 09:34
  • It looks like you are using `evil`. Is that correct? If so, please edit your question to mention `evil` explicitly. You will need to bind keys differently in standard Emacs vs `evil`. – Dan Sep 26 '17 at 14:47

3 Answers3

3

I couldn't reproduce your problem but this solution should work. The easiest way would be to install use-package and then use the bind-key* macro.

If you want to do it manually you can add this to your Emacs config

(define-minor-mode my-override-mode
  "Overrides all major and minor mode keys" t)

(defvar my-override-map (make-sparse-keymap "my-override-map")
  "Override all major and minor mode keys")

(add-to-list 'emulation-mode-map-alists
  `((my-override-mode . ,my-override-map)))

(define-key my-override-map (kbd "<left>")
  (lambda ()
    (interactive)
    (message "Use Vim keys: h for Left")))

(define-key my-override-map (kbd "<right>")
  (lambda ()
    (interactive)
    (message "Use Vim keys: l for Right")))

(define-key my-override-map (kbd "<up>")
  (lambda ()
    (interactive)
    (message "Use Vim keys: k for Up")))

(define-key my-override-map (kbd "<down>")
  (lambda ()
    (interactive)
    (message "Use Vim keys: j for Down")))

Instead of adding the keys to the global map, we create a minor mode and add the keys to the emulation-mode-map-alist which takes precedents over minor and major mode maps.

Update: Evil mode

Evil mode provides it's own emulation map. So you need to add this line

(evil-make-intercept-map my-override-map)
Moyamo
  • 388
  • 2
  • 7
  • Still doesn't work. There seems to be an issue with Normal mode in org-mode. These key bindings only work in Insert Mode – Panch93 Sep 26 '17 at 10:12
  • Are you using evil mode? That makes quite a big difference. – Moyamo Sep 26 '17 at 13:42
  • I apologise for not explicitly mentioning evil mode. It works now. Thanks a lot . Can you explain a bit more about what's happening here? 1) Does evil mode over rise all the default bindings when it is started ? 2)Then how was it working in normal-mode in EVIL ? – Panch93 Sep 27 '17 at 12:29
  • evil-mode overrides most keybindings in the emulation-mode-map. I was trying to override the keys at the same level, so the outcome was not reliable. There aren't many overridden keys in the insert state so regular emacs keybindings will work. – Moyamo Sep 27 '17 at 12:51
2

Use (interactive):

(global-set-key (kbd "<left>")
  (lambda() 
    (interactive)
    (message "Use Vim keys: h for Left")))
Stefan
  • 26,154
  • 3
  • 46
  • 84
caisah
  • 4,056
  • 1
  • 23
  • 43
0

To find out whether org-mode has its own local bindings, use C-h k left to find out the left arrow is bound to. If it says "found in xyz map" (example: "found in global-map") then you can use

(define-key global-map (kbd "<left>") (lambda() ( message "Use Vim keys: h for Left")))

global-set-key only sets global-map, but it's likely that you have evil-mode or org-mode maps that are setting the key, so you'll have to use define-key with those too.

amitp
  • 2,451
  • 12
  • 23