* image-mode.el (image-mode): Add image-after-revert-hook to after-revert-hook.
[bpt/emacs.git] / lisp / org / org-remember.el
index 8a9bcec..a20539d 100644 (file)
@@ -1,11 +1,12 @@
 ;;; org-remember.el --- Fast note taking in Org-mode
 
-;; Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;;   Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
-;; Version: 6.02b
+;; Version: 6.35i
 ;;
 ;; This file is part of GNU Emacs.
 ;;
 ;;; Commentary:
 
 ;; This file contains the system to take fast notes with Org-mode.
-;; This system is used together with John Wiegleys `remember.el'.
+;; This system is used together with John Wiegley's `remember.el'.
 
 ;;; Code:
 
 (eval-when-compile
   (require 'cl))
 (require 'org)
+(require 'org-datetree)
 
+(declare-function remember-mode "remember" ())
 (declare-function remember "remember" (&optional initial))
 (declare-function remember-buffer-desc "remember" ())
 (declare-function remember-finalize "remember" ())
 (defvar remember-save-after-remembering)
-(defvar remember-data-file)
 (defvar remember-register)
 (defvar remember-buffer)
 (defvar remember-handler-functions)
 (defvar remember-annotation-functions)
+(defvar org-clock-heading)
+(defvar org-clock-heading-for-remember)
 
 (defgroup org-remember nil
   "Options concerning interaction with remember.el."
   :group 'org)
 
 (defcustom org-remember-store-without-prompt t
-  "Non-nil means, `C-c C-c' stores remember note without further promts.
-In this case, you need `C-u C-c C-c' to get the prompts for
-note file and headline.
+  "Non-nil means `C-c C-c' stores remember note without further prompts.
+It then uses the file and headline specified by the template or (if the
+template does not specify them) by the variables `org-default-notes-file'
+and `org-remember-default-headline'.  To force prompting anyway, use
+`C-u C-c C-c' to file the note.
+
 When this variable is nil, `C-c C-c' gives you the prompts, and
 `C-u C-c C-c' triggers the fasttrack."
   :group 'org-remember
@@ -62,7 +69,7 @@ When this variable is nil, `C-c C-c' gives you the prompts, and
   "The interface to be used for interactive filing of remember notes.
 This is only used when the interactive mode for selecting a filing
 location is used (see the variable `org-remember-store-without-prompt').
-Allowed vaues are:
+Allowed values are:
 outline                  The interface shows an outline of the relevant file
                          and the correct heading is found by moving through
                          the outline or by searching with incremental search.
@@ -99,13 +106,16 @@ it will be interpreted relative to `org-directory'.
 
 An optional fifth element can specify the headline in that file that should
 be offered first when the user is asked to file the entry.  The default
-headline is given in the variable `org-remember-default-headline'.
+headline is given in the variable `org-remember-default-headline'.  When
+this element is `top' or `bottom', the note will be placed as a level-1
+entry at the beginning or end of the file, respectively.
 
-An optional sixth element specifies the contexts in which the user can
-select the template.  This element can be either a list of major modes
-or a function.  `org-remember' will first check whether the function
-returns `t' or if we are in any of the listed major modes, and select
-the template accordingly.
+An optional sixth element specifies the contexts in which the template
+will be offered to the user.  This element can be a list of major modes
+or a function, and the template will only be offered if `org-remember'
+is called from a mode in the list, or if the function returns t.
+Templates that specify t or nil for the context will be always be added
+to the list of selectable templates.
 
 The template specifies the structure of the remember buffer.  It should have
 a first line starting with a star, to act as the org-mode headline.
@@ -117,19 +127,26 @@ Furthermore, the following %-escapes will be replaced with content:
   %t          time stamp, date only
   %T          time stamp with date and time
   %u, %U      like the above, but inactive time stamps
-  %^t         like %t, but prompt for date.  Similarly %^T, %^u, %^U
-              You may define a prompt like %^{Please specify birthday}t
+  %^t         like %t, but prompt for date.  Similarly %^T, %^u, %^U.
+              You may define a prompt like %^{Please specify birthday
   %n          user name (taken from `user-full-name')
   %a          annotation, normally the link created with org-store-link
-  %i          initial content, the region active.  If %i is indented,
-              the entire inserted text will be indented as well.
-  %c          content of the clipboard, or current kill ring head
+  %i          initial content, copied from the active region.  If %i is
+              indented, the entire inserted text will be indented as well.
+  %c          current kill ring head
+  %x          content of the X clipboard
+  %^C         Interactive selection of which kill or clip to use
+  %^L         Like %^C, but insert as link
+  %k          title of currently clocked task
+  %K          link to currently clocked task
   %^g         prompt for tags, with completion on tags in target file
   %^G         prompt for tags, with completion all tags in all agenda files
+  %^{prop}p   Prompt the user for a value for property `prop'
   %:keyword   specific information for certain link types, see below
   %[pathname] insert the contents of the file given by `pathname'
   %(sexp)     evaluate elisp `(sexp)' and replace with the result
   %!          Store this note immediately after filling the template
+  %&          Visit note immediately after storing it
 
   %?          After completing the template, position cursor here.
 
@@ -154,8 +171,8 @@ calendar           |  %:type %:date"
   :get (lambda (var) ; Make sure all entries have at least 5 elements
         (mapcar (lambda (x)
                   (if (not (stringp (car x))) (setq x (cons "" x)))
-                  (cond ((= (length x) 4) (append x '("")))
-                        ((= (length x) 3) (append x '("" "")))
+                  (cond ((= (length x) 4) (append x '(nil)))
+                        ((= (length x) 3) (append x '(nil nil)))
                         (t x)))
                 (default-value var)))
   :type '(repeat
@@ -164,26 +181,102 @@ calendar           |  %:type %:date"
                (string :tag "Name")
                (character :tag "Selection Key")
                (string :tag "Template")
-               (choice
-                (file :tag "Destination file")
-                (const :tag "Prompt for file" nil))
-               (choice
-                (string :tag "Destination headline")
-                (const :tag "Selection interface for heading"))
-               (choice
-                (const :tag "Use by default" nil)
+               (choice :tag "Destination file"
+                (file :tag "Specify")
+                (function :tag "Function")
+                (const :tag "Use `org-default-notes-file'" nil))
+               (choice :tag "Destin. headline"
+                (string :tag "Specify")
+                (function :tag "Function")
+                (const :tag "Use `org-remember-default-headline'" nil)
+                (const :tag "At beginning of file" top)
+                (const :tag "At end of file" bottom)
+                (const :tag "In a date tree" date-tree))
+               (choice :tag "Context"
+                (const :tag "Use in all contexts" nil)
                 (const :tag "Use in all contexts" t)
                 (repeat :tag "Use only if in major mode"
                         (symbol :tag "Major mode"))
                 (function :tag "Perform a check against function")))))
 
+(defcustom org-remember-delete-empty-lines-at-end t
+  "Non-nil means clean up final empty lines in remember buffer."
+  :group 'org-remember
+  :type 'boolean)
+
+(defcustom org-remember-before-finalize-hook nil
+  "Hook that is run right before a remember process is finalized.
+The remember buffer is still current when this hook runs."
+  :group 'org-remember
+  :type 'hook)
+
+(defvar org-remember-mode-map (make-sparse-keymap)
+  "Keymap for org-remember-mode, a minor mode.
+Use this map to set additional keybindings for when Org-mode is used
+for a Remember buffer.")
+(defvar org-remember-mode-hook nil
+  "Hook for the minor `org-remember-mode'.")
+
+(define-minor-mode org-remember-mode
+  "Minor mode for special key bindings in a remember buffer."
+  nil " Rem" org-remember-mode-map
+  (run-hooks 'org-remember-mode-hook))
+(define-key org-remember-mode-map "\C-c\C-c" 'org-remember-finalize)
+(define-key org-remember-mode-map "\C-c\C-k" 'org-remember-kill)
+
+(defcustom org-remember-clock-out-on-exit 'query
+  "Non-nil means stop the clock when exiting a clocking remember buffer.
+This only applies if the clock is running in the remember buffer.  If the
+clock is not stopped, it continues to run in the storage location.
+Instead of nil or t, this may also be the symbol `query' to prompt the
+user each time a remember buffer with a running clock is filed away.  "
+  :group 'org-remember
+  :type '(choice
+         (const :tag "Never" nil)
+         (const :tag "Always" t)
+         (const :tag "Query user" query)))
+
+(defcustom org-remember-backup-directory nil
+  "Directory where to store all remember buffers, for backup purposes.
+After a remember buffer has been stored successfully, the backup file
+will be removed.  However, if you forget to finish the remember process,
+the file will remain there.
+See also `org-remember-auto-remove-backup-files'."
+  :group 'org-remember
+  :type '(choice
+         (const :tag "No backups" nil)
+         (directory :tag "Directory")))
+
+(defcustom org-remember-auto-remove-backup-files t
+  "Non-nil means remove remember backup files after successfully storage.
+When remember is finished successfully, with storing the note at the
+desired target, remove the backup files related to this remember process
+and show a message about remaining backup files, from previous, unfinished
+remember sessions.
+Backup files will only be made at all, when `org-remember-backup-directory'
+is set."
+  :group 'org-remember
+  :type 'boolean)
+
+(defcustom org-remember-warn-about-backups t
+  "Non-nil means warn about backup files in `org-remember-backup-directory'.
+
+Set this to nil if you find that you don't need the warning.
+
+If you cancel remember calls frequently and know when they
+contain useful information (because you know that you made an
+error or emacs crashed, for example) nil is more useful.  In the
+opposite case, the default, t, is more useful."
+  :group 'org-remember
+  :type 'boolean)
+
 (defvar annotation) ; from remember.el, dynamically scoped in `remember-mode'
 (defvar initial)    ; from remember.el, dynamically scoped in `remember-mode'
 
 ;;;###autoload
 (defun org-remember-insinuate ()
-  "Setup remember.el for use wiht Org-mode."
-  (require 'remember)
+  "Setup remember.el for use with Org-mode."
+  (org-require-remember)
   (setq remember-annotation-functions '(org-remember-annotation))
   (setq remember-handler-functions '(org-remember-handler))
   (add-hook 'remember-mode-hook 'org-remember-apply-template))
@@ -203,7 +296,9 @@ RET on headline   -> Store as sublevel entry to current headline
 RET at beg-of-buf -> Append to file as level 2 headline
 <left>/<right>    -> before/after current headline, same headings level")
 
+(defvar org-jump-to-target-location nil)
 (defvar org-remember-previous-location nil)
+(defvar org-remember-reference-date nil)
 (defvar org-force-remember-template-char) ;; dynamically scoped
 
 ;; Save the major mode of the buffer we called remember from
@@ -234,7 +329,7 @@ RET at beg-of-buf -> Append to file as level 2 headline
                (mapcar (lambda(x) (if (not (nth 5 x)) x))
                        org-remember-templates)
              pre-selected-templates))
-          ;; Then unconditionnally add template for any contexts
+          ;; Then unconditionally add template for any contexts
           (pre-selected-templates2
            (append (mapcar (lambda(x) (if (eq (nth 5 x) t) x))
                            org-remember-templates)
@@ -244,6 +339,7 @@ RET at beg-of-buf -> Append to file as level 2 headline
                                    (append (list (nth 1 x) (car x)) (cddr x))
                                  (append (list (car x) "") (cdr x))))
                              (delq nil pre-selected-templates2)))
+          msg
           (char (or use-char
                     (cond
                      ((= (length templates) 1)
@@ -254,45 +350,72 @@ RET at beg-of-buf -> Append to file as level 2 headline
                           (string-to-char org-force-remember-template-char)
                         org-force-remember-template-char))
                      (t
-                      (message "Select template: %s"
-                               (mapconcat
-                                (lambda (x)
-                                  (cond
-                                   ((not (string-match "\\S-" (nth 1 x)))
-                                    (format "[%c]" (car x)))
-                                   ((equal (downcase (car x))
-                                           (downcase (aref (nth 1 x) 0)))
-                                    (format "[%c]%s" (car x)
-                                            (substring (nth 1 x) 1)))
-                                   (t (format "[%c]%s" (car x) (nth 1 x)))))
-                                templates " "))
-                      (let ((inhibit-quit t) (char0 (read-char-exclusive)))
+                      (setq msg (format
+                                 "Select template: %s%s"
+                                 (mapconcat
+                                  (lambda (x)
+                                    (cond
+                                     ((not (string-match "\\S-" (nth 1 x)))
+                                      (format "[%c]" (car x)))
+                                     ((equal (downcase (car x))
+                                             (downcase (aref (nth 1 x) 0)))
+                                      (format "[%c]%s" (car x)
+                                              (substring (nth 1 x) 1)))
+                                     (t (format "[%c]%s" (car x) (nth 1 x)))))
+                                  templates " ")
+                                 (if (assoc ?C templates)
+                                     ""
+                                   " [C]customize templates")))
+                      (let ((inhibit-quit t) char0)
+                        (while (not char0)
+                          (message msg)
+                          (setq char0 (read-char-exclusive))
+                          (when (and (not (assoc char0 templates))
+                                     (not (equal char0 ?\C-g))
+                                     (not (equal char0 ?C)))
+                            (message "No such template \"%c\"" char0)
+                            (ding) (sit-for 1)
+                            (setq char0 nil)))
                         (when (equal char0 ?\C-g)
                           (jump-to-register remember-register)
-                          (kill-buffer remember-buffer))
+                          (kill-buffer remember-buffer)
+                          (error "Abort"))
+                        (when (not (assoc char0 templates))
+                          (jump-to-register remember-register)
+                          (kill-buffer remember-buffer)
+                          (customize-variable 'org-remember-templates)
+                          (error "Customize templates"))
                         char0))))))
       (cddr (assoc char templates)))))
 
 (defun org-get-x-clipboard (value)
-  "Get the value of the x clibboard, in a way that also works with XEmacs."
+  "Get the value of the x clipboard, compatible with XEmacs, and GNU Emacs 21."
   (if (eq window-system 'x)
-      (let ((x (if org-xemacs-p
-                  (org-no-warnings (get-selection-no-error value))
-                (and (fboundp 'x-selection-value)
-                     (x-selection-value value)))))
-       (and (> (length x) 0) (set-text-properties 0 (length x) nil x) x))))
+      (let ((x (org-get-x-clipboard-compat value)))
+       (if x (org-no-properties x)))))
 
 ;;;###autoload
 (defun org-remember-apply-template (&optional use-char skip-interactive)
   "Initialize *remember* buffer with template, invoke `org-mode'.
 This function should be placed into `remember-mode-hook' and in fact requires
 to be run from that hook to function properly."
+  (when (and (boundp 'initial) (stringp initial))
+    (setq initial (org-no-properties initial))
+    (remove-text-properties 0 (length initial) '(read-only t) initial))
   (if org-remember-templates
       (let* ((entry (org-select-remember-template use-char))
+            (ct (or org-overriding-default-time (org-current-time)))
+            (dct (decode-time ct))
+            (ct1
+             (if (< (nth 2 dct) org-extend-today-until)
+                 (encode-time 0 59 23 (1- (nth 3 dct)) (nth 4 dct) (nth 5 dct))
+               ct))
             (tpl (car entry))
             (plist-p (if org-store-link-plist t nil))
-            (file (if (and (nth 1 entry) (stringp (nth 1 entry))
-                           (string-match "\\S-" (nth 1 entry)))
+            (file (if (and (nth 1 entry)
+                           (or (and (stringp (nth 1 entry))
+                                    (string-match "\\S-" (nth 1 entry)))
+                               (functionp (nth 1 entry))))
                       (nth 1 entry)
                     org-default-notes-file))
             (headline (nth 2 entry))
@@ -300,15 +423,20 @@ to be run from that hook to function properly."
             (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) (org-current-time)))
-            (v-T (format-time-string (cdr org-time-stamp-formats) (org-current-time)))
+            (v-t (format-time-string (car org-time-stamp-formats) ct))
+            (v-T (format-time-string (cdr org-time-stamp-formats) ct))
             (v-u (concat "[" (substring v-t 1 -1) "]"))
             (v-U (concat "[" (substring v-T 1 -1) "]"))
-            ;; `initial' and `annotation' are bound in `remember'
-            (v-i (if (boundp 'initial) initial))
-            (v-a (if (and (boundp 'annotation) annotation)
-                     (if (equal annotation "[[]]") "" annotation)
-                   ""))
+            ;; `initial' and `annotation' are bound in `remember'.
+            ;; But if the property list has them, we prefer those values
+            (v-i (or (plist-get org-store-link-plist :initial)
+                     (and (boundp 'initial) initial)
+                     ""))
+            (v-a (or (plist-get org-store-link-plist :annotation)
+                     (and (boundp 'annotation) annotation)
+                     ""))
+            ;; Is the link empty?  Then we do not want it...
+            (v-a (if (equal v-a "[[]]") "" v-a))
             (clipboards (remove nil (list v-i
                                           (org-get-x-clipboard 'PRIMARY)
                                           (org-get-x-clipboard 'CLIPBOARD)
@@ -319,177 +447,280 @@ to be run from that hook to function properly."
                      (replace-match "[\\1[%^{Link description}]]" 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)))
+            (v-K (if (marker-buffer org-clock-marker)
+                     (org-make-link-string
+                      (buffer-file-name (marker-buffer org-clock-marker))
+                      org-clock-heading)))
+            v-I
             (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)
+
+       (when (functionp file)
+         (setq file (funcall file)))
+       (when (functionp headline)
+         (setq headline (funcall headline)))
        (when (and file (not (file-name-absolute-p file)))
          (setq file (expand-file-name file org-directory)))
+
        (setq org-store-link-plist
-             (append (list :annotation v-a :initial v-i)
-                     org-store-link-plist))
+             (plist-put org-store-link-plist :annotation v-a)
+             org-store-link-plist
+             (plist-put org-store-link-plist :initial v-i))
+
        (unless tpl (setq tpl "") (message "No template") (ding) (sit-for 1))
        (erase-buffer)
        (insert (substitute-command-keys
                 (format
-"## Filing location: Select interactively, default, or last used:
+"## %s  \"%s\" -> \"* %s\"
+## C-u C-c C-c  like C-c C-c, and immediately visit note at target location
+## C-0 C-c C-c  \"%s\" -> \"* %s\"
 ## %s  to select file and header location interactively.
-## %s  \"%s\" -> \"* %s\"
-## C-u C-u C-c C-c  \"%s\" -> \"* %s\"
+## C-2 C-c C-c  as child (C-3: as sibling) of the currently clocked item
 ## To switch templates, use `\\[org-remember]'.  To abort use `C-c C-k'.\n\n"
-                 (if org-remember-store-without-prompt "    C-u C-c C-c" "        C-c C-c")
-                 (if org-remember-store-without-prompt "        C-c C-c" "    C-u C-c C-c")
+                 (if org-remember-store-without-prompt "    C-c C-c" "    C-1 C-c C-c")
                  (abbreviate-file-name (or file org-default-notes-file))
                  (or headline "")
                  (or (car org-remember-previous-location) "???")
-                 (or (cdr org-remember-previous-location) "???"))))
-       (insert tpl) (goto-char (point-min))
-       ;; Simple %-escapes
-       (while (re-search-forward "%\\([tTuUaiAcx]\\)" nil t)
-         (when (and initial (equal (match-string 0) "%i"))
-           (save-match-data
-             (let* ((lead (buffer-substring
-                           (point-at-bol) (match-beginning 0))))
-               (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))
+                 (or (cdr org-remember-previous-location) "???")
+                 (if org-remember-store-without-prompt "C-1 C-c C-c" "        C-c C-c"))))
+       (insert tpl)
 
        ;; %[] Insert contents of a file.
        (goto-char (point-min))
        (while (re-search-forward "%\\[\\(.+\\)\\]" nil t)
-         (let ((start (match-beginning 0))
-               (end (match-end 0))
-               (filename (expand-file-name (match-string 1))))
-           (goto-char start)
-           (delete-region start end)
-           (condition-case error
-               (insert-file-contents filename)
-             (error (insert (format "%%![Couldn't insert %s: %s]"
-                                    filename error))))))
+         (unless (org-remember-escaped-%)
+           (let ((start (match-beginning 0))
+                 (end (match-end 0))
+                 (filename (expand-file-name (match-string 1))))
+             (goto-char start)
+             (delete-region start end)
+             (condition-case error
+                 (insert-file-contents filename)
+               (error (insert (format "%%![Couldn't insert %s: %s]"
+                                      filename error)))))))
+       ;; Simple %-escapes
+       (goto-char (point-min))
+       (while (re-search-forward "%\\([tTuUaiAcxkKI]\\)" nil t)
+         (unless (org-remember-escaped-%)
+           (when (and initial (equal (match-string 0) "%i"))
+             (save-match-data
+               (let* ((lead (buffer-substring
+                             (point-at-bol) (match-beginning 0))))
+                 (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)))
+
        ;; %() embedded elisp
        (goto-char (point-min))
        (while (re-search-forward "%\\((.+)\\)" nil t)
-         (goto-char (match-beginning 0))
-         (let ((template-start (point)))
-           (forward-char 1)
-           (let ((result
-                  (condition-case error
-                      (eval (read (current-buffer)))
-                    (error (format "%%![Error: %s]" error)))))
-             (delete-region template-start (point))
-             (insert result))))
+         (unless (org-remember-escaped-%)
+           (goto-char (match-beginning 0))
+           (let ((template-start (point)))
+             (forward-char 1)
+             (let ((result
+                    (condition-case error
+                        (eval (read (current-buffer)))
+                      (error (format "%%![Error: %s]" error)))))
+               (delete-region template-start (point))
+               (insert result)))))
 
        ;; From the property list
        (when plist-p
          (goto-char (point-min))
          (while (re-search-forward "%\\(:[-a-zA-Z]+\\)" nil t)
+         (unless (org-remember-escaped-%)
            (and (setq x (or (plist-get org-store-link-plist
                                        (intern (match-string 1))) ""))
-                (replace-match x t t))))
+                (replace-match x t t)))))
 
        ;; Turn on org-mode in the remember buffer, set local variables
-       (org-mode)
-       (org-set-local 'org-finish-function 'org-remember-finalize)
+       (let ((org-inhibit-startup t)) (org-mode) (org-remember-mode 1))
        (if (and file (string-match "\\S-" file) (not (file-directory-p file)))
            (org-set-local 'org-default-notes-file file))
-       (if (and headline (stringp headline) (string-match "\\S-" headline))
+       (if headline
            (org-set-local 'org-remember-default-headline headline))
+       (org-set-local 'org-remember-reference-date
+                      (list (nth 4 dct) (nth 3 dct) (nth 5 dct)))
        ;; Interactive template entries
        (goto-char (point-min))
-       (while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([gGuUtTCL]\\)?" nil t)
-         (setq char (if (match-end 3) (match-string 3))
-               prompt (if (match-end 2) (match-string 2)))
-         (goto-char (match-beginning 0))
-         (replace-match "")
-         (setq completions nil default nil)
-         (when prompt
-           (setq completions (org-split-string prompt "|")
-                 prompt (pop completions)
-                 default (car completions)
-                 histvar (intern (concat
-                                  "org-remember-template-prompt-history::"
-                                  (or prompt "")))
-                 completions (mapcar 'list completions)))
-         (cond
-          ((member char '("G" "g"))
-           (let* ((org-last-tags-completion-table
-                   (org-global-tags-completion-table
-                    (if (equal char "G") (org-agenda-files) (and file (list file)))))
-                  (org-add-colon-after-tag-completion t)
-                  (ins (completing-read
-                        (if prompt (concat prompt ": ") "Tags: ")
-                        'org-tags-completion-function nil nil nil
-                        'org-tags-history)))
-             (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 ":")))))
-          ((equal char "C")
-           (cond ((= (length clipboards) 1) (insert (car clipboards)))
-                 ((> (length clipboards) 1)
-                  (insert (read-string "Clipboard/kill value: "
-                                       (car clipboards) '(clipboards . 1)
-                                       (car clipboards))))))
-          ((equal char "L")
-           (cond ((= (length clipboards) 1)
-                  (org-insert-link 0 (car clipboards)))
-                 ((> (length clipboards) 1)
-                  (org-insert-link 0 (read-string "Clipboard/kill value: "
-                                                  (car clipboards)
-                                                  '(clipboards . 1)
-                                                  (car clipboards))))))
-          (char
-           (setq org-time-was-given (equal (upcase char) char))
-           (setq time (org-read-date (equal (upcase char) "U") t nil
-                                     prompt))
-           (org-insert-time-stamp time org-time-was-given
-                                  (member char '("u" "U"))
-                                  nil nil (list org-end-time-was-given)))
-          (t
-           (insert (org-completing-read
-                    (concat (if prompt prompt "Enter string")
-                            (if default (concat " [" default "]"))
-                            ": ")
-                    completions nil nil nil histvar default)))))
+       (while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([gGtTuUCLp]\\)?" nil t)
+         (unless (org-remember-escaped-%)
+           (setq char (if (match-end 3) (match-string 3))
+                 prompt (if (match-end 2) (match-string 2)))
+           (goto-char (match-beginning 0))
+           (replace-match "")
+           (setq completions nil default nil)
+           (when prompt
+             (setq completions (org-split-string prompt "|")
+                   prompt (pop completions)
+                   default (car completions)
+                   histvar (intern (concat
+                                    "org-remember-template-prompt-history::"
+                                    (or prompt "")))
+                   completions (mapcar 'list completions)))
+           (cond
+            ((member char '("G" "g"))
+             (let* ((org-last-tags-completion-table
+                     (org-global-tags-completion-table
+                      (if (equal char "G") (org-agenda-files) (and file (list file)))))
+                    (org-add-colon-after-tag-completion t)
+                    (ins (org-icompleting-read
+                          (if prompt (concat prompt ": ") "Tags: ")
+                          'org-tags-completion-function nil nil nil
+                          'org-tags-history)))
+               (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 ":")))))
+            ((equal char "C")
+             (cond ((= (length clipboards) 1) (insert (car clipboards)))
+                   ((> (length clipboards) 1)
+                    (insert (read-string "Clipboard/kill value: "
+                                         (car clipboards) '(clipboards . 1)
+                                         (car clipboards))))))
+            ((equal char "L")
+             (cond ((= (length clipboards) 1)
+                    (org-insert-link 0 (car clipboards)))
+                   ((> (length clipboards) 1)
+                    (org-insert-link 0 (read-string "Clipboard/kill value: "
+                                                    (car clipboards)
+                                                    '(clipboards . 1)
+                                                    (car clipboards))))))
+            ((equal char "p")
+             (let*
+                 ((prop (org-substring-no-properties prompt))
+                  (pall (concat prop "_ALL"))
+                  (allowed
+                   (with-current-buffer
+                       (or (find-buffer-visiting file)
+                           (find-file-noselect file))
+                     (or (cdr (assoc pall org-file-properties))
+                         (cdr (assoc pall org-global-properties))
+                         (cdr (assoc pall org-global-properties-fixed)))))
+                  (existing (with-current-buffer
+                                (or (find-buffer-visiting file)
+                                    (find-file-noselect file))
+                              (mapcar 'list (org-property-values prop))))
+                  (propprompt (concat "Value for " prop ": "))
+                  (val (if allowed
+                           (org-completing-read
+                            propprompt
+                            (mapcar 'list (org-split-string allowed "[ \t]+"))
+                            nil 'req-match)
+                         (org-completing-read-no-i propprompt existing nil nil
+                                                   "" nil ""))))
+               (org-set-property prop val)))
+            (char
+             ;; These are the date/time related ones
+             (setq org-time-was-given (equal (upcase char) char))
+             (setq time (org-read-date (equal (upcase char) "U") t nil
+                                       prompt))
+             (org-insert-time-stamp time org-time-was-given
+                                    (member char '("u" "U"))
+                                    nil nil (list org-end-time-was-given)))
+            (t
+             (let (org-completion-use-ido)
+               (insert (org-without-partial-completion
+                        (org-completing-read-no-i
+                         (concat (if prompt prompt "Enter string")
+                                 (if default (concat " [" default "]"))
+                                 ": ")
+                         completions nil nil nil histvar default))))))))
+
        (goto-char (point-min))
        (if (re-search-forward "%\\?" nil t)
            (replace-match "")
          (and (re-search-forward "^[^#\n]" nil t) (backward-char 1))))
-    (org-mode)
-    (org-set-local 'org-finish-function 'org-remember-finalize))
+    (let ((org-inhibit-startup t)) (org-mode) (org-remember-mode 1)))
+  (when (save-excursion
+         (goto-char (point-min))
+         (re-search-forward "%&" nil t))
+    (replace-match "")
+    (org-set-local 'org-jump-to-target-location t))
+  (when org-remember-backup-directory
+    (unless (file-directory-p org-remember-backup-directory)
+      (make-directory org-remember-backup-directory))
+    (org-set-local 'auto-save-file-name-transforms nil)
+    (setq buffer-file-name
+         (expand-file-name
+          (format-time-string "remember-%Y-%m-%d-%H-%M-%S")
+          org-remember-backup-directory))
+    (save-buffer)
+    (org-set-local 'auto-save-visited-file-name t)
+    (auto-save-mode 1))
   (when (save-excursion
          (goto-char (point-min))
          (re-search-forward "%!" nil t))
     (replace-match "")
     (add-hook 'post-command-hook 'org-remember-finish-immediately 'append)))
 
+(defun org-remember-escaped-% ()
+  (if (equal (char-before (match-beginning 0)) ?\\)
+      (progn
+       (delete-region (1- (match-beginning 0)) (match-beginning 0))
+       t)
+    nil))
+
+
 (defun org-remember-finish-immediately ()
   "File remember note immediately.
 This should be run in `post-command-hook' and will remove itself
 from that hook."
   (remove-hook 'post-command-hook 'org-remember-finish-immediately)
-  (when org-finish-function
-    (funcall org-finish-function)))
+  (org-remember-finalize))
+
+(defun org-remember-visit-immediately ()
+  "File remember note immediately.
+This should be run in `post-command-hook' and will remove itself
+from that hook."
+  (org-remember '(16))
+  (goto-char (or (text-property-any
+                 (point) (save-excursion (org-end-of-subtree t t))
+                 'org-position-cursor t)
+                (point)))
+  (message "%s"
+          (format
+           (substitute-command-keys
+            "Restore window configuration with \\[jump-to-register] %c")
+           remember-register)))
 
-(defvar org-clock-marker) ; Defined below
+(defvar org-clock-marker) ; Defined in org.el
 (defun org-remember-finalize ()
   "Finalize the remember process."
+  (interactive)
+  (unless org-remember-mode
+    (error "This does not seem to be a remember buffer for Org-mode"))
+  (run-hooks 'org-remember-before-finalize-hook)
   (unless (fboundp 'remember-finalize)
     (defalias 'remember-finalize 'remember-buffer))
   (when (and org-clock-marker
             (equal (marker-buffer org-clock-marker) (current-buffer)))
-    ;; FIXME: test this, this is w/o notetaking!
-    (let (org-log-note-clock-out) (org-clock-out)))
+    ;; the clock is running in this buffer.
+    (when (and (equal (marker-buffer org-clock-marker) (current-buffer))
+              (or (eq org-remember-clock-out-on-exit t)
+                  (and org-remember-clock-out-on-exit
+                       (y-or-n-p "The clock is running in this buffer.  Clock out now? "))))
+      (let (org-log-note-clock-out) (org-clock-out))))
   (when buffer-file-name
-    (save-buffer)
-    (setq buffer-file-name nil))
+    (do-auto-save))
   (remember-finalize))
 
+(defun org-remember-kill ()
+  "Abort the current remember process."
+  (interactive)
+  (let ((org-note-abort t))
+    (org-remember-finalize)))
+
 ;;;###autoload
 (defun org-remember (&optional goto org-force-remember-template-char)
   "Call `remember'.  If this is already a remember buffer, re-apply template.
@@ -504,6 +735,7 @@ note stored by remember.
 Lisp programs can set ORG-FORCE-REMEMBER-TEMPLATE-CHAR to a character
 associated with a template in `org-remember-templates'."
   (interactive "P")
+  (org-require-remember)
   (cond
    ((equal goto '(4)) (org-go-to-remember-target))
    ((equal goto '(16)) (org-remember-goto-last-stored))
@@ -512,7 +744,7 @@ associated with a template in `org-remember-templates'."
     ;; `org-select-remember-template'
     (setq org-select-template-temp-major-mode major-mode)
     (setq org-select-template-original-buffer (current-buffer))
-    (if (eq org-finish-function 'org-remember-finalize)
+    (if org-remember-mode
        (progn
          (when (< (length org-remember-templates) 2)
            (error "No other template available"))
@@ -525,10 +757,14 @@ associated with a template in `org-remember-templates'."
          (org-do-remember (buffer-substring (point) (mark)))
        (org-do-remember))))))
 
+(defvar org-remember-last-stored-marker (make-marker)
+  "Marker pointing to the entry most recently stored with `org-remember'.")
+
 (defun org-remember-goto-last-stored ()
   "Go to the location where the last remember note was stored."
   (interactive)
-  (bookmark-jump "org-remember-last-stored")
+  (org-goto-marker-or-bmk org-remember-last-stored-marker
+                         "org-remember-last-stored")
   (message "This is the last note stored by remember"))
 
 (defun org-go-to-remember-target (&optional template-key)
@@ -552,144 +788,208 @@ The user is queried for the template."
     (widen)
     (goto-char (point-min))
     (if (re-search-forward
-        (concat "^\\*+[ \t]+" (regexp-quote heading)
-                (org-re "\\([ \t]+:[[:alnum:]@_:]*\\)?[ \t]*$"))
+        (format org-complex-heading-regexp-format (regexp-quote heading))
         nil t)
        (goto-char (match-beginning 0))
       (error "Target headline not found: %s" heading))))
 
+;; FIXME (bzg): let's clean up of final empty lines happen only once
+;; (see the org-remember-delete-empty-lines-at-end option below)
 ;;;###autoload
 (defun org-remember-handler ()
   "Store stuff from remember.el into an org file.
-First prompts for an org file.  If the user just presses return, the value
-of `org-default-notes-file' is used.
-Then the command offers the headings tree of the selected file in order to
-file the text at a specific location.
-You can either immediately press RET to get the note appended to the
-file, or you can use vertical cursor motion and visibility cycling (TAB) to
-find a better place.  Then press RET or <left> or <right> in insert the note.
-
-Key      Cursor position   Note gets inserted
------------------------------------------------------------------------------
-RET      buffer-start      as level 1 heading at end of file
-RET      on headline       as sublevel of the heading at cursor
-RET      no heading        at cursor position, level taken from context.
-                          Or use prefix arg to specify level manually.
-<left>   on headline       as same level, before current heading
-<right>  on headline       as same level, after current heading
-
-So the fastest way to store the note is to press RET RET to append it to
-the default file.  This way your current train of thought is not
-interrupted, in accordance with the principles of remember.el.
-You can also get the fast execution without prompting by using
-C-u C-c C-c to exit the remember buffer.  See also the variable
-`org-remember-store-without-prompt'.
-
-Before being stored away, the function ensures that the text has a
-headline, i.e. a first line that starts with a \"*\".  If not, a headline
-is constructed from the current date and some additional data.
+When the template has specified a file and a headline, the entry is filed
+there, or in the location defined by `org-default-notes-file' and
+`org-remember-default-headline'.
+
+If no defaults have been defined, or if the current prefix argument
+is 1 (so you must use `C-1 C-c C-c' to exit remember), an interactive
+process is used to select the target location.
+
+When the prefix is 0 (i.e. when remember is exited with `C-0 C-c C-c'),
+the entry is filed to the same location as the previous note.
+
+When the prefix is 2 (i.e. when remember is exited with `C-2 C-c C-c'),
+the entry is filed as a subentry of the entry where the clock is
+currently running.
+
+When `C-u' has been used as prefix argument, the note is stored and emacs
+moves point to the new location of the note, so that editing can be
+continued there (similar to inserting \"%&\" into the template).
+
+Before storing the note, the function ensures that the text has an
+org-mode-style headline, i.e. a first line that starts with
+a \"*\".  If not, a headline is constructed from the current date and
+some additional data.
 
 If the variable `org-adapt-indentation' is non-nil, the entire text is
 also indented so that it starts in the same column as the headline
 \(i.e. after the stars).
 
 See also the variable `org-reverse-note-order'."
+  (when (and (equal current-prefix-arg 2)
+            (not (marker-buffer org-clock-marker)))
+    (error "No running clock"))
+  (when (org-bound-and-true-p org-jump-to-target-location)
+    (let* ((end (min (point-max) (1+ (point))))
+          (beg (point)))
+      (if (= end beg) (setq beg (1- beg)))
+      (put-text-property beg end 'org-position-cursor t)))
   (goto-char (point-min))
   (while (looking-at "^[ \t]*\n\\|^##.*\n")
     (replace-match ""))
-  (goto-char (point-max))
-  (beginning-of-line 1)
-  (while (looking-at "[ \t]*$\\|##.*")
-    (delete-region (1- (point)) (point-max))
-    (beginning-of-line 1))
+  (when org-remember-delete-empty-lines-at-end
+    (goto-char (point-max))
+    (beginning-of-line 1)
+    (while (and (looking-at "[ \t]*$\\|##.*") (> (point) 1))
+      (delete-region (1- (point)) (point-max))
+      (beginning-of-line 1)))
   (catch 'quit
-    (if org-note-abort (throw 'quit nil))
-    (let* ((txt (buffer-substring (point-min) (point-max)))
-          (fastp (org-xor (equal current-prefix-arg '(4))
+    (if org-note-abort (throw 'quit t))
+    (let* ((visitp (org-bound-and-true-p org-jump-to-target-location))
+          (backup-file
+           (and buffer-file-name
+                (equal (file-name-directory buffer-file-name)
+                       (file-name-as-directory
+                        (expand-file-name org-remember-backup-directory)))
+                (string-match "^remember-[0-9]\\{4\\}"
+                              (file-name-nondirectory buffer-file-name))
+                buffer-file-name))
+
+          (dummy
+           (unless (string-match "\\S-" (buffer-string))
+             (message "Nothing to remember")
+             (and backup-file
+                  (ignore-errors
+                    (delete-file backup-file)
+                    (delete-file (concat backup-file "~"))))
+             (set-buffer-modified-p nil)
+             (throw 'quit t)))
+          (reference-date org-remember-reference-date)
+          (previousp (and (member current-prefix-arg '((16) 0))
+                          org-remember-previous-location))
+          (clockp (equal current-prefix-arg 2))
+          (clocksp (equal current-prefix-arg 3))
+          (fastp (org-xor (equal current-prefix-arg 1)
                           org-remember-store-without-prompt))
           (file (cond
                  (fastp org-default-notes-file)
                  ((and (eq org-remember-interactive-interface 'refile)
                        org-refile-targets)
                   org-default-notes-file)
-                 ((not (and (equal current-prefix-arg '(16))
-                            org-remember-previous-location))
+                 ((not previousp)
                   (org-get-org-file))))
           (heading org-remember-default-headline)
           (visiting (and file (org-find-base-buffer-visiting file)))
           (org-startup-folded nil)
           (org-startup-align-all-tables nil)
           (org-goto-start-pos 1)
-          spos exitcmd level indent reversed)
-      (if (and (equal current-prefix-arg '(16)) org-remember-previous-location)
-         (setq file (car org-remember-previous-location)
-               heading (cdr org-remember-previous-location)
-               fastp t))
+          spos exitcmd level reversed txt text-before-node-creation)
+      (when (equal current-prefix-arg '(4))
+       (setq visitp t))
+      (when previousp
+       (setq file (car org-remember-previous-location)
+             visiting (and file (org-find-base-buffer-visiting file))
+             heading (cdr org-remember-previous-location)
+             fastp t))
+      (when (or clockp clocksp)
+       (setq file (buffer-file-name (marker-buffer org-clock-marker))
+             visiting (and file (org-find-base-buffer-visiting file))
+             heading org-clock-heading-for-remember
+             fastp t))
       (setq current-prefix-arg nil)
-      (if (string-match "[ \t\n]+\\'" txt)
-         (setq txt (replace-match "" t t txt)))
       ;; Modify text so that it becomes a nice subtree which can be inserted
       ;; into an org tree.
-      (let* ((lines (split-string txt "\n"))
-            first)
-       (setq first (car lines) lines (cdr lines))
-       (if (string-match "^\\*+ " first)
-           ;; Is already a headline
-           (setq indent nil)
-         ;; We need to add a headline:  Use time and first buffer line
-         (setq lines (cons first lines)
-               first (concat "* " (current-time-string)
-                             " (" (remember-buffer-desc) ")")
-               indent "  "))
-       (if (and org-adapt-indentation indent)
-           (setq lines (mapcar
-                        (lambda (x)
-                          (if (string-match "\\S-" x)
-                              (concat indent x) x))
-                        lines)))
-       (setq txt (concat first "\n"
-                         (mapconcat 'identity lines "\n"))))
-      (if (string-match "\n[ \t]*\n[ \t\n]*\\'" txt)
-         (setq txt (replace-match "\n\n" t t txt))
-       (if (string-match "[ \t\n]*\\'" txt)
-           (setq txt (replace-match "\n" t t txt))))
-      ;; Put the modified text back into the remember buffer, for refile.
-      (erase-buffer)
-      (insert txt)
+      (when org-remember-delete-empty-lines-at-end
+       (goto-char (point-min))
+       (if (re-search-forward "[ \t\n]+\\'" nil t)
+           ;; remove empty lines at end
+           (replace-match "")))
+      (goto-char (point-min))
+      (setq text-before-node-creation (buffer-string))
+      (unless (looking-at org-outline-regexp)
+       ;; add a headline
+       (insert (concat "* " (current-time-string)
+                       " (" (remember-buffer-desc) ")\n"))
+       (backward-char 1)
+       (when org-adapt-indentation
+         (while (re-search-forward "^" nil t)
+           (insert "  "))))
+      ;; Delete final empty lines
+      (when org-remember-delete-empty-lines-at-end
+       (goto-char (point-min))
+       (if (re-search-forward "\n[ \t]*\n[ \t\n]*\\'" nil t)
+           (replace-match "\n\n")
+         (if (re-search-forward "[ \t\n]*\\'")
+             (replace-match "\n"))))
       (goto-char (point-min))
+      (setq txt (buffer-string))
+      (org-save-markers-in-region (point-min) (point-max))
+      (set-buffer-modified-p nil)
       (when (and (eq org-remember-interactive-interface 'refile)
                 (not fastp))
        (org-refile nil (or visiting (find-file-noselect file)))
+       (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately))
+       (save-excursion
+         (bookmark-jump "org-refile-last-stored")
+         (bookmark-set "org-remember-last-stored")
+         (move-marker org-remember-last-stored-marker (point)))
        (throw 'quit t))
       ;; Find the file
-      (if (not visiting) (find-file-noselect file))
-      (with-current-buffer (or visiting (get-file-buffer file))
-       (unless (org-mode-p)
-         (error "Target files for remember notes must be in Org-mode"))
+      (with-current-buffer (or visiting (find-file-noselect file))
+       (unless (or (org-mode-p) (member heading '(top bottom)))
+         (error "Target files for notes must be in Org-mode if not filing to top/bottom"))
        (save-excursion
          (save-restriction
            (widen)
-           (and (goto-char (point-min))
-                (not (re-search-forward "^\\* " nil t))
-                (insert "\n* " (or heading "Notes") "\n"))
            (setq reversed (org-notes-order-reversed-p))
 
            ;; Find the default location
-           (when (and heading (stringp heading) (string-match "\\S-" heading))
-             (goto-char (point-min))
-             (if (re-search-forward
-                  (concat "^\\*+[ \t]+" (regexp-quote heading)
-                          (org-re "\\([ \t]+:[[:alnum:]@_:]*\\)?[ \t]*$"))
-                  nil t)
-                 (setq org-goto-start-pos (match-beginning 0))
-               (when fastp
+           (when heading
+             (cond
+              ((not (org-mode-p))
+               (if (eq heading 'top)
+                   (goto-char (point-min))
                  (goto-char (point-max))
-                 (unless (bolp) (newline))
-                 (insert "* " heading "\n")
-                 (setq org-goto-start-pos (point-at-bol 0)))))
+                 (or (bolp) (newline)))
+               (insert text-before-node-creation)
+               (when remember-save-after-remembering
+                 (save-buffer)
+                 (if (not visiting) (kill-buffer (current-buffer))))
+               (throw 'quit t))
+              ((eq heading 'top)
+               (goto-char (point-min))
+               (or (looking-at org-outline-regexp)
+                   (re-search-forward org-outline-regexp nil t))
+               (setq org-goto-start-pos (or (match-beginning 0) (point-min))))
+              ((eq heading 'bottom)
+               (goto-char (point-max))
+               (or (bolp) (newline))
+               (setq org-goto-start-pos (point)))
+              ((eq heading 'date-tree)
+               (org-datetree-find-date-create reference-date)
+               (setq reversed nil)
+               (setq org-goto-start-pos (point)))
+              ((and (stringp heading) (string-match "\\S-" heading))
+               (goto-char (point-min))
+               (if (re-search-forward
+                    (format org-complex-heading-regexp-format
+                            (regexp-quote heading))
+                    nil t)
+                   (setq org-goto-start-pos (match-beginning 0))
+                 (when fastp
+                   (goto-char (point-max))
+                   (unless (bolp) (newline))
+                   (insert "* " heading "\n")
+                   (setq org-goto-start-pos (point-at-bol 0)))))
+              (t (goto-char (point-min)) (setq org-goto-start-pos (point)
+                                               heading 'top))))
 
            ;; Ask the User for a location, using the appropriate interface
            (cond
+            ((and fastp (memq heading '(top bottom)))
+             (setq spos org-goto-start-pos
+                         exitcmd (if (eq heading 'top) 'left nil)))
             (fastp (setq spos org-goto-start-pos
                          exitcmd 'return))
             ((eq org-remember-interactive-interface 'outline)
@@ -706,6 +1006,7 @@ See also the variable `org-reverse-note-order'."
             (t (error "This should not happen")))
            (if (not spos) (throw 'quit nil)) ; return nil to show we did
                                        ; not handle this note
+           (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately))
            (goto-char spos)
            (cond ((org-on-heading-p t)
                   (org-back-to-heading t)
@@ -724,27 +1025,43 @@ See also the variable `org-reverse-note-order'."
                               (beginning-of-line 2)
                             (end-of-line 1)
                             (insert "\n"))))
+                    (org-paste-subtree (if clocksp
+                                           level
+                                         (org-get-valid-level level 1)) txt)
+                    (and org-auto-align-tags (org-set-tags nil t))
                     (bookmark-set "org-remember-last-stored")
-                    (org-paste-subtree (org-get-valid-level level 1) txt))
+                    (move-marker org-remember-last-stored-marker (point)))
                    ((eq exitcmd 'left)
                     ;; before current
+                    (org-paste-subtree level txt)
+                    (and org-auto-align-tags (org-set-tags nil t))
                     (bookmark-set "org-remember-last-stored")
-                    (org-paste-subtree level txt))
+                    (move-marker org-remember-last-stored-marker (point)))
                    ((eq exitcmd 'right)
                     ;; after current
                     (org-end-of-subtree t)
+                    (org-paste-subtree level txt)
+                    (and org-auto-align-tags (org-set-tags nil t))
                     (bookmark-set "org-remember-last-stored")
-                    (org-paste-subtree level txt))
+                    (move-marker org-remember-last-stored-marker (point)))
                    (t (error "This should not happen"))))
 
+                 ((eq heading 'bottom)
+                  (org-paste-subtree 1 txt)
+                  (and org-auto-align-tags (org-set-tags nil t))
+                  (bookmark-set "org-remember-last-stored")
+                  (move-marker org-remember-last-stored-marker (point)))
+
                  ((and (bobp) (not reversed))
                   ;; Put it at the end, one level below level 1
                   (save-restriction
                     (widen)
                     (goto-char (point-max))
                     (if (not (bolp)) (newline))
+                    (org-paste-subtree (org-get-valid-level 1 1) txt)
+                    (and org-auto-align-tags (org-set-tags nil t))
                     (bookmark-set "org-remember-last-stored")
-                    (org-paste-subtree (org-get-valid-level 1 1) txt)))
+                    (move-marker org-remember-last-stored-marker (point))))
 
                  ((and (bobp) reversed)
                   ;; Put it at the start, as level 1
@@ -753,28 +1070,82 @@ See also the variable `org-reverse-note-order'."
                     (goto-char (point-min))
                     (re-search-forward "^\\*+ " nil t)
                     (beginning-of-line 1)
+                    (org-paste-subtree 1 txt)
+                    (and org-auto-align-tags (org-set-tags nil t))
                     (bookmark-set "org-remember-last-stored")
-                    (org-paste-subtree 1 txt)))
+                    (move-marker org-remember-last-stored-marker (point))))
                  (t
                   ;; Put it right there, with automatic level determined by
                   ;; org-paste-subtree or from prefix arg
-                  (bookmark-set "org-remember-last-stored")
                   (org-paste-subtree
                    (if (numberp current-prefix-arg) current-prefix-arg)
-                   txt)))
+                   txt)
+                  (and org-auto-align-tags (org-set-tags nil t))
+                  (bookmark-set "org-remember-last-stored")
+                  (move-marker org-remember-last-stored-marker (point))))
+
            (when remember-save-after-remembering
              (save-buffer)
-             (if (not visiting) (kill-buffer (current-buffer)))))))))
+             (if (and (not visiting)
+                      (not (equal (marker-buffer org-clock-marker)
+                                  (current-buffer))))
+                 (kill-buffer (current-buffer))))
+           (when org-remember-auto-remove-backup-files
+             (when backup-file
+               (ignore-errors
+                 (delete-file backup-file)
+                 (delete-file (concat backup-file "~"))))
+             (when org-remember-backup-directory
+               (let ((n (length
+                         (directory-files
+                          org-remember-backup-directory nil
+                          "^remember-.*[0-9]$"))))
+                 (when (and org-remember-warn-about-backups
+                             (> n 0))
+                   (message
+                    "%d backup files (unfinished remember calls) in %s"
+                    n org-remember-backup-directory))))))))))
 
   t)    ;; return t to indicate that we took care of this note.
 
-
 (defun org-do-remember (&optional initial)
   "Call remember."
   (remember initial))
 
+(defun org-require-remember ()
+  "Make sure remember is loaded, or install our own emergency version of it."
+  (condition-case nil
+      (require 'remember)
+    (error
+     ;; Lets install our own micro version of remember
+     (defvar remember-register ?R)
+     (defvar remember-mode-hook nil)
+     (defvar remember-handler-functions nil)
+     (defvar remember-buffer "*Remember*")
+     (defvar remember-save-after-remembering t)
+     (defvar remember-annotation-functions '(buffer-file-name))
+     (defun remember-finalize ()
+       (run-hook-with-args-until-success 'remember-handler-functions)
+       (when (equal remember-buffer (buffer-name))
+        (kill-buffer (current-buffer))
+        (jump-to-register remember-register)))
+     (defun remember-mode ()
+       (fundamental-mode)
+       (setq mode-name "Remember")
+       (run-hooks 'remember-mode-hook))
+     (defun remember (&optional initial)
+       (window-configuration-to-register remember-register)
+       (let* ((annotation (run-hook-with-args-until-success
+                          'remember-annotation-functions)))
+        (switch-to-buffer-other-window (get-buffer-create remember-buffer))
+        (remember-mode)))
+     (defun remember-buffer-desc ()
+       (buffer-substring (point-min) (save-excursion (goto-char (point-min))
+                                                    (point-at-eol)))))))
+
 (provide 'org-remember)
 
+;; arch-tag: 497f30d0-4bc3-4097-8622-2d27ac5f2698
+
 ;;; org-remember.el ends here
 
-;; arch-tag: 497f30d0-4bc3-4097-8622-2d27ac5f2698