* [patch] structure snippet completions
@ 2017-12-04 16:22 Rasmus
2017-12-04 20:55 ` Nicolas Goaziou
2017-12-04 21:37 ` Eric Abrahamsen
0 siblings, 2 replies; 18+ messages in thread
From: Rasmus @ 2017-12-04 16:22 UTC (permalink / raw)
To: emacs-orgmode; +Cc: eric
[-- Attachment #1: Type: text/plain, Size: 427 bytes --]
Hi,
The attached patch adds expansions of "<s"-like snippets to Org v9.2. I
would like to include this in the next version of Org in anticipation of
the changes to the template system.
In at least emacs-git it "just works" after requiring org-tempo.
Since it currently uses with-eval-after-load it would require Emacs 24.4,
but this could be changed to eval-after-load if necessary.
Thanks,
Rasmus
--
What will be next?
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-tempo.el-New-file-for-expansion-of-templates.patch --]
[-- Type: text/x-patch, Size: 7717 bytes --]
From d5e3eacea38d3777f541f5abddebed04171650b6 Mon Sep 17 00:00:00 2001
From: Rasmus <rasmus@gmx.us>
Date: Thu, 9 Nov 2017 16:47:13 +0100
Subject: [PATCH 1/2] org-tempo.el: New file for expansion of templates
* lisp/org-tempo.el: New file.
* doc/org.texi (Structure templates):
* etc/ORG-NEWS: Document new library.
* lisp/org.el (org-modules): Add org-tempo.
---
doc/org.texi | 9 ++++
etc/ORG-NEWS | 4 +-
lisp/org-tempo.el | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
lisp/org.el | 1 +
4 files changed, 146 insertions(+), 1 deletion(-)
create mode 100644 lisp/org-tempo.el
diff --git a/doc/org.texi b/doc/org.texi
index 5becb0175..17092ecbe 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -17396,6 +17396,15 @@ the key is @key{TAB}, the user is prompted to enter a type.
Available structure types are defined in @code{org-structure-template-alist},
see the docstring for adding or changing values.
+@vindex org-tempo
+@vindex org-tempo-keywords-alist
+@code{org-tempo} can be used to expand snippets to structures defined in
+@code{org-structure-template-alist} and @code{org-tempo-keywords-alist}. For
+example, @code{org-tempo} makes @kbd{<} @kbd{s} @kbd{@key{TAB}} expand to a
+@samp{src} code block. Enable it by customizing @code{org-modules} or add
+@code{(require 'org-tempo)} to your Emacs init file@footnote{For more
+information, please refer to the commentary section in @code{org-tempo.el}}.
+
@multitable @columnfractions 0.2 0.8
@item @kbd{c} @tab @samp{#+BEGIN_CENTER}
@item @kbd{C} @tab @samp{#+BEGIN_COMMENT}
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 66865ffe1..9d6c91ef3 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -72,6 +72,8 @@ document, use =shrink= value instead, or in addition to align:
#+END_EXAMPLE
** New features
+*** ~org-tempo~ may used for snippet expansion of structure template.
+See manual and commentary in ~org-tempo.el~ for details.
*** Exclude unnumbered headlines from table of contents
Set their =UNNUMBERED= property to the special =notoc= value. See
manual for details.
@@ -167,7 +169,7 @@ See docstring for details.
** Removed functions
*** ~org-try-structure-completion~
-
+=org-tempo= may be used as a replacement.
** Removed variables
*** org-babel-use-quick-and-dirty-noweb-expansion
diff --git a/lisp/org-tempo.el b/lisp/org-tempo.el
new file mode 100644
index 000000000..666954e1b
--- /dev/null
+++ b/lisp/org-tempo.el
@@ -0,0 +1,133 @@
+;;; org-tempo.el --- template expansion for org structures -*- 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:
+;;
+;; org-tempo reimplements completions of structure template before
+;; point like `org-try-structure-completion' in Org v9.1 and earlier.
+;; For example, strings like "<e" at the beginning of the line will be
+;; expanded to an example block.
+;;
+;; All blocks defined in `org-structure-template-alist' are added as
+;; org-tempo shortcuts, in addition to keywords defined in
+;; `org-tempo-keywords-alist'.
+;;
+;; `tempo' can also be used to define more sophisticated keywords
+;; completions. See the section "Additional keywords" below for
+;; additional details.
+;;
+;;; Code:
+
+(require 'tempo)
+(require 'cl-lib)
+
+(defvar org-tempo-tags nil
+ "Tempo tags for org-mode")
+
+(defcustom org-tempo-keywords-alist
+ '((?L . "latex")
+ (?H . "html")
+ (?A . "ascii")
+ (?i . "index"))
+ "Keyword templates like `org-structure-template-alist'."
+ :group 'org-tempo
+ :type '(repeat
+ (cons (character :tag "Key")
+ (string :tag "Template")))
+ :package-version '(Org . "9.2"))
+
+(defun org-tempo-setup ()
+ (org-tempo-add-templates)
+ (tempo-use-tag-list 'org-tempo-tags)
+ (setq-local tempo-match-finder "^ *\\(<[[:word:]]\\)\\="))
+
+(defun org-tempo-add-templates ()
+ "Update all org-tempo templates.
+
+Goes through `org-structure-template-alist' and
+`org-tempo-keywords-alist'."
+ (let ((keys (mapcar (apply-partially 'format "<%c")
+ (mapcar 'car (append org-structure-template-alist
+ org-tempo-keywords-alist)))))
+ (if (> (length keys)
+ (length (delete-dups keys)))
+ (user-error
+ "Duplicated keys in `org-structure-template-alist' and `org-tempo-keywords-alist'"))
+ (mapcar (lambda (key)
+ (if (assoc-string key org-tempo-tags)
+ (setq org-tempo-tags
+ (delete (assoc-string key org-tempo-tags)
+ org-tempo-tags))))
+ keys)
+ (mapcar 'org-tempo-add-block org-structure-template-alist)
+ (mapcar 'org-tempo-add-keyword org-tempo-keywords-alist)))
+
+(defun org-tempo-add-block (entry)
+ "Add block entry from `org-structure-template-alist'."
+ (let* ((key (format "<%c" (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-tempo-keywords-alist'."
+ (let* ((key (format "<%c" (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)
+
+(add-hook 'org-mode-hook 'org-tempo-setup)
+
+(with-eval-after-load 'org
+ (org-tempo-add-templates)
+ (add-hook 'org-tab-before-tab-emulation-hook
+ (lambda (&optional silent)
+ ;; Simple test if `org-tempo-setup' has been run.
+ ;; May not be the case if `org-tempo' was loaded
+ ;; after Org.
+ (unless (cl-member "<I" tempo-collection :key 'car :test 'equal)
+ (org-tempo-setup))
+ (tempo-complete-tag silent))))
+
+(provide 'org-tempo)
+
+;;; org-tempo.el ends here
diff --git a/lisp/org.el b/lisp/org.el
index 611817b40..47ca283f2 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -706,6 +706,7 @@ For export specific modules, see also `org-export-backends'."
(const :tag " mouse: Additional mouse support" org-mouse)
(const :tag " protocol: Intercept calls from emacsclient" org-protocol)
(const :tag " rmail: Links to RMAIL folders/messages" org-rmail)
+ (const :tag " tempo: Fast completion for structures" org-tempo)
(const :tag " w3m: Special cut/paste from w3m to Org mode." org-w3m)
(const :tag "C annotate-file: Annotate a file with org syntax" org-annotate-file)
--
2.15.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-04 16:22 [patch] structure snippet completions Rasmus
@ 2017-12-04 20:55 ` Nicolas Goaziou
2017-12-05 10:22 ` Rasmus
2017-12-04 21:37 ` Eric Abrahamsen
1 sibling, 1 reply; 18+ messages in thread
From: Nicolas Goaziou @ 2017-12-04 20:55 UTC (permalink / raw)
To: Rasmus; +Cc: eric, emacs-orgmode
Hello,
Rasmus <rasmus@gmx.us> writes:
> The attached patch adds expansions of "<s"-like snippets to Org v9.2. I
> would like to include this in the next version of Org in anticipation of
> the changes to the template system.
Thank you. Some, mostly cosmetics, comments follow.
>
> In at least emacs-git it "just works" after requiring org-tempo.
>
> Since it currently uses with-eval-after-load it would require Emacs 24.4,
> but this could be changed to eval-after-load if necessary.
We officially support Emacs 24.3, even though some tests fail. IOW, you
need to use `eval-after-load'.
> * lisp/org-tempo.el: New file.
> * doc/org.texi (Structure templates):
> * etc/ORG-NEWS: Document new library.
No need to document ORG-NEWS changes.
> +@vindex org-tempo
Is it worth mentioning the _variable_ `org-tempo'?
Also,
@cindex Tempo
@cindex Template expansion
@cindex ... whatever ...
> +@vindex org-tempo-keywords-alist
Is
@vindex org-structure-template-alist
missing?
> +@code{org-tempo} can be used to expand snippets to structures defined
> in
Org Tempo expands snippets...
> +@code{org-structure-template-alist} and @code{org-tempo-keywords-alist}. For
> +example, @code{org-tempo} makes @kbd{<} @kbd{s} @kbd{@key{TAB}}
> expand to a
For example, Org Tempo makes @kbd(< s @key{TAB}) expand to a code block.
> +@samp{src} code block. Enable it by customizing @code{org-modules} or add
> +@code{(require 'org-tempo)} to your Emacs init file@footnote{For more
> +information, please refer to the commentary section in
> @code{org-tempo.el}}.
... @file{org-tempo.el}.}.
> +;;; org-tempo.el --- template expansion for org structures -*- lexical-binding: t; -*-
Template expansion for Org structures
> +;; org-tempo reimplements completions of structure template before
Org Tempo implements...
> +(defvar org-tempo-tags nil
> + "Tempo tags for org-mode")
"Tempo tags for Org mode."
> +(defcustom org-tempo-keywords-alist
> + '((?L . "latex")
> + (?H . "html")
> + (?A . "ascii")
> + (?i . "index"))
> + "Keyword templates like `org-structure-template-alist'."
IMO, the docstring doesn't say much for someone discovering the feature.
> + :group 'org-tempo
You didn't define the `org-tempo' group, did you?
> + :type '(repeat
> + (cons (character :tag "Key")
> + (string :tag "Template")))
> + :package-version '(Org . "9.2"))
> +
> +(defun org-tempo-setup ()
> + (org-tempo-add-templates)
> + (tempo-use-tag-list 'org-tempo-tags)
> + (setq-local tempo-match-finder "^ *\\(<[[:word:]]\\)\\="))
> +
> +(defun org-tempo-add-templates ()
> + "Update all org-tempo templates.
"Update all Org Tempo templates."
> +Goes through `org-structure-template-alist' and
> +`org-tempo-keywords-alist'."
> + (let ((keys (mapcar (apply-partially 'format "<%c")
#'format
> + (mapcar 'car (append org-structure-template-alist
> + org-tempo-keywords-alist)))))
#'car
but I think the following is simpler:
(mapcar (lambda (pair) (format "<%s" (car pair)))
(append org-structure-template-alist
org-tempo-keywords-alist))
> + (if (> (length keys)
> + (length (delete-dups keys)))
`when'
> + (user-error
> + "Duplicated keys in `org-structure-template-alist' and
> `org-tempo-keywords-alist'"))
Is is an issue?
> + (mapcar (lambda (key)
> + (if (assoc-string key org-tempo-tags)
> + (setq org-tempo-tags
> + (delete (assoc-string key org-tempo-tags)
> + org-tempo-tags))))
> + keys)
> + (mapcar 'org-tempo-add-block org-structure-template-alist)
#'org-tempo-add-block
> + (mapcar 'org-tempo-add-keyword org-tempo-keywords-alist)))
#'org-tempo-add-keyword
> +
> +(defun org-tempo-add-block (entry)
> + "Add block entry from `org-structure-template-alist'."
> + (let* ((key (format "<%c" (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 " ")))
> + >)
`org-split-string' -> `split-string'
> + key
> + (format "Insert a %s block" name)
> + 'org-tempo-tags)))
> +
> +(defun org-tempo-add-keyword (entry)
> + "Add keyword entry from `org-tempo-keywords-alist'."
> + (let* ((key (format "<%c" (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
Why `ignore-errors'?
> + ;; Simple test if `org-tempo-setup' has been run.
> + ;; May not be the case if `org-tempo' was loaded
> + ;; after Org.
> + (unless (cl-member "<I" tempo-collection :key 'car :test 'equal)
> + (org-tempo-setup))
(unless (assoc "<I" tempos-collection) (org-tempo-setup))
But wouldn't calling
(org-tempo-setup)
at top level in "org-tempo.el" solve the issue?
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-04 20:55 ` Nicolas Goaziou
@ 2017-12-05 10:22 ` Rasmus
2017-12-05 20:29 ` Nicolas Goaziou
0 siblings, 1 reply; 18+ messages in thread
From: Rasmus @ 2017-12-05 10:22 UTC (permalink / raw)
To: mail; +Cc: eric, emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 2877 bytes --]
Hi,
Thanks for the comments. I have attached a new version that addresses the
issues you raised.
I think Org Tempo should pretty much work as this point, but of course
additional testing would be great. And more cool key expansions of
course.
>> +@vindex org-tempo
>
> Is it worth mentioning the _variable_ `org-tempo'?
No.
> Also,
>
> @cindex Tempo
> @cindex Template expansion
> @cindex ... whatever ...
Good idea.
>> +@vindex org-tempo-keywords-alist
>
> Is
>
> @vindex org-structure-template-alist
>
> missing?
Perhaps. Added.
>> +@code{org-structure-template-alist} and @code{org-tempo-keywords-alist}. For
>> +example, @code{org-tempo} makes @kbd{<} @kbd{s} @kbd{@key{TAB}}
>> expand to a
>
> For example, Org Tempo makes @kbd(< s @key{TAB}) expand to a code block.
That was taken from an old revision of the manual, but I am happy to use
the more clear form.
>> +@samp{src} code block. Enable it by customizing @code{org-modules} or add
>> +@code{(require 'org-tempo)} to your Emacs init file@footnote{For more
>> +information, please refer to the commentary section in
>> @code{org-tempo.el}}.
>
> ... @file{org-tempo.el}.}.
So much texinfo syntax...
>> + (user-error
>> + "Duplicated keys in `org-structure-template-alist' and
>> `org-tempo-keywords-alist'"))
>
> Is is an issue?
I guess if "<l" is defined to both make a export latex block and a latex
keyword it’s at least an issue, but I demoted it to a warning, which is
probably more appropriate.
>> +(defun org-tempo-add-keyword (entry)
>> + "Add keyword entry from `org-tempo-keywords-alist'."
>> + (let* ((key (format "<%c" (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
>
> Why `ignore-errors'?
In case the file selection is quit. But I have re-done the include
keyword in a better way.
>> + ;; Simple test if `org-tempo-setup' has been run.
>> + ;; May not be the case if `org-tempo' was loaded
>> + ;; after Org.
>> + (unless (cl-member "<I" tempo-collection :key 'car :test 'equal)
>> + (org-tempo-setup))
>
> (unless (assoc "<I" tempos-collection) (org-tempo-setup))
>
> But wouldn't calling
>
> (org-tempo-setup)
>
> at top level in "org-tempo.el" solve the issue?
Good idea. I call it if we’re in an Org buffer. Perhaps people use Tempo
in other modes so it would be potentially disruptive to call it in other
modes.
Rasmus
--
You people at the NSA are becoming my new best friends!
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-tempo.el-New-file-for-expansion-of-templates.patch --]
[-- Type: text/x-patch, Size: 8500 bytes --]
From d645c92381420203d42c0397269122de06ee76d9 Mon Sep 17 00:00:00 2001
From: Rasmus <rasmus@gmx.us>
Date: Thu, 9 Nov 2017 16:47:13 +0100
Subject: [PATCH 1/2] org-tempo.el: New file for expansion of templates
* lisp/org-tempo.el: New file.
* doc/org.texi (Structure templates):
* lisp/org.el (org-modules): Add org-tempo.
---
doc/org.texi | 13 +++++
etc/ORG-NEWS | 4 +-
lisp/org-tempo.el | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
lisp/org.el | 1 +
4 files changed, 181 insertions(+), 1 deletion(-)
create mode 100644 lisp/org-tempo.el
diff --git a/doc/org.texi b/doc/org.texi
index 5becb0175..e6e6706cb 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -17396,6 +17396,19 @@ the key is @key{TAB}, the user is prompted to enter a type.
Available structure types are defined in @code{org-structure-template-alist},
see the docstring for adding or changing values.
+@cindex Tempo
+@cindex Template expansion
+@cindex template insertion
+@cindex insertion, of templates
+@vindex org-tempo-keywords-alist
+@vindex org-structure-template-alist
+Org Tempo expands snippets to structures defined in
+@c @code{org-structure-template-alist} and @code{org-tempo-keywords-alist}. For
+@c example, @code{org-tempo} expands @kbd{< s @key{TAB}} to a code block.
+Enable it by customizing @code{org-modules} or add @code{(require
+'org-tempo)} to your Emacs init file@footnote{For more information, please
+refer to the commentary section in @file{org-tempo.el}.}.
+
@multitable @columnfractions 0.2 0.8
@item @kbd{c} @tab @samp{#+BEGIN_CENTER}
@item @kbd{C} @tab @samp{#+BEGIN_COMMENT}
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 66865ffe1..9d6c91ef3 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -72,6 +72,8 @@ document, use =shrink= value instead, or in addition to align:
#+END_EXAMPLE
** New features
+*** ~org-tempo~ may used for snippet expansion of structure template.
+See manual and commentary in ~org-tempo.el~ for details.
*** Exclude unnumbered headlines from table of contents
Set their =UNNUMBERED= property to the special =notoc= value. See
manual for details.
@@ -167,7 +169,7 @@ See docstring for details.
** Removed functions
*** ~org-try-structure-completion~
-
+=org-tempo= may be used as a replacement.
** Removed variables
*** org-babel-use-quick-and-dirty-noweb-expansion
diff --git a/lisp/org-tempo.el b/lisp/org-tempo.el
new file mode 100644
index 000000000..6f9af81fc
--- /dev/null
+++ b/lisp/org-tempo.el
@@ -0,0 +1,164 @@
+;;; org-tempo.el --- Template expansion for Org structures -*- 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:
+;;
+;; Org Tempo reimplements completions of structure template before
+;; point like `org-try-structure-completion' in Org v9.1 and earlier.
+;; For example, strings like "<e" at the beginning of the line will be
+;; expanded to an example block.
+;;
+;; All blocks defined in `org-structure-template-alist' are added as
+;; Org Tempo shortcuts, in addition to keywords defined in
+;; `org-tempo-keywords-alist'.
+;;
+;; `tempo' can also be used to define more sophisticated keywords
+;; completions. See the section "Additional keywords" below for
+;; additional details.
+;;
+;;; Code:
+
+(require 'tempo)
+(require 'cl-lib)
+
+\f
+(defgroup org-tempo nil
+ "Options for template expansion of Org structures"
+ :tag "Org structure"
+ :group 'org)
+
+(defvar org-tempo-tags nil
+ "Tempo tags for org-mode")
+
+(defcustom org-tempo-keywords-alist
+ '((?L . "latex")
+ (?H . "html")
+ (?A . "ascii")
+ (?i . "index"))
+ "Keyword completion elements.
+
+Like `org-structure-template-alist' this alist of KEY characters
+and KEYWORD. The tempo snippet \"<KEY\" is expand to the KEYWORD
+value.
+
+For example \"<l\" at the beginning of a line is expanded to
+#+latex:"
+ :group 'org-tempo
+ :type '(repeat (cons (character :tag "Key")
+ (string :tag "Keyword")))
+ :package-version '(Org . "9.2"))
+
+
+\f
+;;; Org Tempo functions and setup.
+
+(defun org-tempo-setup ()
+ (org-tempo-add-templates)
+ (tempo-use-tag-list 'org-tempo-tags)
+ (setq-local tempo-match-finder "^ *\\(<[[:word:]]\\)\\="))
+
+(defun org-tempo-add-templates ()
+ "Update all Org Tempo templates.
+
+Goes through `org-structure-template-alist' and
+`org-tempo-keywords-alist'."
+ (let ((keys (mapcar (lambda (pair) (format "<%c" (car pair)))
+ (append org-structure-template-alist
+ org-tempo-keywords-alist))))
+ ;; Check for duplicated snippet keys and warn if any are found.
+ (when (> (length keys) (length (delete-dups keys)))
+ (warn
+ "Duplicated keys in `org-structure-template-alist' and `org-tempo-keywords-alist'"))
+
+ ;; Remove any keys already defined in case they have been updated.
+ (mapcar (lambda (key)
+ (if (assoc-string key org-tempo-tags)
+ (setq org-tempo-tags
+ (delete (assoc-string key org-tempo-tags)
+ org-tempo-tags))))
+ keys)
+ (mapcar #'org-tempo-add-block org-structure-template-alist)
+ (mapcar #'org-tempo-add-keyword org-tempo-keywords-alist)))
+
+(defun org-tempo-add-block (entry)
+ "Add block entry from `org-structure-template-alist'."
+ (let* ((key (format "<%c" (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 (split-string name " ")))
+ >)
+ key
+ (format "Insert a %s block" name)
+ 'org-tempo-tags)))
+
+(defun org-tempo-add-keyword (entry)
+ "Add keyword entry from `org-tempo-keywords-alist'."
+ (let* ((key (format "<%c" (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
+
+(defun org-tempo--include-file ()
+ "Ask for file name and take care of quit"
+ (let* ((inhibit-quit t))
+ (unless (with-local-quit
+ (prog1 t
+ (insert
+ (format "#+include: \"%s\" " (file-relative-name
+ (read-file-name "Include file: "))))))
+ (insert "<I")
+ (setq quit-flag nil))))
+
+(tempo-define-template "org-include"
+ '((org-tempo--include-file)
+ p >)
+ "<I"
+ "Include keyword"
+ 'org-tempo-tags)
+
+\f
+;;; Setup of Org Tempo
+;;
+;; Org Tempo is set up with each new Org buffer and potentially in the
+;; current Org buffer.
+;;
+;; Tempo templates can only be added after Org is loaded as
+;; `org-structure-template-alist' must be loaded.
+
+(add-hook 'org-mode-hook 'org-tempo-setup)
+(add-hook 'org-tab-before-tab-emulation-hook
+ 'tempo-complete-tag)
+(when (eq major-mode 'org-mode) (org-tempo-setup))
+
+(eval-after-load 'org
+ '(org-tempo-add-templates))
+
+(provide 'org-tempo)
+
+;;; org-tempo.el ends here
diff --git a/lisp/org.el b/lisp/org.el
index 611817b40..47ca283f2 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -706,6 +706,7 @@ For export specific modules, see also `org-export-backends'."
(const :tag " mouse: Additional mouse support" org-mouse)
(const :tag " protocol: Intercept calls from emacsclient" org-protocol)
(const :tag " rmail: Links to RMAIL folders/messages" org-rmail)
+ (const :tag " tempo: Fast completion for structures" org-tempo)
(const :tag " w3m: Special cut/paste from w3m to Org mode." org-w3m)
(const :tag "C annotate-file: Annotate a file with org syntax" org-annotate-file)
--
2.15.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-05 10:22 ` Rasmus
@ 2017-12-05 20:29 ` Nicolas Goaziou
2017-12-07 23:37 ` Rasmus
0 siblings, 1 reply; 18+ messages in thread
From: Nicolas Goaziou @ 2017-12-05 20:29 UTC (permalink / raw)
To: Rasmus; +Cc: eric, emacs-orgmode
Hello,
Rasmus <rasmus@gmx.us> writes:
> +@cindex Tempo
> +@cindex Template expansion
> +@cindex template insertion
> +@cindex insertion, of templates
> +@vindex org-tempo-keywords-alist
> +@vindex org-structure-template-alist
> +Org Tempo expands snippets to structures defined in
> +@c @code{org-structure-template-alist} and @code{org-tempo-keywords-alist}. For
> +@c example, @code{org-tempo} expands @kbd{< s @key{TAB}} to a code block.
It looks like a typo, but the two lines above are commented.
Also, would it make sense to add a few tests?
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-05 20:29 ` Nicolas Goaziou
@ 2017-12-07 23:37 ` Rasmus
2017-12-07 23:49 ` Rasmus
2017-12-08 21:07 ` Berry, Charles
0 siblings, 2 replies; 18+ messages in thread
From: Rasmus @ 2017-12-07 23:37 UTC (permalink / raw)
To: mail; +Cc: eric, emacs-orgmode
Hi,
Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:
> It looks like a typo, but the two lines above are commented.
Indeed. Thanks.
> Also, would it make sense to add a few tests?
I never feel very creative about tests but I have added some.
I have also pushed the code. "<s"-like snippet expansion should be
enabled by requiring org-tempo.
Let me know about any issues.
Rasmus
--
Sådan en god dansk lagereddike kan man slet ikke bruge mere
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-07 23:37 ` Rasmus
@ 2017-12-07 23:49 ` Rasmus
2017-12-08 2:38 ` Kaushal Modi
2017-12-08 21:07 ` Berry, Charles
1 sibling, 1 reply; 18+ messages in thread
From: Rasmus @ 2017-12-07 23:49 UTC (permalink / raw)
To: emacs-orgmode
Rasmus <rasmus@gmx.us> writes:
> Hi,
>
> Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:
>
>> It looks like a typo, but the two lines above are commented.
>
> Indeed. Thanks.
>
>> Also, would it make sense to add a few tests?
>
> I never feel very creative about tests but I have added some.
>
> I have also pushed the code. "<s"-like snippet expansion should be
> enabled by requiring org-tempo.
>
> Let me know about any issues.
One possible "bug" that I discovered is illustrated by the following
example.
* foo
suggested indention
<s|
When I tab at point ("|") extra indention will be stripped. I don’t
know if this is something that should be fixed.
Rasmus
--
I almost cut my hair, it happened just the other day
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-07 23:49 ` Rasmus
@ 2017-12-08 2:38 ` Kaushal Modi
2017-12-08 20:16 ` Rasmus
0 siblings, 1 reply; 18+ messages in thread
From: Kaushal Modi @ 2017-12-08 2:38 UTC (permalink / raw)
To: Rasmus; +Cc: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 704 bytes --]
On Thu, Dec 7, 2017 at 6:51 PM Rasmus <rasmus@gmx.us> wrote:
> Rasmus <rasmus@gmx.us> writes:
> One possible "bug" that I discovered is illustrated by the following
> example.
>
> * foo
> suggested indention
> <s|
>
> When I tab at point ("|") extra indention will be stripped. I don’t
> know if this is something that should be fixed.
>
That's does look like a bug. The preservation of indentation is especially
useful if you want source block in nested lists.
#+BEGIN_EXAMPLE
Outside list
#+END_EXAMPLE
- list level 1
#+BEGIN_EXAMPLE
At level 1
#+END_EXAMPLE
- list level 2
#+BEGIN_EXAMPLE
At level 2
#+END_EXAMPLE
--
Kaushal Modi
[-- Attachment #2: Type: text/html, Size: 1351 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-08 2:38 ` Kaushal Modi
@ 2017-12-08 20:16 ` Rasmus
0 siblings, 0 replies; 18+ messages in thread
From: Rasmus @ 2017-12-08 20:16 UTC (permalink / raw)
To: emacs-orgmode
Kaushal Modi <kaushal.modi@gmail.com> writes:
> On Thu, Dec 7, 2017 at 6:51 PM Rasmus <rasmus@gmx.us> wrote:
>
>> Rasmus <rasmus@gmx.us> writes:
>> One possible "bug" that I discovered is illustrated by the following
>> example.
>>
>> * foo
>> suggested indention
>> <s|
>>
>> When I tab at point ("|") extra indention will be stripped. I don’t
>> know if this is something that should be fixed.
>>
>
> That's does look like a bug. The preservation of indentation is especially
> useful if you want source block in nested lists.
>
> #+BEGIN_EXAMPLE
> Outside list
> #+END_EXAMPLE
>
> - list level 1
>
> #+BEGIN_EXAMPLE
> At level 1
> #+END_EXAMPLE
>
> - list level 2
>
> #+BEGIN_EXAMPLE
> At level 2
> #+END_EXAMPLE
In that example everything would work fine, though. For it not to work
you’d have alter your example to something like this:
#+BEGIN_EXAMPLE
Outside list
#+END_EXAMPLE
- list level 1
#+BEGIN_EXAMPLE
example with extra indention
#+END_EXAMPLE
Rasmus
--
Lasciate ogni speranza, voi che leggete questo.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-07 23:37 ` Rasmus
2017-12-07 23:49 ` Rasmus
@ 2017-12-08 21:07 ` Berry, Charles
2017-12-08 21:20 ` Rasmus
1 sibling, 1 reply; 18+ messages in thread
From: Berry, Charles @ 2017-12-08 21:07 UTC (permalink / raw)
To: Rasmus
Cc: eric@ericabrahamsen.net, emacs-orgmode@gnu.org,
mail@nicolasgoaziou.fr
> On Dec 7, 2017, at 3:37 PM, Rasmus <rasmus@gmx.us> wrote:
>
> I have also pushed the code. "<s"-like snippet expansion should be
> enabled by requiring org-tempo.
>
Thanks. I was in a deep funk without "<s" and friends. Feeling better now.
> Let me know about any issues.
>
Maybe make `tempo-match-finder' be "^ *\\(<[[:word:]]+\\)" so it will match things like "<la" when I want a latex align environment. Or let the user customize it.
I use some latex environments that would be easier to keep track of if I had multiple characters after the "<".
I know I can implement this in my own setup. Just saying this might be nice for other users, too.
Also, something like "<list" as `(describe-variable 'org-tempo-tags)' is helpful if you have a lot of customizations to keep track of.
A minor gotcha: if you `(require 'org-tempo)' after an org buffer has been created you will need to (org-mode-restart) the buffer to enable completions. I got stuck trying to add custom templates until I realized this.
Chuck
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-08 21:07 ` Berry, Charles
@ 2017-12-08 21:20 ` Rasmus
2017-12-09 13:42 ` numbchild
2017-12-09 17:23 ` Berry, Charles
0 siblings, 2 replies; 18+ messages in thread
From: Rasmus @ 2017-12-08 21:20 UTC (permalink / raw)
To: emacs-orgmode
"Berry, Charles" <ccberry@ucsd.edu> writes:
>> On Dec 7, 2017, at 3:37 PM, Rasmus <rasmus@gmx.us> wrote:
>>
>> I have also pushed the code. "<s"-like snippet expansion should be
>> enabled by requiring org-tempo.
>>
>
> Thanks. I was in a deep funk without "<s" and friends. Feeling better now.
I am happy that I am able to help you for once!
>> Let me know about any issues.
>>
>
> Maybe make `tempo-match-finder' be "^ *\\(<[[:word:]]+\\)" so it will
> match things like "<la" when I want a latex align environment. Or let
> the user customize it.
At the moment snippets with more than one character isn’t supported. Note
that the car of org-structure-template-alist elements is now a character.
"Snippet-strings" (like "la") will be re-added soon cf. the email from
Eric earlier on in this thread.
> A minor gotcha: if you `(require 'org-tempo)' after an org buffer has
> been created you will need to (org-mode-restart) the buffer to enable
> completions. I got stuck trying to add custom templates until I
> realized this.
It shouldn’t do that since this is near the bottom of org-tempo:
(when (eq major-mode 'org-mode) (org-tempo-setup))
On my system it works in the first buffer where I require org-tempo, even
without reloading.
Which version of Emacs are you using?
Rasmus
--
A clever person solves a problem. A wise person avoids it
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-08 21:20 ` Rasmus
@ 2017-12-09 13:42 ` numbchild
2017-12-09 16:22 ` Rasmus
2017-12-09 17:23 ` Berry, Charles
1 sibling, 1 reply; 18+ messages in thread
From: numbchild @ 2017-12-09 13:42 UTC (permalink / raw)
To: Rasmus; +Cc: Org-mode
[-- Attachment #1: Type: text/plain, Size: 3541 bytes --]
error report when I `(require 'org-tempo)`
Debugger entered--Lisp error: (error "Format specifier doesn’t match
argument type")
format("<%c" "Q")
(closure (t) (pair) (format "<%c" (car pair)))(("Q" "#+BEGIN_SRC sql-mode
?\n\n#+END_SRC" "#+BEGIN_SRC sql-mode ?\n\n#+END_SRC"))
mapcar((closure (t) (pair) (format "<%c" (car pair))) (("Q" "#+BEGIN_SRC
sql-mode ?\n\n#+END_SRC" "#+BEGIN_SRC sql-mode ?\n\n#+END_SRC") ("n"
"#+BEGIN_NOTES\n?\n#+END_NOTES") (116 . "translate") (97 . "export ascii")
(99 . "center") (67 . "comment") (101 . "example") (69 . "export") (104 .
"export html") (108 . "export latex") (113 . "quote") (115 . "src") (118 .
"verse") (76 . "latex") (72 . "html") (65 . "ascii") (105 . "index")))
(let ((keys (mapcar (function (lambda (pair) (format "<%c" (car pair))))
(append org-structure-template-alist org-tempo-keywords-alist)))) (if (>
(length keys) (length (delete-dups keys))) (progn (warn "Duplicated keys in
`org-structure-template-alist' and `org-tempo-keywords-alist'"))) (mapc
(function (lambda (key) (if (assoc-string key org-tempo-tags) (setq
org-tempo-tags (delete (assoc-string key org-tempo-tags)
org-tempo-tags))))) keys) (mapc (function org-tempo-add-block)
org-structure-template-alist) (mapc (function org-tempo-add-keyword)
org-tempo-keywords-alist))
org-tempo-add-templates()
org-tempo-setup()
(progn (org-tempo-setup))
(if (eq major-mode 'org-mode) (progn (org-tempo-setup)))
eval-buffer(#<buffer *load*> nil
"/home/stardiviner/Code/Emacs/org-mode/lisp/org-tempo.el" nil t) ; Reading
at buffer position 5019
load-with-code-conversion(#1="/home/stardiviner/Code/Emacs/org-mode/lisp/org-tempo.el"
#1# nil t)
require(org-tempo)
[stardiviner] <Hack this world!> GPG key ID: 47C32433
IRC(freeenode): stardiviner Twitter: @numbchild
Key fingerprint = 9BAA 92BC CDDD B9EF 3B36 CB99 B8C4 B8E5 47C3 2433
Blog: http://stardiviner.github.io/
On Sat, Dec 9, 2017 at 5:20 AM, Rasmus <rasmus@gmx.us> wrote:
> "Berry, Charles" <ccberry@ucsd.edu> writes:
>
> >> On Dec 7, 2017, at 3:37 PM, Rasmus <rasmus@gmx.us> wrote:
> >>
> >> I have also pushed the code. "<s"-like snippet expansion should be
> >> enabled by requiring org-tempo.
> >>
> >
> > Thanks. I was in a deep funk without "<s" and friends. Feeling better
> now.
>
> I am happy that I am able to help you for once!
>
> >> Let me know about any issues.
> >>
> >
> > Maybe make `tempo-match-finder' be "^ *\\(<[[:word:]]+\\)" so it will
> > match things like "<la" when I want a latex align environment. Or let
> > the user customize it.
>
> At the moment snippets with more than one character isn’t supported. Note
> that the car of org-structure-template-alist elements is now a character.
> "Snippet-strings" (like "la") will be re-added soon cf. the email from
> Eric earlier on in this thread.
>
>
> > A minor gotcha: if you `(require 'org-tempo)' after an org buffer has
> > been created you will need to (org-mode-restart) the buffer to enable
> > completions. I got stuck trying to add custom templates until I
> > realized this.
>
> It shouldn’t do that since this is near the bottom of org-tempo:
>
> (when (eq major-mode 'org-mode) (org-tempo-setup))
>
> On my system it works in the first buffer where I require org-tempo, even
> without reloading.
>
> Which version of Emacs are you using?
>
> Rasmus
>
> --
> A clever person solves a problem. A wise person avoids it
>
>
>
[-- Attachment #2: Type: text/html, Size: 5177 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-08 21:20 ` Rasmus
2017-12-09 13:42 ` numbchild
@ 2017-12-09 17:23 ` Berry, Charles
2017-12-10 11:09 ` Rasmus
1 sibling, 1 reply; 18+ messages in thread
From: Berry, Charles @ 2017-12-09 17:23 UTC (permalink / raw)
To: Rasmus; +Cc: emacs-orgmode@gnu.org
> On Dec 8, 2017, at 1:20 PM, Rasmus <rasmus@gmx.us> wrote:
>
>>
>> A minor gotcha: if you `(require 'org-tempo)' after an org buffer has
>> been created you will need to (org-mode-restart) the buffer to enable
>> completions. I got stuck trying to add custom templates until I
>> realized this.
>
> It shouldn’t do that since this is near the bottom of org-tempo:
>
> (when (eq major-mode 'org-mode) (org-tempo-setup))
>
> On my system it works in the first buffer where I require org-tempo, even
> without reloading.
Yes. It does that for me, too. But this only affects the buffer from which I `(require 'org-tempo)'.
If there are already org buffers already open, I have to eval (org-tempo-setup) or (org-mode-restart) each one to enable to enable org-tempo in them. Of course, buffers opened later run the org-mode-hooks, so that isn't a problem.
This isn't likely to affect many users, but if someone tries to debug by starting `emacs -Q', opening an org buffer, and then requiring org-tempo from another buffer, s/he could get stuck.
My init file creates a buffer called org-scratch.org in which I doodle and try things out. I was stuck with org-tempo till I moved it below the (require 'org-tempo).
So maybe add a comment that will warn that (require 'org-tempo) only affects the buffer from which it is run and buffers subsequently opened or restarted.
>
> Which version of Emacs are you using?
25.2.1
Chuck
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-09 17:23 ` Berry, Charles
@ 2017-12-10 11:09 ` Rasmus
0 siblings, 0 replies; 18+ messages in thread
From: Rasmus @ 2017-12-10 11:09 UTC (permalink / raw)
To: emacs-orgmode
"Berry, Charles" <ccberry@ucsd.edu> writes:
>> On Dec 8, 2017, at 1:20 PM, Rasmus <rasmus@gmx.us> wrote:
>>
>
>>>
>>> A minor gotcha: if you `(require 'org-tempo)' after an org buffer has
>>> been created you will need to (org-mode-restart) the buffer to enable
>>> completions. I got stuck trying to add custom templates until I
>>> realized this.
>>
>> It shouldn’t do that since this is near the bottom of org-tempo:
>>
>> (when (eq major-mode 'org-mode) (org-tempo-setup))
>>
>> On my system it works in the first buffer where I require org-tempo, even
>> without reloading.
>
>
> Yes. It does that for me, too. But this only affects the buffer from which I `(require 'org-tempo)'.
I hadn’t thought of that, but that is rather annoying. Requiring Org
Tempo now runs ‘org-tempo-setup’ on all active Org buffers (commit
3efb000739362).
Thanks,
Rasmus
--
Hooray!
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-04 16:22 [patch] structure snippet completions Rasmus
2017-12-04 20:55 ` Nicolas Goaziou
@ 2017-12-04 21:37 ` Eric Abrahamsen
2017-12-05 10:24 ` Rasmus
1 sibling, 1 reply; 18+ messages in thread
From: Eric Abrahamsen @ 2017-12-04 21:37 UTC (permalink / raw)
To: emacs-orgmode
Rasmus <rasmus@gmx.us> writes:
> Hi,
>
> The attached patch adds expansions of "<s"-like snippets to Org v9.2. I
> would like to include this in the next version of Org in anticipation of
> the changes to the template system.
Cool! We were talking about shifting the alist keys to strings, do we
want to do that all at once, in both places, or let this land first?
[...]
>> + (mapcar 'org-tempo-add-block org-structure-template-alist)
>
> #'org-tempo-add-block
>
>> + (mapcar 'org-tempo-add-keyword org-tempo-keywords-alist)))
And `mapc'!
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-04 21:37 ` Eric Abrahamsen
@ 2017-12-05 10:24 ` Rasmus
2017-12-05 19:14 ` Eric Abrahamsen
0 siblings, 1 reply; 18+ messages in thread
From: Rasmus @ 2017-12-05 10:24 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> Rasmus <rasmus@gmx.us> writes:
>
>> Hi,
>>
>> The attached patch adds expansions of "<s"-like snippets to Org v9.2. I
>> would like to include this in the next version of Org in anticipation of
>> the changes to the template system.
>
> Cool! We were talking about shifting the alist keys to strings, do we
> want to do that all at once, in both places, or let this land first?
I’m indifferent. If you make a shift to strings in the part of the code
you know I can alter this code.
>>> + (mapcar 'org-tempo-add-block org-structure-template-alist)
>>
>> #'org-tempo-add-block
>>
>>> + (mapcar 'org-tempo-add-keyword org-tempo-keywords-alist)))
>
> And `mapc'!
Fair enough.
Rasmus
--
This space is left intentionally blank
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] structure snippet completions
2017-12-05 10:24 ` Rasmus
@ 2017-12-05 19:14 ` Eric Abrahamsen
0 siblings, 0 replies; 18+ messages in thread
From: Eric Abrahamsen @ 2017-12-05 19:14 UTC (permalink / raw)
To: emacs-orgmode
Rasmus <rasmus@gmx.us> writes:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> Rasmus <rasmus@gmx.us> writes:
>>
>>> Hi,
>>>
>>> The attached patch adds expansions of "<s"-like snippets to Org v9.2. I
>>> would like to include this in the next version of Org in anticipation of
>>> the changes to the template system.
>>
>> Cool! We were talking about shifting the alist keys to strings, do we
>> want to do that all at once, in both places, or let this land first?
>
> I’m indifferent. If you make a shift to strings in the part of the code
> you know I can alter this code.
On second thought, maybe it would be better to put this in first. A
separate change could do string keys, and also make some of the other
changes people have been asking for (different keybinding, etc), all at
once.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [patch] structure snippet completions
@ 2017-12-04 16:20 Rasmus
0 siblings, 0 replies; 18+ messages in thread
From: Rasmus @ 2017-12-04 16:20 UTC (permalink / raw)
To: emacs-orgmode; +Cc: eric
[-- Attachment #1: Type: text/plain, Size: 427 bytes --]
Hi,
The attached patch adds expansions of "<s"-like snippets to Org v9.2. I
would like to include this in the next version of Org in anticipation of
the changes to the template system.
In at least emacs-git it "just works" after requiring org-tempo.
Since it currently uses with-eval-after-load it would require Emacs 24.4,
but this could be changed to eval-after-load if necessary.
Thanks,
Rasmus
--
What will be next?
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-tempo.el-New-file-for-expansion-of-templates.patch --]
[-- Type: text/x-patch, Size: 7717 bytes --]
From d5e3eacea38d3777f541f5abddebed04171650b6 Mon Sep 17 00:00:00 2001
From: Rasmus <rasmus@gmx.us>
Date: Thu, 9 Nov 2017 16:47:13 +0100
Subject: [PATCH 1/2] org-tempo.el: New file for expansion of templates
* lisp/org-tempo.el: New file.
* doc/org.texi (Structure templates):
* etc/ORG-NEWS: Document new library.
* lisp/org.el (org-modules): Add org-tempo.
---
doc/org.texi | 9 ++++
etc/ORG-NEWS | 4 +-
lisp/org-tempo.el | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
lisp/org.el | 1 +
4 files changed, 146 insertions(+), 1 deletion(-)
create mode 100644 lisp/org-tempo.el
diff --git a/doc/org.texi b/doc/org.texi
index 5becb0175..17092ecbe 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -17396,6 +17396,15 @@ the key is @key{TAB}, the user is prompted to enter a type.
Available structure types are defined in @code{org-structure-template-alist},
see the docstring for adding or changing values.
+@vindex org-tempo
+@vindex org-tempo-keywords-alist
+@code{org-tempo} can be used to expand snippets to structures defined in
+@code{org-structure-template-alist} and @code{org-tempo-keywords-alist}. For
+example, @code{org-tempo} makes @kbd{<} @kbd{s} @kbd{@key{TAB}} expand to a
+@samp{src} code block. Enable it by customizing @code{org-modules} or add
+@code{(require 'org-tempo)} to your Emacs init file@footnote{For more
+information, please refer to the commentary section in @code{org-tempo.el}}.
+
@multitable @columnfractions 0.2 0.8
@item @kbd{c} @tab @samp{#+BEGIN_CENTER}
@item @kbd{C} @tab @samp{#+BEGIN_COMMENT}
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 66865ffe1..9d6c91ef3 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -72,6 +72,8 @@ document, use =shrink= value instead, or in addition to align:
#+END_EXAMPLE
** New features
+*** ~org-tempo~ may used for snippet expansion of structure template.
+See manual and commentary in ~org-tempo.el~ for details.
*** Exclude unnumbered headlines from table of contents
Set their =UNNUMBERED= property to the special =notoc= value. See
manual for details.
@@ -167,7 +169,7 @@ See docstring for details.
** Removed functions
*** ~org-try-structure-completion~
-
+=org-tempo= may be used as a replacement.
** Removed variables
*** org-babel-use-quick-and-dirty-noweb-expansion
diff --git a/lisp/org-tempo.el b/lisp/org-tempo.el
new file mode 100644
index 000000000..666954e1b
--- /dev/null
+++ b/lisp/org-tempo.el
@@ -0,0 +1,133 @@
+;;; org-tempo.el --- template expansion for org structures -*- 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:
+;;
+;; org-tempo reimplements completions of structure template before
+;; point like `org-try-structure-completion' in Org v9.1 and earlier.
+;; For example, strings like "<e" at the beginning of the line will be
+;; expanded to an example block.
+;;
+;; All blocks defined in `org-structure-template-alist' are added as
+;; org-tempo shortcuts, in addition to keywords defined in
+;; `org-tempo-keywords-alist'.
+;;
+;; `tempo' can also be used to define more sophisticated keywords
+;; completions. See the section "Additional keywords" below for
+;; additional details.
+;;
+;;; Code:
+
+(require 'tempo)
+(require 'cl-lib)
+
+(defvar org-tempo-tags nil
+ "Tempo tags for org-mode")
+
+(defcustom org-tempo-keywords-alist
+ '((?L . "latex")
+ (?H . "html")
+ (?A . "ascii")
+ (?i . "index"))
+ "Keyword templates like `org-structure-template-alist'."
+ :group 'org-tempo
+ :type '(repeat
+ (cons (character :tag "Key")
+ (string :tag "Template")))
+ :package-version '(Org . "9.2"))
+
+(defun org-tempo-setup ()
+ (org-tempo-add-templates)
+ (tempo-use-tag-list 'org-tempo-tags)
+ (setq-local tempo-match-finder "^ *\\(<[[:word:]]\\)\\="))
+
+(defun org-tempo-add-templates ()
+ "Update all org-tempo templates.
+
+Goes through `org-structure-template-alist' and
+`org-tempo-keywords-alist'."
+ (let ((keys (mapcar (apply-partially 'format "<%c")
+ (mapcar 'car (append org-structure-template-alist
+ org-tempo-keywords-alist)))))
+ (if (> (length keys)
+ (length (delete-dups keys)))
+ (user-error
+ "Duplicated keys in `org-structure-template-alist' and `org-tempo-keywords-alist'"))
+ (mapcar (lambda (key)
+ (if (assoc-string key org-tempo-tags)
+ (setq org-tempo-tags
+ (delete (assoc-string key org-tempo-tags)
+ org-tempo-tags))))
+ keys)
+ (mapcar 'org-tempo-add-block org-structure-template-alist)
+ (mapcar 'org-tempo-add-keyword org-tempo-keywords-alist)))
+
+(defun org-tempo-add-block (entry)
+ "Add block entry from `org-structure-template-alist'."
+ (let* ((key (format "<%c" (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-tempo-keywords-alist'."
+ (let* ((key (format "<%c" (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)
+
+(add-hook 'org-mode-hook 'org-tempo-setup)
+
+(with-eval-after-load 'org
+ (org-tempo-add-templates)
+ (add-hook 'org-tab-before-tab-emulation-hook
+ (lambda (&optional silent)
+ ;; Simple test if `org-tempo-setup' has been run.
+ ;; May not be the case if `org-tempo' was loaded
+ ;; after Org.
+ (unless (cl-member "<I" tempo-collection :key 'car :test 'equal)
+ (org-tempo-setup))
+ (tempo-complete-tag silent))))
+
+(provide 'org-tempo)
+
+;;; org-tempo.el ends here
diff --git a/lisp/org.el b/lisp/org.el
index 611817b40..47ca283f2 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -706,6 +706,7 @@ For export specific modules, see also `org-export-backends'."
(const :tag " mouse: Additional mouse support" org-mouse)
(const :tag " protocol: Intercept calls from emacsclient" org-protocol)
(const :tag " rmail: Links to RMAIL folders/messages" org-rmail)
+ (const :tag " tempo: Fast completion for structures" org-tempo)
(const :tag " w3m: Special cut/paste from w3m to Org mode." org-w3m)
(const :tag "C annotate-file: Annotate a file with org syntax" org-annotate-file)
--
2.15.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
end of thread, other threads:[~2017-12-10 11:09 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-04 16:22 [patch] structure snippet completions Rasmus
2017-12-04 20:55 ` Nicolas Goaziou
2017-12-05 10:22 ` Rasmus
2017-12-05 20:29 ` Nicolas Goaziou
2017-12-07 23:37 ` Rasmus
2017-12-07 23:49 ` Rasmus
2017-12-08 2:38 ` Kaushal Modi
2017-12-08 20:16 ` Rasmus
2017-12-08 21:07 ` Berry, Charles
2017-12-08 21:20 ` Rasmus
2017-12-09 13:42 ` numbchild
2017-12-09 16:22 ` Rasmus
2017-12-09 17:23 ` Berry, Charles
2017-12-10 11:09 ` Rasmus
2017-12-04 21:37 ` Eric Abrahamsen
2017-12-05 10:24 ` Rasmus
2017-12-05 19:14 ` Eric Abrahamsen
-- strict thread matches above, loose matches on Subject: below --
2017-12-04 16:20 Rasmus
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.