1

Here is what I would like to do. I would like to customize key bindings that point to a different command depending on the file type on which the user is operating.

For instance, if one presses f5 in a Python file .py, I would like f5 to call the equivalent of C-c C-c:

(define-key key-translation-map [f5] (kbd "C-c C-c"))

But if one presses f5 in a R file .R, I would like f5 to call the equivalent of C-c C-b:

(define-key key-translation-map [f5] (kbd "C-c C-b"))

In the user-config function defined in .spacemacs, I tried doing the following:

(with-eval-after-load 'python
  (define-key key-translation-map [f5] (kbd "C-c C-c"))
)
(with-eval-after-load 'ess
  (define-key key-translation-map [f5] (kbd "C-c C-b"))
)

But it does not work properly. The last binding is the one that sticks, then f5becomes bounded to C-c C-b despite the file type.

I also tried putting each key binding above in the individual config.el files that exist in the .emacs.d/layers/+lang/python and .emacs.d/layers/+lang/ess folders. In this case, the opposite happens: only the binding associated to the first file type of the first file loaded is the one that sticks. The keybinding does not change according to in which file the user is.

So, what would be the appropriate way to implement what I want?

1

Here is how I ended up solving the problem. In Spacemacs, it seems that two things are needed in the .spacemacs file.

First, the keybindings conditional on modes need to be defined with eval-define-key. Second, it should be done within a eval-after-load call, in order to wait for mode to be loaded before defining:

(eval-after-load 'python `(evil-define-key 'normal python-mode-map [f5] 'python-shell-send-buffer))

(eval-after-load 'ess `(evil-define-key 'normal ess-mode-map [f5] 'ess-eval-buffer))

|improve this answer|||||
0

Mode specific keymaps

If you want a binding to be only active in specific mode, you have to bind it in specific mode-related keymap. E.g. bindings in python-mode-map are only active when you're in python-mode. The other binding should go respectively to ess-mode-map.

Usually keymap corresponding to the mode is just mode name + map. Not always though!

PS. Remember, that emacs modes (python-mode, ess-mode, etc.) are not the same things as vim modes!

Key translation

Easy way is to use general package (it's not part of spacemacs by default) and general-simulate-keys function . It's self-explanatory.

End result

(define-key python-mode-map
  [f8] (general-simulate-keys "C-c C-c"))

OR

(general-define-key :keymap 'python-mode-map
  [f8] (general-simulate-keys "C-c C-c"))

OR just bind specific function without translating bindings...

(define-key python-mode-map [f8] 'python-shell-send-buffer)
|improve this answer|||||
  • Thanks for your answer! So, I tried including (define-key python-mode-map [f5] (general-simulate-keys "C-c C-c")) (define-key ess-mode-map [f5] (general-simulate-keys "C-c C-b")) in my user-config function, in the .spacemacs file, but it did not work. When I hit F5 it says that F5 is undefined. – Louis15 Sep 4 '17 at 20:12
  • I just checked and general package is not part of spacemacs. You have to install it manually. Maybe it would be sufficient to bind [f8] to specific function like (define-key python-mode-map [f8] 'python-shell-send-buffer)? – mmajcher Sep 4 '17 at 20:34
  • That was my first try, to be honest. It does not work, tough. For some reason, F5 is still said to be undefined when I include exactly (define-key python-mode-map [f5] 'python-shell-send-buffer) in .spacemacs and then hit F5 with a .py file opened. – Louis15 Sep 4 '17 at 21:59
  • Mark this form (define-key ... and do M-x eval-region after you have opened py file in another window and try again. – mmajcher Sep 5 '17 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.