64

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

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

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

93

As @kaushalmodi mentions in the comments you can use (org) Easy 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:

#+BEGIN_SRC 

#+END_SRC

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:

#+NAME: 
#+BEGIN_SRC 

#+END_SRC

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.

  • 2
    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. – Rudolf Olah Oct 23 '18 at 15:53
  • 1
    @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
14

Why not write it yourself?

(defun org-insert-source-block (name language switches header)
  "Asks name, language, switches, header.
Inserts org-mode source code snippet"
  (interactive "sname? 
slanguage? 
sswitches? 
sheader? ")
  (insert 
   (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))
  )
6

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
$0
#+END_SRC

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
  instead.
 "
  (interactive)
  (let* ((gend (org-id-new))
         (newid (replace-regexp-in-string ":" "_" gend)))
    newid))

Here is an example of you might this id function:

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

Results in

org_gcr_2017-08-06_mara_DD608C9A-33B0-4A8D-9123-298746BE973Anil
2
;;; 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'."
  (interactive)
  (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"))
         (src-prompt-str
          (concat "Source code type (default "
                  org-sai-src-default
                  "): "))
         (temp-src-code-types 
          (cons org-sai-src-default src-code-types))
         (src-type-str
          (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))
    (newline)
    (org-indent-line)
    (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.