14

When I'm using org-mode to take notes about a book, sometimes I'll copy/paste some code snippets into the note file. After pasting it, I'll

1. `C-c '` to call `org-edit-special`
2. `C-x h` to mark all the source code
3. `TAB` to format it

Is there a solution in org-mode for me that, after pasting code in #+BEGIN_SRC...#+END_SRC, it will automatically format the code block or I can use just one key such as TAB to format(indent) the whole source code block?

The default TAB(typed in block, not using C-c ') is just align all lines 2 columns after #+BEGIN_SRC header, if there are spaces at the beginning of the second line, it will just add more spaces, it will not indent all lines like the 3 steps.

CodyChan
  • 2,599
  • 1
  • 19
  • 33

5 Answers5

10

Below is a hard solution, but it works perfect. Actually it is just a function which simulations your operations, and use a run-at-time to make it be called every 10 seconds. Cheers.

(defun indent-org-block-automatically ()
  (when (org-in-src-block-p)
   (org-edit-special)
    (indent-region (point-min) (point-max))
    (org-edit-src-exit)))

(run-at-time 1 10 'indent-org-block-automatically)

Of course, you can make it called every 1 second, just change 10 to 1.

Leu_Grady
  • 2,420
  • 1
  • 17
  • 27
  • I don't need `run-at-time` actually, how can I bind the `TAB` key to do the these to replace the default `TAB` when `org-in-src-block-p`. The default `TAB` is bound to `yas-expand` but it will do things as I said in my post. – CodyChan Dec 29 '14 at 03:15
  • It seems like there's now an `org-indent-block` function that could be used instead of the combination of `org-edit-special` and `indent-region`. – gsgx Sep 12 '22 at 18:18
0

This is the code I wrote to solve this problem:

(defun udf/my-org-tab-dwim (&optional arg)
  (interactive)
  (or (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))
      (org-cycle arg)))

(define-key org-mode-map
  (kbd "<tab>") #'udf/my-org-tab-dwim)
kuwze
  • 191
  • 4
0

Start with https://github.com/Bruce-Connor/aggressive-indent-mode to get the paste behavior that you describe.

You know how to do the rest.

grettke
  • 240
  • 2
  • 5
0

Here is my solution, which is a combination of @Leu_Grady's and @kuwze's.

(1) Put the following snippet in .emacs:

(defun my-indent-org-block-automatically ()
  (interactive)
  (when (org-in-src-block-p)
   (org-edit-special)
   (indent-region (point-min) (point-max))
   (org-edit-src-exit)))

(define-key org-mode-map
  (kbd "C-i") #'my-indent-org-block-automatically)

(2) Press C-i when in an Org source block to auto-indent it.

0

Here's a more modern way of doing this:

(defvar orig-command (lookup-key org-mode-map (kbd "TAB")))
(define-key org-mode-map (kbd "TAB") 'my/org-indent-dwim)

(defun my/org-indent-dwim ()
  (interactive)
  (when (org-in-src-block-p)
    (save-excursion
      (org-babel-goto-src-block-head)
      (org-indent-block)))
  (funcall orig-command))

We first grab what the TAB key is originally bound to in org-mode-map, then we rebind it to my/org-indent-dwim. my/org-indent-dwim will indent the block using built-in org-mode functions, so no need to call org-edit-special. At the end, the original function that the binding was bound to is called.

gsgx
  • 188
  • 8