Commit | Line | Data |
---|---|---|
20908596 CD |
1 | ;;; org-remember.el --- Fast note taking in Org-mode |
2 | ||
3 | ;; Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | |
4 | ||
5 | ;; Author: Carsten Dominik <carsten at orgmode dot org> | |
6 | ;; Keywords: outlines, hypermedia, calendar, wp | |
7 | ;; Homepage: http://orgmode.org | |
ce4fdcb9 | 8 | ;; Version: 6.13 |
20908596 CD |
9 | ;; |
10 | ;; This file is part of GNU Emacs. | |
11 | ;; | |
b1fc2b50 | 12 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
20908596 | 13 | ;; it under the terms of the GNU General Public License as published by |
b1fc2b50 GM |
14 | ;; the Free Software Foundation, either version 3 of the License, or |
15 | ;; (at your option) any later version. | |
20908596 CD |
16 | |
17 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;; GNU General Public License for more details. | |
21 | ||
22 | ;; You should have received a copy of the GNU General Public License | |
b1fc2b50 | 23 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
20908596 CD |
24 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
25 | ;; | |
26 | ;;; Commentary: | |
27 | ||
28 | ;; This file contains the system to take fast notes with Org-mode. | |
29 | ;; This system is used together with John Wiegleys `remember.el'. | |
30 | ||
31 | ;;; Code: | |
32 | ||
33 | (eval-when-compile | |
34 | (require 'cl)) | |
35 | (require 'org) | |
36 | ||
621f83e4 | 37 | (declare-function remember-mode "remember" ()) |
20908596 CD |
38 | (declare-function remember "remember" (&optional initial)) |
39 | (declare-function remember-buffer-desc "remember" ()) | |
40 | (declare-function remember-finalize "remember" ()) | |
41 | (defvar remember-save-after-remembering) | |
20908596 CD |
42 | (defvar remember-register) |
43 | (defvar remember-buffer) | |
44 | (defvar remember-handler-functions) | |
45 | (defvar remember-annotation-functions) | |
621f83e4 CD |
46 | (defvar org-clock-heading) |
47 | (defvar org-clock-heading-for-remember) | |
20908596 CD |
48 | |
49 | (defgroup org-remember nil | |
50 | "Options concerning interaction with remember.el." | |
51 | :tag "Org Remember" | |
52 | :group 'org) | |
53 | ||
54 | (defcustom org-remember-store-without-prompt t | |
b349f79f CD |
55 | "Non-nil means, `C-c C-c' stores remember note without further prompts. |
56 | It then uses the file and headline specified by the template or (if the | |
ce4fdcb9 | 57 | template does not specify them) by the variables `org-default-notes-file' |
b349f79f CD |
58 | and `org-remember-default-headline'. To force prompting anyway, use |
59 | `C-u C-c C-c' to file the note. | |
60 | ||
eb82b61d JB |
61 | When this variable is nil, `C-c C-c' gives you the prompts, and |
62 | `C-u C-c C-c' triggers the fasttrack." | |
20908596 CD |
63 | :group 'org-remember |
64 | :type 'boolean) | |
65 | ||
66 | (defcustom org-remember-interactive-interface 'refile | |
67 | "The interface to be used for interactive filing of remember notes. | |
68 | This is only used when the interactive mode for selecting a filing | |
69 | location is used (see the variable `org-remember-store-without-prompt'). | |
70 | Allowed vaues are: | |
71 | outline The interface shows an outline of the relevant file | |
72 | and the correct heading is found by moving through | |
73 | the outline or by searching with incremental search. | |
74 | outline-path-completion Headlines in the current buffer are offered via | |
75 | completion. | |
76 | refile Use the refile interface, and offer headlines, | |
77 | possibly from different buffers." | |
78 | :group 'org-remember | |
79 | :type '(choice | |
80 | (const :tag "Refile" refile) | |
81 | (const :tag "Outline" outline) | |
82 | (const :tag "Outline-path-completion" outline-path-completion))) | |
83 | ||
84 | (defcustom org-remember-default-headline "" | |
85 | "The headline that should be the default location in the notes file. | |
86 | When filing remember notes, the cursor will start at that position. | |
87 | You can set this on a per-template basis with the variable | |
88 | `org-remember-templates'." | |
89 | :group 'org-remember | |
90 | :type 'string) | |
91 | ||
92 | (defcustom org-remember-templates nil | |
93 | "Templates for the creation of remember buffers. | |
94 | When nil, just let remember make the buffer. | |
eb82b61d | 95 | When non-nil, this is a list of 5-element lists. In each entry, the first |
20908596 CD |
96 | element is the name of the template, which should be a single short word. |
97 | The second element is a character, a unique key to select this template. | |
98 | The third element is the template. | |
99 | ||
100 | The fourth element is optional and can specify a destination file for | |
101 | remember items created with this template. The default file is given | |
102 | by `org-default-notes-file'. If the file name is not an absolute path, | |
103 | it will be interpreted relative to `org-directory'. | |
104 | ||
105 | An optional fifth element can specify the headline in that file that should | |
106 | be offered first when the user is asked to file the entry. The default | |
b349f79f CD |
107 | headline is given in the variable `org-remember-default-headline'. When |
108 | this element is `top' or `bottom', the note will be placed as a level-1 | |
109 | entry at the beginning or end of the file, respectively. | |
20908596 | 110 | |
b349f79f CD |
111 | An optional sixth element specifies the contexts in which the template |
112 | will be offered to the user. This element can be a list of major modes | |
113 | or a function, and the template will only be offered if `org-remember' | |
114 | is called from a mode in the list, or if the function returns t. | |
115 | Templates that specify t or nil for the context will be always be added | |
116 | to the list of selectable templates. | |
20908596 CD |
117 | |
118 | The template specifies the structure of the remember buffer. It should have | |
119 | a first line starting with a star, to act as the org-mode headline. | |
120 | Furthermore, the following %-escapes will be replaced with content: | |
121 | ||
122 | %^{prompt} Prompt the user for a string and replace this sequence with it. | |
123 | A default value and a completion table ca be specified like this: | |
124 | %^{prompt|default|completion2|completion3|...} | |
125 | %t time stamp, date only | |
126 | %T time stamp with date and time | |
127 | %u, %U like the above, but inactive time stamps | |
b349f79f CD |
128 | %^t like %t, but prompt for date. Similarly %^T, %^u, %^U. |
129 | You may define a prompt like %^{Please specify birthday | |
20908596 CD |
130 | %n user name (taken from `user-full-name') |
131 | %a annotation, normally the link created with org-store-link | |
132 | %i initial content, the region active. If %i is indented, | |
133 | the entire inserted text will be indented as well. | |
b349f79f CD |
134 | %c current kill ring head |
135 | %x content of the X clipboard | |
136 | %^C Interactive selection of which kill or clip to use | |
137 | %^L Like %^C, but insert as link | |
621f83e4 CD |
138 | %k title of currently clocked task |
139 | %K link to currently clocked task | |
20908596 CD |
140 | %^g prompt for tags, with completion on tags in target file |
141 | %^G prompt for tags, with completion all tags in all agenda files | |
621f83e4 | 142 | %^{prop}p Prompt the user for a value for property `prop' |
20908596 CD |
143 | %:keyword specific information for certain link types, see below |
144 | %[pathname] insert the contents of the file given by `pathname' | |
145 | %(sexp) evaluate elisp `(sexp)' and replace with the result | |
146 | %! Store this note immediately after filling the template | |
b349f79f | 147 | %& Visit note immediately after storing it |
20908596 CD |
148 | |
149 | %? After completing the template, position cursor here. | |
150 | ||
151 | Apart from these general escapes, you can access information specific to the | |
152 | link type that is created. For example, calling `remember' in emails or gnus | |
153 | will record the author and the subject of the message, which you can access | |
154 | with %:author and %:subject, respectively. Here is a complete list of what | |
155 | is recorded for each link type. | |
156 | ||
157 | Link type | Available information | |
158 | -------------------+------------------------------------------------------ | |
159 | bbdb | %:type %:name %:company | |
160 | vm, wl, mh, rmail | %:type %:subject %:message-id | |
161 | | %:from %:fromname %:fromaddress | |
162 | | %:to %:toname %:toaddress | |
163 | | %:fromto (either \"to NAME\" or \"from NAME\") | |
164 | gnus | %:group, for messages also all email fields | |
165 | w3, w3m | %:type %:url | |
166 | info | %:type %:file %:node | |
167 | calendar | %:type %:date" | |
168 | :group 'org-remember | |
169 | :get (lambda (var) ; Make sure all entries have at least 5 elements | |
170 | (mapcar (lambda (x) | |
171 | (if (not (stringp (car x))) (setq x (cons "" x))) | |
621f83e4 CD |
172 | (cond ((= (length x) 4) (append x '(nil))) |
173 | ((= (length x) 3) (append x '(nil nil))) | |
20908596 CD |
174 | (t x))) |
175 | (default-value var))) | |
176 | :type '(repeat | |
177 | :tag "enabled" | |
178 | (list :value ("" ?a "\n" nil nil nil) | |
179 | (string :tag "Name") | |
180 | (character :tag "Selection Key") | |
181 | (string :tag "Template") | |
b349f79f CD |
182 | (choice :tag "Destination file" |
183 | (file :tag "Specify") | |
621f83e4 | 184 | (function :tag "Function") |
b349f79f CD |
185 | (const :tag "Use `org-default-notes-file'" nil)) |
186 | (choice :tag "Destin. headline" | |
187 | (string :tag "Specify") | |
188 | (const :tag "Use `org-remember-default-headline'" nil) | |
189 | (const :tag "Level 1 at beginning of file" top) | |
190 | (const :tag "Level 1 at end of file" bottom)) | |
191 | (choice :tag "Context" | |
192 | (const :tag "Use in all contexts" nil) | |
20908596 CD |
193 | (const :tag "Use in all contexts" t) |
194 | (repeat :tag "Use only if in major mode" | |
195 | (symbol :tag "Major mode")) | |
196 | (function :tag "Perform a check against function"))))) | |
197 | ||
ce4fdcb9 CD |
198 | (defcustom org-remember-before-finalize-hook nil |
199 | "Hook that is run right before a remember process is finalized. | |
200 | The remember buffer is still current when this hook runs." | |
201 | :group 'org-remember | |
202 | :type 'hook) | |
203 | ||
204 | (defvar org-remember-mode-map (make-sparse-keymap) | |
205 | "Keymap for org-remember-mode, a minor mode. | |
206 | Use this map to set additional keybindings for when Org-mode is used | |
207 | for a Remember buffer.") | |
208 | (defvar org-remember-mode-hook nil | |
209 | "Hook for the minor `org-remember-mode'.") | |
210 | ||
211 | (define-minor-mode org-remember-mode | |
212 | "Minor mode for special key bindings in a remember buffer." | |
213 | nil " Rem" org-remember-mode-map | |
214 | (run-hooks 'org-remember-mode-hook)) | |
215 | (define-key org-remember-mode-map "\C-c\C-c" 'org-remember-finalize) | |
216 | (define-key org-remember-mode-map "\C-c\C-k" 'org-remember-kill) | |
217 | ||
b349f79f CD |
218 | (defcustom org-remember-clock-out-on-exit 'query |
219 | "Non-nil means, stop the clock when exiting a clocking remember buffer. | |
220 | This only applies if the clock is running in the remember buffer. If the | |
221 | clock is not stopped, it continues to run in the storage location. | |
222 | Instead of nil or t, this may also be the symbol `query' to prompt the | |
223 | user each time a remember buffer with a running clock is filed away. " | |
224 | :group 'org-remember | |
225 | :type '(choice | |
226 | (const :tag "Never" nil) | |
227 | (const :tag "Always" t) | |
228 | (const :tag "Query user" query))) | |
229 | ||
230 | ||
20908596 CD |
231 | (defvar annotation) ; from remember.el, dynamically scoped in `remember-mode' |
232 | (defvar initial) ; from remember.el, dynamically scoped in `remember-mode' | |
233 | ||
234 | ;;;###autoload | |
235 | (defun org-remember-insinuate () | |
621f83e4 CD |
236 | "Setup remember.el for use with Org-mode." |
237 | (org-require-remember) | |
20908596 CD |
238 | (setq remember-annotation-functions '(org-remember-annotation)) |
239 | (setq remember-handler-functions '(org-remember-handler)) | |
240 | (add-hook 'remember-mode-hook 'org-remember-apply-template)) | |
241 | ||
242 | ;;;###autoload | |
243 | (defun org-remember-annotation () | |
244 | "Return a link to the current location as an annotation for remember.el. | |
245 | If you are using Org-mode files as target for data storage with | |
246 | remember.el, then the annotations should include a link compatible with the | |
247 | conventions in Org-mode. This function returns such a link." | |
248 | (org-store-link nil)) | |
249 | ||
250 | (defconst org-remember-help | |
251 | "Select a destination location for the note. | |
252 | UP/DOWN=headline TAB=cycle visibility [Q]uit RET/<left>/<right>=Store | |
253 | RET on headline -> Store as sublevel entry to current headline | |
254 | RET at beg-of-buf -> Append to file as level 2 headline | |
255 | <left>/<right> -> before/after current headline, same headings level") | |
256 | ||
b349f79f | 257 | (defvar org-jump-to-target-location nil) |
20908596 CD |
258 | (defvar org-remember-previous-location nil) |
259 | (defvar org-force-remember-template-char) ;; dynamically scoped | |
260 | ||
261 | ;; Save the major mode of the buffer we called remember from | |
262 | (defvar org-select-template-temp-major-mode nil) | |
263 | ||
264 | ;; Temporary store the buffer where remember was called from | |
265 | (defvar org-select-template-original-buffer nil) | |
266 | ||
267 | (defun org-select-remember-template (&optional use-char) | |
268 | (when org-remember-templates | |
269 | (let* ((pre-selected-templates | |
270 | (mapcar | |
271 | (lambda (tpl) | |
272 | (let ((ctxt (nth 5 tpl)) | |
273 | (mode org-select-template-temp-major-mode) | |
274 | (buf org-select-template-original-buffer)) | |
275 | (and (or (not ctxt) (eq ctxt t) | |
276 | (and (listp ctxt) (memq mode ctxt)) | |
277 | (and (functionp ctxt) | |
278 | (with-current-buffer buf | |
279 | ;; Protect the user-defined function from error | |
280 | (condition-case nil (funcall ctxt) (error nil))))) | |
281 | tpl))) | |
282 | org-remember-templates)) | |
283 | ;; If no template at this point, add the default templates: | |
284 | (pre-selected-templates1 | |
285 | (if (not (delq nil pre-selected-templates)) | |
286 | (mapcar (lambda(x) (if (not (nth 5 x)) x)) | |
287 | org-remember-templates) | |
288 | pre-selected-templates)) | |
289 | ;; Then unconditionnally add template for any contexts | |
290 | (pre-selected-templates2 | |
291 | (append (mapcar (lambda(x) (if (eq (nth 5 x) t) x)) | |
292 | org-remember-templates) | |
293 | (delq nil pre-selected-templates1))) | |
294 | (templates (mapcar (lambda (x) | |
295 | (if (stringp (car x)) | |
296 | (append (list (nth 1 x) (car x)) (cddr x)) | |
297 | (append (list (car x) "") (cdr x)))) | |
298 | (delq nil pre-selected-templates2))) | |
299 | (char (or use-char | |
300 | (cond | |
301 | ((= (length templates) 1) | |
302 | (caar templates)) | |
303 | ((and (boundp 'org-force-remember-template-char) | |
304 | org-force-remember-template-char) | |
305 | (if (stringp org-force-remember-template-char) | |
306 | (string-to-char org-force-remember-template-char) | |
307 | org-force-remember-template-char)) | |
308 | (t | |
309 | (message "Select template: %s" | |
310 | (mapconcat | |
311 | (lambda (x) | |
312 | (cond | |
313 | ((not (string-match "\\S-" (nth 1 x))) | |
314 | (format "[%c]" (car x))) | |
315 | ((equal (downcase (car x)) | |
316 | (downcase (aref (nth 1 x) 0))) | |
317 | (format "[%c]%s" (car x) | |
318 | (substring (nth 1 x) 1))) | |
319 | (t (format "[%c]%s" (car x) (nth 1 x))))) | |
320 | templates " ")) | |
321 | (let ((inhibit-quit t) (char0 (read-char-exclusive))) | |
322 | (when (equal char0 ?\C-g) | |
323 | (jump-to-register remember-register) | |
324 | (kill-buffer remember-buffer)) | |
325 | char0)))))) | |
326 | (cddr (assoc char templates))))) | |
327 | ||
328 | (defun org-get-x-clipboard (value) | |
621f83e4 | 329 | "Get the value of the x clibboard, compatible with XEmacs, and GNU Emacs 21." |
20908596 | 330 | (if (eq window-system 'x) |
621f83e4 CD |
331 | (let ((x (org-get-x-clipboard-compat value))) |
332 | (if x (org-no-properties x))))) | |
20908596 CD |
333 | |
334 | ;;;###autoload | |
335 | (defun org-remember-apply-template (&optional use-char skip-interactive) | |
336 | "Initialize *remember* buffer with template, invoke `org-mode'. | |
337 | This function should be placed into `remember-mode-hook' and in fact requires | |
338 | to be run from that hook to function properly." | |
621f83e4 CD |
339 | (when (and (boundp 'initial) (stringp initial)) |
340 | (setq initial (org-no-properties initial)) | |
341 | (remove-text-properties 0 (length initial) '(read-only t) initial)) | |
20908596 CD |
342 | (if org-remember-templates |
343 | (let* ((entry (org-select-remember-template use-char)) | |
b349f79f | 344 | (ct (or org-overriding-default-time (org-current-time))) |
621f83e4 CD |
345 | (dct (decode-time ct)) |
346 | (ct1 | |
347 | (if (< (nth 2 dct) org-extend-today-until) | |
348 | (encode-time 0 59 23 (1- (nth 3 dct)) (nth 4 dct) (nth 5 dct)) | |
349 | ct)) | |
20908596 CD |
350 | (tpl (car entry)) |
351 | (plist-p (if org-store-link-plist t nil)) | |
621f83e4 CD |
352 | (file (if (and (nth 1 entry) |
353 | (or (and (stringp (nth 1 entry)) | |
354 | (string-match "\\S-" (nth 1 entry))) | |
355 | (functionp (nth 1 entry)))) | |
20908596 CD |
356 | (nth 1 entry) |
357 | org-default-notes-file)) | |
358 | (headline (nth 2 entry)) | |
359 | (v-c (and (> (length kill-ring) 0) (current-kill 0))) | |
360 | (v-x (or (org-get-x-clipboard 'PRIMARY) | |
361 | (org-get-x-clipboard 'CLIPBOARD) | |
362 | (org-get-x-clipboard 'SECONDARY))) | |
b349f79f CD |
363 | (v-t (format-time-string (car org-time-stamp-formats) ct)) |
364 | (v-T (format-time-string (cdr org-time-stamp-formats) ct)) | |
20908596 CD |
365 | (v-u (concat "[" (substring v-t 1 -1) "]")) |
366 | (v-U (concat "[" (substring v-T 1 -1) "]")) | |
367 | ;; `initial' and `annotation' are bound in `remember' | |
368 | (v-i (if (boundp 'initial) initial)) | |
369 | (v-a (if (and (boundp 'annotation) annotation) | |
370 | (if (equal annotation "[[]]") "" annotation) | |
371 | "")) | |
372 | (clipboards (remove nil (list v-i | |
373 | (org-get-x-clipboard 'PRIMARY) | |
374 | (org-get-x-clipboard 'CLIPBOARD) | |
375 | (org-get-x-clipboard 'SECONDARY) | |
376 | v-c))) | |
377 | (v-A (if (and v-a | |
378 | (string-match "\\[\\(\\[.*?\\]\\)\\(\\[.*?\\]\\)?\\]" v-a)) | |
379 | (replace-match "[\\1[%^{Link description}]]" nil nil v-a) | |
380 | v-a)) | |
381 | (v-n user-full-name) | |
621f83e4 | 382 | (v-k (if (marker-buffer org-clock-marker) |
ce4fdcb9 | 383 | (org-substring-no-properties org-clock-heading))) |
621f83e4 CD |
384 | (v-K (if (marker-buffer org-clock-marker) |
385 | (org-make-link-string | |
386 | (buffer-file-name (marker-buffer org-clock-marker)) | |
387 | org-clock-heading))) | |
388 | v-I | |
20908596 | 389 | (org-startup-folded nil) |
621f83e4 | 390 | (org-inhibit-startup t) |
20908596 CD |
391 | org-time-was-given org-end-time-was-given x |
392 | prompt completions char time pos default histvar) | |
621f83e4 CD |
393 | |
394 | (when (functionp file) | |
395 | (setq file (funcall file))) | |
20908596 CD |
396 | (when (and file (not (file-name-absolute-p file))) |
397 | (setq file (expand-file-name file org-directory))) | |
621f83e4 CD |
398 | |
399 | ||
20908596 CD |
400 | (setq org-store-link-plist |
401 | (append (list :annotation v-a :initial v-i) | |
402 | org-store-link-plist)) | |
403 | (unless tpl (setq tpl "") (message "No template") (ding) (sit-for 1)) | |
404 | (erase-buffer) | |
405 | (insert (substitute-command-keys | |
406 | (format | |
621f83e4 CD |
407 | "## %s \"%s\" -> \"* %s\" |
408 | ## C-u C-c C-c like C-c C-c, and immediately visit note at target location | |
409 | ## C-0 C-c C-c \"%s\" -> \"* %s\" | |
20908596 | 410 | ## %s to select file and header location interactively. |
621f83e4 | 411 | ## C-2 C-c C-c as child of the currently clocked item |
20908596 | 412 | ## To switch templates, use `\\[org-remember]'. To abort use `C-c C-k'.\n\n" |
621f83e4 | 413 | (if org-remember-store-without-prompt " C-c C-c" " C-1 C-c C-c") |
20908596 CD |
414 | (abbreviate-file-name (or file org-default-notes-file)) |
415 | (or headline "") | |
416 | (or (car org-remember-previous-location) "???") | |
621f83e4 CD |
417 | (or (cdr org-remember-previous-location) "???") |
418 | (if org-remember-store-without-prompt "C-1 C-c C-c" " C-c C-c")))) | |
419 | (insert tpl) | |
420 | (goto-char (point-min)) | |
421 | ||
20908596 | 422 | ;; Simple %-escapes |
621f83e4 | 423 | (while (re-search-forward "%\\([tTuUaiAcxkKI]\\)" nil t) |
20908596 CD |
424 | (when (and initial (equal (match-string 0) "%i")) |
425 | (save-match-data | |
426 | (let* ((lead (buffer-substring | |
427 | (point-at-bol) (match-beginning 0)))) | |
428 | (setq v-i (mapconcat 'identity | |
429 | (org-split-string initial "\n") | |
430 | (concat "\n" lead)))))) | |
431 | (replace-match | |
432 | (or (eval (intern (concat "v-" (match-string 1)))) "") | |
433 | t t)) | |
434 | ||
435 | ;; %[] Insert contents of a file. | |
436 | (goto-char (point-min)) | |
437 | (while (re-search-forward "%\\[\\(.+\\)\\]" nil t) | |
438 | (let ((start (match-beginning 0)) | |
439 | (end (match-end 0)) | |
440 | (filename (expand-file-name (match-string 1)))) | |
441 | (goto-char start) | |
442 | (delete-region start end) | |
443 | (condition-case error | |
444 | (insert-file-contents filename) | |
445 | (error (insert (format "%%![Couldn't insert %s: %s]" | |
446 | filename error)))))) | |
447 | ;; %() embedded elisp | |
448 | (goto-char (point-min)) | |
449 | (while (re-search-forward "%\\((.+)\\)" nil t) | |
450 | (goto-char (match-beginning 0)) | |
451 | (let ((template-start (point))) | |
452 | (forward-char 1) | |
453 | (let ((result | |
454 | (condition-case error | |
455 | (eval (read (current-buffer))) | |
456 | (error (format "%%![Error: %s]" error))))) | |
457 | (delete-region template-start (point)) | |
458 | (insert result)))) | |
459 | ||
460 | ;; From the property list | |
461 | (when plist-p | |
462 | (goto-char (point-min)) | |
463 | (while (re-search-forward "%\\(:[-a-zA-Z]+\\)" nil t) | |
464 | (and (setq x (or (plist-get org-store-link-plist | |
465 | (intern (match-string 1))) "")) | |
466 | (replace-match x t t)))) | |
467 | ||
468 | ;; Turn on org-mode in the remember buffer, set local variables | |
ce4fdcb9 | 469 | (let ((org-inhibit-startup t)) (org-mode) (org-remember-mode 1)) |
20908596 CD |
470 | (if (and file (string-match "\\S-" file) (not (file-directory-p file))) |
471 | (org-set-local 'org-default-notes-file file)) | |
b349f79f | 472 | (if headline |
20908596 CD |
473 | (org-set-local 'org-remember-default-headline headline)) |
474 | ;; Interactive template entries | |
475 | (goto-char (point-min)) | |
621f83e4 | 476 | (while (re-search-forward "%^\\({\\([^}]*\\)}\\)?\\([gGtTuUCLp]\\)?" nil t) |
20908596 CD |
477 | (setq char (if (match-end 3) (match-string 3)) |
478 | prompt (if (match-end 2) (match-string 2))) | |
479 | (goto-char (match-beginning 0)) | |
480 | (replace-match "") | |
481 | (setq completions nil default nil) | |
482 | (when prompt | |
483 | (setq completions (org-split-string prompt "|") | |
484 | prompt (pop completions) | |
485 | default (car completions) | |
486 | histvar (intern (concat | |
487 | "org-remember-template-prompt-history::" | |
488 | (or prompt ""))) | |
489 | completions (mapcar 'list completions))) | |
490 | (cond | |
491 | ((member char '("G" "g")) | |
492 | (let* ((org-last-tags-completion-table | |
493 | (org-global-tags-completion-table | |
494 | (if (equal char "G") (org-agenda-files) (and file (list file))))) | |
495 | (org-add-colon-after-tag-completion t) | |
ce4fdcb9 | 496 | (ins (org-ido-completing-read |
20908596 CD |
497 | (if prompt (concat prompt ": ") "Tags: ") |
498 | 'org-tags-completion-function nil nil nil | |
499 | 'org-tags-history))) | |
500 | (setq ins (mapconcat 'identity | |
501 | (org-split-string ins (org-re "[^[:alnum:]_@]+")) | |
502 | ":")) | |
503 | (when (string-match "\\S-" ins) | |
504 | (or (equal (char-before) ?:) (insert ":")) | |
505 | (insert ins) | |
506 | (or (equal (char-after) ?:) (insert ":"))))) | |
507 | ((equal char "C") | |
508 | (cond ((= (length clipboards) 1) (insert (car clipboards))) | |
509 | ((> (length clipboards) 1) | |
510 | (insert (read-string "Clipboard/kill value: " | |
511 | (car clipboards) '(clipboards . 1) | |
512 | (car clipboards)))))) | |
513 | ((equal char "L") | |
514 | (cond ((= (length clipboards) 1) | |
515 | (org-insert-link 0 (car clipboards))) | |
516 | ((> (length clipboards) 1) | |
517 | (org-insert-link 0 (read-string "Clipboard/kill value: " | |
518 | (car clipboards) | |
519 | '(clipboards . 1) | |
520 | (car clipboards)))))) | |
621f83e4 CD |
521 | ((equal char "p") |
522 | (let* | |
ce4fdcb9 CD |
523 | ((prop (org-substring-no-properties prompt)) |
524 | (pall (concat prop "_ALL")) | |
525 | (allowed | |
526 | (with-current-buffer | |
527 | (get-buffer (file-name-nondirectory file)) | |
528 | (or (cdr (assoc pall org-file-properties)) | |
529 | (cdr (assoc pall org-global-properties)) | |
530 | (cdr (assoc pall org-global-properties-fixed))))) | |
621f83e4 CD |
531 | (existing (with-current-buffer |
532 | (get-buffer (file-name-nondirectory file)) | |
533 | (mapcar 'list (org-property-values prop)))) | |
534 | (propprompt (concat "Value for " prop ": ")) | |
535 | (val (if allowed | |
ce4fdcb9 CD |
536 | (org-completing-read |
537 | propprompt | |
538 | (mapcar 'list (org-split-string allowed "[ \t]+")) | |
539 | nil 'req-match) | |
621f83e4 CD |
540 | (org-completing-read propprompt existing nil nil |
541 | "" nil "")))) | |
542 | (org-set-property prop val))) | |
20908596 | 543 | (char |
b349f79f | 544 | ;; These are the date/time related ones |
20908596 CD |
545 | (setq org-time-was-given (equal (upcase char) char)) |
546 | (setq time (org-read-date (equal (upcase char) "U") t nil | |
547 | prompt)) | |
548 | (org-insert-time-stamp time org-time-was-given | |
549 | (member char '("u" "U")) | |
550 | nil nil (list org-end-time-was-given))) | |
551 | (t | |
ce4fdcb9 CD |
552 | (let (org-completion-use-ido) |
553 | (insert (org-completing-read | |
554 | (concat (if prompt prompt "Enter string") | |
555 | (if default (concat " [" default "]")) | |
556 | ": ") | |
557 | completions nil nil nil histvar default)))))) | |
20908596 CD |
558 | (goto-char (point-min)) |
559 | (if (re-search-forward "%\\?" nil t) | |
560 | (replace-match "") | |
561 | (and (re-search-forward "^[^#\n]" nil t) (backward-char 1)))) | |
ce4fdcb9 | 562 | (let ((org-inhibit-startup t)) (org-mode) (org-remember-mode 1))) |
b349f79f CD |
563 | (when (save-excursion |
564 | (goto-char (point-min)) | |
565 | (re-search-forward "%&" nil t)) | |
566 | (replace-match "") | |
567 | (org-set-local 'org-jump-to-target-location t)) | |
20908596 CD |
568 | (when (save-excursion |
569 | (goto-char (point-min)) | |
570 | (re-search-forward "%!" nil t)) | |
571 | (replace-match "") | |
572 | (add-hook 'post-command-hook 'org-remember-finish-immediately 'append))) | |
573 | ||
574 | (defun org-remember-finish-immediately () | |
575 | "File remember note immediately. | |
576 | This should be run in `post-command-hook' and will remove itself | |
577 | from that hook." | |
578 | (remove-hook 'post-command-hook 'org-remember-finish-immediately) | |
ce4fdcb9 | 579 | (org-remember-finalize)) |
20908596 | 580 | |
b349f79f CD |
581 | (defun org-remember-visit-immediately () |
582 | "File remember note immediately. | |
583 | This should be run in `post-command-hook' and will remove itself | |
584 | from that hook." | |
585 | (org-remember '(16)) | |
586 | (goto-char (or (text-property-any | |
587 | (point) (save-excursion (org-end-of-subtree t t)) | |
588 | 'org-position-cursor t) | |
589 | (point))) | |
590 | (message "%s" | |
591 | (format | |
592 | (substitute-command-keys | |
593 | "Restore window configuration with \\[jump-to-register] %c") | |
594 | remember-register))) | |
595 | ||
596 | (defvar org-clock-marker) ; Defined in org.el | |
20908596 CD |
597 | (defun org-remember-finalize () |
598 | "Finalize the remember process." | |
ce4fdcb9 CD |
599 | (interactive) |
600 | (unless org-remember-mode | |
601 | (error "This does not seem to be a remember buffer for Org-mode")) | |
602 | (run-hooks 'org-remember-before-finalize-hook) | |
20908596 CD |
603 | (unless (fboundp 'remember-finalize) |
604 | (defalias 'remember-finalize 'remember-buffer)) | |
605 | (when (and org-clock-marker | |
606 | (equal (marker-buffer org-clock-marker) (current-buffer))) | |
b349f79f CD |
607 | ;; the clock is running in this buffer. |
608 | (when (and (equal (marker-buffer org-clock-marker) (current-buffer)) | |
609 | (or (eq org-remember-clock-out-on-exit t) | |
610 | (and org-remember-clock-out-on-exit | |
611 | (y-or-n-p "The clock is running in this buffer. Clock out now? ")))) | |
612 | (let (org-log-note-clock-out) (org-clock-out)))) | |
20908596 CD |
613 | (when buffer-file-name |
614 | (save-buffer) | |
615 | (setq buffer-file-name nil)) | |
616 | (remember-finalize)) | |
617 | ||
ce4fdcb9 CD |
618 | (defun org-remember-kill () |
619 | "Abort the current remember process." | |
620 | (interactive) | |
621 | (let ((org-note-abort t)) | |
622 | (org-remember-finalize))) | |
623 | ||
20908596 CD |
624 | ;;;###autoload |
625 | (defun org-remember (&optional goto org-force-remember-template-char) | |
626 | "Call `remember'. If this is already a remember buffer, re-apply template. | |
627 | If there is an active region, make sure remember uses it as initial content | |
628 | of the remember buffer. | |
629 | ||
630 | When called interactively with a `C-u' prefix argument GOTO, don't remember | |
631 | anything, just go to the file/headline where the selected template usually | |
632 | stores its notes. With a double prefix arg `C-u C-u', go to the last | |
633 | note stored by remember. | |
634 | ||
635 | Lisp programs can set ORG-FORCE-REMEMBER-TEMPLATE-CHAR to a character | |
636 | associated with a template in `org-remember-templates'." | |
637 | (interactive "P") | |
621f83e4 | 638 | (org-require-remember) |
20908596 CD |
639 | (cond |
640 | ((equal goto '(4)) (org-go-to-remember-target)) | |
641 | ((equal goto '(16)) (org-remember-goto-last-stored)) | |
642 | (t | |
643 | ;; set temporary variables that will be needed in | |
644 | ;; `org-select-remember-template' | |
645 | (setq org-select-template-temp-major-mode major-mode) | |
646 | (setq org-select-template-original-buffer (current-buffer)) | |
ce4fdcb9 | 647 | (if org-remember-mode |
20908596 CD |
648 | (progn |
649 | (when (< (length org-remember-templates) 2) | |
650 | (error "No other template available")) | |
651 | (erase-buffer) | |
652 | (let ((annotation (plist-get org-store-link-plist :annotation)) | |
653 | (initial (plist-get org-store-link-plist :initial))) | |
654 | (org-remember-apply-template)) | |
655 | (message "Press C-c C-c to remember data")) | |
656 | (if (org-region-active-p) | |
657 | (org-do-remember (buffer-substring (point) (mark))) | |
658 | (org-do-remember)))))) | |
659 | ||
b349f79f CD |
660 | (defvar org-remember-last-stored-marker (make-marker) |
661 | "Marker pointing to the entry most recently stored with `org-remember'.") | |
662 | ||
20908596 CD |
663 | (defun org-remember-goto-last-stored () |
664 | "Go to the location where the last remember note was stored." | |
665 | (interactive) | |
b349f79f CD |
666 | (org-goto-marker-or-bmk org-remember-last-stored-marker |
667 | "org-remember-last-stored") | |
20908596 CD |
668 | (message "This is the last note stored by remember")) |
669 | ||
670 | (defun org-go-to-remember-target (&optional template-key) | |
671 | "Go to the target location of a remember template. | |
672 | The user is queried for the template." | |
673 | (interactive) | |
674 | (let* (org-select-template-temp-major-mode | |
675 | (entry (org-select-remember-template template-key)) | |
676 | (file (nth 1 entry)) | |
677 | (heading (nth 2 entry)) | |
678 | visiting) | |
679 | (unless (and file (stringp file) (string-match "\\S-" file)) | |
680 | (setq file org-default-notes-file)) | |
681 | (when (and file (not (file-name-absolute-p file))) | |
682 | (setq file (expand-file-name file org-directory))) | |
683 | (unless (and heading (stringp heading) (string-match "\\S-" heading)) | |
684 | (setq heading org-remember-default-headline)) | |
685 | (setq visiting (org-find-base-buffer-visiting file)) | |
686 | (if (not visiting) (find-file-noselect file)) | |
687 | (switch-to-buffer (or visiting (get-file-buffer file))) | |
688 | (widen) | |
689 | (goto-char (point-min)) | |
690 | (if (re-search-forward | |
691 | (concat "^\\*+[ \t]+" (regexp-quote heading) | |
692 | (org-re "\\([ \t]+:[[:alnum:]@_:]*\\)?[ \t]*$")) | |
693 | nil t) | |
694 | (goto-char (match-beginning 0)) | |
695 | (error "Target headline not found: %s" heading)))) | |
696 | ||
697 | ;;;###autoload | |
698 | (defun org-remember-handler () | |
699 | "Store stuff from remember.el into an org file. | |
621f83e4 CD |
700 | When the template has specified a file and a headline, the entry is filed |
701 | there, or in the location defined by `org-default-notes-file' and | |
702 | `org-remember-default-headline'. | |
703 | ||
704 | If no defaults have been defined, or if the current prefix argument | |
705 | is 1 (so you must use `C-1 C-c C-c' to exit remember), an interactive | |
706 | process is used to select the target location. | |
707 | ||
708 | When the prefix is 0 (i.e. when remember is exited with `C-0 C-c C-c'), | |
709 | the entry is filed to the same location as the previous note. | |
710 | ||
711 | When the prefix is 2 (i.e. when remember is exited with `C-2 C-c C-c'), | |
712 | the entry is fild as a subentry of the entry where the clock is | |
713 | currently running. | |
714 | ||
715 | When `C-u' has been used as prefix argument, the note is stored and emacs | |
716 | moves point to the new location of the note, so that editing can be | |
717 | continued there (smilar to inserting \"%&\" into the tempate). | |
718 | ||
719 | Before storing the note, the function ensures that the text has an | |
720 | org-mode-style headline, i.e. a first line that starts with | |
721 | a \"*\". If not, a headline is constructed from the current date and | |
722 | some additional data. | |
20908596 CD |
723 | |
724 | If the variable `org-adapt-indentation' is non-nil, the entire text is | |
725 | also indented so that it starts in the same column as the headline | |
726 | \(i.e. after the stars). | |
727 | ||
728 | See also the variable `org-reverse-note-order'." | |
621f83e4 CD |
729 | (when (and (equal current-prefix-arg 2) |
730 | (not (marker-buffer org-clock-marker))) | |
93b62de8 | 731 | (error "No running clock")) |
b349f79f CD |
732 | (when (org-bound-and-true-p org-jump-to-target-location) |
733 | (let* ((end (min (point-max) (1+ (point)))) | |
734 | (beg (point))) | |
735 | (if (= end beg) (setq beg (1- beg))) | |
736 | (put-text-property beg end 'org-position-cursor t))) | |
20908596 CD |
737 | (goto-char (point-min)) |
738 | (while (looking-at "^[ \t]*\n\\|^##.*\n") | |
739 | (replace-match "")) | |
740 | (goto-char (point-max)) | |
741 | (beginning-of-line 1) | |
742 | (while (looking-at "[ \t]*$\\|##.*") | |
743 | (delete-region (1- (point)) (point-max)) | |
744 | (beginning-of-line 1)) | |
745 | (catch 'quit | |
746 | (if org-note-abort (throw 'quit nil)) | |
b349f79f | 747 | (let* ((visitp (org-bound-and-true-p org-jump-to-target-location)) |
621f83e4 CD |
748 | (previousp (and (member current-prefix-arg '((16) 0)) |
749 | org-remember-previous-location)) | |
750 | (clockp (equal current-prefix-arg 2)) | |
751 | (fastp (org-xor (equal current-prefix-arg 1) | |
20908596 CD |
752 | org-remember-store-without-prompt)) |
753 | (file (cond | |
754 | (fastp org-default-notes-file) | |
755 | ((and (eq org-remember-interactive-interface 'refile) | |
756 | org-refile-targets) | |
757 | org-default-notes-file) | |
621f83e4 | 758 | ((not previousp) |
20908596 CD |
759 | (org-get-org-file)))) |
760 | (heading org-remember-default-headline) | |
761 | (visiting (and file (org-find-base-buffer-visiting file))) | |
762 | (org-startup-folded nil) | |
763 | (org-startup-align-all-tables nil) | |
764 | (org-goto-start-pos 1) | |
b349f79f | 765 | spos exitcmd level reversed txt) |
621f83e4 CD |
766 | (when (equal current-prefix-arg '(4)) |
767 | (setq visitp t)) | |
768 | (when previousp | |
769 | (setq file (car org-remember-previous-location) | |
93b62de8 | 770 | visiting (and file (org-find-base-buffer-visiting file)) |
621f83e4 CD |
771 | heading (cdr org-remember-previous-location) |
772 | fastp t)) | |
773 | (when clockp | |
774 | (setq file (buffer-file-name (marker-buffer org-clock-marker)) | |
93b62de8 | 775 | visiting (and file (org-find-base-buffer-visiting file)) |
621f83e4 CD |
776 | heading org-clock-heading-for-remember |
777 | fastp t)) | |
20908596 | 778 | (setq current-prefix-arg nil) |
20908596 CD |
779 | ;; Modify text so that it becomes a nice subtree which can be inserted |
780 | ;; into an org tree. | |
20908596 | 781 | (goto-char (point-min)) |
b349f79f CD |
782 | (if (re-search-forward "[ \t\n]+\\'" nil t) |
783 | ;; remove empty lines at end | |
784 | (replace-match "")) | |
785 | (goto-char (point-min)) | |
786 | (unless (looking-at org-outline-regexp) | |
787 | ;; add a headline | |
788 | (insert (concat "* " (current-time-string) | |
789 | " (" (remember-buffer-desc) ")\n")) | |
790 | (backward-char 1) | |
791 | (when org-adapt-indentation | |
792 | (while (re-search-forward "^" nil t) | |
793 | (insert " ")))) | |
794 | (goto-char (point-min)) | |
795 | (if (re-search-forward "\n[ \t]*\n[ \t\n]*\\'" nil t) | |
796 | (replace-match "\n\n") | |
797 | (if (re-search-forward "[ \t\n]*\\'") | |
798 | (replace-match "\n"))) | |
799 | (goto-char (point-min)) | |
800 | (setq txt (buffer-string)) | |
801 | (org-save-markers-in-region (point-min) (point-max)) | |
20908596 CD |
802 | (when (and (eq org-remember-interactive-interface 'refile) |
803 | (not fastp)) | |
804 | (org-refile nil (or visiting (find-file-noselect file))) | |
b349f79f | 805 | (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately)) |
ce4fdcb9 CD |
806 | (save-excursion |
807 | (bookmark-jump "org-refile-last-stored") | |
808 | (bookmark-set "org-remember-last-stored") | |
809 | (move-marker org-remember-last-stored-marker (point))) | |
20908596 CD |
810 | (throw 'quit t)) |
811 | ;; Find the file | |
812 | (if (not visiting) (find-file-noselect file)) | |
813 | (with-current-buffer (or visiting (get-file-buffer file)) | |
814 | (unless (org-mode-p) | |
815 | (error "Target files for remember notes must be in Org-mode")) | |
816 | (save-excursion | |
817 | (save-restriction | |
818 | (widen) | |
819 | (and (goto-char (point-min)) | |
820 | (not (re-search-forward "^\\* " nil t)) | |
b349f79f CD |
821 | (insert "\n* " (or (and (stringp heading) heading) |
822 | "Notes") "\n")) | |
20908596 CD |
823 | (setq reversed (org-notes-order-reversed-p)) |
824 | ||
825 | ;; Find the default location | |
b349f79f CD |
826 | (when heading |
827 | (cond | |
828 | ((eq heading 'top) | |
829 | (goto-char (point-min)) | |
830 | (or (looking-at org-outline-regexp) | |
831 | (re-search-forward org-outline-regexp nil t)) | |
832 | (setq org-goto-start-pos (or (match-beginning 0) (point-min)))) | |
833 | ((eq heading 'bottom) | |
834 | (goto-char (point-max)) | |
b349f79f CD |
835 | (or (bolp) (newline)) |
836 | (setq org-goto-start-pos (point))) | |
837 | ((and (stringp heading) (string-match "\\S-" heading)) | |
838 | (goto-char (point-min)) | |
839 | (if (re-search-forward | |
840 | (concat "^\\*+[ \t]+" (regexp-quote heading) | |
841 | (org-re "\\([ \t]+:[[:alnum:]@_:]*\\)?[ \t]*$")) | |
842 | nil t) | |
843 | (setq org-goto-start-pos (match-beginning 0)) | |
844 | (when fastp | |
845 | (goto-char (point-max)) | |
846 | (unless (bolp) (newline)) | |
847 | (insert "* " heading "\n") | |
848 | (setq org-goto-start-pos (point-at-bol 0))))) | |
849 | (t (goto-char (point-min)) (setq org-goto-start-pos (point) | |
850 | heading 'top)))) | |
20908596 CD |
851 | |
852 | ;; Ask the User for a location, using the appropriate interface | |
853 | (cond | |
b349f79f CD |
854 | ((and fastp (memq heading '(top bottom))) |
855 | (setq spos org-goto-start-pos | |
621f83e4 | 856 | exitcmd (if (eq heading 'top) 'left nil))) |
20908596 CD |
857 | (fastp (setq spos org-goto-start-pos |
858 | exitcmd 'return)) | |
859 | ((eq org-remember-interactive-interface 'outline) | |
860 | (setq spos (org-get-location (current-buffer) | |
861 | org-remember-help) | |
862 | exitcmd (cdr spos) | |
863 | spos (car spos))) | |
864 | ((eq org-remember-interactive-interface 'outline-path-completion) | |
865 | (let ((org-refile-targets '((nil . (:maxlevel . 10)))) | |
866 | (org-refile-use-outline-path t)) | |
867 | (setq spos (org-refile-get-location "Heading: ") | |
868 | exitcmd 'return | |
869 | spos (nth 3 spos)))) | |
870 | (t (error "This should not happen"))) | |
871 | (if (not spos) (throw 'quit nil)) ; return nil to show we did | |
872 | ; not handle this note | |
b349f79f | 873 | (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately)) |
20908596 CD |
874 | (goto-char spos) |
875 | (cond ((org-on-heading-p t) | |
876 | (org-back-to-heading t) | |
877 | (setq level (funcall outline-level)) | |
878 | (cond | |
879 | ((eq exitcmd 'return) | |
880 | ;; sublevel of current | |
881 | (setq org-remember-previous-location | |
882 | (cons (abbreviate-file-name file) | |
883 | (org-get-heading 'notags))) | |
884 | (if reversed | |
885 | (outline-next-heading) | |
886 | (org-end-of-subtree t) | |
887 | (if (not (bolp)) | |
888 | (if (looking-at "[ \t]*\n") | |
889 | (beginning-of-line 2) | |
890 | (end-of-line 1) | |
891 | (insert "\n")))) | |
b349f79f CD |
892 | (org-paste-subtree (org-get-valid-level level 1) txt) |
893 | (and org-auto-align-tags (org-set-tags nil t)) | |
20908596 | 894 | (bookmark-set "org-remember-last-stored") |
b349f79f | 895 | (move-marker org-remember-last-stored-marker (point))) |
20908596 CD |
896 | ((eq exitcmd 'left) |
897 | ;; before current | |
b349f79f CD |
898 | (org-paste-subtree level txt) |
899 | (and org-auto-align-tags (org-set-tags nil t)) | |
20908596 | 900 | (bookmark-set "org-remember-last-stored") |
b349f79f | 901 | (move-marker org-remember-last-stored-marker (point))) |
20908596 CD |
902 | ((eq exitcmd 'right) |
903 | ;; after current | |
904 | (org-end-of-subtree t) | |
b349f79f CD |
905 | (org-paste-subtree level txt) |
906 | (and org-auto-align-tags (org-set-tags nil t)) | |
20908596 | 907 | (bookmark-set "org-remember-last-stored") |
b349f79f | 908 | (move-marker org-remember-last-stored-marker (point))) |
20908596 CD |
909 | (t (error "This should not happen")))) |
910 | ||
621f83e4 CD |
911 | ((eq heading 'bottom) |
912 | (org-paste-subtree 1 txt) | |
913 | (and org-auto-align-tags (org-set-tags nil t)) | |
914 | (bookmark-set "org-remember-last-stored") | |
915 | (move-marker org-remember-last-stored-marker (point))) | |
916 | ||
20908596 CD |
917 | ((and (bobp) (not reversed)) |
918 | ;; Put it at the end, one level below level 1 | |
919 | (save-restriction | |
920 | (widen) | |
921 | (goto-char (point-max)) | |
922 | (if (not (bolp)) (newline)) | |
b349f79f CD |
923 | (org-paste-subtree (org-get-valid-level 1 1) txt) |
924 | (and org-auto-align-tags (org-set-tags nil t)) | |
20908596 | 925 | (bookmark-set "org-remember-last-stored") |
b349f79f | 926 | (move-marker org-remember-last-stored-marker (point)))) |
20908596 CD |
927 | |
928 | ((and (bobp) reversed) | |
929 | ;; Put it at the start, as level 1 | |
930 | (save-restriction | |
931 | (widen) | |
932 | (goto-char (point-min)) | |
933 | (re-search-forward "^\\*+ " nil t) | |
934 | (beginning-of-line 1) | |
b349f79f CD |
935 | (org-paste-subtree 1 txt) |
936 | (and org-auto-align-tags (org-set-tags nil t)) | |
20908596 | 937 | (bookmark-set "org-remember-last-stored") |
b349f79f | 938 | (move-marker org-remember-last-stored-marker (point)))) |
20908596 CD |
939 | (t |
940 | ;; Put it right there, with automatic level determined by | |
941 | ;; org-paste-subtree or from prefix arg | |
20908596 CD |
942 | (org-paste-subtree |
943 | (if (numberp current-prefix-arg) current-prefix-arg) | |
b349f79f CD |
944 | txt) |
945 | (and org-auto-align-tags (org-set-tags nil t)) | |
946 | (bookmark-set "org-remember-last-stored") | |
947 | (move-marker org-remember-last-stored-marker (point)))) | |
948 | ||
20908596 CD |
949 | (when remember-save-after-remembering |
950 | (save-buffer) | |
b349f79f CD |
951 | (if (and (not visiting) |
952 | (not (equal (marker-buffer org-clock-marker) | |
953 | (current-buffer)))) | |
954 | (kill-buffer (current-buffer))))))))) | |
20908596 CD |
955 | |
956 | t) ;; return t to indicate that we took care of this note. | |
957 | ||
20908596 CD |
958 | (defun org-do-remember (&optional initial) |
959 | "Call remember." | |
960 | (remember initial)) | |
961 | ||
621f83e4 CD |
962 | (defun org-require-remember () |
963 | "Make sure remember is loaded, or install our own emergency version of it." | |
964 | (condition-case nil | |
965 | (require 'remember) | |
966 | (error | |
967 | ;; Lets install our own micro version of remember | |
968 | (defvar remember-register ?R) | |
969 | (defvar remember-mode-hook nil) | |
970 | (defvar remember-handler-functions nil) | |
971 | (defvar remember-buffer "*Remember*") | |
972 | (defvar remember-save-after-remembering t) | |
973 | (defvar remember-annotation-functions '(buffer-file-name)) | |
974 | (defun remember-finalize () | |
975 | (run-hook-with-args-until-success 'remember-handler-functions) | |
976 | (when (equal remember-buffer (buffer-name)) | |
977 | (kill-buffer (current-buffer)) | |
978 | (jump-to-register remember-register))) | |
979 | (defun remember-mode () | |
980 | (fundamental-mode) | |
981 | (setq mode-name "Remember") | |
982 | (run-hooks 'remember-mode-hook)) | |
983 | (defun remember (&optional initial) | |
984 | (window-configuration-to-register remember-register) | |
985 | (let* ((annotation (run-hook-with-args-until-success | |
986 | 'remember-annotation-functions))) | |
987 | (switch-to-buffer-other-window (get-buffer-create remember-buffer)) | |
988 | (remember-mode))) | |
989 | (defun remember-buffer-desc () | |
990 | (buffer-substring (point-min) (save-excursion (goto-char (point-min)) | |
991 | (point-at-eol))))))) | |
992 | ||
20908596 CD |
993 | (provide 'org-remember) |
994 | ||
88ac7b50 | 995 | ;; arch-tag: 497f30d0-4bc3-4097-8622-2d27ac5f2698 |
b349f79f CD |
996 | |
997 | ;;; org-remember.el ends here |