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