org-mode has the ability to render source code, with blocks of the following syntax:

#+NAME: <name>
#+BEGIN_SRC <language> <switches> <header arguments>

Is there an existing command to quickly insert these blocks in org-mode, or do I need to use an external tool like yasnippet?


As @kaushalmodi mentions in the comments you can use (org) Structure Templates to speed up insertion of different types of blocks.

The general procedure is to insert < followed by a template selector (usually a single letter) on an otherwise empty line and press TAB.

The template selector for a generic source block template is s, so typing <s followed by TAB will give you this:



Point will be positioned at the end of the first line.

This is a good first approximation of what you want to achieve, but this is Emacs, so let's make it better!

You can define custom templates by adding one or more entries to a variable called org-structure-template-alist. For example:

(add-to-list 'org-structure-template-alist '("n" "#+NAME: ?"))

This code adds a #+NAME: template to org-structure-template-alist, using n as a template selector. After expanding this template point will be positioned at the location of ?.

If you always name your code blocks, you can also overwrite the original version of the source block template with an extended version that includes the #+NAME: line:

(add-to-list 'org-structure-template-alist
             '("s" "#+NAME: ?\n#+BEGIN_SRC \n\n#+END_SRC"))

Typing <s followed by TAB will then give you:



This is just the tip of the iceberg; you can use a similar approach to define additional templates for language-specific code blocks, code blocks with specific header arguments, etc.

  • 3
    Note: Easy Template is replaced with incompatible way in org-mode HEAD. I recommend to use yasnippet.
    – lurdan
    Apr 9 '18 at 7:17
  • @lurdan is this still the case? I just tried <s TAB on Emacs 25 on Mac OS X and it seemed to work. Oct 23 '18 at 15:53
  • 2
    @RudolfOlah Yes, at least for org-mode (git) HEAD. Even with emacs26, bundled org-mode still has org-try-structure-completion function (for Easy-templates). But anyway, it will be replaced by Structure-templates in the future. cf. code.orgmode.org/bzg/org-mode/commit/…
    – lurdan
    Oct 25 '18 at 7:30
  • 7
    You now need (require 'org-tempo) to use <s TAB, but otherwise it works just as before.
    – Clément
    Feb 10 '20 at 17:39
  • 9
    Nowadays it's C-c C-, which runs (org-insert-structure-template)
    – mgalgs
    Jan 8 '21 at 19:24

Here's a function which inserts the code block:

(defun org-insert-source-block (name language switches header)
  "Asks name, language, switches, header.
Inserts org-mode source code snippet"
  (interactive "sname? 
sheader? ")
   (if (string= name "")
     (concat "#+NAME: " name) )
   (format "
#+BEGIN_SRC %s %s %s

#+END_SRC" language switches header
  (forward-line -1)
  (goto-char (line-end-position))
  • Because it’s better to have an org function to call than to copy-paste stuff from SE (people could write it themselves, but that’s probably what would happen). Oct 17 '20 at 9:38

With just a few keystrokes, it is possible to insert empty structural blocks, such as ‘#+BEGIN_SRC’ … ‘#+END_SRC’, or to wrap existing text in such a block.

C-c C-, (org-insert-structure-template)


  • I used to use Easy Templates, but this way is quite better for me. Thanks.
    – gsl
    Apr 17 '20 at 11:22
  • C-c C-, means I hit c and then hit , with the Ctrl pressed? it does not work for me.
    – ZhaoGang
    May 21 '21 at 2:39
  • C-, might not work in a terminal: it should work in GUI Emacs. You can always bind a different key to the function though: (define-key org-mode-map (kbd "C-c e") #'org-insert-structure-template). This is just an example: choose a key that is not used already.
    – NickD
    Jul 8 '21 at 16:38

On my box 99% of the time I'm creating source blocks and 1% of the time I'm doing everything else. For the 1% Easy Templates are perfect and for the 99% I've got a YaSnippet.

  • It creates a unique NAME using org-id but that doesn't matter just us anything) and then it asks me what language I want to use limiting it those the ones that I told Org-Mode Literate Programming (babel)
  • Presents a list of language types that you told Org-Mode that you want to use, and to choose from, instead of typing every type (though I don't use all of them)
  • If the language has to generates a file it asks for the output file name

Here is the YaSnippet with my supporting code at the end.

# -*- mode: snippet -*-
# key: sc
# name: Source Block
# group: HELP
# contributor: gcr@wisdomandwonder.com
# expand-env: ((yas-indent-line 'fixed))
# --
#+NAME: ${1:`(help/org-id-new)`}
#+BEGIN_SRC ${2:$$(let ((langs (sort (-map (lambda (x) (symbol-name (car x))) (if (-contains? org-babel-load-languages '(js . t)) (-snoc org-babel-load-languages '(javascript . t)) org-babel-do-load-languages)) 'string<))) (yas-choose-value (if (-contains? langs "shell") (-snoc langs "sh") langs)))}${2:$(when (-contains? '("ditaa" "dot" "plantuml") yas-text) (concat " :file \\"./image/" (yas-field-value 1) ".png\\""))} $3

It requires dash and org-mode loaded.

(require 'org-id)
(setq org-id-link-to-org-use-id 'nil)
(setq org-id-prefix (concat "org_" (user-real-login-name) "_" (format-time-string "%Y-%m-%d") "_" (system-name)))
(setq org-id-method 'uuid)
(defun help/org-id-new ()
  "Re-purposing `org-id' hit a snag when colons were forbidden in Source-Block
  names. Adding support for a user-defined Org-Id separator would have fixed
  this but with no benefit to Org-Id. So this function removes the colon
  (let* ((gend (org-id-new))
         (newid (replace-regexp-in-string ":" "_" gend)))

Here is an example of you might this id function:

C-u M-:
(insert (help/org-id-new))

Results in

;;; package --- Summary
;;; Commentary:
;;; Code:
(defvar org-sai-src-default "C++"
 "This is the list used to store the default label for source code section.")

(defun org-insert-src-block ()
  "Insert the source code section in `org-mode'."
  (let* ((src-code-types
          '("emacs-lisp" "python" "C" "sh" "java" "js" "clojure" "C++" "css"
            "calc" "asymptote" "dot" "gnuplot" "ledger" "lilypond" "mscgen"
            "octave" "oz" "plantuml" "R" "sass" "screen" "sql" "awk" "ditaa"
            "haskell" "latex" "lisp" "matlab" "ocaml" "org" "perl" "ruby"
            "scheme" "sqlite"))
          (concat "Source code type (default "
                  "): "))
          (cons org-sai-src-default src-code-types))
          (completing-read src-prompt-str temp-src-code-types
                           nil nil nil nil org-sai-src-default)))
    (setq org-sai-src-default src-type-str))
    (insert (format "#+BEGIN_SRC %s\n" src-type-str))
    (insert "#+END_SRC\n")
    (forward-line -2))))

(add-hook 'org-mode-hook
          (lambda ()
            ;; keybinding for inserting code blocks
            (local-set-key (kbd "C-c s") 'org-insert-src-block)))

(provide 'orgAuxiliary)
;;; orgAuxiliary.el ends here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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