1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
| | ;;; org-tempo.el --- Tempo-style templates for Org -*- lexical-binding: t; -*-
;; Copyright (C) 2017 Free Software Foundation, Inc.
;;
;; Author: Rasmus Pank Roulund <emacs at pank dot eu>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;;
;; This file is part of GNU Emacs.
;;
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;
;;; Commentary:
;; Block and structure templates, to replace the previous Org-specific
;; system. The old function `org-try-structure-completion' is
;; provided as a thin wrapper around `tempo-complete-tag', for
;; backwards compatibility.
;;; Code:
(require 'tempo)
(require 'cl-lib)
(defvar org-tempo-tags nil
"Tempo tags for org-mode")
(defcustom org-structure-keyword-alist
'(("L" . "latex")
("H" . "html")
("A" . "ascii")
("i" . "index"))
"Keyword templates expanded using the tempo package."
:group 'org-tempo
:type '(repeat
(cons (string :tag "Key")
(string :tag "Template")))
:package-version '(Org . "9.2"))
(defun org-tempo-setup ()
(tempo-use-tag-list 'org-tempo-tags)
(setq tempo-match-finder "^ *\\(<[[:word:]]\\)\\="))
(add-hook 'org-mode-hook 'org-tempo-setup)
(defun org-tempo-add-templates ()
"Update all org-tempo templates.
Goes through `org-structure-block-alist' and
`org-structure-keyword-alist'."
(let ((keys (mapcar (apply-partially #'format "<%s")
(mapcar #'car (append org-structure-block-alist
org-structure-keyword-alist)))))
(if (> (length keys)
(length (delete-dups keys)))
(user-error "Duplicate keys in `org-structure-template-alist' and `org-structure-template-alist-keywords'"))
(dolist (key keys)
(if (assoc-string key org-tempo-tags)
(setq org-tempo-tags
(delete (assoc-string key org-tempo-tags)
org-tempo-tags))))
(mapc #'org-tempo-add-block org-structure-block-alist)
(mapc #'org-tempo-add-keyword org-structure-keyword-alist))
(setq tempo-dirty-collection t))
(defun org-tempo-add-block (entry)
"Add block entry from `org-structure-block-alist'."
(let* ((key (format "<%s" (car entry)))
(name (cdr entry)))
(tempo-define-template
(format "org-%s" (replace-regexp-in-string " " "-" name))
`(,(format "#+begin_%s " name) p '> n n
,(format "#+end_%s" (car (org-split-string name " ")))
>)
key
(format "Insert a %s block" name)
'org-tempo-tags)))
(defun org-tempo-add-keyword (entry)
"Add keyword entry from `org-structure-keyword-alist'."
(let* ((key (format "<%s" (car entry)))
(name (cdr entry)))
(tempo-define-template
(format "org-%s" (replace-regexp-in-string " " "-" name))
`(,(format "#+%s: " name) p '>)
key
(format "Insert a %s keyword" name)
'org-tempo-tags)))
;; Additional keywords
(tempo-define-template
"org-include"
'("#+include: "
(ignore-errors
(format "\"%s\" " (file-relative-name (read-file-name "Include file: "))))
p >)
"<I"
"Include keyword"
'org-tempo-tags)
(with-eval-after-load 'org
(org-tempo-add-templates)
(add-hook 'org-tab-before-tab-emulation-hook
'tempo-complete-tag))
(provide 'org-tempo)
;;; org-tempo.el ends here
|