;;; mairix.el --- Mairix interface for Emacs
-;; Copyright (C) 2008 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2012 Free Software Foundation, Inc.
;; Author: David Engster <dengste@eml.cc>
;; Keywords: mail searching
;; Currently, RMail, Gnus (with mbox files), and VM are supported as
;; mail programs, but it is pretty easy to interface it with other
;; ones as well. Please see the docs and the source for details.
-;; In a nutshell: include your favourite mail program in
+;; In a nutshell: include your favorite mail program in
;; `mairix-mail-program' and write functions for
;; `mairix-display-functions' and `mairix-get-mail-header-functions'.
;; If you have written such functions for your Emacs mail program of
(defvar mairix-widget-fields-list
'(("from" "f" "From") ("to" "t" "To") ("cc" "c" "Cc")
("subject" "s" "Subject") ("to" "tc" "To or Cc")
- ("from" "a" "Address") (nil "Body" "b") (nil "n" "Attachment")
+ ("from" "a" "Address") (nil "b" "Body") (nil "n" "Attachment")
("Message-ID" "m" "Message ID") (nil "s" "Size") (nil "d" "Date"))
"Fields that should be editable during interactive query customization.
Header, corresponding mairix command and description for editable
(autoload 'rmail "rmail")
(autoload 'rmail-summary-displayed "rmail")
(autoload 'rmail-summary "rmailsum")
-(eval-when-compile
- (defvar rmail-buffer))
+(defvar rmail-buffer)
(defun mairix-rmail-display (folder)
"Display mbox file FOLDER with RMail."
(rmail-summary))))
;; Fetching mail header field:
-(autoload 'rmail-narrow-to-non-pruned-header "rmail")
(defun mairix-rmail-fetch-field (field)
"Get mail header FIELD for current message using RMail."
(unless (and (boundp 'rmail-buffer)
rmail-buffer)
(error "No RMail buffer available"))
- (save-excursion
- (set-buffer rmail-buffer)
- (save-restriction
- (rmail-narrow-to-non-pruned-header)
- (mail-fetch-field field))))
+ ;; At this point, we are in rmail mode, so the rmail funcs are loaded.
+ (if (fboundp 'rmail-get-header) ; Emacs 23
+ (rmail-get-header field)
+ (with-current-buffer rmail-buffer
+ (save-restriction
+ ;; Don't warn about this when compiling Emacs 23.
+ (with-no-warnings (rmail-narrow-to-non-pruned-header))
+ (mail-fetch-field field)))))
;;; Gnus
(eval-when-compile
"Get mail header FIELD for current message using Gnus."
(unless (gnus-alive-p)
(error "Gnus is not running"))
- (save-excursion
- (unless (gnus-buffer-exists-p gnus-article-buffer)
- (error "No article buffer available"))
- (set-buffer gnus-article-buffer)
+ (unless (gnus-buffer-exists-p gnus-article-buffer)
+ (error "No article buffer available"))
+ (with-current-buffer gnus-article-buffer
(gnus-summary-toggle-header 1)
(message-field-value field)))
(defun mairix-search (search threads)
"Call Mairix with SEARCH.
-If THREADS is t, also display whole threads of found
+If THREADS is non-nil, also display whole threads of found
messages. Results will be put into the default search file."
(interactive
(list
mairix-output-buffer)))
(zerop rval)))
-(defun mairix-replace-illegal-chars (header)
- "Replace illegal characters in HEADER for mairix query."
+(defun mairix-replace-invalid-chars (header)
+ "Replace invalid characters in HEADER for mairix query."
(when header
- (while (string-match "[^-.@/,& [:alnum:]]" header)
+ (while (string-match "[^-.@/,^=~& [:alnum:]]" header)
(setq header (replace-match "" t t header)))
(while (string-match "[& ]" header)
(setq header (replace-match "," t t header)))
"Send query from WIDGETS to mairix binary."
(mairix-search
(mairix-widget-make-query-from-widgets widgets)
- (if (widget-value (cadr (assoc "Threads" widgets)))
- t
- -1))
+ (if (widget-value (cadr (assoc "Threads" widgets))) t))
(kill-buffer mairix-customize-query-buffer))
(defun mairix-widget-save-search (widgets)
(concat
(nth 1 cur)
":"
- (mairix-replace-illegal-chars
+ (mairix-replace-invalid-chars
(widget-value
(cadr (assoc (concat "e" (car (cddr cur))) widgets)))))
query)))
(kill-all-local-variables)
(erase-buffer)
(widget-insert
- "Specify your query for Mairix (check boxes for activating fields):\n\n")
+ "Specify your query for Mairix using check boxes for activating fields.\n\n")
(widget-insert
- "(Whitespaces will be converted to ',' (i.e. AND). Use '/' for OR.)\n\n")
+ (concat "Use ~word to match messages "
+ (propertize "not" 'face 'italic)
+ " containing the word)\n"
+ " substring= to match words containing the substring\n"
+ " substring=N to match words containing the substring, allowing\n"
+ " up to N errors(missing/extra/different letters)\n"
+ " ^substring= to match the substring at the beginning of a word.\n"))
+ (widget-insert
+ "Whitespace will be converted to ',' (i.e. AND). Use '/' for OR.\n\n")
(setq mairix-widgets (mairix-widget-build-editable-fields values))
(when (member 'flags mairix-widget-other)
(widget-insert "\nFlags:\n Seen: ")
;;;; Major mode for editing/deleting/saving searches
-(defvar mairix-searches-mode-map nil "'mairix-searches-mode' keymap.")
-
-;; Keymap
-(if (not mairix-searches-mode-map)
- (let ((map (make-keymap)))
- (define-key map [(return)] 'mairix-select-search)
- (define-key map [(down)] 'mairix-next-search)
- (define-key map [(up)] 'mairix-previous-search)
- (define-key map [(right)] 'mairix-next-search)
- (define-key map [(left)] 'mairix-previous-search)
- (define-key map "\C-p" 'mairix-previous-search)
- (define-key map "\C-n" 'mairix-next-search)
- (define-key map [(q)] 'mairix-select-quit)
- (define-key map [(e)] 'mairix-select-edit)
- (define-key map [(d)] 'mairix-select-delete)
- (define-key map [(s)] 'mairix-select-save)
- (setq mairix-searches-mode-map map)))
+(defvar mairix-searches-mode-map
+ (let ((map (make-keymap)))
+ (define-key map [(return)] 'mairix-select-search)
+ (define-key map [(down)] 'mairix-next-search)
+ (define-key map [(up)] 'mairix-previous-search)
+ (define-key map [(right)] 'mairix-next-search)
+ (define-key map [(left)] 'mairix-previous-search)
+ (define-key map "\C-p" 'mairix-previous-search)
+ (define-key map "\C-n" 'mairix-next-search)
+ (define-key map [(q)] 'mairix-select-quit)
+ (define-key map [(e)] 'mairix-select-edit)
+ (define-key map [(d)] 'mairix-select-delete)
+ (define-key map [(s)] 'mairix-select-save)
+ map)
+ "'mairix-searches-mode' keymap.")
(defvar mairix-searches-mode-font-lock-keywords)
(lambda (field)
(list (car (cddr field))
(if (car field)
- (mairix-replace-illegal-chars
+ (mairix-replace-invalid-chars
(funcall get-mail-header (car field)))
nil))))
mairix-widget-fields-list)))
(provide 'mairix)
;;; mairix.el ends here
-
-;; arch-tag: 787ab678-fcd5-4c50-9295-01c2ee5124a6