Mercurial > emacs
annotate lisp/textmodes/remember.el @ 85810:0ab0355c4c17
(msb-unload-hook): Remove function and variable.
(msb-unload-function): New-style unload function,
adapted from `msb-unload-hook'.
author | Juanma Barranquero <lekktu@gmail.com> |
---|---|
date | Wed, 31 Oct 2007 00:30:09 +0000 |
parents | 2a9d361b3986 |
children | 70f347d257ec |
rev | line source |
---|---|
85772 | 1 ;;; remember --- a mode for quickly jotting down things to remember |
2 | |
3 ;; Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, | |
4 ;; 2007 Free Software Foundation, Inc. | |
5 | |
6 ;; Author: John Wiegley <johnw@gnu.org> | |
7 ;; Created: 29 Mar 1999 | |
8 ;; Version: 1.9 | |
9 ;; Keywords: data memory todo pim | |
10 ;; URL: http://gna.org/projects/remember-el/ | |
11 | |
12 ;; This file is part of GNU Emacs. | |
13 | |
14 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
15 ;; it under the terms of the GNU General Public License as published by | |
16 ;; the Free Software Foundation; either version 3, or (at your option) | |
17 ;; any later version. | |
18 | |
19 ;; GNU Emacs is distributed in the hope that it will be useful, | |
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 ;; GNU General Public License for more details. | |
23 | |
24 ;; You should have received a copy of the GNU General Public License | |
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
27 ;; Boston, MA 02110-1301, USA. | |
28 | |
29 ;;; Commentary: | |
30 | |
31 ;; The idea | |
32 ;; | |
33 ;; Todo lists, schedules, phone databases... everything we use | |
34 ;; databases for is really just a way to extend the power of our | |
35 ;; memory. To be able to remember what our conscious mind may not | |
36 ;; currently have access to. | |
37 ;; | |
38 ;; There are many different databases out there -- and good ones -- | |
39 ;; which this mode is not trying to replace. Rather, it's how that | |
40 ;; data gets there that's the question. Most of the time, we just | |
41 ;; want to say "Remember so-and-so's phone number, or that I have to | |
42 ;; buy dinner for the cats tonight." That's the FACT. How it's | |
43 ;; stored is really the computer's problem. But at this point in | |
44 ;; time, it's most definitely also the user's problem, and sometimes | |
45 ;; so laboriously so that people just let data slip, rather than | |
46 ;; expend the effort to record it. | |
47 ;; | |
48 ;; "Remember" is a mode for remembering data. It uses whatever | |
49 ;; back-end is appropriate to record and correlate the data, but it's | |
50 ;; main intention is to allow you to express as _little_ structure as | |
51 ;; possible up front. If you later want to express more powerful | |
52 ;; relationships between your data, or state assumptions that were at | |
53 ;; first too implicit to be recognized, you can "study" the data later | |
54 ;; and rearrange it. But the initial "just remember this" impulse | |
55 ;; should be as close to simply throwing the data at Emacs as | |
56 ;; possible. | |
57 ;; | |
58 ;; Implementation | |
59 ;; | |
60 ;; Hyperbole, as a data presentation tool, always struck me as being | |
61 ;; very powerful, but it seemed to require a lot of "front-end" work | |
62 ;; before that data was really available. The problem with BBDB, or | |
63 ;; keeping up a Bibl-mode file, is that you have to use different | |
64 ;; functions to record the data, and it always takes time to stop what | |
65 ;; you're doing, format the data in the manner expected by that | |
66 ;; particular data interface, and then resume your work. | |
67 ;; | |
68 ;; With "remember", you just hit `M-x remember' (you'd probably want | |
69 ;; to bind this to an easily accessible keystroke, like C-x M-r), slam | |
70 ;; in your text however you like, and then hit C-c C-c. It will file | |
71 ;; the data away for later retrieval, and possibly indexing. | |
72 ;; | |
73 ;; Indexing is to data what "studying" is in the real world. What you | |
74 ;; do when you study (or lucubrate, for some of us) is to realize | |
75 ;; certain relationships implicit in the data, so that you can make | |
76 ;; use of those relationships. Expressing that a certain quote you | |
77 ;; remembered was a religious quote, and that you want the ability to | |
78 ;; pull up all quotes of a religious nature, is what studying does. | |
79 ;; This is a more labor intensive task than the original remembering | |
80 ;; of the data, and it's typical in real life to set aside a special | |
81 ;; period of time for doing this work. | |
82 ;; | |
83 ;; "Remember" works in the same way. When you enter data, either by | |
84 ;; typing it into a buffer, or using the contents of the selected | |
85 ;; region, it will store that data -- unindexed, uninterpreted -- in a | |
86 ;; data pool. It will also try to remember as much context | |
87 ;; information as possible (any text properties that were set, where | |
88 ;; you copied it from, when, how, etc). Later, you can walk through | |
89 ;; your accumulated set of data (both organized, and unorganized) and | |
90 ;; easily begin moving things around, and making annotations that will | |
91 ;; express the full meaning of that data, as far as you know it. | |
92 ;; | |
93 ;; Obviously this latter stage is more user-interface intensive, and | |
94 ;; it would be nice if "remember" could do it as elegantly as | |
95 ;; possible, rather than requiring a billion keystrokes to reorganize | |
96 ;; your hierarchy. Well, as the future arrives, hopefully experience | |
97 ;; and user feedback will help to make this as intuitive a tool as | |
98 ;; possible. | |
99 ;; | |
100 ;; Future Goals | |
101 ;; | |
102 ;; This tool hopes to track (and by doing it with as little new code | |
103 ;; as possible): | |
104 ;; | |
105 ;; - The raw data that gets entered | |
106 ;; | |
107 ;; - The relationships between that data (either determined | |
108 ;; implicitly by parsing the input, or explicitly by the user's | |
109 ;; studying the data). | |
110 ;; | |
111 ;; - Revisioning of the data | |
112 ;; | |
113 ;; - Where it came from, and any context information that can be | |
114 ;; programmatically determined. | |
115 ;; | |
116 ;; - Allowing particular views of the initially amorphous data pool | |
117 ;; (ala the Xanadu concept). | |
118 ;; | |
119 ;; - Storage of the data in a manner most appopriate to that data, | |
120 ;; such as keeping address-book type information in BBDB, etc. | |
121 ;; | |
122 ;; Using "remember" | |
123 ;; | |
124 ;; As a rough beginning, what I do is to keep my .notes file in | |
125 ;; outline-mode format, with a final entry called "* Raw data". Then, | |
126 ;; at intervals, I can move the data that gets appended there into | |
127 ;; other places. But certainly this should evolve into an intuitive | |
128 ;; mechanism for shuffling data off to its appropriate corner of the | |
129 ;; universe. | |
130 ;; | |
131 ;; Mapping the remember functions to very accessible keystrokes | |
132 ;; facilities using the mode: | |
133 ;; | |
134 ;; (autoload 'remember "remember" nil t) | |
135 ;; (autoload 'remember-region "remember" nil t) | |
136 ;; | |
137 ;; (define-key global-map [f8] 'remember) | |
138 ;; (define-key global-map [f9] 'remember-region) | |
139 ;; | |
140 ;; planner.el users should use `remember-to-planner' instead of `remember' | |
141 ;; to save more context information. | |
142 ;; | |
143 ;; Feedback | |
144 ;; | |
145 ;; If Emacs could become a more intelligent data store, where | |
146 ;; brainstorming would focus on the IDEAS involved -- rather than the | |
147 ;; structuring and format of those ideas, or having to stop your | |
148 ;; current flow of work in order to record them -- it would map much | |
149 ;; more closely to how the mind (well, at least mine) works, and hence | |
150 ;; would eliminate that very manual-ness which computers from the very | |
151 ;; beginning have been championed as being able to reduce. | |
152 ;; | |
153 ;; Have you ever noticed that having a laptop to write on doesn't | |
154 ;; _actually_ increase the amount of quality material that you turn | |
155 ;; out, in the long run? Perhaps its because the time we save | |
156 ;; electronically in one way, we're losing electronically in another; | |
157 ;; the tool should never dominate one's focus. As the mystic | |
158 ;; Faridu'd-Din `Attar wrote: "Be occupied as little as possible with | |
159 ;; things of the outer world but much with things of the inner world; | |
160 ;; then right action will overcome inaction." | |
161 | |
162 ;;; History: | |
163 | |
164 ;;; Code: | |
165 | |
166 (provide 'remember) | |
167 | |
168 (defconst remember-version "1.9" | |
169 "This version of remember.") | |
170 | |
171 (defgroup remember nil | |
172 "A mode to remember information." | |
173 :group 'data) | |
174 | |
175 ;;; User Variables: | |
176 | |
177 (defcustom remember-mode-hook nil | |
178 "Functions run upon entering `remember-mode'." | |
179 :type 'hook | |
85798
5810ee84e0f9
remember.el: Add additional items to some defcustom options
Michael Olson <mwolson@gnu.org>
parents:
85772
diff
changeset
|
180 :options '(flyspell-mode turn-on-auto-fill org-remember-apply-template) |
85772 | 181 :group 'remember) |
182 | |
183 (defcustom remember-in-new-frame nil | |
184 "Non-nil means use a separate frame for capturing remember data." | |
185 :type 'boolean | |
186 :group 'remember) | |
187 | |
188 (defcustom remember-register ?R | |
189 "The register in which the window configuration is stored." | |
190 :type 'character | |
191 :group 'remember) | |
192 | |
193 (defcustom remember-filter-functions nil | |
194 "*Functions run to filter remember data. | |
195 All functions are run in the remember buffer." | |
196 :type 'hook | |
197 :group 'remember) | |
198 | |
199 (defcustom remember-handler-functions '(remember-append-to-file) | |
200 "*Functions run to process remember data. | |
201 Each function is called with the current buffer narrowed to what the | |
202 user wants remembered. | |
203 If any function returns non-nil, the data is assumed to have been | |
204 recorded somewhere by that function. " | |
205 :type 'hook | |
85798
5810ee84e0f9
remember.el: Add additional items to some defcustom options
Michael Olson <mwolson@gnu.org>
parents:
85772
diff
changeset
|
206 :options '(remember-store-in-mailbox |
5810ee84e0f9
remember.el: Add additional items to some defcustom options
Michael Olson <mwolson@gnu.org>
parents:
85772
diff
changeset
|
207 remember-append-to-file |
5810ee84e0f9
remember.el: Add additional items to some defcustom options
Michael Olson <mwolson@gnu.org>
parents:
85772
diff
changeset
|
208 remember-diary-extract-entries |
5810ee84e0f9
remember.el: Add additional items to some defcustom options
Michael Olson <mwolson@gnu.org>
parents:
85772
diff
changeset
|
209 org-remember-handler) |
85772 | 210 :group 'remember) |
211 | |
212 (defcustom remember-all-handler-functions nil | |
213 "If non-nil every function in `remember-handler-functions' is | |
214 called." | |
215 :type 'boolean | |
216 :group 'remember) | |
217 | |
218 ;;; Internal Variables: | |
219 | |
220 (defvar remember-buffer "*Remember*" | |
221 "The name of the remember data entry buffer.") | |
222 | |
223 (defcustom remember-save-after-remembering t | |
224 "*Non-nil means automatically save after remembering." | |
225 :type 'boolean | |
226 :group 'remember) | |
227 | |
228 ;;; User Functions: | |
229 | |
230 ;; People with planner.el can set this to planner-annotation-functions: | |
231 ;; (defvaralias 'remember-annotation-functions 'planner-annotation-functions) | |
232 ;; or (defalias 'remember-annotation-functions 'planner-annotation-functions) | |
233 (defcustom remember-annotation-functions | |
234 (if (boundp 'planner-annotation-functions) | |
235 planner-annotation-functions | |
236 '(buffer-file-name)) | |
237 "Hook that returns an annotation to be inserted into the remember buffer. | |
238 If you have planner.el, it's nice to set this to | |
239 `planner-annotation-functions'." | |
240 :type 'hook | |
85798
5810ee84e0f9
remember.el: Add additional items to some defcustom options
Michael Olson <mwolson@gnu.org>
parents:
85772
diff
changeset
|
241 :options '(org-remember-annotation buffer-file-name) |
85772 | 242 :group 'remember) |
243 | |
244 (defvar remember-annotation nil | |
245 "Current annotation.") | |
246 (defvar remember-initial-contents nil | |
247 "Initial contents to place into *Remember* buffer.") | |
248 (defvar remember-before-remember-hook nil | |
249 "Functions run before switching to the *Remember* buffer.") | |
250 | |
251 (defcustom remember-run-all-annotation-functions-flag nil | |
252 "Non-nil means use all annotations returned by | |
253 `remember-annotation-functions'." | |
254 :type 'boolean | |
255 :group 'remember) | |
256 | |
257 ;;;###autoload | |
258 (defun remember (&optional initial) | |
259 "Remember an arbitrary piece of data. | |
260 With a prefix, uses the region as INITIAL." | |
261 (interactive | |
262 (list (when current-prefix-arg | |
263 (buffer-substring (point) (mark))))) | |
264 (funcall (if remember-in-new-frame | |
265 #'frame-configuration-to-register | |
266 #'window-configuration-to-register) remember-register) | |
267 (let* ((annotation | |
268 (if remember-run-all-annotation-functions-flag | |
269 (mapconcat 'identity | |
270 (delq nil | |
271 (mapcar 'funcall remember-annotation-functions)) | |
272 "\n") | |
273 (run-hook-with-args-until-success | |
274 'remember-annotation-functions))) | |
275 (buf (get-buffer-create remember-buffer))) | |
276 (run-hooks 'remember-before-remember-hook) | |
277 (funcall (if remember-in-new-frame | |
278 #'switch-to-buffer-other-frame | |
279 #'switch-to-buffer-other-window) buf) | |
280 (if remember-in-new-frame | |
281 (set-window-dedicated-p | |
282 (get-buffer-window (current-buffer) (selected-frame)) t)) | |
283 (remember-mode) | |
284 (when (= (point-max) (point-min)) | |
285 (when initial (insert initial)) | |
286 (setq remember-annotation annotation) | |
287 (when remember-initial-contents (insert remember-initial-contents)) | |
288 (when (and (stringp annotation) | |
289 (not (equal annotation ""))) | |
290 (insert "\n\n" annotation)) | |
291 (setq remember-initial-contents nil) | |
292 (goto-char (point-min))) | |
293 (message "Use C-c C-c to remember the data."))) | |
294 | |
295 ;;;###autoload | |
296 (defun remember-other-frame (&optional initial) | |
297 "Call `remember' in another frame." | |
298 (interactive | |
299 (list (when current-prefix-arg | |
300 (buffer-substring (point) (mark))))) | |
301 (let ((remember-in-new-frame t)) | |
302 (remember initial))) | |
303 | |
304 (defsubst remember-time-to-seconds (time) | |
305 "Convert TIME to a floating point number." | |
306 (+ (* (car time) 65536.0) | |
307 (cadr time) | |
308 (/ (or (car (cdr (cdr time))) 0) 1000000.0))) | |
309 | |
310 (defsubst remember-mail-date (&optional rfc822-p) | |
311 "Return a simple date. Nothing fancy." | |
312 (if rfc822-p | |
313 (format-time-string "%a, %e %b %Y %T %z" (current-time)) | |
314 (format-time-string "%c" (current-time)))) | |
315 | |
316 (defun remember-buffer-desc () | |
317 "Using the first line of the current buffer, create a short description." | |
318 (buffer-substring (point-min) | |
319 (save-excursion | |
320 (goto-char (point-min)) | |
321 (end-of-line) | |
322 (if (> (- (point) (point-min)) 60) | |
323 (goto-char (+ (point-min) 60))) | |
324 (point)))) | |
325 | |
326 ;; Remembering to UNIX mailboxes | |
327 | |
328 (defcustom remember-mailbox "~/Mail/remember" | |
329 "*The file in which to store remember data as mail." | |
330 :type 'file | |
331 :group 'remember) | |
332 | |
333 (defcustom remember-default-priority "medium" | |
334 "*The default priority for remembered mail messages." | |
335 :type 'string | |
336 :group 'remember) | |
337 | |
338 (defun remember-store-in-mailbox () | |
339 "Store remember data as if it were incoming mail. | |
340 In which case `remember-mailbox' should be the name of the mailbox. | |
341 Each piece of psuedo-mail created will have an `X-Todo-Priority' | |
342 field, for the purpose of appropriate splitting." | |
343 (let ((who (read-string "Who is this item related to? ")) | |
344 (moment | |
345 (format "%.0f" (remember-time-to-seconds (current-time)))) | |
346 (desc (remember-buffer-desc)) | |
347 (text (buffer-string))) | |
348 (with-temp-buffer | |
349 (insert (format " | |
350 From %s %s | |
351 Date: %s | |
352 From: %s | |
353 Message-Id: <remember-%s@%s> | |
354 X-Todo-Priority: %s | |
355 To: %s <%s> | |
356 Subject: %s\n\n" | |
357 (user-login-name) | |
358 (remember-mail-date) | |
359 (remember-mail-date t) | |
360 who | |
361 moment (system-name) | |
362 remember-default-priority | |
363 (user-full-name) user-mail-address | |
364 desc)) | |
365 (let ((here (point))) | |
366 (insert text) | |
367 (unless (bolp) | |
368 (insert "\n")) | |
369 (insert "\n") | |
370 (goto-char here) | |
371 (while (re-search-forward "^\\(From[: ]\\)" nil t) | |
372 (replace-match ">\\1"))) | |
373 (append-to-file (point-min) (point-max) remember-mailbox) | |
374 t))) | |
375 | |
376 ;; Remembering to plain files | |
377 | |
378 (defcustom remember-data-file "~/.notes" | |
379 "*The file in which to store unprocessed data." | |
380 :type 'file | |
381 :group 'remember) | |
382 | |
383 (defcustom remember-leader-text "** " | |
384 "*The text used to begin each remember item." | |
385 :type 'string | |
386 :group 'remember) | |
387 | |
388 (defun remember-append-to-file () | |
389 "Remember, with description DESC, the given TEXT." | |
390 (let ((text (buffer-string)) | |
391 (desc (remember-buffer-desc))) | |
392 (with-temp-buffer | |
393 (insert "\n" remember-leader-text (current-time-string) | |
394 " (" desc ")\n\n" text) | |
395 (if (not (bolp)) | |
396 (insert "\n")) | |
397 (if (find-buffer-visiting remember-data-file) | |
398 (let ((remember-text (buffer-string))) | |
399 (set-buffer (get-file-buffer remember-data-file)) | |
400 (save-excursion | |
401 (goto-char (point-max)) | |
402 (insert remember-text) | |
403 (when remember-save-after-remembering (save-buffer)))) | |
404 (append-to-file (point-min) (point-max) remember-data-file))))) | |
405 | |
406 ;;;###autoload | |
407 (defun remember-region (&optional beg end) | |
408 "Remember the data from BEG to END. | |
409 If called from within the remember buffer, BEG and END are ignored, | |
410 and the entire buffer will be remembered. | |
411 | |
412 This function is meant to be called from the *Remember* buffer. | |
413 If you want to remember a region, supply a universal prefix to | |
414 `remember' instead. For example: C-u M-x remember." | |
415 ;; Sacha: I have no idea where remember.el gets this context information, but | |
416 ;; you can just use remember-annotation-functions. | |
417 (interactive) | |
418 (let ((b (or beg (min (point) (or (mark) (point-min))))) | |
419 (e (or end (max (point) (or (mark) (point-max)))))) | |
420 (save-restriction | |
421 (narrow-to-region b e) | |
422 (if remember-all-handler-functions | |
423 (run-hooks 'remember-handler-functions) | |
424 (run-hook-with-args-until-success 'remember-handler-functions)) | |
425 (remember-destroy)))) | |
426 | |
427 ;;;###autoload | |
428 (defun remember-clipboard () | |
429 "Remember the contents of the current clipboard. | |
430 Most useful for remembering things from Netscape or other X Windows | |
431 application." | |
432 (interactive) | |
433 (remember (current-kill 0))) | |
434 | |
435 ;;;###autoload | |
436 (defun remember-buffer () | |
437 "Remember the contents of the current buffer." | |
438 (interactive) | |
439 (remember-region (point-min) (point-max))) | |
440 | |
441 ;;;###autoload | |
442 (defun remember-destroy () | |
443 "Destroy the current *Remember* buffer." | |
444 (interactive) | |
445 (when (equal remember-buffer (buffer-name)) | |
446 (kill-buffer (current-buffer)) | |
447 (jump-to-register remember-register))) | |
448 | |
449 ;;; Internal Functions: | |
450 | |
451 (defvar remember-mode-map () | |
452 "Keymap used in Remember mode.") | |
453 (when (not remember-mode-map) | |
454 (setq remember-mode-map (make-sparse-keymap)) | |
455 (define-key remember-mode-map "\C-x\C-s" 'remember-buffer) | |
456 (define-key remember-mode-map "\C-c\C-c" 'remember-buffer) | |
457 (define-key remember-mode-map "\C-c\C-k" 'remember-destroy)) | |
458 | |
459 (defun remember-mode () | |
460 "Major mode for output from \\[remember]. | |
461 \\<remember-mode-map>This buffer is used to collect data that you want | |
462 remember. Just hit \\[remember-region] when you're done entering, and | |
463 it will go ahead and file the data for latter retrieval, and possible | |
464 indexing. \\{remember-mode-map}" | |
465 (interactive) | |
466 (kill-all-local-variables) | |
467 (indented-text-mode) | |
468 (use-local-map remember-mode-map) | |
469 (setq major-mode 'remember-mode | |
470 mode-name "Remember") | |
471 (run-hooks 'remember-mode-hook)) | |
472 | |
85806 | 473 ;; arch-tag: 59312a05-06c7-4da1-b6f7-5ea41c9d5577 |
85772 | 474 ;;; remember.el ends here |