mirror of https://github.com/djcb/mu.git
mu4e: update to use server maildir/database/addresses
Mkae mu4e-maildir and mu4e-personal-addresses obsolete, we get those from the server.
This commit is contained in:
parent
dea4789e0e
commit
e1e26d1da2
|
@ -577,7 +577,8 @@ cmd_init (MuConfig *opts, GError **err)
|
|||
if (!opts->quiet) {
|
||||
mu_store_print_info (store, opts->nocolor);
|
||||
g_print ("\nstore created.\n"
|
||||
"now you can use the index command to index some messages.\n"
|
||||
"use 'mu index' to fill the database "
|
||||
"with your messsages.\n"
|
||||
"see mu-index(1) for details\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -323,7 +323,6 @@ Example: +tag,+long tag,-oldtag
|
|||
would add 'tag' and 'long tag', and remove 'oldtag'."
|
||||
(let* (
|
||||
(path (mu4e-message-field msg :path))
|
||||
(maildir (mu4e-message-field msg :maildir))
|
||||
(oldtags (mu4e-message-field msg :tags))
|
||||
(tags-completion
|
||||
(append
|
||||
|
@ -369,7 +368,7 @@ would add 'tag' and 'long tag', and remove 'oldtag'."
|
|||
path))
|
||||
|
||||
(mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", ")))
|
||||
(mu4e-refresh-message path maildir)))
|
||||
(mu4e-refresh-message path)))
|
||||
|
||||
(defun mu4e-action-show-thread (msg)
|
||||
"Show thread for message at point with point remaining on MSG.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;; mu4e-compose.el -- part of mu4e, the mu mail user agent for emacs -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2011-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
@ -260,8 +260,8 @@ If needed, set the Fcc header, and register the handler function."
|
|||
`mu4e-sent-messages-behavior'"
|
||||
mu4e-sent-messages-behavior))))
|
||||
(fccfile (and mdir
|
||||
(concat mu4e-maildir mdir "/cur/"
|
||||
(mu4e~draft-message-filename-construct "S")))))
|
||||
(concat (mu4e-root-maildir) mdir "/cur/"
|
||||
(mu4e~draft-message-filename-construct "S")))))
|
||||
;; if there's an fcc header, add it to the file
|
||||
(when fccfile
|
||||
(message-add-header (concat "Fcc: " fccfile "\n"))
|
||||
|
@ -273,7 +273,7 @@ If needed, set the Fcc header, and register the handler function."
|
|||
(old-handler message-fcc-handler-function))
|
||||
(lambda (file)
|
||||
(setq message-fcc-handler-function old-handler) ;; reset the fcc handler
|
||||
(let ((mdir-path (concat mu4e-maildir maildir)))
|
||||
(let ((mdir-path (concat (mu4e-root-maildir) maildir)))
|
||||
;; Create the full maildir structure for the sent folder if it doesn't exist.
|
||||
;; `mu4e~proc-mkdir` runs asynchronously but no matter whether it runs before or after
|
||||
;; `write-file`, the sent maildir ends up in the correct state.
|
||||
|
@ -817,8 +817,8 @@ draft message."
|
|||
;; as default emacs mailer (define-mail-user-agent etc.)
|
||||
|
||||
;;;###autoload
|
||||
(defun mu4e~compose-mail (&optional to subject other-headers continue
|
||||
switch-function yank-action send-actions return-action)
|
||||
(defun mu4e~compose-mail (&optional to subject other-headers _continue
|
||||
_switch-function yank-action _send-actions _return-action)
|
||||
"This is mu4e's implementation of `compose-mail'.
|
||||
Quoting its docstring:
|
||||
Start composing a mail message to send.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; mu4e-context.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2015-2016 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2015-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
@ -31,14 +31,11 @@
|
|||
(defvar smtpmail-smtp-user)
|
||||
(defvar mu4e-view-date-format)
|
||||
|
||||
(defcustom mu4e-contexts nil "The list of `mu4e-context' objects
|
||||
describing mu4e's contexts."
|
||||
:group 'mu4e)
|
||||
(defvar mu4e-contexts nil "The list of `mu4e-context' objects
|
||||
describing mu4e's contexts.")
|
||||
|
||||
(defcustom mu4e-context-changed-hook nil
|
||||
"Hook run just *after* the context changed."
|
||||
:type 'hook
|
||||
:group 'mu4e-headers)
|
||||
(defvar mu4e-context-changed-hook nil
|
||||
"Hook run just *after* the context changed.")
|
||||
|
||||
(defvar mu4e~context-current nil
|
||||
"The current context; for internal use. Use
|
||||
|
@ -238,8 +235,7 @@ non-nil."
|
|||
(set (car cell) (cdr cell)))
|
||||
(mu4e-context-vars context)))
|
||||
(setq mu4e~context-current context)
|
||||
(unless (eq mu4e-split-view 'single-window)
|
||||
(mu4e~main-view-real nil nil))
|
||||
|
||||
(run-hooks 'mu4e-context-changed-hook)
|
||||
(mu4e-message "Switched context to %s" (mu4e-context-name context)))
|
||||
context))
|
||||
|
@ -248,7 +244,7 @@ non-nil."
|
|||
"When contexts are defined but there is no context yet, switch
|
||||
to the first whose :match-func return non-nil. If none of them
|
||||
match, return the first. For MSG and POLICY, see `mu4e-context-determine'."
|
||||
(when mu4e-contexts
|
||||
(when (and mu4e-contexts (not mu4e~context-current))
|
||||
(let ((context (mu4e-context-determine msg policy)))
|
||||
(when context (mu4e-context-switch
|
||||
nil (mu4e-context-name context))))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; mu4e-contrib.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2013-2016 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2013-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
;;
|
||||
|
@ -20,7 +20,10 @@
|
|||
;;; Commentary:
|
||||
|
||||
;; Some user-contributed functions for mu4e
|
||||
|
||||
(require 'mu4e-headers)
|
||||
(require 'mu4e-view)
|
||||
(require 'bookmark)
|
||||
(require 'eshell)
|
||||
|
||||
;; Contributed by sabof
|
||||
(defvar bookmark-make-record-function)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;; mu4e-draft.el -- part of mu4e, the mu mail user agent for emacs -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2011-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
(defcustom mu4e-compose-dont-reply-to-self nil
|
||||
"If non-nil, don't include self.
|
||||
\(that is, member of `mu4e-user-mail-address-list') in replies."
|
||||
\(that is, member of `(mu4e-personal-addresses)') in replies."
|
||||
:type 'boolean
|
||||
:group 'mu4e-compose)
|
||||
|
||||
|
@ -189,7 +189,7 @@ of the original, we simple copy the list form the original."
|
|||
(cl-member-if
|
||||
(lambda (addr)
|
||||
(string= (downcase addr) (downcase (cdr to-cell))))
|
||||
mu4e-user-mail-address-list))
|
||||
(mu4e-personal-addresses)))
|
||||
reply-to)
|
||||
reply-to)))
|
||||
|
||||
|
@ -253,7 +253,7 @@ REPLY-ALL."
|
|||
(cl-member-if
|
||||
(lambda (addr)
|
||||
(string= (downcase addr) (downcase (cdr cc-cell))))
|
||||
mu4e-user-mail-address-list))
|
||||
(mu4e-personal-addresses)))
|
||||
cc-lst))))
|
||||
cc-lst)))
|
||||
|
||||
|
@ -540,7 +540,7 @@ This is based on `mu4e-drafts-folder', which is evaluated once.")
|
|||
(defun mu4e~draft-determine-path (draft-dir)
|
||||
"Determines the path for a new draft file in DRAFT-DIR."
|
||||
(format "%s/%s/cur/%s"
|
||||
mu4e-maildir draft-dir (mu4e~draft-message-filename-construct "DS")))
|
||||
(mu4e-root-maildir) draft-dir (mu4e~draft-message-filename-construct "DS")))
|
||||
|
||||
|
||||
(defun mu4e-draft-open (compose-type &optional msg)
|
||||
|
@ -550,12 +550,11 @@ In case of a new message (when COMPOSE-TYPE is `reply', `forward'
|
|||
or re-send an existing message (when COMPOSE-TYPE is `resend').
|
||||
|
||||
The name of the draft folder is constructed from the
|
||||
concatenation of `mu4e-maildir' and `mu4e-drafts-folder' (the
|
||||
concatenation of `(mu4e-root-maildir)' and `mu4e-drafts-folder' (the
|
||||
latter will be evaluated). The message file name is a unique name
|
||||
determined by `mu4e-send-draft-file-name'. The initial contents
|
||||
will be created from either `mu4e~draft-reply-construct', or
|
||||
`mu4e~draft-forward-construct' or `mu4e~draft-newmsg-construct'."
|
||||
(unless mu4e-maildir (mu4e-error "Variable mu4e-maildir not set"))
|
||||
(let ((draft-dir nil))
|
||||
(cl-case compose-type
|
||||
|
||||
|
|
1038
mu4e/mu4e-headers.el
1038
mu4e/mu4e-headers.el
File diff suppressed because it is too large
Load Diff
|
@ -42,6 +42,9 @@
|
|||
(require 'gnus-icalendar)
|
||||
(require 'cl-lib)
|
||||
|
||||
(eval-when-compile (require 'mu4e-mark))
|
||||
(eval-when-compile (require 'mu4e-vars))
|
||||
|
||||
;;;###autoload
|
||||
(defun mu4e-icalendar-setup ()
|
||||
"Perform the necessary initialization to use mu4e-icalendar."
|
||||
|
@ -49,34 +52,34 @@
|
|||
(cl-defmethod gnus-icalendar-event:inline-reply-buttons :around
|
||||
((event gnus-icalendar-event) handle)
|
||||
(if (and (boundp 'mu4e~view-rendering)
|
||||
(gnus-icalendar-event:rsvp event))
|
||||
(let ((method (gnus-icalendar-event:method event)))
|
||||
(when (or (string= method "REQUEST") (string= method "PUBLISH"))
|
||||
`(("Accept" mu4e-icalendar-reply (,handle accepted ,event))
|
||||
("Tentative" mu4e-icalendar-reply (,handle tentative ,event))
|
||||
("Decline" mu4e-icalendar-reply (,handle declined ,event)))))
|
||||
(gnus-icalendar-event:rsvp event))
|
||||
(let ((method (gnus-icalendar-event:method event)))
|
||||
(when (or (string= method "REQUEST") (string= method "PUBLISH"))
|
||||
`(("Accept" mu4e-icalendar-reply (,handle accepted ,event))
|
||||
("Tentative" mu4e-icalendar-reply (,handle tentative ,event))
|
||||
("Decline" mu4e-icalendar-reply (,handle declined ,event)))))
|
||||
(cl-call-next-method event handle))))
|
||||
|
||||
(defun mu4e-icalendar-reply (data)
|
||||
"Reply to the text/calendar event present in DATA."
|
||||
;; Based on `gnus-icalendar-reply'.
|
||||
(let* ((handle (car data))
|
||||
(status (cadr data))
|
||||
(event (caddr data))
|
||||
(gnus-icalendar-additional-identities mu4e-user-mail-address-list)
|
||||
(reply (gnus-icalendar-with-decoded-handle handle
|
||||
(gnus-icalendar-event-reply-from-buffer
|
||||
(current-buffer) status (gnus-icalendar-identities))))
|
||||
(msg (mu4e-message-at-point 'noerror))
|
||||
(charset (cdr (assoc 'charset (mm-handle-type handle)))))
|
||||
(status (cadr data))
|
||||
(event (caddr data))
|
||||
(gnus-icalendar-additional-identities (mu4e-personal-addresses))
|
||||
(reply (gnus-icalendar-with-decoded-handle handle
|
||||
(gnus-icalendar-event-reply-from-buffer
|
||||
(current-buffer) status (gnus-icalendar-identities))))
|
||||
(msg (mu4e-message-at-point 'noerror))
|
||||
(charset (cdr (assoc 'charset (mm-handle-type handle)))))
|
||||
(when reply
|
||||
(cl-labels
|
||||
((fold-icalendar-buffer
|
||||
()
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^\\(.\\{72\\}\\)\\(.+\\)$" nil t)
|
||||
(replace-match "\\1\n \\2")
|
||||
(goto-char (line-beginning-position)))))
|
||||
((fold-icalendar-buffer
|
||||
()
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^\\(.\\{72\\}\\)\\(.+\\)$" nil t)
|
||||
(replace-match "\\1\n \\2")
|
||||
(goto-char (line-beginning-position)))))
|
||||
|
||||
(with-current-buffer (get-buffer-create gnus-icalendar-reply-bufname)
|
||||
(delete-region (point-min) (point-max))
|
||||
|
@ -92,7 +95,7 @@
|
|||
(gnus-icalendar--update-org-event event status))
|
||||
(when mu4e-icalendar-diary-file
|
||||
(mu4e~icalendar-insert-diary event status
|
||||
mu4e-icalendar-diary-file))))))
|
||||
mu4e-icalendar-diary-file))))))
|
||||
|
||||
(defun mu4e~icalendar-delete-citation ()
|
||||
"Function passed to `mu4e-compose-cite-function' to remove the citation."
|
||||
|
@ -104,17 +107,17 @@
|
|||
"See `mu4e-sent-handler' for DOCID and PATH."
|
||||
(mu4e-sent-handler docid path)
|
||||
(let* ((docid (mu4e-message-field original-msg :docid))
|
||||
(markdescr (assq 'trash mu4e-marks))
|
||||
(action (plist-get (cdr markdescr) :action))
|
||||
(target (mu4e-get-trash-folder original-msg)))
|
||||
(markdescr (assq 'trash mu4e-marks))
|
||||
(action (plist-get (cdr markdescr) :action))
|
||||
(target (mu4e-get-trash-folder original-msg)))
|
||||
(with-current-buffer (mu4e-get-headers-buffer)
|
||||
(run-hook-with-args 'mu4e-mark-execute-pre-hook 'trash original-msg)
|
||||
(funcall action docid original-msg target))
|
||||
(when (and (mu4e~headers-view-this-message-p docid)
|
||||
(buffer-live-p (mu4e-get-view-buffer)))
|
||||
(buffer-live-p (mu4e-get-view-buffer)))
|
||||
(switch-to-buffer (mu4e-get-view-buffer))
|
||||
(or (mu4e-view-headers-next)
|
||||
(kill-buffer-and-window))))))
|
||||
(kill-buffer-and-window))))))
|
||||
|
||||
(defun mu4e-icalendar-reply-ical (original-msg event status buffer-name)
|
||||
"Reply to ORIGINAL-MSG containing invitation EVENT with STATUS.
|
||||
|
@ -123,8 +126,8 @@ STATUS values. BUFFER-NAME is the name of the buffer holding the
|
|||
response in icalendar format."
|
||||
(let ((message-signature nil))
|
||||
(let ((mu4e-compose-cite-function #'mu4e~icalendar-delete-citation)
|
||||
(mu4e-sent-messages-behavior 'delete)
|
||||
(mu4e-compose-reply-recipients 'sender))
|
||||
(mu4e-sent-messages-behavior 'delete)
|
||||
(mu4e-compose-reply-recipients 'sender))
|
||||
(mu4e~compose-handler 'reply original-msg))
|
||||
;; Make sure the recipient is the organizer
|
||||
(let ((organizer (gnus-icalendar-event:organizer event)))
|
||||
|
@ -136,23 +139,23 @@ response in icalendar format."
|
|||
(mml-insert-multipart "alternative")
|
||||
(mml-insert-part "text/plain")
|
||||
(let ((reply-event (gnus-icalendar-event-from-buffer
|
||||
buffer-name mu4e-user-mail-address-list)))
|
||||
buffer-name (mu4e-personal-addresses))))
|
||||
(insert (gnus-icalendar-event->gnus-calendar reply-event status)))
|
||||
(forward-line 1); move past closing tag
|
||||
(mml-attach-buffer buffer-name "text/calendar; method=REPLY; charset=utf-8")
|
||||
(message-remove-header "Subject")
|
||||
(message-goto-subject)
|
||||
(insert (capitalize (symbol-name status))
|
||||
": " (gnus-icalendar-event:summary event))
|
||||
": " (gnus-icalendar-event:summary event))
|
||||
(set-buffer-modified-p nil); not yet modified by user
|
||||
(when mu4e-icalendar-trash-after-reply
|
||||
;; Override `mu4e-sent-handler' set by `mu4e-compose-mode' to
|
||||
;; also trash the message (thus must be appended to hooks).
|
||||
(add-hook
|
||||
'message-sent-hook
|
||||
(lambda () (setq mu4e-sent-func
|
||||
(mu4e~icalendar-trash-message original-msg)))
|
||||
t t))))
|
||||
'message-sent-hook
|
||||
(lambda () (setq mu4e-sent-func
|
||||
(mu4e~icalendar-trash-message original-msg)))
|
||||
t t))))
|
||||
|
||||
|
||||
(defun mu4e~icalendar-insert-diary (event reply-status filename)
|
||||
|
@ -161,20 +164,20 @@ REPLY-STATUS is the status of the reply. The possible values are
|
|||
given in the doc of `gnus-icalendar-event-reply-from-buffer'."
|
||||
;; FIXME: handle recurring events
|
||||
(let* ((beg (gnus-icalendar-event:start-time event))
|
||||
(beg-date (format-time-string "%d/%m/%Y" beg))
|
||||
(beg-time (format-time-string "%H:%M" beg))
|
||||
(end (gnus-icalendar-event:end-time event))
|
||||
(end-date (format-time-string "%d/%m/%Y" end))
|
||||
(end-time (format-time-string "%H:%M" end))
|
||||
(summary (gnus-icalendar-event:summary event))
|
||||
(location (gnus-icalendar-event:location event))
|
||||
(status (capitalize (symbol-name reply-status)))
|
||||
(txt (if location
|
||||
(format "%s (%s)\n %s " summary status location)
|
||||
(format "%s (%s)" summary status))))
|
||||
(beg-date (format-time-string "%d/%m/%Y" beg))
|
||||
(beg-time (format-time-string "%H:%M" beg))
|
||||
(end (gnus-icalendar-event:end-time event))
|
||||
(end-date (format-time-string "%d/%m/%Y" end))
|
||||
(end-time (format-time-string "%H:%M" end))
|
||||
(summary (gnus-icalendar-event:summary event))
|
||||
(location (gnus-icalendar-event:location event))
|
||||
(status (capitalize (symbol-name reply-status)))
|
||||
(txt (if location
|
||||
(format "%s (%s)\n %s " summary status location)
|
||||
(format "%s (%s)" summary status))))
|
||||
(with-temp-buffer
|
||||
(if (string= beg-date end-date)
|
||||
(insert beg-date " " beg-time "-" end-time " " txt "\n")
|
||||
(insert beg-date " " beg-time "-" end-time " " txt "\n")
|
||||
(insert beg-date " " beg-time " Start of: " txt "\n")
|
||||
(insert beg-date " " end-time " End of: " txt "\n"))
|
||||
(write-region (point-min) (point-max) filename t))))
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
(require 'smtpmail) ;; the queueing stuff (silence elint)
|
||||
(require 'mu4e-utils) ;; utility functions
|
||||
(require 'mu4e-context) ;; the context
|
||||
(require 'mu4e-vars) ;; the context
|
||||
(require 'cl-lib)
|
||||
|
||||
(defconst mu4e~main-buffer-name " *mu4e-main*"
|
||||
|
@ -140,22 +141,31 @@ clicked."
|
|||
"\n")))
|
||||
|
||||
|
||||
(defun mu4e~key-val (key val &optional unit)
|
||||
"Return a key / value pair."
|
||||
(concat
|
||||
" * "
|
||||
(propertize (format "%-20s" key) 'face 'mu4e-header-title-face)
|
||||
": "
|
||||
(propertize val 'face 'mu4e-header-key-face)
|
||||
(if unit
|
||||
(propertize (concat " " unit) 'face 'mu4e-header-title-face)
|
||||
"")
|
||||
"\n"))
|
||||
|
||||
;; NEW
|
||||
;; This is the old `mu4e~main-view' function but without
|
||||
;; buffer switching at the end.
|
||||
(defun mu4e~main-view-real (ignore-auto noconfirm)
|
||||
(defun mu4e~main-view-real (_ignore-auto _noconfirm)
|
||||
(let ((buf (get-buffer-create mu4e~main-buffer-name))
|
||||
(inhibit-read-only t))
|
||||
(with-current-buffer buf
|
||||
(erase-buffer)
|
||||
(insert
|
||||
"* "
|
||||
(propertize "mu4e - mu for emacs version " 'face 'mu4e-title-face)
|
||||
(propertize "mu4e" 'face 'mu4e-header-key-face)
|
||||
(propertize " - mu for emacs version " 'face 'mu4e-title-face)
|
||||
(propertize mu4e-mu-version 'face 'mu4e-header-key-face)
|
||||
(propertize "; (in store: " 'face 'mu4e-title-face)
|
||||
(propertize (format "%s" (plist-get mu4e~server-props :doccount)) 'face 'mu4e-header-key-face)
|
||||
(propertize " messages)" 'face 'mu4e-title-face)
|
||||
|
||||
"\n\n"
|
||||
(propertize " Basics\n\n" 'face 'mu4e-title-face)
|
||||
(mu4e~main-action-str
|
||||
|
@ -183,9 +193,15 @@ clicked."
|
|||
(mu4e~main-action-str "\t* [N]ews\n" 'mu4e-news)
|
||||
(mu4e~main-action-str "\t* [A]bout mu4e\n" 'mu4e-about)
|
||||
(mu4e~main-action-str "\t* [H]elp\n" 'mu4e-display-manual)
|
||||
(mu4e~main-action-str "\t* [q]uit\n" 'mu4e-quit))
|
||||
(mu4e-main-mode)
|
||||
)))
|
||||
(mu4e~main-action-str "\t* [q]uit\n" 'mu4e-quit)
|
||||
|
||||
"\n"
|
||||
(propertize " Info\n\n" 'face 'mu4e-title-face)
|
||||
(mu4e~key-val "database-path" (mu4e-database-path))
|
||||
(mu4e~key-val "maildir" (mu4e-root-maildir))
|
||||
(mu4e~key-val "in store"
|
||||
(format "%d" (plist-get mu4e~server-props :doccount)) "messages"))
|
||||
(mu4e-main-mode))))
|
||||
|
||||
(defun mu4e~main-view-queue ()
|
||||
"Display queue-related actions in the main view."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;; mu4e-mark.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2011-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
@ -288,7 +288,7 @@ The following marks are available, and the corresponding props:
|
|||
(target (if (string= (substring target 0 1) "/")
|
||||
target
|
||||
(concat "/" target)))
|
||||
(fulltarget (concat mu4e-maildir target)))
|
||||
(fulltarget (concat (mu4e-root-maildir) target)))
|
||||
(when (or (file-directory-p fulltarget)
|
||||
(and (yes-or-no-p
|
||||
(format "%s does not exist. Create now?" fulltarget))
|
||||
|
@ -368,7 +368,7 @@ user which one)."
|
|||
|
||||
(defun mu4e~mark-check-target (target)
|
||||
"Check if TARGET exists; if not, offer to create it."
|
||||
(let ((fulltarget (concat mu4e-maildir target)))
|
||||
(let ((fulltarget (concat (mu4e-root-maildir) target)))
|
||||
(if (not (mu4e-create-maildir-maybe fulltarget))
|
||||
(mu4e-error "Target dir %s does not exist " fulltarget)
|
||||
target)))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; mu4e-message.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2012-2018 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2012-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
@ -243,11 +243,11 @@ replace with."
|
|||
(with-temp-buffer
|
||||
(insert body)
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "[
’]" nil t)
|
||||
(while (re-search-forward "[
]" nil t)
|
||||
(replace-match
|
||||
(cond
|
||||
((string= (match-string 0) "’") "'")
|
||||
((string= (match-string 0) " ") " ")
|
||||
((string= (match-string 0) "") "'")
|
||||
((string= (match-string 0) " ") " ")
|
||||
(t ""))))
|
||||
(buffer-string)))
|
||||
|
||||
|
@ -282,14 +282,14 @@ expressions, in which case any of those are tried for a match."
|
|||
Checks whether any of the of the contacts in field
|
||||
CFIELD (either :to, :from, :cc or :bcc) of msg MSG matches *me*,
|
||||
that is, any of the e-mail address in
|
||||
`mu4e-user-mail-address-list'. Returns the contact cell that
|
||||
`(mu4e-personal-addresses)'. Returns the contact cell that
|
||||
matched, or nil."
|
||||
(cl-find-if
|
||||
(lambda (cc-cell)
|
||||
(cl-member-if
|
||||
(lambda (addr)
|
||||
(string= (downcase addr) (downcase (cdr cc-cell))))
|
||||
mu4e-user-mail-address-list))
|
||||
(mu4e-personal-addresses)))
|
||||
(mu4e-message-field msg cfield)))
|
||||
|
||||
(defsubst mu4e-message-part-field (msgpart field)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;;; mu4e-org -- Org-links to mu4e messages/queries -*- lexical-binding: t -*-
|
||||
;; Copyright (C) 2012-2019 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2012-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
|
|
@ -180,8 +180,7 @@ The server output is as follows:
|
|||
|
||||
;; received a pong message
|
||||
((plist-get sexp :pong)
|
||||
(funcall mu4e-pong-func
|
||||
(plist-get sexp :props)))
|
||||
(funcall mu4e-pong-func sexp))
|
||||
|
||||
;; received a contacts message
|
||||
;; note: we use 'member', to match (:contacts nil)
|
||||
|
@ -253,11 +252,7 @@ Start the process if needed."
|
|||
(unless (file-executable-p mu4e-mu-binary)
|
||||
(mu4e-error (format "`mu4e-mu-binary' (%S) not found" mu4e-mu-binary)))
|
||||
(let* ((process-connection-type nil) ;; use a pipe
|
||||
(args '("server"))
|
||||
(args (append args (when mu4e-mu-home (list (concat "--muhome=" mu4e-mu-home)))))
|
||||
(args (append args (mapcar (lambda(addr)
|
||||
(format "--my-address=%s" addr))
|
||||
mu4e-user-mail-address-list))))
|
||||
(args '("server")))
|
||||
(setq mu4e~proc-buf "")
|
||||
(setq mu4e~proc-process (apply 'start-process
|
||||
mu4e~proc-name mu4e~proc-name
|
||||
|
@ -395,15 +390,12 @@ or an error."
|
|||
:skip-dups ,skip-dups
|
||||
:include-related ,include-related)))
|
||||
|
||||
(defun mu4e~proc-index (path my-addresses cleanup lazy-check)
|
||||
"Index messages on PATH with possible CLEANUP and LAZY-CHECK.
|
||||
(defun mu4e~proc-index (&optional cleanup lazy-check)
|
||||
"Index messages with possible CLEANUP and LAZY-CHECK.
|
||||
PATH should point to some maildir directory structure.
|
||||
MY-ADDRESSES is a list of 'my' email addresses (see
|
||||
`mu4e-user-mail-address-list')."
|
||||
(mu4e~call-mu `(index
|
||||
:my-addresses ,my-addresses
|
||||
:cleanup ,cleanup
|
||||
:lazy-check ,lazy-check)))
|
||||
(mu4e~call-mu `(index :cleanup ,cleanup :lazy-check ,lazy-check)))
|
||||
|
||||
(defun mu4e~proc-mkdir (path)
|
||||
"Create a new maildir-directory at filesystem PATH."
|
||||
|
@ -447,26 +439,15 @@ Returns either (:update ... ) or (:error ) sexp, which are handled my
|
|||
(unless (or maildir flags)
|
||||
(mu4e-error "At least one of maildir and flags must be specified"))
|
||||
(unless (or (not maildir)
|
||||
(file-exists-p (concat mu4e-maildir "/" maildir "/")))
|
||||
(file-exists-p (concat (mu4e-root-maildir) "/" maildir "/")))
|
||||
(mu4e-error "Target dir does not exist"))
|
||||
(let* ((idparam (mu4e~docid-msgid-param docid-or-msgid))
|
||||
(flagstr
|
||||
(when flags
|
||||
(concat " flags:"
|
||||
(if (stringp flags) flags (mu4e-flags-to-string flags)))))
|
||||
(path
|
||||
(when maildir
|
||||
(format " maildir:%s" (mu4e~escape maildir))))
|
||||
(rename
|
||||
(if (and maildir mu4e-change-filenames-when-moving)
|
||||
"true" "false")))
|
||||
(mu4e~call-mu `(move
|
||||
:docid ,(if (stringp docid-or-msgid) nil docid-or-msgid)
|
||||
:msgid ,(if (stringp docid-or-msgid) docid-or-msgid nil)
|
||||
:flags ,(or flags nil)
|
||||
:maildir ,(or maildir nil)
|
||||
:rename ,(and maildir mu4e-change-filenames-when-moving)
|
||||
:noview ,no-view))))
|
||||
(mu4e~call-mu `(move
|
||||
:docid ,(if (stringp docid-or-msgid) nil docid-or-msgid)
|
||||
:msgid ,(if (stringp docid-or-msgid) docid-or-msgid nil)
|
||||
:flags ,(or flags nil)
|
||||
:maildir ,(or maildir nil)
|
||||
:rename ,(and maildir mu4e-change-filenames-when-moving)
|
||||
:noview ,no-view)))
|
||||
|
||||
(defun mu4e~proc-ping (&optional queries)
|
||||
"Sends a ping to the mu server, expecting a (:pong ...) in response.
|
||||
|
|
|
@ -83,10 +83,10 @@ NODEFAULT, hour and minute fields will be nil if not given."
|
|||
|
||||
(defun mu4e-user-mail-address-p (addr)
|
||||
"If ADDR is one of user's e-mail addresses return t, nil otherwise.
|
||||
User's addresses are set in `mu4e-user-mail-address-list'. Case
|
||||
User's addresses are set in `(mu4e-personal-addresses)'. Case
|
||||
insensitive comparison is used."
|
||||
(when (and addr mu4e-user-mail-address-list
|
||||
(cl-find addr mu4e-user-mail-address-list
|
||||
(when (and addr (mu4e-personal-addresses)
|
||||
(cl-find addr (mu4e-personal-addresses)
|
||||
:test (lambda (s1 s2)
|
||||
(eq t (compare-strings s1 nil nil s2 nil nil t)))))
|
||||
t))
|
||||
|
@ -182,10 +182,10 @@ see its docstring)."
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(defun mu4e~guess-maildir (path)
|
||||
"Guess the maildir for some path, or nil if cannot find it."
|
||||
(let ((idx (string-match mu4e-maildir path)))
|
||||
(let ((idx (string-match (mu4e-root-maildir) path)))
|
||||
(when (and idx (zerop idx))
|
||||
(replace-regexp-in-string
|
||||
mu4e-maildir
|
||||
(mu4e-root-maildir)
|
||||
""
|
||||
(expand-file-name
|
||||
(concat path "/../.."))))))
|
||||
|
@ -322,7 +322,7 @@ Function will return the cdr of the list element."
|
|||
(dolist (dentry dentries)
|
||||
(when (and (booleanp (cadr dentry)) (cadr dentry))
|
||||
(if (file-accessible-directory-p
|
||||
(concat mu4e-maildir "/" mdir "/" (car dentry) "/cur"))
|
||||
(concat (mu4e-root-maildir) "/" mdir "/" (car dentry) "/cur"))
|
||||
(setq dirs (cons (concat mdir (car dentry)) dirs)))
|
||||
(unless (member (car dentry) '("cur" "new" "tmp"))
|
||||
(setq dirs (append dirs (mu4e~get-maildirs-1 path
|
||||
|
@ -332,7 +332,7 @@ Function will return the cdr of the list element."
|
|||
(defvar mu4e-cache-maildir-list nil
|
||||
"Whether to cache the list of maildirs; set it to t if you find
|
||||
that generating the list on the fly is too slow. If you do, you
|
||||
can set `mu4e-maildir-list' to nil to force regenerating the
|
||||
can set `(mu4e-root-maildir)-list' to nil to force regenerating the
|
||||
cache the next time `mu4e-get-maildirs' gets called.")
|
||||
|
||||
(defvar mu4e-maildir-list nil
|
||||
|
@ -344,14 +344,13 @@ relative paths (ie., /archive, /sent etc.). Most of the work is
|
|||
done in `mu4e~get-maildirs-1'. Note, these results are /cached/
|
||||
if `mu4e-cache-maildir-list' is customized to non-nil. In that case,
|
||||
the list of maildirs will not change until you restart mu4e."
|
||||
(unless mu4e-maildir (mu4e-error "`mu4e-maildir' is not defined"))
|
||||
(unless (and mu4e-maildir-list mu4e-cache-maildir-list)
|
||||
(setq mu4e-maildir-list
|
||||
(sort
|
||||
(append
|
||||
(when (file-accessible-directory-p
|
||||
(concat mu4e-maildir "/cur")) '("/"))
|
||||
(mu4e~get-maildirs-1 mu4e-maildir "/"))
|
||||
(concat (mu4e-root-maildir) "/cur")) '("/"))
|
||||
(mu4e~get-maildirs-1 (mu4e-root-maildir) "/"))
|
||||
(lambda (s1 s2) (string< (downcase s1) (downcase s2))))))
|
||||
mu4e-maildir-list)
|
||||
|
||||
|
@ -389,7 +388,7 @@ maildirs under `mu4e-maildir'."
|
|||
"Like `mu4e-ask-maildir', but check for existence of the maildir,
|
||||
and offer to create it if it does not exist yet."
|
||||
(let* ((mdir (mu4e-ask-maildir prompt))
|
||||
(fullpath (concat mu4e-maildir mdir)))
|
||||
(fullpath (concat (mu4e-root-maildir) mdir)))
|
||||
(unless (file-directory-p fullpath)
|
||||
(and (yes-or-no-p
|
||||
(mu4e-format "%s does not exist. Create now?" fullpath))
|
||||
|
@ -724,37 +723,27 @@ completion; for testing/debugging."
|
|||
|
||||
(defun mu4e~check-requirements ()
|
||||
"Check for the settings required for running mu4e."
|
||||
(unless (>= emacs-major-version 23)
|
||||
(mu4e-error "Emacs >= 23.x is required for mu4e"))
|
||||
(unless (>= emacs-major-version 25)
|
||||
(mu4e-error "Emacs >= 25.x is required for mu4e"))
|
||||
(when mu4e~server-props
|
||||
(let ((version (plist-get mu4e~server-props :version))
|
||||
(mux (plist-get mu4e~server-props :mux)))
|
||||
(unless (or (string= version mu4e-mu-version) mux)
|
||||
(mu4e-error "mu server has version %s, but we need %s"
|
||||
version mu4e-mu-version))))
|
||||
(unless (string= (mu4e-server-version) mu4e-mu-version)
|
||||
(mu4e-error "mu server has version %s, but we need %s"
|
||||
(mu4e-server-version) mu4e-mu-version)))
|
||||
(unless (and mu4e-mu-binary (file-executable-p mu4e-mu-binary))
|
||||
(mu4e-error "Please set `mu4e-mu-binary' to the full path to the mu
|
||||
binary."))
|
||||
(unless mu4e-maildir
|
||||
(mu4e-error "Please set `mu4e-maildir' to the full path to your
|
||||
Maildir directory."))
|
||||
;; expand mu4e-maildir, mu4e-attachment-dir
|
||||
(setq mu4e-maildir (expand-file-name mu4e-maildir))
|
||||
(unless (mu4e-create-maildir-maybe mu4e-maildir)
|
||||
(mu4e-error "%s is not a valid maildir directory" mu4e-maildir))
|
||||
(dolist (var '(mu4e-sent-folder mu4e-drafts-folder
|
||||
mu4e-trash-folder))
|
||||
(unless (and (boundp var) (symbol-value var))
|
||||
(mu4e-error "Please set %S" var))
|
||||
(unless (functionp (symbol-value var)) ;; functions are okay, too
|
||||
(let* ((dir (symbol-value var))
|
||||
(path (concat mu4e-maildir dir)))
|
||||
(path (concat (mu4e-root-maildir) dir)))
|
||||
(unless (string= (substring dir 0 1) "/")
|
||||
(mu4e-error "%S must start with a '/'" dir))
|
||||
(unless (mu4e-create-maildir-maybe path)
|
||||
(mu4e-error "%s (%S) does not exist" path var))))))
|
||||
|
||||
|
||||
(defun mu4e-running-p ()
|
||||
"Whether mu4e is running.
|
||||
Checks whether the server process is live."
|
||||
|
@ -787,14 +776,15 @@ nothing."
|
|||
mu4e-compose-complete-only-after
|
||||
mu4e~contacts-tstamp)))
|
||||
|
||||
(defun mu4e~pong-handler (props func)
|
||||
(defun mu4e~pong-handler (data func)
|
||||
"Handle 'pong' responses from the mu server."
|
||||
(setq mu4e~server-props props) ;; save props from the server
|
||||
(let ((doccount (plist-get props :doccount)))
|
||||
(setq mu4e~server-props (plist-get data :props)) ;; save info from the server
|
||||
(let ((doccount (plist-get mu4e~server-props :doccount)))
|
||||
(mu4e~check-requirements)
|
||||
(mu4e~context-autoswitch nil mu4e-context-policy)
|
||||
(when func (funcall func))
|
||||
(when (zerop doccount)
|
||||
(mu4e-message "Store is empty; (re)indexing. This can take a while.") ;
|
||||
(mu4e-message "Store is empty; (re)indexing. This may take a while.") ;
|
||||
(mu4e-update-index))
|
||||
(when (and mu4e-update-interval (null mu4e~update-timer))
|
||||
(setq mu4e~update-timer
|
||||
|
@ -811,11 +801,6 @@ non-nil). Otherwise, check various requireme`'nts, then start mu4e.
|
|||
When successful, call FUNC (if non-nil) afterwards."
|
||||
;; if we're already running, simply go to the main view
|
||||
(unless (mu4e-running-p) ;; already running?
|
||||
;; no! try to set a context, do some checks, set up pong handler and ping
|
||||
;; the server maybe switch the context
|
||||
(mu4e~context-autoswitch nil mu4e-context-policy)
|
||||
(mu4e~check-requirements)
|
||||
|
||||
;; when it's visible, re-draw the main view when there are changes.
|
||||
(add-hook 'mu4e-index-updated-hook
|
||||
(lambda()
|
||||
|
@ -823,7 +808,7 @@ When successful, call FUNC (if non-nil) afterwards."
|
|||
(when (and (buffer-live-p mainbuf) (get-buffer-window mainbuf))
|
||||
(mu4e~start 'mu4e~main-view))))))
|
||||
|
||||
(setq mu4e-pong-func (lambda (props) (mu4e~pong-handler props func)))
|
||||
(setq mu4e-pong-func (lambda (info) (mu4e~pong-handler info func)))
|
||||
(mu4e~proc-ping
|
||||
(mapcar ;; send it a list of queries we'd like to see read/unread info
|
||||
;; for.
|
||||
|
@ -906,12 +891,7 @@ Also scrolls to the final line, and update the progress throbber."
|
|||
(defun mu4e-update-index ()
|
||||
"Update the mu4e index."
|
||||
(interactive)
|
||||
(unless mu4e-maildir
|
||||
(mu4e-error "`mu4e-maildir' is not defined"))
|
||||
(mu4e~proc-index mu4e-maildir
|
||||
mu4e-user-mail-address-list
|
||||
mu4e-index-cleanup
|
||||
mu4e-index-lazy-check))
|
||||
(mu4e~proc-index mu4e-index-cleanup mu4e-index-lazy-check))
|
||||
|
||||
(defvar mu4e~update-buffer nil
|
||||
"Internal, store the buffer of the update process when
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; mu4e-vars.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2011-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
@ -29,6 +29,7 @@
|
|||
(require 'mu4e-meta)
|
||||
(require 'message)
|
||||
|
||||
(declare-function mu4e-error "mu4e-utils")
|
||||
|
||||
(defgroup mu4e nil
|
||||
"mu4e - mu for emacs"
|
||||
|
@ -50,13 +51,8 @@ path."
|
|||
:group 'mu4e
|
||||
:safe 'stringp)
|
||||
|
||||
(defcustom mu4e-maildir (expand-file-name "~/Maildir")
|
||||
"The absolute file system path to your Maildir.
|
||||
Must not be a symbolic link, and after starting mu4e, cannot
|
||||
change until after quitting."
|
||||
:type 'directory
|
||||
:safe 'stringp
|
||||
:group 'mu4e)
|
||||
(make-obsolete-variable 'mu4e-maildir
|
||||
"determined by server; see `mu4e-root-maildir'." "1.3.8")
|
||||
|
||||
(defcustom mu4e-org-support t
|
||||
"Support org-mode links."
|
||||
|
@ -172,9 +168,10 @@ matched case-insensitively."
|
|||
;; don't use the older vars anymore
|
||||
(make-obsolete-variable 'mu4e-user-mail-address-regexp
|
||||
'mu4e-user-mail-address-list "0.9.9.x")
|
||||
|
||||
(make-obsolete-variable 'mu4e-my-email-addresses
|
||||
'mu4e-user-mail-address-list "0.9.9.x")
|
||||
(make-obsolete-variable 'mu4e-user-mail-address-list
|
||||
"determined by server; see `mu4e-personal-addresses'." "1.3.8")
|
||||
|
||||
(defcustom mu4e-use-fancy-chars nil
|
||||
"When set, allow fancy (Unicode) characters for marks/threads.
|
||||
|
@ -365,10 +362,8 @@ The setting is a symbol:
|
|||
(defcustom mu4e-compose-complete-only-personal nil
|
||||
"Whether to consider only 'personal' e-mail addresses for completion.
|
||||
That is, addresses from messages where user was explicitly in one
|
||||
of the address fields (this excludes mailing list messages). See
|
||||
`mu4e-user-mail-address-list' and the mu-index manpage for
|
||||
details for details (in particular, how to define your own e-mail
|
||||
addresses)."
|
||||
of the address fields (this excludes mailing list messages).
|
||||
These addresses are the ones specified with `mu init'."
|
||||
:type 'boolean
|
||||
:group 'mu4e-compose)
|
||||
|
||||
|
@ -926,13 +921,42 @@ We need to keep this information around to quickly re-sort
|
|||
subsets of the contacts in the completions function in
|
||||
mu4e-compose.")
|
||||
|
||||
(defvar mu4e~server-props nil
|
||||
"Properties we receive from the mu4e server process.
|
||||
\(in the 'pong-handler').")
|
||||
|
||||
(defvar mu4e~headers-last-query nil
|
||||
"The present (most recent) query.")
|
||||
|
||||
(defvar mu4e~server-props nil
|
||||
"Information we receive from the mu4e server process \(in the 'pong-handler').")
|
||||
|
||||
(defun mu4e-root-maildir()
|
||||
"Get the root maildir."
|
||||
(let ((root-maildir (and mu4e~server-props
|
||||
(plist-get mu4e~server-props :root-maildir))))
|
||||
(unless root-maildir
|
||||
(mu4e-error "root maildir unknown; did you start mu4e?"))
|
||||
root-maildir))
|
||||
|
||||
(defun mu4e-database-path()
|
||||
"Get the mu4e database path"
|
||||
(let ((path (and mu4e~server-props
|
||||
(plist-get mu4e~server-props :database-path))))
|
||||
(unless path
|
||||
(mu4e-error "database-path unknown; did you start mu4e?"))
|
||||
path))
|
||||
|
||||
(defun mu4e-personal-addresses()
|
||||
"Get the user's personal addresses, if any. If none are set on the server-side,
|
||||
fall back to the obsolete `mu4e-user-mail-address-list'."
|
||||
(let ((addrs (and mu4e~server-props
|
||||
(plist-get mu4e~server-props :personal-addresses))))
|
||||
(if addrs addrs mu4e-user-mail-address-list)))
|
||||
|
||||
(defun mu4e-server-version()
|
||||
"Get the server version, which should match mu4e's."
|
||||
(let ((version (and mu4e~server-props (plist-get mu4e~server-props :version))))
|
||||
(unless version
|
||||
(mu4e-error "version unknown; did you start mu4e?"))
|
||||
version))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; our handlers funcs these handler funcs define what happens when we receive a
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; mu4e-view.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
|
||||
;;
|
||||
;; Copyright (C) 2011-2018 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2011-2020 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
@ -392,7 +392,7 @@ article-mode."
|
|||
(run-hooks 'gnus-article-decode-hook)
|
||||
(let ((mu4e~view-rendering t) ; customize gnus in mu4e
|
||||
(max-specpdl-size mu4e-view-max-specpdl-size)
|
||||
(gnus-icalendar-additional-identities mu4e-user-mail-address-list))
|
||||
(gnus-icalendar-additional-identities (mu4e-personal-addresses)))
|
||||
(gnus-article-prepare-display))
|
||||
(mu4e-view-mode)
|
||||
(setq mu4e~view-message msg)
|
||||
|
|
264
mu4e/mu4e.texi
264
mu4e/mu4e.texi
|
@ -217,6 +217,7 @@ After these steps, @t{mu4e} should be ready to go!
|
|||
* Requirements:: What is needed
|
||||
* Installation:: How to install @t{mu} and @t{mu4e}
|
||||
* Getting mail:: Getting mail from a server
|
||||
* Initializing the message store:: Settings things up
|
||||
* Indexing your messages:: Creating and maintaining the index
|
||||
* Basic configuration:: Settings for @t{mu4e}
|
||||
* Folders:: Setting up standard folders
|
||||
|
@ -230,14 +231,14 @@ After these steps, @t{mu4e} should be ready to go!
|
|||
@section Requirements
|
||||
|
||||
@t{mu}/@t{mu4e} are known to work on a wide variety of Unix- and
|
||||
Unix-like systems, including many Linux distributions, OS X and FreeBSD,
|
||||
and even on MS-Windows (with Cygwin). @command{emacs} 23 or 24
|
||||
(recommended) is required, as well as
|
||||
Unix-like systems, including many Linux distributions, OS X and
|
||||
FreeBSD, and even on MS-Windows (with Cygwin). @command{emacs} 24 or
|
||||
higher is required, as well as
|
||||
Xapian@footnote{@url{https://xapian.org/}} and
|
||||
GMime@footnote{@url{http://spruce.sourceforge.net/gmime/}}.
|
||||
|
||||
@t{mu} has optional support for the Guile 2.x (Scheme) programming
|
||||
language. There are also some GUI-tools, which require GTK+ 3.x and
|
||||
language. There are also some GUI-toys, which require GTK+ 3.x and
|
||||
Webkit.
|
||||
|
||||
If you intend to compile @t{mu} yourself, you need to have the typical
|
||||
|
@ -249,16 +250,17 @@ you also need the development packages for GTK+, Webkit and Guile.
|
|||
@node Installation
|
||||
@section Installation
|
||||
|
||||
@t{mu4e} is part of @t{mu} --- by installing the latter, the former is installed
|
||||
as well. Some Linux distributions provide packaged versions of
|
||||
@t{mu}/@t{mu4e}; if you can use those, there is no need to compile anything
|
||||
yourself. However, if there are no packages for your distribution, if they are
|
||||
outdated, or if you want to use the latest development versions, you can
|
||||
follow the steps below.
|
||||
@t{mu4e} is part of @t{mu} --- by installing the latter, the former is
|
||||
installed as well. Some Linux distributions provide packaged versions
|
||||
of @t{mu}/@t{mu4e}; if you can use those, there is no need to compile
|
||||
anything yourself. However, if there are no packages for your
|
||||
distribution, if they are outdated, or if you want to use the latest
|
||||
development versions, you can follow the steps below.
|
||||
|
||||
First, you need make sure you have the necessary dependencies; the details
|
||||
depend on your distribution. If you're using another distribution (or another
|
||||
OS), the below can at least be helpful in identifying the packages to install.
|
||||
First, you need make sure you have the necessary dependencies; the
|
||||
details depend on your distribution. If you're using another
|
||||
distribution (or another OS), the below can at least be helpful in
|
||||
identifying the packages to install.
|
||||
|
||||
We provide some instructions for Debian, Ubuntu and Fedora; if those do not
|
||||
apply to you, you can follow either @ref{Building from a release tarball} or
|
||||
|
@ -356,46 +358,74 @@ through things step-by-step.
|
|||
@node Getting mail
|
||||
@section Getting mail
|
||||
|
||||
In order for @t{mu} (and, by extension, @t{mu4e}) to work, you need to have
|
||||
your e-mail messages stored in a
|
||||
@emph{maildir}@footnote{@url{https://en.wikipedia.org/wiki/Maildir}; in this
|
||||
manual we use the term `maildir' for both the standard and the hierarchy of
|
||||
maildirs that store your messages} --- a specific directory structure with
|
||||
one-file-per-message. If you are already using a maildir, you are lucky. If
|
||||
not, some setup is required:
|
||||
In order for @t{mu} (and, by extension, @t{mu4e}) to work, you need to
|
||||
have your e-mail messages stored in a
|
||||
@emph{maildir}@footnote{@url{https://en.wikipedia.org/wiki/Maildir};
|
||||
in this manual we use the term `maildir' for both the standard and the
|
||||
hierarchy of maildirs that store your messages} --- a specific
|
||||
directory structure with one-file-per-message. If you are already
|
||||
using a maildir, you are lucky. If not, some setup is required:
|
||||
|
||||
@itemize
|
||||
@item @emph{Using an external IMAP or POP server} --- if you are using an
|
||||
@abbr{IMAP} or @abbr{POP} server, you can use tools like @t{getmail},
|
||||
@t{fetchmail}, @t{offlineimap} or @t{isync} to download your messages into a
|
||||
maildir (@file{~/Maildir}, often). Because it is such a common case, there is
|
||||
a full example of setting @t{mu4e} up with @t{offlineimap} and Gmail;
|
||||
@pxref{Gmail configuration}.
|
||||
@t{fetchmail}, @t{offlineimap} or @t{isync} to download your messages
|
||||
into a maildir (@file{~/Maildir}, often). Because it is such a common
|
||||
case, there is a full example of setting @t{mu4e} up with
|
||||
@t{offlineimap} and Gmail; @pxref{Gmail configuration}.
|
||||
@item @emph{Using a local mail server} --- if you are using a local mail-server
|
||||
(such as @t{postfix} or @t{qmail}), you can teach them to deliver into a
|
||||
maildir as well, maybe in combination with @t{procmail}. A bit of googling
|
||||
should be able to provide you with the details.
|
||||
(such as @t{postfix} or @t{qmail}), you can teach them to deliver into
|
||||
a maildir as well, maybe in combination with @t{procmail}. A bit of
|
||||
googling should be able to provide you with the details.
|
||||
@end itemize
|
||||
|
||||
@node Initializing the message store
|
||||
@section Initializing the message store
|
||||
|
||||
The first time your run @t{mu}, you need to initialize its store
|
||||
(database). The default location for that is @t{~/.cache/mu/xapian},
|
||||
but you can change this using the @t{--muhome} option, and remember to
|
||||
pass that to the other commands as well.
|
||||
|
||||
Assuming that your maildir is at @file{~/Maildir}, we issue the
|
||||
following command:
|
||||
@example
|
||||
$ mu init --maildir=~/Maildir
|
||||
@end example
|
||||
|
||||
Optionally, you can add some e-mail addresses, so @t{mu} recognizes
|
||||
them as yours:
|
||||
|
||||
@example
|
||||
$ mu init --maildir=~/Maildir --my-address=jim@@example.com --my-address=bob@@example.com
|
||||
@end example
|
||||
|
||||
@t{mu} remembers the maildir and your addresses and uses them when
|
||||
indexing messages. If you want to change them, you need to @t{init}
|
||||
once again.
|
||||
|
||||
If you want to see the current values, you can use @t{mu info}.
|
||||
|
||||
@node Indexing your messages
|
||||
@section Indexing your messages
|
||||
|
||||
After you have succeeded in @ref{Getting mail}, we need to @emph{index} the
|
||||
messages. That is --- we need to scan the messages in the maildir and store the
|
||||
information about them in a special database. We can do that from @t{mu4e} ---
|
||||
@ref{Main view}, but the first time, it is a good idea to run it from the
|
||||
command line, which makes it easier to verify that everything works correctly.
|
||||
After you have succeeded in @ref{Getting mail} and initialized the
|
||||
message database, we need to @emph{index} the messages. That is --- we
|
||||
need to scan the messages in the maildir and store the information
|
||||
about them in a special database.
|
||||
|
||||
We can do that from @t{mu4e} --- @ref{Main view}, but the first time,
|
||||
it is a good idea to run it from the command line, which makes it
|
||||
easier to verify that everything works correctly.
|
||||
|
||||
Assuming that your maildir is at @file{~/Maildir}, we issue the following
|
||||
command:
|
||||
@example
|
||||
$ mu index --maildir=~/Maildir
|
||||
$ mu index
|
||||
@end example
|
||||
|
||||
This should scan your @file{~/Maildir}@footnote{In most cases, you do not even
|
||||
need to provide the @t{--maildir=~/Maildir} since it is the default; see the
|
||||
@t{mu-index} man-page for details} and fill the database, and give progress
|
||||
information while doing so.
|
||||
This should scan your messages and fill the database, and give
|
||||
progress information while doing so.
|
||||
|
||||
The indexing process may take a few minutes the first time you do it
|
||||
(for thousands of e-mails); afterwards it is much faster, since @t{mu}
|
||||
|
@ -448,19 +478,15 @@ situation. See @ref{Dynamic folders} for details.}:
|
|||
@lisp
|
||||
;; these are actually the defaults
|
||||
(setq
|
||||
mu4e-maildir "~/Maildir" ;; top-level Maildir
|
||||
mu4e-sent-folder "/sent" ;; folder for sent messages
|
||||
mu4e-drafts-folder "/drafts" ;; unfinished messages
|
||||
mu4e-trash-folder "/trash" ;; trashed messages
|
||||
mu4e-refile-folder "/archive") ;; saved messages
|
||||
@end lisp
|
||||
|
||||
Note, @code{mu4e-maildir} takes an actual filesystem-path, the other
|
||||
folder names are all relative to @code{mu4e-maildir}. Also note that
|
||||
this must @emph{not} be a symbolic link.
|
||||
|
||||
If you use @t{mu4e-context}, see @ref{Contexts and special folders} for
|
||||
what that means for these special folders.
|
||||
Note, the folder names are all relative to the root-maildir (see the
|
||||
output of @t{mu info}). If you use @t{mu4e-context}, see @ref{Contexts
|
||||
and special folders} for what that means for these special folders.
|
||||
|
||||
@node Retrieval and indexing
|
||||
@section Retrieval and indexing with mu4e
|
||||
|
@ -684,9 +710,9 @@ The main view looks something like the following:
|
|||
|
||||
Bookmarks
|
||||
|
||||
* [bu] Unread messages (26217/26217)
|
||||
* [bt] Today's messages (2/8)
|
||||
* [bw] Last 7 days (7/34)
|
||||
* [bu] Unread messages (26217/26217)
|
||||
* [bt] Today's messages (2/8)
|
||||
* [bw] Last 7 days (7/34)
|
||||
* [bp] Messages with images (276/2315)
|
||||
|
||||
Misc
|
||||
|
@ -710,11 +736,11 @@ Let's walk through the menu.
|
|||
First, the @emph{Basics}:
|
||||
@itemize
|
||||
@item @t{[j]ump to some maildir}: after pressing @key{j} (``jump''),
|
||||
@t{mu4e} asks you for a maildir to visit. These are the maildirs you set in
|
||||
@ref{Basic configuration} and any of your own. If you choose @key{o}
|
||||
(``other'') or @key{/}, you can choose from all maildirs under
|
||||
@code{mu4e-maildir}. After choosing a maildir, the messages in that maildir
|
||||
are listed, in the @ref{Headers view}.
|
||||
@t{mu4e} asks you for a maildir to visit. These are the maildirs you
|
||||
set in @ref{Basic configuration} and any of your own. If you choose
|
||||
@key{o} (``other'') or @key{/}, you can choose from all maildirs under
|
||||
the root-maildir. After choosing a maildir, the messages in that
|
||||
maildir are listed, in the @ref{Headers view}.
|
||||
@item @t{enter a [s]earch query}: after pressing @key{s}, @t{mu4e} asks
|
||||
you for a search query, and after entering one, shows the results in the
|
||||
@ref{Headers view}.
|
||||
|
@ -2630,9 +2656,8 @@ invoke those function even in that case.
|
|||
the current context is also visible in the mode-line when in
|
||||
headers, view or main mode.
|
||||
@item You can set any kind of variable; including settings for mail servers etc.
|
||||
However, settings such as @code{mu4e-maildir} and @code{mu4e-mu-home}
|
||||
are not changeable after they have been set without quitting @t{mu4e}
|
||||
first.
|
||||
However, settings such as @code{mu4e-mu-home} are not changeable after
|
||||
they have been set without quitting @t{mu4e} first.
|
||||
@item @code{leave-func} (if defined) for the context we are leaving, is invoked
|
||||
before the @code{enter-func} (if defined) of the
|
||||
context we are entering.
|
||||
|
@ -3512,10 +3537,6 @@ see, most of it is commented-out.
|
|||
;; use mu4e for e-mail in emacs
|
||||
(setq mail-user-agent 'mu4e-user-agent)
|
||||
|
||||
;; Only needed if your maildir is _not_ ~/Maildir
|
||||
;; Must be a real dir, not a symlink
|
||||
;;(setq mu4e-maildir "/home/user/Maildir")
|
||||
|
||||
;; these must start with a "/", and must exist
|
||||
;; (i.e.. /home/user/Maildir/sent must exist)
|
||||
;; you use e.g. 'mu mkdir' to make the Maildirs if they don't
|
||||
|
@ -3549,10 +3570,8 @@ customize.
|
|||
;; use mu4e for e-mail in emacs
|
||||
(setq mail-user-agent 'mu4e-user-agent)
|
||||
|
||||
;; path to our Maildir directory
|
||||
(setq mu4e-maildir "/home/user/Maildir")
|
||||
|
||||
;; the next are relative to `mu4e-maildir'
|
||||
;; the next are relative to the root maildir
|
||||
;; (see `mu info`).
|
||||
;; instead of strings, they can be functions too, see
|
||||
;; their docstring or the chapter 'Dynamic folders'
|
||||
(setq mu4e-sent-folder "/sent"
|
||||
|
@ -3718,9 +3737,6 @@ Next step: let's make a @t{mu4e} configuration for this:
|
|||
;; use mu4e for e-mail in emacs
|
||||
(setq mail-user-agent 'mu4e-user-agent)
|
||||
|
||||
;; default
|
||||
;; (setq mu4e-maildir "~/Maildir")
|
||||
|
||||
(setq mu4e-drafts-folder "/[Gmail].Drafts")
|
||||
(setq mu4e-sent-folder "/[Gmail].Sent Mail")
|
||||
(setq mu4e-trash-folder "/[Gmail].Trash")
|
||||
|
@ -4207,7 +4223,6 @@ github-repository.
|
|||
|
||||
@menu
|
||||
* Fancy characters:: Non-ascii characters in the UI
|
||||
* Multiple accounts:: (Obsolete) the old way to deal with multiple accounts
|
||||
* Refiling messages:: Moving message to some archive folder
|
||||
* Saving outgoing messages:: Automatically save sent messages
|
||||
* Confirmation before sending:: Check messages before sending
|
||||
|
@ -4242,121 +4257,6 @@ try the @emph{unicode-fonts} package:
|
|||
(unicode-fonts-setup)
|
||||
@end lisp
|
||||
|
||||
|
||||
@node Multiple accounts
|
||||
@section Multiple accounts
|
||||
|
||||
@b{Note}: for @t{mu4e} version 0.9.16 and higher, the recommended way
|
||||
to deal with multiple accounts is through @t{mu4e}'s built-in
|
||||
@ref{Contexts} system. For older versions, the below still works.
|
||||
|
||||
Using @t{mu4e} with multiple email accounts is fairly easy. Although
|
||||
variables such as @code{user-mail-address}, @code{mu4e-sent-folder},
|
||||
@code{message-*}, @code{smtpmail-*}, etc. typically only take one value,
|
||||
it is easy to change their values using @code{mu4e-compose-pre-hook}.
|
||||
The setup described here is one way of doing this (though certainly not
|
||||
the only way).
|
||||
|
||||
This setup assumes that you have multiple mail accounts under
|
||||
@code{mu4e-maildir}. As an example, we'll use @t{~/Maildir/Account1}
|
||||
and @t{~/Maildir/Account2}, but the setup works just as well if
|
||||
@code{mu4e-maildir} points to something else.
|
||||
|
||||
First, you need to make sure that all variables that you wish to change
|
||||
based on user account are set to some initial value. So set up your
|
||||
environment with e.g., your main account:
|
||||
|
||||
@lisp
|
||||
(setq mu4e-sent-folder "/Account1/Saved Items"
|
||||
mu4e-drafts-folder "/Account1/Drafts"
|
||||
user-mail-address "my.address@@account1.example.com"
|
||||
smtpmail-default-smtp-server "smtp.account1.example.com"
|
||||
smtpmail-local-domain "account1.example.com"
|
||||
smtpmail-smtp-server "smtp.account1.example.com"
|
||||
smtpmail-stream-type 'starttls
|
||||
smtpmail-smtp-service 25)
|
||||
@end lisp
|
||||
|
||||
Then create a variable @code{my-mu4e-account-alist}, which should
|
||||
contain a list for each of your accounts. Each list should start with
|
||||
the account name, (which @emph{must} be identical to the account's
|
||||
directory name under @t{~/Maildir}), followed by @code{(variable
|
||||
value)} pairs:
|
||||
|
||||
@lisp
|
||||
(defvar my-mu4e-account-alist
|
||||
'(("Account1"
|
||||
(mu4e-sent-folder "/Account1/Saved Items")
|
||||
(mu4e-drafts-folder "/Account1/Drafts")
|
||||
(user-mail-address "my.address@@account1.example.com")
|
||||
(smtpmail-default-smtp-server "smtp.account1.example.com")
|
||||
(smtpmail-local-domain "account1.example.com")
|
||||
(smtpmail-smtp-user "username1")
|
||||
(smtpmail-smtp-server "smtp.account1.example.com")
|
||||
(smtpmail-stream-type starttls)
|
||||
(smtpmail-smtp-service 25))
|
||||
("Account2"
|
||||
(mu4e-sent-folder "/Account2/Saved Items")
|
||||
(mu4e-drafts-folder "/Account2/Drafts")
|
||||
(user-mail-address "my.address@@account2.example.com")
|
||||
(smtpmail-default-smtp-server "smtp.account2.example.com")
|
||||
(smtpmail-local-domain "account2.example.com")
|
||||
(smtpmail-smtp-user "username2")
|
||||
(smtpmail-smtp-server "smtp.account2.example.com")
|
||||
(smtpmail-stream-type starttls)
|
||||
(smtpmail-smtp-service 587))))
|
||||
@end lisp
|
||||
|
||||
You can put any variable you want in the account lists, just make sure
|
||||
that you put in @emph{all} the variables that differ for each account.
|
||||
Variables that do not differ need not be included. For example, if you
|
||||
use the same SMTP server for both accounts, you don't need to include
|
||||
the SMTP-related variables in @code{my-mu4e-account-alist}.
|
||||
|
||||
Note that some SMTP servers (such as Gmail) require the SMTP username to
|
||||
match the user mail address. In this case, your mail appears to
|
||||
originate from whichever SMTP account you use. Thus unless you are
|
||||
certain your SMTP server does not have this requirement, you should
|
||||
generally use different SMTP account credentials for each mail account.
|
||||
|
||||
Now, the following function can be used to select an account and set the
|
||||
variables in @code{my-mu4e-account-alist} to the correct values:
|
||||
|
||||
@lisp
|
||||
(defun my-mu4e-set-account ()
|
||||
"Set the account for composing a message."
|
||||
(let* ((account
|
||||
(if mu4e-compose-parent-message
|
||||
(let ((maildir (mu4e-message-field mu4e-compose-parent-message :maildir)))
|
||||
(string-match "/\\(.*?\\)/" maildir)
|
||||
(match-string 1 maildir))
|
||||
(completing-read (format "Compose with account: (%s) "
|
||||
(mapconcat #'(lambda (var) (car var))
|
||||
my-mu4e-account-alist "/"))
|
||||
(mapcar #'(lambda (var) (car var)) my-mu4e-account-alist)
|
||||
nil t nil nil (caar my-mu4e-account-alist))))
|
||||
(account-vars (cdr (assoc account my-mu4e-account-alist))))
|
||||
(if account-vars
|
||||
(mapc #'(lambda (var)
|
||||
(set (car var) (cadr var)))
|
||||
account-vars)
|
||||
(error "No email account found"))))
|
||||
@end lisp
|
||||
|
||||
This function then needs to be added to @code{mu4e-compose-pre-hook}:
|
||||
|
||||
@lisp
|
||||
(add-hook 'mu4e-compose-pre-hook 'my-mu4e-set-account)
|
||||
@end lisp
|
||||
|
||||
This way, @code{my-mu4e-set-account} is called every time you edit a
|
||||
message. If you compose a new message, it simply asks you for the
|
||||
account you wish to send the message from (TAB completion works). If
|
||||
you're replying or forwarding a message, or editing an existing draft,
|
||||
the account is chosen automatically, based on the first component of the
|
||||
maildir of the message being replied to, forwarded or edited (i.e., the
|
||||
directory under @t{~/Maildir}).
|
||||
|
||||
@node Refiling messages
|
||||
@section Refiling messages
|
||||
|
||||
|
|
Loading…
Reference in New Issue