Files
doomemacs/modules/lang/org/+babel.el
Henrik Lissner 98b439e3bb Refactor lang/org +babel lazy loader for src blocks
Exposes +org-babel-load-functions, which are a list of functions that
will be tried in order to load the dependencies of a src block.
2018-05-30 18:11:12 +02:00

53 lines
2.3 KiB
EmacsLisp

;;; lang/org/+babel.el -*- lexical-binding: t; -*-
(add-hook 'org-load-hook #'+org|init-babel)
(defvar +org-babel-mode-alist
'(("cpp" . C)
("C++" . C)
("D" . C)
("sh" . shell)
("bash" . shell)
("matlab" . octave))
"An alist that maps languages to babel libraries. This is necessary for babel
libraries (ob-*.el) that don't match the name of the language.")
(defvar +org-babel-load-functions ()
"A list of functions that are used to try to load the current executing src
block. They take one argument (the language specified in the src block, as
string). Stops at the first function to return non-nil.")
(defun +org|init-babel ()
(setq org-src-fontify-natively t ; make code pretty
org-src-preserve-indentation t ; use native major-mode indentation
org-src-tab-acts-natively t
org-src-window-setup 'current-window
org-confirm-babel-evaluate nil) ; you don't need my permission
(defun +org*babel-execute-src-block (orig-fn &rest args)
"Load babel libraries as needed when babel blocks are executed."
(let* ((language (org-element-property :language (org-element-at-point)))
(lang-sym (intern language)))
(when (and (not (cdr (assq lang-sym org-babel-load-languages)))
(or (run-hook-with-args-until-success '+org-babel-load-functions language)
(require
(intern (format "ob-%s"
(or (cdr (assoc (downcase language) +org-babel-mode-alist))
language)))
nil t)))
(map-put org-babel-load-languages lang-sym t))
(apply orig-fn args)))
(advice-add #'org-babel-execute-src-block :around #'+org*babel-execute-src-block)
;; I prefer C-c C-c for confirming over the default C-c '
(map! :map org-src-mode-map "C-c C-c" #'org-edit-src-exit)
;; In a recent update, `org-babel-get-header' was removed from org-mode, which
;; is something a fair number of babel plugins use. So until those plugins
;; update, this polyfill will do:
(defun org-babel-get-header (params key &optional others)
(cl-loop with fn = (if others #'not #'identity)
for p in params
if (funcall fn (eq (car p) key))
collect p)))