When using a C++ source block in org-mode, the indentation doesn't match that of the C++ major mode.

Viewing the source block in the org file:

Indentation in org file

Viewing the same code in a C++ mode buffer or using org-edit-special:

Indentation with C++ major mode

In the major mode buffer, the indentation is correctly treated as spaces as per my configuration

(use-package cc-mode
  (defun my-c-mode-common-hook ()
    (c-set-offset 'substatement-open 0)
    (setq c++-tab-always-indent t)
    (setq c-basic-offset 4)
    (setq c-indent-level 4)
    (setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60))
    (setq tab-width 4)
    (setq indent-tabs-mode t))
  (add-hook 'c-mode-common-hook 'my-c-mode-common-hook))

whereas in the source block they are treated as 6 characters wide tabs. The way the indentation is treated simply switches between being a tab and being 4 spaces, when I switch between the org-edit-special environment and the plain org file.

The relevant part of my configuration:

(setq org-src-preserve-indentation nil)
(setq org-src-tab-acts-natively t)
(setq org-edit-src-content-indentation 0)
  '((emacs-lisp . t)
    (C . t)))

I would be fine with the editing being wonky in the org file, but I would very much prefer the display of the code being correct. How could I accomplish this?

1 Answer 1


That’s because an org buffer is in org-mode, not c++-mode. This is expected; the indentation rules for org files are nothing like those of C++ files, and the indentation rules don’t magically change just because you’re inside of a source block.

You can run org-babel-expand-src-block (bound to C-c C-v v by default) to open the content of the source block in a new buffer. That new buffer will be in the correct mode for the language. Once you’re done editing it, hit C-c C-c to save it back to your org file.


Now I see that you are indenting your files with tab characters. Each buffer has a single value for tab-width which controls how wide a tab is. You can’t have tabs be a different size in one part of the buffer than another.

  • If I have a python source block, the behaves as I expect, 4 spaces. Why is this behavior different than the C++ block if the indentation rules are not affected by the fact that you are inside of a source block? There must be a way to affect how indentation is treated inside of a source block depending on the language used in the source block. This is what I expect the setting org-src-tab-acts-natively to accomplish. As per the documentation: "If non-nil, the effect of TAB in a code block is as if it were issued in the language major mode buffer."
    – dag-h
    Oct 13, 2022 at 18:47
  • To add, my concern is not mainly on the editing part, but on how it is displayed in the org buffer. Even if I edit the source block with org-babel-expand-src-block and get the desired indentation while editing, when saving it back to the file, it saves it with 6-character wide tab characters instead.
    – dag-h
    Oct 13, 2022 at 18:52
  • Oh, you’re using tab characters.
    – db48x
    Oct 14, 2022 at 1:17
  • I don't want to use tab characters. If I edit C++ code in a major mode buffer, the tab key inserts 4 spaces. If I edit Python code in a major mode buffer, it also inserts 4 spaces. If I edit C++ code in a source block, the tab key inserts a 6-wide tab character. If I edit Python code in a source block, the tab key inserts 4 spaces. If I edit C++ code using org-edit-special, use the tab key to insert 4 spaces, and then save the code back to the org-mode buffer, the 4 spaces gets converted into a 6 character wide tab key again.
    – dag-h
    Oct 15, 2022 at 8:02

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.