aboutsummaryrefslogtreecommitdiffstats
path: root/_spacemacs.d
diff options
context:
space:
mode:
authorAaron LI <aaronly.me@outlook.com>2016-12-04 18:48:12 +0800
committerAaron LI <aaronly.me@outlook.com>2016-12-04 18:48:12 +0800
commitdd08c1a07c5311570fc47e07909ffa8d196f365b (patch)
tree2b1b610d2ee3be4facf34f9493f5dec8f1d966bb /_spacemacs.d
parentde6be2b383668de5011c38491227fbf91da0c06c (diff)
downloaddotfiles-dd08c1a07c5311570fc47e07909ffa8d196f365b.tar.bz2
_spacemacs: Do not track "mu4e" package
Diffstat (limited to '_spacemacs.d')
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-actions.el316
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-compose.el839
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-context.el157
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-contrib.el165
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-draft.el495
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-headers.el1717
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-lists.el93
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-main.el225
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-mark.el466
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-message.el284
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-meta.el11
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-proc.el525
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-speedbar.el125
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-utils.el1281
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-vars.el927
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-view.el1542
-rw-r--r--_spacemacs.d/local/mu4e/mu4e.el102
-rw-r--r--_spacemacs.d/local/mu4e/org-mu4e.el323
-rw-r--r--_spacemacs.d/local/mu4e/org-old-mu4e.el289
19 files changed, 0 insertions, 9882 deletions
diff --git a/_spacemacs.d/local/mu4e/mu4e-actions.el b/_spacemacs.d/local/mu4e/mu4e-actions.el
deleted file mode 100644
index 0128c52..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-actions.el
+++ /dev/null
@@ -1,316 +0,0 @@
-;;; mu4e-actions.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Example actions for messages, attachments (see chapter 'Actions' in the
-;; manual)
-
-;;; Code:
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-(require 'cl)
-(require 'ido)
-
-(require 'mu4e-utils)
-(require 'mu4e-message)
-(require 'mu4e-meta)
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e-action-count-lines (msg)
- "Count the number of lines in the e-mail message.
-Works for headers view and message-view."
- (message "Number of lines: %s"
- (shell-command-to-string
- (concat "wc -l < " (shell-quote-argument (mu4e-message-field msg :path))))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e-msg2pdf (concat mu4e-builddir "/toys/msg2pdf/msg2pdf")
- "Path to the msg2pdf toy.")
-
-(defun mu4e-action-view-as-pdf (msg)
- "Convert the message to pdf, then show it.
-Works for the message view."
- (unless (file-executable-p mu4e-msg2pdf)
- (mu4e-error "msg2pdf not found; please set `mu4e-msg2pdf'"))
- (let* ((pdf
- (shell-command-to-string
- (concat mu4e-msg2pdf " "
- (shell-quote-argument (mu4e-message-field msg :path))
- " 2> /dev/null")))
- (pdf (and pdf (> (length pdf) 5)
- (substring pdf 0 -1)))) ;; chop \n
- (unless (and pdf (file-exists-p pdf))
- (mu4e-warn "Failed to create PDF file"))
- (find-file pdf)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defun mu4e~write-body-to-html (msg)
- "Write the body (either html or text) to a temporary file;
-return the filename."
- (let* ((html (mu4e-message-field msg :body-html))
- (txt (mu4e-message-field msg :body-txt))
- (tmpfile (mu4e-make-temp-file "html"))
- (attachments (remove-if (lambda (part)
- (or (null (plist-get part :attachment))
- (null (plist-get part :cid))))
- (mu4e-message-field msg :parts))))
- (unless (or html txt)
- (mu4e-error "No body part for this message"))
- (with-temp-buffer
- (insert "<head><meta charset=\"UTF-8\"></head>\n")
- (insert (or html (concat "<pre>" txt "</pre>")))
- (write-file tmpfile)
- ;; rewrite attachment urls
- (mapc (lambda (attachment)
- (goto-char (point-min))
- (while (re-search-forward (format "src=\"cid:%s\"" (plist-get attachment :cid)) nil t)
- (if (plist-get attachment :temp)
- (replace-match (format "src=\"%s\"" (plist-get attachment :temp)))
- (replace-match (format "src=\"%s%s\"" temporary-file-directory (plist-get attachment :name)))
- (mu4e~proc-extract 'save (mu4e-message-field msg :docid) (plist-get attachment :index) mu4e-decryption-policy temporary-file-directory)
- (mu4e-remove-file-later (format "%s%s" temporary-file-directory (plist-get attachment :name))))))
- attachments)
- (save-buffer)
- tmpfile)))
-
-(defun mu4e-action-view-in-browser (msg)
- "View the body of the message in a browser.
-You can influence the browser to use with the variable
-`browse-url-generic-program', and see the discussion of privacy
-aspects in `(mu4e) Displaying rich-text messages'."
- (browse-url (concat "file://"
- (mu4e~write-body-to-html msg))))
-
-(defun mu4e-action-view-with-xwidget (msg)
- "View the body of the message inside xwidget-webkit. This is
-only available in emacs 25+; also see the discussion of privacy
-aspects in `(mu4e) Displaying rich-text messages'."
- (unless (fboundp 'xwidget-webkit-browse-url)
- (mu4e-error "No xwidget support available"))
- (xwidget-webkit-browse-url
- (concat "file://" (mu4e~write-body-to-html msg)) t))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defconst mu4e-text2speech-command "festival --tts"
- "Program that speaks out text it receives on standard-input.")
-
-(defun mu4e-action-message-to-speech (msg)
- "Pronounce the message text using `mu4e-text2speech-command'."
- (unless (mu4e-message-field msg :body-txt)
- (mu4e-warn "No text body for this message"))
- (with-temp-buffer
- (insert (mu4e-message-field msg :body-txt))
- (shell-command-on-region (point-min) (point-max)
- mu4e-text2speech-command)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e-captured-message nil
- "The last-captured message (the s-expression).")
-
-(defun mu4e-action-capture-message (msg)
- "Remember MSG; we can create a an attachment based on this msg
-with `mu4e-compose-attach-captured-message'."
- (setq mu4e-captured-message msg)
- (message "Message has been captured"))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e-org-contacts-file nil
- "File to store contact information for org-contacts.
-Needed by `mu4e-action-add-org-contact'.")
-
-(eval-when-compile ;; silence compiler warning about free variable
- (unless (require 'org-capture nil 'noerror)
- (defvar org-capture-templates nil)))
-
-(defun mu4e-action-add-org-contact (msg)
- "Add an org-contact entry based on the From: address of the
-current message (in headers or view). You need to set
-`mu4e-org-contacts-file' to the full path to the file where you
-store your org-contacts."
- (unless (require 'org-capture nil 'noerror)
- (mu4e-error "org-capture is not available."))
- (unless mu4e-org-contacts-file
- (mu4e-error "`mu4e-org-contacts-file' is not defined."))
- (let* ((sender (car-safe (mu4e-message-field msg :from)))
- (name (car-safe sender)) (email (cdr-safe sender))
- (blurb
- (format
- (concat
- "* %%?%s\n"
- ":PROPERTIES:\n"
- ":EMAIL: %s\n"
- ":NICK:\n"
- ":BIRTHDAY:\n"
- ":END:\n\n")
- (or name email "")
- (or email "")))
- (key "mu4e-add-org-contact-key")
- (org-capture-templates
- (append org-capture-templates
- (list (list key "contacts" 'entry
- (list 'file mu4e-org-contacts-file) blurb)))))
- (message "%S" org-capture-templates)
- (when (fboundp 'org-capture)
- (org-capture nil key))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e-action-git-apply-patch (msg)
- "Apply the git [patch] message."
- (let ((path (ido-read-directory-name "Target directory: "
- (car ido-work-directory-list)
- "~/" t)))
- (setf ido-work-directory-list
- (cons path (delete path ido-work-directory-list)))
- (shell-command
- (format "cd %s; git apply %s"
- path
- (mu4e-message-field msg :path)))))
-
-(defun mu4e-action-git-apply-mbox (msg)
- "Apply and commit the git [patch] message."
- (let ((path (ido-read-directory-name "Target directory: "
- (car ido-work-directory-list)
- "~/" t)))
- (setf ido-work-directory-list
- (cons path (delete path ido-work-directory-list)))
- (shell-command
- (format "cd %s; git am %s"
- path
- (mu4e-message-field msg :path)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e-action-tags-header "X-Keywords"
- "Header where tags are stored. Used by `mu4e-action-retag-message'.
- Make sure it is one of the headers mu recognizes for storing
- tags: X-Keywords, X-Label, Keywords. Also note that changing
- this setting on already tagged messages can lead to messages
- with multiple tags headers.")
-
-(defun mu4e~contains-line-matching (regexp path)
- "Determine whether the file at path contains a line matching
- the given regexp."
- (with-temp-buffer
- (insert-file-contents path)
- (save-excursion
- (goto-char (point-min))
- (if (re-search-forward regexp nil t)
- t
- nil))))
-
-(defun mu4e~replace-first-line-matching (regexp to-string path)
- "Replace the first line in the file at path that matches regexp
- with the string replace."
- (with-temp-file path
- (insert-file-contents path)
- (save-excursion
- (goto-char (point-min))
- (if (re-search-forward regexp nil t)
- (replace-match to-string nil nil)))))
-
-(defun mu4e-action-retag-message (msg &optional retag-arg)
- "Change tags of a message. Example: +tag \"+long tag\" -oldtag
- adds 'tag' and 'long tag', and removes oldtag."
- (let* ((retag (or retag-arg (read-string "Tags: ")))
- (path (mu4e-message-field msg :path))
- (maildir (mu4e-message-field msg :maildir))
- (oldtags (mu4e-message-field msg :tags))
- (header mu4e-action-tags-header)
- (sep (cond ((string= header "Keywords") ", ")
- ((string= header "X-Label") " ")
- ((string= header "X-Keywords") ", ")
- (t ", ")))
- (taglist (if oldtags (copy-sequence oldtags) '()))
- tagstr)
- (dolist (tag (split-string-and-unquote retag) taglist)
- (cond
- ((string-match "^\\+\\(.+\\)" tag)
- (setq taglist (push (match-string 1 tag) taglist)))
- ((string-match "^\\-\\(.+\\)" tag)
- (setq taglist (delete (match-string 1 tag) taglist)))
- (t
- (setq taglist (push tag taglist)))))
-
- (setq taglist (sort (delete-dups taglist) 'string<))
- (setq tagstr (mapconcat 'identity taglist sep))
-
- (setq tagstr (replace-regexp-in-string "[\\&]" "\\\\\\&" tagstr))
- (setq tagstr (replace-regexp-in-string "[/]" "\\&" tagstr))
-
- (if (not (mu4e~contains-line-matching (concat header ":.*") path))
- ;; Add tags header just before the content
- (mu4e~replace-first-line-matching
- "^$" (concat header ": " tagstr "\n") path)
-
- ;; replaces keywords, restricted to the header
- (mu4e~replace-first-line-matching
- (concat header ":.*")
- (concat header ": " tagstr)
- path))
-
- (mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", ")))
- (mu4e-refresh-message path maildir)))
-
-(defun mu4e-action-show-thread (msg)
- "Show all messages that are in the same thread as the message
-at point. Point remains on the message with the message-id where
-the action was invoked. If invoked in view-mode, continue to
-display the message."
- (let ((msgid (mu4e-message-field msg :message-id)))
- (when msgid
- (let ((mu4e-headers-show-threads t)
- (mu4e-headers-include-related t))
- (mu4e-headers-search
- (format "msgid:%s" msgid)
- nil nil nil
- msgid (eq major-mode 'mu4e-view-mode))))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(provide 'mu4e-actions)
diff --git a/_spacemacs.d/local/mu4e/mu4e-compose.el b/_spacemacs.d/local/mu4e/mu4e-compose.el
deleted file mode 100644
index 32d238d..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-compose.el
+++ /dev/null
@@ -1,839 +0,0 @@
-;; -*-mode: emacs-lisp; tab-width: 8; indent-tabs-mode: t -*-
-;; mu4e-compose.el -- part of mu4e, the mu mail user agent for emacs
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; In this file, various functions to compose/send messages, piggybacking on
-;; gnus' message mode
-
-
-;; Magic / Rupe Goldberg
-
-;; 1) When we reply/forward a message, we get it from the backend, ie:
-;; we send to the backend (mu4e-compose):
-;; compose type:reply docid:30935
-;; backend responds with:
-;; (:compose reply :original ( .... <original message> ))
-
-
-;; 2) When we compose a message, message and headers are separated by
-;; `mail-header-separator', ie. '--text follows this line--. We use
-;; before-save-hook and after-save-hook to remove/re-add this special line, so
-;; it stays in the buffer, but never hits the disk.
-;; see:
-;; mu4e~compose-insert-mail-header-separator
-;; mu4e~compose-remove-mail-header-separator
-;;
-;; (maybe we can get away with remove it only just before sending? what does
-;; gnus do?)
-
-;; 3) When sending a message, we want to do a few things:
-;; a) move the message from drafts to the sent folder (maybe; depends on
-;; `mu4e-sent-messages-behavior')
-;; b) if it's a reply, mark the replied-to message as "R", i.e. replied
-;; if it's a forward, mark the forwarded message as "P", i.e. passed (forwarded)
-;; c) kill all buffers looking at the sent message
-
-;; a) is dealt with by message-mode, but we need to tell it where to move the
-;; sent message. We do this by adding an Fcc: header with the target folder,
-;; see `mu4e~compose-setup-fcc-maybe'. Since message-mode does not natively
-;; understand maildirs, we also need to tell it what to do, so we also set
-;; `message-fcc-handler-function' there. Finally, we add the the message in
-;; the sent-folder to the database.
-;;
-;; b) this is handled in `mu4e~compose-set-parent-flag'
-;;
-;; c) this is handled in our handler for the `sent'-message from the backend
-;; (`mu4e-sent-handler')
-;;
-
-;;; Code:
-
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-(require 'cl)
-
-(require 'message)
-(require 'mail-parse)
-(require 'smtpmail)
-(require 'rfc2368)
-
-(require 'mu4e-utils)
-(require 'mu4e-vars)
-(require 'mu4e-proc)
-(require 'mu4e-actions)
-(require 'mu4e-message)
-(require 'mu4e-draft)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Composing / Sending messages
-(defgroup mu4e-compose nil
- "Customizations for composing/sending messages."
- :group 'mu4e)
-
-(defcustom mu4e-sent-messages-behavior 'sent
- "Determines what mu4e does with sent messages.
-
-This is one of the symbols:
-* `sent' move the sent message to the Sent-folder (`mu4e-sent-folder')
-* `trash' move the sent message to the Trash-folder (`mu4e-trash-folder')
-* `delete' delete the sent message.
-
-Note, when using GMail/IMAP, you should set this to either
-`trash' or `delete', since GMail already takes care of keeping
-copies in the sent folder.
-
-Alternatively, `mu4e-sent-messages-behavior' can be a function
-which takes no arguments, and which should return on of the mentioned symbols,
-for example:
-
- (setq mu4e-sent-messages-behavior (lambda ()
- (if (string= (message-sendmail-envelope-from) \"foo@example.com\")
- 'delete 'sent)))
-
-The various `message-' functions from `message-mode' are available
-for querying the message information."
- :type '(choice (const :tag "move message to mu4e-sent-folder" sent)
- (const :tag "move message to mu4e-trash-folder" trash)
- (const :tag "delete message" delete))
- :safe 'symbolp
- :group 'mu4e-compose)
-
-
-(defcustom mu4e-compose-context-policy 'ask
- "Policy for determining the context when composing a new message.
-
-If the value is `always-ask', ask the user unconditionally.
-
-In all other cases, if any context matches (using its match
-function), this context is used. Otherwise, if none of the
-contexts match, we have the following choices:
-
-- `pick-first': pick the first of the contexts available (ie. the default)
-- `ask': ask the user
-- `ask-if-none': ask if there is no context yet, otherwise leave it as it is
-- nil: return nil; leaves the current context as is.
-
-Also see `mu4e-context-policy'."
- :type '(choice
- (const :tag "Always ask what context to use" 'always-ask)
- (const :tag "Ask if none of the contexts match" 'ask)
- (const :tag "Ask when there's no context yet" 'ask-if-none)
- (const :tag "Pick the first context if none match" 'pick-first)
- (const :tag "Don't change the context when none match" nil)
- :safe 'symbolp
- :group 'mu4e-compose))
-
-
-(defcustom mu4e-compose-crypto-reply-policy 'sign-and-encrypt
- "Policy for signing/encrypting replies to encrypted messages.
-We have the following choices:
-
-- `sign': sign the reply
-- `sign-and-encrypt': sign and encrypt the repy
-- `encrypt': encrypt the reply, but don't sign it.
-- anything else: do nothing."
- :type '(choice
- (const :tag "Sign the reply" 'sign)
- (const :tag "Sign and encrypt the reply" 'sign-and-encrypt)
- (const :tag "Encrypt the reply" 'encrypt)
- (const :tag "Don't do anything" nil)
- :safe 'symbolp
- :group 'mu4e-compose))
-
-(defcustom mu4e-compose-format-flowed nil
- "Whether to compose messages to be sent as format=flowed (or
- with long lines if `use-hard-newlines' is set to nil). The
- variable `fill-flowed-encode-column' lets you customize the
- width beyond which format=flowed lines are wrapped."
- :type 'boolean
- :safe 'booleanp
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-pre-hook nil
- "Hook run just *before* message composition starts.
-If the compose-type is either 'reply' or 'forward', the variable
-`mu4e-compose-parent-message' points to the message replied to /
-being forwarded / edited.
-
-Note that there is no draft message yet when this hook runs, it
-is meant for influencing the how mu4e constructs the draft
-message. If you want to do something with the draft messages after
-it has been constructed, `mu4e-compose-mode-hook' would be the
-place to do that."
- :type 'hook
- :group 'mu4e-compose)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defun mu4e-compose-attach-captured-message ()
- "Insert the last captured message file as an attachment.
-Messages are captured with `mu4e-action-capture-message'."
- (interactive)
- (unless mu4e-captured-message
- (mu4e-warn "No message has been captured"))
- (let ((path (plist-get mu4e-captured-message :path)))
- (unless (file-exists-p path)
- (mu4e-warn "Captured message file not found"))
- (mml-attach-file
- path
- "message/rfc822"
- (or (plist-get mu4e-captured-message :subject) "No subject")
- "attachment")))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;; 'fcc' refers to saving a copy of a sent message to a certain folder. that's
-;; what these 'Sent mail' folders are for!
-;;
-;; We let message mode take care of this by adding a field
-
-;; Fcc: <full-path-to-message-in-target-folder>
-
-;; in the "message-send-hook" (ie., just before sending). message mode will
-;; then take care of the saving when the message is actually sent.
-;;
-;; note, where and if you make this copy depends on the value of
-;; `mu4e-sent-messages-behavior'.
-
-(defun mu4e~compose-setup-fcc-maybe ()
- "Maybe setup Fcc, based on `mu4e-sent-messages-behavior'.
-If needed, set the Fcc header, and register the handler function."
- (let* ((sent-behavior
- ;; Note; we cannot simply use functionp here, since at least
- ;; delete is a function, too...
- (if (member mu4e-sent-messages-behavior '(delete trash sent))
- mu4e-sent-messages-behavior
- (if (functionp mu4e-sent-messages-behavior)
- (funcall mu4e-sent-messages-behavior)
- mu4e-sent-messages-behavior)))
- (mdir
- (case sent-behavior
- (delete nil)
- (trash (mu4e-get-trash-folder mu4e-compose-parent-message))
- (sent (mu4e-get-sent-folder mu4e-compose-parent-message))
- (otherwise
- (mu4e-error "unsupported value '%S' `mu4e-sent-messages-behavior'."
- mu4e-sent-messages-behavior))))
- (fccfile (and mdir
- (concat mu4e-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"))
- ;; sadly, we cannot define as 'buffer-local'... this will screw up gnus
- ;; etc. if you run it after mu4e so, (hack hack) we reset it to the old
- ;; handler after we've done our thing.
- (setq message-fcc-handler-function
- (lexical-let ((maildir mdir) (old-handler message-fcc-handler-function))
- (lambda (file)
- (setq message-fcc-handler-function old-handler) ;; reset the fcc handler
- (write-file file) ;; writing maildirs files is easy
- (mu4e~proc-add file (or maildir "/")))))))) ;; update the database
-
-(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\\):")
-
-(defun mu4e~compose-register-message-save-hooks ()
- "Just before saving, we remove the mail-header-separator; just
-after saving we restore it; thus, the separator should never
-appear on disk."
- (add-hook 'before-save-hook
- 'mu4e~draft-remove-mail-header-separator nil t)
- (add-hook 'after-save-hook
- (lambda ()
- (mu4e~compose-set-friendly-buffer-name)
- (mu4e~draft-insert-mail-header-separator)
- ;; hide some headers again
- (mu4e~compose-hide-headers)
- (set-buffer-modified-p nil)
- (mu4e-message "Saved (%d lines)" (count-lines (point-min) (point-max)))
- ;; update the file on disk -- ie., without the separator
- (mu4e~proc-add (buffer-file-name) mu4e~draft-drafts-folder)) nil t))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; address completion; inspired by org-contacts.el and
-;; https://github.com/nordlow/elisp/blob/master/mine/completion-styles-cycle.el
-(defun mu4e~compose-complete-handler (str pred action)
- (cond
- ((eq action nil)
- (try-completion str mu4e~contacts pred))
- ((eq action t)
- (all-completions str mu4e~contacts pred))
- ((eq action 'metadata)
- ;; our contacts are already sorted - just need to tell the
- ;; completion machinery not to try to undo that...
- '(metadata
- (display-sort-function . mu4e~sort-contacts-for-completion)
- (cycle-sort-function . mu4e~sort-contacts-for-completion)))))
-
-(defun mu4e~compose-complete-contact (&optional start)
- "Complete the text at START with a contact.
-Ie. either 'name <email>' or 'email')."
- (interactive)
- (let ((mail-abbrev-mode-regexp mu4e~compose-address-fields-regexp)
- (eoh ;; end-of-headers
- (save-excursion
- (goto-char (point-min))
- (search-forward-regexp mail-header-separator nil t))))
- ;; try to complete only when we're in the headers area,
- ;; looking at an address field.
- (when (and eoh (> eoh (point)) (mail-abbrev-in-expansion-header-p))
- (let* ((end (point))
- (start
- (or start
- (save-excursion
- (re-search-backward "\\(\\`\\|[\n:,]\\)[ \t]*")
- (goto-char (match-end 0))
- (point)))))
- (list start end 'mu4e~compose-complete-handler)))))
-
-(defun mu4e~compose-setup-completion ()
- "Set up auto-completion of addresses."
- (set (make-local-variable 'completion-ignore-case) t)
- (set (make-local-variable 'completion-cycle-threshold) 7)
- (add-to-list (make-local-variable 'completion-styles) 'substring)
- (add-hook 'completion-at-point-functions
- 'mu4e~compose-complete-contact nil t))
-
-(defun mu4e~remove-refs-maybe ()
- "Remove the References: header if the In-Reply-To header is
-missing. This allows the user to effectively start a new
-message-thread by removing the In-Reply-To header."
- (unless (message-fetch-field "in-reply-to")
- (message-remove-header "References")))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e-compose-mode-map nil
- "Keymap for \"*mu4e-compose*\" buffers.")
-(unless mu4e-compose-mode-map
- (setq mu4e-compose-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
- (define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
- (define-key map (kbd "C-c C-k") 'mu4e-message-kill-buffer)
- (define-key map (kbd "M-q") 'mu4e-fill-paragraph)
- map)))
-
-(defun mu4e-fill-paragraph (&optional region)
- "If `use-hard-newlines', takes a multi-line paragraph and makes
-it into a single line of text. Assume paragraphs are separated
-by blank lines. If `use-hard-newlines' is not enabled, this
-simply executes `fill-paragraph'."
- ;; Inspired by https://www.emacswiki.org/emacs/UnfillParagraph
- (interactive (progn (barf-if-buffer-read-only) '(t)))
- (if mu4e-compose-format-flowed
- (let ((fill-column (point-max))
- (use-hard-newlines nil)); rfill "across" hard newlines
- (fill-paragraph nil region))
- (fill-paragraph nil region)))
-
-(defun mu4e-toggle-use-hard-newlines ()
- (interactive)
- (setq use-hard-newlines (not use-hard-newlines))
- (if use-hard-newlines
- (turn-off-auto-fill)
- (turn-on-auto-fill)))
-
-(defun mu4e~compose-remap-faces ()
- "Our parent `message-mode' uses font-locking for the compose
-buffers; lets remap its faces so it uses the ones for mu4e."
- ;; normal headers
- (face-remap-add-relative 'message-header-name
- '((:inherit mu4e-header-key-face)))
- (face-remap-add-relative 'message-header-other
- '((:inherit mu4e-header-value-face)))
- ;; special headers
- (face-remap-add-relative 'message-header-from
- '((:inherit mu4e-contact-face)))
- (face-remap-add-relative 'message-header-to
- '((:inherit mu4e-contact-face)))
- (face-remap-add-relative 'message-header-cc
- '((:inherit mu4e-contact-face)))
- (face-remap-add-relative 'message-header-bcc
- '((:inherit mu4e-contact-face)))
- (face-remap-add-relative 'message-header-subject
- '((:inherit mu4e-special-header-value-face)))
- ;; citation
- (face-remap-add-relative 'message-cited-text
- '((:inherit mu4e-cited-1-face))))
-
-
-(defvar mu4e-compose-mode-abbrev-table nil)
-(define-derived-mode mu4e-compose-mode message-mode "mu4e:compose"
- "Major mode for the mu4e message composition, derived from `message-mode'.
-\\{message-mode-map}."
- (progn
- (use-local-map mu4e-compose-mode-map)
- (set (make-local-variable 'global-mode-string) '(:eval (mu4e-context-label)))
- (set (make-local-variable 'message-signature) mu4e-compose-signature)
- ;; set this to allow mu4e to work when gnus-agent is unplugged in gnus
- (set (make-local-variable 'message-send-mail-real-function) nil)
- (make-local-variable 'message-default-charset)
- ;; message-mode has font-locking, but uses its own faces. Let's
- ;; use the mu4e-specific ones instead
- (mu4e~compose-remap-faces)
- ;; if the default charset is not set, use UTF-8
- (unless message-default-charset
- (setq message-default-charset 'utf-8))
- ;; make sure mu4e is started in the background (ie. we don't want to error
- ;; out when sending the message; better to do it now if there's a problem)
- (mu4e~start) ;; start mu4e in background, if needed
- (mu4e~compose-register-message-save-hooks)
- ;; set the default directory to the user's home dir; this is probably more
- ;; useful e.g. when finding an attachment file the directory the current
- ;; mail files lives in...
- (setq default-directory (expand-file-name "~/"))
- ;; offer completion for e-mail addresses
- (when mu4e-compose-complete-addresses
- (mu4e~compose-setup-completion))
-
- (when mu4e-compose-format-flowed
- (turn-off-auto-fill)
- (setq truncate-lines nil
- word-wrap t
- use-hard-newlines t)
- ;; Set the marks in the fringes before activating visual-line-mode
- (set (make-local-variable 'visual-line-fringe-indicators)
- '(left-curly-arrow right-curly-arrow))
- (visual-line-mode t))
-
- (when (lookup-key message-mode-map [menu-bar text])
- (define-key-after
- (lookup-key message-mode-map [menu-bar text])
- [mu4e-hard-newlines]
- '(menu-item "Format=flowed" mu4e-toggle-use-hard-newlines
- :button (:toggle . use-hard-newlines)
- :help "Toggle format=flowed"
- :visible (eq major-mode 'mu4e-compose-mode)
- :enable mu4e-compose-format-flowed)
- 'sep))
-
- (when (lookup-key mml-mode-map [menu-bar Attachments])
- (define-key-after
- (lookup-key mml-mode-map [menu-bar Attachments])
- [mu4e-compose-attach-captured-message]
- '(menu-item "Attach captured message"
- mu4e-compose-attach-captured-message
- :help "Attach message captured in Headers View (with 'a c')"
- :visible (eq major-mode 'mu4e-compose-mode))
- (quote Attach\ External...)))
-
- ;; setup the fcc-stuff, if needed
- (add-hook 'message-send-hook
- (lambda () ;; mu4e~compose-save-before-sending
- ;; when in-reply-to was removed, remove references as well.
- (when (eq mu4e~compose-type 'reply)
- (mu4e~remove-refs-maybe))
- (when use-hard-newlines
- (mu4e-send-harden-newlines))
- ;; for safety, always save the draft before sending
- (set-buffer-modified-p t)
- (save-buffer)
- (mu4e~compose-setup-fcc-maybe)
- (widen)) nil t)
- ;; when the message has been sent.
- (add-hook 'message-sent-hook
- (lambda () ;; mu4e~compose-mark-after-sending
- (setq mu4e-sent-func 'mu4e-sent-handler)
- (mu4e~proc-sent (buffer-file-name) mu4e~draft-drafts-folder)) nil t))
- ;; 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-mark-after-sending 'permanent-local-hook t))
-
-(defun mu4e-send-harden-newlines ()
- "Set the hard property to all newlines."
- (save-excursion
- (goto-char (point-min))
- (while (search-forward "\n" nil t)
- (put-text-property (1- (point)) (point) 'hard t))))
-
-(defconst mu4e~compose-buffer-max-name-length 30
- "Maximum length of the mu4e-send-buffer-name.")
-
-(defvar mu4e~compose-type nil
- "Compose-type for this buffer.")
-
-(defun mu4e~compose-set-friendly-buffer-name (&optional compose-type)
- "Set some user-friendly buffer name based on the compose type."
- (let* ((subj (message-field-value "subject"))
- (subj (unless (and subj (string-match "^[:blank:]*$" subj)) subj))
- (str (or subj
- (case compose-type
- (reply "*reply*")
- (forward "*forward*")
- (otherwise "*draft*")))))
- (rename-buffer (generate-new-buffer-name
- (truncate-string-to-width str
- mu4e~compose-buffer-max-name-length
- nil nil t)))))
-
-
-(defun mu4e~compose-crypto-reply (parent compose-type)
- "When composing a reply to an encrypted message, we can
-automatically encrypt that reply."
- (message "%S %S" parent compose-type)
- (when (and (eq compose-type 'reply)
- (and parent (member 'encrypted (mu4e-message-field parent :flags))))
- (case mu4e-compose-crypto-reply-policy
- (sign (mml-secure-message-sign))
- (encrypt (mml-secure-message-encrypt))
- (sign-and-encrypt (mml-secure-message-sign-encrypt))
- (message "Do nothing"))))
-
-
-
-(defun* mu4e~compose-handler (compose-type &optional original-msg includes)
- "Create a new draft message, or open an existing one.
-
-COMPOSE-TYPE determines the kind of message to compose and is a
-symbol, either `reply', `forward', `edit', `resend' `new'. `edit'
-is for editing existing (draft) messages. When COMPOSE-TYPE is
-`reply' or `forward', MSG should be a message plist. If
-COMPOSE-TYPE is `new', ORIGINAL-MSG should be nil.
-
-Optionally (when forwarding, replying) ORIGINAL-MSG is the original
-message we will forward / reply to.
-
-Optionally (when forwarding) INCLUDES contains a list of
- (:file-name <filename> :mime-type <mime-type> :disposition <disposition>)
-for the attachements to include; file-name refers to
-a file which our backend has conveniently saved for us (as a
-tempfile)."
-
- ;; Run the hooks defined for `mu4e-compose-pre-hook'. If compose-type is
- ;; `reply', `forward' or `edit', `mu4e-compose-parent-message' points to the
- ;; message being forwarded or replied to, otherwise it is nil.
- (set (make-local-variable 'mu4e-compose-parent-message) original-msg)
- (put 'mu4e-compose-parent-message 'permanent-local t)
- ;; maybe switch the context
- (mu4e~context-autoswitch mu4e-compose-parent-message
- mu4e-compose-context-policy)
- (run-hooks 'mu4e-compose-pre-hook)
-
- ;; this opens (or re-opens) a messages with all the basic headers set.
- (let ((winconf (current-window-configuration)))
- (condition-case nil
- (mu4e-draft-open compose-type original-msg)
- (quit (set-window-configuration winconf)
- (mu4e-message "Operation aborted")
- (return-from mu4e~compose-handler))))
- ;; insert mail-header-separator, which is needed by message mode to separate
- ;; headers and body. will be removed before saving to disk
- (mu4e~draft-insert-mail-header-separator)
- ;; maybe encrypt/sign replies
- (mu4e~compose-crypto-reply original-msg compose-type)
- ;; include files -- e.g. when forwarding a message with attachments,
- ;; we take those from the original.
- (save-excursion
- (goto-char (point-max)) ;; put attachments at the end
- (dolist (att includes)
- (mml-attach-file
- (plist-get att :file-name) (plist-get att :mime-type))))
- ;; buffer is not user-modified yet
- (mu4e~compose-set-friendly-buffer-name compose-type)
- (set-buffer-modified-p nil)
- ;; now jump to some useful positions, and start writing that mail!
-
- (if (member compose-type '(new forward))
- (message-goto-to)
- (message-goto-body))
- ;; bind to `mu4e-compose-parent-message' of compose buffer
- (set (make-local-variable 'mu4e-compose-parent-message) original-msg)
- (put 'mu4e-compose-parent-message 'permanent-local t)
- ;; remember the compose-type
- (set (make-local-variable 'mu4e~compose-type) compose-type)
- (put 'mu4e~compose-type 'permanent-local t)
-
- ;; hide some headers
- (mu4e~compose-hide-headers)
- ;; switch on the mode
- (mu4e-compose-mode)
- (when mu4e-compose-in-new-frame
- ;; make sure to close the frame when we're done with the message these are
- ;; all buffer-local;
- (push 'delete-frame message-exit-actions)
- (push 'delete-frame message-postpone-actions)))
-
-(defun mu4e-sent-handler (docid path)
- "Handler function, called with DOCID and PATH for the just-sent
-message. For Forwarded ('Passed') and Replied messages, try to set
-the appropriate flag at the message forwarded or replied-to."
- (mu4e~compose-set-parent-flag path)
- (when (file-exists-p path) ;; maybe the draft was not saved at all
- (mu4e~proc-remove docid))
- ;; kill any remaining buffers for the draft file, or they will hang around...
- ;; this seems a bit hamfisted...
- (dolist (buf (buffer-list))
- (when (and (buffer-file-name buf)
- (string= (buffer-file-name buf) path))
- (if message-kill-buffer-on-exit
- (kill-buffer buf))))
- ;; now, try to go back to some previous buffer, in the order
- ;; view->headers->main
- (if (buffer-live-p mu4e~view-buffer)
- (switch-to-buffer mu4e~view-buffer)
- (if (buffer-live-p mu4e~headers-buffer)
- (switch-to-buffer mu4e~headers-buffer)
- ;; if all else fails, back to the main view
- (when (fboundp 'mu4e) (mu4e))))
- (mu4e-message "Message sent"))
-
-(defun mu4e-message-kill-buffer ()
- "Wrapper around `message-kill-buffer'.
-It restores mu4e window layout after killing the compose-buffer."
- (interactive)
- (let ((current-buffer (current-buffer)))
- (message-kill-buffer)
- ;; Compose buffer killed
- (when (not (equal current-buffer (current-buffer)))
- ;; Restore mu4e
- (if mu4e-compose-in-new-frame
- (delete-frame)
- (if (buffer-live-p mu4e~view-buffer)
- (switch-to-buffer mu4e~view-buffer)
- (if (buffer-live-p mu4e~headers-buffer)
- (switch-to-buffer mu4e~headers-buffer)
- ;; if all else fails, back to the main view
- (when (fboundp 'mu4e) (mu4e))))))))
-
-(defun mu4e~compose-set-parent-flag (path)
- "Set the 'replied' \"R\" flag on messages we replied to, and the
-'passed' \"F\" flag on message we have forwarded.
-
-If a message has an 'in-reply-to' header, it is considered a reply
-to the message with the corresponding message id. If it does not
-have an 'in-reply-to' header, but does have a 'references' header,
-it is considered to be a forward message for the message
-corresponding with the /last/ message-id in the references header.
-
-Now, if the message has been determined to be either a forwarded
-message or a reply, we instruct the server to update that message
-with resp. the 'P' (passed) flag for a forwarded message, or the
-'R' flag for a replied message. The original messages are also
-marked as Seen.
-
-Function assumes that it's executed in the context of the message
-buffer."
- (let ((buf (find-file-noselect path)))
- (when buf
- (with-current-buffer buf
- (message-narrow-to-headers-or-head)
- (let ((in-reply-to (message-fetch-field "in-reply-to"))
- (forwarded-from)
- (references (message-fetch-field "references")))
- (unless in-reply-to
- (when references
- (with-temp-buffer ;; inspired by `message-shorten-references'.
- (insert references)
- (goto-char (point-min))
- (let ((refs))
- (while (re-search-forward "<[^ <]+@[^ <]+>" nil t)
- (push (match-string 0) refs))
- ;; the last will be the first
- (setq forwarded-from (first refs))))))
- ;; remove the <>
- (when (and in-reply-to (string-match "<\\(.*\\)>" in-reply-to))
- (mu4e~proc-move (match-string 1 in-reply-to) nil "+R-N"))
- (when (and forwarded-from (string-match "<\\(.*\\)>" forwarded-from))
- (mu4e~proc-move (match-string 1 forwarded-from) nil "+P-N")))))))
-
-(defun mu4e-compose (compose-type)
- "Start composing a message of COMPOSE-TYPE, where COMPOSE-TYPE
-is a symbol, one of `reply', `forward', `edit', `resend'
-`new'. All but `new' take the message at point as input. Symbol
-`edit' is only allowed for draft messages."
- (let ((msg (mu4e-message-at-point 'noerror)))
- ;; some sanity checks
- (unless (or msg (eq compose-type 'new))
- (mu4e-warn "No message at point"))
- (unless (member compose-type '(reply forward edit resend new))
- (mu4e-error "Invalid compose type '%S'" compose-type))
- (when (and (eq compose-type 'edit)
- (not (member 'draft (mu4e-message-field msg :flags))))
- (mu4e-warn "Editing is only allowed for draft messages"))
-
- ;; 'new is special, since it takes no existing message as arg; therefore, we
- ;; don't need to involve the backend, and call the handler *directly*
- (if (eq compose-type 'new)
- (mu4e~compose-handler 'new)
- ;; otherwise, we need the doc-id
- (let* ((docid (mu4e-message-field msg :docid))
- ;; decrypt (or not), based on `mu4e-decryption-policy'.
- (decrypt
- (and (member 'encrypted (mu4e-message-field msg :flags))
- (if (eq mu4e-decryption-policy 'ask)
- (yes-or-no-p (mu4e-format "Decrypt message?"))
- mu4e-decryption-policy))))
- ;; if there's a visible view window, select that before starting composing
- ;; a new message, so that one will be replaced by the compose window. The
- ;; 10-or-so line headers buffer is not a good place to write it...
- (let ((viewwin (get-buffer-window mu4e~view-buffer)))
- (when (window-live-p viewwin)
- (select-window viewwin)))
- ;; talk to the backend
- (mu4e~proc-compose compose-type decrypt docid)))))
-
-(defun mu4e-compose-reply ()
- "Compose a reply for the message at point in the headers buffer."
- (interactive)
- (mu4e-compose 'reply))
-
-(defun mu4e-compose-forward ()
- "Forward the message at point in the headers buffer."
- (interactive)
- (mu4e-compose 'forward))
-
-(defun mu4e-compose-edit ()
- "Edit the draft message at point in the headers buffer.
-This is only possible if the message at point is, in fact, a
-draft message."
- (interactive)
- (mu4e-compose 'edit))
-
-(defun mu4e-compose-resend ()
- "Resend the message at point in the headers buffer."
- (interactive)
- (mu4e-compose 'resend))
-
-(defun mu4e-compose-new ()
- "Start writing a new message."
- (interactive)
- (mu4e-compose 'new))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; mu4e-compose-func and mu4e-send-func are wrappers so we can set ourselves
-;; 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)
- "This is mu4e's implementation of `compose-mail'."
-
- ;; create a new draft message 'resetting' (as below) is not actually needed in
- ;; this case, but let's prepare for the re-edit case as well
- (mu4e~compose-handler 'new)
-
- (when (message-goto-to) ;; reset to-address, if needed
- (message-delete-line))
- (message-add-header (concat "To: " to "\n"))
-
- (when (message-goto-subject) ;; reset subject, if needed
- (message-delete-line))
- (message-add-header (concat "Subject: " subject "\n"))
-
- ;; add any other headers specified
- (when other-headers
- (message-add-header other-headers))
-
- ;; yank message
- (if (bufferp yank-action)
- (list 'insert-buffer yank-action)
- yank-action)
-
- ;; try to put the user at some reasonable spot...
- (if (not to)
- (message-goto-to)
- (if (not subject)
- (message-goto-subject)
- (message-goto-body))))
-
-;; happily, we can re-use most things from message mode
-;;;###autoload
-(define-mail-user-agent 'mu4e-user-agent
- 'mu4e~compose-mail
- 'message-send-and-exit
- 'message-kill-buffer
- 'message-send-hook)
-;; Without this `mail-user-agent' cannot be set to `mu4e-user-agent'
-;; through customize, as the custom type expects a function. Not
-;; sure whether this function is actually ever used; if it is then
-;; returning the symbol is probably the correct thing to do, as other
-;; such functions suggest.
-(defun mu4e-user-agent ()
- 'mu4e-user-agent)
-
-(defun mu4e~compose-browse-url-mail (url &optional ignored)
- "Adapter for `browse-url-mailto-function."
- (let* ((headers (rfc2368-parse-mailto-url url))
- (to (cdr (assoc "To" headers)))
- (subject (cdr (assoc "Subject" headers)))
- (body (cdr (assoc "Body" headers))))
- (mu4e~compose-mail to subject)
- (if body
- (progn
- (message-goto-body)
- (insert body)
- (if (not to)
- (message-goto-to)
- (if (not subject)
- (message-goto-subject)
- (message-goto-body)))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun mu4e-compose-goto-top ()
- "Go to the beginning of the message or buffer.
-Go to the beginning of the message or, if already there, go to the
-beginning of the buffer."
- (interactive)
- (let ((old-position (point)))
- (message-goto-body)
- (when (equal (point) old-position)
- (goto-char (point-min)))))
-
-(define-key mu4e-compose-mode-map
- (vector 'remap 'beginning-of-buffer) 'mu4e-compose-goto-top)
-
-(defun mu4e-compose-goto-bottom ()
- "Go to the end of the message or buffer.
-Go to the end of the message (before signature) or, if already there, go to the
-end of the buffer."
- (interactive)
- (let ((old-position (point))
- (message-position (save-excursion (message-goto-body) (point))))
- (goto-char (point-max))
- (when (re-search-backward message-signature-separator message-position t)
- (forward-line -1))
- (when (equal (point) old-position)
- (goto-char (point-max)))))
-
-(define-key mu4e-compose-mode-map
- (vector 'remap 'end-of-buffer) 'mu4e-compose-goto-bottom)
-
-(provide 'mu4e-compose)
-
-;; Load mu4e completely even when this file was loaded through
-;; autoload.
-(require 'mu4e)
diff --git a/_spacemacs.d/local/mu4e/mu4e-context.el b/_spacemacs.d/local/mu4e/mu4e-context.el
deleted file mode 100644
index f5f8fff..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-context.el
+++ /dev/null
@@ -1,157 +0,0 @@
-; mu4e-context.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2015-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; A mu4e 'context' is a a set of variable-settings and functions, which can be
-;; used e.g. to switch between accounts.
-
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-(require 'cl)
-
-(require 'mu4e-utils)
-
-(defvar mu4e-contexts nil "The list of `mu4e-context' objects
-describing mu4e's contexts.")
-
-(defvar mu4e~context-current nil
- "The current context; for internal use. Use
- `mu4e-context-switch' to change it.")
-
-(defun mu4e-context-current ()
- "Get the currently active context, or nil if there is none."
- mu4e~context-current)
-
-(defun mu4e-context-label ()
- "Propertized string with the current context name, or \"\" if
- there is none."
- (if (mu4e-context-current)
- (concat "[" (propertize (mu4e~quote-for-modeline
- (mu4e-context-name (mu4e-context-current)))
- 'face 'mu4e-title-face) "]") ""))
-
-(defstruct mu4e-context
- "A mu4e context object with the following members:
-- `name': the name of the context, eg. \"Work\" or \"Private\".'
-- `enter-func': a parameterless function invoked when entering
- this context, or nil
-- `leave-func':a parameterless fuction invoked when leaving this
- context, or nil
-- `match-func': a function called when comnposing a new messages,
- and takes a message plist
-for the message replied to or forwarded, and nil
-otherwise. Before composing a new message, `mu4e' switches to the
-first context for which `match-func' return t."
- name ;; name of the context, e.g. "work"
- (enter-func nil) ;; function invoked when entering the context
- (leave-func nil) ;; function invoked when leaving the context
- (match-func nil) ;; function that takes a msg-proplist, and return t
- ;; if it matches, nil otherwise
- vars) ;; alist of variables.
-
-(defun mu4e~context-ask-user (prompt)
- "Let user choose some context based on its name."
- (when mu4e-contexts
- (let* ((names (map 'list (lambda (context)
- (cons (mu4e-context-name context) context))
- mu4e-contexts))
- (context (mu4e-read-option prompt names)))
- (or context (mu4e-error "No such context")))))
-
-(defun mu4e-context-switch (&optional force name)
- "Switch context to a context with NAME which is part of
-`mu4e-contexts'; if NAME is nil, query user.
-
-If the new context is the same and the current context, only
-switch (run associated functions) when prefix argument FORCE is
-non-nil."
- (interactive "P")
- (unless mu4e-contexts
- (mu4e-error "No contexts defined"))
- (let* ((names (map 'list (lambda (context)
- (cons (mu4e-context-name context) context))
- mu4e-contexts))
- (context
- (if name
- (cdr-safe (assoc name names))
- (mu4e~context-ask-user "Switch to context: "))))
- (unless context (mu4e-error "No such context"))
- ;; if new context is same as old one one switch with FORCE is set.
- (when (or force (not (eq context (mu4e-context-current))))
- (when (and (mu4e-context-current)
- (mu4e-context-leave-func mu4e~context-current))
- (funcall (mu4e-context-leave-func mu4e~context-current)))
- ;; enter the new context
- (when (mu4e-context-enter-func context)
- (funcall (mu4e-context-enter-func context)))
- (when (mu4e-context-vars context)
- (mapc #'(lambda (cell)
- (set (car cell) (cdr cell)))
- (mu4e-context-vars context)))
- (setq mu4e~context-current context)
- (mu4e-message "Switched context to %s" (mu4e-context-name context)))
- context))
-
-(defun mu4e~context-autoswitch (&optional msg policy)
- "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
- (let ((context (mu4e-context-determine msg policy)))
- (when context (mu4e-context-switch
- nil (mu4e-context-name context))))))
-
-(defun mu4e-context-determine (msg &optional policy)
- "Return the first context with a match-func that returns t. MSG
-points to the plist for the message replied to or forwarded, or
-nil if there is no such MSG; similar to what
-`mu4e-compose-pre-hook' does.
-
-POLICY specifies how to do the determination. If POLICY is
-'always-ask, we ask the user unconditionally.
-
-In all other cases, if any context matches (using its match
-function), this context is returned. If none of the contexts
-match, POLICY determines what to do:
-
-- pick-first: pick the first of the contexts available
-- ask: ask the user
-- ask-if-none: ask if there is no context yet
-- otherwise, return nil. Effectively, this leaves the current context as it is."
- (when mu4e-contexts
- (if (eq policy 'always-ask)
- (mu4e~context-ask-user "Select context: ")
- (or ;; is there a matching one?
- (find-if (lambda (context)
- (when (mu4e-context-match-func context)
- (funcall (mu4e-context-match-func context) msg)))
- mu4e-contexts)
- ;; no context found yet; consult policy
- (case policy
- (pick-first (car mu4e-contexts))
- (ask (mu4e~context-ask-user "Select context: "))
- (ask-if-none (or (mu4e-context-current)
- (mu4e~context-ask-user "Select context: ")))
- (otherwise nil))))))
-
-(provide 'mu4e-context)
-
diff --git a/_spacemacs.d/local/mu4e/mu4e-contrib.el b/_spacemacs.d/local/mu4e/mu4e-contrib.el
deleted file mode 100644
index 156f5b6..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-contrib.el
+++ /dev/null
@@ -1,165 +0,0 @@
-;;; mu4e-contrib.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2013-2016 Dirk-Jan C. Binnema
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Some user-contributed functions for mu4e
-
-;; Contributed by sabof
-
-(require 'mu4e)
-
-(defun mu4e-headers-mark-all-unread-read ()
- "Put a ! \(read) mark on all visible unread messages."
- (interactive)
- (mu4e-headers-mark-for-each-if
- (cons 'read nil)
- (lambda (msg param)
- (memq 'unread (mu4e-msg-field msg :flags)))))
-
-(defun mu4e-headers-flag-all-read ()
- "Flag all visible messages as \"read\"."
- (interactive)
- (mu4e-headers-mark-all-unread-read)
- (mu4e-mark-execute-all t))
-
-;;;
-
-(defun mu4e-headers-mark-all ()
- "Mark all messages within current query results and ask user to execute which action."
- (interactive)
- (mu4e-headers-mark-for-each-if
- (cons 'something nil)
- (lambda (msg param) t))
- (mu4e-mark-execute-all))
-
-;;;
-
-;;; Bookmark handlers
-;;
-;; Allow bookmarking a mu4e buffer in regular emacs bookmarks.
-
-;; Probably this can be moved to mu4e-view.el.
-(add-hook 'mu4e-view-mode-hook
- #'(lambda ()
- (set (make-local-variable 'bookmark-make-record-function)
- 'mu4e-view-bookmark-make-record)))
-;; And this can be moved to mu4e-headers.el.
-(add-hook 'mu4e-headers-mode-hook
- #'(lambda ()
- (set (make-local-variable 'bookmark-make-record-function)
- 'mu4e-view-bookmark-make-record)))
-
-(defun mu4e-view-bookmark-make-record ()
- "Make a bookmark entry for a mu4e buffer. Note that this is an
-emacs bookmark, not to be confused with `mu4e-bookmarks'."
- (let* ((msg (mu4e-message-at-point))
- (maildir (plist-get msg :maildir))
- (date (format-time-string "%Y%m%d" (plist-get msg :date)))
- (query (format "maildir:%s date:%s" maildir date))
- (docid (plist-get msg :docid))
- (mode (symbol-name major-mode))
- (subject (or (plist-get msg :subject) "No subject")))
- `(,subject
- ,@(bookmark-make-record-default 'no-file 'no-context)
- (location . (,query . ,docid))
- (mode . ,mode)
- (handler . mu4e-bookmark-jump))))
-
-(defun mu4e-bookmark-jump (bookmark)
- "Handler function for record returned by `mu4e-view-bookmark-make-record'.
-BOOKMARK is a bookmark name or a bookmark record."
- (let* ((path (bookmark-prop-get bookmark 'location))
- (mode (bookmark-prop-get bookmark 'mode))
- (docid (cdr path))
- (query (car path)))
- (call-interactively 'mu4e)
- (mu4e-headers-search query)
- (sit-for 0.5)
- (mu4e~headers-goto-docid docid)
- (mu4e~headers-highlight docid)
- (unless (string= mode "mu4e-headers-mode")
- (call-interactively 'mu4e-headers-view-message)
- (run-with-timer 0.1 nil
- (lambda (bmk)
- (bookmark-default-handler
- `("" (buffer . ,(current-buffer)) .
- ,(bookmark-get-bookmark-record bmk))))
- bookmark))))
-
-
-
-;;; handling spam with Bogofilter with possibility to define it for SpamAssassin
-;;; contributed by Gour
-
-;; to add the actions to the menu, you can use something like:
-
-;; (add-to-list 'mu4e-headers-actions
-;; '("sMark as spam" . mu4e-register-msg-as-spam) t)
-;; (add-to-list 'mu4e-headers-actions
-;; '("hMark as ham" . mu4e-register-msg-as-ham) t)
-
-(defvar mu4e-register-as-spam-cmd nil
- "Command for invoking spam processor to register message as spam,
-for example for bogofilter, use \"/usr/bin/bogofilter -Ns < %s\" ")
-
-(defvar mu4e-register-as-ham-cmd nil
- "Command for invoking spam processor to register message as ham.
-For example for bogofile, use \"/usr/bin/bogofilter -Sn < %s\"")
-
-(defun mu4e-register-msg-as-spam (msg)
- "Mark message as spam."
- (interactive)
- (let* ((path (shell-quote-argument (mu4e-message-field msg :path)))
- (command (format mu4e-register-as-spam-cmd path))) ;; re-register msg as spam
- (shell-command command))
-(mu4e-mark-at-point 'delete nil))
-
-(defun mu4e-register-msg-as-ham (msg)
- "Mark message as ham."
- (interactive)
- (let* ((path (shell-quote-argument(mu4e-message-field msg :path)))
- (command (format mu4e-register-as-ham-cmd path))) ;; re-register msg as ham
- (shell-command command))
-(mu4e-mark-at-point 'something nil))
-
-;; (add-to-list 'mu4e-view-actions
-;; '("sMark as spam" . mu4e-view-register-msg-as-spam) t)
-;; (add-to-list 'mu4e-view-actions
-;; '("hMark as ham" . mu4e-view-register-msg-as-ham) t)
-
-(defun mu4e-view-register-msg-as-spam (msg)
- "Mark message as spam (view mode)."
- (interactive)
- (let* ((path (shell-quote-argument (mu4e-message-field msg :path)))
- (command (format mu4e-register-as-spam-cmd path)))
- (shell-command command))
- (mu4e-view-mark-for-delete))
-
-(defun mu4e-view-register-msg-as-ham (msg)
- "Mark message as ham (view mode)."
- (interactive)
- (let* ((path (shell-quote-argument(mu4e-message-field msg :path)))
- (command (format mu4e-register-as-ham-cmd path)))
- (shell-command command))
- (mu4e-view-mark-for-something))
-
-;;; end of spam-filtering functions
-
-(provide 'mu4e-contrib)
diff --git a/_spacemacs.d/local/mu4e/mu4e-draft.el b/_spacemacs.d/local/mu4e/mu4e-draft.el
deleted file mode 100644
index d7df6e0..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-draft.el
+++ /dev/null
@@ -1,495 +0,0 @@
-;; mu4e-draft.el -- part of mu4e, the mu mail user agent for emacs
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; In this file, various functions to create draft messages
-
-;; Code
-
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-(require 'cl)
-
-(require 'mu4e-vars)
-(require 'mu4e-utils)
-(require 'mu4e-message)
-(require 'message) ;; mail-header-separator
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defcustom mu4e-compose-dont-reply-to-self nil
- "If non-nil, don't include self (that is, any member of
-`mu4e-user-mail-address-list') in replies."
- :type 'boolean
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-cite-function
- (or message-cite-function 'message-cite-original-without-signature)
- "The function to use to cite message in replies and forwarded
-messages. This is the mu4e-specific version of
-`message-cite-function'."
- :type 'function
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-signature
- (or message-signature "Sent with my mu4e")
- "The message signature (i.e. the blob at the bottom of
-messages). This is the mu4e-specific version of
-`message-signature'."
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-signature-auto-include t
- "Whether to automatically include a message-signature in new
-messages (if it is set)."
- :type 'boolean
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-auto-include-date nil
- "Whether to include a date header when starting to draft a
-message; if nil, only do so when sending the message."
- :type 'boolean
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-in-new-frame nil
- "Whether to compose messages in a new frame instead of the
-current window."
- :type 'boolean
- :group 'mu4e-compose)
-
-(defvar mu4e-user-agent-string
- (format "mu4e %s; emacs %s" mu4e-mu-version emacs-version)
- "The User-Agent string for mu4e.")
-
-(defun mu4e~draft-cite-original (msg)
- "Return a cited version of the original message MSG as a plist.
-This function uses `mu4e-compose-cite-function', and as such all
-its settings apply."
- (with-temp-buffer
- (when (fboundp 'mu4e-view-message-text) ;; keep bytecompiler happy
- (let ((mu4e-view-date-format "%Y-%m-%dT%T%z"))
- (insert (mu4e-view-message-text msg)))
- (message-yank-original)
- (goto-char (point-min))
- (push-mark (point-max))
- ;; set the the signature separator to 'loose', since in the real world,
- ;; many message don't follow the standard...
- (let ((message-signature-separator "^-- *$")
- (message-signature-insert-empty-line t))
- (funcall mu4e-compose-cite-function))
- (pop-mark)
- (goto-char (point-min))
- (buffer-string))))
-
-(defun mu4e~draft-header (hdr val)
- "Return a header line of the form \"HDR: VAL\".
-If VAL is nil, return nil."
- ;; note: the propertize here is currently useless, since gnus sets its own
- ;; later.
- (when val (format "%s: %s\n"
- (propertize hdr 'face 'mu4e-header-key-face)
- (propertize val 'face 'mu4e-header-value-face))))
-
-(defconst mu4e~max-reference-num 21
- "Maximum number of References:, as suggested by
-`message-shorten-references'.")
-
-(defun mu4e~shorten-1 (list cut surplus)
- "Cut SURPLUS elements out of LIST, beginning with CUTth
-one. Code borrowed from `message-shorten-1'."
- (setcdr (nthcdr (- cut 2) list)
- (nthcdr (+ (- cut 2) surplus 1) list)))
-
-(defun mu4e~draft-references-construct (msg)
- "Construct the value of the References: header based on MSG as a
-comma-separated string. Normally, this the concatenation of the
-existing References + In-Reply-To (which may be empty, an note
-that :references includes the old in-reply-to as well) and the
-message-id. If the message-id is empty, returns the old
-References. If both are empty, return nil."
- (let* ( ;; these are the ones from the message being replied to / forwarded
- (refs (mu4e-message-field msg :references))
- (msgid (mu4e-message-field msg :message-id))
- ;; now, append in
- (refs (if (and msgid (not (string= msgid "")))
- (append refs (list msgid)) refs))
- ;; no doubles
- (refs (delete-duplicates refs :test #'equal))
- (refnum (length refs))
- (cut 2))
- ;; remove some refs when there are too many
- (when (> refnum mu4e~max-reference-num)
- (let ((surplus (- refnum mu4e~max-reference-num)))
- (mu4e~shorten-1 refs cut surplus)))
- (mapconcat (lambda (id) (format "<%s>" id)) refs " ")))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; determine the recipient fields for new messages
-
-(defun mu4e~draft-recipients-list-to-string (lst)
- "Convert a lst LST of address cells into a string with a list of
-e-mail addresses. If LST is nil, returns nil."
- (when lst
- (mapconcat
- (lambda (addrcell)
- (let ((name (car addrcell))
- (email (cdr addrcell)))
- (if name
- (format "%s <%s>" (mu4e~rfc822-quoteit name) email)
- (format "%s" email))))
- lst ", ")))
-
-(defun mu4e~draft-address-cell-equal (cell1 cell2)
- "Return t if CELL1 and CELL2 have the same e-mail address.
-The comparison is done case-insensitively. If the cells done
-match return nil. CELL1 and CELL2 are cons cells of the
-form (NAME . EMAIL)."
- (string=
- (downcase (or (cdr cell1) ""))
- (downcase (or (cdr cell2) ""))))
-
-
-(defun mu4e~draft-create-to-lst (origmsg)
- "Create a list of address for the To: in a new message, based on
-the original message ORIGMSG. If the Reply-To address is set, use
-that, otherwise use the From address. Note, whatever was in the To:
-field before, goes to the Cc:-list (if we're doing a reply-to-all).
-Special case: if we were the sender of the original, we simple copy
-the list form the original."
- (let ((reply-to
- (or (plist-get origmsg :reply-to) (plist-get origmsg :from))))
- (delete-duplicates reply-to :test #'mu4e~draft-address-cell-equal)
- (if mu4e-compose-dont-reply-to-self
- (delete-if
- (lambda (to-cell)
- (member-if
- (lambda (addr)
- (string= (downcase addr) (downcase (cdr to-cell))))
- mu4e-user-mail-address-list))
- reply-to)
- reply-to)))
-
-
-(defun mu4e~draft-create-cc-lst (origmsg reply-all)
- "Create a list of address for the Cc: in a new message, based on
-the original message ORIGMSG, and whether it's a reply-all."
- (when reply-all
- (let* ((cc-lst ;; get the cc-field from the original, remove dups
- (delete-duplicates
- (append
- (plist-get origmsg :to)
- (plist-get origmsg :cc))
- :test #'mu4e~draft-address-cell-equal))
- ;; now we have the basic list, but we must remove
- ;; addresses also in the to list
- (cc-lst
- (delete-if
- (lambda (cc-cell)
- (find-if
- (lambda (to-cell)
- (mu4e~draft-address-cell-equal cc-cell to-cell))
- (mu4e~draft-create-to-lst origmsg)))
- cc-lst))
- ;; finally, we need to remove ourselves from the cc-list
- ;; unless mu4e-compose-keep-self-cc is non-nil
- (cc-lst
- (if (or mu4e-compose-keep-self-cc (null user-mail-address))
- cc-lst
- (delete-if
- (lambda (cc-cell)
- (member-if
- (lambda (addr)
- (string= (downcase addr) (downcase (cdr cc-cell))))
- mu4e-user-mail-address-list))
- cc-lst))))
- cc-lst)))
-
-(defun mu4e~draft-recipients-construct (field origmsg &optional reply-all)
- "Create value (a string) for the recipient field FIELD (a
-symbol, :to or :cc), based on the original message ORIGMSG,
-and (optionally) REPLY-ALL which indicates this is a reply-to-all
-message. Return nil if there are no recipients for the particular field."
- (mu4e~draft-recipients-list-to-string
- (case field
- (:to
- (mu4e~draft-create-to-lst origmsg))
- (:cc
- (mu4e~draft-create-cc-lst origmsg reply-all))
- (otherwise
- (mu4e-error "Unsupported field")))))
-
-
-(defun mu4e~draft-from-construct ()
- "Construct a value for the From:-field of the reply to MSG,
-based on `user-full-name' and `user-mail-address'; if the latter is
-nil, function returns nil."
- (when user-mail-address
- (if user-full-name
- (format "%s <%s>" (mu4e~rfc822-quoteit user-full-name) user-mail-address)
- (format "%s" user-mail-address))))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e~draft-insert-mail-header-separator ()
- "Insert `mail-header-separator' in the first empty line of the message.
-`message-mode' needs this line to know where the headers end and
-the body starts. Note, in `mu4e-compose-mode', we use
-`before-save-hook' and `after-save-hook' to ensure that this
-separator is never written to the message file. Also see
-`mu4e-remove-mail-header-separator'."
- ;; we set this here explicitly, since (as it has happened) a wrong
- ;; value for this (such as "") breaks address completion and other things
- (set (make-local-variable 'mail-header-separator) "--text follows this line--")
- (put 'mail-header-separator 'permanent-local t)
- (save-excursion
- ;; make sure there's not one already
- (mu4e~draft-remove-mail-header-separator)
- (let ((sepa (propertize mail-header-separator
- 'intangible t
- ;; don't make this read-only, message-mode
- ;; seems to require it being writable in some cases
- ;;'read-only "Can't touch this"
- 'rear-nonsticky t
- 'font-lock-face 'mu4e-compose-separator-face)))
- (widen)
- ;; search for the first empty line
- (goto-char (point-min))
- (if (search-forward-regexp "^$" nil t)
- (replace-match sepa)
- (progn ;; no empty line? then prepend one
- (goto-char (point-max))
- (insert "\n" sepa))))))
-
-(defun mu4e~draft-remove-mail-header-separator ()
- "Remove `mail-header-separator; we do this before saving a
-file (and restore it afterwards), to ensure that the separator
-never hits the disk. Also see `mu4e~draft-insert-mail-header-separator."
- (save-excursion
- (widen)
- (goto-char (point-min))
- ;; remove the --text follows this line-- separator
- (when (search-forward-regexp (concat "^" mail-header-separator) nil t)
- (let ((inhibit-read-only t))
- (replace-match "")))))
-
-
-(defun mu4e~draft-reply-all-p (origmsg)
- "Ask user whether she wants to reply to *all* recipients.
-If there is just one recipient of ORIGMSG do nothing."
- (let* ((recipnum
- (+ (length (mu4e~draft-create-to-lst origmsg))
- (length (mu4e~draft-create-cc-lst origmsg t))))
- (response
- (if (= recipnum 1)
- 'all ;; with one recipient, we can reply to 'all'....
- (mu4e-read-option
- "Reply to "
- `( (,(format "all %d recipients" recipnum) . all)
- ("sender only" . sender-only))))))
- (eq response 'all)))
-
-(defun mu4e~draft-message-filename-construct (&optional flagstr)
- "Construct a randomized name for a message file with flags FLAGSTR.
-It looks something like
- <time>-<random>.<hostname>:2,
-You can append flags."
- (let* ((sysname (if (fboundp 'system-name)
- (system-name)
- (with-no-warnings system-name)))
- (hostname (downcase
- (save-match-data
- (substring sysname
- (string-match "^[^.]+" sysname)
- (match-end 0))))))
- (format "%s.%04x%04x%04x%04x.%s:2,%s"
- (format-time-string "%s" (current-time))
- (random 65535) (random 65535) (random 65535) (random 65535)
- hostname (or flagstr ""))))
-
-(defun mu4e~draft-common-construct ()
- "Construct the common headers for each message."
- (concat
- (mu4e~draft-header "User-agent" mu4e-user-agent-string)
- (when mu4e-compose-auto-include-date
- (mu4e~draft-header "Date" (message-make-date)))))
-
-(defconst mu4e~draft-reply-prefix "Re: "
- "String to prefix replies with.")
-
-(defun mu4e~draft-reply-construct (origmsg)
- "Create a draft message as a reply to original message
-ORIGMSG. Replying-to-self is a special; in that case, the To and Cc
-fields will be the same as in the original."
- (let* ((reply-to-self (mu4e-message-contact-field-matches-me origmsg :from))
- (recipnum
- (+ (length (mu4e~draft-create-to-lst origmsg))
- (length (mu4e~draft-create-cc-lst origmsg t))))
- ;; reply-to-self implies reply-all
- (reply-all (or reply-to-self (mu4e~draft-reply-all-p origmsg)))
- (old-msgid (plist-get origmsg :message-id))
- (subject
- (concat mu4e~draft-reply-prefix
- (message-strip-subject-re (or (plist-get origmsg :subject) "")))))
- (concat
- (mu4e~draft-header "From" (or (mu4e~draft-from-construct) ""))
- (mu4e~draft-header "Reply-To" mu4e-compose-reply-to-address)
-
- (if reply-to-self
- ;; When we're replying to ourselves, simply keep the same headers.
- (concat
- (mu4e~draft-header "To" (mu4e~draft-recipients-list-to-string
- (mu4e-message-field origmsg :to)))
- (mu4e~draft-header "Cc" (mu4e~draft-recipients-list-to-string
- (mu4e-message-field origmsg :cc))))
-
- ;; if there's no-one in To, copy the CC-list
- (if (zerop (length (mu4e~draft-create-to-lst origmsg)))
- (mu4e~draft-header "To" (mu4e~draft-recipients-construct
- :cc origmsg reply-all))
- ;; otherwise...
- (concat
- (mu4e~draft-header "To" (mu4e~draft-recipients-construct :to origmsg))
- (mu4e~draft-header "Cc" (mu4e~draft-recipients-construct :cc origmsg
- reply-all)))))
- (mu4e~draft-header "Subject" subject)
- (mu4e~draft-header "References"
- (mu4e~draft-references-construct origmsg))
- (mu4e~draft-common-construct)
- (when old-msgid
- (mu4e~draft-header "In-reply-to" (format "<%s>" old-msgid)))
- "\n\n"
- (mu4e~draft-cite-original origmsg))))
-
-(defconst mu4e~draft-forward-prefix "Fwd: "
- "String to prefix replies with.")
-
-(defun mu4e~draft-forward-construct (origmsg)
- "Create a draft forward message for original message ORIGMSG."
- (let ((subject
- (or (plist-get origmsg :subject) "")))
- (concat
- (mu4e~draft-header "From" (or (mu4e~draft-from-construct) ""))
- (mu4e~draft-header "Reply-To" mu4e-compose-reply-to-address)
- (mu4e~draft-header "To" "")
- (mu4e~draft-common-construct)
- (mu4e~draft-header "References"
- (mu4e~draft-references-construct origmsg))
- (mu4e~draft-header "Subject"
- (concat
- ;; if there's no Fwd: yet, prepend it
- (if (string-match "^Fwd:" subject)
- ""
- mu4e~draft-forward-prefix)
- subject))
- "\n\n"
- (mu4e~draft-cite-original origmsg))))
-
-(defun mu4e~draft-newmsg-construct ()
- "Create a new message."
- (concat
- (mu4e~draft-header "From" (or (mu4e~draft-from-construct) ""))
- (mu4e~draft-header "Reply-To" mu4e-compose-reply-to-address)
- (mu4e~draft-header "To" "")
- (mu4e~draft-header "Subject" "")
- (mu4e~draft-common-construct)))
-
-(defvar mu4e~draft-drafts-folder nil
- "The drafts-folder for this compose buffer, based on
-`mu4e-drafts-folder', which is evaluated once.")
-
-(defun mu4e~draft-open-file (path)
- "Open the the draft file at PATH."
- (if mu4e-compose-in-new-frame
- (find-file-other-frame path)
- (find-file path)))
-
-(defun mu4e~draft-determine-path (draft-dir)
- "Determine the path for a new draft file."
- (format "%s/%s/cur/%s"
- mu4e-maildir draft-dir (mu4e~draft-message-filename-construct "DS")))
-
-
-(defun mu4e-draft-open (compose-type &optional msg)
- "Open a draft file for a new message (when COMPOSE-TYPE is `reply',
- `forward' or `new'), open an existing draft (when COMPOSE-TYPE
-is `edit'), 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
-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 "mu4e-maildir not set"))
- (let ((draft-dir nil))
- (case compose-type
-
- (edit
- ;; case-1: re-editing a draft messages. in this case, we do know the
- ;; full path, but we cannot really know 'drafts folder'... we make a
- ;; guess
- (setq draft-dir (mu4e~guess-maildir (mu4e-message-field msg :path)))
- (mu4e~draft-open-file (mu4e-message-field msg :path)))
-
- (resend
- ;; case-2: copy some exisisting message to a draft message, then edit
- ;; that.
- (setq draft-dir (mu4e~guess-maildir (mu4e-message-field msg :path)))
- (let ((draft-path (mu4e~draft-determine-path draft-dir)))
- (copy-file (mu4e-message-field msg :path) draft-path)
- (mu4e~draft-open-file draft-path)))
-
- ((reply forward new)
- ;; case-3: creating a new message; in this case, we can determine
- ;; mu4e-get-drafts-folder
- (setq draft-dir (mu4e-get-drafts-folder msg))
- (let ((draft-path (mu4e~draft-determine-path draft-dir))
- (initial-contents
- (case compose-type
- (reply (mu4e~draft-reply-construct msg))
- (forward (mu4e~draft-forward-construct msg))
- (new (mu4e~draft-newmsg-construct)))))
- (mu4e~draft-open-file draft-path)
- (insert initial-contents)
- (newline)
- ;; include the message signature (if it's set)
- (if (and mu4e-compose-signature-auto-include mu4e-compose-signature)
- (let ((message-signature mu4e-compose-signature))
- (save-excursion
- (message-insert-signature)
- (mu4e~fontify-signature))))))
- (t (mu4e-error "unsupported compose-type %S" compose-type)))
- ;; if we didn't find a draft folder yet, try some default
- (unless draft-dir
- (setq draft-dir (mu4e-get-drafts-folder msg)))
- ;; evaluate mu4e~drafts-drafts-folder once, here, and use that value
- ;; throughout.
- (set (make-local-variable 'mu4e~draft-drafts-folder) draft-dir)
- (put 'mu4e~draft-drafts-folder 'permanent-local t)
- (unless mu4e~draft-drafts-folder
- (mu4e-error "failed to determine drafts folder"))))
-
-
-(provide 'mu4e-draft)
diff --git a/_spacemacs.d/local/mu4e/mu4e-headers.el b/_spacemacs.d/local/mu4e/mu4e-headers.el
deleted file mode 100644
index e137c02..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-headers.el
+++ /dev/null
@@ -1,1717 +0,0 @@
-;;; mu4e-headers.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; In this file are function related mu4e-headers-mode, to creating the list of
-;; one-line descriptions of emails, aka 'headers' (not to be confused with
-;; headers like 'To:' or 'Subject:')
-
-;; Code:
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-(require 'cl)
-
-(require 'fringe)
-(require 'hl-line)
-
-(require 'mu4e-utils) ;; utility functions
-(require 'mu4e-proc)
-(require 'mu4e-vars)
-(require 'mu4e-mark)
-(require 'mu4e-compose)
-(require 'mu4e-actions)
-(require 'mu4e-message)
-
-;; the headers view
-(defgroup mu4e-headers nil
- "Settings for the headers view."
- :group 'mu4e)
-
-(defcustom mu4e-headers-fields
- '( (:human-date . 12)
- (:flags . 6)
- (:mailing-list . 10)
- (:from . 22)
- (:subject . nil))
- "A list of header fields to show in the headers buffer.
-Each element has the form (HEADER . WIDTH), where HEADER is one of
-the available headers (see `mu4e-header-info') and WIDTH is the
-respective width in characters. A width of `nil' means
-'unrestricted', and this is best reserved for the rightmost (last)
-field. Note that emacs may become very slow with excessively long
-lines (1000s of characters), so if you regularly get such messages,
-you want to avoid fields with `nil' altogether."
- :type `(repeat (cons (choice ,@(mapcar (lambda (h)
- (list 'const :tag
- (plist-get (cdr h) :help)
- (car h)))
- mu4e-header-info))
- (choice (integer :tag "width")
- (const :tag "unrestricted width" nil))))
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-date-format "%x"
- "Date format to use in the headers view.
-In the format of `format-time-string'."
- :type 'string
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-time-format "%X"
- "Time format to use in the headers view.
-In the format of `format-time-string'."
- :type 'string
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-long-date-format "%c"
- "Date format to use in the headers view tooltip.
-In the format of `format-time-string'."
- :type 'string
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-visible-lines 10
- "Number of lines to display in the header view when using the
-horizontal split-view. This includes the header-line at the top,
-and the mode-line."
- :type 'integer
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-visible-columns 30
- "Number of columns to display for the header view when using the
-vertical split-view."
- :type 'integer
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-auto-update t
- "Whether to automatically update the current headers buffer if an
-indexing operation showed changes."
- :type 'boolean
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-results-limit 500
- "Maximum number of results to show; this affects performance
-quite a bit, especially when `mu4e-headers-include-related' is
-non-nil. Set to -1 for no limits, and you temporarily (for one
-query) ignore the limit by pressing a C-u before invoking the
-search."
- :type '(choice (const :tag "Unlimited" -1)
- (integer :tag "Limit"))
- :group 'mu4e-headers)
-
-(make-obsolete-variable 'mu4e-search-results-limit
- 'mu4e-headers-results-limit "0.9.9.5-dev6")
-
-(defcustom mu4e-headers-skip-duplicates nil
- "With this option set to non-nil, show only one of duplicate
-messages. This is useful when you have multiple copies of the same
-message, which is a common occurence for example when using Gmail
-and offlineimap."
- :type 'boolean
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-include-related nil
- "With this option set to non-nil, not just return the matches for
-a searches, but also messages that are related (through their
-references) to these messages. This can be useful e.g. to include
-sent messages into message threads."
- :type 'boolean
- :group 'mu4e-headers)
-
-
-(defvar mu4e-headers-hide-predicate nil
- "Predicate function applied to headers before they are shown;
-if function is nil or evaluates to nil, show the header,
-otherwise don't. function takes one parameter MSG, which is the
-message plist for the message to be hidden or not.
-
-Example that hides all 'trashed' messages:
- (setq mu4e-headers-hide-predicate
- (lambda (msg)
- (member 'trashed (mu4e-message-field msg :flags))))
-
-Note that this is merely a display filter.")
-
-
-(defcustom mu4e-headers-visible-flags
- '(draft flagged new passed replied seen trashed attach encrypted signed unread)
- "An ordered list of flags to show in the headers buffer. Each
-element is a symbol in the list (DRAFT FLAGGED NEW PASSED
-REPLIED SEEN TRASHED ATTACH ENCRYPTED SIGNED UNREAD)."
- :type '(set
- (const :tag "Draft" draft)
- (const :tag "Flagged" flagged)
- (const :tag "New" new)
- (const :tag "Passed" passed)
- (const :tag "Replied" replied)
- (const :tag "Seen" seen)
- (const :tag "Trashed" trashed)
- (const :tag "Attach" attach)
- (const :tag "Encrypted" encrypted)
- (const :tag "Signed" signed)
- (const :tag "Unread" unread))
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-found-hook nil
- "Hook run just *after* all of the headers for the last search
-query have been received and are displayed."
- :type 'hook
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-search-bookmark-hook nil
- "Hook run just after we invoke a bookmarked search. This
-function receives the query as its parameter.
-
-The reason to use this instead of `mu4e-headers-search-hook'
-is if you only want to execute a hook when a search is entered
-via a bookmark, e.g. if you'd like to treat the bookmarks as a
-custom folder and change the options for the search,
-e.g. `mu4e-headers-show-threads', `mu4e-headers-include-related',
-`mu4e-headers-skip-duplicates` or `mu4e-headers-results-limit'."
- :type 'hook
- :group 'mu4e-headers)
-
-(defcustom mu4e-headers-search-hook nil
- "Hook run just before executing a new search operation. This
-function receives the query as its parameter.
-
-This is a more general hook facility than the
-`mu4e-headers-search-bookmark-hook'. It gets called on every
-executed search, not just those that are invoked via bookmarks,
-but also manually invoked searches."
- :type 'hook
- :group 'mu4e-headers)
-
-(defvar mu4e-headers-sort-field :date
- "Field to sort the headers by.
-Field must be a symbol, one of: :date, :subject, :size, :prio,
-:from, :to.")
-
-(defvar mu4e-headers-sort-direction 'descending
- "Direction to sort by; a symbol either `descending' (sorting
- Z->A) or `ascending' (sorting A->Z).")
-
-;; marks for headers of the form; each is a cons-cell (basic . fancy)
-;; each of which is basic ascii char and something fancy, respectively
-(defvar mu4e-headers-draft-mark '("D" . "âš’") "Draft.")
-(defvar mu4e-headers-flagged-mark '("F" . "✚") "Flagged.")
-(defvar mu4e-headers-new-mark '("N" . "✱") "New.")
-(defvar mu4e-headers-passed-mark '("P" . "â¯") "Passed (fwd).")
-(defvar mu4e-headers-replied-mark '("R" . "â®") "Replied.")
-(defvar mu4e-headers-seen-mark '("S" . "✔") "Seen.")
-(defvar mu4e-headers-trashed-mark '("T" . "âš") "Trashed.")
-(defvar mu4e-headers-attach-mark '("a" . "âš“") "W/ attachments.")
-(defvar mu4e-headers-encrypted-mark '("x" . "âš´") "Encrypted.")
-(defvar mu4e-headers-signed-mark '("s" . "☡") "Signed.")
-(defvar mu4e-headers-unread-mark '("u" . "⎕") "Unread.")
-
-;; thread prefix marks
-(defvar mu4e-headers-has-child-prefix '("+" . "â—¼ ") "Parent.")
-(defvar mu4e-headers-empty-parent-prefix '("-" . "â—½ ") "Orphan.")
-(defvar mu4e-headers-first-child-prefix '("\\" . "â”—â–¶") "First child.")
-(defvar mu4e-headers-duplicate-prefix '("=" . "≡ ") "Duplicate.")
-(defvar mu4e-headers-default-prefix '("|" . "│ ") "Default.")
-
-(defvar mu4e-headers-actions
- '( ("capture message" . mu4e-action-capture-message)
- ("show this thread" . mu4e-action-show-thread))
- "List of actions to perform on messages in the headers list.
-The actions are of the form (NAME SHORTCUT FUNC) where:
-* NAME is the name of the action (e.g. \"Count lines\")
-* SHORTCUT is a one-character shortcut to call this action
-* FUNC is a function which receives a message plist as an argument.")
-
-(defvar mu4e-headers-custom-markers
- '(("Older than"
- (lambda (msg date) (time-less-p (mu4e-msg-field msg :date) date))
- (lambda () (mu4e-get-time-date "Match messages before: ")))
- ("Newer than"
- (lambda (msg date) (time-less-p date (mu4e-msg-field msg :date)))
- (lambda () (mu4e-get-time-date "Match messages after: ")))
- ("Bigger than"
- (lambda (msg bytes) (> (mu4e-msg-field msg :size) (* 1024 bytes)))
- (lambda () (read-number "Match messages bigger than (Kbytes): "))))
- "List of custom markers -- functions to mark message that match
-some custom function. Each of the list members has the following format:
- (NAME PREDICATE-FUNC PARAM-FUNC)
-* NAME is the name of the predicate function, and the first character
-is the shortcut (so keep those unique).
-* PREDICATE-FUNC is a function that takes two parameters, MSG
-and (optionally) PARAM, and should return non-nil when there's a
-match.
-* PARAM-FUNC is function that is evaluated once, and its value is then passed to
-PREDICATE-FUNC as PARAM. This is useful for getting user-input.")
-
-(defvar mu4e-headers-show-threads t
- "Whether to show threads in the headers list.")
-
-(defvar mu4e-headers-full-search nil
- "Whether to show all results.
-If this is nil show results up to `mu4e-search-results-limit')")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;; internal variables/constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; docid cookies
-(defconst mu4e~headers-docid-pre "\376"
- "Each header starts (invisibly) with the `mu4e~headers-docid-pre',
-followed by the docid, followed by `mu4e~headers-docid-post'.")
-(defconst mu4e~headers-docid-post "\377"
- "Each header starts (invisibly) with the `mu4e~headers-docid-pre',
-followed by the docid, followed by `mu4e~headers-docid-post'.")
-
-(defvar mu4e~headers-view-win nil
- "The view window connected to this headers view.")
-
-(defvar mu4e~headers-sort-field-choices
- '( ("date" . :date)
- ("from" . :from)
- ("prio" . :prio)
- ("zsize" . :size)
- ("subject" . :subject)
- ("to" . :to))
- "List of cells describing the various sort-options.
-In the format needed for `mu4e-read-option'.")
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun mu4e~headers-clear ()
- "Clear the header buffer and related data structures."
- (when (buffer-live-p mu4e~headers-buffer)
- (let ((inhibit-read-only t))
- (with-current-buffer mu4e~headers-buffer
- (setq mu4e~view-msg nil)
- (mu4e~mark-clear)
- (erase-buffer)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; handler functions
-;;
-;; next are a bunch of handler functions; those will be called from mu4e~proc in
-;; response to output from the server process
-
-(defun mu4e~headers-view-handler (msg)
- "Handler function for displaying a message."
- (mu4e-view msg mu4e~headers-buffer))
-
-(defun mu4e~headers-view-this-message-p (docid)
- "Is DOCID currently being viewed?"
- (let ((viewbuf (get-buffer mu4e~view-buffer-name)))
- (when (and viewbuf (buffer-live-p viewbuf))
- (with-current-buffer viewbuf
- (eq docid (plist-get mu4e~view-msg :docid))))))
-
-(defun mu4e~headers-update-handler (msg is-move)
- "Update handler, will be called when a message has been updated
-in the database. This function will update the current list of
-headers."
- (when (buffer-live-p mu4e~headers-buffer)
- (with-current-buffer mu4e~headers-buffer
- (let* ((docid (mu4e-message-field msg :docid))
- (initial-message-at-point (mu4e~headers-docid-at-point))
- (initial-column (current-column))
- (point (mu4e~headers-docid-pos docid)))
-
- (when point ;; is the message present in this list?
-
- ;; if it's marked, unmark it now
- (when (mu4e-mark-docid-marked-p docid)
- (mu4e-mark-set 'unmark))
-
- ;; re-use the thread info from the old one; this is needed because
- ;; *update* messages don't have thread info by themselves (unlike
- ;; search results)
- ;; since we still have the search results, re-use
- ;; those
- (plist-put msg :thread
- (mu4e~headers-field-for-docid docid :thread))
-
- ;; first, remove the old one (otherwise, we'd have two headers with
- ;; the same docid...
- (mu4e~headers-remove-handler docid)
-
- ;; if we're actually viewing this message (in mu4e-view mode), we
- ;; update it; that way, the flags can be updated, as well as the path
- ;; (which is useful for viewing the raw message)
- (when (mu4e~headers-view-this-message-p docid)
- (mu4e-view msg mu4e~headers-buffer))
- ;; now, if this update was about *moving* a message, we don't show it
- ;; anymore (of course, we cannot be sure if the message really no
- ;; longer matches the query, but this seem a good heuristic. if it
- ;; was only a flag-change, show the message with its updated flags.
- (unless is-move
- (mu4e~headers-header-handler msg point))
-
- (if (and initial-message-at-point
- (mu4e~headers-goto-docid initial-message-at-point))
- (progn
- (move-to-column initial-column)
- (mu4e~headers-highlight initial-message-at-point))
- ;; attempt to highlight the corresponding line and make it visible
- (mu4e~headers-highlight docid)))))))
-
-(defun mu4e~headers-remove-handler (docid)
- "Remove handler, will be called when a message with DOCID has
-been removed from the database. This function will hide the removed
-message from the current list of headers. If the message is not
-present, don't do anything."
- (when (buffer-live-p mu4e~headers-buffer)
- (with-current-buffer mu4e~headers-buffer
- (mu4e~headers-remove-header docid t)
-
- ;; if we were viewing this message, close it now.
- (when (and (mu4e~headers-view-this-message-p docid)
- (buffer-live-p mu4e~view-buffer))
- (with-current-buffer mu4e~view-buffer
- ;; XXX it seems this sometimes fails; investigate;
- ;; for now, just ignore the error
- (ignore-errors
- (kill-buffer-and-window)))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defsubst mu4e~headers-contact-str (contacts)
- "Turn the list of contacts CONTACTS (with elements (NAME . EMAIL)
-into a string."
- (mapconcat
- (lambda (ct)
- (let ((name (car ct)) (email (cdr ct)))
- (or name email "?"))) contacts ", "))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defsubst mu4e~headers-thread-prefix (thread)
- "Calculate the thread prefix based on thread info THREAD."
- (when thread
- (let ((get-prefix
- (lambda (cell) (if mu4e-use-fancy-chars (cdr cell) (car cell)))))
- (concat
- (make-string (* (if (plist-get thread :empty-parent) 0 1)
- (plist-get thread :level)) ?\s)
- (cond
- ((plist-get thread :has-child)
- (funcall get-prefix mu4e-headers-has-child-prefix))
- ((plist-get thread :empty-parent)
- (funcall get-prefix mu4e-headers-empty-parent-prefix))
- ((plist-get thread :first-child)
- (funcall get-prefix mu4e-headers-first-child-prefix))
- ((plist-get thread :duplicate)
- (funcall get-prefix mu4e-headers-duplicate-prefix))
- (t
- (funcall get-prefix mu4e-headers-default-prefix)))
- " "))))
-
-(defsubst mu4e~headers-flags-str (flags)
- "Get a display string for the flags.
-Note that `mu4e-flags-to-string' is for internal use only; this
-function is for display. (This difference is significant, since
-internally, the Maildir spec determines what the flags look like,
-while our display may be different)."
- (let ((str "")
- (get-prefix
- (lambda (cell) (if mu4e-use-fancy-chars (cdr cell) (car cell)))))
- (dolist (flag mu4e-headers-visible-flags)
- (when (member flag flags)
- (setq str
- (concat str
- (case flag
- ('draft (funcall get-prefix mu4e-headers-draft-mark))
- ('flagged (funcall get-prefix mu4e-headers-flagged-mark))
- ('new (funcall get-prefix mu4e-headers-new-mark))
- ('passed (funcall get-prefix mu4e-headers-passed-mark))
- ('replied (funcall get-prefix mu4e-headers-replied-mark))
- ('seen (funcall get-prefix mu4e-headers-seen-mark))
- ('trashed (funcall get-prefix mu4e-headers-trashed-mark))
- ('attach (funcall get-prefix mu4e-headers-attach-mark))
- ('encrypted (funcall get-prefix mu4e-headers-encrypted-mark))
- ('signed (funcall get-prefix mu4e-headers-signed-mark))
- ('unread (funcall get-prefix mu4e-headers-unread-mark)))))))
- str))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defconst mu4e-headers-from-or-to-prefix '("" . "To ")
- "Prefix for the :from-or-to field.
-It's a cons cell with the car element being the From: prefix, the
-cdr element the To: prefix.")
-
-(defsubst mu4e~headers-from-or-to (msg)
- "When the from address for message MSG is one of the the user's addresses,
-\(as per `mu4e-user-mail-address-list'), show the To address;
-otherwise ; show the from address; prefixed with the appropriate
-`mu4e-headers-from-or-to-prefix'."
- (let ((addr (cdr-safe (car-safe (mu4e-message-field msg :from)))))
- (if (mu4e-user-mail-address-p addr)
- (concat (cdr mu4e-headers-from-or-to-prefix)
- (mu4e~headers-contact-str (mu4e-message-field msg :to)))
- (concat (car mu4e-headers-from-or-to-prefix)
- (mu4e~headers-contact-str (mu4e-message-field msg :from))))))
-
-(defsubst mu4e~headers-human-date (msg)
- "Show a 'human' date.
-If the date is today, show the time, otherwise, show the
-date. The formats used for date and time are
-`mu4e-headers-date-format' and `mu4e-headers-time-format'."
- (let ((date (mu4e-msg-field msg :date)))
- (if (equal date '(0 0 0))
- "None"
- (let ((day1 (decode-time date))
- (day2 (decode-time (current-time))))
- (if (and
- (eq (nth 3 day1) (nth 3 day2)) ;; day
- (eq (nth 4 day1) (nth 4 day2)) ;; month
- (eq (nth 5 day1) (nth 5 day2))) ;; year
- (format-time-string mu4e-headers-time-format date)
- (format-time-string mu4e-headers-date-format date))))))
-
-
-(defsubst mu4e~headers-thread-subject (msg)
- "Get the subject if it is the first one in a thread; otherwise,
-return the thread-prefix without the subject-text. In other words,
-show the subject of a thread only once, similar to e.g. 'mutt'."
- (let* ((tinfo (mu4e-message-field msg :thread))
- (subj (mu4e-msg-field msg :subject)))
- (concat ;; prefix subject with a thread indicator
- (mu4e~headers-thread-prefix tinfo)
- (if (or (not tinfo) (zerop (plist-get tinfo :level))
- (plist-get tinfo :empty-parent))
- (truncate-string-to-width subj 600) ""))))
-
-
-(defsubst mu4e~headers-mailing-list (list)
- "Get some identifier for the mailing list."
- (if list
- (propertize (mu4e-get-mailing-list-shortname list) 'help-echo list)
- ""))
-
-(defun mu4e~headers-custom-field (msg field)
- "Show some custom header field, or raise an error if it is not
-found."
- (let* ((item (or (assoc field mu4e-header-info-custom)
- (mu4e-error "field %S not found" field)))
- (func (or (plist-get (cdr-safe item) :function)
- (mu4e-error "no :function defined for field %S %S"
- field (cdr item)))))
- (funcall func msg)))
-
-(defun mu4e~headers-field-apply-basic-properties (msg field val width)
- (case field
- (:subject
- (concat ;; prefix subject with a thread indicator
- (mu4e~headers-thread-prefix (mu4e-message-field msg :thread))
- ;; "["(plist-get (mu4e-message-field msg :thread) :path) "] "
- ;; work-around: emacs' display gets really slow when lines are too long;
- ;; so limit subject length to 600
- (truncate-string-to-width val 600)))
- (:thread-subject (mu4e~headers-thread-subject msg))
- ((:maildir :path :message-id) val)
- ((:to :from :cc :bcc) (mu4e~headers-contact-str val))
- ;; if we (ie. `user-mail-address' is the 'From', show
- ;; 'To', otherwise show From
- (:from-or-to (mu4e~headers-from-or-to msg))
- (:date (format-time-string mu4e-headers-date-format val))
- (:mailing-list (mu4e~headers-mailing-list val))
- (:human-date (propertize (mu4e~headers-human-date msg)
- 'help-echo (format-time-string
- mu4e-headers-long-date-format
- (mu4e-msg-field msg :date))))
- (:flags (propertize (mu4e~headers-flags-str val)
- 'help-echo (format "%S" val)))
- (:tags (propertize (mapconcat 'identity val ", ")))
- (:size (mu4e-display-size val))
- (t (mu4e~headers-custom-field msg field))))
-
-(defun mu4e~headers-field-truncate-to-width (_msg _field val width)
- "Truncate VAL to WIDTH."
- (if width
- (truncate-string-to-width val width 0 ?\s t)
- val))
-
-(defvar mu4e~headers-field-handler-functions
- '(mu4e~headers-field-apply-basic-properties
- mu4e~headers-field-truncate-to-width))
-
-(defun mu4e~headers-field-handler (f-w msg)
- "Create a description of the field of MSG described by F-W."
- (let* ((field (car f-w))
- (width (cdr f-w))
- (val (mu4e-message-field msg (car f-w))))
- (dolist (func mu4e~headers-field-handler-functions)
- (setq val (funcall func msg field val width)))
- val))
-
-(defvar mu4e~headers-line-handler-functions
- '(mu4e~headers-line-apply-flag-face))
-
-(defun mu4e~headers-line-apply-flag-face (msg line)
- "Adjust LINE's face property based on FLAGS."
- (let* ((flags (mu4e-message-field msg :flags))
- (face (cond
- ((memq 'trashed flags) 'mu4e-trashed-face)
- ((memq 'draft flags) 'mu4e-draft-face)
- ((or (memq 'unread flags) (memq 'new flags))
- 'mu4e-unread-face)
- ((memq 'flagged flags) 'mu4e-flagged-face)
- ((memq 'replied flags) 'mu4e-replied-face)
- ((memq 'passed flags) 'mu4e-forwarded-face)
- (t 'mu4e-header-face))))
- ;; hmmm, this only works with emacs 24.4+
- (when (fboundp 'add-face-text-property)
- (add-face-text-property 0 (length line) face t line))
- line))
-
-(defun mu4e~headers-line-handler (msg line)
- (dolist (func mu4e~headers-line-handler-functions)
- (setq line (funcall func msg line)))
- line)
-
-;; note: this function is very performance-sensitive
-(defun mu4e~headers-header-handler (msg &optional point)
- "Create a one line description of MSG in this buffer, at POINT,
-if provided, or at the end of the buffer otherwise."
- (unless (and mu4e-headers-hide-predicate
- (funcall mu4e-headers-hide-predicate msg))
- (let ((docid (mu4e-message-field msg :docid))
- (line (mapconcat (lambda (f-w)
- (mu4e~headers-field-handler f-w msg))
- mu4e-headers-fields " ")))
- (setq line (mu4e~headers-line-handler msg line))
- (mu4e~headers-add-header line docid point msg))))
-
-(defconst mu4e~no-matches "No matching messages found")
-(defconst mu4e~end-of-results "End of search results")
-
-(defun mu4e~headers-found-handler (count)
- "Create a one line description of the number of headers found
-after the end of the search results."
- (when (buffer-live-p mu4e~headers-buffer)
- (with-current-buffer mu4e~headers-buffer
- (save-excursion
- (goto-char (point-max))
- (let ((inhibit-read-only t)
- (str (if (zerop count) mu4e~no-matches mu4e~end-of-results)))
- (insert (propertize str 'face 'mu4e-system-face 'intangible t))
- (unless (zerop count)
- (mu4e-message "Found %d matching message%s"
- count (if (= 1 count) "" "s")))))
- ;; if we need to jump to some specific message, do so now
- (goto-char (point-min))
- (when mu4e~headers-msgid-target
- (mu4e-headers-goto-message-id mu4e~headers-msgid-target))
- (when (and mu4e~headers-view-target (mu4e-message-at-point 'noerror))
- ;; view the message at point when there is one.
- (mu4e-headers-view-message))
- (setq mu4e~headers-view-target nil
- mu4e~headers-msgid-target nil))
- (when (mu4e~headers-docid-at-point)
- (mu4e~headers-highlight (mu4e~headers-docid-at-point)))
- ;; run-hooks
- (run-hooks 'mu4e-headers-found-hook)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defmacro mu4e~headers-defun-mark-for (mark)
- "Define a function mu4e~headers-mark-MARK."
- (let ((funcname (intern (format "mu4e-headers-mark-for-%s" mark)))
- (docstring (format "Mark header at point with %s." mark)))
- `(progn
- (defun ,funcname () ,docstring
- (interactive)
- (mu4e-headers-mark-and-next ',mark))
- (put ',funcname 'definition-name ',mark))))
-
-(mu4e~headers-defun-mark-for refile)
-(mu4e~headers-defun-mark-for something)
-(mu4e~headers-defun-mark-for delete)
-(mu4e~headers-defun-mark-for flag)
-(mu4e~headers-defun-mark-for move)
-(mu4e~headers-defun-mark-for read)
-(mu4e~headers-defun-mark-for trash)
-(mu4e~headers-defun-mark-for unflag)
-(mu4e~headers-defun-mark-for untrash)
-(mu4e~headers-defun-mark-for unmark)
-(mu4e~headers-defun-mark-for unread)
-(mu4e~headers-defun-mark-for action)
-
-
-;;; headers-mode and mode-map ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e-headers-mode-map nil
- "Keymap for *mu4e-headers* buffers.")
-(unless mu4e-headers-mode-map
- (setq mu4e-headers-mode-map
- (let ((map (make-sparse-keymap)))
-
- (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
- ;; for terminal users
- (define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
-
- (define-key map "s" 'mu4e-headers-search)
- (define-key map "S" 'mu4e-headers-search-edit)
-
- (define-key map "/" 'mu4e-headers-search-narrow)
-
- (define-key map "j" 'mu4e~headers-jump-to-maildir)
-
- (define-key map (kbd "<M-left>") 'mu4e-headers-query-prev)
- (define-key map (kbd "\\") 'mu4e-headers-query-prev)
- (define-key map (kbd "<M-right>") 'mu4e-headers-query-next)
-
- (define-key map "b" 'mu4e-headers-search-bookmark)
- (define-key map "B" 'mu4e-headers-search-bookmark-edit)
-
- (define-key map "O" 'mu4e-headers-change-sorting)
- (define-key map "P" 'mu4e-headers-toggle-threading)
- (define-key map "Q" 'mu4e-headers-toggle-full-search)
- (define-key map "W" 'mu4e-headers-toggle-include-related)
- (define-key map "V" 'mu4e-headers-toggle-skip-duplicates)
-
- (define-key map "q" 'mu4e~headers-quit-buffer)
- (define-key map "g" 'mu4e-headers-rerun-search) ;; for compatibility
-
- (define-key map "%" 'mu4e-headers-mark-pattern)
- (define-key map "t" 'mu4e-headers-mark-subthread)
- (define-key map "T" 'mu4e-headers-mark-thread)
-
- ;; navigation between messages
- (define-key map "p" 'mu4e-headers-prev)
- (define-key map "n" 'mu4e-headers-next)
- (define-key map (kbd "<M-up>") 'mu4e-headers-prev)
- (define-key map (kbd "<M-down>") 'mu4e-headers-next)
-
- (define-key map (kbd "[") 'mu4e-headers-prev-unread)
- (define-key map (kbd "]") 'mu4e-headers-next-unread)
-
- ;; change the number of headers
- (define-key map (kbd "C-+") 'mu4e-headers-split-view-grow)
- (define-key map (kbd "C--") 'mu4e-headers-split-view-shrink)
- (define-key map (kbd "<C-kp-add>") 'mu4e-headers-split-view-grow)
- (define-key map (kbd "<C-kp-subtract>") 'mu4e-headers-split-view-shrink)
-
- (define-key map ";" 'mu4e-context-switch)
-
- ;; switching to view mode (if it's visible)
- (define-key map "y" 'mu4e-select-other-view)
-
- ;; marking/unmarking ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (define-key map (kbd "<backspace>") 'mu4e-headers-mark-for-trash)
- (define-key map (kbd "d") 'mu4e-headers-mark-for-trash)
- (define-key map (kbd "<delete>") 'mu4e-headers-mark-for-delete)
- (define-key map (kbd "<deletechar>") 'mu4e-headers-mark-for-delete)
- (define-key map (kbd "D") 'mu4e-headers-mark-for-delete)
- (define-key map (kbd "m") 'mu4e-headers-mark-for-move)
- (define-key map (kbd "r") 'mu4e-headers-mark-for-refile)
-
- (define-key map (kbd "?") 'mu4e-headers-mark-for-unread)
- (define-key map (kbd "!") 'mu4e-headers-mark-for-read)
- (define-key map (kbd "A") 'mu4e-headers-mark-for-action)
-
- (define-key map (kbd "u") 'mu4e-headers-mark-for-unmark)
- (define-key map (kbd "+") 'mu4e-headers-mark-for-flag)
- (define-key map (kbd "-") 'mu4e-headers-mark-for-unflag)
- (define-key map (kbd "=") 'mu4e-headers-mark-for-untrash)
- (define-key map (kbd "&") 'mu4e-headers-mark-custom)
-
- (define-key map (kbd "*") 'mu4e-headers-mark-for-something)
- (define-key map (kbd "<kp-multiply>") 'mu4e-headers-mark-for-something)
- (define-key map (kbd "<insertchar>") 'mu4e-headers-mark-for-something)
- (define-key map (kbd "<insert>") 'mu4e-headers-mark-for-something)
-
-
- (define-key map (kbd "#") 'mu4e-mark-resolve-deferred-marks)
-
- (define-key map "U" 'mu4e-mark-unmark-all)
- (define-key map "x" 'mu4e-mark-execute-all)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (define-key map "a" 'mu4e-headers-action)
-
- ;; message composition
- (define-key map "R" 'mu4e-compose-reply)
- (define-key map "F" 'mu4e-compose-forward)
- (define-key map "C" 'mu4e-compose-new)
- (define-key map "E" 'mu4e-compose-edit)
-
- (define-key map (kbd "RET") 'mu4e-headers-view-message)
- (define-key map [mouse-2] 'mu4e-headers-view-message)
-
- (define-key map "$" 'mu4e-show-log)
- (define-key map "H" 'mu4e-display-manual)
-
- ;; menu
- (define-key map [menu-bar] (make-sparse-keymap))
- (let ((menumap (make-sparse-keymap "Headers")))
- (define-key map [menu-bar headers] (cons "Headers" menumap))
-
- (define-key menumap [mu4e~headers-quit-buffer]
- '("Quit view" . mu4e~headers-quit-buffer))
- (define-key menumap [display-help] '("Help" . mu4e-display-manual))
-
- (define-key menumap [sepa0] '("--"))
-
- (define-key menumap [toggle-include-related]
- '(menu-item "Toggle related messages"
- mu4e-headers-toggle-include-related
- :button (:toggle .
- (and (boundp 'mu4e-headers-include-related)
- mu4e-headers-include-related))))
- (define-key menumap [toggle-threading]
- '(menu-item "Toggle threading" mu4e-headers-toggle-threading
- :button (:toggle .
- (and (boundp 'mu4e-headers-show-threads)
- mu4e-headers-show-threads))))
-
- (define-key menumap [sepa1] '("--"))
-
- (define-key menumap [execute-marks] '("Execute marks"
- . mu4e-mark-execute-all))
- (define-key menumap [unmark-all] '("Unmark all" . mu4e-mark-unmark-all))
- (define-key menumap [unmark]
- '("Unmark" . mu4e-headers-mark-for-unmark))
-
- (define-key menumap [mark-pattern] '("Mark pattern" .
- mu4e-headers-mark-pattern))
- (define-key menumap [mark-as-read] '("Mark as read" .
- mu4e-headers-mark-for-read))
- (define-key menumap [mark-as-unread]
- '("Mark as unread" . mu4e-headers-mark-for-unread))
-
- (define-key menumap [mark-delete]
- '("Mark for deletion" . mu4e-headers-mark-for-delete))
- (define-key menumap [mark-trash]
- '("Mark for trash" . mu4e-headers-mark-for-trash))
- (define-key menumap [mark-move]
- '("Mark for move" . mu4e-headers-mark-for-move))
- (define-key menumap [sepa2] '("--"))
-
-
- (define-key menumap [resend] '("Resend" . mu4e-compose-resend))
- (define-key menumap [forward] '("Forward" . mu4e-compose-forward))
- (define-key menumap [reply] '("Reply" . mu4e-compose-reply))
- (define-key menumap [compose-new] '("Compose new" . mu4e-compose-new))
-
-
- (define-key menumap [sepa3] '("--"))
-
- (define-key menumap [query-next]
- '("Next query" . mu4e-headers-query-next))
- (define-key menumap [query-prev] '("Previous query" .
- mu4e-headers-query-prev))
- (define-key menumap [narrow-search] '("Narrow search" .
- mu4e-headers-search-narrow))
- (define-key menumap [bookmark] '("Search bookmark" .
- mu4e-headers-search-bookmark))
- (define-key menumap [jump] '("Jump to maildir" .
- mu4e~headers-jump-to-maildir))
- (define-key menumap [refresh] '("Refresh" . mu4e-headers-rerun-search))
- (define-key menumap [search] '("Search" . mu4e-headers-search))
-
-
- (define-key menumap [sepa4] '("--"))
-
- (define-key menumap [view] '("View" . mu4e-headers-view-message))
- (define-key menumap [next] '("Next" . mu4e-headers-next))
- (define-key menumap [previous] '("Previous" . mu4e-headers-prev))
- (define-key menumap [sepa5] '("--")))
- map)))
-(fset 'mu4e-headers-mode-map mu4e-headers-mode-map)
-
-
-(defun mu4e~header-line-format ()
- "Get the format for the header line."
- (let ((uparrow (if mu4e-use-fancy-chars " â–²" " ^"))
- (downarrow (if mu4e-use-fancy-chars " â–¼" " V")))
- (cons
- (make-string
- (+ mu4e~mark-fringe-len (floor (fringe-columns 'left t))) ?\s)
- (mapcar
- (lambda (item)
- (let* ((field (car item)) (width (cdr item))
- (info (cdr (assoc field
- (append mu4e-header-info mu4e-header-info-custom))))
- (sortable (plist-get info :sortable))
- ;; if sortable, it is either t (when field is sortable itself)
- ;; or a symbol (if another field is used for sorting)
- (sortfield (when sortable (if (booleanp sortable) field sortable)))
- (help (plist-get info :help))
- ;; triangle to mark the sorted-by column
- (arrow
- (when (and sortable (eq sortfield mu4e-headers-sort-field))
- (if (eq mu4e-headers-sort-direction 'descending) downarrow uparrow)))
- (name (concat (plist-get info :shortname) arrow))
- (map (make-sparse-keymap)))
- (when sortable
- (define-key map [header-line mouse-1]
- (lambda (&optional e)
- ;; getting the field, inspired by `tabulated-list-col-sort'
- (interactive "e")
- (let* ((obj (posn-object (event-start e)))
- (field
- (and obj (get-text-property 0 'field (car obj)))))
- ;; "t": if we're already sorted by field, the sort-order is
- ;; changed
- (mu4e-headers-change-sorting field t)))))
- (concat
- (propertize
- (if width
- (truncate-string-to-width name width 0 ?\s t)
- name)
- 'face (when arrow 'bold)
- 'help-echo help
- 'mouse-face (when sortable 'highlight)
- 'keymap (when sortable map)
- 'field field) " ")))
- mu4e-headers-fields))))
-
-(defvar mu4e-headers-mode-abbrev-table nil)
-
-(defun mu4e~headers-do-auto-update ()
- "Update the current headers buffer after indexing has brought
-some changes, `mu4e-headers-auto-update' is non-nil and there is no
-user-interaction ongoing."
- (when (and mu4e-headers-auto-update ;; must be set
- (zerop (mu4e-mark-marks-num)) ;; non active marks
- (not (active-minibuffer-window))) ;; no user input
- (with-current-buffer mu4e~headers-buffer
- (mu4e-headers-rerun-search))))
-
-(define-derived-mode mu4e-headers-mode special-mode
- "mu4e:headers"
- "Major mode for displaying mu4e search results.
-\\{mu4e-headers-mode-map}."
- (use-local-map mu4e-headers-mode-map)
- (make-local-variable 'mu4e~headers-proc)
- (make-local-variable 'mu4e~highlighted-docid)
- (make-local-variable 'global-mode-string)
- (set (make-local-variable 'hl-line-face) 'mu4e-header-highlight-face)
-
- ;; maybe update the current headers upon indexing changes
- (add-hook 'mu4e-index-updated-hook 'mu4e~headers-do-auto-update nil t)
- (setq
- truncate-lines t
- buffer-undo-list t ;; don't record undo information
- overwrite-mode nil
- header-line-format (mu4e~header-line-format))
-
- (mu4e~mark-initialize) ;; initialize the marking subsystem
- (hl-line-mode 1))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; highlighting
-(defvar mu4e~highlighted-docid nil
- "The highlighted docid")
-
-(defun mu4e~headers-highlight (docid)
- "Highlight the header with DOCID, or do nothing if it's not found.
-Also, unhighlight any previously highlighted headers."
- (with-current-buffer mu4e~headers-buffer
- (save-excursion
- ;; first, unhighlight the previously highlighted docid, if any
- (when (and docid mu4e~highlighted-docid
- (mu4e~headers-goto-docid mu4e~highlighted-docid))
- (hl-line-unhighlight))
- ;; now, highlight the new one
- (when (mu4e~headers-goto-docid docid)
- (hl-line-highlight)))
- (setq mu4e~highlighted-docid docid)))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e~headers-select-window ()
- "When there is a visible window for the headers buffer, make sure
-to select it. This is needed when adding new headers, otherwise
-adding a lot of new headers looks really choppy."
- (let ((win (get-buffer-window mu4e~headers-buffer)))
- (when win (select-window win))))
-
-;;;; headers in the buffer are prefixed by an invisible string with the docid
-;;;; followed by an EOT ('end-of-transmission', \004, ^D) non-printable ascii
-;;;; character. this string also has a text-property with the docid. the former
-;;;; is used for quickly finding a certain header, the latter for retrieving the
-;;;; docid at point without string matching etc.
-
-(defsubst mu4e~headers-docid-cookie (docid)
- "Create an invisible string containing DOCID; this is to be used
-at the beginning of lines to identify headers."
- (propertize (format "%s%d%s"
- mu4e~headers-docid-pre docid mu4e~headers-docid-post)
- 'docid docid 'invisible t));;
-
-(defsubst mu4e~headers-docid-at-point (&optional point)
- "Get the docid for the header at POINT, or at current (point) if
-nil. Returns the docid, or nil if there is none."
- (save-excursion
- (when point
- (goto-char point))
- (get-text-property (line-beginning-position) 'docid)))
-
-(defun mu4e~headers-goto-docid (docid &optional to-mark)
- "Go to the beginning of the line with the header with docid
-DOCID, or nil if it cannot be found. If the optional TO-MARK is
-non-nil, go to the point directly *after* the docid-cookie instead
-of the beginning of the line."
- (let ((oldpoint (point)) (newpoint))
- (goto-char (point-min))
- (setq newpoint
- (search-forward (mu4e~headers-docid-cookie docid) nil t))
- (unless to-mark
- (if (null newpoint)
- (goto-char oldpoint) ;; not found; restore old pos
- (progn
- (beginning-of-line) ;; found, move to beginning of line
- (setq newpoint (point)))))
- newpoint)) ;; return the point, or nil if not found
-
-
-(defsubst mu4e~headers-docid-pos (docid)
- "Return the pos of the beginning of the line with the header with
-docid DOCID, or nil if it cannot be found."
- (let ((pos))
- (save-excursion
- (setq pos (mu4e~headers-goto-docid docid)))
- pos))
-
-(defsubst mu4e~headers-field-for-docid (docid field)
- "Get FIELD (a symbol, see `mu4e-headers-names') for the message
-with DOCID which must be present in the headers buffer."
- (save-excursion
- (when (mu4e~headers-goto-docid docid)
- (mu4e-message-field (mu4e-message-at-point) field))))
-
-(defun mu4e-headers-goto-message-id (msgid)
- "Go to the next message with message-id MSGID. Return the
-message plist, or nil if not found."
- (mu4e-headers-find-if
- (lambda (msg)
- (let ((this-msgid (mu4e-message-field msg :message-id)))
- (when (and this-msgid (string= msgid this-msgid))
- msg)))))
-
-;;;; markers mark headers for
-(defun mu4e~headers-mark (docid mark)
- "(Visually) mark the header for DOCID with character MARK."
- (with-current-buffer mu4e~headers-buffer
- (let ((inhibit-read-only t) (oldpoint (point)))
- (unless (mu4e~headers-goto-docid docid)
- (mu4e-error "Cannot find message with docid %S" docid))
- ;; now, we're at the beginning of the header, looking at
- ;; <docid>\004
- ;; (which is invisible). jump past that…
- (unless (re-search-forward mu4e~headers-docid-post nil t)
- (mu4e-error "Cannot find the `mu4e~headers-docid-post' separator"))
-
- ;; clear old marks, and add the new ones.
- (let ((msg (get-text-property (point) 'msg)))
- (delete-char mu4e~mark-fringe-len)
- (insert (propertize
- (format mu4e~mark-fringe-format mark)
- 'face 'mu4e-header-marks-face
- 'docid docid
- 'msg msg)))
- (goto-char oldpoint))))
-
-
-(defsubst mu4e~headers-add-header (str docid point &optional msg)
- "Add header STR with DOCID to the buffer at POINT if non-nil, or
-at (point-max) otherwise. If MSG is not nil, add it as the
-text-property `msg'."
- (when (buffer-live-p mu4e~headers-buffer)
- (with-current-buffer mu4e~headers-buffer
- (let ((inhibit-read-only t)
- (is-first-header (= (point-min) (point-max))))
- (save-excursion
- (goto-char (if point point (point-max)))
- (insert
- (propertize
- (concat
- (mu4e~headers-docid-cookie docid)
- mu4e~mark-fringe
- str "\n")
- 'docid docid 'msg msg)))))))
-
-(defun mu4e~headers-remove-header (docid &optional ignore-missing)
- "Remove header with DOCID at point.
-When IGNORE-MISSING is non-nill, don't raise an error when the
-docid is not found."
- (with-current-buffer mu4e~headers-buffer
- (if (mu4e~headers-goto-docid docid)
- (let ((inhibit-read-only t))
- (delete-region (line-beginning-position) (line-beginning-position 2)))
- (unless ignore-missing
- (mu4e-error "Cannot find message with docid %S" docid)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e~headers-search-execute (expr ignore-history)
- "Search in the mu database for EXPR, and switch to the output
-buffer for the results. If IGNORE-HISTORY is true, do *not* update
-the query history stack."
- ;; note: we don't want to update the history if this query comes from
- ;; `mu4e~headers-query-next' or `mu4e~headers-query-prev'.
- (mu4e-hide-other-mu4e-buffers)
- (let* ((buf (get-buffer-create mu4e~headers-buffer-name))
- (inhibit-read-only t)
- (maxnum (unless mu4e-headers-full-search mu4e-headers-results-limit)))
- (with-current-buffer buf
- (mu4e-headers-mode)
- (unless ignore-history
- ;; save the old present query to the history list
- (when mu4e~headers-last-query
- (mu4e~headers-push-query mu4e~headers-last-query 'past)))
- (setq
- mu4e~headers-buffer buf
- mode-name "mu4e-headers"
- mu4e~headers-last-query expr
- global-mode-string
- '(:eval
- (concat
- (propertize
- (mu4e~quote-for-modeline mu4e~headers-last-query)
- 'face 'mu4e-modeline-face)
- " "
- (mu4e-context-label)))))
-
- (switch-to-buffer buf)
- (run-hook-with-args 'mu4e-headers-search-hook expr)
- (mu4e~proc-find
- expr
- mu4e-headers-show-threads
- mu4e-headers-sort-field
- mu4e-headers-sort-direction
- maxnum
- mu4e-headers-skip-duplicates
- mu4e-headers-include-related)))
-
-(defun mu4e~headers-redraw-get-view-window ()
- "Close all windows, redraw the headers buffer based on the value
-of `mu4e-split-view', and return a window for the message view."
- (mu4e-hide-other-mu4e-buffers)
- (unless (buffer-live-p mu4e~headers-buffer)
- (mu4e-error "No headers buffer available"))
- (switch-to-buffer mu4e~headers-buffer)
- ;; kill the existing view win
- (when (buffer-live-p mu4e~view-buffer)
- (kill-buffer mu4e~view-buffer))
- ;; get a new view window
- (setq mu4e~headers-view-win
- (let* ((new-win-func
- (cond
- ((eq mu4e-split-view 'horizontal) ;; split horizontally
- '(split-window-vertically mu4e-headers-visible-lines))
- ((eq mu4e-split-view 'vertical) ;; split vertically
- '(split-window-horizontally mu4e-headers-visible-columns)))))
- (cond ((with-demoted-errors "Unable to split window: %S"
- (eval new-win-func)))
- (t ;; no splitting; just use the currently selected one
- (selected-window)))))
- mu4e~headers-view-win)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; search-based marking
-
-(defun mu4e-headers-for-each (func)
- "Call FUNC for each header, moving point to the header.
-FUNC receives one argument, the message s-expression for the
-corresponding header."
- (save-excursion
- (goto-char (point-min))
- (while (search-forward mu4e~headers-docid-pre nil t)
- ;; not really sure why we need to jump to bol; we do need to, otherwise we
- ;; miss lines sometimes...
- (let ((msg (get-text-property (line-beginning-position) 'msg)))
- (when msg
- (funcall func msg))))))
-
-(defun mu4e-headers-find-if (func &optional backward)
- "Move to the next header for which FUNC returns non-`nil',
-starting from the current position. FUNC receives one argument, the
-message s-expression for the corresponding header. If BACKWARD is
-non-`nil', search backwards. Returns the new position, or `nil' if
-nothing was found. If you want to exclude matches for the current
-message, you can use `mu4e-headers-find-if-next'."
- (let ((pos)
- (search-func (if backward 'search-backward 'search-forward)))
- (save-excursion
- (while (and (null pos)
- (funcall search-func mu4e~headers-docid-pre nil t))
- ;; not really sure why we need to jump to bol; we do need to, otherwise we
- ;; miss lines sometimes...
- (let ((msg (get-text-property (line-beginning-position) 'msg)))
- (when (and msg (funcall func msg))
- (setq pos (point))))))
- (when pos
- (goto-char pos))))
-
-(defun mu4e-headers-find-if-next (func &optional backwards)
- "Like `mu4e-headers-find-if', but do not match the current header.
-Move to the next or (if BACKWARDS is non-`nil') header for which FUNC
-returns non-`nil', starting from the current position."
- (let ((pos))
- (save-excursion
- (if backwards
- (beginning-of-line)
- (end-of-line))
- (setq pos (mu4e-headers-find-if func backwards)))
- (when pos (goto-char pos))))
-
-(defvar mu4e~headers-regexp-hist nil
- "History list of regexps used.")
-
-(defun mu4e-headers-mark-for-each-if (markpair mark-pred &optional param)
- "Mark all headers for which predicate function MARK-PRED returns
-non-nil with MARKPAIR. MARK-PRED is function that receives two
-arguments, MSG (the message at point) and PARAM (a user-specified
-parameter). MARKPAIR is a cell (MARK . TARGET); see
-`mu4e-mark-at-point' for details about marks."
- (mu4e-headers-for-each
- (lambda (msg)
- (when (funcall mark-pred msg param)
- (mu4e-mark-at-point (car markpair) (cdr markpair))))))
-
-(defun mu4e-headers-mark-pattern ()
- "Ask user for a kind of mark (move, delete etc.), a field to
-match and a regular expression to match with. Then, mark all
-matching messages with that mark."
- (interactive)
- (let ((markpair (mu4e~mark-get-markpair "Mark matched messages with: " t))
- (field (mu4e-read-option "Field to match: "
- '( ("subject" . :subject)
- ("from" . :from)
- ("to" . :to)
- ("cc" . :cc)
- ("bcc" . :bcc)
- ("list" . :mailing-list))))
- (pattern (read-string
- (mu4e-format "Regexp:")
- nil 'mu4e~headers-regexp-hist)))
- (mu4e-headers-mark-for-each-if
- markpair
- (lambda (msg param)
- (let* ((do-mark) (value (mu4e-msg-field msg field)))
- (setq do-mark
- (if (member field '(:to :from :cc :bcc :reply-to))
- (find-if (lambda (contact)
- (let ((name (car contact)) (email (cdr contact)))
- (or (and name (string-match pattern name))
- (and email (string-match pattern email))))) value)
- (string-match pattern (or value "")))))))))
-
-(defun mu4e-headers-mark-custom ()
- "Mark messages based on a user-provided predicate function."
- (interactive)
- (let* ((pred (mu4e-read-option "Match function: "
- mu4e-headers-custom-markers))
- (param (when (cdr pred) (eval (cdr pred))))
- (markpair (mu4e~mark-get-markpair "Mark matched messages with: " t)))
- (mu4e-headers-mark-for-each-if markpair (car pred) param)))
-
-(defun mu4e~headers-get-thread-info (msg what)
- "Get WHAT (a symbol, either path or thread-id) for MSG."
- (let* ((thread (or (mu4e-message-field msg :thread)
- (mu4e-error "No thread info found")))
- (path (or (plist-get thread :path)
- (mu4e-error "No threadpath found"))))
- (case what
- (path path)
- (thread-id
- (save-match-data
- ;; the thread id is the first segment of the thread path
- (when (string-match "^\\([[:xdigit:]]+\\):?" path)
- (match-string 1 path))))
- (otherwise (mu4e-error "Not supported")))))
-
-
-(defun mu4e-headers-mark-thread-using-markpair (markpair &optional subthread)
- "Mark the thread at point using the given markpair. If SUBTHREAD is
-non-nil, marking is limited to the message at point and its
-descendants."
- (let* ((mark (car markpair))
- (allowed-marks (mapcar 'car mu4e-marks)))
- (unless (memq mark allowed-marks)
- (mu4e-error "The mark (%s) has to be one of: %s"
- mark allowed-marks)))
- ;; note: the tread id is shared by all messages in a thread
- (let* ((msg (mu4e-message-at-point))
- (thread-id (mu4e~headers-get-thread-info msg 'thread-id))
- (path (mu4e~headers-get-thread-info msg 'path))
- (last-marked-point))
- (mu4e-headers-for-each
- (lambda (mymsg)
- (let ((my-thread-id (mu4e~headers-get-thread-info mymsg 'thread-id)))
- (if subthread
- ;; subthread matching; mymsg's thread path should have path as its
- ;; prefix
- (when (string-match (concat "^" path)
- (mu4e~headers-get-thread-info mymsg 'path))
- (mu4e-mark-at-point (car markpair) (cdr markpair))
- (setq last-marked-point (point)))
- ;; nope; not looking for the subthread; looking for the whole thread
- (when (string= thread-id
- (mu4e~headers-get-thread-info mymsg 'thread-id))
- (mu4e-mark-at-point (car markpair) (cdr markpair))
- (setq last-marked-point (point)))))))
- (when last-marked-point
- (goto-char last-marked-point)
- (mu4e-headers-next))))
-
-(defun mu4e-headers-mark-thread (&optional subthread markpair)
- "Like `mu4e-headers-mark-thread-using-markpair' but prompt for the markpair."
- (interactive
- (let* ((subthread current-prefix-arg))
- (list current-prefix-arg
- ;; FIXME: e.g., for refiling we should evaluate this
- ;; for each line separately
- (mu4e~mark-get-markpair
- (if subthread "Mark subthread with: " "Mark whole thread with: ") t))))
- (mu4e-headers-mark-thread-using-markpair markpair subthread))
-
-(defun mu4e-headers-mark-subthread (&optional markpair)
- "Like `mu4e-mark-thread', but only for a sub-thread."
- (interactive)
- (if markpair (mu4e-headers-mark-thread t markpair)
- (let ((current-prefix-arg t))
- (call-interactively 'mu4e-headers-mark-thread))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;; the query past / present / future ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e~headers-query-past nil
- "Stack of queries before the present one.")
-(defvar mu4e~headers-query-future nil
- "Stack of queries after the present one.")
-(defvar mu4e~headers-query-stack-size 20
- "Maximum size for the query stacks.")
-
-(defun mu4e~headers-push-query (query where)
- "Push QUERY to one of the query stacks.
-WHERE is a symbol telling us where to push; it's a symbol, either
-'future or 'past. Functional also removes duplicats, limits the
-stack size."
- (let ((stack
- (case where
- (past mu4e~headers-query-past)
- (future mu4e~headers-query-future))))
- ;; only add if not the same item
- (unless (and stack (string= (car stack) query))
- (push query stack)
- ;; limit the stack to `mu4e~headers-query-stack-size' elements
- (when (> (length stack) mu4e~headers-query-stack-size)
- (setq stack (subseq stack 0 mu4e~headers-query-stack-size)))
- ;; remove all duplicates of the new element
- (remove-if (lambda (elm) (string= elm (car stack))) (cdr stack))
- ;; update the stacks
- (case where
- (past (setq mu4e~headers-query-past stack))
- (future (setq mu4e~headers-query-future stack))))))
-
-(defun mu4e~headers-pop-query (whence)
- "Pop a query from the stack.
-WHENCE is a symbol telling us where to get it from, either `future'
-or `past'."
- (case whence
- (past
- (unless mu4e~headers-query-past
- (mu4e-warn "No more previous queries"))
- (pop mu4e~headers-query-past))
- (future
- (unless mu4e~headers-query-future
- (mu4e-warn "No more next queries"))
- (pop mu4e~headers-query-future))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;; interactive functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e~headers-search-hist nil
- "History list of searches.")
-
-(defvar mu4e~headers-msgid-target nil
- "Message-id to jump to after the search has finished.")
-
-(defvar mu4e~headers-view-target nil
- "Whether to automatically view (open) the target message (as
- per `mu4e~headers-msgid-target').")
-
-(defun mu4e-headers-search (&optional expr prompt edit ignore-history msgid show)
- "Search in the mu database for EXPR, and switch to the output
-buffer for the results. This is an interactive function which ask
-user for EXPR. PROMPT, if non-nil, is the prompt used by this
-function (default is \"Search for:\"). If EDIT is non-nil,
-instead of executing the query for EXPR, let the user edit the
-query before executing it. If IGNORE-HISTORY is true, do *not*
-update the query history stack. If MSGID is non-nil, attempt to
-move point to the first message with that message-id after
-searching. If SHOW is non-nil, show the message with MSGID."
- ;; note: we don't want to update the history if this query comes from
- ;; `mu4e~headers-query-next' or `mu4e~headers-query-prev'."
- (interactive)
- (let* ((prompt (mu4e-format (or prompt "Search for: ")))
- (expr
- (if edit
- (read-string prompt expr)
- (or expr
- (read-string prompt nil 'mu4e~headers-search-hist)))))
- (mu4e-mark-handle-when-leaving)
- (mu4e~headers-search-execute expr ignore-history)
- (setq mu4e~headers-msgid-target msgid
- mu4e~headers-view-target show)))
-
-(defun mu4e-headers-search-edit ()
- "Edit the last search expression."
- (interactive)
- (mu4e-headers-search mu4e~headers-last-query nil t))
-
-(defun mu4e-headers-search-bookmark (&optional expr edit)
- "Search using some bookmarked query EXPR.
-If EDIT is non-nil, let the user edit the bookmark before starting
-the search."
- (interactive)
- (let ((expr
- (or expr
- (mu4e-ask-bookmark (if edit "Select bookmark: " "Bookmark: ")))))
- (run-hook-with-args 'mu4e-headers-search-bookmark-hook expr)
- (mu4e-headers-search expr (when edit "Edit bookmark: ") edit)))
-
-(defun mu4e-headers-search-bookmark-edit ()
- "Edit an existing bookmark before executing it."
- (interactive)
- (mu4e-headers-search-bookmark nil t))
-
-
-(defun mu4e-headers-search-narrow (filter )
- "Narrow the last search by appending search expression FILTER to
-the last search expression. Note that you can go back to previous
-query (effectively, 'widen' it), with `mu4e-headers-query-prev'."
- (interactive
- (let ((filter
- (read-string (mu4e-format "Narrow down to: ")
- nil 'mu4e~headers-search-hist nil t)))
- (list filter)))
- (unless mu4e~headers-last-query
- (mu4e-warn "There's nothing to filter"))
- (mu4e-headers-search
- (format "(%s) AND (%s)" mu4e~headers-last-query filter)))
-
-
-(defun mu4e-headers-change-sorting (&optional field dir)
- "Change the sorting/threading parameters.
-FIELD is the field to sort by; DIR is a symbol: either 'ascending,
-'descending, 't (meaning: if FIELD is the same as the current
-sortfield, change the sort-order) or nil (ask the user)."
- (interactive)
- (let* ((field
- (or field
- (mu4e-read-option "Sortfield: " mu4e~headers-sort-field-choices)))
- ;; note: 'sortable' is either a boolean (meaning: if non-nil, this is
- ;; sortable field), _or_ another field (meaning: sort by this other field).
- (sortable (plist-get (cdr (assoc field mu4e-header-info)) :sortable))
- ;; error check
- (sortable
- (if sortable
- sortable
- (mu4e-error "Not a sortable field")))
- (sortfield (if (booleanp sortable) field sortable))
- (dir
- (case dir
- ((ascending descending) dir)
- ;; change the sort order if field = curfield
- (t
- (if (eq sortfield mu4e-headers-sort-field)
- (if (eq mu4e-headers-sort-direction 'ascending)
- 'descending 'ascending)
- 'descending))
- (mu4e-read-option "Direction: "
- '(("ascending" . 'ascending) ("descending" . 'descending))))))
- (setq
- mu4e-headers-sort-field sortfield
- mu4e-headers-sort-direction dir)
- (mu4e-message "Sorting by %s (%s)"
- (symbol-name sortfield)
- (symbol-name mu4e-headers-sort-direction))
- (mu4e-headers-rerun-search)))
-
-(defun mu4e~headers-toggle (name togglevar dont-refresh)
- "Toggle variable TOGGLEVAR for feature NAME. Unless DONT-REFRESH is non-nil,
-re-run the last search."
- (set togglevar (not (symbol-value togglevar)))
- (mu4e-message "%s turned %s%s"
- name
- (if (symbol-value togglevar) "on" "off")
- (if dont-refresh
- " (press 'g' to refresh)" ""))
- (unless dont-refresh
- (mu4e-headers-rerun-search)))
-
-(defun mu4e-headers-toggle-threading (&optional dont-refresh)
- "Toggle `mu4e-headers-show-threads'. With prefix-argument, do
-_not_ refresh the last search with the new setting for threading."
- (interactive "P")
- (mu4e~headers-toggle "Threading" 'mu4e-headers-show-threads dont-refresh))
-
-(defun mu4e-headers-toggle-full-search (&optional dont-refresh)
- "Toggle `mu4e-headers-full-search'. With prefix-argument, do
-_not_ refresh the last search with the new setting for threading."
- (interactive "P")
- (mu4e~headers-toggle "Full-search"
- 'mu4e-headers-full-search dont-refresh))
-
-(defun mu4e-headers-toggle-include-related (&optional dont-refresh)
- "Toggle `mu4e-headers-include-related'. With prefix-argument, do
-_not_ refresh the last search with the new setting for threading."
- (interactive "P")
- (mu4e~headers-toggle "Include-related"
- 'mu4e-headers-include-related dont-refresh))
-
-(defun mu4e-headers-toggle-skip-duplicates (&optional dont-refresh)
- "Toggle `mu4e-headers-skip-duplicates'. With prefix-argument, do
-_not_ refresh the last search with the new setting for threading."
- (interactive "P")
- (mu4e~headers-toggle "Skip-duplicates"
- 'mu4e-headers-skip-duplicates dont-refresh))
-
-(defvar mu4e~headers-loading-buf nil
- "A buffer for loading a message view.")
-
-(defun mu4e~headers-get-loading-buf ()
- "Get a buffer to give feedback while loading a message view."
- (unless (buffer-live-p mu4e~headers-loading-buf)
- (setq mu4e~headers-loading-buf
- (get-buffer-create " *mu4e-loading*")))
- (with-current-buffer mu4e~headers-loading-buf
- (let ((inhibit-read-only t))
- (erase-buffer)
- (local-set-key (kbd "q") 'kill-buffer-and-window)
- (insert (propertize "Waiting for message..."
- 'face 'mu4e-system-face 'intangible t))))
- mu4e~headers-loading-buf)
-
-(defun mu4e-headers-view-message ()
- "View message at point.
-If there's an existing window for the view, re-use that one. If
-not, create a new one, depending on the value of
-`mu4e-split-view': if it's a symbol `horizontal' or `vertical',
-split the window accordingly; if it is nil, replace the current
-window. "
- (interactive)
- (unless (eq major-mode 'mu4e-headers-mode)
- (mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))
- (let* ((msg (mu4e-message-at-point))
- (docid (or (mu4e-message-field msg :docid)
- (mu4e-warn "No message at point")))
- ;; decrypt (or not), based on `mu4e-decryption-policy'.
- (decrypt
- (and (member 'encrypted (mu4e-message-field msg :flags))
- (if (eq mu4e-decryption-policy 'ask)
- (yes-or-no-p (mu4e-format "Decrypt message?"))
- mu4e-decryption-policy)))
- (viewwin (mu4e~headers-redraw-get-view-window)))
- (unless (window-live-p viewwin)
- (mu4e-error "Cannot get a message view"))
- (select-window viewwin)
- (switch-to-buffer (mu4e~headers-get-loading-buf))
- (mu4e~proc-view docid mu4e-view-show-images decrypt)))
-
-(defun mu4e-headers-rerun-search ()
- "Rerun the search for the last search expression."
- (interactive)
- ;; if possible, try to return to the same message
- (let* ((msg (mu4e-message-at-point))
- (msgid (and msg (mu4e-message-field msg :message-id))))
- (mu4e-headers-search mu4e~headers-last-query nil nil t msgid)))
-
-(defun mu4e~headers-query-navigate (whence)
- "Execute the previous query from the query stacks.
-WHENCE determines where the query is taken from and is a symbol,
-either `future' or `past'."
- (let ((query (mu4e~headers-pop-query whence))
- (where (if (eq whence 'future) 'past 'future)))
- (when query
- (mu4e~headers-push-query mu4e~headers-last-query where)
- (mu4e-headers-search query nil nil t))))
-
-(defun mu4e-headers-query-next ()
- "Execute the previous query from the query stacks."
- (interactive)
- (mu4e~headers-query-navigate 'future))
-
-(defun mu4e-headers-query-prev ()
- "Execute the previous query from the query stacks."
- (interactive)
- (mu4e~headers-query-navigate 'past))
-
-;; forget the past so we don't repeat it :/
-(defun mu4e-headers-forget-queries ()
- "Forget all the complete query history."
- (interactive)
- (setq ;; note: don't forget the present one
- mu4e~headers-query-past nil
- mu4e~headers-query-future nil)
- (mu4e-message "Query history cleared"))
-
-(defun mu4e~headers-move (lines)
- "Move point LINES lines forward (if LINES is positive) or
-backward (if LINES is negative). If this succeeds, return the new
-docid. Otherwise, return nil."
- (unless (eq major-mode 'mu4e-headers-mode)
- (mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))
- (let ((succeeded (zerop (forward-line lines)))
- (docid (mu4e~headers-docid-at-point)))
- ;; move point, even if this function is called when this window is not
- ;; visible
- (when docid
- ;; update all windows showing the headers buffer
- (walk-windows
- (lambda (win)
- (when (eq (window-buffer win) mu4e~headers-buffer)
- (set-window-point win (point))))
- nil t)
- ;;(set-window-point (get-buffer-window mu4e~headers-buffer t) (point))
- ;; attempt to highlight the new line, display the message
- (mu4e~headers-highlight docid)
- ;; update message view if it was already showing
- (when (and mu4e-split-view (window-live-p mu4e~headers-view-win))
- (mu4e-headers-view-message))
- docid)))
-
-(defun mu4e-headers-next (&optional n)
- "Move point to the next message header.
-If this succeeds, return the new docid. Otherwise, return nil.
-Optionally, takes an integer N (prefix argument), to the Nth next
-header."
- (interactive "P")
- (mu4e~headers-move (or n 1)))
-
-(defun mu4e-headers-prev (&optional n)
- "Move point to the previous message header.
-If this succeeds, return the new docid. Otherwise, return nil.
-Optionally, takes an integer N (prefix argument), to the Nth
-previous header."
- (interactive "P")
- (mu4e~headers-move (- (or n 1))))
-
-(defun mu4e~headers-prev-or-next-unread (backwards)
- "Move point to the next message that is unread (and
-untrashed). If BACKWARDS is non-`nil', move backwards."
- (interactive)
- (or (mu4e-headers-find-if-next
- (lambda (msg)
- (let ((flags (mu4e-message-field msg :flags)))
- (and (member 'unread flags) (not (member 'trashed flags)))))
- backwards)
- (mu4e-message (format "No %s unread message found"
- (if backwards "previous" "next")))))
-
-(defun mu4e-headers-prev-unread ()
- "Move point to the previous message that is unread (and
-untrashed)."
- (interactive)
- (mu4e~headers-prev-or-next-unread t))
-
-(defun mu4e-headers-next-unread ()
- "Move point to the next message that is unread (and
-untrashed)."
- (interactive)
- (mu4e~headers-prev-or-next-unread nil))
-
-(defun mu4e~headers-jump-to-maildir (maildir)
- "Show the messages in maildir (user is prompted to ask what
-maildir)."
- (interactive
- (let ((maildir (mu4e-ask-maildir "Jump to maildir: ")))
- (list maildir)))
- (when maildir
- (mu4e-mark-handle-when-leaving)
- (mu4e-headers-search
- (format "maildir:\"%s\"" maildir))))
-
-(defun mu4e-headers-split-view-grow (&optional n)
- "In split-view, grow the headers window.
-In horizontal split-view, increase the number of lines shown by N.
-In vertical split-view, increase the number of columns shown by N.
-If N is negative shrink the headers window. When not in split-view
-do nothing."
- (interactive "P")
- (let ((n (or n 1))
- (hwin (get-buffer-window mu4e~headers-buffer)))
- (when (and (buffer-live-p mu4e~view-buffer) (window-live-p hwin))
- (let ((n (or n 1)))
- (case mu4e-split-view
- ;; emacs has weird ideas about what horizontal, vertical means...
- (horizontal
- (window-resize hwin n nil)
- (incf mu4e-headers-visible-lines n))
- (vertical
- (window-resize hwin n t)
- (incf mu4e-headers-visible-columns n)))))))
-
-(defun mu4e-headers-split-view-shrink (&optional n)
- "In split-view, shrink the headers window.
-In horizontal split-view, decrease the number of lines shown by N.
-In vertical split-view, decrease the number of columns shown by N.
-If N is negative grow the headers window. When not in split-view
-do nothing."
- (interactive "P")
- (mu4e-headers-split-view-grow (- (or n 1))))
-
-(defun mu4e-headers-action (&optional actionfunc)
- "Ask user what to do with message-at-point, then do it.
-The actions are specified in `mu4e-headers-actions'. Optionally,
-pass ACTIONFUNC, which is a function that takes a msg-plist
-argument."
- (interactive)
- (let ((msg (mu4e-message-at-point))
- (afunc (or actionfunc (mu4e-read-option "Action: " mu4e-headers-actions))))
- (funcall afunc msg)))
-
-(defun mu4e-headers-mark-and-next (mark)
- "Set mark MARK on the message at point or on all messages in the
-region if there is a region, then move to the next message."
- (interactive)
- (mu4e-mark-set mark)
- (mu4e-headers-next))
-
-(defun mu4e~headers-quit-buffer ()
- "Quit the mu4e-headers buffer.
-This is a rather complex function, to ensure we don't disturb
-other windows."
- (interactive)
- (unless (eq major-mode 'mu4e-headers-mode)
- (mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))
- (mu4e-mark-handle-when-leaving)
- (let ((curbuf (current-buffer)) (curwin (selected-window))
- (headers-visible))
- (walk-windows
- (lambda (win)
- (with-selected-window win
- ;; if we the view window connected to this one, kill it
- (when (and (not (one-window-p win)) (eq mu4e~headers-view-win win))
- (delete-window win)
- (setq mu4e~headers-view-win nil)))
- ;; and kill any _other_ (non-selected) window that shows the current
- ;; buffer
- (when (and
- (eq curbuf (window-buffer win)) ;; does win show curbuf?
- (not (eq curwin win)) ;; it's not the curwin?
- (not (one-window-p))) ;; and not the last one?
- (delete-window win)))) ;; delete it!
- ;; now, all *other* windows should be gone. kill ourselves, and return
- ;; to the main view
- (kill-buffer)
- (mu4e~main-view)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(provide 'mu4e-headers)
diff --git a/_spacemacs.d/local/mu4e/mu4e-lists.el b/_spacemacs.d/local/mu4e/mu4e-lists.el
deleted file mode 100644
index 00884da..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-lists.el
+++ /dev/null
@@ -1,93 +0,0 @@
-;;; mu4e-lists.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; In this file, we create a table of list-id -> shortname for mailing lists.
-;; The shortname (friendly) should a at most 8 characters, camel-case
-
-
-(defvar mu4e~mailing-lists
- '( ("bbdb-info.lists.sourceforge.net" . "BBDB")
- ("boost-announce.lists.boost.org" . "BoostA")
- ("boost-interest.lists.boost.org" . "BoostI")
- ("conkeror.mozdev.org" . "Conkeror")
- ("curl-library.cool.haxx.se" . "LibCurl")
- ("crypto-gram-list.schneier.com " . "CryptoGr")
- ("dbus.lists.freedesktop.org" . "DBus")
- ("desktop-devel-list.gnome.org" . "GnomeDT")
- ("emacs-devel.gnu.org" . "EmacsDev")
- ("emacs-orgmode.gnu.org" . "Orgmode")
- ("emms-help.gnu.org" . "Emms")
- ("enlightenment-devel.lists.sourceforge.net" . "E-Dev")
- ("erlang-questions.erlang.org" . "Erlang")
- ("evolution-hackers.lists.ximian.com" . "EvoDev")
- ("farsight-devel.lists.sourceforge.net" . "Farsight")
- ("mailman.lists.freedesktop.org" . "FDeskTop")
- ("gcc-help.gcc.gnu.org" . "Gcc")
- ("gmime-devel-list.gnome.org" . "GMimeDev")
- ("gnome-shell-list.gnome.org" . "GnomeSh")
- ("gnu-emacs-sources.gnu.org" . "EmacsSrc")
- ("gnupg-users.gnupg.org" . "GnupgU")
- ("gpe.handhelds.org" . "GPE")
- ("gstreamer-devel.lists.freedesktop.org" . "GstDev")
- ("gstreamer-devel.lists.sourceforge.net" . "GstDev")
- ("gstreamer-openmax.lists.sourceforge.net" . "GstOmx")
- ("gtk-devel-list.gnome.org" . "GtkDev")
- ("gtkmm-list.gnome.org" . "GtkmmDev")
- ("guile-devel.gnu.org" . "GuileDev")
- ("guile-user.gnu.org" . "GuileUsr")
- ("help-gnu-emacs.gnu.org" . "EmacsUsr")
- ("lggdh-algemeen.vvtp.tudelft.nl" . "LGGDH")
- ("linux-bluetooth.vger.kernel.org" . "Bluez")
- ("maemo-developers.maemo.org" . "MaemoDev")
- ("maemo-users.maemo.org" . "MaemoUsr")
- ("monit-general.nongnu.org" . "Monit")
- ("mu-discuss.googlegroups.com" . "Mu")
- ("nautilus-list.gnome.org" . "Nautilus")
- ("notmuch.notmuchmail.org" . "Notmuch")
- ("orbit-list.gnome.org" . "ORBit")
- ("pulseaudio-discuss.lists.freedesktop.org" . "PulseA")
- ("sqlite-announce.sqlite.org" . "SQliteAnn")
- ("sqlite-dev.sqlite.org" . "SQLiteDev")
- ("sup-talk.rubyforge.org" . "Sup")
- ("sylpheed-claws-users.lists.sourceforge.net" . "Sylpheed")
- ("tinymail-devel-list.gnome.org" . "Tinymail")
- ("unicode.sarasvati.unicode.org" . "Unicode")
- ("xapian-discuss.lists.xapian.org" . "Xapian")
- ("xdg.lists.freedesktop.org" . "XDG")
- ("wl-en.lists.airs.net" . "Wdrlust")
- ("wl-en.ml.gentei.org" . "WdrLust")
- ("xapian-devel.lists.xapian.org" . "Xapian")
- ("zsh-users.zsh.org" . "ZshUsr"))
- "AList of cells (MAILING-LIST-ID . SHORTNAME)")
-
-(defvar mu4e-user-mailing-lists nil
- "An alist with cells (MAILING-LIST-ID . SHORTNAME); these are
-used in addition to the built-in list `mu4e~mailing-lists'.")
-
-(defvar mu4e-mailing-list-patterns nil
- "A list of regex patterns to capture a shortname out of a list
-ID. For the first regex that matches, its first matchgroup will
-be used as the shortname.")
-
-(provide 'mu4e-lists)
diff --git a/_spacemacs.d/local/mu4e/mu4e-main.el b/_spacemacs.d/local/mu4e/mu4e-main.el
deleted file mode 100644
index a647a2d..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-main.el
+++ /dev/null
@@ -1,225 +0,0 @@
-;;; mu4e-main.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(require 'smtpmail) ;; the queing stuff (silence elint)
-(require 'mu4e-utils) ;; utility functions
-(require 'mu4e-context) ;; the context
-
-
-(defconst mu4e~main-buffer-name " *mu4e-main*"
- "*internal* Name of the mu4e main view buffer.")
-
-(defvar mu4e-main-mode-map
- (let ((map (make-sparse-keymap)))
-
- (define-key map "b" 'mu4e-headers-search-bookmark)
- (define-key map "B" 'mu4e-headers-search-bookmark-edit)
-
- (define-key map "s" 'mu4e-headers-search)
- (define-key map "q" 'mu4e-quit)
- (define-key map "j" 'mu4e~headers-jump-to-maildir)
- (define-key map "C" 'mu4e-compose-new)
-
- (define-key map "m" 'mu4e~main-toggle-mail-sending-mode)
- (define-key map "f" 'smtpmail-send-queued-mail)
-
- ;;
- (define-key map "U" 'mu4e-update-mail-and-index)
- (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
- ;; for terminal users
- (define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
-
- (define-key map "S" 'mu4e-interrupt-update-mail)
- (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
- (define-key map ";" 'mu4e-context-switch)
-
- (define-key map "$" 'mu4e-show-log)
- (define-key map "A" 'mu4e-about)
- (define-key map "N" 'mu4e-news)
- (define-key map "H" 'mu4e-display-manual)
- map)
-
- "Keymap for the *mu4e-main* buffer.")
-(fset 'mu4e-main-mode-map mu4e-main-mode-map)
-
-(defvar mu4e-main-mode-abbrev-table nil)
-(define-derived-mode mu4e-main-mode special-mode "mu4e:main"
- "Major mode for the mu4e main screen.
-\\{mu4e-main-mode-map}."
- (use-local-map mu4e-main-mode-map)
- (setq
- truncate-lines t
- overwrite-mode 'overwrite-mode-binary)
-
- ;; show context in mode-string
- (set (make-local-variable 'global-mode-string) '(:eval (mu4e-context-label)))
- (set (make-local-variable 'revert-buffer-function) #'mu4e~main-view-real))
-
-
-(defun mu4e~main-action-str (str &optional func-or-shortcut)
- "Highlight the first occurence of [.] in STR.
-If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it
-when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is
-a string, execute the corresponding keyboard action when it is
-clicked."
- (let ((newstr
- (replace-regexp-in-string
- "\\[\\(..?\\)\\]"
- (lambda(m)
- (format "[%s]"
- (propertize (match-string 1 m) 'face 'mu4e-highlight-face)))
- str))
- (map (make-sparse-keymap))
- (func (if (functionp func-or-shortcut)
- func-or-shortcut
- (if (stringp func-or-shortcut)
- (lexical-let ((macro func-or-shortcut))
- (lambda()(interactive)
- (execute-kbd-macro macro)))))))
- (define-key map [mouse-2] func)
- (define-key map (kbd "RET") func)
- (put-text-property 0 (length newstr) 'keymap map newstr)
- (put-text-property (string-match "\\[.+$" newstr)
- (- (length newstr) 1) 'mouse-face 'highlight newstr) newstr))
-
-;; NEW
-;; This is the old `mu4e~main-view' function but without
-;; buffer switching at the end.
-(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-mu-version 'face 'mu4e-header-key-face)
-
- ;; show some server properties; in this case; a big C when there's
- ;; crypto support, a big G when there's Guile support
- " "
- (propertize
- (concat
- (when (plist-get mu4e~server-props :crypto) "C")
- (when (plist-get mu4e~server-props :guile) "G"))
- 'face 'mu4e-title-face)
-
- "\n\n"
- (propertize " Basics\n\n" 'face 'mu4e-title-face)
- (mu4e~main-action-str "\t* [j]ump to some maildir\n" 'mu4e-jump-to-maildir)
- (mu4e~main-action-str "\t* enter a [s]earch query\n" 'mu4e-search)
- (mu4e~main-action-str "\t* [C]ompose a new message\n" 'mu4e-compose-new)
- "\n"
- (propertize " Bookmarks\n\n" 'face 'mu4e-title-face)
- ;; TODO: it's a bit uncool to hard-code the "b" shortcut...
- (mapconcat
- (lambda (bm)
- (mu4e~main-action-str
- (concat "\t* [b" (make-string 1 (mu4e-bookmark-key bm)) "] "
- (mu4e-bookmark-name bm))
- (concat "b" (make-string 1 (mu4e-bookmark-key bm)))))
- (mu4e-bookmarks) "\n")
- "\n\n"
- (propertize " Misc\n\n" 'face 'mu4e-title-face)
-
- (mu4e~main-action-str "\t* [;]Switch focus\n" 'mu4e-context-switch)
-
- (mu4e~main-action-str "\t* [U]pdate email & database\n"
- 'mu4e-update-mail-and-index)
-
- ;; show the queue functions if `smtpmail-queue-dir' is defined
- (if (file-directory-p smtpmail-queue-dir)
- (mu4e~main-view-queue)
- "")
- "\n"
- (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)
- )))
-
-(defun mu4e~main-view-queue ()
- "Display queue-related actions in the main view."
- (concat
- (mu4e~main-action-str "\t* toggle [m]ail sending mode "
- 'mu4e~main-toggle-mail-sending-mode)
- "(currently "
- (propertize (if smtpmail-queue-mail "queued" "direct")
- 'face 'mu4e-header-key-face)
- ")\n"
- (let ((queue-size (mu4e~main-queue-size)))
- (if (zerop queue-size)
- ""
- (mu4e~main-action-str
- (format "\t* [f]lush %s queued %s\n"
- (propertize (int-to-string queue-size)
- 'face 'mu4e-header-key-face)
- (if (> queue-size 1) "mails" "mail"))
- 'smtpmail-send-queued-mail)))))
-
-(defun mu4e~main-queue-size ()
- "Return, as an int, the number of emails in the queue."
- (condition-case nil
- (with-temp-buffer
- (insert-file-contents (expand-file-name smtpmail-queue-index-file
- smtpmail-queue-dir))
- (count-lines (point-min) (point-max)))
- (error 0)))
-
-(defun mu4e~main-view ()
- "Create the mu4e main-view, and switch to it."
- (mu4e~main-view-real nil nil)
- (switch-to-buffer mu4e~main-buffer-name)
- (goto-char (point-min))
- (setq global-mode-string '(:eval (mu4e-context-label))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Interactive functions
-;; NEW
-;; Toggle mail sending mode without switching
-(defun mu4e~main-toggle-mail-sending-mode ()
- "Toggle sending mail mode, either queued or direct."
- (interactive)
- (let ((curpos (point)))
- (unless (file-directory-p smtpmail-queue-dir)
- (mu4e-error "`smtpmail-queue-dir' does not exist"))
- (setq smtpmail-queue-mail (not smtpmail-queue-mail))
- (message
- (concat "Outgoing mail will now be "
- (if smtpmail-queue-mail "queued" "sent directly")))
- (mu4e~main-view-real nil nil)
- (goto-char curpos)))
-
-
-;; (progn
-;; (define-key mu4e-compose-mode-map (kbd "C-c m") 'mu4e~main-toggle-mail-sending-mode)
-;; (define-key mu4e-view-mode-map (kbd "C-c m") 'mu4e~main-toggle-mail-sending-mode)
-;; (define-key mu4e-compose-mode-map (kbd "C-c m") 'mu4e~main-toggle-mail-sending-mode)
-;; (define-key mu4e-headers-mode-map (kbd "C-c m") 'mu4e~main-toggle-mail-sending-mode)
-;; )
-
-(provide 'mu4e-main)
diff --git a/_spacemacs.d/local/mu4e/mu4e-mark.el b/_spacemacs.d/local/mu4e/mu4e-mark.el
deleted file mode 100644
index 4b17f34..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-mark.el
+++ /dev/null
@@ -1,466 +0,0 @@
-;; mu4e-mark.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; In this file are function related to marking messages; they assume we are
-;; currently in the headers buffer.
-
-;; Code:
-(require 'mu4e-proc)
-(require 'mu4e-utils)
-(require 'mu4e-message)
-
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-
-;; keep byte-compiler happy
-(declare-function mu4e~headers-mark "mu4e-headers")
-(declare-function mu4e~headers-goto-docid "mu4e-headers")
-(declare-function mu4e-headers-next "mu4e-headers")
-
-
-(defcustom mu4e-headers-leave-behavior 'ask
- "What to do when user leaves the headers view.
-That is when he e.g. quits, refreshes or does a new search.
-Value is one of the following symbols:
-- `ask' ask user whether to ignore the marks
-- `apply' automatically apply the marks before doing anything else
-- `ignore' automatically ignore the marks without asking"
- :type '(choice (const ask :tag "ask user whether to ignore marks")
- (const apply :tag "apply marks without asking")
- (const ignore :tag "ignore marks without asking"))
- :group 'mu4e-headers)
-
-(defcustom mu4e-mark-execute-pre-hook nil
- "Hook run just *before* a mark is applied to a message. The hook function
-is called with two arguments, the mark being executed and the message itself.")
-
-(defvar mu4e-headers-show-target t
- "Whether to show targets (such as '-> delete', '-> /archive')
-when marking message. Normally, this is useful information for the
-user, however, when you often mark large numbers (thousands) of
-message, showing the target makes this quite a bit slower (showing
-the target uses an emacs feature called 'overlays', which aren't
-particularly fast).")
-
-;;; insert stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e~mark-map nil
- "Map (hash) of docid->markinfo; when a message is marked, the
-information is added here.
-markinfo is a cons cell consisting of the following:
-\(mark . target)
-where
- MARK is the type of mark (move, trash, delete)
- TARGET (optional) is the target directory (for 'move')")
-
-;; the mark-map is specific for the current header buffer
-;; currently, there can't be more than one, but we never know what will
-;; happen in the future
-
-;; the fringe is the space on the left of headers, where we put marks below some
-;; handy definitions; only `mu4e-mark-fringe-len' should be change (if ever),
-;; the others follow from that.
-(defconst mu4e~mark-fringe-len 2
- "Width of the fringe for marks on the left.")
-(defconst mu4e~mark-fringe (make-string mu4e~mark-fringe-len ?\s)
- "The space on the left of message headers to put marks.")
-(defconst mu4e~mark-fringe-format (format "%%-%ds" mu4e~mark-fringe-len)
- "Format string to set a mark and leave remaining space.")
-
-(defun mu4e~mark-initialize ()
- "Initialize the marks subsystem."
- (set (make-local-variable 'mu4e~mark-map) (make-hash-table)))
-
-(defun mu4e~mark-clear ()
- "Clear the marks subsystem."
- (clrhash mu4e~mark-map))
-
-(defun mu4e~mark-find-headers-buffer ()
- "Find the headers buffer, if any."
- (find-if
- (lambda (b)
- (with-current-buffer b
- (eq major-mode 'mu4e-headers-mode)))
- (buffer-list)))
-
-(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."
- `(cond
- ((eq major-mode 'mu4e-headers-mode) ,@body)
- ((eq major-mode 'mu4e-view-mode)
- (when (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."))))))
- (t
- ;; even in other modes (e.g. mu4e-main-mode we try to find
- ;; the headers buffer
- (let ((hbuf (mu4e~mark-find-headers-buffer)))
- (if (buffer-live-p hbuf)
- (with-current-buffer hbuf
- ,@body)
- (progn (mu4e-message "%S" major-mode) ,@body))))))
-
-(defvar mu4e-marks
- '((refile
- :char ("r" . "â–¶")
- :prompt "refile"
- :dyn-target (lambda (target msg) (mu4e-get-refile-folder msg))
- :action (lambda (docid msg target) (mu4e~proc-move docid
- (mu4e~mark-check-target target) "-N")))
- (delete
- :char ("D" . "âŒ")
- :prompt "Delete"
- :show-target (lambda (target) "delete")
- :action (lambda (docid msg target) (mu4e~proc-remove docid)))
- (flag
- :char ("+" . "✚")
- :prompt "+flag"
- :show-target (lambda (target) "flag")
- :action (lambda (docid msg target) (mu4e~proc-move docid nil "+F-u-N")))
- (move
- :char ("m" . "â–·")
- :prompt "move"
- :ask-target mu4e~mark-get-move-target
- :action (lambda (docid msg target) (mu4e~proc-move docid
- (mu4e~mark-check-target target) "-N")))
- (read
- :char ("!" . "â—¼")
- :prompt "!read"
- :show-target (lambda (target) "read")
- :action (lambda (docid msg target) (mu4e~proc-move docid nil "+S-u-N")))
- (trash
- :char ("d" . "â–¼")
- :prompt "dtrash"
- :dyn-target (lambda (target msg) (mu4e-get-trash-folder msg))
- :action (lambda (docid msg target) (mu4e~proc-move docid
- (mu4e~mark-check-target target) "+T-N")))
- (unflag
- :char ("-" . "âž–")
- :prompt "-unflag"
- :show-target (lambda (target) "unflag")
- :action (lambda (docid msg target) (mu4e~proc-move docid nil "-F-N")))
- (untrash
- :char ("=" . "â–²")
- :prompt "=untrash"
- :show-target (lambda (target) "untrash")
- :action (lambda (docid msg target) (mu4e~proc-move docid nil "-T")))
- (unread
- :char ("?" . "â—»")
- :prompt "?unread"
- :show-target (lambda (target) "unread")
- :action (lambda (docid msg target) (mu4e~proc-move docid nil "-S+u-N")))
- (unmark
- :char " "
- :prompt "unmark"
- :action (mu4e-error "No action for unmarking"))
- (action
- :char ( "a" . "â—¯")
- :prompt "action"
- :ask-target (lambda () (mu4e-read-option "Action: " mu4e-headers-actions))
- :action (lambda (docid msg actionfunc)
- (save-excursion
- (when (mu4e~headers-goto-docid docid)
- (mu4e-headers-action actionfunc)))))
- (something
- :char ("*" . "✱")
- :prompt "*something"
- :action (mu4e-error "No action for deferred mark")))
-
- "The list of all the possible marks.
-This is an alist mapping mark symbols to their properties. The
-properties are:
- :char (string) or (basic . fancy) The character to display in
- the headers view. Either a single-character string, or a
- dotted-pair cons cell where the second item will be used if
- `mu4e-use-fancy-chars' is `t', otherwise we'll use
- the first one. It can also be a plain string for backwards
- compatibility since we didn't always support
- `mu4e-use-fancy-chars' here.
- :prompt (string) The prompt to use when asking for marks (used for
- example when marking a whole thread)
- :ask-target (function returning a string) Get the target. This
- function run once per bulk-operation, and thus is suitable
- for user-interaction. If nil, the target is nil.
- :dyn-target (function from (TARGET MSG) to string). Compute
- the dynamic target. This is run once per message, which is
- passed as MSG. The default is to just return the target.
- :show-target (function from TARGET to string) How to display
- the target.
- :action (function taking (DOCID MSG TARGET)). The action to
- apply on the message.")
-
-
-(defun mu4e-mark-at-point (mark target)
- "Mark (or unmark) message at point.
-MARK specifies the mark-type. For `move'-marks and `trash'-marks
-the TARGET argument is non-nil and specifies to which
-maildir the message is to be moved/trashed. The function works in
-both headers buffers and message buffers.
-
-The following marks are available, and the corresponding props:
-
- MARK TARGET description
- ----------------------------------------------------------
- `refile' y mark this message for archiving
- `something' n mark this message for *something* (decided later)
- `delete' n remove the message
- `flag' n mark this message for flagging
- `move' y move the message to some folder
- `read' n mark the message as read
- `trash' y trash the message to some folder
- `unflag' n mark this message for unflagging
- `untrash' n remove the 'trashed' flag from a message
- `unmark' n unmark this message
- `unread' n mark the message as unread
- `action' y mark the message for some action."
- (interactive)
- (let* ((msg (mu4e-message-at-point))
- (docid (mu4e-message-field msg :docid))
- ;; get a cell with the mark char and the 'target' 'move' already has a
- ;; target (the target folder) the other ones get a pseudo "target", as
- ;; info for the user.
- (markdesc (cdr (or (assq mark mu4e-marks) (mu4e-error "Invalid mark %S" mark))))
- (get-markkar
- (lambda (char)
- (if (listp char)
- (if mu4e-use-fancy-chars (cdr char) (car char))
- char)))
- (markkar (funcall get-markkar (plist-get markdesc :char)))
- (target (mu4e~mark-get-dyn-target mark target))
- (show-fct (plist-get markdesc :show-target))
- (shown-target (if show-fct
- (funcall show-fct target)
- (if target (format "%S" target)))))
- (unless docid (mu4e-warn "No message on this line"))
- (unless (eq major-mode 'mu4e-headers-mode) (mu4e-error "Not in headers-mode"))
- (save-excursion
- (when (mu4e~headers-mark docid markkar)
- ;; update the hash -- remove everything current, and if add the new stuff,
- ;; unless we're unmarking
- (remhash docid mu4e~mark-map)
- ;; remove possible overlays
- (remove-overlays (line-beginning-position) (line-end-position))
- ;; now, let's set a mark (unless we were unmarking)
- (unless (eql mark 'unmark)
- (puthash docid (cons mark target) mu4e~mark-map)
- ;; when we have a target (ie., when moving), show the target folder in
- ;; an overlay
- (when (and shown-target mu4e-headers-show-target)
- (let* ((targetstr (propertize (concat "-> " shown-target " ")
- 'face 'mu4e-system-face))
- ;; mu4e~headers-goto-docid docid t \will take us just after the
- ;; docid cookie and then we skip the mu4e~mark-fringe
- (start (+ (length mu4e~mark-fringe)
- (mu4e~headers-goto-docid docid t)))
- (overlay (make-overlay start (+ start (length targetstr)))))
- (overlay-put overlay 'display targetstr)
- docid)))))))
-
-
-(defun mu4e~mark-get-move-target ()
- "Ask for a move target, and propose to create it if it does not exist."
- (interactive)
- ;; (mu4e-message-at-point) ;; raises error if there is none
- (let* ((target (mu4e-ask-maildir "Move message to: "))
- (target (if (string= (substring target 0 1) "/")
- target
- (concat "/" target)))
- (fulltarget (concat mu4e-maildir target)))
- (when (or (file-directory-p fulltarget)
- (and (yes-or-no-p
- (format "%s does not exist. Create now?" fulltarget))
- (mu4e~proc-mkdir fulltarget)))
- target)))
-
-(defun mu4e~mark-ask-target (mark)
- "Ask the target for MARK, if the user should be asked the target."
- (let ((getter (plist-get (cdr (assq mark mu4e-marks)) :ask-target)))
- (and getter (funcall getter))))
-
-(defun mu4e~mark-get-dyn-target (mark target)
- "Get the dynamic target for MARK. The result may depend on the
-message at point."
- (let ((getter (plist-get (cdr (assq mark mu4e-marks)) :dyn-target)))
- (if getter
- (funcall getter target (mu4e-message-at-point))
- target)))
-
-
-(defun mu4e-mark-set (mark &optional target)
- "Mark the header at point, or, if region is active, mark all
-headers in the region. Optionally, provide TARGET (for moves)."
- (unless target
- (setq target (mu4e~mark-ask-target mark)))
- (if (not (use-region-p))
- ;; single message
- (mu4e-mark-at-point mark target)
- ;; mark all messages in the region.
- (save-excursion
- (let ((cant-go-further) (eor (region-end)))
- (goto-char (region-beginning))
- (while (and (<= (point) eor) (not cant-go-further))
- (mu4e-mark-at-point mark target)
- (setq cant-go-further (not (mu4e-headers-next))))))))
-
-(defun mu4e-mark-restore (docid)
- "Restore the visual mark for the message with DOCID."
- (let ((markcell (gethash docid mu4e~mark-map)))
- (when markcell
- (save-excursion
- (when (mu4e~headers-goto-docid docid)
- (mu4e-mark-at-point (car markcell) (cdr markcell)))))))
-
-(defun mu4e~mark-get-markpair (prompt &optional allow-something)
- "Ask user for a mark; return (MARK . TARGET).
-If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark
-as well."
- (let* ((marks (mapcar (lambda (markdescr)
- (cons (plist-get (cdr markdescr) :prompt)
- (car markdescr)))
- mu4e-marks))
- (marks
- (if allow-something
- marks (remove-if (lambda (m) (eq 'something (cdr m))) marks)))
- (mark (mu4e-read-option prompt marks))
- (target (mu4e~mark-ask-target mark)))
- (cons mark target)))
-
-
-(defun mu4e-mark-resolve-deferred-marks ()
- "Check if there are any deferred ('something') marks.
-If there are such marks, replace them with a _real_ mark (ask the
-user which one)."
- (interactive)
- (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."
- (let ((fulltarget (concat mu4e-maildir target)))
- (if (not (mu4e-create-maildir-maybe fulltarget))
- (mu4e-error "Target dir %s does not exist " fulltarget)
- target)))
-
-(defun mu4e-mark-execute-all (&optional no-confirmation)
- "Execute the actions for all marked messages in this buffer.
-After the actions have been executed succesfully, the affected
-messages are *hidden* from the current header list. Since the
-headers are the result of a search, we cannot be certain that the
-messages no longer match the current one - to get that
-certainty, we need to rerun the search, but we don't want to do
-that automatically, as it may be too slow and/or break the user's
-flow. Therefore, we hide the message, which in practice seems to
-work well.
-
-If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
- (interactive)
- (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))
- (markdescr (assq mark mu4e-marks))
- (msg (save-excursion
- (mu4e~headers-goto-docid docid)
- (mu4e-message-at-point))))
- ;; note: whenever you do something with the message,
- ;; it looses its N (new) flag
- (if markdescr
- (progn
- (run-hook-with-args
- 'mu4e-mark-execute-pre-hook mark msg)
- (funcall (plist-get (cdr markdescr) :action) docid msg target))
- (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)
- (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?"
- (when (gethash docid mu4e~mark-map) t))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(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,
-quitting the buffer) is taken; returning t means 'take the following
-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
diff --git a/_spacemacs.d/local/mu4e/mu4e-message.el b/_spacemacs.d/local/mu4e/mu4e-message.el
deleted file mode 100644
index e339077..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-message.el
+++ /dev/null
@@ -1,284 +0,0 @@
-;;; mu4e-message.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2012-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Functions to get data from mu4e-message plist structure
-
-;;; Code:
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-
-(require 'mu4e-vars)
-(require 'mu4e-utils)
-
-(require 'cl)
-(require 'html2text)
-
-
-(defcustom mu4e-html2text-command
- (if (fboundp 'shr-insert-document) 'mu4e-shr2text 'html2text)
-
- "Either a shell command or a function that converts from html to plain text.
-
-If it is a shell-command, the command reads html from standard
-input and outputs plain text on standard output. If you use the
-htmltext program, it's recommended you use \"html2text -utf8
--width 72\". Alternatives are the python-based html2markdown, w3m
-and on MacOS you may want to use textutil.
-
-It can also be a function, which takes the current buffer in html
-as input, and transforms it into html (like the `html2text'
-function).
-
-In both cases, the output is expected to be in UTF-8 encoding.
-
-Newer emacs has the shr renderer, and when its available,
-conversion defaults `mu4e-shr2text'; otherwise, the default is
-emacs' built-in `html2text' function."
- :type '(choice string function)
- :group 'mu4e-view)
-
-(defcustom mu4e-view-prefer-html nil
- "Whether to base the body display on the html-version.
-If the e-mail message has no html-version the plain-text version
-is always used."
- :type 'boolean
- :group 'mu4e-view)
-
-(defcustom mu4e-view-html-plaintext-ratio-heuristic 5
- "Ratio between the length of the html and the plain text part
-below which mu4e will consider the plain text part to be 'This
-messages requires html' text bodies."
- :type 'integer
- :group 'mu4e-view)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defsubst mu4e-message-field-raw (msg field)
- "Retrieve FIELD from message plist MSG.
-FIELD is one of :from, :to, :cc, :bcc, :subject, :data,
-:message-id, :path, :maildir, :priority, :attachments,
-:references, :in-reply-to, :body-txt, :body-html
-
-Returns `nil' if the field does not exist.
-
-A message plist looks something like:
-\(:docid 32461
- :from ((\"Nikola Tesla\" . \"niko@example.com\"))
- :to ((\"Thomas Edison\" . \"tom@example.com\"))
- :cc ((\"Rupert The Monkey\" . \"rupert@example.com\"))
- :subject \"RE: what about the 50K?\"
- :date (20369 17624 0)
- :size 4337
- :message-id \"6BDC23465F79238C8233AB82D81EE81AF0114E4E74@123213.mail.example.com\"
- :path \"/home/tom/Maildir/INBOX/cur/133443243973_1.10027.atlas:2,S\"
- :maildir \"/INBOX\"
- :priority normal
- :flags (seen)
- :attachments
- ((:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)
- (:index 3 :name \"book.pdf\" :mime-type \"application/pdf\" :size 192220))
- :references (\"6BDC23465F79238C8384574032D81EE81AF0114E4E74@123213.mail.example.com\"
- \"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\")
- :in-reply-to \"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\"
- :body-txt \"Hi Tom, ...\"
-\)).
-Some notes on the format:
-- The address fields are lists of pairs (NAME . EMAIL), where NAME can be nil.
-- The date is in format emacs uses in `current-time'
-- Attachments are a list of elements with fields :index (the number of
- the MIME-part), :name (the file name, if any), :mime-type (the
- MIME-type, if any) and :size (the size in bytes, if any).
-- Messages in the Headers view come from the database and do not have
- :attachments, :body-txt or :body-html fields. Message in the
- Message view use the actual message file, and do include these fields."
- ;; after all this documentation, the spectacular implementation
- (if msg
- (plist-get msg field)
- (mu4e-error "message must be non-nil")))
-
-(defsubst mu4e-message-field (msg field)
- "Retrieve FIELD from message plist MSG.
-Like `mu4e-message-field-nil', but will sanitize `nil' values:
-- all string field except body-txt/body-html: nil -> \"\"
-- numeric fields + dates : nil -> 0
-- all others : return the value
-Thus, function will return nil for empty lists, non-existing body-txt or body-html."
- (let ((val (mu4e-message-field-raw msg field)))
- (cond
- (val
- val) ;; non-nil -> just return it
- ((member field '(:subject :message-id :path :maildir :in-reply-to))
- "") ;; string fields except body-txt, body-html: nil -> ""
- ((member field '(:body-html :body-txt))
- val)
- ((member field '(:docid :size))
- 0) ;; numeric type: nil -> 0
- (t
- val)))) ;; otherwise, just return nil
-
-(defsubst mu4e-message-has-field (msg field)
- "Return t if MSG contains FIELD, nil otherwise."
- (plist-member msg field))
-
-(defsubst mu4e-message-at-point (&optional noerror)
- "Get the message s-expression for the message at point in either
-the headers buffer or the view buffer, or nil if there is no such
-message. If optional NOERROR is non-nil, do not raise an error when
-there is no message at point."
- (let ((msg (or (get-text-property (point) 'msg) mu4e~view-msg)))
- (if msg
- msg
- (unless noerror (mu4e-warn "No message at point")))))
-
-(defsubst mu4e-message-field-at-point (field)
- "Get the field FIELD from the message at point.
-This is equivalent to:
- (mu4e-message-field (mu4e-message-at-point) FIELD)."
- (mu4e-message-field (mu4e-message-at-point) field))
-
-(defun mu4e-message-body-text (msg)
- "Get the body in text form for this message.
-This is either :body-txt, or if not available, :body-html converted
-to text, using `mu4e-html2text-command' is non-nil, it will use
-that. Normally, thiss function prefers the text part, but this can
-be changed by setting `mu4e-view-prefer-html'."
- (let* ((txt (mu4e-message-field msg :body-txt))
- (html (mu4e-message-field msg :body-html))
- (body
- (cond
- ;; does it look like some text? ie., if the text part is more than
- ;; mu4e-view-html-plaintext-ratio-heuristic times shorter than the
- ;; html part, it should't be used
- ;; This is an heuristic to guard against 'This messages requires
- ;; html' text bodies.
- ((and (> (* mu4e-view-html-plaintext-ratio-heuristic
- (length txt)) (length html))
- ;; use html if it's prefered, unless there is no html
- (or (not mu4e-view-prefer-html) (not html)))
- txt)
- ;; otherwise, it there some html?
- (html
- (with-temp-buffer
- (insert html)
- (cond
- ((stringp mu4e-html2text-command)
- (let* ((tmp-file (mu4e-make-temp-file "html")))
- (write-region (point-min) (point-max) tmp-file)
- (erase-buffer)
- (call-process-shell-command mu4e-html2text-command tmp-file t t)
- (delete-file tmp-file)))
- ((functionp mu4e-html2text-command)
- (funcall mu4e-html2text-command))
- (t (mu4e-error "Invalid `mu4e-html2text-command'")))
- (buffer-string))
- )
- (t ;; otherwise, an empty body
- ""))))
- ;; and finally, remove some crap from the remaining string; it seems
- ;; esp. outlook lies about its encoding (ie., it says 'iso-8859-1' but
- ;; really it's 'windows-1252'), thus giving us these funky chars. here, we
- ;; either remove them, or replace with 'what-was-meant' (heuristically)
- (with-temp-buffer
- (insert body)
- (goto-char (point-min))
- (while (re-search-forward "[  ’]" nil t)
- (replace-match
- (cond
- ((string= (match-string 0) "’") "'")
- (t ""))))
- (buffer-string))))
-
-(defun mu4e-message-contact-field-matches (msg cfield rx)
- "Checks whether any of the of the contacts in field
-CFIELD (either :to, :from, :cc or :bcc, or a list of those) of
-msg MSG matches (with their name or e-mail address) regular
-expressions RX. If there is a match, return non-nil; otherwise
-return nil. RX can also be a list of regular expressions, in
-which case any of those are tried for a match."
- (if (and cfield (listp cfield))
- (or (mu4e-message-contact-field-matches msg (car cfield) rx)
- (mu4e-message-contact-field-matches msg (cdr cfield) rx))
- (when cfield
- (if (listp rx)
- ;; if rx is a list, try each one of them for a match
- (find-if
- (lambda (a-rx) (mu4e-message-contact-field-matches msg cfield a-rx))
- rx)
- ;; not a list, check the rx
- (find-if
- (lambda (ct)
- (let ((name (car ct)) (email (cdr ct)))
- (or
- (and name (string-match rx name))
- (and email (string-match rx email)))))
- (mu4e-message-field msg cfield))))))
-
-(defun mu4e-message-contact-field-matches-me (msg cfield)
- "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
-matched, or nil."
- (find-if
- (lambda (cc-cell)
- (member-if
- (lambda (addr)
- (string= (downcase addr) (downcase (cdr cc-cell))))
- mu4e-user-mail-address-list))
- (mu4e-message-field msg cfield)))
-
-(defsubst mu4e-message-part-field (msgpart field)
- "Get some field in a message part; a part would look something like:
- (:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)."
- (plist-get msgpart field))
-
-;; backward compatibility ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defalias 'mu4e-msg-field 'mu4e-message-field)
-(defalias 'mu4e-body-text 'mu4e-message-body-text) ;; backward compatibility
-
-(defun mu4e-field-at-point (field)
- "Get FIELD (a symbol, see `mu4e-header-info') for the message at
-point in eiter the headers buffer or the view buffer."
- (plist-get (mu4e-message-at-point) field))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defun mu4e-shr2text ()
- "Html to text using the shr engine; this can be used in
-`mu4e-html2text-command' in a new enough emacs. Based on code by
-Titus von der Malsburg."
- (interactive)
- (let ((dom (libxml-parse-html-region (point-min) (point-max)))
- ;; When HTML emails contain references to remote images,
- ;; retrieving these images leaks information. For example,
- ;; the sender can see when I openend the email and from which
- ;; computer (IP address). For this reason, it is preferrable
- ;; to not retrieve images.
- ;; See this discussion on mu-discuss:
- ;; https://groups.google.com/forum/#!topic/mu-discuss/gr1cwNNZnXo
- (shr-inhibit-images t))
- (erase-buffer)
- (shr-insert-document dom)
- (goto-char (point-min))))
-
-(provide 'mu4e-message)
diff --git a/_spacemacs.d/local/mu4e/mu4e-meta.el b/_spacemacs.d/local/mu4e/mu4e-meta.el
deleted file mode 100644
index 255d6e9..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-meta.el
+++ /dev/null
@@ -1,11 +0,0 @@
-;; auto-generated
-(defconst mu4e-mu-version "0.9.17"
- "Required mu binary version; mu4e's version must agree with this.")
-
-(defconst mu4e-builddir "/home/aly/devel/mu"
- "Top-level build directory.")
-
-(defconst mu4e-doc-dir "/home/aly/local/mu/share/doc/mu"
- "Mu4e's data-dir.")
-
-(provide 'mu4e-meta)
diff --git a/_spacemacs.d/local/mu4e/mu4e-proc.el b/_spacemacs.d/local/mu4e/mu4e-proc.el
deleted file mode 100644
index d6d90e1..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-proc.el
+++ /dev/null
@@ -1,525 +0,0 @@
-;; mu4e-proc.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-(require 'mu4e-vars)
-(require 'mu4e-utils)
-(require 'mu4e-meta)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; internal vars
-
-(defvar mu4e~proc-buf nil
- "Buffer (string) for data received from the backend.")
-(defconst mu4e~proc-name " *mu4e-proc*"
- "Name of the server process, buffer.")
-(defvar mu4e~proc-process nil
- "The mu-server process.")
-
-;; dealing with the length cookie that precedes expressions
-(defconst mu4e~cookie-pre "\376"
- "Each expression we get from the backend (mu server) starts with
-a length cookie:
- <`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.")
-(defconst mu4e~cookie-post "\377"
- "Each expression we get from the backend (mu server) starts with
-a length cookie:
- <`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.")
-(defconst mu4e~cookie-matcher-rx
- (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)" mu4e~cookie-post)
- "Regular expression matching the length cookie.
-Match 1 will be the length (in hex).")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defsubst mu4e~proc-send-command (frm &rest args)
- "Send as command to the mu server process.
-Start the process if needed."
- (unless (mu4e~proc-running-p)
- (mu4e~proc-start))
- (let ((cmd (apply 'format frm args)))
- (mu4e-log 'to-server "%s" cmd)
- (process-send-string mu4e~proc-process (concat cmd "\n"))))
-
-(defun mu4e~proc-start ()
- "Start the mu server process."
- (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))))))
- (setq mu4e~proc-buf "")
- (setq mu4e~proc-process (apply 'start-process
- mu4e~proc-name mu4e~proc-name
- mu4e-mu-binary args))
- ;; register a function for (:info ...) sexps
- (unless mu4e~proc-process
- (mu4e-error "Failed to start the mu4e backend"))
- (set-process-query-on-exit-flag mu4e~proc-process nil)
- (set-process-coding-system mu4e~proc-process 'binary 'utf-8-unix)
- (set-process-filter mu4e~proc-process 'mu4e~proc-filter)
- (set-process-sentinel mu4e~proc-process 'mu4e~proc-sentinel)))
-
-(defun mu4e~proc-kill ()
- "Kill the mu server process."
- (let* ((buf (get-buffer mu4e~proc-name))
- (proc (and (buffer-live-p buf) (get-buffer-process buf))))
- (when proc
- (let ((delete-exited-processes t))
- ;; the mu server signal handler will make it quit after 'quit'
- (mu4e~proc-send-command "cmd:quit"))
- ;; try sending SIGINT (C-c) to process, so it can exit gracefully
- (ignore-errors
- (signal-process proc 'SIGINT))))
- (setq
- mu4e~proc-process nil
- mu4e~proc-buf nil))
-
-(defun mu4e~proc-running-p ()
- "Whether the mu process is running."
- (when (and mu4e~proc-process
- (memq (process-status mu4e~proc-process)
- '(run open listen connect stop)))
- t))
-
-(defsubst mu4e~proc-eat-sexp-from-buf ()
- "'Eat' the next s-expression from `mu4e~proc-buf'.
-Note: this is a string, not an emacs-buffer. `mu4e~proc-buf gets
-its contents from the mu-servers in the following form:
- <`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>
-Function returns this sexp, or nil if there was none.
-`mu4e~proc-buf' is updated as well, with all processed sexp data
-removed."
- (ignore-errors ;; the server may die in the middle...
- ;; mu4e~cookie-matcher-rx:
- ;; (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)]" mu4e~cookie-post)
- (let ((b (string-match mu4e~cookie-matcher-rx mu4e~proc-buf))
- (sexp-len) (objcons))
- (when b
- (setq sexp-len (string-to-number (match-string 1 mu4e~proc-buf) 16))
- ;; does mu4e~proc-buf contain the full sexp?
- (when (>= (length mu4e~proc-buf) (+ sexp-len (match-end 0)))
- ;; clear-up start
- (setq mu4e~proc-buf (substring mu4e~proc-buf (match-end 0)))
- ;; note: we read the input in binary mode -- here, we take the part
- ;; that is the sexp, and convert that to utf-8, before we interpret
- ;; it.
- (setq objcons (read-from-string
- (decode-coding-string
- (substring mu4e~proc-buf 0 sexp-len)
- 'utf-8 t)))
- (when objcons
- (setq mu4e~proc-buf (substring mu4e~proc-buf sexp-len))
- (car objcons)))))))
-
-
-(defun mu4e~proc-filter (proc str)
- "A process-filter for the 'mu server' output.
-It accumulates the strings into valid sexps by checking of the
-';;eox' end-of-sexp marker, and then evaluating them.
-
-The server output is as follows:
-
- 1. an error
- (:error 2 :message \"unknown command\")
- ;; eox
- => this will be passed to `mu4e-error-func'.
-
- 2a. a message sexp looks something like:
- \(
- :docid 1585
- :from ((\"Donald Duck\" . \"donald@example.com\"))
- :to ((\"Mickey Mouse\" . \"mickey@example.com\"))
- :subject \"Wicked stuff\"
- :date (20023 26572 0)
- :size 15165
- :references (\"200208121222.g7CCMdb80690@msg.id\")
- :in-reply-to \"200208121222.g7CCMdb80690@msg.id\"
- :message-id \"foobar32423847ef23@pluto.net\"
- :maildir: \"/archive\"
- :path \"/home/mickey/Maildir/inbox/cur/1312254065_3.32282.pluto,4cd5bd4e9:2,\"
- :priority high
- :flags (new unread)
- :attachments ((2 \"hello.jpg\" \"image/jpeg\") (3 \"laah.mp3\" \"audio/mp3\"))
- :body-txt \" <message body>\"
-\)
-;; eox
- => this will be passed to `mu4e-header-func'.
-
- 2b. After the list of message sexps has been returned (see 2a.),
- we'll receive a sexp that looks like
- (:found <n>) with n the number of messages found. The <n> will be
- passed to `mu4e-found-func'.
-
- 3. a view looks like:
- (:view <msg-sexp>)
- => the <msg-sexp> (see 2.) will be passed to `mu4e-view-func'.
-
- 4. a database update looks like:
- (:update <msg-sexp> :move <nil-or-t>)
-
- => the <msg-sexp> (see 2.) will be passed to
- `mu4e-update-func', :move tells us whether this is a move to
- another maildir, or merely a flag change.
-
- 5. a remove looks like:
- (:remove <docid>)
- => the docid will be passed to `mu4e-remove-func'
-
- 6. a compose looks like:
- (:compose <reply|forward|edit|new> [:original<msg-sexp>] [:include <attach>])
- `mu4e-compose-func'."
- (mu4e-log 'misc "* Received %d byte(s)" (length str))
- (setq mu4e~proc-buf (concat mu4e~proc-buf str)) ;; update our buffer
- (let ((sexp (mu4e~proc-eat-sexp-from-buf)))
- (with-local-quit
- (while sexp
- (mu4e-log 'from-server "%S" sexp)
- (cond
- ;; a header plist can be recognized by the existence of a :date field
- ((plist-get sexp :date)
- (funcall mu4e-header-func sexp))
-
- ;; the found sexp, we receive after getting all the headers
- ((plist-get sexp :found)
- (funcall mu4e-found-func (plist-get sexp :found)))
-
- ;; viewing a specific message
- ((plist-get sexp :view)
- (funcall mu4e-view-func (plist-get sexp :view)))
-
- ;; receive an erase message
- ((plist-get sexp :erase)
- (funcall mu4e-erase-func))
-
- ;; receive a :sent message
- ((plist-get sexp :sent)
- (funcall mu4e-sent-func
- (plist-get sexp :docid)
- (plist-get sexp :path)))
-
- ;; received a pong message
- ((plist-get sexp :pong)
- (funcall mu4e-pong-func
- (plist-get sexp :props)))
-
- ;; received a contacts message
- ;; note: we use 'member', to match (:contacts nil)
- ((plist-member sexp :contacts)
- (funcall mu4e-contacts-func
- (plist-get sexp :contacts)))
-
- ;; something got moved/flags changed
- ((plist-get sexp :update)
- (funcall mu4e-update-func
- (plist-get sexp :update) (plist-get sexp :move)))
-
- ;; a message got removed
- ((plist-get sexp :remove)
- (funcall mu4e-remove-func (plist-get sexp :remove)))
-
- ;; start composing a new message
- ((plist-get sexp :compose)
- (funcall mu4e-compose-func
- (plist-get sexp :compose)
- (plist-get sexp :original)
- (plist-get sexp :include)))
-
- ;; do something with a temporary file
- ((plist-get sexp :temp)
- (funcall mu4e-temp-func
- (plist-get sexp :temp) ;; name of the temp file
- (plist-get sexp :what) ;; what to do with it
- ;; (pipe|emacs|open-with...)
- (plist-get sexp :docid) ;; docid of the message
- (plist-get sexp :param)));; parameter for the action
-
- ;; get some info
- ((plist-get sexp :info)
- (funcall mu4e-info-func sexp))
-
- ;; receive an error
- ((plist-get sexp :error)
- (funcall mu4e-error-func
- (plist-get sexp :error)
- (plist-get sexp :message)))
-
- (t (mu4e-message "Unexpected data from server [%S]" sexp)))
-
- (setq sexp (mu4e~proc-eat-sexp-from-buf))))))
-
-
-;; error codes are defined in src/mu-util
-;;(defconst mu4e-xapian-empty 19 "Error code: xapian is empty/non-existent")
-
-(defun mu4e~proc-sentinel (proc msg)
- "Function that will be called when the mu-server process terminates."
- (let ((status (process-status proc)) (code (process-exit-status proc)))
- (setq mu4e~proc-process nil)
- (setq mu4e~proc-buf "") ;; clear any half-received sexps
- (cond
- ((eq status 'signal)
- (cond
- ((eq code 9) (message nil))
- ;;(message "the mu server process has been stopped"))
- (t (error (format "mu server process received signal %d" code)))))
- ((eq status 'exit)
- (cond
- ((eq code 0)
- (message nil)) ;; don't do anything
- ((eq code 11)
- (error "Database is locked by another process"))
- ((eq code 15)
- (error "Database needs upgrade; try `mu index --rebuild' from the command line"))
- ((eq code 19)
- (error "Database empty; try indexing some messages"))
- (t (error "mu server process ended with exit code %d" code))))
- (t
- (error "Something bad happened to the mu server process")))))
-
-(defsubst mu4e~docid-msgid-param (docid-or-msgid)
- "Construct a backend parameter based on DOCID-OR-MSGID."
- (format
- (if (stringp docid-or-msgid)
- "msgid:\"%s\""
- "docid:%d")
- docid-or-msgid))
-
-(defun mu4e~proc-remove (docid)
- "Remove message identified by docid.
-The results are reporter through either (:update ... ) or (:error)
-sexp, which are handled my `mu4e-error-func', respectively."
- (mu4e~proc-send-command "cmd:remove docid:%d" docid))
-
-(defun mu4e~proc-escape (str)
- "Escape STRING for transport -- put it in quotes, and escape existing quotation.
-In particular, backslashes and double-quotes."
- (let ((esc (replace-regexp-in-string "\\\\" "\\\\\\\\" str)))
- (format "\"%s\"" (replace-regexp-in-string "\"" "\\\\\"" esc))))
-
-(defun mu4e~proc-find (query threads sortfield sortdir maxnum skip-dups include-related)
- "Start a database query for QUERY.
-If THREADS is non-nil, show results in threaded fasion, SORTFIELD
-is a symbol describing the field to sort by (or nil); see
-`mu4e~headers-sortfield-choices'. If SORT is `descending', sort
-Z->A, if it's `ascending', sort A->Z. MAXNUM determines the maximum
-number of results to return, or nil for 'unlimited'. If SKIP-DUPS
-is non-nil, show only one of duplicate messages (see
-`mu4e-headers-skip-duplicates'). If INCLUDE-RELATED is non-nil,
-include messages related to the messages matching the search
-query (see `mu4e-headers-include-related').
-
-For each
-result found, a function is called, depending on the kind of
-result. The variables `mu4e-error-func' contain the function that
-will be called for, resp., a message (header row) or an error."
- (mu4e~proc-send-command
- (concat
- "cmd:find query:%s threads:%s sortfield:%s reverse:%s maxnum:%d "
- "skip-dups:%s include-related:%s")
- (mu4e~proc-escape query)
- (if threads "true" "false")
- ;; sortfield is e.g. ':subject'; this removes the ':'
- (if (null sortfield) "nil" (substring (symbol-name sortfield) 1))
- ;; TODO: use ascending/descending in backend too (it's clearer than 'reverse'
- (if (eq sortdir 'descending) "true" "false")
- (if maxnum maxnum -1)
- (if skip-dups "true" "false")
- (if include-related "true" "false")))
-
-(defun mu4e~proc-move (docid-or-msgid &optional maildir flags)
- "Move message identified by DOCID-OR-MSGID.
-At least one of MAILDIR and FLAGS should be specified. Note, even
-if MAILDIR is nil, this is still a move, since a change in flags
-still implies a change in message filename.
-
-MAILDIR (), optionally
-setting FLAGS (keyword argument :flags). optionally setting FLAGS
-in the process. If MAILDIR is nil, message will be moved within the
-same maildir.
-
-MAILDIR must be a maildir, that is, the part _without_ cur/ or new/
-or the root-maildir-prefix. E.g. \"/archive\". This directory must
-already exist.
-
-The FLAGS parameter can have the following forms:
- 1. a list of flags such as '(passed replied seen)
- 2. a string containing the one-char versions of the flags, e.g. \"PRS\"
- 3. a delta-string specifying the changes with +/- and the one-char flags,
- e.g. \"+S-N\" to set Seen and remove New.
-
-The flags are any of `deleted', `flagged', `new', `passed', `replied' `seen' or
-`trashed', or the corresponding \"DFNPRST\" as defined in [1]. See
-`mu4e-string-to-flags' and `mu4e-flags-to-string'.
-The server reports the results for the operation through
-`mu4e-update-func'.
-
-If the variable `mu4e-change-filenames-when-moving' is
-non-nil, moving to a different maildir generates new names for
-the target files; this helps certain tools (such as mbsync).
-
-The results are reported through either (:update ... )
-or (:error ) sexp, which are handled my `mu4e-update-func' and
-`mu4e-error-func', respectively."
- (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 "/")))
- (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~proc-escape maildir))))
- (rename
- (if (and maildir mu4e-change-filenames-when-moving) "true" "false")))
- (mu4e~proc-send-command "cmd:move %s %s %s %s"
- idparam (or flagstr "") (or path "")
- (format "newname:%s" rename))))
-
-(defun mu4e~proc-index (path my-addresses cleanup lazy-check)
- "Update the message database for filesystem PATH, which should
-point to some maildir directory structure. MY-ADDRESSES is a list
-of 'my' email addresses (see `mu4e-user-mail-address-list')."
- (let ((path (mu4e~proc-escape path))
- (addrs (when my-addresses (mapconcat 'identity my-addresses ","))))
- (if addrs
- (mu4e~proc-send-command "cmd:index path:%s my-addresses:%s cleanup:%s lazy-check:%s"
- path addrs (if cleanup "true" : "false") (if lazy-check "true"))
- (mu4e~proc-send-command "cmd:index path:%s" path))))
-
-(defun mu4e~proc-add (path maildir)
- "Add the message at PATH to the database.
-With MAILDIR set to the maildir this message resides in,
-e.g. '/drafts'; if this works, we will receive (:info add :path
-<path> :docid <docid>) as well as (:update <msg-sexp>)."
- (mu4e~proc-send-command "cmd:add path:%s %s"
- (mu4e~proc-escape path)
- (if maildir
- (format "maildir:%s" (mu4e~proc-escape maildir))
- "")))
-
-(defun mu4e~proc-sent (path maildir)
- "Add the message at PATH to the database.
-With MAILDIR set to the maildir this message resides in,
-e.g. '/drafts'.
-
- if this works, we will receive (:info add :path <path> :docid
-<docid> :fcc <path>)."
- (mu4e~proc-send-command "cmd:sent path:%s maildir:%s"
- (mu4e~proc-escape path) (mu4e~proc-escape maildir)))
-
-
-(defun mu4e~proc-compose (type decrypt &optional docid)
- "Start composing a message of certain TYPE (a symbol, either
-`forward', `reply', `edit', `resend' or `new', based on an
-original message (ie, replying to, forwarding, editing,
-resending) with DOCID or nil for type `new'.
-
-The result will be delivered to the function registered as
-`mu4e-compose-func'."
- (unless (member type '(forward reply edit resend new))
- (mu4e-error "Unsupported compose-type %S" type))
- (unless (eq (null docid) (eq type 'new))
- (mu4e-error "`new' implies docid not-nil, and vice-versa"))
- (mu4e~proc-send-command
- "cmd:compose type:%s docid:%d extract-encrypted:%s use-agent:true"
- (symbol-name type) docid (if decrypt "true" "false")))
-
-(defun mu4e~proc-mkdir (path)
- "Create a new maildir-directory at filesystem PATH."
- (mu4e~proc-send-command "cmd:mkdir path:%s" (mu4e~proc-escape path)))
-
-(defun mu4e~proc-extract (action docid partidx decrypt &optional path what param)
- "Extract an attachment with index PARTIDX from message with DOCID
-and perform ACTION on it (as symbol, either `save', `open', `temp') which
-mean:
- * save: save the part to PARAM1 (a path) (non-optional for save)$
- * open: open the part with the default application registered for doing so
- * temp: save to a temporary file, then respond with
- (:temp <path> :what <what> :param <param>)."
- (let ((cmd
- (concat "cmd:extract "
- (case action
- (save
- (format "action:save docid:%d index:%d path:%s extract-encrypted:%s use-agent:true"
- docid partidx (mu4e~proc-escape path) (if decrypt "true" "false")))
- (open (format "action:open docid:%d index:%d extract-encrypted:%s use-agent:true"
- docid partidx (if decrypt "true" "false")))
- (temp
- (format "action:temp docid:%d index:%d what:%s%s extract-encrypted:%s use-agent:true"
- docid partidx what
- (if param
- (if (stringp param)
- (format " param:%s" (mu4e~proc-escape param))
- (format " param:%S" param)) "") (if decrypt "true" "false")))
- (otherwise (mu4e-error "Unsupported action %S" action))))
- ))
- (mu4e~proc-send-command "%s" cmd)))
-
-
-(defun mu4e~proc-ping ()
- "Sends a ping to the mu server, expecting a (:pong ...) in response."
- (mu4e~proc-send-command "cmd:ping"))
-
-(defun mu4e~proc-contacts (personal after)
- "Sends the contacts command to the mu server.
-A (:contacts (<list>)) is expected in response. If PERSONAL is
-non-nil, only get personal contacts, if AFTER is non-nil, get
-only contacts seen AFTER (the time_t value)."
- (mu4e~proc-send-command
- "cmd:contacts personal:%s after:%d"
- (if personal "true" "false")
- (or after 0)))
-
-(defun mu4e~proc-view (docid-or-msgid &optional images decrypt)
- "Get one particular message based on its DOCID-OR-MSGID.
-Optionally, if IMAGES is non-nil, backend will any images
-attached to the message, and return them as temp files.
-The result will be delivered to the function registered as
-`mu4e-view-func'."
- (mu4e~proc-send-command
- "cmd:view %s extract-images:%s extract-encrypted:%s use-agent:true"
- (mu4e~docid-msgid-param docid-or-msgid)
- (if images "true" "false")
- (if decrypt "true" "false")))
-
-(defun mu4e~proc-view-path (path &optional images decrypt)
- "View message at PATH (keyword argument).
-Optionally, if IMAGES is non-nil, backend will any images
-attached to the message, and return them as temp files. The
-result will be delivered to the function registered as
-`mu4e-view-func'."
- (mu4e~proc-send-command
- "cmd:view path:%s extract-images:%s extract-encrypted:%s use-agent:true"
- (mu4e~proc-escape path)
- (if images "true" "false")
- (if decrypt "true" "false")))
-
-
-(provide 'mu4e-proc)
-;; End of mu4e-proc.el
diff --git a/_spacemacs.d/local/mu4e/mu4e-speedbar.el b/_spacemacs.d/local/mu4e/mu4e-speedbar.el
deleted file mode 100644
index 09a4c49..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-speedbar.el
+++ /dev/null
@@ -1,125 +0,0 @@
-;;; mu4e-speedbar --- Speedbar support for mu4e
-
-;; Copyright (C) 2012-2016 Antono Vasiljev, Dirk-Jan C. Binnema
-;;
-;; Author: Antono Vasiljev <self@antono.info>
-;; Version: 0.1
-;; Keywords: file, tags, tools
-;;
-;; This file is not part of GNU Emacs.
-;;
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Speedbar provides a frame in which files, and locations in files
-;; are displayed. These functions provide mu4e specific support,
-;; showing maildir list in the side-bar.
-;;
-;; This file requires speedbar.
-
-;;; Code:
-
-(require 'speedbar)
-(require 'mu4e-vars)
-(require 'mu4e-headers)
-(require 'mu4e-utils)
-
-(defvar mu4e-main-speedbar-key-map nil
- "Keymap used when in mu4e display mode.")
-(defvar mu4e-headers-speedbar-key-map nil
- "Keymap used when in mu4e display mode.")
-(defvar mu4e-view-speedbar-key-map nil
- "Keymap used when in mu4e display mode.")
-
-(defvar mu4e-main-speedbar-menu-items nil
- "Additional menu-items to add to speedbar frame.")
-(defvar mu4e-headers-speedbar-menu-items nil
- "Additional menu-items to add to speedbar frame.")
-(defvar mu4e-view-speedbar-menu-items nil
- "Additional menu-items to add to speedbar frame.")
-
-
-(defun mu4e-speedbar-install-variables ()
- "Install those variables used by speedbar to enhance mu4e."
- (dolist (keymap
- '( mu4e-main-speedbar-key-map
- mu4e-headers-speedbar-key-map
- mu4e-view-speedbar-key-map))
- (unless keymap
- (setq keymap (speedbar-make-specialized-keymap))
- (define-key keymap "RET" 'speedbar-edit-line)
- (define-key keymap "e" 'speedbar-edit-line))))
-
-
-;; Make sure our special speedbar major mode is loaded
-(if (featurep 'speedbar)
- (mu4e-speedbar-install-variables)
- (add-hook 'speedbar-load-hook 'mu4e-speedbar-install-variables))
-
-(defun mu4e~speedbar-render-maildir-list ()
- "Insert the list of maildirs in the speedbar."
- (interactive)
- (mapcar (lambda (maildir-name)
- (speedbar-insert-button
- (concat " " maildir-name)
- 'mu4e-highlight-face
- 'highlight
- 'mu4e~speedbar-maildir
- maildir-name))
- (mu4e-get-maildirs)))
-
-(defun mu4e~speedbar-maildir (&optional text token ident)
- "Jump to maildir TOKEN. TEXT and INDENT are not used."
- (speedbar-with-attached-buffer
- (mu4e-headers-search (concat "\"maildir:" token "\"")
- current-prefix-arg)))
-
-(defun mu4e~speedbar-render-bookmark-list ()
- "Insert the list of bookmarks in the speedbar"
- (interactive)
- (mapcar (lambda (bookmark)
- (speedbar-insert-button
- (concat " " (mu4e-bookmark-name bookmark))
- 'mu4e-highlight-face
- 'highlight
- 'mu4e~speedbar-bookmark
- (mu4e-bookmark-query bookmark)))
- (mu4e-bookmarks)))
-
-(defun mu4e~speedbar-bookmark (&optional text token ident)
- "Run bookmarked query TOKEN. TEXT and INDENT are not used."
- (speedbar-with-attached-buffer
- (mu4e-headers-search token current-prefix-arg)))
-
-;;;###autoload
-(defun mu4e-speedbar-buttons (buffer)
- "Create buttons for any mu4e BUFFER."
- (interactive)
- (erase-buffer)
- (insert (propertize "* mu4e\n\n" 'face 'mu4e-title-face))
-
- (insert (propertize " Bookmarks\n" 'face 'mu4e-title-face))
- (mu4e~speedbar-render-bookmark-list)
- (insert "\n")
- (insert (propertize " Maildirs\n" 'face 'mu4e-title-face))
- (mu4e~speedbar-render-maildir-list))
-
-(defun mu4e-main-speedbar-buttons (buffer) (mu4e-speedbar-buttons buffer))
-(defun mu4e-headers-speedbar-buttons (buffer) (mu4e-speedbar-buttons buffer))
-(defun mu4e-view-speedbar-buttons (buffer) (mu4e-speedbar-buttons buffer))
-
-
-(provide 'mu4e-speedbar)
-;;; mu4e-speedbar.el ends here
diff --git a/_spacemacs.d/local/mu4e/mu4e-utils.el b/_spacemacs.d/local/mu4e/mu4e-utils.el
deleted file mode 100644
index f8110b5..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-utils.el
+++ /dev/null
@@ -1,1281 +0,0 @@
-;;; mu4e-utils.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-;; Copyright (C) 2013 Tibor Simko
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Utility functions used in the mu4e
-
-;;; Code:
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-(require 'cl)
-
-(eval-when-compile (require 'org nil 'noerror))
-
-(require 'mu4e-vars)
-(require 'mu4e-meta)
-(require 'mu4e-lists)
-(require 'doc-view)
-
-;; keep the byte-compiler happy
-(declare-function mu4e~proc-mkdir "mu4e-proc")
-(declare-function mu4e~proc-ping "mu4e-proc")
-(declare-function mu4e~proc-contacts "mu4e-proc")
-(declare-function mu4e~proc-kill "mu4e-proc")
-(declare-function mu4e~proc-index "mu4e-proc")
-(declare-function mu4e~proc-add "mu4e-proc")
-(declare-function mu4e~proc-mkdir "mu4e-proc")
-(declare-function mu4e~proc-running-p "mu4e-proc")
-
-(declare-function mu4e~context-autoswitch "mu4e-context")
-(declare-function mu4e-context-determine "mu4e-context")
-(declare-function mu4e-context-vars "mu4e-context")
-(declare-function show-all "org")
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; the following is taken from org.el; we copy it here since we don't want to
-;; depend on org-mode directly (it causes byte-compilation errors) TODO: a
-;; cleaner solution....
-(defconst mu4e~ts-regexp0
- (concat
- "\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)"
- "\\( +[^]+0-9>\r\n -]+\\)?\\( +\\([0-9]\\{1,2\\}\\):"
- "\\([0-9]\\{2\\}\\)\\)?\\)")
- "Regular expression matching time strings for analysis.
-This one does not require the space after the date, so it can be
-used on a string that terminates immediately after the date.")
-
-(defun mu4e-parse-time-string (s &optional nodefault)
- "Parse the standard Org-mode time string.
-This should be a lot faster than the normal `parse-time-string'.
-If time is not given, defaults to 0:00. However, with optional
-NODEFAULT, hour and minute fields will be nil if not given."
- (if (string-match mu4e~ts-regexp0 s)
- (list 0
- (if (or (match-beginning 8) (not nodefault))
- (string-to-number (or (match-string 8 s) "0")))
- (if (or (match-beginning 7) (not nodefault))
- (string-to-number (or (match-string 7 s) "0")))
- (string-to-number (match-string 4 s))
- (string-to-number (match-string 3 s))
- (string-to-number (match-string 2 s))
- nil nil nil)
- (mu4e-error "Not a standard mu4e time string: %s" s)))
-
-
-(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')."
- (when (and addr mu4e-user-mail-address-list
- (find addr mu4e-user-mail-address-list :test 'string=))
- t))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defmacro with~mu4e-context-vars (context &rest body)
- "Evaluate BODY, with variables let-bound for CONTEXT (if any).
-`funcall'."
- (declare (indent 2))
- `(let* ((vars (and ,context (mu4e-context-vars ,context))))
- (progv ;; XXX: perhaps use eval's lexical environment instead of progv?
- (mapcar (lambda(cell) (car cell)) vars)
- (mapcar (lambda(cell) (cdr cell)) vars)
- (eval ,@body))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; the standard folders can be functions too
-(defun mu4e~get-folder (foldervar msg)
- "Within the mu-context of MSG, get message folder FOLDERVAR.
-If FOLDER is a string, return it, if it is a function, evaluate
-this function with MSG as parameter (which may be `nil'), and
-return the result."
- (unless (member foldervar
- '(mu4e-sent-folder mu4e-drafts-folder
- mu4e-trash-folder mu4e-refile-folder))
- (mu4e-error "Folder must be one of mu4e-(sent|drafts|trash|refile)-folder"))
- ;; get the value with the vars for the relevants context let-bound
- (with~mu4e-context-vars (mu4e-context-determine msg nil)
- (let* ((folder (symbol-value foldervar))
- (val
- (cond
- ((stringp folder) folder)
- ((functionp folder) (funcall folder msg))
- (t (mu4e-error "unsupported type for %S" folder)))))
- (or val (mu4e-error "%S evaluates to nil" foldervar)))))
-
-(defun mu4e-get-drafts-folder (&optional msg)
- "Get the sent folder. See `mu4e-drafts-folder'."
- (mu4e~get-folder 'mu4e-drafts-folder msg))
-
-(defun mu4e-get-refile-folder (&optional msg)
- "Get the folder for refiling. See `mu4e-refile-folder'."
- (mu4e~get-folder 'mu4e-refile-folder msg))
-
-(defun mu4e-get-sent-folder (&optional msg)
- "Get the sent folder. See `mu4e-sent-folder'."
- (mu4e~get-folder 'mu4e-sent-folder msg))
-
-(defun mu4e-get-trash-folder (&optional msg)
- "Get the sent folder. See `mu4e-trash-folder'."
- (mu4e~get-folder 'mu4e-trash-folder msg))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e-remove-file-later (filename)
- "Remove FILENAME in a few seconds."
- (lexical-let ((filename filename))
- (run-at-time "10 sec" nil
- (lambda () (ignore-errors (delete-file filename))))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e-make-temp-file (ext)
- "Create a temporary file with extension EXT. The file will
-self-destruct in a few seconds, enough to open it in another
-program."
- (let ((tmpfile (make-temp-file "mu4e-" nil (concat "." ext))))
- (mu4e-remove-file-later tmpfile)
- tmpfile))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; mu4e-attachment-dir is either a string or a function that takes a filename
-;; and the mime-type as argument, either (or both) which can be nil
-(defun mu4e~get-attachment-dir (&optional fname mimetype)
- "Get the directory for saving attachments from
-`mu4e-attachment-dir' (which can be either a string or a function,
-see its docstring)."
- (let
- ((dir
- (cond
- ((stringp mu4e-attachment-dir)
- mu4e-attachment-dir)
- ((functionp mu4e-attachment-dir)
- (funcall mu4e-attachment-dir fname mimetype))
- (t
- (mu4e-error "unsupported type for mu4e-attachment-dir" )))))
- (if dir
- (expand-file-name dir)
- (mu4e-error (mu4e-error "mu4e-attachment-dir evaluates to nil")))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e~guess-maildir (path)
- "Guess the maildir for some path, or nil if cannot find it."
- (let ((idx (string-match mu4e-maildir path)))
- (when (and idx (zerop idx))
- (replace-regexp-in-string
- mu4e-maildir
- ""
- (expand-file-name
- (concat path "/../.."))))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e-create-maildir-maybe (dir)
- "Offer to create maildir DIR if it does not exist yet.
-Return t if the dir already existed, or an attempt has been made to
-create it -- we cannot be sure creation succeeded here, since this
-is done asynchronously. Otherwise, return nil. NOte, DIR has to be
-an absolute path."
- (if (and (file-exists-p dir) (not (file-directory-p dir)))
- (mu4e-error "%s exists, but is not a directory." dir))
- (cond
- ((file-directory-p dir) t)
- ((yes-or-no-p (mu4e-format "%s does not exist yet. Create now?" dir))
- (mu4e~proc-mkdir dir) t)
- (t nil)))
-
-(defun mu4e-format (frm &rest args)
- "Create [mu4e]-prefixed string based on format FRM and ARGS."
- (concat
- "[" (propertize "mu4e" 'face 'mu4e-title-face) "] "
- (apply 'format frm args)))
-
-(defun mu4e-message (frm &rest args)
- "Like `message', but prefixed with mu4e.
-If we're waiting for user-input or if there's some message in the
-echo area, don't show anything."
- (unless (or (active-minibuffer-window))
- (message "%s" (apply 'mu4e-format frm args))))
-
-(defun mu4e-index-message (frm &rest args)
- "Like `mu4e-message', but specifically for
-index-messages. Doesn't display anything if
-`mu4e-hide-index-messages' is non-nil. "
- (unless mu4e-hide-index-messages
- (apply 'mu4e-message frm args)))
-
-(defun mu4e-error (frm &rest args)
- "Create [mu4e]-prefixed error based on format FRM and ARGS.
-Does a local-exit and does not return, and raises a
-debuggable (backtrace) error."
- (mu4e-log 'error (apply 'mu4e-format frm args))
- (error "%s" (apply 'mu4e-format frm args)))
-
-;; the user-error function is only available in emacs-trunk
-(unless (fboundp 'user-error)
- (defalias 'user-error 'error))
-
-(defun mu4e-warn (frm &rest args)
- "Create [mu4e]-prefixed warning based on format FRM and ARGS.
-Does a local-exit and does not return. In emacs versions below
-24.2, the functions is the same as `mu4e-error'."
- (mu4e-log 'error (apply 'mu4e-format frm args))
- (user-error "%s" (apply 'mu4e-format frm args)))
-
-(defun mu4e~read-char-choice (prompt choices)
- "Read and return one of CHOICES, prompting for PROMPT.
-Any input that is not one of CHOICES is ignored. This mu4e's
-version of `read-char-choice', that becomes case-insentive after
-trying an exact match."
- (let ((choice) (chosen) (inhibit-quit nil))
- (while (not chosen)
- (message nil);; this seems needed...
- (setq choice (read-char-exclusive prompt))
- (setq chosen (or (member choice choices)
- (member (downcase choice) choices)
- (member (upcase choice) choices))))
- (car chosen)))
-
-(defun mu4e-read-option (prompt options)
- "Ask user for an option from a list on the input area.
-PROMPT describes a multiple-choice question to the user.
-OPTIONS describe the options, and is a list of cells describing
-particular options. Cells have the following structure:
-
- (OPTIONSTRING . RESULT)
-
-where OPTIONSTRING is a non-empty string describing the
-option. The first character of OPTIONSTRING is used as the
-shortcut, and obviously all shortcuts must be different, so you
-can prefix the string with an uniquifying character.
-
-The options are provided as a list for the user to choose from;
-user can then choose by typing CHAR. Example:
- (mu4e-read-option \"Choose an animal: \"
- '((\"Monkey\" . monkey) (\"Gnu\" . gnu) (\"xMoose\" . moose)))
-
-User now will be presented with a list: \"Choose an animal:
- [M]onkey, [G]nu, [x]Moose\".
-
-Function will return the cdr of the list element."
- (let* ((prompt (mu4e-format "%s" prompt))
- (chosen)
- (optionsstr
- (mapconcat
- (lambda (option)
- ;; try to detect old-style options, and warn
- (when (characterp (car-safe (cdr-safe option)))
- (mu4e-error
- (concat "Please use the new format for options/actions; "
- "see the manual")))
- (let* ((kar (substring (car option) 0 1))
- (val (cdr option)))
- (concat
- "[" (propertize kar 'face 'mu4e-highlight-face) "]"
- (substring (car option) 1))))
- options ", "))
- (response
- (mu4e~read-char-choice
- (concat prompt optionsstr
- " [" (propertize "C-g" 'face 'mu4e-highlight-face)
- " to cancel]")
- ;; the allowable chars
- (map 'list (lambda(elm) (string-to-char (car elm))) options)))
- (chosen
- (find-if
- (lambda (option) (eq response (string-to-char (car option))))
- options)))
- (if chosen
- (cdr chosen)
- (mu4e-warn "Unknown shortcut '%c'" response))))
-
-(defun mu4e~get-maildirs-1 (path mdir)
- "Get maildirs under path, recursively, as a list of relative paths."
- (let ((dirs)
- (dentries
- (ignore-errors
- (directory-files-and-attributes
- (concat path mdir) nil
- "^[^.]\\|\\.[^.][^.]" t))))
- (dolist (dentry dentries)
- (when (and (booleanp (cadr dentry)) (cadr dentry))
- (if (file-accessible-directory-p
- (concat mu4e-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
- (concat mdir (car dentry) "/")))))))
- dirs))
-
-(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
-cache the next time `mu4e-get-maildirs' gets called.")
-
-(defvar mu4e-maildir-list nil
- "Cached list of maildirs.")
-
-(defun mu4e-get-maildirs ()
- "Get maildirs under `mu4e-maildir', recursively, as a list of
-relative paths (ie., /archive, /sent etc.). Most of the work is
-done in `mu4e-get-maildirs-1'. Note, these results are /cached/, so
-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 "/"))
- (lambda (s1 s2) (string< (downcase s1) (downcase s2))))))
- mu4e-maildir-list)
-
-(defun mu4e-ask-maildir (prompt)
- "Ask the user for a shortcut (using PROMPT) as defined in
-`mu4e-maildir-shortcuts', then return the corresponding folder
-name. If the special shortcut 'o' (for _o_ther) is used, or if
-`mu4e-maildir-shortcuts' is not defined, let user choose from all
-maildirs under `mu4e-maildir'."
- (let ((prompt (mu4e-format "%s" prompt)))
- (if (not mu4e-maildir-shortcuts)
- (funcall mu4e-completing-read-function prompt (mu4e-get-maildirs))
- (let* ((mlist (append mu4e-maildir-shortcuts '(("ther" . ?o))))
- (fnames
- (mapconcat
- (lambda (item)
- (concat
- "["
- (propertize (make-string 1 (cdr item))
- 'face 'mu4e-highlight-face)
- "]"
- (car item)))
- mlist ", "))
- (kar (read-char (concat prompt fnames))))
- (if (member kar '(?/ ?o)) ;; user chose 'other'?
- (funcall mu4e-completing-read-function prompt
- (mu4e-get-maildirs) nil nil "/")
- (or (car-safe
- (find-if (lambda (item) (= kar (cdr item)))
- mu4e-maildir-shortcuts))
- (mu4e-warn "Unknown shortcut '%c'" kar)))))))
-
-
-(defun mu4e-ask-maildir-check-exists (prompt)
- "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)))
- (unless (file-directory-p fullpath)
- (and (yes-or-no-p
- (mu4e-format "%s does not exist. Create now?" fullpath))
- (mu4e~proc-mkdir fullpath)))
- mdir))
-
-
-(defstruct mu4e-bookmark
- "A mu4e bookmarl object with the following members:
-- `name': the user-visible name of the bookmark
-- `key': a single key to search for this bookmark
-- `query': the query for this bookmark. Either a literal string or a function
- that evaluates to a string."
- name ;; name/description of the bookmark
- query ;; a query (a string or a function evaluation to string)
- key ;; key to activate the bookmark
- )
-
-(defun mu4e-bookmarks ()
- "Get `mu4e-bookmarks' in the (new) format, converting from the old
-format if needed."
- (map 'list
- (lambda (item)
- (if (mu4e-bookmark-p item)
- item ;; already in the right format
- (if (and (listp item) (= (length item) 3))
- (make-mu4e-bookmark
- :name (nth 1 item)
- :query (nth 0 item)
- :key (nth 2 item))
- (mu4e-error "Invalid bookmark in mu4e-bookmarks"))))
- mu4e-bookmarks))
-
-
-(defun mu4e-ask-bookmark (prompt &optional kar)
- "Ask the user for a bookmark (using PROMPT) as defined in
-`mu4e-bookmarks', then return the corresponding query."
- (unless (mu4e-bookmarks) (mu4e-error "No bookmarks defined"))
- (let* ((prompt (mu4e-format "%s" prompt))
- (bmarks
- (mapconcat
- (lambda (bm)
- (concat
- "[" (propertize (make-string 1 (mu4e-bookmark-key bm))
- 'face 'mu4e-highlight-face)
- "]"
- (mu4e-bookmark-name bm))) (mu4e-bookmarks) ", "))
- (kar (read-char (concat prompt bmarks))))
- (mu4e-get-bookmark-query kar)))
-
-(defun mu4e-get-bookmark-query (kar)
- "Get the corresponding bookmarked query for shortcut character
-KAR, or raise an error if none is found."
- (let* ((chosen-bm
- (or (find-if
- (lambda (bm)
- (= kar (mu4e-bookmark-key bm)))
- (mu4e-bookmarks))
- (mu4e-warn "Unknown shortcut '%c'" kar)))
- (expr (mu4e-bookmark-query chosen-bm))
- (query (eval expr)))
- (if (stringp query)
- query
- (mu4e-warn "Expression must evaluate to query string ('%S')" expr))))
-
-
-(defun mu4e-bookmark-define (query name key)
- "Define a bookmark for QUERY with name NAME and
-shortcut-character KEY in the list of `mu4e-bookmarks'. This
-replaces any existing bookmark with KEY."
- (setq mu4e-bookmarks
- (remove-if
- (lambda (bm)
- (= (mu4e-bookmark-key bm) key))
- (mu4e-bookmarks)))
- (add-to-list 'mu4e-bookmarks
- (make-mu4e-bookmark
- :name name
- :query query
- :key key) t))
-
-
-;;; converting flags->string and vice-versa ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e~flags-to-string-raw (flags)
- "Convert a list of flags into a string as seen in Maildir
-message files; flags are symbols draft, flagged, new, passed,
-replied, seen, trashed and the string is the concatenation of the
-uppercased first letters of these flags, as per [1]. Other flags
-than the ones listed here are ignored.
-Also see `mu4e-flags-to-string'.
-\[1\]: http://cr.yp.to/proto/maildir.html"
- (when flags
- (let ((kar (case (car flags)
- ('draft ?D)
- ('flagged ?F)
- ('new ?N)
- ('passed ?P)
- ('replied ?R)
- ('seen ?S)
- ('trashed ?T)
- ('attach ?a)
- ('encrypted ?x)
- ('signed ?s)
- ('unread ?u))))
- (concat (and kar (string kar))
- (mu4e~flags-to-string-raw (cdr flags))))))
-
-(defun mu4e-flags-to-string (flags)
- "Remove duplicates and sort the output of `mu4e~flags-to-string-raw'."
- (concat
- (sort (remove-duplicates
- (append (mu4e~flags-to-string-raw flags) nil)) '>)))
-
-(defun mu4e~string-to-flags-1 (str)
- "Convert a string with message flags as seen in Maildir
-messages into a list of flags in; flags are symbols draft,
-flagged, new, passed, replied, seen, trashed and the string is
-the concatenation of the uppercased first letters of these flags,
-as per [1]. Other letters than the ones listed here are ignored.
-Also see `mu4e-flags-to-string'.
-\[1\]: http://cr.yp.to/proto/maildir.html."
- (when (/= 0 (length str))
- (let ((flag
- (case (string-to-char str)
- (?D 'draft)
- (?F 'flagged)
- (?P 'passed)
- (?R 'replied)
- (?S 'seen)
- (?T 'trashed))))
- (append (when flag (list flag))
- (mu4e~string-to-flags-1 (substring str 1))))))
-
-(defun mu4e-string-to-flags (str)
- "Convert a string with message flags as seen in Maildir messages
-into a list of flags in; flags are symbols draft, flagged, new,
-passed, replied, seen, trashed and the string is the concatenation
-of the uppercased first letters of these flags, as per [1]. Other
-letters than the ones listed here are ignored. Also see
-`mu4e-flags-to-string'. \[1\]:
-http://cr.yp.to/proto/maildir.html "
- ;; "Remove duplicates from the output of `mu4e~string-to-flags-1'"
- (remove-duplicates (mu4e~string-to-flags-1 str)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defun mu4e-display-size (size)
- "Get a string representation of SIZE (in bytes)."
- (cond
- ((>= size 1000000) (format "%2.1fM" (/ size 1000000.0)))
- ((and (>= size 1000) (< size 1000000))
- (format "%2.1fK" (/ size 1000.0)))
- ((< size 1000) (format "%d" size))
- (t (propertize "?" 'face 'mu4e-system-face))))
-
-
-(defun mu4e-display-manual ()
- "Display the mu4e manual page for the current mode.
-Or go to the top level if there is none."
- (interactive)
- (info (case major-mode
- ('mu4e-main-mode "(mu4e)Main view")
- ('mu4e-headers-mode "(mu4e)Headers view")
- ('mu4e-view-mode "(mu4e)Message view")
- (t "mu4e"))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e-last-query ()
- "Get the most recent query or nil if there is none."
- (when (buffer-live-p mu4e~headers-buffer)
- (with-current-buffer mu4e~headers-buffer
- mu4e~headers-last-query)))
-
-(defun mu4e-select-other-view ()
- "When the headers view is selected, select the message view (if
-that has a live window), and vice versa."
- (interactive)
- (let* ((other-buf
- (cond
- ((eq major-mode 'mu4e-headers-mode)
- mu4e~view-buffer)
- ((eq major-mode 'mu4e-view-mode)
- mu4e~headers-buffer)))
- (other-win (and other-buf (get-buffer-window other-buf))))
- (if (window-live-p other-win)
- (select-window other-win)
- (mu4e-message "No window to switch to"))))
-
-
-(defconst mu4e-output-buffer-name "*mu4e-output*"
- "*internal* Name of the mu4e output buffer.")
-
-(defun mu4e-process-file-through-pipe (path pipecmd)
- "Process file at PATH through a pipe with PIPECMD."
- (let ((buf (get-buffer-create mu4e-output-buffer-name)))
- (with-current-buffer buf
- (let ((inhibit-read-only t))
- (erase-buffer)
- (call-process-shell-command pipecmd path t t)
- (view-mode)))
- (switch-to-buffer buf)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defvar mu4e~lists-hash nil
- "Hashtable of mailing-list-id => shortname, based on
- `mu4e~mailing-lists' and `mu4e-user-mailing-lists'.")
-
-(defun mu4e-get-mailing-list-shortname (list-id)
- "Get the shortname for a mailing-list with list-id LIST-ID. based
-on `mu4e~mailing-lists', `mu4e-user-mailing-lists', and
-`mu4e-mailing-list-patterns'."
- (unless mu4e~lists-hash
- (setq mu4e~lists-hash (make-hash-table :test 'equal))
- (dolist (cell mu4e~mailing-lists)
- (puthash (car cell) (cdr cell) mu4e~lists-hash))
- (dolist (cell mu4e-user-mailing-lists)
- (puthash (car cell) (cdr cell) mu4e~lists-hash)))
- (or
- (gethash list-id mu4e~lists-hash)
- (and (boundp 'mu4e-mailing-list-patterns)
- (cl-member-if
- (lambda (pattern)
- (string-match pattern list-id))
- mu4e-mailing-list-patterns)
- (match-string 1 list-id))
- ;; if it's not in the db, take the part until the first dot if there is one;
- ;; otherwise just return the whole thing
- (if (string-match "\\([^.]*\\)\\." list-id)
- (match-string 1 list-id)
- list-id)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defvar mu4e-index-updated-hook nil
- "Hook run when the indexing process had one or more updated messages.
-This can be used as a simple way to invoke some action when new
-messages appear, but note that an update in the index does not
-necessarily mean a new message.")
-
-;; some handler functions for server messages
-;;
-(defun mu4e-info-handler (info)
- "Handler function for (:info ...) sexps received from the server
-process."
- (let ((type (plist-get info :info)))
- (cond
- ((eq type 'add) t) ;; do nothing
- ((eq type 'index)
- (if (eq (plist-get info :status) 'running)
- (mu4e-index-message "Indexing... processed %d, updated %d"
- (plist-get info :processed) (plist-get info :updated))
- (progn
- (mu4e-index-message
- "Indexing completed; processed %d, updated %d, cleaned-up %d"
- (plist-get info :processed) (plist-get info :updated)
- (plist-get info :cleaned-up))
- (unless (zerop (plist-get info :updated))
- (run-hooks 'mu4e-index-updated-hook)))))
- ((plist-get info :message)
- (mu4e-index-message "%s" (plist-get info :message))))))
-
-(defun mu4e-error-handler (errcode errmsg)
- "Handler function for showing an error."
- ;; don't use mu4e-error here; it's running in the process filter context
- (case errcode
- (4 (user-error "No matches for this search query."))
- (t (error "Error %d: %s" errcode errmsg))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;; RFC2822 handling of phrases in mail-addresses
-;;; The optional display-name contains a phrase, it sits before the angle-addr
-;;; as specified in RFC2822 for email-addresses in header fields.
-;;; contributed by jhelberg
-
-(defun mu4e~rfc822-phrase-type (ph)
- "Return either atom, quoted-string, a corner-case or nil. This
- 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
- 'rfc822-containing-quote)) ; starts with quote, but doesn't end with one
- ((string-match-p "[\"]" ph) 'rfc822-containing-quote)
- ((string-match-p "[\000-\037()\*<>@,;:\\\.]+" ph) nil)
- (t 'rfc822-atom)))
-
-(defun mu4e~rfc822-quoteit (ph)
- "Quote RFC822 phrase only if necessary.
- Atoms and quoted strings don't need quotes. The rest do. In
- case a phrase contains a quote, it will be escaped."
- (let ((type (mu4e~rfc822-phrase-type ph)))
- (cond
- ((eq type 'rfc822-atom) ph)
- ((eq type 'rfc822-quoted-string) ph)
- ((eq type 'rfc822-containing-quote)
- (format "\"%s\""
- (replace-regexp-in-string "\"" "\\\\\"" ph)))
- (t (format "\"%s\"" ph)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defsubst mu4e~process-contact (contact)
- "Process CONTACT, and either return nil when it should not be included,
-or (rfc822-string . CONTACT) otherwise."
- (when mu4e-contact-rewrite-function
- (setq contact (funcall mu4e-contact-rewrite-function contact)))
- (when contact
- (let ((name (plist-get contact :name))
- (mail (plist-get contact :mail))
- (ignore-rx (or mu4e-compose-complete-ignore-address-regexp "$^")))
- (when (and mail (not (string-match ignore-rx mail)))
- (cons
- (if name (format "%s <%s>" (mu4e~rfc822-quoteit name) mail) mail)
- contact)))))
-
-
-(defun mu4e~sort-contacts (contacts)
- "Destructively sort contacts (only for cycling) in order of
- 'mostly likely contact'.t See the code for the detail"
- (let* ((now (+ (float-time) 3600)) ;; allow for clock diffs
- (recent (- (float-time) (* 15 24 3600))))
- (sort* contacts
- (lambda (c1 c2)
- (let* ( (c1 (cdr c1)) (c2 (cdr c2))
- (personal1 (plist-get c1 :personal))
- (personal2 (plist-get c2 :personal))
- ;; note: freq, tstamp can only be missing if the rewrite
- ;; function removed them. If the rewrite function changed the
- ;; contact somehow, we guess it's important.
- (freq1 (or (plist-get c1 :freq) 500))
- (freq2 (or (plist-get c2 :freq) 500))
- (tstamp1 (or (plist-get c1 :tstamp) now))
- (tstamp2 (or (plist-get c2 :tstamp) now)))
- ;; only one is personal? if so, that one comes first
- (if (not (equal personal1 personal2))
- (if personal1 t nil)
- ;; only one is recent? that one comes first
- (if (not (equal (> tstamp1 recent) (> tstamp2 recent)))
- (> tstamp1 tstamp2)
- ;; otherwise, use the frequency
- (> freq1 freq2))))))))
-
-(defun mu4e~sort-contacts-for-completion (contacts)
- "Takes CONTACTS, which is a list of RFC-822 addresses, and sort them based
-on the ranking in `mu4e~contacts.'"
- (sort* contacts
- (lambda (c1 c2)
- (let ((rank1 (gethash c1 mu4e~contacts))
- (rank2 (gethash c2 mu4e~contacts)))
- (< rank1 rank2)))))
-
-;; start and stopping
-(defun mu4e~fill-contacts (contact-data)
- "We receive a list of contacts, which each contact of the form
- (:me NAME :mail EMAIL :tstamp TIMESTAMP :freq FREQUENCY)
-and fill the hash `mu4e~contacts-for-completion' with it, with
-each contact mapped to an integer for their ranking.
-
-This is used by the completion function in mu4e-compose."
- (let ((contacts) (rank 0))
- (dolist (contact contact-data)
- (let ((contact-maybe (mu4e~process-contact contact)))
- ;; note, this gives cells (rfc822-address . contact)
- (when contact-maybe (push contact-maybe contacts))))
- (setq contacts (mu4e~sort-contacts contacts))
- ;; now, we have our nicely sorted list, map them to a list
- ;; of increasing integers. We use that map in the composer
- ;; to sort them there. It would have been so much easier if emacs
- ;; allowed us to use the sorted-list as-is, but no such luck.
- (setq mu4e~contacts (make-hash-table :test 'equal :weakness nil
- :size (length contacts)))
- (dolist (contact contacts)
- (puthash (car contact) rank mu4e~contacts)
- (incf rank))
- (mu4e-index-message "Contacts received: %d"
- (hash-table-count mu4e~contacts))))
-
-(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"))
- (when mu4e~server-props
- (let ((version (plist-get mu4e~server-props :version)))
- (unless (string= version mu4e-mu-version)
- (mu4e-error "mu server has version %s, but we need %s"
- 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)))
- (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."
- (mu4e~proc-running-p))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; starting / getting mail / updating the index
-;;
-;;
-(defvar mu4e~update-timer nil
- "The mu4e update timer.")
-(defconst mu4e~update-name "*mu4e-update*"
- "Name of the process and buffer to update mail.")
-(defconst mu4e~update-buffer-height 8
- "Height of the mu4e message retrieval/update buffer.")
-
-(defvar mu4e~get-mail-ask-password "mu4e get-mail: Enter password: "
- "Query string for `mu4e-get-mail-command' password.")
-(defvar mu4e~get-mail-password-regexp "^Remote: Enter password: $"
- "Regexp to match a password query in the `mu4e-get-mail-command' output.")
-
-(defun mu4e~request-contacts ()
- "If `mu4e-compose-complete-addresses' is non-nil, get/update the
-list of contacts we use for autocompletion; otherwise, do nothing."
- (when mu4e-compose-complete-addresses
- (setq mu4e-contacts-func 'mu4e~fill-contacts)
- (mu4e~proc-contacts
- mu4e-compose-complete-only-personal
- (when mu4e-compose-complete-only-after
- (float-time
- (apply 'encode-time
- (mu4e-parse-time-string mu4e-compose-complete-only-after)))))))
-
-(defun mu4e~start (&optional func)
- "If `mu4e-contexts' have been defined, but we don't have a
-context yet, switch to the matching one, or none matches, the
-first.
-If mu4e is already running, execute function FUNC (if non-nil).
-Otherwise, check various requirements, then start mu4e. When
-successful, call FUNC (if non-nil) afterwards."
- ;; if we're already running, simply go to the main view
- (if (mu4e-running-p) ;; already running?
- (when func (funcall func)) ;; yes! run func if defined
- (progn
- ;; 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)
- (lexical-let ((func func))
- (mu4e~check-requirements)
- ;; set up the 'pong' handler func
- (setq mu4e-pong-func
- (lambda (props)
- (setq mu4e~server-props props) ;; save props from the server
- (let ((version (plist-get props :version))
- (doccount (plist-get props :doccount)))
- (mu4e~check-requirements)
- (when func (funcall func))
- (when (and mu4e-update-interval (null mu4e~update-timer))
- (setq mu4e~update-timer
- (run-at-time
- 0 mu4e-update-interval
- (lambda () (mu4e-update-mail-and-index
- mu4e-index-update-in-background)))))
- (mu4e-message "Started mu4e with %d message%s in store"
- doccount (if (= doccount 1) "" "s"))))))
- ;; wake up server
- (mu4e~proc-ping)
- ;; maybe request the list of contacts, automatically refresh after
- ;; reindexing
- (mu4e~request-contacts)
- (add-hook 'mu4e-index-updated-hook 'mu4e~request-contacts))))
-
-(defun mu4e-clear-caches ()
- "Clear any cached resources."
- (setq
- mu4e-maildir-list nil
- mu4e~contacts nil))
-
-(defun mu4e~stop ()
- "Stop the mu4e session."
- (when mu4e~update-timer
- (cancel-timer mu4e~update-timer)
- (setq mu4e~update-timer nil))
- (mu4e-clear-caches)
- (mu4e~proc-kill)
- ;; kill all main/view/headers buffer
- (mapcar
- (lambda (buf)
- (with-current-buffer buf
- (when (member major-mode
- '(mu4e-headers-mode mu4e-view-mode mu4e-main-mode))
- (kill-buffer))))
- (buffer-list)))
-
-
-
-(defvar mu4e~progress-reporter nil
- "Internal, the progress reporter object.")
-
-(defun mu4e~get-mail-process-filter (proc msg)
- "Filter the output of `mu4e-get-mail-command'.
-Currently the filter only checks if the command asks for a password
-by matching the output against `mu4e~get-mail-password-regexp'.
-The messages are inserted into the process buffer.
-
-Also scrolls to the final line, and update the progress throbber."
- (when mu4e~progress-reporter
- (progress-reporter-update mu4e~progress-reporter))
-
- (when (string-match mu4e~get-mail-password-regexp msg)
- (if (process-get proc 'x-interactive)
- (process-send-string proc
- (concat (read-passwd mu4e~get-mail-ask-password)
- "\n"))
- ;; TODO kill process?
- (mu4e-error "Unrecognized password request")))
- (when (process-buffer proc)
- (let ((inhibit-read-only t)
- (procwin (get-buffer-window (process-buffer proc))))
- ;; Insert at end of buffer. Leave point alone.
- (with-current-buffer (process-buffer proc)
- (goto-char (point-max))
- (if (string-match ".*\r\\(.*\\)" msg)
- (progn
- (kill-line 0)
- (insert (match-string 1 msg)))
- (insert msg)))
- ;; Auto-scroll unless user is interacting with the window.
- (when (and (window-live-p procwin)
- (not (eq (selected-window) procwin)))
- (with-selected-window procwin
- (goto-char (point-max)))))))
-
-(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))
-
-(defvar mu4e~update-buffer nil
- "Internal, store the buffer of the update process when
- updating.")
-
-(define-derived-mode mu4e~update-mail-mode special-mode "mu4e:update"
- "Major mode used for retrieving new e-mail messages in `mu4e'.")
-
-(define-key mu4e~update-mail-mode-map (kbd "q") 'mu4e-interrupt-update-mail)
-
-(defun mu4e~temp-window (buf height)
- "Create a temporary window with HEIGHT at the bottom of the
-frame to display buffer BUF."
- (let ((win
- (split-window
- (frame-root-window)
- (- (window-height (frame-root-window)) height))))
- (set-window-buffer win buf)
- (set-window-dedicated-p win t)
- win))
-
-(defun mu4e~update-sentinel-func (proc msg)
- "Sentinel function for the update process."
- (when mu4e~progress-reporter
- (progress-reporter-done mu4e~progress-reporter)
- (setq mu4e~progress-reporter nil))
- (let* ((status (process-status proc))
- (code (process-exit-status proc))
- (maybe-error (or (not (eq status 'exit)) (/= code 0)))
- (buf (and (buffer-live-p mu4e~update-buffer) mu4e~update-buffer))
- (win (and buf (get-buffer-window buf))))
- (message nil)
- (if maybe-error
- (progn
- (when mu4e-index-update-error-warning
- (mu4e-message "Update process returned with non-zero exit code")
- (sit-for 5))
- (when mu4e-index-update-error-continue
- (mu4e-update-index)))
- (mu4e-update-index))
- (if (window-live-p win)
- (with-selected-window win (kill-buffer-and-window))
- (when (buffer-live-p buf) (kill-buffer buf)))))
-
-;; complicated function, as it:
-;; - needs to check for errors
-;; - (optionally) pop-up a window
-;; - (optionally) check password requests
-(defun mu4e~update-mail-and-index-real (run-in-background)
- "Get a new mail by running `mu4e-get-mail-command'. If
-RUN-IN-BACKGROUND is non-nil (or called with prefix-argument),
-run in the background; otherwise, pop up a window."
- (let* ((process-connection-type t)
- (proc (start-process-shell-command
- "mu4e-update" " *mu4e-update*"
- mu4e-get-mail-command))
- (buf (process-buffer proc))
- (win (or run-in-background
- (mu4e~temp-window buf mu4e~update-buffer-height))))
- (setq mu4e~update-buffer buf)
- (when (window-live-p win)
- (with-selected-window win
- ;; ;;(switch-to-buffer buf)
- ;; (set-window-dedicated-p win t)
- (erase-buffer)
- (insert "\n") ;; FIXME -- needed so output start
- (mu4e~update-mail-mode)))
- (setq mu4e~progress-reporter
- (unless mu4e-hide-index-messages
- (make-progress-reporter
- (mu4e-format "Retrieving mail..."))))
- (set-process-sentinel proc 'mu4e~update-sentinel-func)
- ;; if we're running in the foreground, handle password requests
- (unless run-in-background
- (process-put proc 'x-interactive (not run-in-background))
- (set-process-filter proc 'mu4e~get-mail-process-filter))))
-
-(defun mu4e-update-mail-and-index (run-in-background)
- "Get a new mail by running `mu4e-get-mail-command'. If
-run-in-background is non-nil (or called with prefix-argument), run
-in the background; otherwise, pop up a window."
- (interactive "P")
- (unless mu4e-get-mail-command
- (mu4e-error "`mu4e-get-mail-command' is not defined"))
- (if (and (buffer-live-p mu4e~update-buffer)
- (process-live-p (get-buffer-process mu4e~update-buffer)))
- (mu4e-message "Update process is already running")
- (progn
- (run-hooks 'mu4e-update-pre-hook)
- (mu4e~update-mail-and-index-real run-in-background))))
-
-(defun mu4e-interrupt-update-mail ()
- "Stop the update process by sending SIGINT to it."
- (interactive)
- (let* ((proc (and (buffer-live-p mu4e~update-buffer)
- (get-buffer-process mu4e~update-buffer))))
- (when (process-live-p proc)
- (interrupt-process proc t))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; logging / debugging
-(defvar mu4e~log-max-lines 1200
- "*internal* Last <n> number of lines to keep around in the buffer.")
-(defconst mu4e~log-buffer-name "*mu4e-log*"
- "*internal* Name of the logging buffer.")
-
-(defun mu4e-log (type frm &rest args)
- "Write a message of TYPE with format-string FRM and ARGS in
-*mu4e-log* buffer, if the variable mu4e-debug is non-nil. Type is
-either 'to-server, 'from-server or 'misc. This function is meant for debugging."
- (when mu4e-debug
- (with-current-buffer (get-buffer-create mu4e~log-buffer-name)
- (view-mode)
- (setq buffer-undo-list t)
- (let* ((inhibit-read-only t)
- (tstamp (propertize (format-time-string "%Y-%m-%d %T"
- (current-time))
- 'face 'font-lock-string-face))
- (msg-face
- (case type
- (from-server 'font-lock-type-face)
- (to-server 'font-lock-function-name-face)
- (misc 'font-lock-variable-name-face)
- (error 'font-lock-warning-face)
- (otherwise (mu4e-error "Unsupported log type"))))
- (msg (propertize (apply 'format frm args) 'face msg-face)))
- (goto-char (point-max))
- (insert tstamp
- (case type
- (from-server " <- ")
- (to-server " -> ")
- (error " !! ")
- (otherwise " "))
- msg "\n")
-
- ;; if `mu4e-log-max-lines is specified and exceeded, clearest the oldest
- ;; lines
- (when (numberp mu4e~log-max-lines)
- (let ((lines (count-lines (point-min) (point-max))))
- (when (> lines mu4e~log-max-lines)
- (goto-char (point-max))
- (forward-line (- mu4e~log-max-lines lines))
- (beginning-of-line)
- (delete-region (point-min) (point)))))))))
-
-(defun mu4e-toggle-logging ()
- "Toggle between enabling/disabling debug-mode (in debug-mode,
-mu4e logs some of its internal workings to a log-buffer. See
-`mu4e-visit-log'."
- (interactive)
- (mu4e-log 'misc "logging disabled")
- (setq mu4e-debug (not mu4e-debug))
- (mu4e-message "debug logging has been %s"
- (if mu4e-debug "enabled" "disabled"))
- (mu4e-log 'misc "logging enabled"))
-
-(defun mu4e-show-log ()
- "Visit the mu4e debug log."
- (interactive)
- (let ((buf (get-buffer mu4e~log-buffer-name)))
- (unless (buffer-live-p buf)
- (mu4e-warn "No debug log available"))
- (switch-to-buffer buf)))
-
-
-(defun mu4e-split-ranges-to-numbers (str n)
- "Convert STR containing attachment numbers into a list of numbers.
-STR is a string; N is the highest possible number in the list.
-This includes expanding e.g. 3-5 into 3,4,5. If the letter
-\"a\" ('all')) is given, that is expanded to a list with numbers [1..n]."
- (let ((str-split (split-string str))
- beg end list)
- (dolist (elem str-split list)
- ;; special number "a" converts into all attachments 1-N.
- (when (equal elem "a")
- (setq elem (concat "1-" (int-to-string n))))
- (if (string-match "\\([0-9]+\\)-\\([0-9]+\\)" elem)
- ;; we have found a range A-B, which needs converting
- ;; into the numbers A, A+1, A+2, ... B.
- (progn
- (setq beg (string-to-number (match-string 1 elem))
- end (string-to-number (match-string 2 elem)))
- (while (<= beg end)
- (add-to-list 'list beg 'append)
- (setq beg (1+ beg))))
- ;; else just a number
- (add-to-list 'list (string-to-number elem) 'append)))
- ;; Check that all numbers are valid.
- (mapc
- #'(lambda (x)
- (cond
- ((> x n)
- (mu4e-warn "Attachment %d bigger than maximum (%d)" x n))
- ((< x 1)
- (mu4e-warn "Attachment number must be greater than 0 (%d)" x))))
- list)))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defvar mu4e-imagemagick-identify "identify"
- "Name/path of the Imagemagick 'identify' program.")
-
-(defun mu4e-display-image (imgpath &optional maxwidth maxheight)
- "Display image IMG at point; optionally specify MAXWIDTH and
-MAXHEIGHT. Function tries to use imagemagick if available (ie.,
-emacs was compiled with inmagemagick support); otherwise MAXWIDTH
-and MAXHEIGHT are ignored."
- (let* ((have-im (and (fboundp 'imagemagick-types)
- (imagemagick-types))) ;; hmm, should check for specific type
- (identify (and have-im maxwidth
- (executable-find mu4e-imagemagick-identify)))
- (props (and identify (shell-command-to-string
- (format "%s -format '%%w' %s"
- identify (shell-quote-argument imgpath)))))
- (width (and props (string-to-number props)))
- (img (if have-im
- (if (> (or width 0) (or maxwidth 0))
- (create-image imgpath 'imagemagick nil :width maxwidth)
- (create-image imgpath 'imagemagick))
- (create-image imgpath))))
- (when img
- (save-excursion
- (insert "\n")
- (let ((size (image-size img))) ;; inspired by gnus..
- (insert-char ?\n
- (max 0 (round (- (window-height) (or maxheight (cdr size)) 1) 2)))
- (insert-char ?\.
- (max 0 (round (- (window-width) (or maxwidth (car size))) 2)))
- (insert-image img))))))
-
-
-(defun mu4e-hide-other-mu4e-buffers ()
- "Bury mu4e-buffers (main, headers, view) (and delete all windows
-displaying it). Do _not_ bury the current buffer, though."
- (interactive)
- (let ((curbuf (current-buffer)))
- ;; note: 'walk-windows' does not seem to work correctly when modifying
- ;; windows; therefore, the doloops here
- (dolist (frame (frame-list))
- (dolist (win (window-list frame nil))
- (with-current-buffer (window-buffer win)
- (unless (eq curbuf (current-buffer))
- (when (member major-mode '(mu4e-headers-mode mu4e-view-mode))
- (when (eq t (window-deletable-p win))
- (delete-window win))))))) t))
-
-
-(defun mu4e-get-time-date (prompt)
- "Determine the emacs time value for the time/date entered by user
- after PROMPT. Formats are all that are accepted by
- `parse-time-string'."
- (let ((timestr (read-string (mu4e-format "%s" prompt))))
- (apply 'encode-time (mu4e-parse-time-string timestr))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(define-derived-mode mu4e-org-mode org-mode "mu4e:org"
- "Major mode for mu4e documents, derived from
- `org-mode'.")
-
-(defun mu4e-info (path)
- "Show a buffer with the information (an org-file) at PATH."
- (interactive)
- (unless (file-exists-p path)
- (mu4e-error "Cannot find %s" path))
- (lexical-let ((curbuf (current-buffer)))
- (find-file path)
- (mu4e-org-mode)
- (setq buffer-read-only t)
- (define-key mu4e-org-mode-map (kbd "q")
- (lambda ()
- (interactive)
- (bury-buffer)
- (switch-to-buffer curbuf)))))
-
-(defun mu4e-about ()
- "Show the mu4e 'about' page."
- (interactive)
- (mu4e-info (concat mu4e-doc-dir "/mu4e-about.org")))
-
-(defun mu4e-news ()
- "Show the mu4e 'about' page."
- (interactive)
- (mu4e-info (concat mu4e-doc-dir "/NEWS.org")))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun mu4e-refresh-message (path maildir)
- "Re-parse message at PATH and MAILDIR; if this works, we will
-receive (:info add :path <path> :docid <docid>) as well as (:update
-<msg-sexp>)."
- (mu4e~proc-add path maildir))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun mu4e~fontify-cited ()
- "Colorize message content based on the citation level. This is
-used in the view and compose modes."
- (save-excursion
- (goto-char (point-min))
- (when (search-forward-regexp "^\n" nil t) ;; search the first empty line
- (while (re-search-forward mu4e-cited-regexp nil t)
- (let* ((level (string-width (replace-regexp-in-string
- "[^>]" "" (match-string 0))))
- (face (unless (zerop level)
- (intern-soft (format "mu4e-cited-%d-face" level)))))
- (when face
- (add-text-properties (line-beginning-position 1)
- (line-end-position 1) `(face ,face))))))))
-
-(defun mu4e~fontify-signature ()
- "Give the message signatures a distinctive color. This is used in
-the view and compose modes."
- (let ((inhibit-read-only t))
- (save-excursion
- ;; give the footer a different color...
- (goto-char (point-min))
- (let ((p (search-forward "^-- *$" nil t)))
- (when p
- (add-text-properties p (point-max) '(face mu4e-footer-face)))))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun mu4e~quote-for-modeline (str)
- "Quote a string to be used literally in the modeline."
- (replace-regexp-in-string "%" "%%" str t t))
-
-
-(provide 'mu4e-utils)
-;;; End of mu4e-utils.el
diff --git a/_spacemacs.d/local/mu4e/mu4e-vars.el b/_spacemacs.d/local/mu4e/mu4e-vars.el
deleted file mode 100644
index e07b196..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-vars.el
+++ /dev/null
@@ -1,927 +0,0 @@
-;;; mu4e-vars.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Customization
-(require 'mu4e-meta)
-(require 'message)
-
-(defgroup mu4e nil
- "mu4e - mu for emacs"
- :group 'mail)
-
-(defcustom mu4e-mu-home nil
- "Location of the mu homedir, or nil for the default."
- :group 'mu4e
- :type '(choice (const :tag "Default location" nil)
- (directory :tag "Specify location"))
- :safe 'stringp)
-
-(defcustom mu4e-mu-binary (executable-find "mu")
- "Name of the mu-binary to use.
-If it cannot be found in your PATH, you can specify the full
-path."
- :type 'file
- :group 'mu4e
- :safe 'stringp)
-
-(defcustom mu4e-maildir (expand-file-name "~/Maildir")
- "The file system path to your Maildir. Must not be a symbolic
-link."
- :type 'directory
- :safe 'stringp
- :group 'mu4e)
-
-(defcustom mu4e-get-mail-command "true"
- "Shell command to run to retrieve new mail.
-Common values are \"offlineimap\", \"fetchmail\" or \"mbsync\", but
-arbitrary shell-commands can be used.
-
-When set to the literal string \"true\" (the default), the
-command simply finishes succesfully (running the 'true' command)
-without retrieving any mail. This can be useful when mail is
-already retrieved in another way."
- :type 'string
- :group 'mu4e
- :safe 'stringp)
-
-(defcustom mu4e-index-update-error-warning t
- "Whether to display warnings when we the retrieval process (as
- per `mu4e-get-mail-command') finished with a non-zero exit code."
- :type 'boolean
- :group 'mu4e
- :safe 'booleanp)
-
-(defcustom mu4e-index-update-error-continue t
- "Whether to continue with indexing when we the retrieval
- process (as per `mu4e-get-mail-command') finished with a non-zero
- exit code."
- :type 'boolean
- :group 'mu4e
- :safe 'booleanp)
-
-(defcustom mu4e-index-update-in-background t
- "Whether to run the automatic mail retrieval in the
-background."
- :type 'boolean
- :group 'mu4e
- :safe 'booleanp)
-
-(defcustom mu4e-index-cleanup t
- "Whether to run a cleanup face after indexing -- that is, see
-if the is a message in the filesystem for each file in the
-message store. Having this option as `t' ensures that no
-non-existing mesages are shown but can also be quite slow with
-large message stores."
- :type 'boolean
- :group 'mu4e
- :safe 'booleanp)
-
-(defcustom mu4e-index-lazy-check nil
- "Whether to run do a 'lazy check' for deciding whether to
-indexing a message. When this is set to `t', mu only uses the
-directory timestamps to decide on whether it needs to check the
-messages beneath it, which would miss messages that are modified
-outside mu. On the other hand, it's significantly faster."
- :type 'boolean
- :group 'mu4e
- :safe 'booleanp)
-
-
-(defcustom mu4e-update-interval nil
- "Number of seconds between automatic calls to retrieve mail and
-update the database. If nil, don't update automatically. Note,
-changes in `mu4e-update-interval' only take effect after restarting
-mu4e."
- :type '(choice (const :tag "No automatic update" nil)
- (integer :tag "Seconds"))
- :group 'mu4e
- :safe 'integerp)
-
-(defvar mu4e-update-pre-hook nil
- "Hook run just *before* the mail-retrieval / database updating process starts.
- You can use this hook for example to `mu4e-get-mail-command' with
- some specific setting.")
-
-(defcustom mu4e-hide-index-messages nil
- "Whether to hide the \"Indexing...\" messages, or any messages
-relating to updated contacts."
- :type 'boolean
- :group 'mu4e)
-
-(defcustom mu4e-change-filenames-when-moving nil
- "When moving messages to different folders, normally mu/mu4e keep
-the base filename the same (the flags-part of the filename may
-change still). With this option set to non-nil, mu4e instead
-changes the filename. This latter behavior works better with some
-IMAP-synchronization programs such as mbsync; the default works
-better with e.g. offlineimap."
- :type 'boolean
- :group 'mu4e
- :safe 'booleanp)
-
-(defcustom mu4e-attachment-dir (expand-file-name "~/")
- "Default directory for saving attachments.
-This can be either a string (a file system path), or a function
-that takes a filename and the mime-type as arguments, and returns
-the attachment dir. See Info node `(mu4e) Attachments' for details."
- :type 'directory
- :group 'mu4e
- :safe 'stringp)
-
-(defcustom mu4e-user-mail-address-list `(,user-mail-address)
- "List of e-mail addresses to consider 'my email addresses'.
-I.e. addresses whose presence in an email imply that it is a
-personal message. Note that e-mail addresses are case-sensitive,
-as per RFC531."
- :type '(repeat (string :tag "Address"))
- :group 'mu4e)
-
-;; 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")
-
-(defcustom mu4e-use-fancy-chars nil
- "Whether to use fancy (Unicode) characters for marks and
-threads. You can customize the exact fancy characters used with
-`mu4e-marks' and various `mu4e-headers-..-mark' and
-`mu4e-headers..-prefix' variables."
- :type 'boolean
- :group 'mu4e)
-
-(defcustom mu4e-date-format-long "%c"
- "Date format to use in the message view, in the format of
- `format-time-string'."
- :type 'string
- :group 'mu4e)
-
-(defvar mu4e-debug nil
- "When set to non-nil, log debug information to the *mu4e-log* buffer.")
-
-(defcustom mu4e-bookmarks
- '( ("flag:unread AND NOT flag:trashed" "Unread messages" ?u)
- ("date:today..now" "Today's messages" ?t)
- ("date:7d..now" "Last 7 days" ?w)
- ("mime:image/*" "Messages with images" ?p))
- "A list of pre-defined queries.
-These will show up in the main screen. Each of the list elements
-is a three-element list of the form (QUERY DESCRIPTION KEY),
-where QUERY is a string with a mu query, DESCRIPTION is a short
-description of the query (this will show up in the UI), and KEY
-is a shortcut key for the query."
- :type '(repeat (list (string :tag "Query")
- (string :tag "Description")
- character))
- :group 'mu4e)
-
-(defvar mu4e-bookmarks
- `( ,(make-mu4e-bookmark
- :name "Unread messages"
- :query "flag:unread AND NOT flag:trashed"
- :key ?u)
- ,(make-mu4e-bookmark
- :name "Today's messages"
- :query "date:today..now"
- :key ?t)
- ,(make-mu4e-bookmark
- :name "Last 7 days"
- :query "date:7d..now"
- :key ?w)
- ,(make-mu4e-bookmark
- :name "Messages with images"
- :query "mime:image/*"
- :key ?p))
- "A list of pre-defined queries. Each query is represented by a
-mu4e-bookmark structure with parameters @t{:name} with the name
-of the bookmark, @t{:query} with the query expression (a query
-string or an s-expression that evaluates to query string) and a
-@t{:key}, which is the shortcut-key for the query.
-
-An older form of bookmark, a 3-item list with (QUERY DESCRIPTION
-KEY) is still recognized as well, for backward-compatibility.")
-
-
-(defcustom mu4e-split-view 'horizontal
- "How to show messages / headers.
-A symbol which is either:
- * `horizontal': split horizontally (headers on top)
- * `vertical': split vertically (headers on the left).
- * anything else: don't split (show either headers or messages,
- not both)
-Also see `mu4e-headers-visible-lines'
-and `mu4e-headers-visible-columns'."
- :type '(choice (const :tag "Split horizontally" horizontal)
- (const :tag "Split vertically" vertical)
- (const :tag "Don't split" nil))
- :group 'mu4e-headers)
-
-(defcustom mu4e-view-show-images nil
- "Whether to automatically display attached images in the message
-view buffer."
- :type 'boolean
- :group 'mu4e-view)
-
-(make-obsolete-variable 'mu4e-show-images
- 'mu4e-view-show-images "0.9.9.x")
-
-(defcustom mu4e-confirm-quit t
- "Whether to confirm to quit mu4e."
- :type 'boolean
- :group 'mu4e)
-
-(defcustom mu4e-cited-regexp "^\\(\\([[:alpha:]]+\\)\\|\\( *\\)\\)\\(\\(>+ ?\\)+\\)"
- "Regular expression that determines whether a line is a
- citation. This recognizes lines starting with numbers of '>'
- and spaces as well as citations of the type \"John> ... \"."
- :type 'string
- :group 'mu4e)
-
-(defcustom mu4e-completing-read-function 'ido-completing-read
- "Function to be used to receive input from the user with
-completion. This is used to receive the name of the maildir
-to switch to via `mu4e~headers-jump-to-maildir'.
-
-Suggested possible values are:
- * `completing-read': built-in completion method
- * `ido-completing-read': dynamic completion within the minibuffer."
- :type 'function
- :options '(completing-read ido-completing-read)
- :group 'mu4e)
-
-(defcustom mu4e-context-policy 'ask-if-none
- "The policy to determine the context when entering the mu4e main view.
-
-If the value is `always-ask', ask the user unconditionally.
-
-In all other cases, if any context matches (using its match
-function), this context is used. Otherwise, if none of the
-contexts match, we have the following choices:
-
-- `pick-first': pick the first of the contexts available (ie. the default)
-- `ask': ask the user
-- `ask-if-none': ask if there is no context yet, otherwise leave it as it is
-- nil: return nil; leaves the current context as is.
-
-Also see `mu4e-compose-context-policy'."
- :type '(choice
- (const :tag "Always ask what context to use, even if one matches"
- 'always-ask)
- (const :tag "Ask if none of the contexts match" 'ask)
- (const :tag "Ask when there's no context yet" 'ask-if-none)
- (const :tag "Pick the first context if none match" 'pick-first)
- (const :tag "Don't change the context when none match" nil)
- :safe 'symbolp
- :group 'mu4e))
-
-
-;; crypto
-(defgroup mu4e-crypto nil
- "Crypto-related settings."
- :group 'mu4e)
-
-(defcustom mu4e-auto-retrieve-keys nil
- "Attempt to automatically retrieve public keys when needed."
- :type 'boolean
- :group 'mu4e-crypto)
-
-(defcustom mu4e-decryption-policy t
- "Policy for dealing with encrypted parts.
-The setting is a symbol:
- * t: try to decrypt automatically
- * `ask': ask before decrypting anything
- * nil: don't try to decrypt anything."
- :type '(choice (const :tag "Try to decrypt automatically" t)
- (const :tag "Ask before decrypting anything" ask)
- (const :tag "Don't try to decrypt anything" nil))
- :group 'mu4e-crypto)
-
-;; completion; we put them here rather than in mu4e-compose, as mu4e-utils needs
-;; the variables.
-
-(defgroup mu4e-compose nil
- "Message-composition related settings."
- :group 'mu4e)
-
-;; address completion
-(defcustom mu4e-compose-complete-addresses t
- "Whether to do auto-completion of e-mail addresses."
- :type 'boolean
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-complete-only-personal nil
- "Whether to consider only 'personal' e-mail addresses,
-i.e. 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)."
- :type 'boolean
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-complete-only-after "2010-01-01"
- "Consider only contacts last seen after this date.
-Date must be a string, in a format parseable by
-`org-parse-time-string'. This excludes really old contacts.
-Set to nil to not have any time-based restriction."
- :type 'string
- :group 'mu4e-compose)
-
-
-;;; names and mail-addresses can be mapped onto their canonical
-;;; counterpart. use the customizeable function
-;;; mu4e-canonical-contact-function to do that. below the identity
-;;; function for mapping a contact onto the canonical one.
-(defun mu4e-contact-identity (contact)
- "This returns the name and the mail-address of a contact.
-It is used as the identity function for converting contacts to
-their canonical counterpart; useful as an example."
- (let ((name (plist-get contact :name))
- (mail (plist-get contact :mail)))
- (list :name name :mail mail)))
-
-(defcustom mu4e-contact-rewrite-function nil
- "Either nil or a function to be used for when processing
-contacts and rewrite them or remove them altogether.
-
-If the function receives the contact as a list of the form
- (:name NAME :mail EMAIL ... other properties ... )
-(other properties may be there as well)
-
-The function should return either:
- - nil: remove this contact, or
-- the rewritten cell, or
-- the existing cell as-is
-
-For rewriting, it is recommended to use `plist-put' to set the
-changed parameters, so the other properties stay in place. Those
-are needed for sorting the contacts."
- :type 'function
- :group 'mu4e-compose)
-
-
-(defcustom mu4e-compose-complete-ignore-address-regexp "no-?reply"
- "Ignore any e-mail addresses for completion if they match this regexp."
- :type 'string
- :group 'mu4e-compose)
-
-(defcustom mu4e-compose-reply-to-address nil
- "The Reply-To address (if this, for some reason, is not equal to
-the From: address.)"
- :type 'string
- :group 'mu4e-compose)
-
-
-;; backward compatibility
-(make-obsolete-variable 'mu4e-reply-to-address 'mu4e-compose-reply-to-address
- "v0.9.9")
-
-(defcustom mu4e-compose-keep-self-cc nil
- "Non-nil means your e-mail address is kept on the CC list when
-replying to messages."
- :type 'boolean
- :group 'mu4e-compose)
-
-(defvar mu4e-compose-parent-message nil
- "The parent message plist.
-This is the message being replied to, forwarded or edited; used
-in `mu4e-compose-pre-hook'. For new messages, it is nil.")
-
-;; Folders
-(defgroup mu4e-folders nil
- "Special folders."
- :group 'mu4e)
-
-(defcustom mu4e-drafts-folder "/drafts"
- "Your folder for draft messages, relative to `mu4e-maildir'.
-e.g. \"/drafts\". Instead of a string, may also be a function that
-takes a message (a msg plist, see `mu4e-message-get-field'), and
-returns a folder. Note, the message parameter refers to the
-original message being replied to / being forwarded / re-edited and
-is nil otherwise. `mu4e-drafts-folder' is only evaluated once."
- :type '(choice
- (string :tag "Folder name")
- (function :tag "Function return folder name"))
- :group 'mu4e-folders)
-
-(defcustom mu4e-refile-folder "/archive"
- "Your folder for refiling messages, relative to `mu4e-maildir',
-e.g. \"/Archive\". Instead of a string, may also be a function that
-takes a message (a msg plist, see `mu4e-message-get-field'), and
-returns a folder. Note that the message parameter refers to the
-message-at-point."
- :type '(choice
- (string :tag "Folder name")
- (function :tag "Function return folder name"))
- :group 'mu4e-folders)
-
-(defcustom mu4e-sent-folder "/sent"
- "Your folder for sent messages, relative to `mu4e-maildir',
-e.g. \"/Sent Items\". Instead of a string, may also be a function
-that takes a message (a msg plist, see `mu4e-message-get-field'),
-and returns a folder. Note that the message parameter refers to
-the original message being replied to / being forwarded /
-re-edited, and is nil otherwise."
- :type '(choice
- (string :tag "Folder name")
- (function :tag "Function return folder name"))
- :group 'mu4e-folders)
-
-(defcustom mu4e-trash-folder "/trash"
- "Your folder for trashed messages, relative to `mu4e-maildir',
-e.g. \"/trash\". Instead of a string, may also be a function that
-takes a message (a msg plist, see `mu4e-message-get-field'), and
-returns a folder. When using `mu4e-trash-folder' in the headers
-view (when marking messages for trash). Note that the message
-parameter refers to the message-at-point. When using it when
-composing a message (see `mu4e-sent-messages-behavior'), this
-refers to the original message being replied to / being forwarded /
-re-edited, and is nil otherwise."
- :type '(choice
- (string :tag "Folder name")
- (function :tag "Function return folder name"))
- :group 'mu4e-folders)
-
-
-(defcustom mu4e-maildir-shortcuts nil
- "A list of maildir shortcuts. This makes it possible to quickly
-go to a particular maildir (folder), or quickly moving messages to
-them (e.g., for archiving or refiling). The list contains elements
-of the form (maildir . shortcut), where MAILDIR is a maildir (such
-as \"/archive/\"), and shortcut is a single character.
-
-You can use these shortcuts in the headers and view buffers, for
-example with `mu4e-mark-for-move-quick' (or 'm', by default) or
-`mu4e-jump-to-maildir' (or 'j', by default), followed by the
-designated shortcut character for the maildir.
-
-Unlike in search queries, folder names with spaces in them must NOT
-be quoted, since mu4e does this automatically for you."
- :type '(repeat (cons (string :tag "Maildir") character))
- :group 'mu4e-folders)
-
-;; Faces
-(defgroup mu4e-faces nil
- "Type faces (fonts) used in mu4e."
- :group 'mu4e
- :group 'faces)
-
-(defface mu4e-unread-face
- '((t :inherit font-lock-keyword-face :bold t))
- "Face for an unread message header."
- :group 'mu4e-faces)
-
-(defface mu4e-moved-face
- '((t :inherit font-lock-comment-face :slant italic))
- "Face for a message header that has been moved to some folder.
-\(It's still visible in the search results, since we cannot
-be sure it no longer matches)."
- :group 'mu4e-faces)
-
-(defface mu4e-trashed-face
- '((t :inherit font-lock-comment-face :strike-through t))
- "Face for an message header in the trash folder."
- :group 'mu4e-faces)
-
-(defface mu4e-draft-face
- '((t :inherit font-lock-string-face))
- "Face for a draft message header
-I.e. a message with the draft flag set."
- :group 'mu4e-faces)
-
-(defface mu4e-flagged-face
- '((t :inherit font-lock-constant-face :bold t))
- "Face for a flagged message header."
- :group 'mu4e-faces)
-
-(defface mu4e-replied-face
- '((t :inherit font-lock-builtin-face :bold nil))
- "Face for a replied message header."
- :group 'mu4e-faces)
-
-(defface mu4e-forwarded-face
- '((t :inherit font-lock-builtin-face :bold nil))
- "Face for a passed (forwarded) message header."
- :group 'mu4e-faces)
-
-(defface mu4e-header-face
- '((t :inherit default))
- "Face for a header without any special flags."
- :group 'mu4e-faces)
-
-(defface mu4e-header-title-face
- '((t :inherit font-lock-type-face))
- "Face for a header title in the headers view."
- :group 'mu4e-faces)
-
-(defface mu4e-header-highlight-face
- '((t :inherit region :weight bold :underline t))
- "Face for the header at point."
- :group 'mu4e-faces)
-
-(defface mu4e-header-marks-face
- '((t :inherit font-lock-preprocessor-face))
- "Face for the mark in the headers list."
- :group 'mu4e-faces)
-
-(defface mu4e-header-key-face
- '((t :inherit message-header-name :bold t))
- "Face for a header key (such as \"Foo\" in \"Subject:\ Foo\")."
- :group 'mu4e-faces)
-
-(defface mu4e-header-value-face
- '((t :inherit font-lock-type-face))
- "Face for a header value (such as \"Re: Hello!\")."
- :group 'mu4e-faces)
-
-(defface mu4e-special-header-value-face
- '((t :inherit font-lock-builtin-face))
- "Face for special header values."
- :group 'mu4e-faces)
-
-(defface mu4e-link-face
- '((t :inherit link))
- "Face for showing URLs and attachments in the message view."
- :group 'mu4e-faces)
-
-(defface mu4e-contact-face
- '((t :inherit font-lock-variable-name-face))
- "Face for showing URLs and attachments in the message view."
- :group 'mu4e-faces)
-
-(defface mu4e-highlight-face
- '((t :inherit highlight))
- "Face for highlighting things."
- :group 'mu4e-faces)
-
-(defface mu4e-title-face
- '((t :inherit font-lock-type-face :bold t))
- "Face for a header title in the headers view."
- :group 'mu4e-faces)
-
-(defface mu4e-modeline-face
- '((t :inherit font-lock-string-face :bold t))
- "Face for the query in the mode-line."
- :group 'mu4e-faces)
-
-(defface mu4e-view-body-face
- '((t :inherit default))
- "Face for the body in the message-view."
- :group 'mu4e-faces)
-
-(defface mu4e-footer-face
- '((t :inherit font-lock-comment-face))
- "Face for message footers (signatures)."
- :group 'mu4e-faces)
-
-(defface mu4e-url-number-face
- '((t :inherit font-lock-constant-face :bold t))
- "Face for the number tags for URLs."
- :group 'mu4e-faces)
-
-(defface mu4e-attach-number-face
- '((t :inherit font-lock-variable-name-face :bold t))
- "Face for the number tags for attachments."
- :group 'mu4e-faces)
-
-(defface mu4e-cited-1-face
- '((t :inherit font-lock-builtin-face :bold nil :italic t))
- "Face for cited message parts (level 1)."
- :group 'mu4e-faces)
-
-(defface mu4e-cited-2-face
- '((t :inherit font-lock-preprocessor-face :bold nil :italic t))
- "Face for cited message parts (level 2)."
- :group 'mu4e-faces)
-
-(defface mu4e-cited-3-face
- '((t :inherit font-lock-variable-name-face :bold nil :italic t))
- "Face for cited message parts (level 3)."
- :group 'mu4e-faces)
-
-(defface mu4e-cited-4-face
- '((t :inherit font-lock-keyword-face :bold nil :italic t))
- "Face for cited message parts (level 4)."
- :group 'mu4e-faces)
-
-(defface mu4e-cited-5-face
- '((t :inherit font-lock-comment-face :bold nil :italic t))
- "Face for cited message parts (level 5)."
- :group 'mu4e-faces)
-
-(defface mu4e-cited-6-face
- '((t :inherit font-lock-comment-delimiter-face :bold nil :italic t))
- "Face for cited message parts (level 6)."
- :group 'mu4e-faces)
-
-(defface mu4e-cited-7-face
- '((t :inherit font-lock-type-face :bold nil :italic t))
- "Face for cited message parts (level 7)."
- :group 'mu4e-faces)
-
-(defface mu4e-system-face
- '((t :inherit font-lock-comment-face :slant italic))
- "Face for system message (such as the footers for message headers)."
- :group 'mu4e-faces)
-
-(defface mu4e-ok-face
- '((t :inherit font-lock-comment-face :bold t :slant normal))
- "Face for things that are okay."
- :group 'mu4e-faces)
-
-(defface mu4e-warning-face
- '((t :inherit font-lock-warning-face :bold t :slant normal))
- "Face for warnings / error."
- :group 'mu4e-faces)
-
-(defface mu4e-compose-separator-face
- '((t :inherit message-separator :slant italic))
- "Face for the separator between headers / message in
-mu4e-compose-mode."
- :group 'mu4e-faces)
-
-(defface mu4e-compose-header-face
- '((t :inherit message-separator :slant italic))
- "Face for the separator between headers / message in
-mu4e-compose-mode."
- :group 'mu4e-faces)
-
-(defface mu4e-region-code
- '((t (:background "DarkSlateGray")))
- "Face for highlighting marked region in mu4e-view buffer."
- :group 'mu4e-faces)
-
-;; headers info
-(defconst mu4e-header-info
- '( (:attachments .
- ( :name "Attachments"
- :shortname "Atts"
- :help "Message attachments"
- :sortable nil))
- (:bcc .
- ( :name "Bcc"
- :shortname "Bcc"
- :help "Blind Carbon-Copy recipients for the message"
- :sortable t))
- (:cc .
- ( :name "Cc"
- :shortname "Cc"
- :help "Carbon-Copy recipients for the message"
- :sortable t))
- (:date .
- ( :name "Date"
- :shortname "Date"
- :help "Date/time when the message was written"
- :sortable t))
- (:human-date .
- ( :name "Date"
- :shortname "Date"
- :help "Date/time when the message was written."
- :sortable :date))
- (:flags .
- ( :name "Flags"
- :shortname "Flgs"
- :help "Flags for the message"
- :sortable nil))
- (:from .
- ( :name "From"
- :shortname "From"
- :help "The sender of the message"
- :sortable t))
- (:from-or-to .
- ( :name "From/To"
- :shortname "From/To"
- :help "Sender of the message if it's not me; otherwise the recipient"
- :sortable nil))
- (:maildir .
- ( :name "Maildir"
- :shortname "Maildir"
- :help "Maildir for this message"
- :sortable t))
- (:mailing-list .
- ( :name "List"
- :shortname "List"
- :help "Mailing list for this message"
- :sortable nil))
- (:message-id .
- ( :name "Message-Id"
- :shortname "MsgID"
- :help "Message-Id for this message"
- :sortable nil))
- (:path .
- ( :name "Path"
- :shortname "Path"
- :help "Full filesystem path to the message"
- :sortable t))
- (:signature .
- ( :name "Signature"
- :shortname "Sgn"
- :help "Check for the cryptographic signature"
- :sortable nil))
- (:decryption .
- ( :name "Decryption"
- :shortname "Dec"
- :help "Check the cryptographic decryption status"
- :sortable nil))
- (:size .
- ( :name "Size"
- :shortname "Size"
- :help "Size of the message"
- :sortable t))
- (:subject .
- ( :name "Subject"
- :shortname "Subject"
- :help "Subject of the message"
- :sortable t))
- (:tags .
- ( :name "Tags"
- :shortname "Tags"
- :help "Tags for the message"
- :sortable nil))
- (:thread-subject .
- ( :name "Subject"
- :shortname "Subject"
- :help "Subject of the thread"
- :sortable :subject))
- (:to .
- ( :name "To"
- :shortname "To"
- :help "Recipient of the message"
- :sortable t))
- (:user-agent .
- ( :name "User-Agent"
- :shortname "UA"
- :help "Program used for writing this message"
- :sortable t)))
- "An alist of all possible header fields and information about them.
-This is used in the user-interface (the column headers in the header list, and
-the fields the message view).
-
-Most fields should be self-explanatory. A special one is
-`:from-or-to', which is equal to `:from' unless `:from' matches one
-of the addresses in `mu4e-user-mail-address-list', in which case it
-will be equal to `:to'.
-
-Furthermore, the property `:sortable' determines whether we can
-sort by this field. This can be either a boolean (nil or t), or a
-symbol for /another/ field. For example, the `:human-date' field
-uses `:date' for that.
-
-Note, `:sortable' does not work for custom header fields.")
-
-
-(defvar mu4e-header-info-custom
- '( (:recipnum .
- ( :name "Number of recipients"
- :shortname "Recip#"
- :help "Number of recipients for this message"
- :function
- (lambda (msg)
- (format "%d"
- (+ (length (mu4e-message-field msg :to))
- (length (mu4e-message-field msg :cc))))))))
-"A list of custom (user-defined) headers. The format is similar
-to `mu4e-header-info', but adds a :function property, which
-should point to a function that takes a message p-list as
-argument, and returns a string. See the default value of
-`mu4e-header-info-custom for an example.")
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; run-time vars used in multiple places
-
-;; headers
-(defconst mu4e~headers-buffer-name "*mu4e-headers*"
- "Name of the buffer for message headers.")
-(defvar mu4e~headers-buffer nil "Buffer for message headers.")
-; view
-(defconst mu4e~view-buffer-name "*mu4e-view*"
- "Name for the message view buffer.")
-
-(defconst mu4e~view-embedded-buffer-name " *mu4e-embedded-view*"
- "Name for the embedded message view buffer.")
-
-(defvar mu4e~view-buffer nil "The view buffer.")
-
-(defvar mu4e~view-msg nil "The message being viewed in view mode.")
-
-(defvar mu4e~view-headers-buffer nil
- "The headers buffer connected to this view.")
-
-(defvar mu4e~contacts nil
- "Hash of that maps contacts (ie. 'name <e-mail>') to an integer
-with their sort order. 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.")
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; our handlers funcs
-;; these handler funcs define what happens when we receive a certain message
-;; from the server
-(defun mu4e~default-handler (&rest args)
- "*internal* Dummy handler function."
- (error "Not handled: %S" args))
-
-(defvar mu4e-error-func 'mu4e~default-handler
- "A function called for each error returned from the server
-process; the function is passed an error plist as argument. See
-`mu4e~proc-filter' for the format.")
-
-(defvar mu4e-update-func 'mu4e~default-handler
- "A function called for each :update sexp returned from the server
-process; the function is passed a msg sexp as argument. See
-`mu4e~proc-filter' for the format.")
-
-(defvar mu4e-remove-func 'mu4e~default-handler
- "A function called for each :remove sexp returned from the server
-process, when some message has been deleted. The function is passed
-the docid of the removed message.")
-
-(defvar mu4e-sent-func 'mu4e~default-handler
- "A function called for each :sent sexp returned from the server
-process, when some message has been sent. The function is passed
-the docid and the draft-path of the sent message.")
-
-(defvar mu4e-view-func 'mu4e~default-handler
- "A function called for each single message sexp returned from the
-server process. The function is passed a message sexp as
-argument. See `mu4e~proc-filter' for the format.")
-
-(defvar mu4e-header-func 'mu4e~default-handler
- "A function called for each message returned from the server
-process; the function is passed a msg plist as argument. See
-`mu4e~proc-filter' for the format.")
-
-(defvar mu4e-found-func 'mu4e~default-handler
- "A function called for when we received a :found sexp after the
-headers have returns, to report on the number of matches. See
-`mu4e~proc-filter' for the format.")
-
-(defvar mu4e-erase-func 'mu4e~default-handler
- "A function called for when we received an :erase sexp after the
-headers have returns, to clear the current headers buffer. See
-`mu4e~proc-filter' for the format.")
-
-(defvar mu4e-compose-func 'mu4e~default-handler
- "A function called for each message returned from the server
-process that is used as basis for composing a new message (ie.,
-either a reply or a forward); the function is passed msg and a
-symbol (either reply or forward). See `mu4e~proc-filter' for the
-format of <msg-plist>.")
-
-(defvar mu4e-info-func 'mu4e~default-handler
- "A function called for each (:info type ....) sexp received from
-the server process.")
-
-(defvar mu4e-pong-func 'mu4e~default-handler
- "A function called for each (:pong type ....) sexp received from
-the server process.")
-
-(defvar mu4e-contacts-func 'mu4e~default-handler
- "A function called for each (:contacts (<list-of-contacts>) sexp
-received from the server process.")
-
-(defvar mu4e-temp-func 'mu4e~default-handler
- "A function called for each (:temp <file> <cookie>) sexp received
-from the server process.")
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(provide 'mu4e-vars)
-;;; End of mu4e-vars.el
diff --git a/_spacemacs.d/local/mu4e/mu4e-view.el b/_spacemacs.d/local/mu4e/mu4e-view.el
deleted file mode 100644
index 564835d..0000000
--- a/_spacemacs.d/local/mu4e/mu4e-view.el
+++ /dev/null
@@ -1,1542 +0,0 @@
-;;; mu4e-view.el -- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; In this file we define mu4e-view-mode (+ helper functions), which is used for
-;; viewing e-mail messages
-
-;;; Code:
-(require 'mu4e-utils) ;; utility functions
-(require 'mu4e-vars)
-(require 'mu4e-mark)
-(require 'mu4e-proc)
-(require 'mu4e-compose)
-(require 'mu4e-actions)
-(require 'mu4e-message)
-
-(require 'comint)
-(require 'browse-url)
-(require 'button)
-(require 'epa)
-(require 'epg)
-(require 'thingatpt)
-(require 'calendar)
-
-(eval-when-compile (byte-compile-disable-warning 'cl-functions))
-(require 'cl)
-
-
-;; the message view
-(defgroup mu4e-view nil
- "Settings for the message view."
- :group 'mu4e)
-
-(defcustom mu4e-view-fields
- '(:from :to :cc :subject :flags :date :maildir :mailing-list :tags
- :attachments :signature :decryption)
- "Header fields to display in the message view buffer.
-For the complete list of available headers, see `mu4e-header-info'."
- :type (list 'symbol)
- :group 'mu4e-view)
-
-
-(defcustom mu4e-view-show-addresses nil
- "Whether to initially show full e-mail addresses for contacts in
-address fields, rather than only their names."
- :type 'boolean
- :group 'mu4e-view)
-
-(make-obsolete-variable 'mu4e-view-wrap-lines nil "0.9.9-dev7")
-(make-obsolete-variable 'mu4e-view-hide-cited nil "0.9.9-dev7")
-
-(defcustom mu4e-view-date-format "%c"
- "Date format to use in the message view.
-In the format of `format-time-string'."
- :type 'string
- :group 'mu4e-view)
-
-(defcustom mu4e-view-image-max-width 800
- "The maximum width for images to display.
-This is only effective if you're using an emacs with Imagemagick
-support, and `mu4e-view-show-images' is non-nil."
- :group 'mu4e-view)
-
-(defcustom mu4e-view-image-max-height 600
- "The maximum height for images to display.
-This is only effective if you're using an emacs with Imagemagick
-support, and `mu4e-view-show-images' is non-nil."
- :group 'mu4e-view)
-
-(defcustom mu4e-view-scroll-to-next t
- "If non-nil, move to the next message when calling
-`mu4e-view-scroll-up-or-next' (typically bound to SPC) when at the
-end of a message. Otherwise, don't move to the next message.")
-
-(defcustom mu4e-save-multiple-attachments-without-asking nil
- "If non-nil, saving multiple attachments asks once for a
-directory and saves all attachments in the chosen directory."
- :type 'boolean
- :group 'mu4e-view)
-
-(defvar mu4e-view-actions
- '( ("capture message" . mu4e-action-capture-message)
- ("view as pdf" . mu4e-action-view-as-pdf)
- ("show this thread" . mu4e-action-show-thread))
- "List of actions to perform on messages in view mode.
-The actions are of the form:
- (NAME FUNC)
-where:
-* NAME is the name of the action (e.g. \"Count lines\")
-* FUNC is a function which receives a message plist as an argument.
-
-The first letter of NAME is used as a shortcut character.")
-
-(defvar mu4e-view-attachment-actions
- '( ("wopen-with" . mu4e-view-open-attachment-with)
- ("ein-emacs" . mu4e-view-open-attachment-emacs)
- ("dimport-in-diary" . mu4e-view-import-attachment-diary)
- ("|pipe" . mu4e-view-pipe-attachment))
- "List of actions to perform on message attachments.
-The actions are cons-cells of the form:
- (NAME . FUNC)
-where:
-* NAME is the name of the action (e.g. \"Count lines\")
-* FUNC is a function which receives two arguments: the message
- plist and the attachment number.
-The first letter of NAME is used as a shortcut character.")
-
-(defvar mu4e-view-fill-headers t
- "If non-nil, automatically fill the headers when viewing them.")
-
-(defvar mu4e-view-contacts-header-keymap
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] 'mu4e~view-compose-contact)
- (define-key map "C" 'mu4e~view-compose-contact)
- (define-key map "c" 'mu4e~view-copy-contact)
- map)
- "Keymap used for the contacts in the header fields.")
-
-(defvar mu4e-view-clickable-urls-keymap
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-1] 'mu4e~view-browse-url-from-binding)
- (define-key map [?\M-\r] 'mu4e~view-browse-url-from-binding)
- map)
- "Keymap used for the urls inside the body.")
-
-(defvar mu4e-view-attachments-header-keymap
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-1] 'mu4e~view-open-attach-from-binding)
- (define-key map [?\M-\r] 'mu4e~view-open-attach-from-binding)
- (define-key map [mouse-2] 'mu4e~view-save-attach-from-binding)
- (define-key map (kbd "<S-return>") 'mu4e~view-save-attach-from-binding)
- map)
- "Keymap used in the \"Attachements\" header field.")
-
-(defcustom mu4e-view-auto-mark-as-read t
- "Automatically mark messages are 'read' when you read
-them. This is typically the expected behavior, but can be turned
-off, for example when using a read-only file-system."
- :type 'boolean
- :group 'mu4e-view)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defvar mu4e~view-cited-hidden nil "Whether cited lines are hidden.")
-(defvar mu4e~view-link-map nil
- "A map of some number->url so we can jump to url by number.")
-
-(defvar mu4e~path-parent-docid-map (make-hash-table :test 'equal)
- "A map of msg paths --> parent-docids.
-This is to determine what is the parent docid for embedded
-message extracted at some path.")
-
-(defvar mu4e~view-attach-map nil
- "A mapping of user-visible attachment number to the actual part index.")
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun mu4e-view-message-with-message-id (msgid)
- "View message with message-id MSGID. This (re)creates a
-headers-buffer with a search for MSGID, then open a view for that
-message."
- (mu4e-headers-search (concat "msgid:" msgid) nil nil t msgid t))
-
-(define-obsolete-function-alias 'mu4e-view-message-with-msgid
- 'mu4e-view-message-with-message-id "0.9.17")
-
-(defun mu4e~view-custom-field (msg field)
- "Show some custom header field, or raise an error if it is not
-found."
- (let* ((item (or (assoc field mu4e-header-info-custom)
- (mu4e-error "field %S not found" field)))
- (func (or (plist-get (cdr-safe item) :function)
- (mu4e-error "no :function defined for field %S %S"
- field (cdr item)))))
- (funcall func msg)))
-
-
-(defun mu4e-view-message-text (msg)
- "Return the message to display (as a string), based on the MSG plist."
- (concat
- (mapconcat
- (lambda (field)
- (let ((fieldval (mu4e-message-field msg field)))
- (case field
- (:subject (mu4e~view-construct-header field fieldval))
- (:path (mu4e~view-construct-header field fieldval))
- (:maildir (mu4e~view-construct-header field fieldval))
- (:user-agent (mu4e~view-construct-header field fieldval))
- ((:flags :tags) (mu4e~view-construct-flags-tags-header
- field fieldval))
-
- ;; contact fields
- (:to (mu4e~view-construct-contacts-header msg field))
- (:from (mu4e~view-construct-contacts-header msg field))
- (:cc (mu4e~view-construct-contacts-header msg field))
- (:bcc (mu4e~view-construct-contacts-header msg field))
-
- ;; if we (`user-mail-address' are the From, show To, otherwise,
- ;; show From
- (:from-or-to
- (let* ((from (mu4e-message-field msg :from))
- (from (and from (cdar from))))
- (if (mu4e-user-mail-address-p from)
- (mu4e~view-construct-contacts-header msg :to)
- (mu4e~view-construct-contacts-header msg :from))))
- ;; date
- (:date
- (let ((datestr
- (when fieldval (format-time-string mu4e-view-date-format
- fieldval))))
- (if datestr (mu4e~view-construct-header field datestr) "")))
- ;; size
- (:size
- (mu4e~view-construct-header field (mu4e-display-size fieldval)))
- (:mailing-list
- (mu4e~view-construct-header field fieldval))
- (:message-id
- (mu4e~view-construct-header field fieldval))
- ;; attachments
- (:attachments (mu4e~view-construct-attachments-header msg))
- ;; pgp-signatures
- (:signature (mu4e~view-construct-signature-header msg))
- ;; pgp-decryption
- (:decryption (mu4e~view-construct-decryption-header msg))
- (t (mu4e~view-construct-header field
- (mu4e~view-custom-field msg field))))))
- mu4e-view-fields "")
- "\n"
- (let ((body (mu4e-message-body-text msg)))
- (when (fboundp 'add-face-text-property)
- (add-face-text-property 0 (length body) 'mu4e-view-body-face t body))
- body)))
-
-(defun mu4e~view-embedded-winbuf ()
- "Get a buffer (shown in a window) for the embedded message."
- (let* ((buf (get-buffer-create mu4e~view-embedded-buffer-name))
- (win (or (get-buffer-window buf) (split-window-vertically))))
- (select-window win)
- (switch-to-buffer buf)))
-
-(defun mu4e~delete-all-overlays ()
- "`delete-all-overlays' with compatibility fallback."
- (if (functionp 'delete-all-overlays)
- (delete-all-overlays)
- (remove-overlays)))
-
-
-(defun mu4e-view (msg headersbuf)
- "Display the message MSG in a new buffer, and keep in sync with HDRSBUF.
-'In sync' here means that moving to the next/previous message in
-the the message view affects HDRSBUF, as does marking etc.
-
-As a side-effect, a message that is being viewed loses its 'unread'
-marking if it still had that."
- (let* ((embedded ;; is it as an embedded msg (ie. message/rfc822 att)?
- (when (gethash (mu4e-message-field msg :path)
- mu4e~path-parent-docid-map) t))
- (buf
- (if embedded
- (mu4e~view-embedded-winbuf)
- (get-buffer-create mu4e~view-buffer-name))))
- ;; note: mu4e~view-mark-as-read-maybe will pseudo-recursively call mu4e-view
- ;; again by triggering mu4e~view again as it marks the message as read
- (with-current-buffer buf
- (switch-to-buffer buf)
- (setq mu4e~view-msg msg)
- (when (or embedded (not (mu4e~view-mark-as-read-maybe msg)))
- (let ((inhibit-read-only t))
- (erase-buffer)
- (mu4e~delete-all-overlays)
- (insert (mu4e-view-message-text msg))
- (goto-char (point-min))
- (mu4e~fontify-cited)
- (mu4e~fontify-signature)
- (mu4e~view-make-urls-clickable)
- (mu4e~view-show-images-maybe msg)
- (setq
- mu4e~view-buffer buf
- mu4e~view-headers-buffer headersbuf)
- (when embedded (local-set-key "q" 'kill-buffer-and-window))
- (mu4e-view-mode))))))
-
-(defun mu4e~view-get-property-from-event (prop)
- "Get the property PROP at point, or the location of the mouse.
-The action is chosen based on the `last-command-event'.
-Meant to be evoked from interactive commands."
- (if (and (eventp last-command-event)
- (mouse-event-p last-command-event))
- (let ((posn (event-end last-command-event)))
- (when (numberp (posn-point posn))
- (get-text-property
- (posn-point posn)
- prop
- (window-buffer (posn-window posn)))
- ))
- (get-text-property (point) prop)))
-
-(defun mu4e~view-construct-header (field val &optional dont-propertize-val)
- "Return header field FIELD (as in `mu4e-header-info') with value
-VAL if VAL is non-nil. If DONT-PROPERTIZE-VAL is non-nil, do not
-add text-properties to VAL."
- (let* ((info (cdr (assoc field
- (append mu4e-header-info mu4e-header-info-custom))))
- (key (plist-get info :name))
- (help (plist-get info :help)))
- (if (and val (> (length val) 0))
- (with-temp-buffer
- (insert (propertize (concat key ":")
- 'face 'mu4e-header-key-face
- 'help-echo help) " "
- (if dont-propertize-val
- val
- (propertize val 'face 'mu4e-header-value-face)) "\n")
- (when mu4e-view-fill-headers
- ;; temporarily set the fill column <margin> positions to the right, so
- ;; we can indent the following lines correctly
- (let* ((margin 1)
- (fill-column (max (- fill-column margin) 0)))
- (fill-region (point-min) (point-max))
- (goto-char (point-min))
- (while (and (zerop (forward-line 1)) (not (looking-at "^$")))
- (indent-to-column margin))))
- (buffer-string))
- "")))
-
-(defun mu4e~view-compose-contact (&optional point)
- "Compose a message for the address at point."
- (interactive)
- (unless (get-text-property (or point (point)) 'email)
- (mu4e-error "No address at point"))
- (mu4e~compose-mail (get-text-property (or point (point)) 'long)))
-
-(defun mu4e~view-copy-contact (&optional full)
- "Compose a message for the address at (point)."
- (interactive "P")
- (let ((email (get-text-property (point) 'email))
- (long (get-text-property (point) 'long)))
- (unless email (mu4e-error "No address at point"))
- (kill-new (if full long email))
- (mu4e-message "Address copied.")))
-
-(defun mu4e~view-construct-contacts-header (msg field)
- "Add a header for a contact field (ie., :to, :from, :cc, :bcc)."
- (mu4e~view-construct-header field
- (mapconcat
- (lambda(c)
- (let* ((name (when (car c)
- (replace-regexp-in-string "[[:cntrl:]]" "" (car c))))
- (email (when (cdr c)
- (replace-regexp-in-string "[[:cntrl:]]" "" (cdr c))))
- (short (or name email)) ;; name may be nil
- (long (if name (format "%s <%s>" name email) email)))
- (propertize
- (if mu4e-view-show-addresses long short)
- 'long long
- 'short short
- 'email email
- 'keymap mu4e-view-contacts-header-keymap
- 'face 'mu4e-contact-face
- 'mouse-face 'highlight
- 'help-echo (format "<%s>\n%s" email
- "[mouse-2] or C to compose a mail for this recipient"))))
- (mu4e-message-field msg field) ", ") t))
-
-
-(defun mu4e~view-construct-flags-tags-header (field val)
- "Construct a Flags: header."
- (mu4e~view-construct-header
- field
- (mapconcat
- (lambda (flag)
- (propertize
- (if (symbolp flag)
- (symbol-name flag)
- flag)
- 'face 'mu4e-special-header-value-face))
- val
- (propertize ", " 'face 'mu4e-header-value-face)) t))
-
-(defun mu4e~view-construct-signature-header (msg)
- "Construct a Signature: header, if there are any signed parts."
- (let* ((parts (mu4e-message-field msg :parts))
- (verdicts
- (remove-if 'null
- (mapcar (lambda (part) (mu4e-message-part-field part :signature))
- parts)))
- (val (when verdicts
- (mapconcat
- (lambda (v)
- (propertize (symbol-name v)
- 'face (if (eq v 'verified)
- 'mu4e-ok-face 'mu4e-warning-face)))
- verdicts ", ")))
- (btn (when val
- (with-temp-buffer
- (insert-text-button "Details"
- 'action (lambda (b)
- (mu4e-view-verify-msg-popup
- (button-get b 'msg))))
- (buffer-string))))
- (val (when val (concat val " (" btn ")"))))
- (mu4e~view-construct-header :signature val t)))
-
-(defun mu4e~view-construct-decryption-header (msg)
- "Construct a Decryption: header, if there are any encrypted parts."
- (let* ((parts (mu4e-message-field msg :parts))
- (verdicts
- (remove-if 'null
- (mapcar (lambda (part)
- (mu4e-message-part-field part :decryption))
- parts)))
- (succeeded (remove-if (lambda (v) (eq v 'failed)) verdicts))
- (failed (remove-if (lambda (v) (eq v 'succeeded)) verdicts))
- (succ (when succeeded
- (propertize
- (concat (number-to-string (length succeeded))
- " part(s) decrypted")
- 'face 'mu4e-ok-face)))
- (fail (when failed
- (propertize
- (concat (number-to-string (length failed))
- " part(s) failed")
- 'face 'mu4e-warning-face)))
- (val (concat succ fail)))
- (mu4e~view-construct-header :decryption val t)))
-
-(defun mu4e~view-open-attach-from-binding ()
- "Open the attachement at point, or click location."
- (interactive)
- (let* (( msg (mu4e~view-get-property-from-event 'mu4e-msg))
- ( attnum (mu4e~view-get-property-from-event 'mu4e-attnum)))
- (when (and msg attnum)
- (mu4e-view-open-attachment msg attnum))))
-
-(defun mu4e~view-save-attach-from-binding ()
- "Save the attachement at point, or click location."
- (interactive)
- (let* (( msg (mu4e~view-get-property-from-event 'mu4e-msg))
- ( attnum (mu4e~view-get-property-from-event 'mu4e-attnum)))
- (when (and msg attnum)
- (mu4e-view-save-attachment-single msg attnum))))
-
-(defun mu4e~view-construct-attachments-header (msg)
- "Display attachment information; the field looks like something like:
- :parts ((:index 1 :name \"1.part\" :mime-type \"text/plain\"
- :type (leaf) :attachment nil :size 228)
- (:index 2 :name \"analysis.doc\"
- :mime-type \"application/msword\"
- :type (leaf attachment) :attachment nil :size 605196))"
- (setq mu4e~view-attach-map ;; buffer local
- (make-hash-table :size 64 :weakness nil))
- (let* ((id 0)
- (attachments
- ;; we only list parts that look like attachments, ie. that have a
- ;; non-nil :attachment property; we record a mapping between
- ;; user-visible numbers and the part indices
- (remove-if-not
- (lambda (part)
- (let* ((mtype (or (mu4e-message-part-field part :mime-type)
- "application/octet-stream"))
- (attachtype (mu4e-message-part-field part :type))
- (isattach
- (or ;; we consider parts marked either
- ;; "attachment" or "inline" as attachment.
- (member 'attachment attachtype)
- ;; list inline parts as attachment (so they can be
- ;; saved), unless they are text/plain, which are
- ;; usually just message footers in mailing lists
- (and (member 'inline attachtype)
- (not (string-match "^text/plain" mtype))))))
- (or ;; remove if it's not an attach *or* if it's an
- ;; image/audio/application type (but not a signature)
- isattach
- (string-match "^\\(image\\|audio\\)" mtype)
- (string= "message/rfc822" mtype)
- (string= "text/calendar" mtype)
- (and (string-match "^application" mtype)
- (not (string-match "signature" mtype))))))
- (mu4e-message-field msg :parts)))
- (attstr
- (mapconcat
- (lambda (part)
- (let ((index (mu4e-message-part-field part :index))
- (name (mu4e-message-part-field part :name))
- (size (mu4e-message-part-field part :size)))
- (incf id)
- (puthash id index mu4e~view-attach-map)
-
- (concat
- (propertize (format "[%d]" id)
- 'face 'mu4e-attach-number-face)
- (propertize name 'face 'mu4e-link-face
- 'keymap mu4e-view-attachments-header-keymap
- 'mouse-face 'highlight
- 'help-echo (concat
- "[mouse-1] or [M-RET] opens the attachment\n"
- "[mouse-2] or [S-RET] offers to save it")
- 'mu4e-msg msg
- 'mu4e-attnum id
- )
- (when (and size (> size 0))
- (propertize (format "(%s)" (mu4e-display-size size))
- 'face 'mu4e-header-key-face)))))
- attachments ", ")))
- (when attachments
- (mu4e~view-construct-header :attachments attstr t))))
-
-(defun mu4e-view-for-each-part (msg func)
- "Apply FUNC to each part in MSG.
-FUNC should be a function taking two arguments:
- 1. the message MSG, and
- 2. a plist describing the attachment. The plist looks like:
- (:index 1 :name \"test123.doc\"
- :mime-type \"application/msword\" :attachment t :size 1234)."
- (dolist (part (mu4e-msg-field msg :parts))
- (funcall func msg part)))
-
-(defvar mu4e-view-mode-map nil
- "Keymap for \"*mu4e-view*\" buffers.")
-(unless mu4e-view-mode-map
- (setq mu4e-view-mode-map
- (let ((map (make-sparse-keymap)))
-
- (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
- (define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
-
- (define-key map "q" 'mu4e~view-quit-buffer)
-
- ;; note, 'z' is by-default bound to 'bury-buffer'
- ;; but that's not very useful in this case
- (define-key map "z" 'ignore)
-
- (define-key map "s" 'mu4e-headers-search)
- (define-key map "S" 'mu4e-view-search-edit)
- (define-key map "/" 'mu4e-view-search-narrow)
-
- (define-key map (kbd "<M-left>") 'mu4e-headers-query-prev)
- (define-key map (kbd "<M-right>") 'mu4e-headers-query-next)
-
- (define-key map "b" 'mu4e-headers-search-bookmark)
- (define-key map "B" 'mu4e-headers-search-bookmark-edit)
-
- (define-key map "%" 'mu4e-view-mark-pattern)
- (define-key map "t" 'mu4e-view-mark-subthread)
- (define-key map "T" 'mu4e-view-mark-thread)
-
- (define-key map "v" 'mu4e-view-verify-msg-popup)
-
- (define-key map "j" 'mu4e~headers-jump-to-maildir)
-
- (define-key map "g" 'mu4e-view-go-to-url)
- (define-key map "k" 'mu4e-view-save-url)
- (define-key map "f" 'mu4e-view-fetch-url)
-
- (define-key map "F" 'mu4e-compose-forward)
- (define-key map "R" 'mu4e-compose-reply)
- (define-key map "C" 'mu4e-compose-new)
- (define-key map "E" 'mu4e-compose-edit)
-
- (define-key map "." 'mu4e-view-raw-message)
- (define-key map "|" 'mu4e-view-pipe)
- (define-key map "a" 'mu4e-view-action)
-
- (define-key map ";" 'mu4e-context-switch)
-
- ;; toggle header settings
- (define-key map "O" 'mu4e-headers-change-sorting)
- (define-key map "P" 'mu4e-headers-toggle-threading)
- (define-key map "Q" 'mu4e-headers-toggle-full-search)
- (define-key map "W" 'mu4e-headers-toggle-include-related)
-
- ;; change the number of headers
- (define-key map (kbd "C-+") 'mu4e-headers-split-view-grow)
- (define-key map (kbd "C--") 'mu4e-headers-split-view-shrink)
- (define-key map (kbd "<C-kp-add>") 'mu4e-headers-split-view-grow)
- (define-key map (kbd "<C-kp-subtract>") 'mu4e-headers-split-view-shrink)
-
- ;; intra-message navigation
- (define-key map (kbd "SPC") 'mu4e-view-scroll-up-or-next)
- (define-key map (kbd "<home>") 'beginning-of-buffer)
- (define-key map (kbd "<end>") 'end-of-buffer)
- (define-key map (kbd "RET") 'mu4e-scroll-up)
- (define-key map (kbd "<backspace>") 'mu4e-scroll-down)
-
- ;; navigation between messages
- (define-key map "p" 'mu4e-view-headers-prev)
- (define-key map "n" 'mu4e-view-headers-next)
- ;; the same
- (define-key map (kbd "<M-down>") 'mu4e-view-headers-next)
- (define-key map (kbd "<M-up>") 'mu4e-view-headers-prev)
-
- (define-key map (kbd "[") 'mu4e-view-headers-prev-unread)
- (define-key map (kbd "]") 'mu4e-view-headers-next-unread)
-
- ;; switching to view mode (if it's visible)
- (define-key map "y" 'mu4e-select-other-view)
-
- ;; attachments
- (define-key map "e" 'mu4e-view-save-attachment)
- (define-key map "o" 'mu4e-view-open-attachment)
- (define-key map "A" 'mu4e-view-attachment-action)
-
- ;; marking/unmarking
- (define-key map "d" 'mu4e-view-mark-for-trash)
- (define-key map (kbd "<delete>") 'mu4e-view-mark-for-delete)
- (define-key map (kbd "<deletechar>") 'mu4e-view-mark-for-delete)
- (define-key map (kbd "D") 'mu4e-view-mark-for-delete)
- (define-key map (kbd "m") 'mu4e-view-mark-for-move)
- (define-key map (kbd "r") 'mu4e-view-mark-for-refile)
-
- (define-key map (kbd "?") 'mu4e-view-mark-for-unread)
- (define-key map (kbd "!") 'mu4e-view-mark-for-read)
-
- (define-key map (kbd "+") 'mu4e-view-mark-for-flag)
- (define-key map (kbd "-") 'mu4e-view-mark-for-unflag)
- (define-key map (kbd "=") 'mu4e-view-mark-for-untrash)
- (define-key map (kbd "&") 'mu4e-view-mark-custom)
-
- (define-key map (kbd "*") 'mu4e-view-mark-for-something)
- (define-key map (kbd "<kp-multiply>") 'mu4e-view-mark-for-something)
- (define-key map (kbd "<insert>") 'mu4e-view-mark-for-something)
- (define-key map (kbd "<insertchar>") 'mu4e-view-mark-for-something)
-
- (define-key map (kbd "#") 'mu4e-mark-resolve-deferred-marks)
-
- ;; misc
- (define-key map "w" 'visual-line-mode)
- (define-key map "#" 'mu4e-view-toggle-hide-cited)
- (define-key map "h" 'mu4e-view-toggle-html)
- (define-key map (kbd "M-q") 'mu4e-view-fill-long-lines)
-
- ;; next 3 only warn user when attempt in the message view
- (define-key map "u" 'mu4e-view-unmark)
- (define-key map "U" 'mu4e-view-unmark-all)
- (define-key map "x" 'mu4e-view-marked-execute)
-
- (define-key map "$" 'mu4e-show-log)
- (define-key map "H" 'mu4e-display-manual)
-
- ;; menu
- (define-key map [menu-bar] (make-sparse-keymap))
- (let ((menumap (make-sparse-keymap "View")))
- (define-key map [menu-bar headers] (cons "View" menumap))
-
- (define-key menumap [quit-buffer]
- '("Quit view" . mu4e~view-quit-buffer))
- (define-key menumap [display-help] '("Help" . mu4e-display-manual))
-
- (define-key menumap [sepa0] '("--"))
- (define-key menumap [wrap-lines]
- '("Toggle wrap lines" . visual-line-mode))
- (define-key menumap [toggle-html]
- '("Toggle view-html" . mu4e-view-toggle-html))
- (define-key menumap [hide-cited]
- '("Toggle hide cited" . mu4e-view-toggle-hide-cited))
- (define-key menumap [raw-view]
- '("View raw message" . mu4e-view-raw-message))
- (define-key menumap [pipe]
- '("Pipe through shell" . mu4e-view-pipe))
- ;; (define-key menumap [inspect]
- ;; '("Inspect with guile" . mu4e-inspect-message))
-
- (define-key menumap [sepa8] '("--"))
- (define-key menumap [open-att]
- '("Open attachment" . mu4e-view-open-attachment))
- (define-key menumap [extract-att]
- '("Extract attachment" . mu4e-view-save-attachment))
-
- (define-key menumap [save-url]
- '("Save URL to kill-ring" . mu4e-view-save-url))
- (define-key menumap [fetch-url]
- '("Fetch URL" . mu4e-view-fetch-url))
- (define-key menumap [goto-url]
- '("Visit URL" . mu4e-view-go-to-url))
-
- (define-key menumap [sepa1] '("--"))
- (define-key menumap [mark-delete]
- '("Mark for deletion" . mu4e-view-mark-for-delete))
- (define-key menumap [mark-trash]
- '("Mark for trash" . mu4e-view-mark-for-trash))
- (define-key menumap [mark-move]
- '("Mark for move" . mu4e-view-mark-for-move))
-
- (define-key menumap [sepa2] '("--"))
- (define-key menumap [resend] '("Resend" . mu4e-compose-resend))
- (define-key menumap [forward] '("Forward" . mu4e-compose-forward))
- (define-key menumap [reply] '("Reply" . mu4e-compose-reply))
- (define-key menumap [compose-new] '("Compose new" . mu4e-compose-new))
- (define-key menumap [sepa3] '("--"))
-
- (define-key menumap [query-next]
- '("Next query" . mu4e-headers-query-next))
- (define-key menumap [query-prev]
- '("Previous query" . mu4e-headers-query-prev))
- (define-key menumap [narrow-search]
- '("Narrow search" . mu4e-headers-search-narrow))
- (define-key menumap [bookmark]
- '("Search bookmark" . mu4e-headers-search-bookmark))
- (define-key menumap [jump]
- '("Jump to maildir" . mu4e~headers-jump-to-maildir))
- (define-key menumap [search]
- '("Search" . mu4e-headers-search))
-
- (define-key menumap [sepa4] '("--"))
- (define-key menumap [next] '("Next" . mu4e-view-headers-next))
- (define-key menumap [previous] '("Previous" . mu4e-view-headers-prev)))
- map)))
-
-(fset 'mu4e-view-mode-map mu4e-view-mode-map)
-
-(defcustom mu4e-view-mode-hook nil
- "Hook run when entering Mu4e-View mode."
- :options '(turn-on-visual-line-mode)
- :type 'hook
- :group 'mu4e-view)
-
-(defvar mu4e-view-mode-abbrev-table nil)
-(define-derived-mode mu4e-view-mode special-mode "mu4e:view"
- "Major mode for viewing an e-mail message in mu4e.
-\\{mu4e-view-mode-map}."
- (use-local-map mu4e-view-mode-map)
-
- (make-local-variable 'mu4e~view-headers-buffer)
- (make-local-variable 'mu4e~view-msg)
- (make-local-variable 'mu4e~view-link-map)
- (make-local-variable 'mu4e~view-attach-map)
- (make-local-variable 'mu4e~view-cited-hidden)
-
- ;; show context in mode-string
- (set (make-local-variable 'global-mode-string) '(:eval (mu4e-context-label)))
-
- (setq buffer-undo-list t);; don't record undo info
-
- ;; autopair mode gives error when pressing RET
- ;; turn it off
- (when (boundp 'autopair-dont-activate)
- (setq autopair-dont-activate t)))
-
-(defun mu4e~view-mark-as-read-maybe (msg)
- "Clear the message MSG New/Unread status and set it to Seen.
-If the message is not New/Unread, do nothing. Evaluates to t if it
-triggers any changes, nil otherwise. If this function does any
-changes, it triggers a refresh."
- (when (and mu4e-view-auto-mark-as-read msg)
- (let ((flags (mu4e-message-field msg :flags))
- (msgid (mu4e-message-field msg :message-id))
- (docid (mu4e-message-field msg :docid)))
- ;; attached (embedded) messages don't have docids; leave them alone if it is a new message
- (when (and docid (or (member 'unread flags) (member 'new flags)))
- ;; mark /all/ messages with this message-id as read, so all copies of
- ;; this message will be marked as read.
- (mu4e~proc-move msgid nil "+S-u-N")
- t))))
-
-(defun mu4e~view-browse-url-func (url)
- "Return a function that executes `browse-url' with URL.
-What browser is called is depending on
-`browse-url-browser-function' and `browse-url-mailto-function'."
- (save-match-data
- (if (string-match "^mailto:" url)
- (lexical-let ((url url))
- (lambda ()
- (interactive)
- (mu4e~compose-browse-url-mail url)))
- (lexical-let ((url url))
- (lambda ()
- (interactive)
- (browse-url url))))))
-
-(defun mu4e~view-browse-url-from-binding (&optional url)
- "View in browser the url at point, or click location.
-If the optional argument URL is provided, browse that instead.
-If the url is mailto link, start writing an email to that address."
- (interactive)
- (let* (( url (or url (mu4e~view-get-property-from-event 'mu4e-url))))
- (when url
- (if (string-match-p "^mailto:" url)
- (mu4e~compose-browse-url-mail url)
- (browse-url url)))))
-
-(defun mu4e~view-show-images-maybe (msg)
- "Show attached images, if `mu4e-show-images' is non-nil."
- (when (and (display-images-p) mu4e-view-show-images)
- (mu4e-view-for-each-part msg
- (lambda (msg part)
- (when (string-match "^image/"
- (or (mu4e-message-part-field part :mime-type)
- "application/object-stream"))
- (let ((imgfile (mu4e-message-part-field part :temp)))
- (when (and imgfile (file-exists-p imgfile))
- (save-excursion
- (goto-char (point-max))
- (mu4e-display-image imgfile
- mu4e-view-image-max-width
- mu4e-view-image-max-height)))))))))
-
-
-(defvar mu4e~view-beginning-of-url-regexp
- "https?\\://\\|mailto:"
- "Regexp that matches the beginning of http:/https:/mailto:
-URLs; match-string 1 will contain the matched URL, if any.")
-
-;; this is fairly simplistic...
-(defun mu4e~view-make-urls-clickable ()
- "Turn things that look like URLs into clickable things.
-Also number them so they can be opened using `mu4e-view-go-to-url'."
- (let ((num 0))
- (save-excursion
- (setq mu4e~view-link-map ;; buffer local
- (make-hash-table :size 32 :weakness nil))
- (goto-char (point-min))
- (while (re-search-forward mu4e~view-beginning-of-url-regexp nil t)
- (let ((bounds (thing-at-point-bounds-of-url-at-point)))
- (when bounds
- (let* ((url (thing-at-point-url-at-point))
- (ov (make-overlay (car bounds) (cdr bounds))))
- (puthash (incf num) url mu4e~view-link-map)
- (add-text-properties
- (car bounds)
- (cdr bounds)
- `(face mu4e-link-face
- mouse-face highlight
- mu4e-url ,url
- keymap ,mu4e-view-clickable-urls-keymap
- help-echo
- "[mouse-1] or [M-RET] to open the link"))
- (overlay-put ov 'after-string
- (propertize (format "[%d]" num)
- 'face 'mu4e-url-number-face)))))))))
-
-
-(defun mu4e~view-hide-cited ()
- "Toggle hiding of cited lines in the message body."
- (save-excursion
- (let ((inhibit-read-only t))
- (goto-char (point-min))
- (flush-lines mu4e-cited-regexp)
- (setq mu4e~view-cited-hidden t))))
-
-(defmacro mu4e~view-in-headers-context (&rest body)
- "Evaluate BODY in the context of the headers buffer connected to
-this view."
- `(progn
- (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))
- (curwin (selected-window)))
- (unless docid
- (mu4e-error "message without docid: action is not possible."))
- (with-current-buffer mu4e~view-headers-buffer
- (when (get-buffer-window)
- (select-window (get-buffer-window)))
- (if (mu4e~headers-goto-docid docid)
- ,@body
- (mu4e-error "cannot find message in headers buffer."))))))
-
-(defun mu4e-view-headers-next (&optional n)
- "Move point to the next message header in the headers buffer
-connected with this message view. If this succeeds, return the new
-docid. Otherwise, return nil. Optionally, takes an integer
-N (prefix argument), to the Nth next header."
- (interactive "P")
- (mu4e~view-in-headers-context
- (mu4e~headers-move (or n 1))))
-
-(defun mu4e-view-headers-prev (&optional n)
- "Move point to the previous message header in the headers buffer
-connected with this message view. If this succeeds, return the new
-docid. Otherwise, return nil. Optionally, takes an integer
-N (prefix argument), to the Nth previous header."
- (interactive "P")
- (mu4e~view-in-headers-context
- (mu4e~headers-move (- (or n 1)))))
-
-(defun mu4e~view-prev-or-next-unread (backwards)
- "Move point to the next or previous (when BACKWARDS is non-`nil')
-unread message header in the headers buffer connected with this
-message view. If this succeeds, return the new docid. Otherwise,
-return nil."
- (mu4e~view-in-headers-context
- (mu4e~headers-prev-or-next-unread backwards))
- (mu4e-select-other-view)
- (mu4e-headers-view-message))
-
-(defun mu4e-view-headers-prev-unread ()
-"Move point to the previous unread message header in the headers
-buffer connected with this message view. If this succeeds, return
-the new docid. Otherwise, return nil."
- (interactive)
- (mu4e~view-prev-or-next-unread t))
-
-(defun mu4e-view-headers-next-unread ()
- "Move point to the next unread message header in the headers
-buffer connected with this message view. If this succeeds, return
-the new docid. Otherwise, return nil."
- (interactive)
- (mu4e~view-prev-or-next-unread nil))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; Interactive functions
-
-(defun mu4e-view-toggle-hide-cited ()
- "Toggle hiding of cited lines in the message body."
- (interactive)
- (if mu4e~view-cited-hidden
- (mu4e-view-refresh)
- (mu4e~view-hide-cited)))
-
-(defun mu4e-view-toggle-html ()
- "Toggle html-display of the message body (if any)."
- (interactive)
- (setq mu4e-view-prefer-html (not mu4e-view-prefer-html))
- (mu4e-view-refresh))
-
-(defun mu4e-view-refresh ()
- "Redisplay the current message."
- (interactive)
- (mu4e-view mu4e~view-msg mu4e~view-headers-buffer)
- (setq mu4e~view-cited-hidden nil))
-
-(defun mu4e-view-action (&optional msg)
- "Ask user for some action to apply on MSG, then do it.
-If MSG is nil apply action to message returned
-bymessage-at-point. The actions are specified in
-`mu4e-view-actions'."
- (interactive)
- (let* ((msg (or msg (mu4e-message-at-point)))
- (actionfunc (mu4e-read-option "Action: " mu4e-view-actions)))
- (funcall actionfunc msg)))
-
-(defun mu4e-view-mark-pattern ()
- "Ask user for a kind of mark (move, delete etc.), a field to
-match and a regular expression to match with. Then, mark all
-matching messages with that mark."
- (interactive)
- (mu4e~view-in-headers-context (mu4e-headers-mark-pattern)))
-
-(defun mu4e-view-mark-thread (&optional markpair)
- "Ask user for a kind of mark (move, delete etc.), and apply it
-to all messages in the thread at point in the headers view. The
-optional MARKPAIR can also be used to provide the mark
-selection."
- (interactive)
- (mu4e~view-in-headers-context
- (if markpair (mu4e-headers-mark-thread nil markpair)
- (call-interactively 'mu4e-headers-mark-thread))))
-
-(defun mu4e-view-mark-subthread (&optional markpair)
- "Ask user for a kind of mark (move, delete etc.), and apply it
-to all messages in the subthread at point in the headers view.
-The optional MARKPAIR can also be used to provide the mark
-selection."
- (interactive)
- (mu4e~view-in-headers-context
- (if markpair (mu4e-headers-mark-subthread markpair)
- (mu4e-headers-mark-subthread))))
-
-(defun mu4e-view-search-narrow ()
- "Run `mu4e-headers-search-narrow' in the headers buffer."
- (interactive)
- (mu4e~view-in-headers-context
- (call-interactively 'mu4e-headers-search-narrow)))
-
-(defun mu4e-view-search-edit ()
- "Run `mu4e-headers-search-edit' in the headers buffer."
- (interactive)
- (mu4e~view-in-headers-context (mu4e-headers-search-edit)))
-
-(defun mu4e-mark-region-code ()
- "Highlight region marked with `message-mark-inserted-region'.
-Add this function to `mu4e-view-mode-hook' to enable this feature."
- (require 'message)
- (let (beg end ov-beg ov-end ov-inv)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward
- (concat "^" message-mark-insert-begin) nil t)
- (setq ov-beg (match-beginning 0)
- ov-end (match-end 0)
- ov-inv (make-overlay ov-beg ov-end)
- beg ov-end)
- (overlay-put ov-inv 'invisible t)
- (when (re-search-forward
- (concat "^" message-mark-insert-end) nil t)
- (setq ov-beg (match-beginning 0)
- ov-end (match-end 0)
- ov-inv (make-overlay ov-beg ov-end)
- end ov-beg)
- (overlay-put ov-inv 'invisible t))
- (when (and beg end)
- (let ((ov (make-overlay beg end)))
- (overlay-put ov 'face 'mu4e-region-code))
- (setq beg nil end nil))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Wash functions
-(defun mu4e-view-fill-long-lines ()
- "Fill lines that are wider than the window width or `fill-column'."
- (interactive)
- (with-current-buffer mu4e~view-buffer
- (save-excursion
- (let ((inhibit-read-only t)
- (width (window-width (get-buffer-window (current-buffer)))))
- (save-restriction
- (message-goto-body)
- (while (not (eobp))
- (end-of-line)
- (when (>= (current-column) (min fill-column width))
- (narrow-to-region (min (1+ (point)) (point-max))
- (point-at-bol))
- (let ((goback (point-marker)))
- (fill-paragraph nil)
- (goto-char (marker-position goback)))
- (widen))
- (forward-line 1)))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; attachment handling
-(defun mu4e~view-get-attach-num (prompt msg &optional multi)
- "Ask the user with PROMPT for an attachment number for MSG, and
-ensure it is valid. The number is [1..n] for attachments
-\[0..(n-1)] in the message. If MULTI is nil, return the number for
-the attachment; otherwise (MULTI is non-nil), accept ranges of
-attachment numbers, as per `mu4e-split-ranges-to-numbers', and
-return the corresponding string."
- (let* ((count (hash-table-count mu4e~view-attach-map)) (def))
- (when (zerop count) (mu4e-error "No attachments for this message"))
- (if (not multi)
- (if (= count 1)
- (read-number (mu4e-format "%s: " prompt) 1)
- (read-number (mu4e-format "%s (1-%d): " prompt count)))
- (progn
- (setq def (if (= count 1) "1" (format "1-%d" count)))
- (read-string (mu4e-format "%s (default %s): " prompt def)
- nil nil def)))))
-
-(defun mu4e~view-get-attach (msg attnum)
- "Return the attachment plist in MSG corresponding to attachment
-number ATTNUM."
- (let* ((partid (gethash attnum mu4e~view-attach-map))
- (attach
- (find-if
- (lambda (part)
- (eq (mu4e-message-part-field part :index) partid))
- (mu4e-message-field msg :parts))))
- (or attach (mu4e-error "Not a valid attachment"))))
-
-
-(defun mu4e~view-request-attachment-path (fname path)
- "Ask the user where to save FNAME (default is PATH/FNAME)."
- (let ((fpath (expand-file-name
- (read-file-name
- (mu4e-format "Save as ")
- path nil nil fname) path)))
- (if (file-directory-p fpath)
- (expand-file-name fname fpath)
- fpath)))
-
-(defun mu4e~view-request-attachments-dir (path)
- "Ask the user where to save multiple attachments (default is PATH)."
- (let ((fpath (expand-file-name
- (read-directory-name
- (mu4e-format "Save in directory ")
- path nil nil nil) path)))
- (if (file-directory-p fpath)
- fpath)))
-
-(defun mu4e-view-save-attachment-single (&optional msg attnum)
- "Save attachment number ATTNUM from MSG.
-If MSG is nil use the message returned by `message-at-point'.
-If ATTNUM is nil ask for the attachment number."
- (interactive)
- (let* ((msg (or msg (mu4e-message-at-point)))
- (attnum (or attnum
- (mu4e~view-get-attach-num "Attachment to save" msg)))
- (att (mu4e~view-get-attach msg attnum))
- (fname (plist-get att :name))
- (mtype (plist-get att :mime-type))
- (path (concat
- (mu4e~get-attachment-dir fname mtype) "/"))
- (index (plist-get att :index))
- (retry t) (fpath))
- (while retry
- (setq fpath (mu4e~view-request-attachment-path fname path))
- (setq retry
- (and (file-exists-p fpath)
- (not (y-or-n-p (mu4e-format "Overwrite '%s'?" fpath))))))
- (mu4e~proc-extract
- 'save (mu4e-message-field msg :docid)
- index mu4e-decryption-policy fpath)))
-
-
-(defun mu4e-view-save-attachment-multi (&optional msg)
- "Offer to save multiple email attachments from the current message.
-Default is to save all messages, [1..n], where n is the number of
-attachments. You can type multiple values separated by space, e.g.
- 1 3-6 8
-will save attachments 1,3,4,5,6 and 8.
-
-Furthermore, there is a shortcut \"a\" which so means all
-attachments, but as this is the default, you may not need it."
- (interactive)
- (let* ((msg (or msg (mu4e-message-at-point)))
- (attachstr (mu4e~view-get-attach-num
- "Attachment number range (or 'a' for 'all')" msg t))
- (count (hash-table-count mu4e~view-attach-map))
- (attachnums (mu4e-split-ranges-to-numbers attachstr count)))
- (if mu4e-save-multiple-attachments-without-asking
- (let* ((path (concat (mu4e~get-attachment-dir) "/"))
- (attachdir (mu4e~view-request-attachments-dir path)))
- (dolist (num attachnums)
- (let* ((att (mu4e~view-get-attach msg num))
- (fname (plist-get att :name))
- (index (plist-get att :index))
- (retry t)
- fpath)
- (while retry
- (setq fpath (expand-file-name (concat attachdir fname) path))
- (setq retry
- (and (file-exists-p fpath)
- (not (y-or-n-p
- (mu4e-format "Overwrite '%s'?" fpath))))))
- (mu4e~proc-extract
- 'save (mu4e-message-field msg :docid)
- index mu4e-decryption-policy fpath))))
- (dolist (num attachnums)
- (mu4e-view-save-attachment-single msg num)))))
-
-(defun mu4e-view-save-attachment (&optional multi)
- "Offer to save attachment(s).
-If MULTI (prefix-argument) is nil, save a single one, otherwise,
-offer to save a range of attachments."
- (interactive "P")
- (if multi
- (mu4e-view-save-attachment-multi)
- (mu4e-view-save-attachment-single)))
-
-(defun mu4e-view-open-attachment (&optional msg attnum)
- "Open attachment number ATTNUM from MSG.
-If MSG is nil use the message returned by `message-at-point'.
-If ATTNUM is nil ask for the attachment number."
- (interactive)
- (let* ((msg (or msg (mu4e-message-at-point)))
- (attnum (or attnum
- (mu4e~view-get-attach-num "Attachment to open" msg)))
- (att (or (mu4e~view-get-attach msg attnum)))
- (index (plist-get att :index))
- (docid (mu4e-message-field msg :docid))
- (mimetype (plist-get att :mime-type)))
- (if (and mimetype (string= mimetype "message/rfc822"))
- ;; special handling for message-attachments; we open them in mu4e. we also
- ;; send the docid as parameter (4th arg); we'll get this back from the
- ;; server, and use it to determine the parent message (ie., the current
- ;; message) when showing the embedded message/rfc822, and return to the
- ;; current message when quitting that one.
- (mu4e~view-temp-action docid index "mu4e" docid)
- ;; otherwise, open with the default program (handled in mu-server
- (mu4e~proc-extract 'open docid index mu4e-decryption-policy))))
-
-
-(defun mu4e~view-temp-action (docid index what &optional param)
- "Open attachment INDEX for message with DOCID, and invoke ACTION."
- (interactive)
- (mu4e~proc-extract 'temp docid index mu4e-decryption-policy nil what param ))
-
-(defvar mu4e~view-open-with-hist nil "History list for the open-with argument.")
-
-(defun mu4e-view-open-attachment-with (msg attachnum &optional cmd)
- "Open MSG's attachment ATTACHNUM with CMD.
-If CMD is nil, ask user for it."
- (interactive)
- (let* ((att (mu4e~view-get-attach msg attachnum))
- (cmd (or cmd
- (read-string
- (mu4e-format "Shell command to open it with: ")
- nil 'mu4e~view-open-with-hist)))
- (index (plist-get att :index)))
- (mu4e~view-temp-action
- (mu4e-message-field msg :docid) index "open-with" cmd)))
-
-(defvar mu4e~view-pipe-hist nil
- "History list for the pipe argument.")
-
-(defun mu4e-view-pipe-attachment (msg attachnum &optional pipecmd)
- "Feed MSG's attachment ATTACHNUM through pipe PIPECMD.
-If PIPECMD is nil, ask user for it."
- (interactive)
- (let* ((att (mu4e~view-get-attach msg attachnum))
- (pipecmd (or pipecmd
- (read-string
- (mu4e-format "Pipe: ")
- nil
- 'mu4e~view-pipe-hist)))
- (index (plist-get att :index)))
- (mu4e~view-temp-action
- (mu4e-message-field msg :docid) index "pipe" pipecmd)))
-
-
-(defun mu4e-view-open-attachment-emacs (msg attachnum)
- "Open MSG's attachment ATTACHNUM in the current emacs instance."
- (interactive)
- (let* ((att (mu4e~view-get-attach msg attachnum))
- (index (plist-get att :index)))
- (mu4e~view-temp-action (mu4e-message-field msg :docid) index "emacs")))
-
-(defun mu4e-view-import-attachment-diary (msg attachnum)
- "Open MSG's attachment ATTACHNUM in the current emacs instance."
- (interactive)
- (let* ((att (mu4e~view-get-attach msg attachnum))
- (index (plist-get att :index)))
- (mu4e~view-temp-action (mu4e-message-field msg :docid) index "diary")))
-
-(defun mu4e-view-attachment-action (&optional msg)
- "Ask user what to do with attachments in MSG
-If MSG is nil use the message returned by `message-at-point'.
-The actions are specified in `mu4e-view-attachment-actions'."
- (interactive)
- (let* ((msg (or msg (mu4e-message-at-point)))
- (actionfunc (mu4e-read-option
- "Action on attachment: "
- mu4e-view-attachment-actions))
- (attnum (mu4e~view-get-attach-num "Which attachment" msg)))
- (when (and actionfunc attnum)
- (funcall actionfunc msg attnum))))
-
-;; handler-function to handle the response we get from the server when we
-;; want to do something with one of the attachments.
-(defun mu4e~view-temp-handler (path what docid param)
- "Handler function for doing things with temp files (ie.,
-attachments) in response to a (mu4e~proc-extract 'temp ... )."
- (cond
- ((string= what "open-with")
- ;; 'param' will be the program to open-with
- (start-process "*mu4e-open-with-proc*" "*mu4e-open-with*" param path))
- ((string= what "pipe")
- ;; 'param' will be the pipe command, path the infile for this
- (mu4e-process-file-through-pipe path param))
- ;; if it's mu4e, it's some embedded message; 'param' may contain the docid
- ;; of the parent message.
- ((string= what "mu4e")
- ;; remember the mapping path->docid, which maps the path of the embedded
- ;; message to the docid of its parent
- (puthash path docid mu4e~path-parent-docid-map)
- (mu4e~proc-view-path path mu4e-view-show-images mu4e-decryption-policy))
- ((string= what "emacs")
- (find-file path)
- ;; make the buffer read-only since it usually does not make
- ;; sense to edit the temp buffer; use C-x C-q if you insist...
- (setq buffer-read-only t))
- ((string= what "diary")
- (icalendar-import-file path diary-file))
- (t (mu4e-error "Unsupported action %S" what))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun mu4e-view-mark-custom ()
- "Run some custom mark function."
- (mu4e~view-in-headers-context
- (mu4e-headers-mark-custom)))
-
-(defun mu4e~view-split-view-p ()
- "Return t if we're in split-view, nil otherwise."
- (member mu4e-split-view '(horizontal vertical)))
-
-(defun mu4e-view-scroll-up-or-next ()
- "Scroll-up the current message.
-If `mu4e-view-scroll-to-next' is non-nil, and we can't scroll-up
-anymore, go the next message."
- (interactive)
- (condition-case nil
- (scroll-up)
- (error
- (when mu4e-view-scroll-to-next
- (mu4e-view-headers-next)))))
-
-(defun mu4e-scroll-up ()
- "Scroll text of selected window up one line."
- (interactive)
- (scroll-up 1))
-
-(defun mu4e-scroll-down ()
- "Scroll text of selected window down one line."
- (interactive)
- (scroll-down 1))
-
-(defun mu4e-view-unmark-all ()
- "If we're in split-view, unmark all messages.
-Otherwise, warn user that unmarking only works in the header
-list."
- (interactive)
- (if (mu4e~view-split-view-p)
- (mu4e~view-in-headers-context (mu4e-mark-unmark-all))
- (mu4e-message "Unmarking needs to be done in the header list view")))
-
-(defun mu4e-view-unmark ()
- "If we're in split-view, unmark message at point.
-Otherwise, warn user that unmarking only works in the header
-list."
- (interactive)
- (if (mu4e~view-split-view-p)
- (mu4e-view-mark-for-unmark)
- (mu4e-message "Unmarking needs to be done in the header list view")))
-
-
-(defmacro mu4e~view-defun-mark-for (mark)
- "Define a function mu4e-view-mark-for-MARK."
- (let ((funcname (intern (format "mu4e-view-mark-for-%s" mark)))
- (docstring (format "Mark the current message for %s." mark)))
- `(progn
- (defun ,funcname () ,docstring
- (interactive)
- (mu4e~view-in-headers-context
- (mu4e-headers-mark-and-next ',mark)))
- (put ',funcname 'definition-name ',mark))))
-
-(mu4e~view-defun-mark-for move)
-(mu4e~view-defun-mark-for trash)
-(mu4e~view-defun-mark-for refile)
-(mu4e~view-defun-mark-for delete)
-(mu4e~view-defun-mark-for flag)
-(mu4e~view-defun-mark-for unflag)
-(mu4e~view-defun-mark-for unmark)
-(mu4e~view-defun-mark-for something)
-(mu4e~view-defun-mark-for read)
-(mu4e~view-defun-mark-for unread)
-
-(defun mu4e-view-marked-execute ()
- "Execute the marks."
- (interactive)
- (mu4e~view-in-headers-context
- (mu4e-mark-execute-all)))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; URL handling
-(defun mu4e~view-get-urls-num (prompt &optional multi)
- "Ask the user with PROMPT for an URL number for MSG, and ensure
-it is valid. The number is [1..n] for URLs \[0..(n-1)] in the
-message. If MULTI is nil, return the number for the URL;
-otherwise (MULTI is non-nil), accept ranges of URL numbers, as
-per `mu4e-split-ranges-to-numbers', and return the corresponding
-string."
- (let* ((count (hash-table-count mu4e~view-link-map)) (def))
- (when (zerop count) (mu4e-error "No links for this message"))
- (if (not multi)
- (if (= count 1)
- (read-number (mu4e-format "%s: " prompt) 1)
- (read-number (mu4e-format "%s (1-%d): " prompt count)))
- (progn
- (setq def (if (= count 1) "1" (format "1-%d" count)))
- (read-string (mu4e-format "%s (default %s): " prompt def)
- nil nil def)))))
-
-(defun mu4e-view-go-to-url (&optional multi)
- "Offer to go to url(s). If MULTI (prefix-argument) is nil, go to
-a single one, otherwise, offer to go to a range of urls."
- (interactive "P")
- (mu4e~view-handle-urls "URL to visit"
- multi (lambda (url) (mu4e~view-browse-url-from-binding url))))
-
-(defun mu4e-view-save-url (&optional multi)
- "Offer to save urls(s) to the kill-ring. If
-MULTI (prefix-argument) is nil, save a single one, otherwise, offer
-to save a range of URLs."
- (interactive "P")
- (mu4e~view-handle-urls "URL to save" multi
- (lambda (url)
- (kill-new url)
- (mu4e-message "Saved %s to the kill-ring" url))))
-
-(defun mu4e-view-fetch-url (&optional multi)
- "Offer to fetch (download) urls(s). If MULTI (prefix-argument) is nil,
-download a single one, otherwise, offer to fetch a range of
-URLs. The urls are fetched to `mu4e-attachment-dir'."
- (interactive "P")
- (mu4e~view-handle-urls "URL to fetch" multi
- (lambda (url)
- (let ((target (concat (mu4e~get-attachment-dir url) "/"
- (file-name-nondirectory url))))
- (url-copy-file url target)
- (mu4e-message "Fetched %s -> %s" url target)))))
-
-(defun mu4e~view-handle-urls (prompt multi urlfunc)
- "If MULTI is nil, apply URLFUNC to a single uri, otherwise, apply
-it to a range of uris. PROMPT is the query to present to the user."
- (interactive "P")
- (if multi
- (mu4e~view-handle-multi-urls prompt urlfunc)
- (mu4e~view-handle-single-url prompt urlfunc)))
-
-(defun mu4e~view-handle-single-url (prompt urlfunc &optional num)
- "Apply URLFUNC to url NUM in the current message, prompting the
-user with PROMPT."
- (interactive)
- (let* ((num (or num (mu4e~view-get-urls-num prompt)))
- (url (gethash num mu4e~view-link-map)))
- (unless url (mu4e-warn "Invalid number for URL"))
- (funcall urlfunc url)))
-
-(defun mu4e~view-handle-multi-urls (prompt urlfunc)
- "Apply URLFUNC to a a range of urls in the current message,
-prompting the user with PROMPT.
-
-Default is to aplly it to all URLs, [1..n], where n is the number
-of urls. You can type multiple values separated by space, e.g. 1
-3-6 8 will visit urls 1,3,4,5,6 and 8.
-
-Furthermore, there is a shortcut \"a\" which means all urls, but as
-this is the default, you may not need it."
- (interactive)
- (let* ((linkstr (mu4e~view-get-urls-num
- "URL number range (or 'a' for 'all')" t))
- (count (hash-table-count mu4e~view-link-map))
- (linknums (mu4e-split-ranges-to-numbers linkstr count)))
- (dolist (num linknums)
- (mu4e~view-handle-single-url prompt urlfunc num))))
-
-(defun mu4e-view-for-each-uri (func)
- "Execute FUNC (which receives a uri) for each uri in the current
- message."
- (maphash (lambda (num uri) (funcall func uri)) mu4e~view-link-map))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defconst mu4e~view-raw-buffer-name " *mu4e-raw-view*"
- "*internal* Name for the raw message view buffer")
-
-(defun mu4e-view-raw-message ()
- "Display the raw contents of message at point in a new buffer."
- (interactive)
- (let ((path (mu4e-message-field-at-point :path))
- (buf (get-buffer-create mu4e~view-raw-buffer-name)))
- (unless (and path (file-readable-p path))
- (mu4e-error "Not a readable file: %S" path))
- (with-current-buffer buf
- (let ((inhibit-read-only t))
- (erase-buffer)
- (insert-file-contents path)
- (view-mode)
- (goto-char (point-min))))
- (switch-to-buffer buf)))
-
-(defun mu4e-view-pipe (cmd)
- "Pipe the message at point through shell command CMD, and display
-the results."
- (interactive "sShell command: ")
- (let ((path (mu4e-message-field (mu4e-message-at-point) :path)))
- (mu4e-process-file-through-pipe path cmd)))
-
-(defconst mu4e~verify-buffer-name " *mu4e-verify*")
-
-(defun mu4e-view-verify-msg-popup (&optional msg)
- "Pop-up a little signature verification window for (optional) MSG
-or message-at-point."
- (interactive)
- (let* ((msg (or msg (mu4e-message-at-point)))
- (path (mu4e-message-field msg :path))
- (cmd (format "%s verify --verbose %s %s"
- mu4e-mu-binary
- (shell-quote-argument path)
- (if mu4e-decryption-policy
- "--decrypt --use-agent"
- "")))
- (output (shell-command-to-string cmd))
- ;; create a new one
- (buf (get-buffer-create mu4e~verify-buffer-name))
- (win (or (get-buffer-window buf)
- (split-window-vertically (- (window-height) 6)))))
- (with-selected-window win
- (let ((inhibit-read-only t))
- ;; (set-window-dedicated-p win t)
- (switch-to-buffer buf)
- (erase-buffer)
- (insert output)
- (goto-char (point-min))
- (local-set-key "q" 'kill-buffer-and-window))
- (setq buffer-read-only t))
- (select-window win)))
-
-
-(defun mu4e~view-quit-buffer ()
- "Quit the mu4e-view buffer.
-This is a rather complex function, to ensure we don't disturb
-other windows."
- (interactive)
- (unless (eq major-mode 'mu4e-view-mode)
- (mu4e-error "Must be in mu4e-view-mode (%S)" major-mode))
- (let ((curbuf (current-buffer)) (curwin (selected-window))
- (headers-win))
- (walk-windows
- (lambda (win)
- ;; check whether the headers buffer window is visible
- (when (eq mu4e~view-headers-buffer (window-buffer win))
- (setq headers-win win))
- ;; and kill any _other_ (non-selected) window that shows the current
- ;; buffer
- (when
- (and
- (eq curbuf (window-buffer win)) ;; does win show curbuf?
- (not (eq curwin win)) ;; but it's not the curwin?
- (not (one-window-p))) ;; and not the last one on the frame?
- (delete-window win)))) ;; delete it!
- ;; now, all *other* windows should be gone.
- ;; if the headers view is also visible, kill ourselves + window; otherwise
- ;; switch to the headers view
- (if (window-live-p headers-win)
- ;; headers are visible
- (progn
- (kill-buffer-and-window) ;; kill the view win
- (setq mu4e~headers-view-win nil)
- (select-window headers-win)) ;; and switch to the headers win...
- ;; headers are not visible...
- (progn
- (kill-buffer)
- (setq mu4e~headers-view-win nil)
- (when (buffer-live-p mu4e~view-headers-buffer)
- (switch-to-buffer mu4e~view-headers-buffer))))))
-
-(provide 'mu4e-view)
-;; end of mu4e-view
diff --git a/_spacemacs.d/local/mu4e/mu4e.el b/_spacemacs.d/local/mu4e/mu4e.el
deleted file mode 100644
index b605cb9..0000000
--- a/_spacemacs.d/local/mu4e/mu4e.el
+++ /dev/null
@@ -1,102 +0,0 @@
-;;; mu4e.el --- part of mu4e, the mu mail user agent
-;;
-;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Keywords: email
-;; Version: 0.0
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-
-(require 'mu4e-meta) ;; autogenerated file with metadata (version etc.)
-(require 'mu4e-headers) ;; headers view
-(require 'mu4e-view) ;; message view
-(require 'mu4e-main) ;; main screen
-(require 'mu4e-compose) ;; message composition / sending
-(require 'mu4e-proc) ;; communication with backend
-(require 'mu4e-utils) ;; utility functions
-(require 'mu4e-context) ;; support for contexts
-(require 'mu4e-speedbar) ;; support for speedbar
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; we can't properly use compose buffers that are revived using
-;; desktop-save-mode; so let's turn that off
-(require 'desktop)
-(add-to-list 'desktop-modes-not-to-save 'mu4e-compose-mode)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; register our handler functions; these connect server messages to functions
-;; to handle them.
-;;
-;;
-;; these are all defined in mu4e-headers
-(setq mu4e-update-func 'mu4e~headers-update-handler)
-(setq mu4e-header-func 'mu4e~headers-header-handler)
-(setq mu4e-found-func 'mu4e~headers-found-handler)
-(setq mu4e-view-func 'mu4e~headers-view-handler)
-(setq mu4e-remove-func 'mu4e~headers-remove-handler)
-(setq mu4e-erase-func 'mu4e~headers-clear)
-
-;; these ones are defined in mu4e-utils
-(setq mu4e-info-func 'mu4e-info-handler)
-(setq mu4e-error-func 'mu4e-error-handler)
-;; note: mu4e-utils also dynamically (temporarily)
-;; registers mu4e-pong func
-
-;; this one is defined in mu4e-compose
-(setq mu4e-compose-func 'mu4e~compose-handler)
-;; note: mu4e-compose.el dynamically registers mu4e-sent-func
-;; we don't do that here, because it's only a local (temporary)
-;; handler
-
-;; this one is defined in mu4e-view
-(setq mu4e-temp-func 'mu4e~view-temp-handler)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;###autoload
-(defun mu4e (&optional background)
- "If mu4e is not running yet, start it. Then, show the main
-window, unless BACKGROUND (prefix-argument) is non-nil."
- (interactive "P")
- ;; start mu4e, then show the main view
- (mu4e~start (unless background 'mu4e~main-view)))
-
-(defun mu4e-quit()
- "Quit the mu4e session."
- (interactive)
- (if mu4e-confirm-quit
- (when (y-or-n-p (mu4e-format "Are you sure you want to quit?"))
- (mu4e~stop))
- (mu4e~stop)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(provide 'mu4e)
-
-;;; mu4e.el ends here
diff --git a/_spacemacs.d/local/mu4e/org-mu4e.el b/_spacemacs.d/local/mu4e/org-mu4e.el
deleted file mode 100644
index 545f566..0000000
--- a/_spacemacs.d/local/mu4e/org-mu4e.el
+++ /dev/null
@@ -1,323 +0,0 @@
-;;; org-mu4e -- Support for links to mu4e messages/queries from within
-;;; org-mode, and for writing message in org-mode, sending them as
-;;; rich-text
-;;
-;; Copyright (C) 2012-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Keywords: outlines, hypermedia, calendar, mail
-;; Version: 0.0
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of 1the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-
-;; The expect version here is org 8.x
-
-
-;; the 'noerror is just to make sure bytecompilations does not break...
-;; FIXME: find a better solution
-(require 'org nil 'noerror)
-(require 'org-exp nil 'noerror)
-
-(eval-when-compile (require 'cl))
-(require 'mu4e)
-
-(defgroup org-mu4e nil
- "Settings for the org-mode related functionality in mu4e."
- :group 'mu4e
- :group 'org)
-
-(defvar org-mu4e-link-query-in-headers-mode nil
- "If non-nil, `org-store-link' in `mu4e-headers-mode' links to the
-the current query; otherwise, it links to the message at point.")
-
-(defcustom org-mu4e-link-desc-func
- (lambda (msg) (or (plist-get msg :subject) "No subject"))
- "Function that takes a msg and returns a string for the
-description part of an org-mode link.
-
-Example usage:
-
- (defun my-link-descr (msg)
- (let ((subject (or (plist-get msg :subject)
- \"No subject\"))
- (date (or (format-time-string mu4e-headers-date-format
- (mu4e-msg-field msg :date))
- \"No date\")))
- (concat subject \" \" date)))
-
- (setq org-mu4e-link-desc-func 'my-link-descr)"
- :type 'function
- :group 'org-mu4e)
-
-(defun org-mu4e-store-link ()
- "Store a link to a mu4e query or message."
- (when (member major-mode '(mu4e-headers-mode mu4e-view-mode))
- (if (and (eq major-mode 'mu4e-headers-mode)
- org-mu4e-link-query-in-headers-mode)
- ;; storing links to queries
- (let* ((query (mu4e-last-query))
- desc link)
- (org-store-link-props :type "mu4e" :query query)
- (setq
- desc (concat "mu4e:query:" query)
- link desc)
- (org-add-link-props :link link :description desc)
- link)
- ;; storing links to messages
- (let* ((msg (mu4e-message-at-point))
- (msgid (or (plist-get msg :message-id) "<none>"))
- (from (or (plist-get msg :from) '(("none" . "none"))))
- (fromname (car (car from)))
- (fromaddress (cdr (car from)))
- (to (or (plist-get msg :to) '(("none" . "none"))))
- (toname (car (car to)))
- (toaddress (cdr (car to)))
- (fromto (if (mu4e-user-mail-address-p fromaddress)
- (format "to %s <%s>" toname toaddress)
- (format "from %s <%s>" fromname fromaddress)))
- (date (plist-get msg :date))
- (date-ts (format-time-string (org-time-stamp-format t) date))
- (date-ts-ia (format-time-string (org-time-stamp-format t t) date))
- (subject (or (plist-get msg :subject) "<none>"))
- link)
- (org-store-link-props :type "mu4e" :link link
- :message-id msgid)
- (setq link (concat "mu4e:msgid:" msgid))
- (org-add-link-props :link link
- :to (format "%s <%s>" toname toaddress)
- :toname toname
- :toaddress toaddress
- :from (format "%s <%s>" fromname fromaddress)
- :fromname fromname
- :fromaddress fromaddress
- :fromto fromto
- :date date-ts-ia
- :date-timestamp date-ts
- :date-timestamp-inactive date-ts-ia
- :subject subject
- :description (funcall org-mu4e-link-desc-func msg))
- link))))
-
-(org-add-link-type "mu4e" 'org-mu4e-open)
-(add-hook 'org-store-link-functions 'org-mu4e-store-link)
-
-(defun org-mu4e-open (path)
- "Open the mu4e message (for paths starting with 'msgid:') or run
-the query (for paths starting with 'query:')."
- (cond
- ((string-match "^msgid:\\(.+\\)" path)
- (mu4e-view-message-with-message-id (match-string 1 path)))
- ((string-match "^query:\\(.+\\)" path)
- (mu4e-headers-search (match-string 1 path) current-prefix-arg))
- (t (mu4e-error "mu4e: unrecognized link type '%s'" path))))
-
-(defun org-mu4e-store-and-capture ()
- "Store a link to the current message or query (depending on
-`org-mu4e-link-query-in-headers-mode', and capture it with
-org-mode)."
- (interactive)
- (org-mu4e-store-link)
- (org-capture))
-
-
-
-;;; editing with org-mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; below, some functions for the org->html conversion
-;; based on / inspired by Eric Schulte's org-mime.el
-;; Homepage: http://orgmode.org/worg/org-contrib/org-mime.php
-;;
-;; EXPERIMENTAL
-(defun org~mu4e-mime-file (ext path id)
- "Create a file for an attachment."
- (format (concat "<#part type=\"%s\" filename=\"%s\" "
- "disposition=inline id=\"<%s>\">\n<#/part>\n")
- ext path id))
-
-(defun org~mu4e-mime-multipart (plain html &optional images)
- "Create a multipart/alternative with text/plain and text/html alternatives.
-If the html portion of the message includes images, wrap the html
-and images in a multipart/related part."
- (concat "<#multipart type=alternative><#part type=text/plain>"
- plain
- (when images "<#multipart type=related>")
- "<#part type=text/html>"
- html
- images
- (when images "<#/multipart>\n")
- "<#/multipart>\n"))
-
-(defun org~mu4e-mime-replace-images (str current-file)
- "Replace images in html files with cid links."
- (let (html-images)
- (cons
- (replace-regexp-in-string ;; replace images in html
- "src=\"\\([^\"]+\\)\""
- (lambda (text)
- (format
- "src=\"cid:%s\""
- (let* ((url (and (string-match "src=\"\\([^\"]+\\)\"" text)
- (match-string 1 text)))
- (path (expand-file-name
- url (file-name-directory current-file)))
- (ext (file-name-extension path))
- (id (replace-regexp-in-string "[\/\\\\]" "_" path)))
- (add-to-list 'html-images
- (org~mu4e-mime-file
- (concat "image/" ext) path id))
- id)))
- str)
- html-images)))
-
-(defun org~mu4e-mime-convert-to-html ()
- "Convert the current body to html."
- (unless (fboundp 'org-export-string-as)
- (mu4e-error "require function 'org-export-string-as not found."))
- (let* ((begin
- (save-excursion
- (goto-char (point-min))
- (search-forward mail-header-separator)))
- (end (point-max))
- (raw-body (buffer-substring begin end))
- (tmp-file (make-temp-name (expand-file-name "mail"
- temporary-file-directory)))
- ;; because we probably don't want to skip part of our mail
- (org-export-skip-text-before-1st-heading nil)
- ;; because we probably don't want to export a huge style file
- (org-export-htmlize-output-type 'inline-css)
- ;; makes the replies with ">"s look nicer
- (org-export-preserve-breaks t)
- ;; dvipng for inline latex because MathJax doesn't work in mail
- (org-export-with-LaTeX-fragments
- (if (executable-find "dvipng") 'dvipng
- (mu4e-message "Cannot find dvipng, ignore inline LaTeX") nil))
- ;; to hold attachments for inline html images
- (html-and-images
- (org~mu4e-mime-replace-images
- (org-export-string-as raw-body 'html t)
- tmp-file))
- (html-images (cdr html-and-images))
- (html (car html-and-images)))
- (delete-region begin end)
- (save-excursion
- (goto-char begin)
- (newline)
- (insert (org~mu4e-mime-multipart
- raw-body html (mapconcat 'identity html-images "\n"))))))
-
-;; next some functions to make the org/mu4e-compose-mode switch as smooth as
-;; possible.
-(defun org~mu4e-mime-decorate-headers ()
- "Make the headers visually distinctive (org-mode)."
- (save-excursion
- (goto-char (point-min))
- (let* ((eoh (when (search-forward mail-header-separator)
- (match-end 0)))
- (olay (make-overlay (point-min) eoh)))
- (when olay
- (overlay-put olay 'face 'font-lock-comment-face)))))
-
-(defun org~mu4e-mime-undecorate-headers ()
- "Don't make the headers visually distinctive.
-\(well, mu4e-compose-mode will take care of that)."
- (save-excursion
- (goto-char (point-min))
- (let* ((eoh (when (search-forward mail-header-separator)
- (match-end 0))))
- (remove-overlays (point-min) eoh))))
-
-(defvar org-mu4e-convert-to-html nil
- "Whether to do automatic org-mode => html conversion when sending messages.")
-
-(defun org~mu4e-mime-convert-to-html-maybe ()
- "Convert to html if `org-mu4e-convert-to-html' is non-nil.
-This function is called when sending a message (from
-`message-send-hook') and, if non-nil, will send the message as
-the rich-text version of the what is assumed to be an org-mode
-body."
- (when org-mu4e-convert-to-html
- (mu4e-message "Converting to html")
- (org~mu4e-mime-convert-to-html)))
-
-(defun org~mu4e-mime-switch-headers-or-body ()
- "Switch the buffer to either mu4e-compose-mode (when in headers)
-or org-mode (when in the body)."
- (interactive)
- (let* ((sepapoint
- (save-excursion
- (goto-char (point-min))
- (search-forward-regexp mail-header-separator nil t))))
- ;; only do stuff when the sepapoint exist; note that after sending the
- ;; message, this function maybe called on a message with the sepapoint
- ;; stripped. This is why we don't use `message-point-in-header'.
- (when sepapoint
- (cond
- ;; we're in the body, but in mu4e-compose-mode?
- ;; if so, switch to org-mode
- ((and (> (point) sepapoint) (eq major-mode 'mu4e-compose-mode))
- (org-mode)
- (add-hook 'before-save-hook
- (lambda ()
- (mu4e-error "Switch to mu4e-compose-mode (M-m) before saving."))
- nil t)
- (org~mu4e-mime-decorate-headers)
- (local-set-key (kbd "M-m")
- (lambda (keyseq)
- (interactive "kEnter mu4e-compose-mode key sequence: ")
- (let ((func (lookup-key mu4e-compose-mode-map keyseq)))
- (if func (funcall func) (insert keyseq))))))
- ;; we're in the headers, but in org-mode?
- ;; if so, switch to mu4e-compose-mode
- ((and (<= (point) sepapoint) (eq major-mode 'org-mode))
- (org~mu4e-mime-undecorate-headers)
- (mu4e-compose-mode)
- (add-hook 'message-send-hook 'org~mu4e-mime-convert-to-html-maybe nil t)))
- ;; and add the hook
- (add-hook 'post-command-hook 'org~mu4e-mime-switch-headers-or-body t t))))
-
-
-(defun org-mu4e-compose-org-mode ()
- "Pseudo-Minor mode for mu4e-compose-mode, to edit the message
-body using org-mode."
- (interactive)
- (unless (member major-mode '(org-mode mu4e-compose-mode))
- (mu4e-error "Need org-mode or mu4e-compose-mode"))
- ;; we can check if we're already in org-mu4e-compose-mode by checking if the
- ;; post-command-hook is set; hackish...but a buffer-local variable does not
- ;; seem to survive buffer switching
- (if (not (member 'org~mu4e-mime-switch-headers-or-body post-command-hook))
- (progn
- (org~mu4e-mime-switch-headers-or-body)
- (mu4e-message
- (concat
- "org-mu4e-compose-org-mode enabled; "
- "press M-m before issuing message-mode commands")))
- (progn ;; otherwise, remove crap
- (remove-hook 'post-command-hook 'org~mu4e-mime-switch-headers-or-body t)
- (org~mu4e-mime-undecorate-headers) ;; shut off org-mode stuff
- (mu4e-compose-mode)
- (message "org-mu4e-compose-org-mode disabled"))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(provide 'org-mu4e)
-
-;;; org-mu4e.el ends here
diff --git a/_spacemacs.d/local/mu4e/org-old-mu4e.el b/_spacemacs.d/local/mu4e/org-old-mu4e.el
deleted file mode 100644
index d73a780..0000000
--- a/_spacemacs.d/local/mu4e/org-old-mu4e.el
+++ /dev/null
@@ -1,289 +0,0 @@
-;;; org-mu4e -- Support for links to mu4e messages/queries from within org-mode,
-;;; and for writing message in org-mode, sending them as rich-text
-;;
-;; Copyright (C) 2012-2016 Dirk-Jan C. Binnema
-
-;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
-;; Keywords: outlines, hypermedia, calendar, mail
-;; Version: 0.0
-
-;; This file is not part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-;; This should support org-mode versions 6.x. 7.x
-
-;; the 'noerror is just to make sure bytecompilations does not break...
-;; FIXME: find a better solution
-(require 'org nil 'noerror)
-(require 'org-exp nil 'noerror)
-
-(eval-when-compile (require 'cl))
-(require 'mu4e)
-
-(defgroup org-mu4e nil
- "Settings for the org-mode related functionality in mu4e."
- :group 'mu4e
- :group 'org)
-
-(defcustom org-mu4e-link-desc-func
- (lambda (msg) (or (plist-get msg :subject) "No subject"))
- "Function that takes a msg and returns a string for the
-description part of an org-mode link.
-
-Example usage:
-
- (defun my-link-descr (msg)
- (let ((subject (or (plist-get msg :subject)
- \"No subject\"))
- (date (or (format-time-string mu4e-headers-date-format
- (mu4e-msg-field msg :date))
- \"No date\")))
- (concat subject \" \" date)))
-
- (setq org-mu4e-link-desc-func 'my-link-descr)"
- :type 'function
- :group 'org-mu4e)
-
-(defun org-mu4e-store-link ()
- "Store a link to a mu4e query or message."
- (cond
- ;; storing links to queries
- ((eq major-mode 'mu4e-headers-mode)
- (let* ((query (mu4e-last-query))
- desc link)
- (org-store-link-props :type "mu4e" :query query)
- (setq
- desc (concat "mu4e:query:" query)
- link desc)
- (org-add-link-props :link link :description desc)
- link))
- ;; storing links to messages
- ((eq major-mode 'mu4e-view-mode)
- (let* ((msg (mu4e-message-at-point))
- (msgid (or (plist-get msg :message-id) "<none>"))
- link)
- (org-store-link-props :type "mu4e" :link link
- :message-id msgid)
- (setq link (concat "mu4e:msgid:" msgid))
- (org-add-link-props :link link
- :description (funcall org-mu4e-link-desc-func msg))
- link))))
-
-(org-add-link-type "mu4e" 'org-mu4e-open)
-(add-hook 'org-store-link-functions 'org-mu4e-store-link)
-
-(defun org-mu4e-open (path)
- "Open the mu4e message (for paths starting with 'msgid:') or run
-the query (for paths starting with 'query:')."
- (require 'mu4e)
- (cond
- ((string-match "^msgid:\\(.+\\)" path)
- (mu4e-view-message-with-message-id (match-string 1 path)))
- ((string-match "^query:\\(.+\\)" path)
- (mu4e-headers-search (match-string 1 path) current-prefix-arg))
- (t (mu4e-error "mu4e: unrecognized link type '%s'" path))))
-
-
-
-
-;;; editing with org-mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; below, some functions for the org->html conversion
-;; based on / inspired by Eric Schulte's org-mime.el
-;; Homepage: http://orgmode.org/worg/org-contrib/org-mime.php
-;;
-;; EXPERIMENTAL
-(defun org~mu4e-mime-file (ext path id)
- "Create a file for an attachment."
- (format (concat "<#part type=\"%s\" filename=\"%s\" "
- "disposition=inline id=\"<%s>\">\n<#/part>\n")
- ext path id))
-
-(defun org~mu4e-mime-multipart (plain html &optional images)
- "Create a multipart/alternative with text/plain and text/html alternatives.
-If the html portion of the message includes images, wrap the html
-and images in a multipart/related part."
- (concat "<#multipart type=alternative><#part type=text/plain>"
- plain
- (when images "<#multipart type=related>")
- "<#part type=text/html>"
- html
- images
- (when images "<#/multipart>\n")
- "<#/multipart>\n"))
-
-(defun org~mu4e-mime-replace-images (str current-file)
- "Replace images in html files with cid links."
- (let (html-images)
- (cons
- (replace-regexp-in-string ;; replace images in html
- "src=\"\\([^\"]+\\)\""
- (lambda (text)
- (format
- "src=\"cid:%s\""
- (let* ((url (and (string-match "src=\"\\([^\"]+\\)\"" text)
- (match-string 1 text)))
- (path (expand-file-name
- url (file-name-directory current-file)))
- (ext (file-name-extension path))
- (id (replace-regexp-in-string "[\/\\\\]" "_" path)))
- (add-to-list 'html-images
- (org~mu4e-mime-file
- (concat "image/" ext) path id))
- id)))
- str)
- html-images)))
-
-(defun org~mu4e-mime-convert-to-html ()
- "Convert the current body to html."
- (unless (fboundp 'org-export-string)
- (mu4e-error "require function 'org-export-string not found."))
- (unless (executable-find "dvipng")
- (mu4e-error "Required program dvipng not found"))
- (let* ((begin
- (save-excursion
- (goto-char (point-min))
- (search-forward mail-header-separator)))
- (end (point-max))
- (raw-body (buffer-substring begin end))
- (tmp-file (make-temp-name (expand-file-name "mail"
- temporary-file-directory)))
- (body (org-export-string raw-body 'org
- (file-name-directory tmp-file)))
- ;; because we probably don't want to skip part of our mail
- (org-export-skip-text-before-1st-heading nil)
- ;; because we probably don't want to export a huge style file
- (org-export-htmlize-output-type 'inline-css)
- ;; makes the replies with ">"s look nicer
- (org-export-preserve-breaks t)
- ;; dvipng for inline latex because MathJax doesn't work in mail
- (org-export-with-LaTeX-fragments 'dvipng)
- ;; to hold attachments for inline html images
- (html-and-images
- (org~mu4e-mime-replace-images
- (org-export-string raw-body 'html
- (file-name-directory tmp-file))
- tmp-file))
- (html-images (cdr html-and-images))
- (html (car html-and-images)))
- (delete-region begin end)
- (save-excursion
- (goto-char begin)
- (newline)
- (insert (org~mu4e-mime-multipart
- body html (mapconcat 'identity html-images "\n"))))))
-
-;; next some functions to make the org/mu4e-compose-mode switch as smooth as
-;; possible.
-(defun org~mu4e-mime-decorate-headers ()
- "Make the headers visually distinctive (org-mode)."
- (save-excursion
- (goto-char (point-min))
- (let* ((eoh (when (search-forward mail-header-separator)
- (match-end 0)))
- (olay (make-overlay (point-min) eoh)))
- (when olay
- (overlay-put olay 'face 'font-lock-comment-face)))))
-
-(defun org~mu4e-mime-undecorate-headers ()
- "Don't make the headers visually distinctive.
-\(well, mu4e-compose-mode will take care of that)."
- (save-excursion
- (goto-char (point-min))
- (let* ((eoh (when (search-forward mail-header-separator)
- (match-end 0))))
- (remove-overlays (point-min) eoh))))
-
-(defvar org-mu4e-convert-to-html nil
- "Whether to do automatic org-mode => html conversion when sending messages.")
-
-(defun org~mu4e-mime-convert-to-html-maybe ()
- "Convert to html if `org-mu4e-convert-to-html' is non-nil.
-This function is called when sending a message (from
-`message-send-hook') and, if non-nil, will send the message as
-the rich-text version of the what is assumed to be an org-mode
-body."
- (when org-mu4e-convert-to-html
- (mu4e-message "Converting to html")
- (org~mu4e-mime-convert-to-html)))
-
-(defun org~mu4e-mime-switch-headers-or-body ()
- "Switch the buffer to either mu4e-compose-mode (when in headers)
-or org-mode (when in the body)."
- (interactive)
- (let* ((sepapoint
- (save-excursion
- (goto-char (point-min))
- (search-forward-regexp mail-header-separator nil t))))
- ;; only do stuff when the sepapoint exist; note that after sending the
- ;; message, this function maybe called on a message with the sepapoint
- ;; stripped. This is why we don't use `message-point-in-header'.
- (when sepapoint
- (cond
- ;; we're in the body, but in mu4e-compose-mode?
- ;; if so, switch to org-mode
- ((and (> (point) sepapoint) (eq major-mode 'mu4e-compose-mode))
- (org-mode)
- (add-hook 'before-save-hook
- (lambda ()
- (mu4e-error "Switch to mu4e-compose-mode (M-m) before saving."))
- nil t)
- (org~mu4e-mime-decorate-headers)
- (local-set-key (kbd "M-m")
- (lambda (keyseq)
- (interactive "kEnter mu4e-compose-mode key sequence: ")
- (let ((func (lookup-key mu4e-compose-mode-map keyseq)))
- (if func (funcall func) (insert keyseq))))))
- ;; we're in the headers, but in org-mode?
- ;; if so, switch to mu4e-compose-mode
- ((and (<= (point) sepapoint) (eq major-mode 'org-mode))
- (org~mu4e-mime-undecorate-headers)
- (mu4e-compose-mode)
- (add-hook 'message-send-hook 'org~mu4e-mime-convert-to-html-maybe nil t)))
- ;; and add the hook
- (add-hook 'post-command-hook 'org~mu4e-mime-switch-headers-or-body t t))))
-
-
-(defun org-mu4e-compose-org-mode ()
- "Pseudo-Minor mode for mu4e-compose-mode, to edit the message
-body using org-mode."
- (interactive)
- (unless (member major-mode '(org-mode mu4e-compose-mode))
- (mu4e-error "Need org-mode or mu4e-compose-mode"))
- ;; we can check if we're already in org-mu4e-compose-mode by checking if the
- ;; post-command-hook is set; hackish...but a buffer-local variable does not
- ;; seem to survive buffer switching
- (if (not (member 'org~mu4e-mime-switch-headers-or-body post-command-hook))
- (progn
- (org~mu4e-mime-switch-headers-or-body)
- (mu4e-message
- (concat
- "org-mu4e-compose-org-mode enabled; "
- "press M-m before issuing message-mode commands")))
- (progn ;; otherwise, remove crap
- (remove-hook 'post-command-hook 'org~mu4e-mime-switch-headers-or-body t)
- (org~mu4e-mime-undecorate-headers) ;; shut off org-mode stuff
- (mu4e-compose-mode)
- (message "org-mu4e-compose-org-mode disabled"))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(provide 'org-mu4e)
-
-;;; org-mu4e.el ends here