summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Abrahamsen <eric@ericabrahamsen.net>2017-11-05 09:25:15 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2017-11-05 09:56:26 +0100
commitc04e357f3d5d93484277a7e439847b1233b872bd (patch)
tree404c98f6d6bba86b6230de8cd6732a6f10a95245
parentfd50740c968f515ae354747a2535a3b6655935cb (diff)
downloadorg-mode-c04e357f3d5d93484277a7e439847b1233b872bd.tar.gz
Replace easy templates with org-insert-structure-template
* lisp/org.el (org-insert-structure-template): New function for wrapping region (or element at point) in a begin/end block. (org-structure-predefined-blocks): New option holding predefined blocks, for completion. (org-try-structure-completion, org-complete-expand-structure-template): Remove functions. * doc/org.texi (Inserting structure templates): Document. * testing/lisp/test-org.el (test-org/insert-template): New test.
-rw-r--r--doc/org.texi101
-rw-r--r--etc/ORG-NEWS4
-rw-r--r--lisp/org.el132
-rw-r--r--testing/lisp/test-org.el45
4 files changed, 158 insertions, 124 deletions
diff --git a/doc/org.texi b/doc/org.texi
index 77da6d3..e116a9b 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -749,7 +749,7 @@ Specific header arguments
Miscellaneous
* Completion:: M-TAB guesses completions
-* Easy templates:: Quick insertion of structural elements
+* Structure templates:: Quick insertion of structural elements
* Speed keys:: Electric commands at the beginning of a headline
* Code evaluation security:: Org mode files evaluate inline code
* Customization:: Adapting Org to changing tastes
@@ -10108,18 +10108,16 @@ look like the fontified Emacs buffer@footnote{This works automatically for
the HTML back-end (it requires version 1.34 of the @file{htmlize.el} package,
which you need to install). Fontified code chunks in @LaTeX{} can be
achieved using either the
-@url{https://www.ctan.org/tex-archive/macros/latex/contrib/listings/?lang=en, listings,}
-or the
-@url{https://github.com/gpoore/minted, minted,} package.
+@url{https://www.ctan.org/tex-archive/macros/latex/contrib/listings/?lang=en,
+listings,} or the @url{https://github.com/gpoore/minted, minted,} package.
If you use minted or listing, you must load the packages manually, for
-example by adding the desired package to
-@code{org-latex-packages-alist}. Refer to @code{org-latex-listings}
-for details.}. This is done with the @samp{src} block, where you also need
-to specify the name of the major mode that should be used to fontify the
-example@footnote{Code in @samp{src} blocks may also be evaluated either
-interactively or on export. @xref{Working with source code}, for more
-information on evaluating code blocks.}, see @ref{Easy templates} for
-shortcuts to easily insert code blocks.
+example by adding the desired package to @code{org-latex-packages-alist}.
+Refer to @code{org-latex-listings} for details.}. This is done with the
+@samp{src} block, where you also need to specify the name of the major mode
+that should be used to fontify the example@footnote{Code in @samp{src} blocks
+may also be evaluated either interactively or on export. @xref{Working with
+source code}, for more information on evaluating code blocks.}, see
+@ref{Structure templates} for shortcuts to easily insert code blocks.
@cindex #+BEGIN_SRC
@example
@@ -10185,9 +10183,8 @@ If the syntax for the label format conflicts with the language syntax, use a
HTML export also allows examples to be published as text areas (@pxref{Text
areas in HTML export}).
-Because the @code{#+BEGIN_...} and @code{#+END_...} patterns need to be added
-so often, shortcuts are provided using the Easy templates facility
-(@pxref{Easy templates}).
+Because the @code{#+BEGIN_...} @dots{} @code{#+END_...} patterns need to be
+added so often, a shortcut is provided (@pxref{Structure templates}).
@table @kbd
@kindex C-c '
@@ -15243,12 +15240,12 @@ A @samp{src} block conforms to this structure:
#+END_SRC
@end example
-Org mode's templates system (@pxref{Easy templates}) speeds up creating
-@samp{src} code blocks with just three keystrokes. Do not be put-off by
-having to remember the source block syntax. Org also works with other
-completion systems in Emacs, some of which predate Org and have custom
-domain-specific languages for defining templates. Regular use of templates
-reduces errors, increases accuracy, and maintains consistency.
+Do not be put-off by having to remember the source block syntax. Org mode
+offers a command for wrapping existing text in a block (@pxref{Structure
+templates}). Org also works with other completion systems in Emacs, some of
+which predate Org and have custom domain-specific languages for defining
+templates. Regular use of templates reduces errors, increases accuracy, and
+maintains consistency.
@cindex source code, inline
An inline code block conforms to this structure:
@@ -17299,7 +17296,7 @@ emacs -Q --batch --eval "
@menu
* Completion:: M-TAB guesses completions
-* Easy templates:: Quick insertion of structural elements
+* Structure templates:: Quick insertion of structural elements
* Speed keys:: Electric commands at the beginning of a headline
* Code evaluation security:: Org mode files evaluate inline code
* Customization:: Adapting Org to changing tastes
@@ -17374,46 +17371,40 @@ If your desktop intercepts the combo @kbd{M-@key{TAB}} to switch windows, use
environment.
@end table
-@node Easy templates
-@section Easy templates
+@node Structure templates
+@section Structure templates
@cindex template insertion
@cindex insertion, of templates
-With just a few keystrokes, Org's easy templates inserts empty pairs of
-structural elements, such as @code{#+BEGIN_SRC} and @code{#+END_SRC}. Easy
-templates use an expansion mechanism, which is native to Org, in a process
-similar to @file{yasnippet} and other Emacs template expansion packages.
+With just a few keystrokes, it is possible to insert empty structural blocks,
+such as @samp{#+BEGIN_SRC} @dots{} @samp{#+END_SRC}, or to wrap existing text
+in such a block.
-@kbd{<} @kbd{s} @kbd{@key{TAB}} expands to a @samp{src} code block.
-
-@kbd{<} @kbd{l} @kbd{@key{TAB}} expands to:
-
-#+BEGIN_EXPORT latex
-
-#+END_EXPORT
+@table @kbd
+@orgcmd{C-c C-x w,org-insert-structure-template}
+Prompt for a type of block structure, and insert the block at point. If the
+region is active, it is wrapped in the block. First prompts the user for
+a key, which is used to look up a structure type from the values below. If
+the key is @key{TAB}, the user is prompted to enter a type.
+@end table
-Org comes with these pre-defined easy templates:
-
-@multitable @columnfractions 0.1 0.9
-@item @kbd{s} @tab @code{#+BEGIN_SRC ... #+END_SRC}
-@item @kbd{e} @tab @code{#+BEGIN_EXAMPLE ... #+END_EXAMPLE}
-@item @kbd{q} @tab @code{#+BEGIN_QUOTE ... #+END_QUOTE}
-@item @kbd{v} @tab @code{#+BEGIN_VERSE ... #+END_VERSE}
-@item @kbd{c} @tab @code{#+BEGIN_CENTER ... #+END_CENTER}
-@item @kbd{C} @tab @code{#+BEGIN_COMMENT ... #+END_COMMENT}
-@item @kbd{l} @tab @code{#+BEGIN_EXPORT latex ... #+END_EXPORT}
-@item @kbd{L} @tab @code{#+LATEX:}
-@item @kbd{h} @tab @code{#+BEGIN_EXPORT html ... #+END_EXPORT}
-@item @kbd{H} @tab @code{#+HTML:}
-@item @kbd{a} @tab @code{#+BEGIN_EXPORT ascii ... #+END_EXPORT}
-@item @kbd{A} @tab @code{#+ASCII:}
-@item @kbd{i} @tab @code{#+INDEX:} line
-@item @kbd{I} @tab @code{#+INCLUDE:} line
+@vindex org-structure-template-alist
+Available structure types are defined in @code{org-structure-template-alist},
+see the docstring for adding or changing values.
+
+@multitable @columnfractions 0.2 0.8
+@item @kbd{c} @tab @samp{#+BEGIN_CENTER}
+@item @kbd{C} @tab @samp{#+BEGIN_COMMENT}
+@item @kbd{e} @tab @samp{#+BEGIN_EXAMPLE}
+@item @kbd{E} @tab @samp{#+BEGIN_EXPORT}
+@item @kbd{a} @tab @samp{#+BEGIN_EXPORT ascii}
+@item @kbd{h} @tab @samp{#+BEGIN_EXPORT html}
+@item @kbd{l} @tab @samp{#+BEGIN_EXPORT latex}
+@item @kbd{s} @tab @samp{#+BEGIN_SRC}
+@item @kbd{q} @tab @samp{#+BEGIN_QUOTE}
+@item @kbd{v} @tab @samp{#+BEGIN_VERSE}
@end multitable
-More templates can added by customizing the variable
-@code{org-structure-template-alist}, whose docstring has additional details.
-
@node Speed keys
@section Speed keys
@cindex speed keys
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 391ef94..97ccf88 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -149,6 +149,10 @@ you should expect to see something like:
#+END_EXAMPLE
** New functions
+*** ~org-insert-structure-template~
+
+This function can be used to wrap existing text of Org elements in
+a #+BEGIN_FOO/#+END_FOO block. Bound to C-c C-x w by default.
*** ~org-export-excluded-from-toc-p~
diff --git a/lisp/org.el b/lisp/org.el
index 78a0b47..f873f10 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6740,8 +6740,6 @@ Use `\\[org-edit-special]' to edit table.el tables"))
((run-hook-with-args-until-success
'org-tab-after-check-for-cycling-hook))
- ((org-try-structure-completion))
-
((run-hook-with-args-until-success
'org-tab-before-tab-emulation-hook))
@@ -11859,76 +11857,71 @@ keywords relative to each registered export back-end."
"TITLE:" "TODO:" "TYP_TODO:" "SELECT_TAGS:" "EXCLUDE_TAGS:"))
(defcustom org-structure-template-alist
- '(("s" "#+BEGIN_SRC ?\n\n#+END_SRC")
- ("e" "#+BEGIN_EXAMPLE\n?\n#+END_EXAMPLE")
- ("q" "#+BEGIN_QUOTE\n?\n#+END_QUOTE")
- ("v" "#+BEGIN_VERSE\n?\n#+END_VERSE")
- ("V" "#+BEGIN_VERBATIM\n?\n#+END_VERBATIM")
- ("c" "#+BEGIN_CENTER\n?\n#+END_CENTER")
- ("C" "#+BEGIN_COMMENT\n?\n#+END_COMMENT")
- ("l" "#+BEGIN_EXPORT latex\n?\n#+END_EXPORT")
- ("L" "#+LaTeX: ")
- ("h" "#+BEGIN_EXPORT html\n?\n#+END_EXPORT")
- ("H" "#+HTML: ")
- ("a" "#+BEGIN_EXPORT ascii\n?\n#+END_EXPORT")
- ("A" "#+ASCII: ")
- ("i" "#+INDEX: ?")
- ("I" "#+INCLUDE: %file ?"))
+ '((?a . "export ascii")
+ (?c . "center")
+ (?C . "comment")
+ (?e . "example")
+ (?E . "export")
+ (?h . "export html")
+ (?l . "export latex")
+ (?q . "quote")
+ (?s . "src")
+ (?v . "verse"))
"Structure completion elements.
-This is a list of abbreviation keys and values. The value gets inserted
-if you type `<' followed by the key and then press the completion key,
-usually `TAB'. %file will be replaced by a file name after prompting
-for the file using completion. The cursor will be placed at the position
-of the `?' in the template.
-There are two templates for each key, the first uses the original Org syntax,
-the second uses Emacs Muse-like syntax tags. These Muse-like tags become
-the default when the /org-mtags.el/ module has been loaded. See also the
-variable `org-mtags-prefer-muse-templates'."
+This is an alist of characters and values. When
+`org-insert-structure-template' is called, an additional key is
+read. The key is first looked up in this alist, and the
+corresponding structure is inserted, with \"#+BEGIN_\" and
+\"#+END_\" added automatically."
:group 'org-completion
:type '(repeat
- (list
- (string :tag "Key")
- (string :tag "Template")))
- :version "26.1"
- :package-version '(Org . "8.3"))
-
-(defun org-try-structure-completion ()
- "Try to complete a structure template before point.
-This looks for strings like \"<e\" on an otherwise empty line and
-expands them."
- (let ((l (buffer-substring (point-at-bol) (point)))
- a)
- (when (and (looking-at "[ \t]*$")
- (string-match "^[ \t]*<\\([a-zA-Z]+\\)$" l)
- (setq a (assoc (match-string 1 l) org-structure-template-alist)))
- (org-complete-expand-structure-template (+ -1 (point-at-bol)
- (match-beginning 1)) a)
- t)))
-
-(defun org-complete-expand-structure-template (start cell)
- "Expand a structure template."
- (let ((rpl (nth 1 cell))
- (ind ""))
- (delete-region start (point))
- (when (string-match "\\`[ \t]*#\\+" rpl)
- (cond
- ((bolp))
- ((not (string-match "\\S-" (buffer-substring (point-at-bol) (point))))
- (setq ind (buffer-substring (point-at-bol) (point))))
- (t (newline))))
- (setq start (point))
- (when (string-match "%file" rpl)
- (setq rpl (replace-match
- (concat
- "\""
- (save-match-data
- (abbreviate-file-name (read-file-name "Include file: ")))
- "\"")
- t t rpl)))
- (setq rpl (mapconcat 'identity (split-string rpl "\n")
- (concat "\n" ind)))
- (insert rpl)
- (when (re-search-backward "\\?" start t) (delete-char 1))))
+ (cons (character :tag "Key")
+ (string :tag "Template")))
+ :package-version '(Org . "9.2"))
+
+(defun org-insert-structure-template (type)
+ "Insert a block structure of the type #+begin_foo/#+end_foo.
+First read a character, which can be one of the keys in
+`org-structure-template-alist'. When it is <TAB>, prompt the
+user for a string to use. With an active region, wrap the region
+in the block. Otherwise, insert an empty block."
+ (interactive
+ (list
+ (let* ((key (read-key "Key: "))
+ (struct-string
+ (or (cdr (assq key org-structure-template-alist))
+ (and (= key ?\t)
+ (read-string "Structure type: "))
+ (user-error "`%c' has no structure definition" key))))
+ struct-string)))
+ (let* ((region? (use-region-p))
+ (s (if region? (region-beginning) (point)))
+ (e (copy-marker (if region? (region-end) (point)) t))
+ column)
+ (when (string-match-p
+ (concat "\\`" (regexp-opt '("example" "export" "src")))
+ type)
+ (org-escape-code-in-region s e))
+ (goto-char s)
+ (setq column (current-indentation))
+ (beginning-of-line)
+ (indent-to column)
+ (insert (format "#+begin_%s\n" type))
+ (goto-char e)
+ (if (bolp)
+ (progn
+ (skip-chars-backward " \n\t")
+ (forward-line))
+ (end-of-line)
+ (insert "\n"))
+ (indent-to column)
+ (insert (format "#+end_%s\n"
+ (car (split-string type))))
+ (when (or (not region?)
+ (string-match-p "src\\|\\`export\\'" type))
+ (goto-char s)
+ (end-of-line))
+ (set-marker e nil)))
;;;; TODO, DEADLINE, Comments
@@ -19393,6 +19386,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mode-map "\C-c\C-xE" 'org-inc-effort)
(org-defkey org-mode-map "\C-c\C-xo" 'org-toggle-ordered-property)
(org-defkey org-mode-map "\C-c\C-xi" 'org-columns-insert-dblock)
+(org-defkey org-mode-map "\C-c\C-xw" 'org-insert-structure-template)
(org-defkey org-mode-map [(control ?c) (control ?x) ?\;] 'org-timer-set-timer)
(org-defkey org-mode-map "\C-c\C-x." 'org-timer)
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 379ded6..4a307ef 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -4000,6 +4000,51 @@ Text.
(org-next-block 1 nil "^[ \t]*#\\+BEGIN_QUOTE")
(looking-at "#\\+begin_quote")))))
+(ert-deftest test-org/insert-template ()
+ "Test `org-insert-structure-template'."
+ ;; Test in empty buffer.
+ (should
+ (string= "#+begin_foo\n#+end_foo\n"
+ (org-test-with-temp-text ""
+ (org-insert-structure-template "foo")
+ (buffer-string))))
+ ;; Test with multiple lines in buffer.
+ (should
+ (string= "#+begin_foo\nI'm a paragraph\n#+end_foo\n\nI'm a second paragraph"
+ (org-test-with-temp-text "I'm a paragraph\n\nI'm a second paragraph"
+ (org-mark-element)
+ (org-insert-structure-template "foo")
+ (buffer-string))))
+ ;; Test with text in buffer, no region, no final newline.
+ (should
+ (string= "#+begin_foo\nI'm a paragraph.\n#+end_foo\n"
+ (org-test-with-temp-text "I'm a paragraph."
+ (org-mark-element)
+ (org-insert-structure-template "foo")
+ (buffer-string))))
+ ;; Test with text in buffer and region set.
+ (should
+ (string= "#+begin_foo\nI'm a paragraph\n\nI'm a second paragrah\n#+end_foo\n"
+ (org-test-with-temp-text "I'm a paragraph\n\nI'm a second paragrah"
+ (set-mark (point))
+ (goto-char (point-max))
+ (org-insert-structure-template "foo")
+ (buffer-string))))
+ ;; Test with example escaping.
+ (should
+ (string= "#+begin_example\n,* Heading\n#+end_example\n"
+ (org-test-with-temp-text "* Heading"
+ (org-mark-element)
+ (org-insert-structure-template "example")
+ (buffer-string))))
+ ;; Test with indentation.
+ (should
+ (string= " #+begin_foo\n This is a paragraph\n #+end_foo\n"
+ (org-test-with-temp-text " This is a paragraph"
+ (org-mark-element)
+ (org-insert-structure-template "foo")
+ (buffer-string)))))
+
(ert-deftest test-org/previous-block ()
"Test `org-previous-block' specifications."
;; Regular test.