org-remember.el 44.5 KB
Newer Older
1 2
;;; org-remember.el --- Fast note taking in Org-mode

3
;; Copyright (C) 2004-2011  Free Software Foundation, Inc.
4 5 6 7

;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
8
;; Version: 7.7
9 10 11
;;
;; This file is part of GNU Emacs.
;;
12
;; GNU Emacs is free software: you can redistribute it and/or modify
13
;; it under the terms of the GNU General Public License as published by
14 15
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
16 17 18 19 20 21 22

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
23
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
24 25 26 27 28
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:

;; This file contains the system to take fast notes with Org-mode.
29
;; This system is used together with John Wiegley's `remember.el'.
30 31 32 33 34 35

;;; Code:

(eval-when-compile
  (require 'cl))
(require 'org)
36
(require 'org-compat)
37
(require 'org-datetree)
38

39
(declare-function remember-mode "remember" ())
40 41 42
(declare-function remember "remember" (&optional initial))
(declare-function remember-buffer-desc "remember" ())
(declare-function remember-finalize "remember" ())
43

44 45 46 47 48
(defvar remember-save-after-remembering)
(defvar remember-register)
(defvar remember-buffer)
(defvar remember-handler-functions)
(defvar remember-annotation-functions)
49 50
(defvar org-clock-heading)
(defvar org-clock-heading-for-remember)
51 52 53 54 55 56 57

(defgroup org-remember nil
  "Options concerning interaction with remember.el."
  :tag "Org Remember"
  :group 'org)

(defcustom org-remember-store-without-prompt t
58 59
  "Non-nil means \\<org-remember-mode-map>\\[org-remember-finalize] \
stores the remember note without further prompts.
60
It then uses the file and headline specified by the template or (if the
61
template does not specify them) by the variables `org-default-notes-file'
62
and `org-remember-default-headline'.  To force prompting anyway, use
63
\\[universal-argument] \\[org-remember-finalize] to file the note.
64

65 66
When this variable is nil, \\[org-remember-finalize] gives you the prompts, and
\\[universal-argument] \\[org-remember-finalize] triggers the fasttrack."
67 68 69 70 71 72 73
  :group 'org-remember
  :type 'boolean)

(defcustom org-remember-interactive-interface 'refile
  "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').
74
Allowed values are:
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
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.
outline-path-completion  Headlines in the current buffer are offered via
                         completion.
refile                   Use the refile interface, and offer headlines,
                         possibly from different buffers."
  :group 'org-remember
  :type '(choice
	  (const :tag "Refile" refile)
	  (const :tag "Outline" outline)
	  (const :tag "Outline-path-completion" outline-path-completion)))

(defcustom org-remember-default-headline ""
  "The headline that should be the default location in the notes file.
When filing remember notes, the cursor will start at that position.
You can set this on a per-template basis with the variable
`org-remember-templates'."
  :group 'org-remember
  :type 'string)

(defcustom org-remember-templates nil
  "Templates for the creation of remember buffers.
When nil, just let remember make the buffer.
99 100 101 102
When non-nil, this is a list of (up to) 6-element lists.  In each entry,
the first element is the name of the template, which should be a single
short word.  The second element is a character, a unique key to select
this template.  The third element is the template.
103 104 105 106 107 108 109 110

The fourth element is optional and can specify a destination file for
remember items created with this template.  The default file is given
by `org-default-notes-file'.  If the file name is not an absolute path,
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
111 112 113
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.
114

115 116 117 118
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.
119
Templates that specify t or nil for the context will always be added
120
to the list of selectable templates.
121 122 123 124 125

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.
Furthermore, the following %-escapes will be replaced with content:

126 127
  %^{PROMPT}  prompt the user for a string and replace this sequence with it.
              A default value and a completion table can be specified like this:
128
              %^{prompt|default|completion2|completion3|...}
129 130 131 132 133
              The arrow keys access a prompt-specific history.
  %a          annotation, normally the link created with `org-store-link'
  %A          like %a, but prompt for the description part
  %i          initial content, copied from the active region.  If %i is
              indented, the entire inserted text will be indented as well.
134 135 136
  %t          time stamp, date only
  %T          time stamp with date and time
  %u, %U      like the above, but inactive time stamps
137
  %^t         like %t, but prompt for date.  Similarly %^T, %^u, %^U.
138
              You may define a prompt like %^{Please specify birthday}t
139
  %n          user name (taken from `user-full-name')
140 141
  %c          current kill ring head
  %x          content of the X clipboard
142
  %:keyword   specific information for certain link types, see below
143 144 145 146 147 148 149 150 151 152 153 154 155 156
  %^C         interactive selection of which kill or clip to use
  %^L         like %^C, but insert as link
  %k          title of the currently clocked task
  %K          link to the currently clocked task
  %^g         prompt for tags, completing tags in the target file
  %^G         prompt for tags, completing all tags in all agenda files
  %^{PROP}p   Prompt the user for a value for property PROP
  %[PATHNAME] insert the contents of the file given by PATHNAME
  %(SEXP)     evaluate elisp `(SEXP)' and replace with the result
  %!          store this note immediately after completing the template\
              \\<org-remember-mode-map>
              (skipping the \\[org-remember-finalize] that normally triggers storing)
  %&          jump to target location immediately after storing note
  %?          after completing the template, position cursor here.
157 158 159 160

Apart from these general escapes, you can access information specific to the
link type that is created.  For example, calling `remember' in emails or gnus
will record the author and the subject of the message, which you can access
Carsten Dominik's avatar
Carsten Dominik committed
161
with %:fromname and %:subject, respectively.  Here is a complete list of what
162 163 164 165 166 167 168 169 170
is recorded for each link type.

Link type          |  Available information
-------------------+------------------------------------------------------
bbdb               |  %:type %:name %:company
vm, wl, mh, rmail  |  %:type %:subject %:message-id
                   |  %:from %:fromname %:fromaddress
                   |  %:to   %:toname   %:toaddress
                   |  %:fromto (either \"to NAME\" or \"from NAME\")
Carsten Dominik's avatar
Carsten Dominik committed
171 172
gnus               |  %:group, for messages also all email fields and
                   |  %:org-date (the Date: header in Org format)
173 174 175 176 177 178 179
w3, w3m            |  %:type %:url
info               |  %:type %:file %:node
calendar           |  %:type %:date"
  :group 'org-remember
  :get (lambda (var) ; Make sure all entries have at least 5 elements
	 (mapcar (lambda (x)
		   (if (not (stringp (car x))) (setq x (cons "" x)))
180 181
		   (cond ((= (length x) 4) (append x '(nil)))
			 ((= (length x) 3) (append x '(nil nil)))
182 183 184 185 186 187 188 189
			 (t x)))
		 (default-value var)))
  :type '(repeat
	  :tag "enabled"
	  (list :value ("" ?a "\n" nil nil nil)
		(string :tag "Name")
		(character :tag "Selection Key")
		(string :tag "Template")
190 191
		(choice :tag "Destination file"
		 (file :tag "Specify")
192
		 (function :tag "Function")
193 194 195
		 (const :tag "Use `org-default-notes-file'" nil))
		(choice :tag "Destin. headline"
		 (string :tag "Specify")
196
		 (function :tag "Function")
197
		 (const :tag "Use `org-remember-default-headline'" nil)
198
		 (const :tag "At beginning of file" top)
199 200
		 (const :tag "At end of file" bottom)
		 (const :tag "In a date tree" date-tree))
201 202
		(choice :tag "Context"
		 (const :tag "Use in all contexts" nil)
203 204 205 206 207
		 (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")))))

208 209 210 211 212
(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)

213 214 215 216 217 218
(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)

219
(defvar org-remember-mode-map (make-sparse-keymap)
220
  "Keymap for `org-remember-mode', a minor mode.
221 222 223 224 225 226 227
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."
228 229 230 231
  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)
232

233
(defcustom org-remember-clock-out-on-exit 'query
234
  "Non-nil means stop the clock when exiting a clocking remember buffer.
235 236 237
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
238
user each time a remember buffer with a running clock is filed away."
239 240 241 242 243 244
  :group 'org-remember
  :type '(choice
	  (const :tag "Never" nil)
	  (const :tag "Always" t)
	  (const :tag "Query user" query)))

245 246 247 248 249 250 251 252 253 254 255 256
(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
257
  "Non-nil means remove remember backup files after successfully storage.
258 259 260 261 262 263 264 265
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)
266

267 268 269 270 271 272 273
(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
274
error or Emacs crashed, for example) nil is more useful.  In the
275 276 277 278
opposite case, the default, t, is more useful."
  :group 'org-remember
  :type 'boolean)

279 280 281 282 283
(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 ()
284 285
  "Setup remember.el for use with Org-mode."
  (org-require-remember)
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
  (setq remember-annotation-functions '(org-remember-annotation))
  (setq remember-handler-functions '(org-remember-handler))
  (add-hook 'remember-mode-hook 'org-remember-apply-template))

;;;###autoload
(defun org-remember-annotation ()
  "Return a link to the current location as an annotation for remember.el.
If you are using Org-mode files as target for data storage with
remember.el, then the annotations should include a link compatible with the
conventions in Org-mode.  This function returns such a link."
  (org-store-link nil))

(defconst org-remember-help
"Select a destination location for the note.
UP/DOWN=headline   TAB=cycle visibility  [Q]uit   RET/<left>/<right>=Store
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")

305
(defvar org-jump-to-target-location nil)
306
(defvar org-remember-previous-location nil)
307
(defvar org-remember-reference-date nil)
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
(defvar org-force-remember-template-char) ;; dynamically scoped

;; Save the major mode of the buffer we called remember from
(defvar org-select-template-temp-major-mode nil)

;; Temporary store the buffer where remember was called from
(defvar org-select-template-original-buffer nil)

(defun org-select-remember-template (&optional use-char)
  (when org-remember-templates
    (let* ((pre-selected-templates
	    (mapcar
	     (lambda (tpl)
	       (let ((ctxt (nth 5 tpl))
		     (mode org-select-template-temp-major-mode)
		     (buf org-select-template-original-buffer))
		 (and (or (not ctxt) (eq ctxt t)
			  (and (listp ctxt) (memq mode ctxt))
			  (and (functionp ctxt)
			       (with-current-buffer buf
				 ;; Protect the user-defined function from error
				 (condition-case nil (funcall ctxt) (error nil)))))
		      tpl)))
	     org-remember-templates))
	   ;; If no template at this point, add the default templates:
	   (pre-selected-templates1
	    (if (not (delq nil pre-selected-templates))
		(mapcar (lambda(x) (if (not (nth 5 x)) x))
			org-remember-templates)
	      pre-selected-templates))
338
	   ;; Then unconditionally add template for any contexts
339 340 341 342 343 344 345 346 347
	   (pre-selected-templates2
	    (append (mapcar (lambda(x) (if (eq (nth 5 x) t) x))
			    org-remember-templates)
		    (delq nil pre-selected-templates1)))
	   (templates (mapcar (lambda (x)
				(if (stringp (car x))
				    (append (list (nth 1 x) (car x)) (cddr x))
				  (append (list (car x) "") (cdr x))))
			      (delq nil pre-selected-templates2)))
348
	   msg
349 350 351 352 353 354 355 356 357 358
	   (char (or use-char
		     (cond
		      ((= (length templates) 1)
		       (caar templates))
		      ((and (boundp 'org-force-remember-template-char)
			    org-force-remember-template-char)
		       (if (stringp org-force-remember-template-char)
			   (string-to-char org-force-remember-template-char)
			 org-force-remember-template-char))
		      (t
359
		       (setq msg (format
360
				  "Select template: %s%s"
361 362 363 364 365 366 367 368 369 370
				  (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)))))
371 372 373 374
				   templates " ")
				  (if (assoc ?C templates)
				      ""
				    " [C]customize templates")))
375 376 377 378 379
		       (let ((inhibit-quit t) char0)
			 (while (not char0)
			   (message msg)
			   (setq char0 (read-char-exclusive))
			   (when (and (not (assoc char0 templates))
380 381
				      (not (equal char0 ?\C-g))
				      (not (equal char0 ?C)))
382 383 384
			     (message "No such template \"%c\"" char0)
			     (ding) (sit-for 1)
			     (setq char0 nil)))
385 386
			 (when (equal char0 ?\C-g)
			   (jump-to-register remember-register)
387 388
			   (kill-buffer remember-buffer)
			   (error "Abort"))
389 390 391 392 393
			 (when (not (assoc char0 templates))
			   (jump-to-register remember-register)
			   (kill-buffer remember-buffer)
			   (customize-variable 'org-remember-templates)
			   (error "Customize templates"))
394 395 396 397 398 399 400 401
			 char0))))))
      (cddr (assoc char templates)))))

;;;###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."
402 403 404
  (when (and (boundp 'initial) (stringp initial))
    (setq initial (org-no-properties initial))
    (remove-text-properties 0 (length initial) '(read-only t) initial))
405 406
  (if org-remember-templates
      (let* ((entry (org-select-remember-template use-char))
407
	     (ct (or org-overriding-default-time (org-current-time)))
408 409 410 411 412
	     (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))
413 414
	     (tpl (car entry))
	     (plist-p (if org-store-link-plist t nil))
415
	     (file (if (and (nth 1 entry)
416 417 418
			    (or (and (stringp (nth 1 entry))
				     (string-match "\\S-" (nth 1 entry)))
				(functionp (nth 1 entry))))
419 420 421 422 423 424 425
		       (nth 1 entry)
		     org-default-notes-file))
	     (headline (nth 2 entry))
	     (v-c (and (> (length kill-ring) 0) (current-kill 0)))
	     (v-x (or (org-get-x-clipboard 'PRIMARY)
		      (org-get-x-clipboard 'CLIPBOARD)
		      (org-get-x-clipboard 'SECONDARY)))
426 427
	     (v-t (format-time-string (car org-time-stamp-formats) ct))
	     (v-T (format-time-string (cdr org-time-stamp-formats) ct))
428 429
	     (v-u (concat "[" (substring v-t 1 -1) "]"))
	     (v-U (concat "[" (substring v-T 1 -1) "]"))
430 431 432 433 434 435 436 437 438 439
	     ;; `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))
440 441 442 443 444 445 446 447 448 449
	     (clipboards (remove nil (list v-i
					   (org-get-x-clipboard 'PRIMARY)
					   (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)
		    v-a))
	     (v-n user-full-name)
450
	     (v-k (if (marker-buffer org-clock-marker)
451
		      (org-substring-no-properties org-clock-heading)))
452 453 454 455 456
	     (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
457
	     (org-startup-folded nil)
458
	     (org-inhibit-startup t)
459 460
	     org-time-was-given org-end-time-was-given x
	     prompt completions char time pos default histvar)
461 462 463

	(when (functionp file)
	  (setq file (funcall file)))
464 465
	(when (functionp headline)
	  (setq headline (funcall headline)))
466 467
	(when (and file (not (file-name-absolute-p file)))
	  (setq file (expand-file-name file org-directory)))
468

469
	(setq org-store-link-plist
470 471 472 473
	      (plist-put org-store-link-plist :annotation v-a)
	      org-store-link-plist
	      (plist-put org-store-link-plist :initial v-i))

474 475 476 477
	(unless tpl (setq tpl "") (message "No template") (ding) (sit-for 1))
	(erase-buffer)
	(insert (substitute-command-keys
		 (format
478 479 480
"## %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\"
481
## %s  to select file and header location interactively.
482
## C-2 C-c C-c  as child (C-3: as sibling) of the currently clocked item
483
## To switch templates, use `\\[org-remember]'.  To abort use `C-c C-k'.\n\n"
484
		  (if org-remember-store-without-prompt "    C-c C-c" "    C-1 C-c C-c")
485 486 487
		  (abbreviate-file-name (or file org-default-notes-file))
		  (or headline "")
		  (or (car org-remember-previous-location) "???")
488 489 490 491
		  (or (cdr org-remember-previous-location) "???")
		  (if org-remember-store-without-prompt "C-1 C-c C-c" "        C-c C-c"))))
	(insert tpl)

492 493 494 495 496 497 498 499 500 501 502 503 504
	;; %[] Insert contents of a file.
	(goto-char (point-min))
	(while (re-search-forward "%\\[\\(.+\\)\\]" nil t)
	  (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)))))))
505
	;; Simple %-escapes
506
	(goto-char (point-min))
507
	(while (re-search-forward "%\\([tTuUaiAcxkKI]\\)" nil t)
508 509 510 511 512 513 514 515 516 517 518
	  (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)))
519 520 521 522

	;; %() embedded elisp
	(goto-char (point-min))
	(while (re-search-forward "%\\((.+)\\)" nil t)
523 524 525 526 527 528 529 530 531 532
	  (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)))))
533 534 535 536 537

	;; From the property list
	(when plist-p
	  (goto-char (point-min))
	  (while (re-search-forward "%\\(:[-a-zA-Z]+\\)" nil t)
538
	  (unless (org-remember-escaped-%)
539 540
	    (and (setq x (or (plist-get org-store-link-plist
					(intern (match-string 1))) ""))
541
		 (replace-match x t t)))))
542 543

	;; Turn on org-mode in the remember buffer, set local variables
544
	(let ((org-inhibit-startup t)) (org-mode) (org-remember-mode 1))
545 546
	(if (and file (string-match "\\S-" file) (not (file-directory-p file)))
	    (org-set-local 'org-default-notes-file file))
547
	(if headline
548
	    (org-set-local 'org-remember-default-headline headline))
549 550
	(org-set-local 'org-remember-reference-date
		       (list (nth 4 dct) (nth 3 dct) (nth 5 dct)))
551 552
	;; Interactive template entries
	(goto-char (point-min))
553
	(while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([gGtTuUCLp]\\)?" nil t)
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
	  (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
Carsten Dominik's avatar
Carsten Dominik committed
579
				     (org-split-string ins (org-re "[^[:alnum:]_@#%]+"))
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
				     ":"))
		(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
605 606
			(or (find-buffer-visiting file)
			    (find-file-noselect file))
607 608 609 610
		      (or (cdr (assoc pall org-file-properties))
			  (cdr (assoc pall org-global-properties))
			  (cdr (assoc pall org-global-properties-fixed)))))
		   (existing (with-current-buffer
611 612
				 (or (find-buffer-visiting file)
				     (find-file-noselect file))
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
			       (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)
633 634 635 636 637 638
		(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))))))))
639

640 641 642 643
	(goto-char (point-min))
	(if (re-search-forward "%\\?" nil t)
	    (replace-match "")
	  (and (re-search-forward "^[^#\n]" nil t) (backward-char 1))))
644
    (let ((org-inhibit-startup t)) (org-mode) (org-remember-mode 1)))
645 646 647 648 649
  (when (save-excursion
	  (goto-char (point-min))
	  (re-search-forward "%&" nil t))
    (replace-match "")
    (org-set-local 'org-jump-to-target-location t))
650 651 652 653 654 655 656 657 658 659 660
  (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))
661 662 663 664 665 666
  (when (save-excursion
	  (goto-char (point-min))
	  (re-search-forward "%!" nil t))
    (replace-match "")
    (add-hook 'post-command-hook 'org-remember-finish-immediately 'append)))

667 668 669 670 671 672 673 674
(defun org-remember-escaped-% ()
  (if (equal (char-before (match-beginning 0)) ?\\)
      (progn
	(delete-region (1- (match-beginning 0)) (match-beginning 0))
	t)
    nil))


675 676 677 678 679
(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)
680
  (org-remember-finalize))
681

682 683 684 685 686 687 688 689 690 691 692
(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
693
	    (substitute-command-keys
694 695 696 697
	     "Restore window configuration with \\[jump-to-register] %c")
	    remember-register)))

(defvar org-clock-marker) ; Defined in org.el
698 699
(defun org-remember-finalize ()
  "Finalize the remember process."
700 701 702 703
  (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)
704 705 706 707
  (unless (fboundp 'remember-finalize)
    (defalias 'remember-finalize 'remember-buffer))
  (when (and org-clock-marker
	     (equal (marker-buffer org-clock-marker) (current-buffer)))
708 709 710 711 712 713
    ;; 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))))
714
  (when buffer-file-name
715
    (do-auto-save))
716 717
  (remember-finalize))

718 719 720 721 722 723
(defun org-remember-kill ()
  "Abort the current remember process."
  (interactive)
  (let ((org-note-abort t))
    (org-remember-finalize)))

724 725 726 727 728 729
;;;###autoload
(defun org-remember (&optional goto org-force-remember-template-char)
  "Call `remember'.  If this is already a remember buffer, re-apply template.
If there is an active region, make sure remember uses it as initial content
of the remember buffer.

730 731
When called interactively with a \\[universal-argument] \
prefix argument GOTO, don't remember
732
anything, just go to the file/headline where the selected template usually
733 734
stores its notes.  With a double prefix argument \
\\[universal-argument] \\[universal-argument], go to the last
735 736 737 738 739
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")
740
  (org-require-remember)
741 742 743 744 745 746 747 748
  (cond
   ((equal goto '(4)) (org-go-to-remember-target))
   ((equal goto '(16)) (org-remember-goto-last-stored))
   (t
    ;; set temporary variables that will be needed in
    ;; `org-select-remember-template'
    (setq org-select-template-temp-major-mode major-mode)
    (setq org-select-template-original-buffer (current-buffer))
749
    (if org-remember-mode
750 751 752 753 754 755 756 757 758 759 760 761
	(progn
	  (when (< (length org-remember-templates) 2)
	    (error "No other template available"))
	  (erase-buffer)
	  (let ((annotation (plist-get org-store-link-plist :annotation))
		(initial (plist-get org-store-link-plist :initial)))
	    (org-remember-apply-template))
	  (message "Press C-c C-c to remember data"))
      (if (org-region-active-p)
	  (org-do-remember (buffer-substring (point) (mark)))
	(org-do-remember))))))

762 763 764
(defvar org-remember-last-stored-marker (make-marker)
  "Marker pointing to the entry most recently stored with `org-remember'.")

765 766 767
(defun org-remember-goto-last-stored ()
  "Go to the location where the last remember note was stored."
  (interactive)
768 769
  (org-goto-marker-or-bmk org-remember-last-stored-marker
			  "org-remember-last-stored")
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
  (message "This is the last note stored by remember"))

(defun org-go-to-remember-target (&optional template-key)
  "Go to the target location of a remember template.
The user is queried for the template."
  (interactive)
  (let* (org-select-template-temp-major-mode
	 (entry (org-select-remember-template template-key))
	 (file (nth 1 entry))
	 (heading (nth 2 entry))
	 visiting)
    (unless (and file (stringp file) (string-match "\\S-" file))
      (setq file org-default-notes-file))
    (when (and file (not (file-name-absolute-p file)))
      (setq file (expand-file-name file org-directory)))
    (unless (and heading (stringp heading) (string-match "\\S-" heading))
      (setq heading org-remember-default-headline))
    (setq visiting (org-find-base-buffer-visiting file))
    (if (not visiting) (find-file-noselect file))
789
    (switch-to-buffer (or visiting (get-file-buffer file)))
790 791 792
    (widen)
    (goto-char (point-min))
    (if (re-search-forward
793
	 (format org-complex-heading-regexp-format (regexp-quote heading))
794 795 796 797
	 nil t)
	(goto-char (match-beginning 0))
      (error "Target headline not found: %s" heading))))

798 799
;; FIXME (bzg): let's clean up of final empty lines happen only once
;; (see the org-remember-delete-empty-lines-at-end option below)
800 801 802
;;;###autoload
(defun org-remember-handler ()
  "Store stuff from remember.el into an org file.
803 804 805
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'.
806
\\<org-remember-mode-map>
807
If no defaults have been defined, or if the current prefix argument
808
is 1 (using C-1 \\[org-remember-finalize] to exit remember), an interactive
809 810
process is used to select the target location.

811 812
When the prefix is 0 (i.e. when remember is exited with \
C-0 \\[org-remember-finalize]),
813 814
the entry is filed to the same location as the previous note.

815 816
When the prefix is 2 (i.e. when remember is exited with \
C-2 \\[org-remember-finalize]),
817
the entry is filed as a subentry of the entry where the clock is
818 819
currently running.

820 821 822 823
When \\[universal-argument] 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).
824 825 826 827 828

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.
829 830 831 832 833 834

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'."
835 836
  (when (and (equal current-prefix-arg 2)
	     (not (marker-buffer org-clock-marker)))
837
    (error "No running clock"))
838 839 840 841 842
  (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)))
843 844 845
  (goto-char (point-min))
  (while (looking-at "^[ \t]*\n\\|^##.*\n")
    (replace-match ""))
846 847 848 849 850 851
  (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)))
852
  (catch 'quit
853
    (if org-note-abort (throw 'quit t))
854
    (let* ((visitp (org-bound-and-true-p org-jump-to-target-location))
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
	   (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)))
873
	   (reference-date org-remember-reference-date)
874 875 876
	   (previousp (and (member current-prefix-arg '((16) 0))
			   org-remember-previous-location))
	   (clockp (equal current-prefix-arg 2))
877
	   (clocksp (equal current-prefix-arg 3))
878
	   (fastp (org-xor (equal current-prefix-arg 1)
879 880 881 882 883 884
			   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)
885
		  ((not previousp)
886 887 888 889 890 891
		   (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)
892
	   spos exitcmd level reversed txt text-before-node-creation)
893 894 895 896
      (when (equal current-prefix-arg '(4))
	(setq visitp t))
      (when previousp
	(setq file (car org-remember-previous-location)
897
	      visiting (and file (org-find-base-buffer-visiting file))
898 899
	      heading (cdr org-remember-previous-location)
	      fastp t))
900
      (when (or clockp clocksp)
901
	(setq file (buffer-file-name (marker-buffer org-clock-marker))
902
	      visiting (and file (org-find-base-buffer-visiting file))
903 904
	      heading org-clock-heading-for-remember
	      fastp t))
905 906 907
      (setq current-prefix-arg nil)
      ;; Modify text so that it becomes a nice subtree which can be inserted
      ;; into an org tree.
908 909 910 911 912
      (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 "")))
913
      (goto-char (point-min))
914
      (setq text-before-node-creation (buffer-string))
915 916 917 918 919 920 921 922
      (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 "  "))))
923 924 925 926 927 928 929
      ;; 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"))))
930 931 932
      (goto-char (point-min))
      (setq txt (buffer-string))
      (org-save-markers-in-region (point-min) (point-max))
933
      (set-buffer-modified-p nil)
934 935 936
      (when (and (eq org-remember-interactive-interface 'refile)
		 (not fastp))
	(org-refile nil (or visiting (find-file-noselect file)))
937
	(and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately))
938 939 940 941
	(save-excursion
	  (bookmark-jump "org-refile-last-stored")
	  (bookmark-set "org-remember-last-stored")
	  (move-marker org-remember-last-stored-marker (point)))
942 943
	(throw 'quit t))
      ;; Find the file
944
      (with-current-buffer (or visiting (find-file-noselect file))
945 946
	(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"))
947 948 949 950 951 952
	(save-excursion
	  (save-restriction
	    (widen)
	    (setq reversed (org-notes-order-reversed-p))

	    ;; Find the default location
953 954
	    (when heading
	      (cond
955 956 957 958 959 960 961 962 963 964
	       ((not (org-mode-p))
		(if (eq heading 'top)
		    (goto-char (point-min))
		  (goto-char (point-max))
		  (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))
965 966 967 968 969 970 971 972 973
	       ((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)))
974 975 976 977
	       ((eq heading 'date-tree)
		(org-datetree-find-date-create reference-date)
		(setq reversed nil)
		(setq org-goto-start-pos (point)))
978 979 980
	       ((and (stringp heading) (string-match "\\S-" heading))
		(goto-char (point-min))
		(if (re-search-forward
981 982
		     (format org-complex-heading-regexp-format
			     (regexp-quote heading))
983 984 985 986 987 988 989 990 991
		     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))))
992 993 994

	    ;; Ask the User for a location, using the appropriate interface
	    (cond
995 996
	     ((and fastp (memq heading '(top bottom)))
	      (setq spos org-goto-start-pos
997
			  exitcmd (if (eq heading 'top) 'left nil)))
998 999 1000 1001 1002 1003 1004 1005 1006 1007
	     (fastp (setq spos org-goto-start-pos
			  exitcmd 'return))
	     ((eq org-remember-interactive-interface 'outline)
	      (setq spos (org-get-location (current-buffer)
					   org-remember-help)
		    exitcmd (cdr spos)
		    spos (car spos)))
	     ((eq org-remember-interactive-interface 'outline-path-completion)
	      (let ((org-refile-targets '((nil . (:maxlevel . 10))))
		    (org-refile-use-outline-path t))
1008
		(setq spos (org-refile-get-location "Heading")
1009 1010 1011 1012 1013
		      exitcmd 'return
		      spos (nth 3 spos))))
	     (t (error "This should not happen")))
	    (if (not spos) (throw 'quit nil)) ; return nil to show we did
					; not handle this note
1014
	    (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately))
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
	    (goto-char spos)
	    (cond ((org-on-heading-p t)
		   (org-back-to-heading t)
		   (setq level (funcall outline-level))
		   (cond
		    ((eq exitcmd 'return)
		     ;; sublevel of current
		     (setq org-remember-previous-location
			   (cons (abbreviate-file-name file)
				 (org-get-heading 'notags)))
		     (if reversed
			 (outline-next-heading)
		       (org-end-of-subtree t)
		       (if (not (bolp))
			   (if (looking-at "[ \t]*\n")
			       (beginning-of-line 2)
			     (end-of-line 1)
			     (insert "\n"))))
1033 1034 1035
		     (org-paste-subtree (if clocksp
					    level
					  (org-get-valid-level level 1)) txt)
1036
		     (and org-auto-align-tags (org-set-tags nil t))
1037
		     (bookmark-set "org-remember-last-stored")
1038
		     (move-marker org-remember-last-stored-marker (point)))
1039 1040
		    ((eq exitcmd 'left)
		     ;; before current
1041 1042
		     (org-paste-subtree level txt)
		     (and org-auto-align-tags (org-set-tags nil t))
1043
		     (bookmark-set "org-remember-last-stored")
1044
		     (move-marker org-remember-last-stored-marker (point)))
1045 1046 1047
		    ((eq exitcmd 'right)
		     ;; after current
		     (org-end-of-subtree t)
1048 1049
		     (org-paste-subtree level txt)
		     (and org-auto-align-tags (org-set-tags nil t))
1050
		     (bookmark-set "org-remember-last-stored")
1051
		     (move-marker org-remember-last-stored-marker (point)))
1052 1053
		    (t (error "This should not happen"))))

1054 1055 1056 1057 1058 1059
		  ((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)))

1060 1061 1062 1063 1064 1065
		  ((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))
1066 1067
		     (org-paste-subtree (org-get-valid-level 1 1) txt)
		     (and org-auto-align-tags (org-set-tags nil t))
1068
		     (bookmark-set "org-remember-last-stored")
1069
		     (move-marker org-remember-last-stored-marker (point))))
1070 1071 1072 1073 1074 1075

		  ((and (bobp) reversed)
		   ;; Put it at the start, as level 1
		   (save-restriction
		     (widen)
		     (goto-char (point-min))
1076
		     (re-search-forward org-outline-regexp-bol nil t)
1077
		     (beginning-of-line 1)
1078 1079
		     (org-paste-subtree 1 txt)
		     (and org-auto-align-tags (org-set-tags nil t))
1080
		     (bookmark-set "org-remember-last-stored")
1081
		     (move-marker org-remember-last-stored-marker (point))))
1082 1083 1084 1085 1086
		  (t
		   ;; Put it right there, with automatic level determined by
		   ;; org-paste-subtree or from prefix arg
		   (org-paste-subtree
		    (if (numberp current-prefix-arg) current-prefix-arg)
1087 1088 1089 1090 1091
		    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))))

1092 1093
	    (when remember-save-after-remembering
	      (save-buffer)
1094 1095 1096
	      (if (and (not visiting)
		       (not (equal (marker-buffer org-clock-marker)
				   (current-buffer))))
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
		  (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]$"))))
1108 1109
		  (when (and org-remember-warn-about-backups
                             (> n 0))
1110 1111 1112
		    (message
		     "%d backup files (unfinished remember calls) in %s"
		     n org-remember-backup-directory))))))))))
1113 1114 1115 1116 1117 1118 1119

  t)    ;; return t to indicate that we took care of this note.

(defun org-do-remember (&optional initial)
  "Call remember."
  (remember initial))

1120 1121 1122 1123 1124
(defun org-require-remember ()
  "Make sure remember is loaded, or install our own emergency version of it."
  (condition-case nil
      (require 'remember)
    (error
Juanma Barranquero's avatar
Juanma Barranquero committed
1125
     ;; Let's install our own micro version of remember
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
     (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)))))))

1151 1152
(provide 'org-remember)

1153

1154 1155

;;; org-remember.el ends here