org-capture: Expand interactive placeholders last

* lisp/org-capture.el (org-capture-templates): Update docstring.
(org-capture-fill-template): Expand interactive placeholders when the
template is otherwise completely filled.

This restores the previous behaviour for template's expansion.
This commit is contained in:
Nicolas Goaziou 2015-12-03 23:27:07 +01:00
parent 11291ffcd0
commit 5c13a6b765

View file

@ -231,8 +231,8 @@ be replaced with content and expanded:
%(sexp) Evaluate elisp `(sexp)' and replace it with the results.
Only placeholders pre-existing within the template, or
introduced with %[pathname] are expanded this way. Since this
happens very late in the process, other %-escapes can be used to
fill the expression.
happens after expanding non-interactive %-escapes, those can
be used to fill the expression.
%<...> The result of format-time-string on the ... format specification.
%t Time stamp, date only.
%T Time stamp with date and time.
@ -261,9 +261,8 @@ be replaced with content and expanded:
A default value and a completion table ca be specified like this:
%^{prompt|default|completion2|completion3|...}.
%? After completing the template, position cursor here.
%number Insert the text entered at the nth %^{prompt}, where `number' is a
number, starting from 1. These placeholders are expanded as the
last step of the process.
%\\N Insert the text entered at the nth %^{prompt}, where N
is a number, starting from 1.
Apart from these general escapes, you can access information specific to
the link type that is created. For example, calling `org-capture' in emails
@ -1604,7 +1603,6 @@ The template may still contain \"%?\" for cursor positioning."
(erase-buffer)
;; Turn on org-mode in temp buffer, set local variables. This
;; is to support completion in interactive prompts
(let ((org-inhibit-startup t)) (org-mode))
(insert template)
(goto-char (point-min))
(org-capture-steal-local-variables buffer)
@ -1629,16 +1627,14 @@ The template may still contain \"%?\" for cursor positioning."
;; Mark %() embedded elisp for later evaluation.
(org-capture--expand-embedded-elisp 'mark)
(let ((regexp "%\\(:[-a-za-z]+\\|<\\([^>\n]+\\)>\\|[aAcfFikKlntTuUx]\\|\
\\^\\(?:{\\([^}]*\\)}\\)?\\([CgGLptTuU]\\)?\\)")
(strings))
;; Expand non-interactive templates.
(let ((regexp "%\\(:[-a-za-z]+\\|<\\([^>\n]+\\)>\\|[aAcfFikKlntTuUx]\\)"))
(save-excursion
(while (re-search-forward regexp nil t)
(let ((pos (copy-marker (match-beginning 0)))
(end (copy-marker (match-end 0)))
(value (match-string 1))
(time-string (match-string 2))
(prompt (match-string-no-properties 3))
(key (match-string 4)))
(time-string (match-string 2)))
(unless (org-capture-escaped-%)
(goto-char pos)
(delete-region pos end)
@ -1655,20 +1651,47 @@ The template may still contain \"%?\" for cursor positioning."
(insert (mapconcat #'identity
(split-string initial "\n")
(concat "\n" lead)))))
(?^
;; Interactive template entries.
(let ((completions nil)
(default nil)
(histvar nil))
(when prompt
(setq completions (org-split-string prompt "|"))
(setq prompt (pop completions))
(setq default (car completions))
(setq histvar
(intern (concat
"org-capture-template-prompt-history::"
(?a (insert v-a))
(?A (insert v-A))
(?c (insert v-c))
(?f (insert v-f))
(?F (insert v-F))
(?k (insert v-k))
(?K (insert v-K))
(?l (insert v-l))
(?t (insert v-t))
(?T (insert v-T))
(?u (insert v-u))
(?U (insert v-U))
(?x (insert v-x)))
(set-marker pos nil)
(set-marker end nil))))))
;; Expand %() embedded Elisp. Limit to Sexp originally marked.
(org-capture--expand-embedded-elisp)
;; Expand interactive templates. This is the last step so that
;; template is mostly expanded when prompting happens.
(let ((org-inhibit-startup t)) (org-mode))
(let (strings) ; Stores interactive answers.
(save-excursion
(let ((regexp "%\\^\\(?:{\\([^}]*\\)}\\)?\\([CgGLptTuU]\\)?"))
(while (re-search-forward regexp nil t)
(unless (org-capture-escaped-%)
(let* ((items
(and (match-end 1)
(save-match-data
(split-string (match-string-no-properties 1)
"|"))))
(prompt (nth 0 items))
(default (nth 1 items))
(completions (nthcdr 2 items))
(histvar
(intern
(concat "org-capture-template-prompt-history::"
(or prompt ""))))
(setq completions (mapcar #'list completions)))
(key (match-string 2)))
(delete-region (match-beginning 0) (match-end 0))
(pcase key
((or `"G" `"g")
(let* ((org-last-tags-completion-table
@ -1729,22 +1752,7 @@ The template may still contain \"%?\" for cursor positioning."
": ")
completions nil nil nil histvar default)
strings)
(insert (car strings))))))
(?a (insert v-a))
(?A (insert v-A))
(?c (insert v-c))
(?f (insert v-f))
(?F (insert v-F))
(?k (insert v-k))
(?K (insert v-K))
(?l (insert v-l))
(?t (insert v-t))
(?T (insert v-T))
(?u (insert v-u))
(?U (insert v-U))
(?x (insert v-x)))
(set-marker pos nil)
(set-marker end nil)))))
(insert (car strings)))))))))
;; Replace %n escapes with nth %^{...} string.
(setq strings (nreverse strings))
@ -1753,16 +1761,17 @@ The template may still contain \"%?\" for cursor positioning."
(unless (org-capture-escaped-%)
(replace-match
(nth (1- (string-to-number (match-string 1))) strings)
nil t))))
;; Expand %() embedded Elisp. Limit to Sexp originally marked.
(org-capture--expand-embedded-elisp)
nil t)))))
;; Make sure there are no empty lines before the text, and that
;; it ends with a newline character.
(goto-char (point-min))
(while (looking-at "[ \t]*\n") (replace-match ""))
(when (re-search-forward "[ \t\n]*\\'" nil t) (replace-match "\n"))
(skip-chars-forward " \t\n")
(delete-region (point-min) (line-beginning-position))
(goto-char (point-max))
(skip-chars-backward " \t\n")
(delete-region (point) (point-max))
(insert "\n")
;; Return the expanded template and kill the temporary buffer.
(untabify (point-min) (point-max))
(set-buffer-modified-p nil)