* merge branch 'master' of github.com:djcb/mu
This commit is contained in:
@ -192,11 +192,16 @@ If needed, set the Fcc header, and register the handler function."
|
||||
|
||||
|
||||
|
||||
(defconst mu4e~compose-hidden-headers
|
||||
(defvar mu4e-compose-hidden-headers
|
||||
`("^References:" "^Face:" "^X-Face:"
|
||||
"^X-Draft-From:" "^User-agent:")
|
||||
"Hidden headers when composing.")
|
||||
|
||||
(defun mu4e~compose-hide-headers ()
|
||||
"Hide the headers as per `mu4e-compose-hidden-headers'."
|
||||
(let ((message-hidden-headers mu4e-compose-hidden-headers))
|
||||
(message-hide-headers)))
|
||||
|
||||
(defconst mu4e~compose-address-fields-regexp
|
||||
"^\\(To\\|B?Cc\\|Reply-To\\|From\\):")
|
||||
|
||||
@ -211,8 +216,7 @@ appear on disk."
|
||||
(mu4e~compose-set-friendly-buffer-name)
|
||||
(mu4e~draft-insert-mail-header-separator)
|
||||
;; hide some headers again
|
||||
(let ((message-hidden-headers mu4e~compose-hidden-headers))
|
||||
(message-hide-headers))
|
||||
(mu4e~compose-hide-headers)
|
||||
(set-buffer-modified-p nil)
|
||||
;; update the file on disk -- ie., without the separator
|
||||
(mu4e~proc-add (buffer-file-name) mu4e~draft-drafts-folder)) nil t))
|
||||
@ -255,7 +259,7 @@ appear on disk."
|
||||
(define-derived-mode mu4e-compose-mode message-mode "mu4e:compose"
|
||||
"Major mode for the mu4e message composition, derived from `message-mode'.
|
||||
\\{message-mode-map}."
|
||||
(let ((message-hidden-headers mu4e~compose-hidden-headers))
|
||||
(progn
|
||||
(use-local-map mu4e-compose-mode-map)
|
||||
(make-local-variable 'message-default-charset)
|
||||
;; if the default charset is not set, use UTF-8
|
||||
@ -279,7 +283,7 @@ appear on disk."
|
||||
|
||||
(define-key mu4e-compose-mode-map (kbd "C-S-u") 'mu4e-update-mail-and-index)
|
||||
(define-key mu4e-compose-mode-map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
|
||||
|
||||
|
||||
;; setup the fcc-stuff, if needed
|
||||
(add-hook 'message-send-hook
|
||||
(defun mu4e~compose-save-before-sending ()
|
||||
@ -293,7 +297,7 @@ appear on disk."
|
||||
(setq mu4e-sent-func 'mu4e-sent-handler)
|
||||
(mu4e~proc-sent (buffer-file-name) mu4e~draft-drafts-folder)) nil))
|
||||
;; mark these two hooks as permanent-local, so they'll survive mode-changes
|
||||
;; (put 'mu4e~compose-save-before-sending 'permanent-local-hook t)
|
||||
;; (put 'mu4e~compose-save-before-sending 'permanent-local-hook t)
|
||||
(put 'mu4e~compose-mark-after-sending 'permanent-local-hook t))
|
||||
|
||||
(defconst mu4e~compose-buffer-max-name-length 30
|
||||
@ -312,12 +316,7 @@ appear on disk."
|
||||
(truncate-string-to-width str
|
||||
mu4e~compose-buffer-max-name-length
|
||||
nil nil t)))))
|
||||
|
||||
(defconst mu4e~compose-hidden-headers
|
||||
'("^References:" "^Face:" "^X-Face:" "^X-Draft-From:"
|
||||
"^User-Agent:" "^In-Reply-To:")
|
||||
"List of regexps with message headers that are to be hidden.")
|
||||
|
||||
|
||||
(defun mu4e~compose-handler (compose-type &optional original-msg includes)
|
||||
"Create a new draft message, or open an existing one.
|
||||
|
||||
@ -371,8 +370,7 @@ tempfile)."
|
||||
(set (make-local-variable 'mu4e-compose-parent-message) original-msg)
|
||||
(put 'mu4e-compose-parent-message 'permanent-local t)
|
||||
;; hide some headers
|
||||
(let ((message-hidden-headers mu4e~compose-hidden-headers))
|
||||
(message-hide-headers))
|
||||
(mu4e~compose-hide-headers)
|
||||
;; switch on the mode
|
||||
(mu4e-compose-mode))
|
||||
|
||||
|
||||
@ -102,7 +102,7 @@ e-mail addresses. If LST is nil, returns nil."
|
||||
(let ((name (car addrcell))
|
||||
(email (cdr addrcell)))
|
||||
(if name
|
||||
(format "\"%s\" <%s>" name email)
|
||||
(format "%s <%s>" (mu4e~rfc822-quoteit name) email)
|
||||
(format "%s" email))))
|
||||
lst ", ")))
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
;; mu4e-mark.el -- part of mu4e, the mu mail user agent
|
||||
;;
|
||||
;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2011-2013 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
@ -82,6 +82,24 @@ where
|
||||
"Clear the marks subsystem."
|
||||
(clrhash mu4e~mark-map))
|
||||
|
||||
|
||||
(defmacro mu4e~mark-in-context (&rest body)
|
||||
"Evaluate BODY in the context of the headers buffer in case this
|
||||
is either a headers or view buffer, and "
|
||||
`(cond
|
||||
((eq major-mode 'mu4e-headers-mode) ,@body)
|
||||
((eq major-mode 'mu4e-view-mode)
|
||||
(if (buffer-live-p mu4e~view-headers-buffer)
|
||||
(let* ((msg (mu4e-message-at-point))
|
||||
(docid (mu4e-message-field msg :docid)))
|
||||
(with-current-buffer mu4e~view-headers-buffer
|
||||
(if (mu4e~headers-goto-docid docid)
|
||||
,@body
|
||||
(mu4e-error "cannot find message in headers buffer."))))
|
||||
(mu4e-error "no headers buffer connected to view")))
|
||||
(t (progn (mu4e-message "%S" major-mode) ,@body))))
|
||||
|
||||
|
||||
(defun mu4e-mark-at-point (mark &optional target)
|
||||
"Mark (or unmark) message at point.
|
||||
MARK specifies the mark-type. For `move'-marks and `trash'-marks
|
||||
@ -229,19 +247,19 @@ as well."
|
||||
If there are such marks, replace them with a _real_ mark (ask the
|
||||
user which one)."
|
||||
(interactive)
|
||||
(let ((markpair))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(let ((mark (car val)) (target (cdr val)))
|
||||
(when (eql mark 'something)
|
||||
(unless markpair
|
||||
(setq markpair
|
||||
(mu4e~mark-get-markpair "Set deferred mark(s) to: " nil)))
|
||||
(save-excursion
|
||||
(when (mu4e~headers-goto-docid docid)
|
||||
(mu4e-mark-set (car markpair) (cdr markpair)))))))
|
||||
mu4e~mark-map)))
|
||||
|
||||
(mu4e~mark-in-context
|
||||
(let ((markpair))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(let ((mark (car val)) (target (cdr val)))
|
||||
(when (eql mark 'something)
|
||||
(unless markpair
|
||||
(setq markpair
|
||||
(mu4e~mark-get-markpair "Set deferred mark(s) to: " nil)))
|
||||
(save-excursion
|
||||
(when (mu4e~headers-goto-docid docid)
|
||||
(mu4e-mark-set (car markpair) (cdr markpair)))))))
|
||||
mu4e~mark-map))))
|
||||
|
||||
(defun mu4e~mark-check-target (target)
|
||||
"Check if the target exists if not, offer to create it."
|
||||
@ -264,46 +282,48 @@ work well.
|
||||
|
||||
If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
|
||||
(interactive)
|
||||
(let ((marknum (hash-table-count mu4e~mark-map)))
|
||||
(if (zerop marknum)
|
||||
(message "Nothing is marked")
|
||||
(mu4e-mark-resolve-deferred-marks)
|
||||
(when (or no-confirmation
|
||||
(y-or-n-p
|
||||
(format "Are you sure you want to execute %d mark%s?"
|
||||
marknum (if (> marknum 1) "s" ""))))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(let ((mark (car val)) (target (cdr val)))
|
||||
;; note: whenever you do something with the message,
|
||||
;; it looses its N (new) flag
|
||||
(case mark
|
||||
(refile (mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))
|
||||
(delete (mu4e~proc-remove docid))
|
||||
(flag (mu4e~proc-move docid nil "+F-u-N"))
|
||||
(move (mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))
|
||||
(read (mu4e~proc-move docid nil "+S-u-N"))
|
||||
(trash (mu4e~proc-move docid (mu4e~mark-check-target target) "+T-N"))
|
||||
(unflag (mu4e~proc-move docid nil "-F-N"))
|
||||
(unread (mu4e~proc-move docid nil "-S+u-N"))
|
||||
(otherwise (mu4e-error "Unrecognized mark %S" mark)))))
|
||||
mu4e~mark-map))
|
||||
(mu4e-mark-unmark-all)
|
||||
(message nil))))
|
||||
(mu4e~mark-in-context
|
||||
(let ((marknum (hash-table-count mu4e~mark-map)))
|
||||
(if (zerop marknum)
|
||||
(message "Nothing is marked")
|
||||
(mu4e-mark-resolve-deferred-marks)
|
||||
(when (or no-confirmation
|
||||
(y-or-n-p
|
||||
(format "Are you sure you want to execute %d mark%s?"
|
||||
marknum (if (> marknum 1) "s" ""))))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(let ((mark (car val)) (target (cdr val)))
|
||||
;; note: whenever you do something with the message,
|
||||
;; it looses its N (new) flag
|
||||
(case mark
|
||||
(refile (mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))
|
||||
(delete (mu4e~proc-remove docid))
|
||||
(flag (mu4e~proc-move docid nil "+F-u-N"))
|
||||
(move (mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))
|
||||
(read (mu4e~proc-move docid nil "+S-u-N"))
|
||||
(trash (mu4e~proc-move docid (mu4e~mark-check-target target) "+T-N"))
|
||||
(unflag (mu4e~proc-move docid nil "-F-N"))
|
||||
(unread (mu4e~proc-move docid nil "-S+u-N"))
|
||||
(otherwise (mu4e-error "Unrecognized mark %S" mark)))))
|
||||
mu4e~mark-map))
|
||||
(mu4e-mark-unmark-all)
|
||||
(message nil)))))
|
||||
|
||||
(defun mu4e-mark-unmark-all ()
|
||||
"Unmark all marked messages."
|
||||
(interactive)
|
||||
(when (or (null mu4e~mark-map) (zerop (hash-table-count mu4e~mark-map)))
|
||||
(mu4e-warn "Nothing is marked"))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(save-excursion
|
||||
(when (mu4e~headers-goto-docid docid)
|
||||
(mu4e-mark-set 'unmark))))
|
||||
mu4e~mark-map)
|
||||
;; in any case, clear the marks map
|
||||
(mu4e~mark-clear))
|
||||
(mu4e~mark-in-context
|
||||
(when (or (null mu4e~mark-map) (zerop (hash-table-count mu4e~mark-map)))
|
||||
(mu4e-warn "Nothing is marked"))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(save-excursion
|
||||
(when (mu4e~headers-goto-docid docid)
|
||||
(mu4e-mark-set 'unmark))))
|
||||
mu4e~mark-map)
|
||||
;; in any case, clear the marks map
|
||||
(mu4e~mark-clear)))
|
||||
|
||||
(defun mu4e-mark-docid-marked-p (docid)
|
||||
"Is the given docid marked?"
|
||||
@ -313,25 +333,27 @@ If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
|
||||
(defun mu4e-mark-marks-num ()
|
||||
"Return the number of marks in the current buffer."
|
||||
(if mu4e~mark-map (hash-table-count mu4e~mark-map) 0))
|
||||
|
||||
|
||||
(defun mu4e-mark-handle-when-leaving ()
|
||||
"If there are any marks in the current buffer, handle those
|
||||
according to the value of `mu4e-headers-leave-behavior'. This
|
||||
function is to be called before any further action (like searching,
|
||||
quiting the buffer) is taken; returning t means 'take the following
|
||||
action', return nil means 'don't do anything'"
|
||||
(let ((marknum (mu4e-mark-marks-num))
|
||||
(what mu4e-headers-leave-behavior))
|
||||
(unless (zerop marknum) ;; nothing to do?
|
||||
(when (eq what 'ask)
|
||||
(setq what (mu4e-read-option
|
||||
(format "There are %d existing mark(s); should we: " marknum)
|
||||
'( ("apply marks" . apply)
|
||||
("ignore marks?" . ignore)))))
|
||||
;; we determined what to do... now do it
|
||||
(when (eq what 'apply)
|
||||
(mu4e-mark-execute-all t)))))
|
||||
|
||||
action', return nil means 'don't do anything'."
|
||||
(mu4e~mark-in-context
|
||||
(let ((marknum (mu4e-mark-marks-num))
|
||||
(what mu4e-headers-leave-behavior))
|
||||
(unless (zerop marknum) ;; nothing to do?
|
||||
(when (eq what 'ask)
|
||||
(setq what (mu4e-read-option
|
||||
(format "There are %d existing mark(s); should we: " marknum)
|
||||
'( ("apply marks" . apply)
|
||||
("ignore marks?" . ignore)))))
|
||||
;; we determined what to do... now do it
|
||||
(when (eq what 'apply)
|
||||
(mu4e-mark-execute-all t))))))
|
||||
|
||||
|
||||
(provide 'mu4e-mark)
|
||||
;; End of mu4e-mark.el
|
||||
|
||||
@ -553,13 +553,14 @@ process."
|
||||
|
||||
(defun mu4e~rfc822-phrase-type (ph)
|
||||
"Return either atom, quoted-string, a corner-case or nil. This
|
||||
checks for quotes around the phrase first
|
||||
checks for empty string first. Then quotes around the phrase
|
||||
(returning 'rfc822-quoted-string). Then whether there is a quote
|
||||
inside the phrase (returning 'rfc822-containing-quote).
|
||||
The reverse of the RFC atext definition is then tested.
|
||||
If it matches, nil is returned, if not, it is an 'rfc822-atom, which
|
||||
is returned."
|
||||
(cond
|
||||
((= (length ph) 0) 'rfc822-empty)
|
||||
((= (aref ph 0) ?\")
|
||||
(if (string-match "\"\\([^\"\\\n]\\|\\\\.\\|\\\\\n\\)*\"" ph)
|
||||
'rfc822-quoted-string
|
||||
|
||||
@ -780,10 +780,10 @@ Also number them so they can be opened using `mu4e-view-go-to-url'."
|
||||
|
||||
|
||||
(defmacro mu4e~view-in-headers-context (&rest body)
|
||||
"Evaluate BODY in the current headers buffer, with moved to the
|
||||
current message."
|
||||
"Evaluate BODY in the context of the headers buffer connected to
|
||||
this view."
|
||||
`(progn
|
||||
(unless '(buffer-live-p mu4e~view-headers-buffer)
|
||||
(unless (buffer-live-p mu4e~view-headers-buffer)
|
||||
(mu4e-error "no headers-buffer connected"))
|
||||
(let* ((msg (mu4e-message-at-point))
|
||||
(docid (mu4e-message-field msg :docid)))
|
||||
|
||||
@ -732,7 +732,7 @@ respectively. In the example, we use @code{:human-date}, which shows when the
|
||||
time when the message was sent today, and the date otherwise.
|
||||
@item The header field used for sorting is indicated by ``@t{V}'' or
|
||||
``@t{^}''@footnote{or you can use little graphical triangles; see variable
|
||||
@code{mu4e-use-fancy-chars}}, indicating the sort order (descending or
|
||||
@code{mu4e-use-fancy-chars}}, corresponding to the sort order (descending or
|
||||
ascending, respectively). You can influence this by a mouse click, or
|
||||
@key{O}. Not all fields allow sorting.
|
||||
@item Instead of showing the @t{From:} and @t{To:} fields separately, you
|
||||
@ -757,7 +757,7 @@ u=@emph{unread}. The tooltip for this field also contains this information.
|
||||
Jamie Zawinski's mail threading algorithm,
|
||||
@url{http://www.jwz.org/doc/threading.html}}.
|
||||
@item The headers view is @emph{automatically updated} if any changes are
|
||||
found during the indexing process, and if there is not current
|
||||
found during the indexing process, and if there is no current
|
||||
user-interaction. If you do not want such automatic updates, set
|
||||
@code{mu4e-headers-auto-update} to @code{nil}.
|
||||
@end itemize
|
||||
@ -1134,8 +1134,8 @@ is used for images.
|
||||
@section Displaying rich-text messages
|
||||
|
||||
@t{mu4e} normally prefers the plain-text version for messages that consist of
|
||||
both a plain-text and html (rich-text) versions of the body-text. You change
|
||||
this by setting @code{mu4e-view-prefer-html} to @t{t}.
|
||||
both a plain-text and html (rich-text) versions of the body-text. You can
|
||||
change this by setting @code{mu4e-view-prefer-html} to @t{t}.
|
||||
|
||||
If there is only an html-version, or if the plain-text version is too short in
|
||||
comparison with the html part@footnote{this is for the case where the
|
||||
@ -1225,7 +1225,8 @@ For more information, see the @command{mu-verify} manual page.
|
||||
@section Actions
|
||||
|
||||
You can perform custom functions (``actions'') on messages and their
|
||||
attachments. For a general discussion on how to define your own, see see @ref{Actions}.
|
||||
attachments. For a general discussion on how to define your own, see see
|
||||
@ref{Actions}.
|
||||
|
||||
@subsection Message actions
|
||||
|
||||
@ -2403,16 +2404,17 @@ shortcut character @key{o} is due to the first character of
|
||||
The @command{emacs}-package @t{sauron}@footnote{Sauron can be found at
|
||||
@url{https://github.com/djcb/sauron}, or in the Marmalade package-repository
|
||||
at @url{http://http://marmalade-repo.org/}} (by the same author) can be used
|
||||
to get notifications about new mails. If you put something like the below
|
||||
script in your @t{crontab} (or have some other way of having it execute every
|
||||
@emph{n} minutes) you receive notifications in the sauron-buffer when new
|
||||
messages arrive.
|
||||
to get notifications about new mails. If you run something like the below
|
||||
script from your @t{crontab} (or have some other way of having it execute
|
||||
every @emph{n} minutes), you receive notifications in the @t{sauron}-buffer
|
||||
when new messages arrive.
|
||||
|
||||
@verbatim
|
||||
#!/bin/sh
|
||||
# put the path to your Inbox folder here
|
||||
|
||||
# put the path to your Inbox folder here
|
||||
CHECKDIR="/home/$LOGNAME/Maildir/Inbox"
|
||||
|
||||
sauron-msg () {
|
||||
DBUS_COOKIE="/home/$LOGNAME/.sauron-dbus"
|
||||
if test "x$DBUS_SESSION_BUS_ADDRESS" = "x"; then
|
||||
@ -3011,7 +3013,7 @@ normal, synchronous fashion.
|
||||
@section Known issues
|
||||
|
||||
Although they are not really @emph{questions}, we end this chapter with a list
|
||||
of known issue and/or missing features in @t{mu4e}. Thus, users won't have to
|
||||
of known issues and/or missing features in @t{mu4e}. Thus, users won't have to
|
||||
search in vain for things that are not there (yet), and the author can use it
|
||||
as a todo-list.
|
||||
|
||||
@ -3020,11 +3022,24 @@ as a todo-list.
|
||||
utf-8}; so, if you problems with encodings, be sure to have
|
||||
@code{(set-language-environment "UTF-8")} in your @file{~/.emacs}.
|
||||
@item @emph{Thread handling is incomplete.} While threads are calculated and are
|
||||
visible in the headers buffer, you can not collapse/open them.
|
||||
visible in the headers buffer, you cannot collapse/open them.
|
||||
@item @emph{The key-bindings are @emph{somewhat} hard-coded.} That is, the main
|
||||
menu assumes the default key-bindings, as do the clicks-on-bookmarks.
|
||||
@item @emph{The @t{emacs} front-end of the @t{notmuch} e-mail indexer
|
||||
conflicts with @t{mu4e}}. @t{notmuch} running in parallel with
|
||||
@t{mu4e} leads to
|
||||
@verbatim
|
||||
error in process filter: mu4e-error-handler: Error 70: cannot read
|
||||
~/Maildir/...
|
||||
@end verbatim
|
||||
when sending a reply to a new e-mail. This seems to be caused by @t{notmuch}
|
||||
changing the name of the original message file while @t{mu4e} is working in on
|
||||
it. To prevent this, deactivate @t{notmuch} in your Emacs setup.
|
||||
@end itemize
|
||||
|
||||
For a more complete list, please refer to the issues-list in the
|
||||
github-repository.
|
||||
|
||||
|
||||
@node Tips and Tricks
|
||||
@appendix Tips and Tricks
|
||||
@ -3195,7 +3210,8 @@ If you have multiple accounts, you can accommodate them as well:
|
||||
((string-match "Account1" maildir)
|
||||
(setq folder (or (catch 'found
|
||||
(dolist (mailing-list my-mu4e-mailing-lists)
|
||||
(if (mu4e-message-contact-field-matches msg :to (car mailing-list))
|
||||
(if (mu4e-message-contact-field-matches
|
||||
msg :to (car mailing-list))
|
||||
(throw 'found (cdr mailing-list)))))
|
||||
"/Account1/General")))
|
||||
((string-match "Gmail" maildir)
|
||||
@ -3203,7 +3219,8 @@ If you have multiple accounts, you can accommodate them as well:
|
||||
((string-match "Account2" maildir)
|
||||
(setq folder (or (cdar (member* subject my-mu4e-subject-alist
|
||||
:test #'(lambda (x y)
|
||||
(string-match (car y) x))))
|
||||
(string-match
|
||||
(car y) x))))
|
||||
"/Account2/General"))))
|
||||
folder))
|
||||
@end lisp
|
||||
@ -3216,10 +3233,12 @@ message based on the mailing list to which it was sent. This requires
|
||||
another variable:
|
||||
|
||||
@lisp
|
||||
(defvar my-mu4e-mailing-lists '(("mu-discuss@@googlegroups.com" . "/Account1/mu4e")
|
||||
("pandoc-discuss@@googlegroups.com" . "/Account1/Pandoc")
|
||||
("auctex@@gnu.org" . "/Account1/AUCTeX"))
|
||||
"List of mailing list addresses and folders where their messages are saved.")
|
||||
(defvar my-mu4e-mailing-lists
|
||||
'(("mu-discuss@@googlegroups.com" . "/Account1/mu4e")
|
||||
("pandoc-discuss@@googlegroups.com" . "/Account1/Pandoc")
|
||||
("auctex@@gnu.org" . "/Account1/AUCTeX"))
|
||||
"List of mailing list addresses and folders where
|
||||
their messages are saved.")
|
||||
@end lisp
|
||||
|
||||
@node Saving outgoing messages
|
||||
|
||||
Reference in New Issue
Block a user