2

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?

Louis15
  • 263
  • 3
  • 9

2 Answers2

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 evil-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))
Drew
  • 75,699
  • 9
  • 109
  • 225
Louis15
  • 263
  • 3
  • 9
  • By '...defined with eval-define-key' I think mean '...defined with evil-define-key', right? – DJBunk Oct 31 '21 at 15:02
  • Also - this doesn't quite seem to work like this I expected. When I use your f5 binding (put it in the dotspacemacs/user-config function) that binding is not present when I load an R console using ess - I have to load the R console then re-load my spacemacs config for this keybinding to take effect. Is this the intended effect, or should the keybinding be present whenever I load an R console using ess? – DJBunk Oct 31 '21 at 17:05
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)
mmajcher
  • 96
  • 3
  • 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 04 '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 04 '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 04 '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 05 '17 at 09:16