]> code.delx.au - gnu-emacs/blobdiff - lisp/org/org-capture.el
CC Mode: truncate the semi-nonlit cache when applying syntax-table to a quote
[gnu-emacs] / lisp / org / org-capture.el
index 05cca0e311ebad36531c3ee00d1b597caf63b089..6b5e857a04133652bfd202f1322fe5a43235d37b 100644 (file)
@@ -1,11 +1,10 @@
 ;;; org-capture.el --- Fast note taking in Org-mode
 
-;; Copyright (C) 2010-201 Free Software Foundation, Inc.
+;; Copyright (C) 2010-2016 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
-;; Version: 7.7
 ;;
 ;; This file is part of GNU Emacs.
 ;;
 ;;
 ;;; Commentary:
 
-;; This file contains an alternative implementation of the same functionality
-;; that is also provided by org-remember.el.  The implementation is more
+;; This file contains an alternative implementation of the functionality
+;; that used to be provided by org-remember.el.  The implementation is more
 ;; streamlined, can produce more target types (e.g. plain list items or
 ;; table lines).  Also, it does not use a temporary buffer for editing
 ;; the captured entry - instead it uses an indirect buffer that visits
 ;; the new entry already in the target buffer (this was an idea by Samuel
-;; Wales).  John Wiegley's excellent `remember.el' is not needed for this
-;; implementation, even though we borrow heavily from its ideas.
+;; Wales).  John Wiegley's excellent `remember.el' is not needed anymore
+;; for this implementation, even though we borrow heavily from its ideas.
 
 ;; This implementation heavily draws on ideas by James TD Smith and
 ;; Samuel Wales, and, of cause, uses John Wiegley's remember.el as inspiration.
 (eval-when-compile
   (require 'cl))
 (require 'org)
-(require 'org-mks)
 
 (declare-function org-datetree-find-date-create "org-datetree"
                  (date &optional keep-restriction))
 (declare-function org-table-get-specials "org-table" ())
 (declare-function org-table-goto-line "org-table" (N))
+(declare-function org-pop-to-buffer-same-window "org-compat"
+                 (&optional buffer-or-name norecord label))
+(declare-function org-at-encrypted-entry-p "org-crypt" ())
+(declare-function org-encrypt-entry "org-crypt" ())
+(declare-function org-decrypt-entry "org-crypt" ())
 
 (defvar org-remember-default-headline)
 (defvar org-remember-templates)
@@ -100,7 +103,7 @@ description  A short string describing the template, will be shown during
              selection.
 
 type         The type of entry.  Valid types are:
-               entry       an Org-mode node, with a headline. Will be
+               entry       an Org-mode node, with a headline.  Will be
                            filed as the child of the target entry or as
                            a top-level entry.
                item        a plain list item, will be placed in the
@@ -178,17 +181,27 @@ properties are:
                      template only needs information that can be added
                      automatically.
 
+ :jump-to-captured   When set, jump to the captured entry when finished.
+
  :empty-lines        Set this to the number of lines the should be inserted
                      before and after the new item.  Default 0, only common
                      other value is 1.
 
+ :empty-lines-before Set this to the number of lines the should be inserted
+                     before the new item.  Overrides :empty-lines for the
+                     number lines inserted before.
+
+ :empty-lines-after  Set this to the number of lines the should be inserted
+                     after the new item.  Overrides :empty-lines for the
+                     number of lines inserted after.
+
  :clock-in           Start the clock in this item.
 
  :clock-keep         Keep the clock running when filing the captured entry.
 
  :clock-resume       Start the interrupted clock when finishing the capture.
                      Note that :clock-keep has precedence over :clock-resume.
-                     When setting both to `t', the current clock will run and
+                     When setting both to t, the current clock will run and
                      the previous one will not be resumed.
 
  :unnarrowed         Do not narrow the target buffer, simply show the
@@ -210,138 +223,164 @@ will be filed as a child of the target headline.  It can also be
 freely formatted text.  Furthermore, the following %-escapes will
 be replaced with content and expanded in this order:
 
-  %[pathname] insert the contents of the file given by `pathname'.
-  %(sexp)     evaluate elisp `(sexp)' and replace with the result.
-  %<...>      the result of format-time-string on the ... format specification.
-  %t          time stamp, date only.
-  %T          time stamp with date and time.
-  %u, %U      like the above, but inactive time stamps.
-  %a          annotation, normally the link created with `org-store-link'.
-  %i          initial content, copied from the active region.  If %i is
+  %[pathname] Insert the contents of the file given by `pathname'.
+  %(sexp)     Evaluate elisp `(sexp)' and replace it with the results.
+              For convenience, %:keyword (see below) placeholders within
+              the expression will be expanded prior to this.
+  %<...>      The result of format-time-string on the ... format specification.
+  %t          Time stamp, date only.
+  %T          Time stamp with date and time.
+  %u, %U      Like the above, but inactive time stamps.
+  %i          Initial content, copied from the active region.  If %i is
               indented, the entire inserted text will be indented as well.
-  %A          like %a, but prompt for the description part.
-  %c          current kill ring head.
-  %x          content of the X clipboard.
-  %k          title of currently clocked task.
-  %K          link to currently clocked task.
-  %n          user name (taken from `user-full-name').
-  %f          file visited by current buffer when org-capture was called.
-  %F          full path of the file or directory visited by current buffer.
-  %:keyword   specific information for certain link types, see below.
-  %^g         prompt for tags, with completion on tags in target file.
-  %^G         prompt for tags, with completion on all tags in all agenda files.
-  %^t         like %t, but prompt for date.  Similarly %^T, %^u, %^U.
-              You may define a prompt like %^{Please specify birthday.
-  %^C         interactive selection of which kill or clip to use.
-  %^L         like %^C, but insert as link.
-  %^{prop}p   prompt the user for a value for property `prop'.
-  %^{prompt}  prompt the user for a string and replace this sequence with it.
+  %a          Annotation, normally the link created with `org-store-link'.
+  %A          Like %a, but prompt for the description part.
+  %l          Like %a, but only insert the literal link.
+  %c          Current kill ring head.
+  %x          Content of the X clipboard.
+  %k          Title of currently clocked task.
+  %K          Link to currently clocked task.
+  %n          User name (taken from the variable `user-full-name').
+  %f          File visited by current buffer when org-capture was called.
+  %F          Full path of the file or directory visited by current buffer.
+  %:keyword   Specific information for certain link types, see below.
+  %^g         Prompt for tags, with completion on tags in target file.
+  %^G         Prompt for tags, with completion on all tags in all agenda files.
+  %^t         Like %t, but prompt for date.  Similarly %^T, %^u, %^U.
+              You may define a prompt like: %^{Please specify birthday}t
+  %^C         Interactive selection of which kill or clip to use.
+  %^L         Like %^C, but insert as link.
+  %^{prop}p   Prompt the user for a value for property `prop'.
+  %^{prompt}  Prompt the user for a string and replace this sequence with it.
               A default value and a completion table ca be specified like this:
               %^{prompt|default|completion2|completion3|...}.
   %?          After completing the template, position cursor here.
+  %\\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
-or gnus will record the author and the subject of the message, which you
+Apart from these general escapes, you can access information specific to
+the link type that is created.  For example, calling `org-capture' in emails
+or in Gnus will record the author and the subject of the message, which you
 can access with \"%:from\" and \"%:subject\", respectively.  Here is a
 complete list of what is recorded for each link type.
 
 Link type               |  Available information
 ------------------------+------------------------------------------------------
 bbdb                    |  %:type %:name %:company
-vm, wl, mh, mew, rmail  |  %:type %:subject %:message-id
-                        |  %:from %:fromname %:fromaddress
+vm, wl, mh, mew, rmail, |  %:type %:subject %:message-id
+gnus                    |  %:from %:fromname %:fromaddress
                         |  %:to   %:toname   %:toaddress
                         |  %:fromto (either \"to NAME\" or \"from NAME\")
-                        |  %:date
-                        |  %:date-timestamp (as active timestamp)
+                        |  %:date %:date-timestamp (as active timestamp)
                         |  %:date-timestamp-inactive (as inactive timestamp)
 gnus                    |  %:group, for messages also all email fields
 w3, w3m                 |  %:type %:url
 info                    |  %:type %:file %:node
 calendar                |  %:type %:date"
   :group 'org-capture
+  :version "24.1"
   :type
   '(repeat
     (choice :value ("" "" entry (file "~/org/notes.org") "")
-     (list :tag "Multikey description"
-          (string :tag "Keys       ")
-          (string :tag "Description"))
-     (list :tag "Template entry"
-          (string :tag "Keys           ")
-          (string :tag "Description    ")
-          (choice :tag "Capture Type   " :value entry
-                  (const :tag "Org entry" entry)
-                  (const :tag "Plain list item" item)
-                  (const :tag "Checkbox item" checkitem)
-                  (const :tag "Plain text" plain)
-                  (const :tag "Table line" table-line))
-          (choice :tag "Target location"
-                  (list :tag "File"
-                        (const :format "" file)
-                        (file :tag "  File"))
-                  (list :tag "ID"
-                        (const :format "" id)
-                        (string :tag "  ID"))
-                  (list :tag "File & Headline"
-                        (const :format "" file+headline)
-                        (file   :tag "  File    ")
-                        (string :tag "  Headline"))
-                  (list :tag "File & Outline path"
-                        (const :format "" file+olp)
-                        (file   :tag "  File    ")
-                        (repeat :tag "Outline path" :inline t
-                                (string :tag "Headline")))
-                  (list :tag "File & Regexp"
-                        (const :format "" file+regexp)
-                        (file   :tag "  File  ")
-                        (regexp :tag "  Regexp"))
-                  (list :tag "File & Date tree"
-                        (const :format "" file+datetree)
-                        (file :tag "  File"))
-                  (list :tag "File & Date tree, prompt for date"
-                        (const :format "" file+datetree+prompt)
-                        (file :tag "  File"))
-                  (list :tag "File & function"
-                        (const :format "" file+function)
-                        (file :tag "  File    ")
-                        (sexp :tag "  Function"))
-                  (list :tag "Current clocking task"
-                        (const :format "" clock))
-                  (list :tag "Function"
-                        (const :format "" function)
-                        (sexp :tag "  Function")))
-          (choice :tag "Template"
-                  (string)
-                  (list :tag "File"
-                        (const :format "" file)
-                        (file :tag "Template file"))
-                  (list :tag "Function"
-                        (const :format "" function)
-                        (function :tag "Template function")))
-          (plist :inline t
-                 ;; Give the most common options as checkboxes
-                 :options (((const :format "%v " :prepend) (const t))
-                           ((const :format "%v " :immediate-finish) (const t))
-                           ((const :format "%v " :empty-lines) (const 1))
-                           ((const :format "%v " :clock-in) (const t))
-                           ((const :format "%v " :clock-keep) (const t))
-                           ((const :format "%v " :clock-resume) (const t))
-                           ((const :format "%v " :unnarrowed) (const t))
-                           ((const :format "%v " :kill-buffer) (const t))))))))
+           (list :tag "Multikey description"
+                 (string :tag "Keys       ")
+                 (string :tag "Description"))
+           (list :tag "Template entry"
+                 (string :tag "Keys           ")
+                 (string :tag "Description    ")
+                 (choice :tag "Capture Type   " :value entry
+                         (const :tag "Org entry" entry)
+                         (const :tag "Plain list item" item)
+                         (const :tag "Checkbox item" checkitem)
+                         (const :tag "Plain text" plain)
+                         (const :tag "Table line" table-line))
+                 (choice :tag "Target location"
+                         (list :tag "File"
+                               (const :format "" file)
+                               (file :tag "  File"))
+                         (list :tag "ID"
+                               (const :format "" id)
+                               (string :tag "  ID"))
+                         (list :tag "File & Headline"
+                               (const :format "" file+headline)
+                               (file   :tag "  File    ")
+                               (string :tag "  Headline"))
+                         (list :tag "File & Outline path"
+                               (const :format "" file+olp)
+                               (file   :tag "  File    ")
+                               (repeat :tag "Outline path" :inline t
+                                       (string :tag "Headline")))
+                         (list :tag "File & Regexp"
+                               (const :format "" file+regexp)
+                               (file   :tag "  File  ")
+                               (regexp :tag "  Regexp"))
+                         (list :tag "File & Date tree"
+                               (const :format "" file+datetree)
+                               (file :tag "  File"))
+                         (list :tag "File & Date tree, prompt for date"
+                               (const :format "" file+datetree+prompt)
+                               (file :tag "  File"))
+                         (list :tag "File & function"
+                               (const :format "" file+function)
+                               (file :tag "  File    ")
+                               (sexp :tag "  Function"))
+                         (list :tag "Current clocking task"
+                               (const :format "" clock))
+                         (list :tag "Function"
+                               (const :format "" function)
+                               (sexp :tag "  Function")))
+                 (choice :tag "Template"
+                         (string)
+                         (list :tag "File"
+                               (const :format "" file)
+                               (file :tag "Template file"))
+                         (list :tag "Function"
+                               (const :format "" function)
+                               (function :tag "Template function")))
+                 (plist :inline t
+                        ;; Give the most common options as checkboxes
+                        :options (((const :format "%v " :prepend) (const t))
+                                  ((const :format "%v " :immediate-finish) (const t))
+                                  ((const :format "%v " :jump-to-captured) (const t))
+                                  ((const :format "%v " :empty-lines) (const 1))
+                                  ((const :format "%v " :empty-lines-before) (const 1))
+                                  ((const :format "%v " :empty-lines-after) (const 1))
+                                  ((const :format "%v " :clock-in) (const t))
+                                  ((const :format "%v " :clock-keep) (const t))
+                                  ((const :format "%v " :clock-resume) (const t))
+                                  ((const :format "%v " :unnarrowed) (const t))
+                                  ((const :format "%v " :table-line-pos) (const t))
+                                  ((const :format "%v " :kill-buffer) (const t))))))))
 
 (defcustom org-capture-before-finalize-hook nil
   "Hook that is run right before a capture process is finalized.
-The capture buffer is still current when this hook runs."
+The capture buffer is still current when this hook runs and it is
+widened to the entire buffer."
   :group 'org-capture
+  :version "24.1"
   :type 'hook)
 
 (defcustom org-capture-after-finalize-hook nil
   "Hook that is run right after a capture process is finalized.
-  Suitable for window cleanup"
+Suitable for window cleanup."
   :group 'org-capture
+  :version "24.1"
   :type 'hook)
 
+(defcustom org-capture-prepare-finalize-hook nil
+  "Hook that is run before the finalization starts.
+The capture buffer is current and still narrowed."
+  :group 'org-capture
+  :version "24.1"
+  :type 'hook)
+
+(defcustom org-capture-bookmark t
+  "When non-nil, add a bookmark pointing at the last stored
+position when capturing."
+  :group 'org-capture
+  :version "24.3"
+  :type 'boolean)
+
 ;;; The property list for keeping information about the capture process
 
 (defvar org-capture-plist nil
@@ -372,7 +411,7 @@ to avoid conflicts with other active capture processes."
   (plist-get (if local org-capture-current-plist org-capture-plist) prop))
 
 (defun org-capture-member (prop &optional local)
-  "Is PROP a preperty in `org-capture-plist'.
+  "Is PROP a property in `org-capture-plist'.
 When LOCAL is set, use the local variable `org-capture-current-plist',
 this is necessary after initialization of the capture process,
 to avoid conflicts with other active capture processes."
@@ -389,18 +428,87 @@ for a capture buffer.")
   "Hook for the minor `org-capture-mode'.")
 
 (define-minor-mode org-capture-mode
-  "Minor mode for special key bindings in a capture buffer."
+  "Minor mode for special key bindings in a capture buffer.
+
+Turning on this mode runs the normal hook `org-capture-mode-hook'."
   nil " Rem" org-capture-mode-map
   (org-set-local
    'header-line-format
-   "Capture buffer.  Finish `C-c C-c', refile `C-c C-w', abort `C-c C-k'.")
-  (run-hooks 'org-capture-mode-hook))
+   (substitute-command-keys
+    "Capture buffer.  Finish `C-c C-c', refile `C-c C-w', abort `C-c C-k'.")))
 (define-key org-capture-mode-map "\C-c\C-c" 'org-capture-finalize)
 (define-key org-capture-mode-map "\C-c\C-k" 'org-capture-kill)
 (define-key org-capture-mode-map "\C-c\C-w" 'org-capture-refile)
 
 ;;; The main commands
 
+(defvar org-capture-initial nil)
+(defvar org-capture-entry nil)
+
+;;;###autoload
+(defun org-capture-string (string &optional keys)
+  "Capture STRING with the template selected by KEYS."
+  (interactive "sInitial text: \n")
+  (let ((org-capture-initial string)
+       (org-capture-entry (org-capture-select-template keys)))
+    (org-capture)))
+
+(defcustom org-capture-templates-contexts nil
+  "Alist of capture templates and valid contexts.
+
+For example, if you have a capture template \"c\" and you want
+this template to be accessible only from `message-mode' buffers,
+use this:
+
+   ((\"c\" ((in-mode . \"message-mode\"))))
+
+Here are the available contexts definitions:
+
+      in-file: command displayed only in matching files
+      in-mode: command displayed only in matching modes
+  not-in-file: command not displayed in matching files
+  not-in-mode: command not displayed in matching modes
+    in-buffer: command displayed only in matching buffers
+not-in-buffer: command not displayed in matching buffers
+   [function]: a custom function taking no argument
+
+If you define several checks, the agenda command will be
+accessible if there is at least one valid check.
+
+You can also bind a key to another agenda custom command
+depending on contextual rules.
+
+   ((\"c\" \"d\" ((in-mode . \"message-mode\"))))
+
+Here it means: in `message-mode buffers', use \"c\" as the
+key for the capture template otherwise associated with \"d\".
+\(The template originally associated with \"d\" is not displayed
+to avoid duplicates.)"
+  :version "24.3"
+  :group 'org-capture
+  :type '(repeat (list :tag "Rule"
+                      (string :tag "        Capture key")
+                      (string :tag "Replace by template")
+                      (repeat :tag "Available when"
+                             (choice
+                              (cons :tag "Condition"
+                                    (choice
+                                     (const :tag "In file" in-file)
+                                     (const :tag "Not in file" not-in-file)
+                                     (const :tag "In buffer" in-buffer)
+                                     (const :tag "Not in buffer" not-in-buffer)
+                                     (const :tag "In mode" in-mode)
+                                     (const :tag "Not in mode" not-in-mode))
+                                    (regexp))
+                              (function :tag "Custom function"))))))
+
+(defcustom org-capture-use-agenda-date nil
+  "Non-nil means use the date at point when capturing from agendas.
+When nil, you can still capture using the date at point with \\[org-agenda-capture]."
+  :group 'org-capture
+  :version "24.3"
+  :type 'boolean)
+
 ;;;###autoload
 (defun org-capture (&optional goto keys)
   "Capture something.
@@ -419,10 +527,19 @@ stored.
 
 When called with a `C-0' (zero) prefix, insert a template at point.
 
-Lisp programs can set KEYS to a string associated with a template in
-`org-capture-templates'.  In this case, interactive selection will be
-bypassed."
+ELisp programs can set KEYS to a string associated with a template
+in `org-capture-templates'.  In this case, interactive selection
+will be bypassed.
+
+If `org-capture-use-agenda-date' is non-nil, capturing from the
+agenda will use the date at point as the default date.  Then, a
+`C-1' prefix will tell the capture process to use the HH:MM time
+of the day at point (if any) or the current HH:MM time."
   (interactive "P")
+  (when (and org-capture-use-agenda-date
+            (eq major-mode 'org-agenda-mode))
+    (setq org-overriding-default-time
+         (org-get-cursor-date (equal goto 1))))
   (cond
    ((equal goto '(4)) (org-capture-goto-target))
    ((equal goto '(16)) (org-capture-goto-last-stored))
@@ -433,9 +550,11 @@ bypassed."
                                org-capture-link-is-already-stored)
                           (plist-get org-store-link-plist :annotation)
                         (ignore-errors (org-store-link nil))))
-          (initial (and (org-region-active-p)
-                        (buffer-substring (point) (mark))))
-          (entry (org-capture-select-template keys)))
+          (entry (or org-capture-entry (org-capture-select-template keys)))
+          initial)
+      (setq initial (or org-capture-initial
+                       (and (org-region-active-p)
+                            (buffer-substring (point) (mark)))))
       (when (stringp initial)
        (remove-text-properties 0 (length initial) '(read-only t) initial))
       (when (stringp annotation)
@@ -459,8 +578,9 @@ bypassed."
                              (file-name-nondirectory
                               (buffer-file-name orig-buf)))
                         :annotation annotation
-                        :initial initial)
-       (org-capture-put :default-time
+                        :initial initial
+                        :return-to-wconf (current-window-configuration)
+                        :default-time
                         (or org-overriding-default-time
                             (org-current-time)))
        (org-capture-set-target-location)
@@ -475,7 +595,8 @@ bypassed."
            ;;insert at point
            (org-capture-insert-template-here)
          (condition-case error
-             (org-capture-place-template)
+             (org-capture-place-template
+              (equal (car (org-capture-get :target)) 'function))
            ((error quit)
             (if (and (buffer-base-buffer (current-buffer))
                      (string-match "\\`CAPTURE-" (buffer-name)))
@@ -484,7 +605,7 @@ bypassed."
             (error "Capture template `%s': %s"
                    (org-capture-get :key)
                    (nth 1 error))))
-         (if (and (org-mode-p)
+         (if (and (derived-mode-p 'org-mode)
                   (org-capture-get :clock-in))
              (condition-case nil
                  (progn
@@ -496,7 +617,7 @@ bypassed."
                (error
                 "Could not start the clock in this capture buffer")))
          (if (org-capture-get :immediate-finish)
-             (org-capture-finalize nil)))))))))
+             (org-capture-finalize)))))))))
 
 (defun org-capture-get-template ()
   "Get the template from a file or a function if necessary."
@@ -521,10 +642,14 @@ bypassed."
 With prefix argument STAY-WITH-CAPTURE, jump to the location of the
 captured item after finalizing."
   (interactive "P")
+  (when (org-capture-get :jump-to-captured)
+    (setq stay-with-capture t))
   (unless (and org-capture-mode
               (buffer-base-buffer (current-buffer)))
     (error "This does not seem to be a capture buffer for Org-mode"))
 
+  (run-hooks 'org-capture-prepare-finalize-hook)
+
   ;; Did we start the clock in this capture buffer?
   (when (and org-capture-clock-was-started
             org-clock-marker (marker-buffer org-clock-marker)
@@ -572,9 +697,10 @@ captured item after finalizing."
          (goto-char end)
          (or (bolp) (newline))
          (org-capture-empty-lines-after
-          (or (org-capture-get :empty-lines 'local) 0))))
+          (or (org-capture-get :empty-lines-after 'local)
+              (org-capture-get :empty-lines 'local) 0))))
       ;; Postprocessing:  Update Statistics cookies, do the sorting
-      (when (org-mode-p)
+      (when (derived-mode-p 'org-mode)
        (save-excursion
          (when (ignore-errors (org-back-to-heading))
            (org-update-parent-todo-statistics)
@@ -589,11 +715,17 @@ captured item after finalizing."
       ;; Store this place as the last one where we stored something
       ;; Do the marking in the base buffer, so that it makes sense after
       ;; the indirect buffer has been killed.
-      (org-capture-bookmark-last-stored-position)
+      (when org-capture-bookmark
+       (org-capture-bookmark-last-stored-position))
 
       ;; Run the hook
       (run-hooks 'org-capture-before-finalize-hook))
 
+    (when (org-capture-get :decrypted)
+      (save-excursion
+       (goto-char (org-capture-get :decrypted))
+       (org-encrypt-entry)))
+
     ;; Kill the indirect buffer
     (save-buffer)
     (let ((return-wconf (org-capture-get :return-to-wconf 'local))
@@ -610,7 +742,8 @@ captured item after finalizing."
              (pos (org-capture-get :initial-target-position))
              (ipt (org-capture-get :insertion-point))
              (size (org-capture-get :captured-entry-size)))
-         (when reg
+         (if (not reg)
+             (widen)
            (cond ((< ipt (car reg))
                   ;; insertion point is before the narrowed region
                   (narrow-to-region (+ size (car reg)) (+ size (cdr reg))))
@@ -658,20 +791,20 @@ already gone.  Any prefix argument will be passed to the refile command."
   (let ((pos (point))
        (base (buffer-base-buffer (current-buffer)))
        (org-refile-for-capture t))
-    (org-capture-finalize)
     (save-window-excursion
       (with-current-buffer (or base (current-buffer))
        (save-excursion
          (save-restriction
            (widen)
            (goto-char pos)
-           (call-interactively 'org-refile)))))))
+           (call-interactively 'org-refile)))))
+    (org-capture-finalize)))
 
 (defun org-capture-kill ()
   "Abort the current capture process."
   (interactive)
-  ;; FIXME: This does not do the right thing, we need to remove the new stuff
-  ;; By hand it is easy: undo, then kill the buffer
+  ;; FIXME: This does not do the right thing, we need to remove the
+  ;; new stuff by hand it is easy: undo, then kill the buffer
   (let ((org-note-abort t)
        (org-capture-before-finalize-hook nil))
     (org-capture-finalize)))
@@ -695,9 +828,11 @@ already gone.  Any prefix argument will be passed to the refile command."
   ;; store the current point
   (org-capture-put :initial-target-position (point)))
 
+(defvar org-time-was-given) ; dynamically scoped parameter
 (defun org-capture-set-target-location (&optional target)
-  "Find target buffer and position and store then in the property list."
-  (let ((target-entry-p t))
+  "Find TARGET buffer and position.
+Store them in the capture property list."
+  (let ((target-entry-p t) decrypted-hl-pos)
     (setq target (or target (org-capture-get :target)))
     (save-excursion
       (cond
@@ -722,7 +857,7 @@ already gone.  Any prefix argument will be passed to the refile command."
        (widen)
        (let ((hd (nth 2 target)))
          (goto-char (point-min))
-         (unless (org-mode-p)
+         (unless (derived-mode-p 'org-mode)
            (error
             "Target buffer \"%s\" for file+headline should be in Org mode"
             (current-buffer)))
@@ -754,7 +889,7 @@ already gone.  Any prefix argument will be passed to the refile command."
              (goto-char (if (org-capture-get :prepend)
                             (match-beginning 0) (match-end 0)))
              (org-capture-put :exact-position (point))
-             (setq target-entry-p (and (org-mode-p) (org-at-heading-p))))
+             (setq target-entry-p (and (derived-mode-p 'org-mode) (org-at-heading-p))))
          (error "No match for target regexp in file %s" (nth 1 target))))
 
        ((memq (car target) '(file+datetree file+datetree+prompt))
@@ -776,10 +911,23 @@ already gone.  Any prefix argument will be passed to the refile command."
            (let ((prompt-time (org-read-date
                                nil t nil "Date for tree entry:"
                                (current-time))))
-             (org-capture-put :prompt-time prompt-time)
+             (org-capture-put
+              :default-time
+              (cond ((and (or (not (boundp 'org-time-was-given))
+                              (not org-time-was-given))
+                          (not (= (time-to-days prompt-time) (org-today))))
+                     ;; Use 00:00 when no time is given for another date than today?
+                     (apply 'encode-time (append '(0 0 0) (cdddr (decode-time prompt-time)))))
+                    ((string-match "\\([^ ]+\\)--?[^ ]+[ ]+\\(.*\\)" org-read-date-final-answer)
+                     ;; Replace any time range by its start
+                     (apply 'encode-time
+                            (org-read-date-analyze
+                             (replace-match "\\1 \\2" nil nil org-read-date-final-answer)
+                             prompt-time (decode-time prompt-time))))
+                    (t prompt-time)))
              (time-to-days prompt-time)))
           (t
-           ;; current date, possible corrected for late night workers
+           ;; current date, possibly corrected for late night workers
            (org-today))))))
 
        ((eq (car target) 'file+function)
@@ -788,12 +936,12 @@ already gone.  Any prefix argument will be passed to the refile command."
        (widen)
        (funcall (nth 2 target))
        (org-capture-put :exact-position (point))
-       (setq target-entry-p (and (org-mode-p) (org-at-heading-p))))
+       (setq target-entry-p (and (derived-mode-p 'org-mode) (org-at-heading-p))))
 
        ((eq (car target) 'function)
        (funcall (nth 1 target))
        (org-capture-put :exact-position (point))
-       (setq target-entry-p (and (org-mode-p) (org-at-heading-p))))
+       (setq target-entry-p (and (derived-mode-p 'org-mode) (org-at-heading-p))))
 
        ((eq (car target) 'clock)
        (if (and (markerp org-clock-hd-marker)
@@ -806,8 +954,14 @@ already gone.  Any prefix argument will be passed to the refile command."
 
        (t (error "Invalid capture target specification")))
 
+      (when (and (featurep 'org-crypt) (org-at-encrypted-entry-p))
+       (org-decrypt-entry)
+       (setq decrypted-hl-pos
+             (save-excursion (and (org-back-to-heading t) (point)))))
+
       (org-capture-put :buffer (current-buffer) :pos (point)
-                      :target-entry-p target-entry-p))))
+                      :target-entry-p target-entry-p
+                      :decrypted decrypted-hl-pos))))
 
 (defun org-capture-expand-file (file)
   "Expand functions and symbols for FILE.
@@ -831,14 +985,17 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
             (find-file-noselect (expand-file-name file org-directory)))))
 
 (defun org-capture-steal-local-variables (buffer)
-  "Install Org-mode local variables."
+  "Install Org-mode local variables of BUFFER."
   (mapc (lambda (v)
          (ignore-errors (org-set-local (car v) (cdr v))))
        (buffer-local-variables buffer)))
 
-(defun org-capture-place-template ()
-  "Insert the template at the target location, and display the buffer."
-  (org-capture-put :return-to-wconf (current-window-configuration))
+(defun org-capture-place-template (&optional inhibit-wconf-store)
+  "Insert the template at the target location, and display the buffer.
+When `inhibit-wconf-store', don't store the window configuration, as it
+may have been stored before."
+  (unless inhibit-wconf-store
+    (org-capture-put :return-to-wconf (current-window-configuration)))
   (delete-other-windows)
   (org-switch-to-buffer-other-window
    (org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE"))
@@ -846,7 +1003,8 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
   (show-all)
   (goto-char (org-capture-get :pos))
   (org-set-local 'org-capture-target-marker
-                (move-marker (make-marker) (point)))
+                (point-marker))
+  (org-set-local 'outline-level 'org-outline-level)
   (let* ((template (org-capture-get :template))
         (type (org-capture-get :type)))
     (case type
@@ -886,7 +1044,7 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
          (progn
            (outline-next-heading)
            (or (bolp) (insert "\n")))
-       (org-end-of-subtree t t)
+       (org-end-of-subtree t nil)
        (or (bolp) (insert "\n")))))
     (org-capture-empty-lines-before)
     (setq beg (point))
@@ -898,8 +1056,9 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
     (setq end (point))
     (org-capture-mark-kill-region beg (1- end))
     (org-capture-narrow beg (1- end))
-    (goto-char beg)
-    (if (re-search-forward "%\\?" end t) (replace-match ""))))
+    (if (or (re-search-backward "%\\?" beg t)
+           (re-search-forward "%\\?" end t))
+       (replace-match ""))))
 
 (defun org-capture-place-item ()
   "Place the template as a new plain list item."
@@ -907,30 +1066,30 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
         (target-entry-p (org-capture-get :target-entry-p))
         (ind 0)
         beg end)
-    (cond
-     ((org-capture-get :exact-position)
-      (goto-char (org-capture-get :exact-position)))
-     ((not target-entry-p)
-      ;; Insert as top-level entry, either at beginning or at end of file
-      (setq beg (point-min) end (point-max)))
-     (t
-      (setq beg (1+ (point-at-eol))
-           end (save-excursion (outline-next-heading) (point)))))
-    (if (org-capture-get :prepend)
-       (progn
-         (goto-char beg)
-         (if (org-list-search-forward (org-item-beginning-re) end t)
-             (progn
-               (goto-char (match-beginning 0))
-               (setq ind (org-get-indentation)))
-           (goto-char end)
-           (setq ind 0)))
-      (goto-char end)
-      (if (org-list-search-backward (org-item-beginning-re) beg t)
+    (if (org-capture-get :exact-position)
+       (goto-char (org-capture-get :exact-position))
+      (cond
+       ((not target-entry-p)
+       ;; Insert as top-level entry, either at beginning or at end of file
+       (setq beg (point-min) end (point-max)))
+       (t
+       (setq beg (1+ (point-at-eol))
+             end (save-excursion (outline-next-heading) (point)))))
+      (if (org-capture-get :prepend)
          (progn
-           (setq ind (org-get-indentation))
-           (org-end-of-item))
-       (setq ind 0)))
+           (goto-char beg)
+           (if (org-list-search-forward (org-item-beginning-re) end t)
+               (progn
+                 (goto-char (match-beginning 0))
+                 (setq ind (org-get-indentation)))
+             (goto-char end)
+             (setq ind 0)))
+       (goto-char end)
+       (if (org-list-search-backward (org-item-beginning-re) beg t)
+           (progn
+             (setq ind (org-get-indentation))
+             (org-end-of-item))
+         (setq ind 0))))
     ;; Remove common indentation
     (setq txt (org-remove-indentation txt))
     ;; Make sure this is indeed an item
@@ -955,7 +1114,9 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
     (setq end (point))
     (org-capture-mark-kill-region beg (1- end))
     (org-capture-narrow beg (1- end))
-    (if (re-search-forward "%\\?" end t) (replace-match ""))))
+    (if (or (re-search-backward "%\\?" beg t)
+           (re-search-forward "%\\?" end t))
+       (replace-match ""))))
 
 (defun org-capture-place-table-line ()
   "Place the template as a table line."
@@ -975,9 +1136,9 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
       (setq beg (1+ (point-at-eol))
            end (save-excursion (outline-next-heading) (point)))))
     (if (re-search-forward org-table-dataline-regexp end t)
-       (let ((b (org-table-begin)) (e (org-table-end)))
+       (let ((b (org-table-begin)) (e (org-table-end)) (case-fold-search t))
          (goto-char e)
-         (if (looking-at "[ \t]*#\\+TBLFM:")
+         (if (looking-at "[ \t]*#\\+tblfm:")
              (forward-line 1))
          (narrow-to-region b (point)))
       (goto-char end)
@@ -1033,7 +1194,9 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
       (setq end (point))))
     (goto-char beg)
     (org-capture-position-for-last-stored 'table-line)
-    (if (re-search-forward "%\\?" end t) (replace-match ""))
+    (if (or (re-search-backward "%\\?" beg t)
+           (re-search-forward "%\\?" end t))
+       (replace-match ""))
     (org-table-align)))
 
 (defun org-capture-place-plain-text ()
@@ -1068,7 +1231,9 @@ Of course, if exact position has been required, just put it there."
     (setq end (point))
     (org-capture-mark-kill-region beg (1- end))
     (org-capture-narrow beg (1- end))
-    (if (re-search-forward "%\\?" end t) (replace-match ""))))
+    (if (or (re-search-backward "%\\?" beg t)
+           (re-search-forward "%\\?" end t))
+       (replace-match ""))))
 
 (defun org-capture-mark-kill-region (beg end)
   "Mark the region that will have to be killed when aborting capture."
@@ -1109,7 +1274,11 @@ Of course, if exact position has been required, just put it there."
        (save-restriction
          (widen)
          (goto-char pos)
-         (bookmark-set "org-capture-last-stored")
+         (let ((bookmark-name (plist-get org-bookmark-names-plist
+                                         :last-capture)))
+           (when bookmark-name
+             (with-demoted-errors
+               (bookmark-set bookmark-name))))
          (move-marker org-capture-last-stored-marker (point)))))))
 
 (defun org-capture-narrow (beg end)
@@ -1119,18 +1288,20 @@ Of course, if exact position has been required, just put it there."
     (goto-char beg)))
 
 (defun org-capture-empty-lines-before (&optional n)
-  "Arrange for the correct number of empty lines before the insertion point.
+  "Set the correct number of empty lines before the insertion point.
 Point will be after the empty lines, so insertion can directly be done."
-  (setq n (or n (org-capture-get :empty-lines) 0))
+  (setq n (or n (org-capture-get :empty-lines-before)
+             (org-capture-get :empty-lines) 0))
   (let ((pos (point)))
     (org-back-over-empty-lines)
     (delete-region (point) pos)
     (if (> n 0) (newline n))))
 
 (defun org-capture-empty-lines-after (&optional n)
-  "Arrange for the correct number of empty lines after the inserted string.
+  "Set the correct number of empty lines after the inserted string.
 Point will remain at the first line after the inserted text."
-  (setq n (or n (org-capture-get :empty-lines) 0))
+  (setq n (or n (org-capture-get :empty-lines-after)
+             (org-capture-get :empty-lines) 0))
   (org-back-over-empty-lines)
   (while (looking-at "[ \t]*\n") (replace-match ""))
   (let ((pos (point)))
@@ -1138,19 +1309,20 @@ Point will remain at the first line after the inserted text."
     (goto-char pos)))
 
 (defvar org-clock-marker) ; Defined in org.el
-;;;###autoload
+
 (defun org-capture-insert-template-here ()
+  "Insert the capture template at point."
   (let* ((template (org-capture-get :template))
         (type  (org-capture-get :type))
         beg end pp)
     (or (bolp) (newline))
     (setq beg (point))
     (cond
-     ((and (eq type 'entry) (org-mode-p))
+     ((and (eq type 'entry) (derived-mode-p 'org-mode))
       (org-capture-verify-tree (org-capture-get :template))
       (org-paste-subtree nil template t))
      ((and (memq type '(item checkitem))
-          (org-mode-p)
+          (derived-mode-p 'org-mode)
           (save-excursion (skip-chars-backward " \t\n")
                           (setq pp (point))
                           (org-in-item-p)))
@@ -1199,7 +1371,7 @@ The user is queried for the template."
       (error "No capture template selected"))
     (org-capture-set-plist entry)
     (org-capture-set-target-location)
-    (switch-to-buffer (org-capture-get :buffer))
+    (org-pop-to-buffer-same-window (org-capture-get :buffer))
     (goto-char (org-capture-get :pos))))
 
 (defun org-capture-get-indirect-buffer (&optional buffer prefix)
@@ -1212,21 +1384,122 @@ Use PREFIX as a prefix for the name of the indirect buffer."
       (setq bname (concat prefix "-" (number-to-string (incf n)) "-" base)))
     (condition-case nil
         (make-indirect-buffer buffer bname 'clone)
-      (error (make-indirect-buffer buffer bname)))))
-
+      (error
+       (let ((buf (make-indirect-buffer buffer bname)))
+        (with-current-buffer buf (org-mode))
+        buf)))))
 
 (defun org-capture-verify-tree (tree)
-  "Throw error if TREE is not a valid tree"
+  "Throw error if TREE is not a valid tree."
   (unless (org-kill-is-subtree-p tree)
     (error "Template is not a valid Org entry or tree")))
 
-;;; The template code
+(defun org-mks (table title &optional prompt specials)
+  "Select a member of an alist with multiple keys.
+TABLE is the alist which should contain entries where the car is a string.
+There should be two types of entries.
+
+1. prefix descriptions like (\"a\" \"Description\")
+   This indicates that `a' is a prefix key for multi-letter selection, and
+   that there are entries following with keys like \"ab\", \"ax\"...
+
+2. Selectable members must have more than two elements, with the first
+   being the string of keys that lead to selecting it, and the second a
+   short description string of the item.
+
+The command will then make a temporary buffer listing all entries
+that can be selected with a single key, and all the single key
+prefixes.  When you press the key for a single-letter entry, it is selected.
+When you press a prefix key, the commands (and maybe further prefixes)
+under this key will be shown and offered for selection.
+
+TITLE will be placed over the selection in the temporary buffer,
+PROMPT will be used when prompting for a key.  SPECIAL is an alist with
+also (\"key\" \"description\") entries.  When one of these is selection,
+only the bare key is returned."
+  (setq prompt (or prompt "Select: "))
+  (let (tbl orig-table dkey ddesc des-keys allowed-keys
+           current prefix rtn re pressed buffer (inhibit-quit t))
+    (save-window-excursion
+      (setq buffer (org-switch-to-buffer-other-window "*Org Select*"))
+      (setq orig-table table)
+      (catch 'exit
+       (while t
+         (erase-buffer)
+         (insert title "\n\n")
+         (setq tbl table
+               des-keys nil
+               allowed-keys nil
+               cursor-type nil)
+         (setq prefix (if current (concat current " ") ""))
+         (while tbl
+           (cond
+            ((and (= 2 (length (car tbl))) (= (length (caar tbl)) 1))
+             ;; This is a description on this level
+             (setq dkey (caar tbl) ddesc (cadar tbl))
+             (pop tbl)
+             (push dkey des-keys)
+             (push dkey allowed-keys)
+             (insert prefix "[" dkey "]" "..." "  " ddesc "..." "\n")
+             ;; Skip keys which are below this prefix
+             (setq re (concat "\\`" (regexp-quote dkey)))
+             (let (case-fold-search)
+               (while (and tbl (string-match re (caar tbl))) (pop tbl))))
+            ((= 2 (length (car tbl)))
+             ;; Not yet a usable description, skip it
+             )
+            (t
+             ;; usable entry on this level
+             (insert prefix "[" (caar tbl) "]" "     " (nth 1 (car tbl)) "\n")
+             (push (caar tbl) allowed-keys)
+             (pop tbl))))
+         (when specials
+           (insert "-------------------------------------------------------------------------------\n")
+           (let ((sp specials))
+             (while sp
+               (insert (format "[%s]     %s\n"
+                               (caar sp) (nth 1 (car sp))))
+               (push (caar sp) allowed-keys)
+               (pop sp))))
+         (push "\C-g" allowed-keys)
+         (goto-char (point-min))
+         (if (not (pos-visible-in-window-p (point-max)))
+             (org-fit-window-to-buffer))
+         (message prompt)
+         (setq pressed (char-to-string (read-char-exclusive)))
+         (while (not (member pressed allowed-keys))
+           (message "Invalid key `%s'" pressed) (sit-for 1)
+           (message prompt)
+           (setq pressed (char-to-string (read-char-exclusive))))
+         (when (equal pressed "\C-g")
+           (kill-buffer buffer)
+           (error "Abort"))
+         (when (and (not (assoc pressed table))
+                    (not (member pressed des-keys))
+                    (assoc pressed specials))
+           (throw 'exit (setq rtn pressed)))
+         (unless (member pressed des-keys)
+           (throw 'exit (setq rtn (rassoc (cdr (assoc pressed table))
+                                          orig-table))))
+         (setq current (concat current pressed))
+         (setq table (mapcar
+                      (lambda (x)
+                        (if (and (> (length (car x)) 1)
+                                 (equal (substring (car x) 0 1) pressed))
+                            (cons (substring (car x) 1) (cdr x))
+                          nil))
+                      table))
+         (setq table (remove nil table)))))
+    (when buffer (kill-buffer buffer))
+    rtn))
 
+;;; The template code
 (defun org-capture-select-template (&optional keys)
   "Select a capture template.
 Lisp programs can force the template by setting KEYS to a string."
   (let ((org-capture-templates
-        (or org-capture-templates
+        (or (org-contextualize-keys
+             org-capture-templates org-capture-templates-contexts)
             '(("t" "Task" entry (file+headline "" "Tasks")
                "* TODO %?\n  %u\n  %a")))))
     (if keys
@@ -1243,8 +1516,7 @@ Lisp programs can force the template by setting KEYS to a string."
 The template may still contain \"%?\" for cursor positioning."
   (setq template (or template (org-capture-get :template)))
   (when (stringp initial)
-    (setq initial (org-no-properties initial))
-    (remove-text-properties 0 (length initial) '(read-only t) initial))
+    (setq initial (org-no-properties initial)))
   (let* ((buffer (org-capture-get :buffer))
         (file (buffer-file-name (or (buffer-base-buffer buffer) buffer)))
         (ct (org-capture-get :default-time))
@@ -1258,8 +1530,8 @@ The template may still contain \"%?\" for cursor positioning."
         (v-x (or (org-get-x-clipboard 'PRIMARY)
                  (org-get-x-clipboard 'CLIPBOARD)
                  (org-get-x-clipboard 'SECONDARY)))
-        (v-t (format-time-string (car org-time-stamp-formats) ct))
-        (v-T (format-time-string (cdr org-time-stamp-formats) ct))
+        (v-t (format-time-string (car org-time-stamp-formats) ct1))
+        (v-T (format-time-string (cdr org-time-stamp-formats) ct1))
         (v-u (concat "[" (substring v-t 1 -1) "]"))
         (v-U (concat "[" (substring v-T 1 -1) "]"))
         ;; `initial' and `annotation' might habe been passed.
@@ -1279,14 +1551,16 @@ The template may still contain \"%?\" for cursor positioning."
                                       (org-get-x-clipboard 'CLIPBOARD)
                                       (org-get-x-clipboard 'SECONDARY)
                                       v-c)))
-        (v-A (if (and v-a
-                      (string-match
-                       "\\[\\(\\[.*?\\]\\)\\(\\[.*?\\]\\)?\\]" v-a))
-                 (replace-match "[\\1[%^{Link description}]]" nil nil v-a)
+        (l-re "\\[\\[\\(.*?\\)\\]\\(\\[.*?\\]\\)?\\]")
+        (v-A (if (and v-a (string-match l-re v-a))
+                 (replace-match "[[\\1][%^{Link description}]]" nil nil v-a)
+               v-a))
+        (v-l (if (and v-a (string-match l-re v-a))
+                 (replace-match "\\1" nil nil v-a)
                v-a))
         (v-n user-full-name)
         (v-k (if (marker-buffer org-clock-marker)
-                 (org-substring-no-properties org-clock-heading)))
+                 (org-no-properties org-clock-heading)))
         (v-K (if (marker-buffer org-clock-marker)
                  (org-make-link-string
                   (buffer-file-name (marker-buffer org-clock-marker))
@@ -1297,7 +1571,7 @@ The template may still contain \"%?\" for cursor positioning."
         (org-startup-folded nil)
         (org-inhibit-startup t)
         org-time-was-given org-end-time-was-given x
-        prompt completions char time pos default histvar)
+        prompt completions char time pos default histvar strings)
 
     (setq org-store-link-plist
          (plist-put org-store-link-plist :annotation v-a)
@@ -1309,12 +1583,12 @@ The template may still contain \"%?\" for cursor positioning."
            (sit-for 1))
     (save-window-excursion
       (delete-other-windows)
-      (switch-to-buffer (get-buffer-create "*Capture*"))
+      (org-pop-to-buffer-same-window (get-buffer-create "*Capture*"))
       (erase-buffer)
       (insert template)
       (goto-char (point-min))
       (org-capture-steal-local-variables buffer)
-      (setq buffer-file-name nil)
+      (setq buffer-file-name nil mark-active nil)
 
       ;; %[] Insert contents of a file.
       (goto-char (point-min))
@@ -1327,18 +1601,10 @@ The template may still contain \"%?\" for cursor positioning."
            (delete-region start end)
            (condition-case error
                (insert-file-contents filename)
-             (error (insert (format "%%![Couldn't insert %s: %s]"
+             (error (insert (format "%%![Could not insert %s: %s]"
                                     filename error)))))))
       ;; %() embedded elisp
-      (goto-char (point-min))
-      (while (re-search-forward "%\\((.+)\\)" nil t)
-       (unless (org-capture-escaped-%)
-         (goto-char (match-beginning 0))
-         (let ((template-start (point)))
-           (forward-char 1)
-           (let ((result (org-eval (read (current-buffer)))))
-             (delete-region template-start (point))
-             (insert result)))))
+      (org-capture-expand-embedded-elisp)
 
       ;; The current time
       (goto-char (point-min))
@@ -1347,7 +1613,7 @@ The template may still contain \"%?\" for cursor positioning."
 
       ;; Simple %-escapes
       (goto-char (point-min))
-      (while (re-search-forward "%\\([tTuUaiAcxkKInfF]\\)" nil t)
+      (while (re-search-forward "%\\([tTuUaliAcxkKInfF]\\)" nil t)
        (unless (org-capture-escaped-%)
          (when (and initial (equal (match-string 0) "%i"))
            (save-match-data
@@ -1356,9 +1622,8 @@ The template may still contain \"%?\" for cursor positioning."
                (setq v-i (mapconcat 'identity
                                     (org-split-string initial "\n")
                                     (concat "\n" lead))))))
-         (replace-match
-          (or (eval (intern (concat "v-" (match-string 1)))) "")
-          t t)))
+         (replace-match (or (eval (intern (concat "v-" (match-string 1)))) "")
+                        t t)))
 
       ;; From the property list
       (when plist-p
@@ -1374,8 +1639,7 @@ The template may still contain \"%?\" for cursor positioning."
       (let ((org-inhibit-startup t)) (org-mode))
       ;; Interactive template entries
       (goto-char (point-min))
-      (while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([gGtTuUCLp]\\)?"
-                               nil t)
+      (while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([gGtTuUCLp]\\)?" nil t)
        (unless (org-capture-escaped-%)
          (setq char (if (match-end 3) (match-string-no-properties 3))
                prompt (if (match-end 2) (match-string-no-properties 2)))
@@ -1406,12 +1670,14 @@ The template may still contain \"%?\" for cursor positioning."
              (setq ins (mapconcat 'identity
                                   (org-split-string
                                    ins (org-re "[^[:alnum:]_@#%]+"))
-                                      ":"))
+                                  ":"))
              (when (string-match "\\S-" ins)
                (or (equal (char-before) ?:) (insert ":"))
                (insert ins)
                (or (equal (char-after) ?:) (insert ":"))
-               (and (org-on-heading-p) (org-set-tags nil 'align)))))
+               (and (org-at-heading-p)
+                    (let ((org-ignore-region t))
+                      (org-set-tags nil 'align))))))
           ((equal char "C")
            (cond ((= (length clipboards) 1) (insert (car clipboards)))
                  ((> (length clipboards) 1)
@@ -1427,7 +1693,7 @@ The template may still contain \"%?\" for cursor positioning."
                                                   '(clipboards . 1)
                                                   (car clipboards))))))
           ((equal char "p")
-           (org-set-property (org-substring-no-properties prompt) nil))
+           (org-set-property (org-no-properties prompt) nil))
           (char
            ;; These are the date/time related ones
            (setq org-time-was-given (equal (upcase char) char))
@@ -1439,17 +1705,27 @@ The template may still contain \"%?\" for cursor positioning."
                                   nil nil (list org-end-time-was-given)))
           (t
            (let (org-completion-use-ido)
-             (insert (org-completing-read-no-i
-                      (concat (if prompt prompt "Enter string")
-                              (if default (concat " [" default "]"))
-                              ": ")
-                      completions nil nil nil histvar default)))))))
+             (push (org-completing-read-no-i
+                    (concat (if prompt prompt "Enter string")
+                            (if default (concat " [" default "]"))
+                            ": ")
+                    completions nil nil nil histvar default)
+                   strings)
+             (insert (car strings)))))))
+      ;; Replace %n escapes with nth %^{...} string
+      (setq strings (nreverse strings))
+      (goto-char (point-min))
+      (while (re-search-forward "%\\\\\\([1-9][0-9]*\\)" nil t)
+       (unless (org-capture-escaped-%)
+         (replace-match
+          (nth (1- (string-to-number (match-string 1))) strings)
+          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 ""))
       (if (re-search-forward "[ \t\n]*\\'" nil t) (replace-match "\n"))
-      ;; Return the expanded tempate and kill the temporary buffer
+      ;; Return the expanded template and kill the temporary buffer
       (untabify (point-min) (point-max))
       (set-buffer-modified-p nil)
       (prog1 (buffer-string) (kill-buffer (current-buffer))))))
@@ -1462,9 +1738,57 @@ The template may still contain \"%?\" for cursor positioning."
        t)
     nil))
 
+(defun org-capture-expand-embedded-elisp ()
+  "Evaluate embedded elisp %(sexp) and replace with the result."
+  (goto-char (point-min))
+  (while (re-search-forward "%(" nil t)
+    (unless (org-capture-escaped-%)
+      (goto-char (match-beginning 0))
+      (let ((template-start (point)))
+       (forward-char 1)
+       (let* ((sexp (read (current-buffer)))
+              (result (org-eval
+                       (org-capture--expand-keyword-in-embedded-elisp sexp))))
+         (delete-region template-start (point))
+         (when result
+           (if (stringp result)
+               (insert result)
+             (error "Capture template sexp `%s' must evaluate to string or nil"
+                    sexp))))))))
+
+(defun org-capture--expand-keyword-in-embedded-elisp (attr)
+  "Recursively replace capture link keywords in ATTR sexp.
+Such keywords are prefixed with \"%:\".  See
+`org-capture-template' for more information."
+  (cond ((consp attr)
+        (mapcar 'org-capture--expand-keyword-in-embedded-elisp attr))
+       ((symbolp attr)
+        (let* ((attr-symbol (symbol-name attr))
+               (key (and (string-match "%\\(:.*\\)" attr-symbol)
+                         (intern (match-string 1 attr-symbol)))))
+          (or (plist-get org-store-link-plist key)
+              attr)))
+       (t attr)))
+
+(defun org-capture-inside-embedded-elisp-p ()
+  "Return non-nil if point is inside of embedded elisp %(sexp)."
+  (let (beg end)
+    (with-syntax-table emacs-lisp-mode-syntax-table
+      (save-excursion
+       ;; `looking-at' and `search-backward' below do not match the "%(" if
+       ;; point is in its middle
+       (when (equal (char-before) ?%)
+         (backward-char))
+       (save-match-data
+         (when (or (looking-at "%(") (search-backward "%(" nil t))
+           (setq beg (point))
+           (setq end (progn (forward-char) (forward-sexp) (1- (point)))))))
+      (when (and beg end)
+       (and (<= (point) end) (>= (point) beg))))))
+
 ;;;###autoload
 (defun org-capture-import-remember-templates ()
-  "Set org-capture-templates to be similar to `org-remember-templates'."
+  "Set `org-capture-templates' to be similar to `org-remember-templates'."
   (interactive)
   (when (and (yes-or-no-p
              "Import old remember templates into org-capture-templates? ")
@@ -1481,7 +1805,7 @@ The template may still contain \"%?\" for cursor positioning."
                   (position (or (nth 4 entry) org-remember-default-headline))
                   (type 'entry)
                   (prepend org-reverse-note-order)
-                  immediate target)
+                  immediate target jump-to-captured)
               (cond
                ((member position '(top bottom))
                 (setq target (list 'file file)
@@ -1495,14 +1819,16 @@ The template may still contain \"%?\" for cursor positioning."
                 (setq template (replace-match "" t t template)
                       immediate t))
 
+              (when (string-match "%&" template)
+                (setq jump-to-captured t))
+
               (append (list key desc type target template)
                       (if prepend '(:prepend t))
-                      (if immediate '(:immediate-finish t)))))
+                      (if immediate '(:immediate-finish t))
+                      (if jump-to-captured '(:jump-to-captured t)))))
 
           org-remember-templates))))
 
 (provide 'org-capture)
 
-
-
 ;;; org-capture.el ends here