1

Is is possible to define key bindings for org-mode that:

  1. Only work inside code blocks;
  2. Are specific to the programming language of the code block.

For example: if my source code block is for Python, then C-c C-a runs a function that formats python code (like python black), but if the code block is for R, then C-c C-a runs a function that formats R code (like styler). If I am outside a source code block C-c C-a does not do anything.

3
  • 2
    Not an answer but do you know about C-c ' (that's C-c followed by a single quote)? That invokes the function org-edit-special which creates a separate buffer with major mode being the one specified by the code block language, so you can edit/format it at will. Another C-c ' finishes the edit by putting the resulting code back into the code block and getting rid of the buffer.
    – NickD
    Jun 10, 2020 at 3:07
  • Hi @NickD, thanks for the suggestion. I know about ord-edit-special and have been using it, but that's exactly what I am also trying to avoid by having key bindings for code blocks. Jun 10, 2020 at 14:15
  • 1
    OK - had to make sure. The link to John Kitchin's article in the answer seems to be what you are looking for.
    – NickD
    Jun 10, 2020 at 14:17

2 Answers 2

1

Have a look at Adding keymaps to src blocks by John Kitchin. It does more than you want. You can edit src blocks as you would normally edit code of that type. There is a link to a file in org-mode that you can download and evaluate to make this available for you. You will need to adapt the recipes he gives for your needs.

The major problem is defining the keymap you associate to a src block; this is done in John Kitchin's code for emacs lisp and python src blocks by requiring lispy and elpy and then using their keymaps when calling make-composed-keymap. The problem is that a user may have highly customised keys for editing, for example, python. The only way I could think of to capture all these adjustments that the user has made would be to open programmatically a buffer with a file of the type required (python for this case, so open dummy.py) and steal its keymap while in that buffer via (setq src-block-python-map (make-composed-keymap (append (current-active-maps) (list org-mode-map)))) then close this buffer and associate this monstrosity to each python src block as John Kitchin does in the linked file

2
  • Drew, I did summarise what the linked file did for someone who used it. Everything from "You can edit src blocks ,,," onwards is what you ask for. Jun 10, 2020 at 17:44
  • I have added the outline of how to make the keymaps necessary but this itself is tentative because there may be a better way.. Someone might wish to take Kitchin's file and turn it into a minor mode that does the right thing for every src block encountered. Jun 11, 2020 at 6:11
1

Sure, you can do that!

This will bind C-c c to the sexp (print "Hello JS!") when point is inside a "js" src block.

(with-eval-after-load "org" (define-key org-mode-map (kbd "C-c c")
                  (lambda () (interactive) 
                    (if (org-in-src-block-p) 
                        (let ((lang (nth 0 (org-babel-get-src-block-info))))
                          (if (string= lang "js")
                              (print "Hello JS!")))))))

And if you only want this to work INSIDE your src block (i.e., not when point is on the #+BEGIN_SRC or #+END_SRC) replace line 3 with (if (org-in-src-block-p 1).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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