I'm looking for an easy way to highlight a chunk of text inside a Babel source block (not the entire block) and execute that inside the current session (creating the new session buffer if necessary). In my case, it's almost always R code, but theoretically I guess it should sense the language of the block the same way Ctrl-c does.

I don't need the results inserted back in the org buffer, I'm only executing for side effects like defining variables, etc., similar to hitting Cmd-Return in RStudio.

3 Answers 3


There is a somewhat hacky solution. The following advice re-defines the source code string returned by org-babel-get-src-block-info if the region is active within this source code block and it is the top-level source code block. You can switch off this behavior by setting the org-babel-region to nil.

(defcustom org-babel-region t
  "Restrict execution to region."
  :type 'boolean
  :group 'org-babel)

(defadvice org-babel-get-src-block-info (after org-babel-src-region activate)
  "Restrict org-babel execution to region
  if region is active within this source code block
  and it is the top-level source code block."
  ;; source code block string is (nth 1 (org-babel-get-src-block-info))
  ;; head marker is (last (org-babel-get-src-block-info))
  ;; the outer-most src code block is stored in variable `org-babel-current-src-block-location'
  (let (head-marker b e)
    (and org-babel-region
     (setq head-marker (car (last ad-return-value)))
     (equal org-babel-current-src-block-location head-marker)
     (setq b (region-beginning) e (region-end))
       (and (goto-char b)
        (equal head-marker (org-babel-where-is-src-block-head))
        (goto-char e)
        (equal head-marker (org-babel-where-is-src-block-head))))
     (setf (nth 1 ad-return-value)
           (buffer-substring-no-properties b e)))))

I have tested the advice with code blocks for emacs-lisp and sh. I do not have R but it should work for R too.

In the current implementation output remains enabled for the evaluation of a region if it is enabled for the whole source code block (e.g., in the header arguments).

This may be a catch. There are some source code blocks where you must print the output within the source code block or you get an error. In this case you will get an error if the selected region does not include the print directives, i.e., in most cases the end of the source code block.


Here my version; integrated some scimax functions. Please see the comment for required package and improvements.

Should work on any language. The code does not print nor return at the moment

(defun babel-eval-region ()


    (let* ((el (org-element-context))
         (p (point))
         (language (org-element-property :language el))
         (switches (org-element-property :switches el))
         (parameters (org-element-property :parameters el)))

    (insert (format "\n#+END_SRC
               ,#+BEGIN_SRC %s %s %s\n" language (or switches "") (or parameters "")))


    (insert (format "\n#+END_SRC
               ,#+BEGIN_SRC %s %s %s\n" language (or switches "") (or parameters ""))))


      (previous-line 3)
      (kill-line 3)

      (kill-line 1)
      (setq p2 (point))
      (search-backward "#+END_SRC")
      (delete-region p2 (point))
      (kill-line 1)

    (run-with-idle-timer 2 nil
        (lambda ()
          (message "%s" (propertize "region executed" 'face '(:foreground "red")))
          (run-with-idle-timer 3 nil
              (lambda ()
            (message nil)))))


It is important that the cursor stays at the end of the marked region before running the function. You can type C-x C-x which should bounded to exchange-point-and-mark if your cursor is at the beginning of the region.

  • This uses incf which requires cl which is deprecated. Better (require cl-lib and) use cl-incf.
    – Stefan
    Apr 10, 2020 at 15:41
  • thank you stefan. I will change it at some point when I have time.
    – mhass
    Apr 10, 2020 at 20:40

Here is a contemporary (2023-10) version of Tobias' approach:

  (advice-add 'org-babel--normalize-body
            :filter-return #'(lambda (orig-result)
                               "Return contents of region if it is active."
                               (if (use-region-p)
                                   (buffer-substring (region-beginning) (region-end))

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.