emacs: Improve the definition and use of `notmuch-fcc-dirs'.

Re-work the declaration and definition of `notmuch-fcc-dirs'. The
variable now allows three types of values:

- nil: no Fcc header is added,

- a string: the value of `notmuch-fcc-dirs' is the name of the
  folder to use,

- a list: the folder is chosen based on the From address of the
  current message using a list of regular expressions and
  corresponding folders:

     ((\"Sebastian@SSpaeth.de\" . \"privat\")
      (\"spaetz@sspaeth.de\" . \"OUTBOX.OSS\")
      (\".*\" . \"defaultinbox\"))

  If none of the regular expressions match the From address, no
  Fcc header will be added.
This commit is contained in:
David Edmondson 2010-11-08 15:01:25 +00:00 committed by Carl Worth
parent c471c4eb04
commit ea1c2bb5c5

View file

@ -16,6 +16,7 @@
;; To use this as the fcc handler for message-mode,
;; customize the notmuch-fcc-dirs variable
(eval-when-compile (require 'cl))
(require 'message)
(require 'notmuch-lib)
@ -23,41 +24,40 @@
(defvar notmuch-maildir-fcc-count 0)
(defcustom notmuch-fcc-dirs "sent"
"Determines the maildir directory to save outgoing mails in.
"Determines the maildir directory in which to save outgoing mail.
If set to non-nil, this will cause message mode to file your
mail in the specified directory (fcc).
Three types of values are permitted:
It is either a string if you only need one fcc directory or a
list if they depend on your From address (see example).
- nil: no Fcc header is added,
In the former case it is a string such as \"INBOX.Sent\".
- a string: the value of `notmuch-fcc-dirs' is the name of the
folder to use,
In the fancy setup, where you want different outboxes depending
on your From address, you supply a list like this:
- a list: the folder is chosen based on the From address of the
current message using a list of regular expressions and
corresponding folders:
((\"defaultinbox\")
(\"Sebastian Spaeth <Sebastian@SSpaeth.de>\" . \"privat\")
(\"Sebastian Spaeth <spaetz@sspaeth.de>\" . \"OUTBOX.OSS\")
)
((\"Sebastian@SSpaeth.de\" . \"privat\")
(\"spaetz@sspaeth.de\" . \"OUTBOX.OSS\")
(\".*\" . \"defaultinbox\"))
The outbox that matches a key (case insensitive) will be
used. The first entry is used as a default fallback when nothing
else matches.
If none of the regular expressions match the From address, no
Fcc header will be added.
In all cases, a relative FCC directory will be understood to
specify a directory within the notmuch mail store, (as set by
the database.path option in the notmuch configuration file).
In all cases, a relative FCC directory will be understood to
specify a directory within the notmuch mail store, (as set by
the database.path option in the notmuch configuration file).
You will be prompted to create the directory if it does not exist yet when
sending a mail.
This function will not modify the headers if there is a FCC
header, but will check that the target directory exists."
You will be prompted to create the directory if it does not exist
yet when sending a mail."
:require 'notmuch-fcc-initialization
:group 'notmuch
)
:type '(choice
(const :tag "No FCC header" nil)
(string :tag "A single folder")
(repeat :tag "A folder based on the From header"
(cons regexp (string :tag "Folder")))))
(defun notmuch-fcc-initialization ()
"If notmuch-fcc-directories is set,
@ -67,44 +67,66 @@
(setq message-fcc-handler-function
'(lambda (destdir)
(notmuch-maildir-fcc-write-buffer-to-maildir destdir t)))
;;add a hook to actually insert the Fcc header when sending
;; add a hook to actually insert the Fcc header when sending
(add-hook 'message-header-setup-hook 'notmuch-fcc-header-setup))
(defun notmuch-fcc-header-setup ()
"Adds an appropriate fcc header to the current mail buffer
"Add an Fcc header to the current message buffer.
Can be added to message-send-hook and will set the FCC header
based on the values of notmuch-fcc-directories (see the
variable customization there for examples). It uses the first
entry as default fallback if no From address matches."
;; only do something if notmuch-fcc-dirs is set
(when notmuch-fcc-dirs
(let (subdir)
(if (stringp notmuch-fcc-dirs)
;; notmuch-fcc-dirs is a string, just use it as subdir
(setq subdir notmuch-fcc-dirs)
;; else: it's a list of alists (("sent") ("name1" . "sent1"))
(setq subdir (cdr (assoc-string (message-fetch-field "from") notmuch-fcc-dirs t)))
;; if we found no hit, use the first entry as default fallback
(unless subdir (setq subdir (car (car notmuch-fcc-dirs)))))
Can be added to `message-send-hook' and will set the Fcc header
based on the values of `notmuch-fcc-dirs'. An existing Fcc header
will NOT be removed or replaced."
;; if there is no fcc header yet, add ours
(unless (message-fetch-field "fcc")
(message-add-header (concat "Fcc: "
(let ((subdir
(cond
((or (not notmuch-fcc-dirs)
(message-fetch-field "Fcc"))
;; Nothing set or an existing header.
nil)
((stringp notmuch-fcc-dirs)
notmuch-fcc-dirs)
((and (listp notmuch-fcc-dirs)
(= 1 (length (car notmuch-fcc-dirs))))
;; Old style - no longer works.
(error "Invalid `notmuch-fcc-dirs' setting (old style)"))
((listp notmuch-fcc-dirs)
(let* ((from (message-fetch-field "From"))
(match
(catch 'first-match
(dolist (re-folder notmuch-fcc-dirs)
(when (string-match-p (car re-folder) from)
(throw 'first-match re-folder))))))
(if match
(cdr match)
(message "No Fcc header added.")
nil)))
(t
(error "Invalid `notmuch-fcc-dirs' setting (neither string nor list)")))))
(when subdir
(message-add-header
(concat "Fcc: "
;; If the resulting directory is not an absolute path,
;; prepend the standard notmuch database path.
(if (= (elt subdir 0) ?/)
subdir
(concat (notmuch-database-path) "/" subdir)))))
(concat (notmuch-database-path) "/" subdir))))
;; finally test if fcc points to a valid maildir
(let ((fcc-header (message-fetch-field "fcc")))
(let ((fcc-header (message-fetch-field "Fcc")))
(unless (notmuch-maildir-fcc-dir-is-maildir-p fcc-header)
(cond ((not (file-writable-p fcc-header))
(error (format "%s is not a maildir, but you don't have permission to create one." fcc-header)))
(error (format "No permission to create %s, which does not exist"
fcc-header)))
((y-or-n-p (format "%s is not a maildir. Create it? "
fcc-header))
(notmuch-maildir-fcc-create-maildir fcc-header))
(t
(error "Not sending message."))))))))
(error "Message not sent"))))))))
(defun notmuch-maildir-fcc-host-fixer (hostname)
(replace-regexp-in-string "/\\|:"