;;; remember --- a mode for quickly jotting down things to remember
-;; Copyright (C) 1999-2001, 2003-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1999-2001, 2003-2015 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
+;; Maintainer: emacs-devel@gnu.org
;; Created: 29 Mar 1999
;; Version: 2.0
;; Keywords: data memory todo pim
;;
;; * Using "remember"
;;
-;; As a rough beginning, what I do is to keep my .notes file in
+;; As a rough beginning, what I do is to keep my `remember-data-file' in
;; outline-mode format, with a final entry called "* Raw data". Then,
;; at intervals, I can move the data that gets appended there into
;; other places. But certainly this should evolve into an intuitive
;;; Code:
-(provide 'remember)
-
(defconst remember-version "2.0"
"This version of remember.")
:type 'boolean
:group 'remember)
+;; See below for more user variables.
+
;;; Internal Variables:
(defvar remember-buffer "*Remember*"
transient-mark-mode))
(buffer-substring (region-beginning) (region-end)))))
(funcall (if remember-in-new-frame
- #'frame-configuration-to-register
+ #'frameset-to-register
#'window-configuration-to-register) remember-register)
(let* ((annotation
(if remember-run-all-annotation-functions-flag
(if remember-in-new-frame
(set-window-dedicated-p
(get-buffer-window (current-buffer) (selected-frame)) t))
+ (setq buffer-offer-save t)
(remember-mode)
(when (= (point-max) (point-min))
(when initial (insert initial))
(defsubst remember-mail-date (&optional rfc822-p)
"Return a simple date. Nothing fancy."
- (if rfc822-p
- (format-time-string "%a, %e %b %Y %T %z" (current-time))
- (format-time-string "%a %b %e %T %Y" (current-time))))
+ (format-time-string (if rfc822-p "%a, %e %b %Y %T %z" "%a %b %e %T %Y")))
(defun remember-buffer-desc ()
"Using the first line of the current buffer, create a short description."
;; Remembering to plain files
(defcustom remember-data-file (locate-user-emacs-file "notes" ".notes")
- "The file in which to store unprocessed data."
+ "The file in which to store unprocessed data.
+When set via customize, visited file of the notes buffer (if it
+exists) might be changed."
+ :version "24.4" ; added locate-user-emacs-file
:type 'file
+ :set (lambda (symbol value)
+ (let ((buf (find-buffer-visiting (default-value symbol))))
+ (set-default symbol value)
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (set-visited-file-name
+ (expand-file-name remember-data-file))))))
+ :initialize 'custom-initialize-default
:group 'remember)
(defcustom remember-leader-text "** "
(defun remember-append-to-file ()
"Remember, with description DESC, the given TEXT."
- (let ((text (buffer-string))
- (desc (remember-buffer-desc)))
- (with-temp-buffer
- (insert "\n" remember-leader-text (current-time-string)
- " (" desc ")\n\n" text)
- (if (not (bolp))
- (insert "\n"))
- (if (find-buffer-visiting remember-data-file)
- (let ((remember-text (buffer-string)))
- (set-buffer (get-file-buffer remember-data-file))
- (save-excursion
- (goto-char (point-max))
- (insert remember-text)
- (when remember-save-after-remembering (save-buffer))))
- (append-to-file (point-min) (point-max) remember-data-file)))))
+ (let* ((text (buffer-string))
+ (desc (remember-buffer-desc))
+ (remember-text (concat "\n" remember-leader-text (current-time-string)
+ " (" desc ")\n\n" text
+ (save-excursion (goto-char (point-max))
+ (if (bolp) nil "\n"))))
+ (buf (find-buffer-visiting remember-data-file)))
+ (if buf
+ (with-current-buffer buf
+ (save-excursion
+ (goto-char (point-max))
+ (insert remember-text))
+ (if remember-save-after-remembering (save-buffer)))
+ (append-to-file remember-text nil remember-data-file))))
(defun remember-region (&optional beg end)
"Remember the data from BEG to END.
(remember-destroy))))
(defcustom remember-data-directory "~/remember"
- "The directory in which to store remember data as files."
+ "The directory in which to store remember data as files.
+Used by `remember-store-in-files'."
:type 'directory
:version "24.4"
:group 'remember)
(defcustom remember-directory-file-name-format "%Y-%m-%d_%T-%z"
- "Format string for the file name in which to store unprocessed data."
+ "Format string for the file name in which to store unprocessed data.
+This is passed to `format-time-string'.
+Used by `remember-store-in-files'."
:type 'string
:version "24.4"
:group 'remember)
(defun remember-store-in-files ()
"Store remember data in a file in `remember-data-directory'.
-The file is named after `remember-directory-file-name-format' fed through
-`format-time-string'."
- (let ((name (format-time-string
- remember-directory-file-name-format (current-time)))
+The file is named by calling `format-time-string' using
+`remember-directory-file-name-format' as the format string."
+ (let ((name (format-time-string remember-directory-file-name-format))
(text (buffer-string)))
(with-temp-buffer
(insert text)
:type '(choice (const :tag "diary-file" nil) file)
:group 'remember)
+(defvar calendar-date-style) ; calendar.el
+
(defun remember-diary-convert-entry (entry)
"Translate MSG to an entry readable by diary."
(save-match-data
;; which requires calendar.
(require 'calendar)
(replace-match
- (let ((style (if (boundp 'calendar-date-style)
- calendar-date-style
- ;; Don't complain about obsolescence.
- (if (with-no-warnings european-calendar-style)
- 'european
- 'american))))
- (cond ((eq style 'european)
- (concat (match-string 3 entry) "/"
- (match-string 2 entry) "/"
- (match-string 1 entry)))
- ((eq style 'iso)
- (concat (match-string 1 entry) "-"
+ (cond ((eq calendar-date-style 'european)
+ (concat (match-string 3 entry) "/"
+ (match-string 2 entry) "/"
+ (match-string 1 entry)))
+ ((eq calendar-date-style 'iso)
+ (concat (match-string 1 entry) "-"
(match-string 2 entry) "-"
(match-string 3 entry)))
- (t (concat (match-string 2 entry) "/"
- (match-string 3 entry) "/"
- (match-string 1 entry)))))
+ (t (concat (match-string 2 entry) "/"
+ (match-string 3 entry) "/"
+ (match-string 1 entry))))
t t entry))
entry)))
(goto-char (point-min))
(let (list)
(while (re-search-forward "^DIARY:\\s-*\\(.+\\)" nil t)
- (add-to-list 'list (remember-diary-convert-entry (match-string 1))))
+ (push (remember-diary-convert-entry (match-string 1)) list))
(when list
(diary-make-entry (mapconcat 'identity list "\n")
nil remember-diary-file))
(define-key map "\C-c\C-c" 'remember-finalize)
(define-key map "\C-c\C-k" 'remember-destroy)
map)
- "Keymap used in Remember mode.")
+ "Keymap used in `remember-mode'.")
(define-derived-mode remember-mode indented-text-mode "Remember"
"Major mode for output from \\[remember].
\\{remember-mode-map}"
(set-keymap-parent remember-mode-map nil))
+;; Notes buffer showing the notes:
+
+(defcustom remember-notes-buffer-name "*notes*"
+ "Name of the notes buffer.
+Setting it to *scratch* will hijack the *scratch* buffer for the
+purpose of storing notes."
+ :type 'string
+ :version "24.4")
+
+(defcustom remember-notes-initial-major-mode nil
+ "Major mode to use in the notes buffer when it's created.
+If this is nil, use `initial-major-mode'."
+ :type '(choice (const :tag "Use `initial-major-mode'" nil)
+ (function :tag "Major mode" text-mode))
+ :version "24.4")
+
+(defcustom remember-notes-bury-on-kill t
+ "Non-nil means `kill-buffer' will bury the notes buffer instead of killing."
+ :type 'boolean
+ :version "24.4")
+
+(defun remember-notes-save-and-bury-buffer ()
+ "Save (if it is modified) and bury the current buffer."
+ (interactive)
+ (when (buffer-modified-p)
+ (save-buffer))
+ (bury-buffer))
+
+
+
+(defvar remember-notes-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-c\C-c" 'remember-notes-save-and-bury-buffer)
+ map)
+ "Keymap used in `remember-notes-mode'.")
+
+(define-minor-mode remember-notes-mode
+ "Minor mode for the `remember-notes' buffer.
+This sets `buffer-save-without-query' so that `save-some-buffers' will
+save the notes buffer without asking.
+
+\\{remember-notes-mode-map}"
+ nil nil nil
+ (cond
+ (remember-notes-mode
+ (add-hook 'kill-buffer-query-functions
+ #'remember-notes--kill-buffer-query nil t)
+ (setq buffer-save-without-query t))))
+
+;;;###autoload
+(defun remember-notes (&optional switch-to)
+ "Return the notes buffer, creating it if needed, and maybe switch to it.
+This buffer is for notes that you want to preserve across Emacs sessions.
+The notes are saved in `remember-data-file'.
+
+If a buffer is already visiting that file, just return it.
+
+Otherwise, create the buffer, and rename it to `remember-notes-buffer-name',
+unless a buffer of that name already exists. Set the major mode according
+to `remember-notes-initial-major-mode', and enable `remember-notes-mode'
+minor mode.
+
+Use \\<remember-notes-mode-map>\\[remember-notes-save-and-bury-buffer] to save and bury the notes buffer.
+
+Interactively, or if SWITCH-TO is non-nil, switch to the buffer.
+Return the buffer.
+
+Set `initial-buffer-choice' to `remember-notes' to visit your notes buffer
+when Emacs starts. Set `remember-notes-buffer-name' to \"*scratch*\"
+to turn the *scratch* buffer into your notes buffer."
+ (interactive "p")
+ (let ((buf (or (find-buffer-visiting remember-data-file)
+ (with-current-buffer (find-file-noselect remember-data-file)
+ (and remember-notes-buffer-name
+ (not (get-buffer remember-notes-buffer-name))
+ (rename-buffer remember-notes-buffer-name))
+ (funcall (or remember-notes-initial-major-mode
+ initial-major-mode))
+ (remember-notes-mode 1)
+ (current-buffer)))))
+ (when switch-to
+ (switch-to-buffer buf))
+ buf))
+
+(defun remember-notes--kill-buffer-query ()
+ "Function that `remember-notes-mode' adds to `kill-buffer-query-functions'.
+Save the current buffer if modified. If `remember-notes-bury-on-kill'
+is non-nil, bury it and return nil; otherwise return t."
+ (when (buffer-modified-p)
+ (save-buffer))
+ (if remember-notes-bury-on-kill
+ (progn
+ ;; bury-buffer always returns nil, but let's be explicit.
+ (bury-buffer)
+ nil)
+ t))
+
+(provide 'remember)
+
;;; remember.el ends here