mirror of
https://github.com/djcb/mu.git
synced 2024-06-21 06:56:48 +02:00
* rename many internal functions to have a mu4e~ prefix (WIP)
- this allows to distinguish between internal and external stuff - the ~ is behind the 'z' in ascii, so last in the completion buffer
This commit is contained in:
parent
2f2853c0dd
commit
927e26ec05
|
@ -38,7 +38,7 @@
|
|||
(require 'mu4e-view)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(defun mu4e--cite-original (msg)
|
||||
(defun mu4e~compose-cite-original (msg)
|
||||
"Return a cited version of the original message MSG (ie., the
|
||||
plist). This function use gnus' `message-cite-function', and as
|
||||
such all its settings apply."
|
||||
|
@ -51,13 +51,13 @@ such all its settings apply."
|
|||
(buffer-string)))
|
||||
|
||||
|
||||
(defun mu4e--header (hdr val)
|
||||
(defun mu4e~compose-header (hdr val)
|
||||
"Return a header line of the form HDR: VAL\n. If VAL is nil,
|
||||
return nil."
|
||||
(when val (format "%s: %s\n" hdr val)))
|
||||
|
||||
|
||||
(defun mu4e--refererences-construct (msg)
|
||||
(defun mu4e~compose-refererences-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 (which may be empty) and the message-id. If the
|
||||
|
@ -76,7 +76,7 @@ return nil."
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; determine the recipient fields for new messages
|
||||
|
||||
(defun mu4e--recipients-list-to-string (lst)
|
||||
(defun mu4e~compose-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
|
||||
|
@ -89,7 +89,7 @@ e-mail addresses. If LST is nil, returns nil."
|
|||
(format "%s" email))))
|
||||
lst ", ")))
|
||||
|
||||
(defun mu4e--address-cell-equal (cell1 cell2)
|
||||
(defun mu4e~compose-address-cell-equal (cell1 cell2)
|
||||
"Return t if cell1 and cell2 have the same e-mail
|
||||
address (case-insensitively), nil otherwise. cell1 and cell2 are
|
||||
cons cells (NAME . EMAIL)."
|
||||
|
@ -99,7 +99,7 @@ e-mail addresses. If LST is nil, returns nil."
|
|||
|
||||
|
||||
|
||||
(defun mu4e--create-to-lst (origmsg)
|
||||
(defun mu4e~compose-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:
|
||||
|
@ -109,10 +109,10 @@ field before, goes to the Cc:-list (if we're doing a reply-to-all)."
|
|||
(or reply-to
|
||||
(delete-duplicates
|
||||
(plist-get origmsg :from)
|
||||
:test #'mu4e--address-cell-equal))))
|
||||
:test #'mu4e~compose-address-cell-equal))))
|
||||
to-lst))
|
||||
|
||||
(defun mu4e--create-cc-lst (origmsg reply-all)
|
||||
(defun mu4e~compose-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
|
||||
|
@ -121,7 +121,7 @@ the original message ORIGMSG, and whether it's a reply-all."
|
|||
(append
|
||||
(plist-get origmsg :to)
|
||||
(plist-get origmsg :cc))
|
||||
:test #'mu4e--address-cell-equal))
|
||||
:test #'mu4e~compose-address-cell-equal))
|
||||
;; now we have the basic list, but we must remove
|
||||
;; addresses also in the to list
|
||||
(cc-lst
|
||||
|
@ -129,8 +129,8 @@ the original message ORIGMSG, and whether it's a reply-all."
|
|||
(lambda (cc-cell)
|
||||
(find-if
|
||||
(lambda (to-cell)
|
||||
(mu4e--address-cell-equal cc-cell to-cell))
|
||||
(mu4e--create-to-lst origmsg)))
|
||||
(mu4e~compose-address-cell-equal cc-cell to-cell))
|
||||
(mu4e~compose-create-to-lst origmsg)))
|
||||
cc-lst))
|
||||
;; finally, we need to remove ourselves from the cc-list
|
||||
(cc-lst
|
||||
|
@ -138,27 +138,27 @@ the original message ORIGMSG, and whether it's a reply-all."
|
|||
cc-lst
|
||||
(delete-if
|
||||
(lambda (cc-cell)
|
||||
(mu4e--address-cell-equal cc-cell
|
||||
(mu4e~compose-address-cell-equal cc-cell
|
||||
(cons nil user-mail-address)))
|
||||
cc-lst))))
|
||||
cc-lst)))
|
||||
|
||||
(defun mu4e--recipients-construct (field origmsg &optional reply-all)
|
||||
(defun mu4e~compose-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--recipients-list-to-string
|
||||
(mu4e~compose-recipients-list-to-string
|
||||
(case field
|
||||
(:to
|
||||
(mu4e--create-to-lst origmsg))
|
||||
(mu4e~compose-create-to-lst origmsg))
|
||||
(:cc
|
||||
(mu4e--create-cc-lst origmsg reply-all))
|
||||
(mu4e~compose-create-cc-lst origmsg reply-all))
|
||||
(otherwise
|
||||
(error "Unsupported field")))))
|
||||
|
||||
|
||||
(defun mu4e--from-construct ()
|
||||
(defun mu4e~compose-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."
|
||||
|
@ -169,10 +169,10 @@ nil, function returns nil."
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(defun mu4e--insert-mail-header-separator ()
|
||||
(defun mu4e~compose-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-edit-mode, we use
|
||||
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 file. Also see
|
||||
`mu4e-remove-mail-header-separator'."
|
||||
|
@ -187,22 +187,22 @@ separator is never written to file. Also see
|
|||
(goto-char (point-max))
|
||||
(insert (concat "\n" mail-header-separator "\n"))))))
|
||||
|
||||
(defun mu4e--remove-mail-header-separator ()
|
||||
(defun mu4e~compose-remove-mail-header-separator ()
|
||||
"Remove `mail-header-separator; we do this before saving a
|
||||
file (and restore it afterwardds), to ensure that the separator
|
||||
never hits the disk. Also see `mu4e--insert-mail-header-separator."
|
||||
never hits the disk. Also see `mu4e~compose-insert-mail-header-separator."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
;; remove the --text follows this line-- separator
|
||||
(when (search-forward-regexp (concat "^" mail-header-separator))
|
||||
(replace-match ""))))
|
||||
|
||||
(defun mu4e--user-wants-reply-all (origmsg)
|
||||
(defun mu4e~compose-user-wants-reply-all (origmsg)
|
||||
"Ask user whether she wants to reply to *all* recipients if there
|
||||
are more than 1 (based on ORIGMSG)."
|
||||
(let* ((recipnum
|
||||
(+ (length (mu4e--create-to-lst origmsg))
|
||||
(length (mu4e--create-cc-lst origmsg t))))
|
||||
(+ (length (mu4e~compose-create-to-lst origmsg))
|
||||
(length (mu4e~compose-create-cc-lst origmsg t))))
|
||||
(response
|
||||
(if (= recipnum 1)
|
||||
?a ;; with one recipient, we can reply to 'all'....
|
||||
|
@ -213,68 +213,68 @@ are more than 1 (based on ORIGMSG)."
|
|||
(= response ?a)))
|
||||
|
||||
|
||||
(defun mu4e--reply-construct (origmsg)
|
||||
(defun mu4e~compose-reply-construct (origmsg)
|
||||
"Create a draft message as a reply to original message ORIGMSG."
|
||||
(let* ((recipnum
|
||||
(+ (length (mu4e--create-to-lst origmsg))
|
||||
(length (mu4e--create-cc-lst origmsg t))))
|
||||
(reply-all (mu4e--user-wants-reply-all origmsg))
|
||||
(+ (length (mu4e~compose-create-to-lst origmsg))
|
||||
(length (mu4e~compose-create-cc-lst origmsg t))))
|
||||
(reply-all (mu4e~compose-user-wants-reply-all origmsg))
|
||||
(old-msgid (plist-get origmsg :message-id))
|
||||
(subject (or (plist-get origmsg :subject) "")))
|
||||
(concat
|
||||
|
||||
(mu4e--header "From" (or (mu4e--from-construct) ""))
|
||||
(mu4e--header "Reply-To" mu4e-reply-to-address)
|
||||
(mu4e--header "To" (mu4e--recipients-construct :to origmsg))
|
||||
(mu4e--header "Cc" (mu4e--recipients-construct :cc origmsg
|
||||
(mu4e~compose-header "From" (or (mu4e~compose-from-construct) ""))
|
||||
(mu4e~compose-header "Reply-To" mu4e-reply-to-address)
|
||||
(mu4e~compose-header "To" (mu4e~compose-recipients-construct :to origmsg))
|
||||
(mu4e~compose-header "Cc" (mu4e~compose-recipients-construct :cc origmsg
|
||||
reply-all))
|
||||
(mu4e--header "User-agent" (mu4e-user-agent))
|
||||
(mu4e--header "References" (mu4e--refererences-construct origmsg))
|
||||
(mu4e~compose-header "User-agent" (mu4e-user-agent))
|
||||
(mu4e~compose-header "References" (mu4e~compose-refererences-construct origmsg))
|
||||
|
||||
(when old-msgid
|
||||
(mu4e--header "In-reply-to" (format "<%s>" old-msgid)))
|
||||
(mu4e~compose-header "In-reply-to" (format "<%s>" old-msgid)))
|
||||
|
||||
(mu4e--header "Subject"
|
||||
(mu4e~compose-header "Subject"
|
||||
(concat
|
||||
;; if there's no Re: yet, prepend it
|
||||
(if (string-match "^Re:" subject) "" "Re:")
|
||||
subject))
|
||||
"\n\n"
|
||||
(mu4e--cite-original origmsg))))
|
||||
(mu4e~compose-cite-original origmsg))))
|
||||
|
||||
|
||||
(defun mu4e--forward-construct (origmsg)
|
||||
(defun mu4e~compose-forward-construct (origmsg)
|
||||
"Create a draft forward message for original message ORIGMSG."
|
||||
|
||||
(let ((subject
|
||||
(or (plist-get origmsg :subject) "")))
|
||||
(concat
|
||||
(mu4e--header "From" (or (mu4e--from-construct) ""))
|
||||
(mu4e--header "Reply-To" mu4e-reply-to-address)
|
||||
(mu4e--header "To" "")
|
||||
(mu4e--header "User-agent" (mu4e-user-agent))
|
||||
(mu4e--header "References" (mu4e--refererences-construct origmsg))
|
||||
(mu4e--header "Subject"
|
||||
(mu4e~compose-header "From" (or (mu4e~compose-from-construct) ""))
|
||||
(mu4e~compose-header "Reply-To" mu4e-reply-to-address)
|
||||
(mu4e~compose-header "To" "")
|
||||
(mu4e~compose-header "User-agent" (mu4e-user-agent))
|
||||
(mu4e~compose-header "References" (mu4e~compose-refererences-construct origmsg))
|
||||
(mu4e~compose-header "Subject"
|
||||
(concat
|
||||
;; if there's no Fwd: yet, prepend it
|
||||
(if (string-match "^Fwd:" subject) "" "Fwd:")
|
||||
subject))
|
||||
"\n\n"
|
||||
(mu4e--cite-original origmsg))))
|
||||
(mu4e~compose-cite-original origmsg))))
|
||||
|
||||
|
||||
(defun mu4e--newmsg-construct ()
|
||||
(defun mu4e~compose-newmsg-construct ()
|
||||
"Create a new message."
|
||||
(concat
|
||||
(mu4e--header "From" (or (mu4e--from-construct) ""))
|
||||
(mu4e--header "Reply-To" mu4e-reply-to-address)
|
||||
(mu4e--header "To" "")
|
||||
(mu4e--header "User-agent" (mu4e-user-agent))
|
||||
(mu4e--header "Subject" "")
|
||||
(mu4e~compose-header "From" (or (mu4e~compose-from-construct) ""))
|
||||
(mu4e~compose-header "Reply-To" mu4e-reply-to-address)
|
||||
(mu4e~compose-header "To" "")
|
||||
(mu4e~compose-header "User-agent" (mu4e-user-agent))
|
||||
(mu4e~compose-header "Subject" "")
|
||||
"\n"))
|
||||
|
||||
|
||||
(defun mu4e--open-new-draft-file (compose-type &optional msg)
|
||||
(defun mu4e~compose-open-new-draft-file (compose-type &optional msg)
|
||||
"Open a draft file for a new message, creating it if it does not
|
||||
already exist, and optionally fill it with STR. Function also adds
|
||||
the new message to the database. When the draft message is added to
|
||||
|
@ -293,9 +293,9 @@ use the new docid. Returns the full path to the new message."
|
|||
(format-time-string "%Y%m%d" (current-time))
|
||||
(emacs-pid) (random t) hostname)))
|
||||
(str (case compose-type
|
||||
(reply (mu4e--reply-construct msg))
|
||||
(forward (mu4e--forward-construct msg))
|
||||
(new (mu4e--newmsg-construct))
|
||||
(reply (mu4e~compose-reply-construct msg))
|
||||
(forward (mu4e~compose-forward-construct msg))
|
||||
(new (mu4e~compose-newmsg-construct))
|
||||
(t (error "unsupported compose-type %S" compose-type)))))
|
||||
(when str
|
||||
(with-current-buffer (find-file-noselect draft)
|
||||
|
@ -303,13 +303,13 @@ use the new docid. Returns the full path to the new message."
|
|||
draft)) ;; return the draft buffer file
|
||||
|
||||
|
||||
(define-derived-mode mu4e-edit-mode message-mode "mu4e:edit"
|
||||
(define-derived-mode mu4e-compose-mode message-mode "mu4e:compose"
|
||||
"Major mode for the mu4e message composition, derived from `message-mode'.
|
||||
\\{message-mode-map}."
|
||||
(let ((message-hidden-headers
|
||||
`("^References:" "^Face:" "^X-Face:" "^X-Draft-From:"
|
||||
"^User-agent:")))
|
||||
(use-local-map mu4e-edit-mode-map)
|
||||
(use-local-map mu4e-compose-mode-map)
|
||||
(message-hide-headers)
|
||||
(make-local-variable 'before-save-hook)
|
||||
(make-local-variable 'after-save-hook)
|
||||
|
@ -325,23 +325,23 @@ use the new docid. Returns the full path to the new message."
|
|||
;; hack-hack-hack... 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--remove-mail-header-separator)
|
||||
(add-hook 'before-save-hook 'mu4e~compose-remove-mail-header-separator)
|
||||
(add-hook 'after-save-hook
|
||||
(lambda ()
|
||||
(mu4e--set-friendly-buffer-name)
|
||||
(mu4e--insert-mail-header-separator)
|
||||
(mu4e~compose-set-friendly-buffer-name)
|
||||
(mu4e~compose-insert-mail-header-separator)
|
||||
(set-buffer-modified-p nil)))
|
||||
;; update the db when the file is saved...]
|
||||
(add-hook 'after-save-hook
|
||||
(lambda()
|
||||
(mu4e-proc-add (buffer-file-name) mu4e-drafts-folder))))
|
||||
(mu4e~proc-add (buffer-file-name) mu4e-drafts-folder))))
|
||||
;; notify the backend that a message has been sent. The backend will respond
|
||||
;; with (:sent ...) sexp, which is handled in `mu4e-compose-handler'.
|
||||
(add-hook 'message-sent-hook
|
||||
(lambda ()
|
||||
(set-buffer-modified-p t)
|
||||
(basic-save-buffer)
|
||||
(mu4e-proc-sent (buffer-file-name) mu4e-drafts-folder)))
|
||||
(mu4e~proc-sent (buffer-file-name) mu4e-drafts-folder)))
|
||||
;; register the function; this function will be called when the '(:sent...)'
|
||||
;; message is received (see mu4e-proc.el) with parameters docid and path
|
||||
(setq mu4e-sent-func 'mu4e-sent-handler)
|
||||
|
@ -351,10 +351,10 @@ use the new docid. Returns the full path to the new message."
|
|||
(setq default-directory (expand-file-name "~/")))
|
||||
|
||||
|
||||
(defconst mu4e--buffer-max-name-length 30
|
||||
(defconst mu4e~compose-buffer-max-name-length 30
|
||||
"Maximum length of the mu4e-send-buffer-name.")
|
||||
|
||||
(defun mu4e--set-friendly-buffer-name (&optional compose-type)
|
||||
(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))
|
||||
|
@ -365,7 +365,7 @@ use the new docid. Returns the full path to the new message."
|
|||
(otherwise "*draft*")))))
|
||||
(rename-buffer (generate-new-buffer-name
|
||||
(truncate-string-to-width str
|
||||
mu4e--buffer-max-name-length
|
||||
mu4e~compose-buffer-max-name-length
|
||||
nil nil t)))))
|
||||
|
||||
|
||||
|
@ -395,22 +395,22 @@ The name of the draft folder is constructed from the concatenation
|
|||
The message file name is a unique name determined by
|
||||
`mu4e-send-draft-file-name'.
|
||||
|
||||
The initial STR would be created from either `mu4e--reply-construct',
|
||||
ar`mu4e--forward-construct' or `mu4e--newmsg-construct'. The editing buffer is
|
||||
The initial STR would be created from either `mu4e~compose-reply-construct',
|
||||
ar`mu4e~compose-forward-construct' or `mu4e~compose-newmsg-construct'. The editing buffer is
|
||||
using Gnus' `message-mode'."
|
||||
(unless mu4e-maildir (error "mu4e-maildir not set"))
|
||||
(unless mu4e-drafts-folder (error "mu4e-drafts-folder not set"))
|
||||
(let ((draft
|
||||
(if (member compose-type '(reply forward new))
|
||||
(mu4e--open-new-draft-file compose-type original-msg)
|
||||
(mu4e~compose-open-new-draft-file compose-type original-msg)
|
||||
(if (eq compose-type 'edit)
|
||||
(plist-get original-msg :path)
|
||||
(error "unsupported compose-type %S" compose-type)))))
|
||||
(find-file draft)
|
||||
(mu4e-edit-mode)
|
||||
(mu4e-compose-mode)
|
||||
;; insert mail-header-separator, which is needed by message mode to separate
|
||||
;; headers and body. will be removed before saving to disk
|
||||
(mu4e--insert-mail-header-separator)
|
||||
(mu4e~compose-insert-mail-header-separator)
|
||||
;; include files -- e.g. when forwarding a message with attachments,
|
||||
;; we take those from the original.
|
||||
(save-excursion
|
||||
|
@ -428,7 +428,7 @@ using Gnus' `message-mode'."
|
|||
(if (member compose-type '(new forward))
|
||||
(message-goto-to)
|
||||
(message-goto-body))
|
||||
(mu4e--set-friendly-buffer-name compose-type)
|
||||
(mu4e~compose-set-friendly-buffer-name compose-type)
|
||||
;; buffer is not user-modified yet
|
||||
(set-buffer-modified-p nil)))
|
||||
|
||||
|
@ -452,13 +452,13 @@ message."
|
|||
(with-current-buffer(find-file-noselect path)
|
||||
;; for Forward ('Passed') and Replied messages, try to set the appropriate
|
||||
;; flag at the message forwarded or replied-to
|
||||
(mu4e--set-parent-flag docid path)
|
||||
(mu4e~compose-set-parent-flag docid path)
|
||||
;; handle the draft -- should it be moved to the sent-folder, or elsewhere?
|
||||
(mu4e--save-copy-maybe docid path)
|
||||
(mu4e~compose-save-copy-maybe docid path)
|
||||
;; now, get rid of the buffer
|
||||
(kill-buffer)))
|
||||
|
||||
(defun mu4e--save-copy-maybe (docid path)
|
||||
(defun mu4e~compose-save-copy-maybe (docid path)
|
||||
"Handler function, called with DOCID and PATH for the just-sent
|
||||
message, which will move it to the sent-folder or elsewhere,
|
||||
depending on the value of `mu4e-sent-messages-behavior'.
|
||||
|
@ -467,16 +467,16 @@ Function assumes that it's executed in the context of the message
|
|||
buffer."
|
||||
;; first, what to do with the draft message in PATH?
|
||||
(if (eq mu4e-sent-messages-behavior 'delete)
|
||||
(mu4e-proc-remove docid) ;; remove it
|
||||
(mu4e~proc-remove docid) ;; remove it
|
||||
;; otherwise,
|
||||
(progn ;; prepare the message for saving
|
||||
(basic-save-buffer)
|
||||
;; now either move it to trash or to sent
|
||||
(if (eq mu4e-sent-messages-behavior 'trash)
|
||||
(mu4e-proc-move docid mu4e-trash-folder "+T-D+S")
|
||||
(mu4e-proc-move docid mu4e-sent-folder "-T-D+S")))))
|
||||
(mu4e~proc-move docid mu4e-trash-folder "+T-D+S")
|
||||
(mu4e~proc-move docid mu4e-sent-folder "-T-D+S")))))
|
||||
|
||||
(defun mu4e--set-parent-flag (docid path)
|
||||
(defun mu4e~compose-set-parent-flag (docid path)
|
||||
"Set the 'replied' \"R\" flag on messages we replied to, and the
|
||||
'passed' \"F\" flag on message we have forwarded.
|
||||
|
||||
|
@ -509,9 +509,9 @@ buffer.
|
|||
(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"))
|
||||
(mu4e~proc-move (match-string 1 in-reply-to) nil "+R"))
|
||||
(when (and forwarded-from (string-match "<\\(.*\\)>" forwarded-from))
|
||||
(mu4e-proc-move (match-string 1 forwarded-from) nil "+P"))))
|
||||
(mu4e~proc-move (match-string 1 forwarded-from) nil "+P"))))
|
||||
|
||||
|
||||
|
||||
|
@ -519,7 +519,7 @@ buffer.
|
|||
;; mu4e-compose-func and mu4e-send-func are wrappers so we can set ourselves
|
||||
;; as default emacs mailer (define-mail-user-agent etc.)
|
||||
|
||||
(defun mu4e--compose-func (&optional to subject other-headers continue
|
||||
(defun mu4e~compose-compose-func (&optional to subject other-headers continue
|
||||
switch-function yank-action send-actions return-action)
|
||||
"mu4e's implementation of `compose-mail'."
|
||||
|
||||
|
|
|
@ -35,16 +35,16 @@
|
|||
(require 'mu4e-mark)
|
||||
|
||||
;;;; internal variables/constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(defconst mu4e-hdrs-fringe " " "*internal* The space on the left of
|
||||
(defconst mu4e~hdrs-fringe " " "*internal* The space on the left of
|
||||
message headers to put marks.")
|
||||
|
||||
(defun mu4e-hdrs-clear ()
|
||||
(defun mu4e~hdrs-clear ()
|
||||
"Clear the header buffer and related data structures."
|
||||
(when (buffer-live-p mu4e-hdrs-buffer)
|
||||
(when (buffer-live-p mu4e~hdrs-buffer)
|
||||
(let ((inhibit-read-only t))
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(erase-buffer)
|
||||
(mu4e--mark-clear)))))
|
||||
(mu4e~mark-clear)))))
|
||||
|
||||
|
||||
(defun mu4e-hdrs-search (expr &optional full-search)
|
||||
|
@ -52,17 +52,17 @@ message headers to put marks.")
|
|||
buffer for the results. If FULL-SEARCH is non-nil return all
|
||||
results, otherwise, limit number of results to
|
||||
`mu4e-search-results-limit'."
|
||||
(let ((buf (get-buffer-create mu4e-hdrs-buffer-name))
|
||||
(let ((buf (get-buffer-create mu4e~hdrs-buffer-name))
|
||||
(inhibit-read-only t))
|
||||
(with-current-buffer buf
|
||||
(mu4e-hdrs-mode)
|
||||
(setq
|
||||
global-mode-string (propertize expr 'face 'mu4e-title-face)
|
||||
mu4e-last-expr expr
|
||||
mu4e-hdrs-buffer buf
|
||||
mu4e~hdrs-buffer buf
|
||||
mode-name "mu4e-headers"))
|
||||
(switch-to-buffer buf)
|
||||
(mu4e-proc-find
|
||||
(mu4e~proc-find
|
||||
(replace-regexp-in-string "\"" "\\\\\"" expr) ;; escape "\"
|
||||
(unless full-search mu4e-search-results-limit))
|
||||
;;; when we're starting a new search, we also kill the
|
||||
|
@ -72,22 +72,22 @@ results, otherwise, limit number of results to
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; handler functions
|
||||
;;
|
||||
;; next are a bunch of handler functions; those will be called from mu4e-proc in
|
||||
;; next are a bunch of handler functions; those will be called from mu4e~proc in
|
||||
;; response to output from the server process
|
||||
|
||||
|
||||
(defun mu4e-hdrs-view-handler (msg)
|
||||
(defun mu4e~hdrs-view-handler (msg)
|
||||
"Handler function for displaying a message."
|
||||
(mu4e-view msg mu4e-hdrs-buffer))
|
||||
(mu4e-view msg mu4e~hdrs-buffer))
|
||||
|
||||
(defun mu4e-hdrs-update-handler (msg is-move)
|
||||
(defun mu4e~hdrs-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-hdrs-buffer)
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(when (buffer-live-p mu4e~hdrs-buffer)
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(let* ((docid (plist-get msg :docid))
|
||||
(point (mu4e--docid-pos docid)))
|
||||
(point (mu4e~docid-pos docid)))
|
||||
(when point ;; is the message present in this list?
|
||||
|
||||
;; if it's marked, unmark it now
|
||||
|
@ -99,11 +99,11 @@ headers."
|
|||
;; search results)
|
||||
;; but since we still have the search results, re-use those
|
||||
(plist-put msg :thread
|
||||
(mu4e--field-for-docid docid :thread))
|
||||
(mu4e~field-for-docid docid :thread))
|
||||
|
||||
;; first, remove the old one (otherwise, we'd have two headers with
|
||||
;; the same docid...
|
||||
(mu4e-hdrs-remove-handler docid)
|
||||
(mu4e~hdrs-remove-handler docid)
|
||||
|
||||
;; if we we're actually viewing this message (in mu4e-view mode), we
|
||||
;; update the `mu4e-current-msg' there as well; that way, the flags can
|
||||
|
@ -113,30 +113,30 @@ headers."
|
|||
(when (and viewbuf (buffer-live-p viewbuf))
|
||||
(with-current-buffer viewbuf
|
||||
(when (eq docid (plist-get mu4e-current-msg :docid))
|
||||
(mu4e-view msg mu4e-hdrs-buffer)))))
|
||||
(mu4e-view msg mu4e~hdrs-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-hdrs-header-handler msg point))
|
||||
(mu4e~hdrs-header-handler msg point))
|
||||
|
||||
;; attempt to highlight the corresponding line and make it visible
|
||||
(mu4e-hdrs-highlight docid))))))
|
||||
(mu4e~hdrs-highlight docid))))))
|
||||
|
||||
|
||||
(defun mu4e-hdrs-remove-handler (docid)
|
||||
(defun mu4e~hdrs-remove-handler (docid)
|
||||
"Remove handler, will be called when a message has been removed
|
||||
from the database. This function will hide the removed message from
|
||||
the current list of headers."
|
||||
(when (buffer-live-p mu4e-hdrs-buffer)
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(mu4e-hdrs-remove-header docid))))
|
||||
(when (buffer-live-p mu4e~hdrs-buffer)
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(mu4e~hdrs-remove-header docid))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defun mu4e-hdrs-contact-str (contacts)
|
||||
(defun mu4e~hdrs-contact-str (contacts)
|
||||
"Turn the list of contacts CONTACTS (with elements (NAME . EMAIL)
|
||||
into a string."
|
||||
(mapconcat
|
||||
|
@ -161,10 +161,10 @@ into a string."
|
|||
(duplicate "= ")
|
||||
(t "| "))))))
|
||||
|
||||
(defun mu4e-hdrs-header-handler (msg &optional point)
|
||||
(defun mu4e~hdrs-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."
|
||||
(when (buffer-live-p mu4e-hdrs-buffer)
|
||||
(when (buffer-live-p mu4e~hdrs-buffer)
|
||||
(let* ((docid (plist-get msg :docid))
|
||||
(line
|
||||
(mapconcat
|
||||
|
@ -178,7 +178,7 @@ if provided, or at the end of the buffer otherwise."
|
|||
(mu4e-thread-prefix (plist-get msg :thread))
|
||||
val))
|
||||
((:maildir :path) val)
|
||||
((:to :from :cc :bcc) (mu4e-hdrs-contact-str val))
|
||||
((:to :from :cc :bcc) (mu4e~hdrs-contact-str val))
|
||||
;; if we (ie. `user-mail-address' is the 'From', show
|
||||
;; 'To', otherwise show From
|
||||
(:from-or-to
|
||||
|
@ -187,8 +187,8 @@ if provided, or at the end of the buffer otherwise."
|
|||
(if (and from (string-match
|
||||
mu4e-user-mail-address-regexp from))
|
||||
(concat "To "
|
||||
(mu4e-hdrs-contact-str (plist-get msg :to)))
|
||||
(mu4e-hdrs-contact-str from-lst))))
|
||||
(mu4e~hdrs-contact-str (plist-get msg :to)))
|
||||
(mu4e~hdrs-contact-str from-lst))))
|
||||
(:date (format-time-string mu4e-headers-date-format val))
|
||||
(:flags (mu4e-flags-to-string val))
|
||||
(:size (mu4e-display-size val))
|
||||
|
@ -210,13 +210,13 @@ if provided, or at the end of the buffer otherwise."
|
|||
(propertize line 'face 'mu4e-header-face)))))
|
||||
|
||||
;; now, append the header line
|
||||
(mu4e-hdrs-add-header line docid point msg))))
|
||||
(mu4e~hdrs-add-header line docid point msg))))
|
||||
|
||||
(defun mu4e-hdrs-found-handler (count)
|
||||
(defun mu4e~hdrs-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-hdrs-buffer)
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(when (buffer-live-p mu4e~hdrs-buffer)
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(let ((inhibit-read-only t)
|
||||
|
@ -228,7 +228,7 @@ after the end of the search results."
|
|||
(message "Found %d matching message%s"
|
||||
count (if (= 1 count) "" "s"))
|
||||
;; highlight the first message
|
||||
(mu4e-hdrs-highlight (mu4e--docid-at-point (point-min)))))))))
|
||||
(mu4e~hdrs-highlight (mu4e~docid-at-point (point-min)))))))))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
|
@ -240,11 +240,11 @@ after the end of the search results."
|
|||
"Keymap for *mu4e-headers* buffers.")
|
||||
(unless mu4e-hdrs-mode-map
|
||||
;; add some quick funcs so our key descriptions below are shorter
|
||||
(defun mu4e--hdrs-mark-trash()(interactive)(mu4e-hdrs-mark-and-next 'trash))
|
||||
(defun mu4e--hdrs-mark-delete()(interactive)(mu4e-hdrs-mark-and-next 'delete))
|
||||
(defun mu4e--hdrs-mark-unmark()(interactive)(mu4e-hdrs-mark-and-next 'unmark))
|
||||
(defun mu4e--hdrs-mark-read()(interactive)(mu4e-hdrs-mark-and-next 'read))
|
||||
(defun mu4e--hdrs-mark-unread()(interactive)(mu4e-hdrs-mark-and-next 'unread))
|
||||
(defun mu4e~hdrs-mark-trash()(interactive)(mu4e-hdrs-mark-and-next 'trash))
|
||||
(defun mu4e~hdrs-mark-delete()(interactive)(mu4e-hdrs-mark-and-next 'delete))
|
||||
(defun mu4e~hdrs-mark-unmark()(interactive)(mu4e-hdrs-mark-and-next 'unmark))
|
||||
(defun mu4e~hdrs-mark-read()(interactive)(mu4e-hdrs-mark-and-next 'read))
|
||||
(defun mu4e~hdrs-mark-unread()(interactive)(mu4e-hdrs-mark-and-next 'unread))
|
||||
|
||||
(setq mu4e-hdrs-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
|
@ -254,8 +254,8 @@ after the end of the search results."
|
|||
(define-key map "b" 'mu4e-search-bookmark)
|
||||
(define-key map "B" 'mu4e-search-bookmark-edit-first)
|
||||
|
||||
(define-key map "q" 'mu4e-hdrs-kill-buffer-and-window)
|
||||
(define-key map "z" 'mu4e-hdrs-kill-buffer-and-window)
|
||||
(define-key map "q" 'mu4e~hdrs-kill-buffer-and-window)
|
||||
(define-key map "z" 'mu4e~hdrs-kill-buffer-and-window)
|
||||
|
||||
(define-key map "r" 'mu4e-rerun-search)
|
||||
(define-key map "g" 'mu4e-rerun-search) ;; for compatibility
|
||||
|
@ -271,16 +271,16 @@ after the end of the search results."
|
|||
(define-key map "y" 'mu4e-select-other-view)
|
||||
|
||||
;; marking/unmarking ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(define-key map (kbd "<backspace>") 'mu4e--hdrs-mark-trash)
|
||||
(define-key map (kbd "d") 'mu4e--hdrs-mark-trash)
|
||||
(define-key map (kbd "<backspace>") 'mu4e~hdrs-mark-trash)
|
||||
(define-key map (kbd "d") 'mu4e~hdrs-mark-trash)
|
||||
|
||||
(define-key map (kbd "<delete>") 'mu4e--hdrs-mark-delete)
|
||||
(define-key map (kbd "<deletechar>") 'mu4e--hdrs-mark-delete)
|
||||
(define-key map (kbd "D") 'mu4e--hdrs-mark-delete)
|
||||
(define-key map (kbd "<delete>") 'mu4e~hdrs-mark-delete)
|
||||
(define-key map (kbd "<deletechar>") 'mu4e~hdrs-mark-delete)
|
||||
(define-key map (kbd "D") 'mu4e~hdrs-mark-delete)
|
||||
|
||||
(define-key map (kbd "o") 'mu4e--hdrs-mark-unread)
|
||||
(define-key map (kbd "r") 'mu4e--hdrs-mark-read)
|
||||
(define-key map (kbd "u") 'mu4e--hdrs-mark-unmark)
|
||||
(define-key map (kbd "o") 'mu4e~hdrs-mark-unread)
|
||||
(define-key map (kbd "r") 'mu4e~hdrs-mark-read)
|
||||
(define-key map (kbd "u") 'mu4e~hdrs-mark-unmark)
|
||||
|
||||
(define-key map "m" 'mu4e-hdrs-mark-for-move-and-next)
|
||||
|
||||
|
@ -309,8 +309,8 @@ after the end of the search results."
|
|||
(let ((menumap (make-sparse-keymap "Headers")))
|
||||
(define-key map [menu-bar headers] (cons "Headers" menumap))
|
||||
|
||||
(define-key menumap [mu4e-hdrs-kill-buffer-and-window]
|
||||
'("Quit view" . mu4e-hdrs-kill-buffer-and-window))
|
||||
(define-key menumap [mu4e~hdrs-kill-buffer-and-window]
|
||||
'("Quit view" . mu4e~hdrs-kill-buffer-and-window))
|
||||
(define-key menumap [display-help] '("Help" . mu4e-display-manual))
|
||||
|
||||
(define-key menumap [sepa0] '("--"))
|
||||
|
@ -318,16 +318,16 @@ after the end of the search results."
|
|||
(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--hdrs-mark-unmark))
|
||||
(define-key menumap [unmark] '("Unmark" . mu4e~hdrs-mark-unmark))
|
||||
|
||||
(define-key menumap [mark-as-read] '("Mark as read" . mu4e--hdrs-mark-read))
|
||||
(define-key menumap [mark-as-read] '("Mark as read" . mu4e~hdrs-mark-read))
|
||||
(define-key menumap [mark-as-unread]
|
||||
'("Mark as unread" . mu4e--hdrs-mark-unread))
|
||||
'("Mark as unread" . mu4e~hdrs-mark-unread))
|
||||
|
||||
(define-key menumap [mark-delete]
|
||||
'("Mark for deletion" . mu4e--hdrs-mark-delete))
|
||||
'("Mark for deletion" . mu4e~hdrs-mark-delete))
|
||||
(define-key menumap [mark-trash]
|
||||
'("Mark for trash" . mu4e--hdrs-mark-trash))
|
||||
'("Mark for trash" . mu4e~hdrs-mark-trash))
|
||||
(define-key menumap [mark-move]
|
||||
'("Mark for move" . mu4e-hdrs-mark-for-move-and-next))
|
||||
(define-key menumap [sepa1] '("--"))
|
||||
|
@ -359,8 +359,8 @@ after the end of the search results."
|
|||
(use-local-map mu4e-hdrs-mode-map)
|
||||
|
||||
(make-local-variable 'mu4e-last-expr)
|
||||
(make-local-variable 'mu4e-hdrs-proc)
|
||||
(make-local-variable 'mu4e--highlighted-docid)
|
||||
(make-local-variable 'mu4e~hdrs-proc)
|
||||
(make-local-variable 'mu4e~highlighted-docid)
|
||||
|
||||
(make-local-variable 'global-mode-string)
|
||||
(make-local-variable 'hl-line-face)
|
||||
|
@ -370,13 +370,13 @@ after the end of the search results."
|
|||
buffer-undo-list t ;; don't record undo information
|
||||
overwrite-mode 'overwrite-mode-binary
|
||||
hl-line-face 'mu4e-header-highlight-face)
|
||||
(mu4e--mark-initialize) ;; initialize the marking subsystem
|
||||
(mu4e~mark-initialize) ;; initialize the marking subsystem
|
||||
(hl-line-mode 1)
|
||||
|
||||
(setq header-line-format
|
||||
(cons
|
||||
(make-string
|
||||
(+ (length mu4e-hdrs-fringe) (floor (fringe-columns 'left t))) ?\s)
|
||||
(+ (length mu4e~hdrs-fringe) (floor (fringe-columns 'left t))) ?\s)
|
||||
(map 'list
|
||||
(lambda (item)
|
||||
(let ((field (cdr (assoc (car item) mu4e-header-names)))
|
||||
|
@ -391,22 +391,22 @@ after the end of the search results."
|
|||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; higlighting
|
||||
(defvar mu4e--highlighted-docid nil
|
||||
(defvar mu4e~highlighted-docid nil
|
||||
"*internal* The highlighted docid")
|
||||
|
||||
(defun mu4e-hdrs-highlight (docid)
|
||||
(defun mu4e~hdrs-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-hdrs-buffer
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(save-excursion
|
||||
;; first, unhighlight the previously highlighted docid, if any
|
||||
(when (and mu4e--highlighted-docid
|
||||
(mu4e--goto-docid mu4e--highlighted-docid))
|
||||
(when (and mu4e~highlighted-docid
|
||||
(mu4e~goto-docid mu4e~highlighted-docid))
|
||||
(hl-line-unhighlight))
|
||||
;; now, highlight the new one
|
||||
(when (mu4e--goto-docid docid)
|
||||
(when (mu4e~goto-docid docid)
|
||||
(hl-line-highlight)))
|
||||
(setq mu4e--highlighted-docid docid)))
|
||||
(setq mu4e~highlighted-docid docid)))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -414,7 +414,7 @@ found. Also, unhighlight any previously highlighted headers."
|
|||
"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-hdrs-buffer)))
|
||||
(let ((win (get-buffer-window mu4e~hdrs-buffer)))
|
||||
(when win (select-window win))))
|
||||
|
||||
;;;; headers in the buffer are prefixed by an invisible string with the docid
|
||||
|
@ -423,12 +423,12 @@ adding a lot of new headers looks really choppy."
|
|||
;;;; is used for quickly finding a certain header, the latter for retrieving the
|
||||
;;;; docid at point without string matching etc.
|
||||
|
||||
(defun mu4e--docid-cookie (docid)
|
||||
(defun mu4e~docid-cookie (docid)
|
||||
"Create an invisible string containing DOCID; this is to be used
|
||||
at the beginning of lines to identify headers."
|
||||
(propertize (format "%d\004" docid) 'docid docid 'invisible t))
|
||||
|
||||
(defun mu4e--docid-at-point (&optional point)
|
||||
(defun mu4e~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
|
||||
|
@ -436,7 +436,7 @@ nil. Returns the docid, or nil if there is none."
|
|||
(goto-char point))
|
||||
(get-text-property (line-beginning-position) 'docid)))
|
||||
|
||||
(defun mu4e--goto-docid (docid &optional to-mark)
|
||||
(defun mu4e~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
|
||||
|
@ -453,27 +453,27 @@ of the beginning of the line."
|
|||
(setq newpoint (point)))))
|
||||
newpoint)) ;; return the point, or nil if not found
|
||||
|
||||
(defun mu4e--docid-pos (docid)
|
||||
(defun mu4e~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--goto-docid docid)))
|
||||
(setq pos (mu4e~goto-docid docid)))
|
||||
pos))
|
||||
|
||||
(defun mu4e--field-for-docid (docid field)
|
||||
(defun mu4e~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--goto-docid docid)
|
||||
(when (mu4e~goto-docid docid)
|
||||
(mu4e-field-at-point field))))
|
||||
|
||||
;;;; markers mark headers for
|
||||
(defun mu4e--mark-header (docid mark)
|
||||
(defun mu4e~mark-header (docid mark)
|
||||
"(Visually) mark the header for DOCID with character MARK."
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(let ((inhibit-read-only t) (oldpoint (point)))
|
||||
(unless (mu4e--goto-docid docid)
|
||||
(unless (mu4e~goto-docid docid)
|
||||
(error "Cannot find message with docid %S" docid))
|
||||
;; now, we're at the beginning of the header, looking at
|
||||
;; <docid>\004
|
||||
|
@ -484,17 +484,17 @@ with DOCID which must be present in the headers buffer."
|
|||
;; the area to write the marker.
|
||||
;;(forward-char)
|
||||
;; clear old marks, and add the new ones.
|
||||
(delete-char (length mu4e-hdrs-fringe))
|
||||
(delete-char (length mu4e~hdrs-fringe))
|
||||
(insert (propertize mark 'face 'mu4e-hdrs-marks-face) " ")
|
||||
(goto-char oldpoint))))
|
||||
|
||||
|
||||
(defun mu4e-hdrs-add-header (str docid point &optional msg)
|
||||
(defun mu4e~hdrs-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'."
|
||||
(unless docid (error "Invalid message"))
|
||||
(when (buffer-live-p mu4e-hdrs-buffer)
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(when (buffer-live-p mu4e~hdrs-buffer)
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(let ((inhibit-read-only t)
|
||||
(is-first-header (= (point-min) (point-max))))
|
||||
(save-excursion
|
||||
|
@ -502,13 +502,13 @@ at (point-max) otherwise. If MSG is not nil, add it as the text-property `msg'."
|
|||
(insert
|
||||
(propertize
|
||||
(concat
|
||||
(mu4e--docid-cookie docid)
|
||||
mu4e-hdrs-fringe str "\n") 'docid docid 'msg msg)))))))
|
||||
(mu4e~docid-cookie docid)
|
||||
mu4e~hdrs-fringe str "\n") 'docid docid 'msg msg)))))))
|
||||
|
||||
(defun mu4e-hdrs-remove-header (docid)
|
||||
(defun mu4e~hdrs-remove-header (docid)
|
||||
"Remove header with DOCID at POINT."
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(unless (mu4e--goto-docid docid)
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
(unless (mu4e~goto-docid docid)
|
||||
(error "Cannot find message with docid %S" docid))
|
||||
(let ((inhibit-read-only t))
|
||||
(delete-region (line-beginning-position) (line-beginning-position 2)))))
|
||||
|
@ -555,7 +555,7 @@ current window. "
|
|||
(interactive)
|
||||
(unless (eq major-mode 'mu4e-hdrs-mode)
|
||||
(error "Must be in mu4e-hdrs-mode (%S)" major-mode))
|
||||
(let* ((docid (mu4e--docid-at-point))
|
||||
(let* ((docid (mu4e~docid-at-point))
|
||||
(viewwin (and mu4e-view-buffer
|
||||
(get-buffer-window mu4e-view-buffer))))
|
||||
(unless docid (error "No message at point."))
|
||||
|
@ -581,13 +581,13 @@ current window. "
|
|||
(erase-buffer)
|
||||
(insert (propertize "Waiting for message..."
|
||||
'face 'mu4e-system-face 'intangible t)))
|
||||
(mu4e-proc-view docid)))
|
||||
(mu4e~proc-view docid)))
|
||||
|
||||
(defun mu4e-hdrs-kill-buffer-and-window ()
|
||||
(defun mu4e~hdrs-kill-buffer-and-window ()
|
||||
"Quit the message view and return to the main view."
|
||||
(interactive)
|
||||
(when (mu4e-mark-handle-when-leaving)
|
||||
(mu4e-kill-buffer-and-window mu4e-hdrs-buffer)
|
||||
(mu4e-kill-buffer-and-window mu4e~hdrs-buffer)
|
||||
(mu4e-main-view)))
|
||||
|
||||
(defun mu4e-rerun-search ()
|
||||
|
@ -599,20 +599,20 @@ do a new search."
|
|||
(mu4e-hdrs-search mu4e-last-expr)
|
||||
(call-interactively 'mu4e-search))))
|
||||
|
||||
(defun mu4e--hdrs-move (lines)
|
||||
(defun mu4e~hdrs-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-hdrs-mode)
|
||||
(error "Must be in mu4e-hdrs-mode (%S)" major-mode))
|
||||
(let ((succeeded (= 0 (forward-line lines)))
|
||||
(docid (mu4e--docid-at-point)))
|
||||
(docid (mu4e~docid-at-point)))
|
||||
;; trick to move point, even if this function is called when this window
|
||||
;; is not visible
|
||||
(when docid
|
||||
(set-window-point (get-buffer-window mu4e-hdrs-buffer) (point))
|
||||
(set-window-point (get-buffer-window mu4e~hdrs-buffer) (point))
|
||||
;; attempt to highlight the new line, display the message
|
||||
(mu4e-hdrs-highlight docid)
|
||||
(mu4e~hdrs-highlight docid)
|
||||
;; if there already is a visible message view, show the message
|
||||
(when (and (buffer-live-p mu4e-view-buffer)
|
||||
(window-live-p (get-buffer-window mu4e-view-buffer)))
|
||||
|
@ -624,13 +624,13 @@ docid. Otherwise, return nil."
|
|||
"Move point to the next message header. If this succeeds, return
|
||||
the new docid. Otherwise, return nil."
|
||||
(interactive)
|
||||
(mu4e--hdrs-move 1))
|
||||
(mu4e~hdrs-move 1))
|
||||
|
||||
(defun mu4e-prev-header ()
|
||||
"Move point to the previous message header. If this succeeds,
|
||||
return the new docid. Otherwise, return nil."
|
||||
(interactive)
|
||||
(mu4e--hdrs-move -1))
|
||||
(mu4e~hdrs-move -1))
|
||||
|
||||
|
||||
(defun mu4e-jump-to-maildir ()
|
||||
|
@ -650,18 +650,18 @@ a symbol, one of `reply', `forward', `edit', `new'. All but `new'
|
|||
take the message at point as input. Symbol `edit' is only allowed
|
||||
for draft messages."
|
||||
(interactive)
|
||||
(let ((mu4e-hdrs-buffer (get-buffer-create mu4e-hdrs-buffer-name))
|
||||
(let ((mu4e~hdrs-buffer (get-buffer-create mu4e~hdrs-buffer-name))
|
||||
(compose-type
|
||||
(or compose-type
|
||||
(intern (ido-completing-read "Compose type: "
|
||||
'("reply" "forward" "edit" "new"))))))
|
||||
(with-current-buffer mu4e-hdrs-buffer
|
||||
(with-current-buffer mu4e~hdrs-buffer
|
||||
;; 'new is special, since it takes no existing message as arg therefore,
|
||||
;; we don't need to call thec backend, and call the handler *directly*
|
||||
(if (eq compose-type 'new)
|
||||
(mu4e-compose-handler 'new)
|
||||
;; otherwise, we need the doc-id
|
||||
(let ((docid (mu4e--docid-at-point)))
|
||||
(let ((docid (mu4e~docid-at-point)))
|
||||
(unless docid (error "No message at point."))
|
||||
;; note, the first two chars of the line (the mark margin) does *not*
|
||||
;; have the 'draft property; thus, we check one char before the end of
|
||||
|
@ -678,7 +678,7 @@ for draft messages."
|
|||
(select-window viewwin)))
|
||||
|
||||
;; talk to the backend
|
||||
(mu4e-proc-compose compose-type docid))))))
|
||||
(mu4e~proc-compose compose-type docid))))))
|
||||
|
||||
(defun mu4e-compose-reply ()
|
||||
"Reply to the current message."
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
(require 'mu4e-utils)
|
||||
|
||||
;;; marks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(defvar mu4e--mark-map nil
|
||||
(defvar mu4e~mark-map nil
|
||||
"Map (hash) of docid->markinfo; when a message is marked, the
|
||||
information is added here.
|
||||
|
||||
|
@ -45,14 +45,14 @@ where
|
|||
;; happen in the future
|
||||
|
||||
|
||||
(defun mu4e--mark-initialize ()
|
||||
(defun mu4e~mark-initialize ()
|
||||
"Initialize the marks subsystem."
|
||||
(make-local-variable 'mu4e--mark-map)
|
||||
(setq mu4e--mark-map (make-hash-table :size 16 :rehash-size 2)))
|
||||
(make-local-variable 'mu4e~mark-map)
|
||||
(setq mu4e~mark-map (make-hash-table :size 16 :rehash-size 2)))
|
||||
|
||||
(defun mu4e--mark-clear ()
|
||||
(defun mu4e~mark-clear ()
|
||||
"Clear the marks subsystem."
|
||||
(clrhash mu4e--mark-map))
|
||||
(clrhash mu4e~mark-map))
|
||||
|
||||
|
||||
(defun mu4e-mark-at-point (mark &optional target)
|
||||
|
@ -72,7 +72,7 @@ The following marks are available, and the corresponding props:
|
|||
`unread' n mark the message as unread
|
||||
`unmark' n unmark this message"
|
||||
(interactive)
|
||||
(let* ((docid (mu4e--docid-at-point))
|
||||
(let* ((docid (mu4e~docid-at-point))
|
||||
(markkar
|
||||
(case mark ;; the visual mark
|
||||
('move "m")
|
||||
|
@ -84,25 +84,25 @@ The following marks are available, and the corresponding props:
|
|||
(t (error "Invalid mark %S" mark)))))
|
||||
(unless docid (error "No message on this line"))
|
||||
(save-excursion
|
||||
(when (mu4e--mark-header docid markkar))
|
||||
(when (mu4e~mark-header docid markkar))
|
||||
;; update the hash -- remove everything current, and if add the new stuff,
|
||||
;; unless we're unmarking
|
||||
(remhash docid mu4e--mark-map)
|
||||
(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 (list mark target) mu4e--mark-map)
|
||||
(puthash docid (list mark target) mu4e~mark-map)
|
||||
;; when we have a target (ie., when moving), show the target folder in
|
||||
;; an overlay
|
||||
(when target
|
||||
(let* ((targetstr (propertize (concat "-> " target " ")
|
||||
'face 'mu4e-system-face))
|
||||
;; mu4e-goto-docid docid t will take us just after the docid cookie
|
||||
;; and then we skip the mu4e-hdrs-fringe
|
||||
(start (+ (length mu4e-hdrs-fringe)
|
||||
(mu4e--goto-docid docid t)))
|
||||
;; mu4e-goto-docid docid t \will take us just after the docid cookie
|
||||
;; and then we skip the mu4e~hdrs-fringe
|
||||
(start (+ (length mu4e~hdrs-fringe)
|
||||
(mu4e~goto-docid docid t)))
|
||||
(overlay (make-overlay start (+ start (length targetstr)))))
|
||||
(overlay-put overlay 'display targetstr)
|
||||
docid))))))
|
||||
|
@ -129,7 +129,7 @@ headers in the region."
|
|||
the region, for moving to maildir TARGET. If target is not
|
||||
provided, function asks for it."
|
||||
(interactive)
|
||||
(unless (mu4e--docid-at-point)
|
||||
(unless (mu4e~docid-at-point)
|
||||
(error "No message at point."))
|
||||
(let* ((target (or target (mu4e-ask-maildir "Move message to: ")))
|
||||
(target (if (string= (substring target 0 1) "/")
|
||||
|
@ -139,7 +139,7 @@ provided, function asks for it."
|
|||
(when (or (file-directory-p fulltarget)
|
||||
(and (yes-or-no-p
|
||||
(format "%s does not exist. Create now?" fulltarget))
|
||||
(mu4e-proc-mkdir fulltarget)))
|
||||
(mu4e~proc-mkdir fulltarget)))
|
||||
(mu4e-mark-set 'move target))))
|
||||
|
||||
|
||||
|
@ -158,45 +158,45 @@ work well.
|
|||
If NO-CONFIRMATION is non-nil, do not ask the user for
|
||||
confirmation."
|
||||
(interactive)
|
||||
(if (zerop (hash-table-count mu4e--mark-map))
|
||||
(if (zerop (hash-table-count mu4e~mark-map))
|
||||
(message "Nothing is marked")
|
||||
(when (or no-confirmation
|
||||
(y-or-n-p (format "Sure you want to execute marks on %d message(s)?"
|
||||
(hash-table-count mu4e--mark-map))))
|
||||
(hash-table-count mu4e~mark-map))))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(let ((mark (nth 0 val)) (target (nth 1 val)))
|
||||
(case mark
|
||||
(move (mu4e-proc-move docid target))
|
||||
(read (mu4e-proc-move docid nil "+S-u-N"))
|
||||
(unread (mu4e-proc-move docid nil "-S+u"))
|
||||
(move (mu4e~proc-move docid target))
|
||||
(read (mu4e~proc-move docid nil "+S-u-N"))
|
||||
(unread (mu4e~proc-move docid nil "-S+u"))
|
||||
(trash
|
||||
(unless mu4e-trash-folder
|
||||
(error "`mu4e-trash-folder' not set"))
|
||||
(mu4e-proc-move docid mu4e-trash-folder "+T"))
|
||||
(delete (mu4e-proc-remove docid)))))
|
||||
mu4e--mark-map)
|
||||
(mu4e~proc-move docid mu4e-trash-folder "+T"))
|
||||
(delete (mu4e~proc-remove docid)))))
|
||||
mu4e~mark-map)
|
||||
(mu4e-mark-unmark-all)
|
||||
(message nil))))
|
||||
|
||||
(defun mu4e-mark-unmark-all ()
|
||||
"Unmark all marked messages."
|
||||
(interactive)
|
||||
(when (zerop (hash-table-count mu4e--mark-map))
|
||||
(when (zerop (hash-table-count mu4e~mark-map))
|
||||
(error "Nothing is marked"))
|
||||
(maphash
|
||||
(lambda (docid val)
|
||||
(save-excursion
|
||||
(when (mu4e--goto-docid docid)
|
||||
(when (mu4e~goto-docid docid)
|
||||
(mu4e-mark-set 'unmark))))
|
||||
mu4e--mark-map)
|
||||
mu4e~mark-map)
|
||||
;; in any case, clear the marks map
|
||||
(mu4e--mark-clear))
|
||||
(mu4e~mark-clear))
|
||||
|
||||
|
||||
(defun mu4e-mark-docid-marked-p (docid)
|
||||
"Is the given docid marked?"
|
||||
(when (gethash docid mu4e--mark-map) t))
|
||||
(when (gethash docid mu4e~mark-map) t))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
|
@ -207,7 +207,7 @@ function is to be called before any further action (like searching,
|
|||
quiting the buffer) is taken; returning t means 'take the following
|
||||
action', return nil means 'don't do anything'"
|
||||
(let ((marknum
|
||||
(if mu4e--mark-map (hash-table-count mu4e--mark-map) 0))
|
||||
(if mu4e~mark-map (hash-table-count mu4e~mark-map) 0))
|
||||
(what mu4e-headers-leave-behavior))
|
||||
(unless (or (= marknum 0) (eq what 'ignore) (eq what 'apply))
|
||||
;; if `mu4e-headers-leave-behavior' is not apply or ignore, ask the user
|
||||
|
|
|
@ -27,21 +27,18 @@
|
|||
(require 'mu4e-utils)
|
||||
(require 'mu4e-meta)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; internal vars
|
||||
|
||||
(defvar mu4e-buf nil "*internal* Buffer for results data.")
|
||||
(defvar mu4e~proc-buf nil "Buffer for results data.")
|
||||
(defconst mu4e~proc-name "*mu4e-proc*" "Name of the server process, buffer.")
|
||||
(defvar mu4e~proc-process nil "The mu-server process")
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defvar mu4e-path-docid-map
|
||||
(make-hash-table :size 32 :rehash-size 2 :test 'equal :weakness nil)
|
||||
"*internal* hash we use to keep a path=>docid mapping for message
|
||||
we added ourselves (ie., draft messages), so we can e.g. move them
|
||||
to the sent folder using their docid")
|
||||
|
||||
(defconst mu4e-server-name "*mu4e-server*"
|
||||
"*internal* Name of the server process, buffer.")
|
||||
|
||||
(defun mu4e-start-proc ()
|
||||
(defun mu4e~proc-start ()
|
||||
"Start the mu server process."
|
||||
(unless (file-executable-p mu4e-mu-binary)
|
||||
(error (format "`mu4e-mu-binary' (%S) not found" mu4e-mu-binary)))
|
||||
|
@ -49,61 +46,61 @@ to the sent folder using their docid")
|
|||
(args '("server"))
|
||||
(args (append args (when mu4e-mu-home
|
||||
(list (concat "--muhome=" mu4e-mu-home))))))
|
||||
(setq mu4e-buf "")
|
||||
(setq mu4e-mu-proc (apply 'start-process
|
||||
mu4e-server-name mu4e-server-name
|
||||
(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
|
||||
(when mu4e-mu-proc
|
||||
(set-process-query-on-exit-flag mu4e-mu-proc nil)
|
||||
(set-process-coding-system mu4e-mu-proc 'binary 'utf-8-unix)
|
||||
(set-process-filter mu4e-mu-proc 'mu4e-proc-filter)
|
||||
(set-process-sentinel mu4e-mu-proc 'mu4e-proc-sentinel))))
|
||||
(when mu4e~proc-process
|
||||
(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-kill-proc ()
|
||||
(defun mu4e~proc-kill ()
|
||||
"Kill the mu server process."
|
||||
(let* ((buf (get-buffer mu4e-server-name))
|
||||
(let* ((buf (get-buffer mu4e~proc-name))
|
||||
(proc (and 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 "quit"))
|
||||
(mu4e~proc-send-command "quit"))
|
||||
;; try sending SIGINT (C-c) to process, so it can exit gracefully
|
||||
(ignore-errors
|
||||
(signal-process proc 'SIGINT))))
|
||||
(setq
|
||||
mu4e-mu-proc nil
|
||||
mu4e-buf nil))
|
||||
mu4e~proc-process nil
|
||||
mu4e~proc-buf nil))
|
||||
|
||||
|
||||
(defun mu4e-proc-eat-sexp-from-buf ()
|
||||
"'Eat' the next s-expression from `mu4e-buf'. `mu4e-buf gets its
|
||||
(defun mu4e~proc-eat-sexp-from-buf ()
|
||||
"'Eat' the next s-expression from `mu4e~proc-buf'. `mu4e~proc-buf gets its
|
||||
contents from the mu-servers in the following form:
|
||||
\376<len-of-sexp>\376<sexp>
|
||||
Function returns this sexp, or nil if there was none. `mu4e-buf' is
|
||||
Function returns this sexp, or nil if there was none. `mu4e~proc-buf' is
|
||||
updated as well, with all processed sexp data removed."
|
||||
(when mu4e-buf
|
||||
(when mu4e~proc-buf
|
||||
;; TODO: maybe try a non-regexp solution?
|
||||
(let* ((b (string-match "\376\\([0-9]+\\)\376" mu4e-buf))
|
||||
(let* ((b (string-match "\376\\([0-9]+\\)\376" mu4e~proc-buf))
|
||||
(sexp-len
|
||||
(when b (string-to-number (match-string 1 mu4e-buf)))))
|
||||
;; does mu4e-buf contain the full sexp?
|
||||
(when (and b (>= (length mu4e-buf) (+ sexp-len (match-end 0))))
|
||||
(when b (string-to-number (match-string 1 mu4e~proc-buf)))))
|
||||
;; does mu4e~proc-buf contain the full sexp?
|
||||
(when (and b (>= (length mu4e~proc-buf) (+ sexp-len (match-end 0))))
|
||||
;; clear-up start
|
||||
(setq mu4e-buf (substring mu4e-buf (match-end 0)))
|
||||
(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.
|
||||
(let ((objcons
|
||||
(ignore-errors ;; note: this may fail if we killed the process
|
||||
;; in the middle
|
||||
(read-from-string
|
||||
(decode-coding-string (substring mu4e-buf 0 sexp-len) 'utf-8)))))
|
||||
(decode-coding-string (substring mu4e~proc-buf 0 sexp-len) 'utf-8)))))
|
||||
(when objcons
|
||||
(setq mu4e-buf (substring mu4e-buf sexp-len))
|
||||
(setq mu4e~proc-buf (substring mu4e~proc-buf sexp-len))
|
||||
(car objcons)))))))
|
||||
|
||||
|
||||
(defun mu4e-proc-filter (proc str)
|
||||
(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.
|
||||
|
@ -160,8 +157,8 @@ updated as well, with all processed sexp data removed."
|
|||
(:compose <reply|forward|edit|new> [:original<msg-sexp>] [:include <attach>])
|
||||
`mu4e-compose-func'."
|
||||
(mu4e-log 'misc "* Received %d byte(s)" (length str))
|
||||
(setq mu4e-buf (concat mu4e-buf str)) ;; update our buffer
|
||||
(let ((sexp (mu4e-proc-eat-sexp-from-buf)))
|
||||
(setq mu4e~proc-buf (concat mu4e~proc-buf str)) ;; update our buffer
|
||||
(let ((sexp (mu4e~proc-eat-sexp-from-buf)))
|
||||
(while sexp
|
||||
(mu4e-log 'from-server "%S" sexp)
|
||||
(cond
|
||||
|
@ -227,18 +224,18 @@ updated as well, with all processed sexp data removed."
|
|||
|
||||
(t (message "Unexpected data from server [%S]" sexp)))
|
||||
|
||||
(setq sexp (mu4e-proc-eat-sexp-from-buf)))))
|
||||
(setq sexp (mu4e~proc-eat-sexp-from-buf)))))
|
||||
|
||||
|
||||
;; error codes are defined in src/mu-util.h
|
||||
;;(defconst mu4e-xapian-empty 19 "Error code: xapian is empty/non-existent")
|
||||
|
||||
(defun mu4e-proc-sentinel (proc msg)
|
||||
(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-mu-proc nil)
|
||||
(setq mu4e-buf "") ;; clear any half-received sexps
|
||||
(setq mu4e~proc-process nil)
|
||||
(setq mu4e~proc-buf "") ;; clear any half-received sexps
|
||||
(cond
|
||||
((eq status 'signal)
|
||||
(cond
|
||||
|
@ -257,13 +254,13 @@ terminates."
|
|||
(t
|
||||
(message "Something bad happened to the mu server process")))))
|
||||
|
||||
(defun mu4e-proc-send-command (frm &rest args)
|
||||
(defun mu4e~proc-send-command (frm &rest args)
|
||||
"Send as command to the mu server process; start the process if needed."
|
||||
(unless (mu4e-proc-is-running)
|
||||
(mu4e-start-proc))
|
||||
(unless (mu4e~proc-is-running)
|
||||
(mu4e~proc-start))
|
||||
(let ((cmd (apply 'format frm args)))
|
||||
(mu4e-log 'to-server "%s" cmd)
|
||||
(process-send-string mu4e-mu-proc (concat cmd "\n"))))
|
||||
(process-send-string mu4e~proc-process (concat cmd "\n"))))
|
||||
|
||||
|
||||
(defun mu4e--docid-msgid-param (docid-or-msgid)
|
||||
|
@ -274,23 +271,23 @@ terminates."
|
|||
"docid:%d")
|
||||
docid-or-msgid))
|
||||
|
||||
(defun mu4e-proc-remove (docid)
|
||||
(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 "remove docid:%d" docid))
|
||||
(mu4e~proc-send-command "remove docid:%d" docid))
|
||||
|
||||
(defun mu4e-proc-find (query &optional maxnum)
|
||||
(defun mu4e~proc-find (query &optional maxnum)
|
||||
"Start a database query for QUERY, (optionally) getting up to
|
||||
MAXNUM results. 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
|
||||
(mu4e~proc-send-command
|
||||
"find query:\"%s\"%s" query
|
||||
(if maxnum (format " maxnum:%d" maxnum) "")))
|
||||
|
||||
(defun mu4e-proc-move (docid-or-msgid &optional maildir flags)
|
||||
(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
|
||||
|
@ -329,30 +326,30 @@ or (:error ) sexp, which are handled my `mu4e-update-func' and
|
|||
(path
|
||||
(when maildir
|
||||
(format " maildir:\"%s\"" maildir))))
|
||||
(mu4e-proc-send-command "move %s %s %s"
|
||||
(mu4e~proc-send-command "move %s %s %s"
|
||||
idparam (or flagstr "") (or path ""))))
|
||||
|
||||
|
||||
(defun mu4e-proc-index (path)
|
||||
(defun mu4e~proc-index (path)
|
||||
"Update the message database for filesystem PATH, which should
|
||||
point to some maildir directory structure."
|
||||
(mu4e-proc-send-command "index path:\"%s\"" path))
|
||||
(mu4e~proc-send-command "index path:\"%s\"" path))
|
||||
|
||||
(defun mu4e-proc-add (path maildir)
|
||||
(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>)."
|
||||
(mu4e-proc-send-command "add path:\"%s\" maildir:\"%s\""
|
||||
(mu4e~proc-send-command "add path:\"%s\" maildir:\"%s\""
|
||||
path maildir))
|
||||
|
||||
(defun mu4e-proc-sent (path 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>)."
|
||||
(mu4e-proc-send-command "sent path:\"%s\" maildir:\"%s\""
|
||||
(mu4e~proc-send-command "sent path:\"%s\" maildir:\"%s\""
|
||||
path maildir))
|
||||
|
||||
(defun mu4e-proc-compose (type &optional docid)
|
||||
(defun mu4e~proc-compose (type &optional docid)
|
||||
"Start composing a message of certain TYPE (a symbol, either
|
||||
`forward', `reply', `edit' or `new', based on an original
|
||||
message (ie, replying to, forwarding, editing) with DOCID or nil
|
||||
|
@ -364,14 +361,14 @@ for type `new'.
|
|||
(error "Unsupported compose-type %S" type))
|
||||
(unless (eq (null docid) (eq type 'new))
|
||||
(error "`new' implies docid not-nil, and vice-versa"))
|
||||
(mu4e-proc-send-command "compose type:%s docid:%d"
|
||||
(mu4e~proc-send-command "compose type:%s docid:%d"
|
||||
(symbol-name type) docid))
|
||||
|
||||
(defun mu4e-proc-mkdir (path)
|
||||
(defun mu4e~proc-mkdir (path)
|
||||
"Create a new maildir-directory at filesystem PATH."
|
||||
(mu4e-proc-send-command "mkdir path:\"%s\"" path))
|
||||
(mu4e~proc-send-command "mkdir path:\"%s\"" path))
|
||||
|
||||
(defun mu4e-proc-extract (action docid partidx &optional path what param)
|
||||
(defun mu4e~proc-extract (action docid partidx &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:
|
||||
|
@ -390,19 +387,19 @@ mean:
|
|||
(format "action:temp docid:%d index:%d what:%s param:\"%s\""
|
||||
docid partidx what param))
|
||||
(otherwise (error "Unsupported action %S" action))))))
|
||||
(mu4e-proc-send-command cmd)))
|
||||
(mu4e~proc-send-command cmd)))
|
||||
|
||||
|
||||
(defun mu4e-proc-ping ()
|
||||
(defun mu4e~proc-ping ()
|
||||
"Sends a ping to the mu server, expecting a (:pong ...) in
|
||||
response."
|
||||
(mu4e-proc-send-command "ping"))
|
||||
(mu4e~proc-send-command "ping"))
|
||||
|
||||
(defun mu4e-proc-view (docid-or-msgid)
|
||||
(defun mu4e~proc-view (docid-or-msgid)
|
||||
"Get one particular message based on its DOCID-OR-MSGID (keyword
|
||||
argument). The result will be delivered to the function registered
|
||||
as `mu4e-message-func'."
|
||||
(mu4e-proc-send-command "view %s"
|
||||
(mu4e~proc-send-command "view %s"
|
||||
(mu4e--docid-msgid-param docid-or-msgid)))
|
||||
|
||||
(provide 'mu4e-proc)
|
||||
|
|
|
@ -38,7 +38,7 @@ dir already existed, or has been created, nil otherwise."
|
|||
(cond
|
||||
((file-directory-p dir) t)
|
||||
((yes-or-no-p (format "%s does not exist yes. Create now?" dir))
|
||||
(mu4e-proc-mkdir dir))
|
||||
(mu4e~proc-mkdir dir))
|
||||
(t nil)))
|
||||
|
||||
(defun mu4e-check-requirements ()
|
||||
|
@ -287,6 +287,36 @@ Also see `mu/flags-to-string'.
|
|||
((< size 1000) (format "%d" size))
|
||||
(t (propertize "?" 'face 'mu4e-system-face))))
|
||||
|
||||
;; functions for org-contacts
|
||||
(defun mu4e-view-snarf-from (name-or-email)
|
||||
"Get the From:-data for the current message; NAME-OR-EMAIL should
|
||||
be a symbol 'name or 'email to get the corresponding field. If the
|
||||
field is not found, \"\" is returned.
|
||||
|
||||
You can use this with e.g. org-contact with a template like:
|
||||
(\"c\" \"Contacts\" entry (file \"~/Org/contacts.org\")
|
||||
\"* %(mu4e-view-snarf-from 'name)
|
||||
:PROPERTIES:
|
||||
:EMAIL: %(mu4e-view-snarf-from 'email)
|
||||
:END:\")))
|
||||
|
||||
See the `org-contacts' documentation for more details."
|
||||
;; FIXME: we need to explictly go to some view buffer, since when using this
|
||||
;; from org-capture, we'll be taken to the capture buffer instead.
|
||||
(with-current-buffer mu4e-view-buffer-name
|
||||
(unless (eq major-mode 'mu4e-view-mode)
|
||||
(error "Not in mu4e-view mode."))
|
||||
(unless mu4e-current-msg
|
||||
(error "No current message."))
|
||||
(let ((from (car-safe (plist-get mu4e-current-msg :from))))
|
||||
(cond
|
||||
((not from) "") ;; nothing found
|
||||
((eq name-or-email 'name)
|
||||
(or (car-safe from) ""))
|
||||
((eq name-or-email 'email)
|
||||
(or (cdr-safe from) ""))
|
||||
(t (error "Not supported: %S" name-or-email))))))
|
||||
|
||||
|
||||
(defun mu4e-body-text (msg)
|
||||
"Get the body in text form for this message, which is either :body-txt,
|
||||
|
@ -350,7 +380,7 @@ processing takes part in the background, unless buf is non-nil."
|
|||
;; there may be an error, give the user up to 5 seconds to check
|
||||
(when maybe-error
|
||||
(sit-for 5))
|
||||
(mu4e-proc-index mu4e-maildir)
|
||||
(mu4e~proc-index mu4e-maildir)
|
||||
(let ((buf (process-buffer proc)))
|
||||
(when (buffer-live-p buf)
|
||||
(kill-buffer buf))))))))
|
||||
|
@ -497,7 +527,7 @@ that has a live window), and vice versa."
|
|||
((eq major-mode 'mu4e-hdrs-mode)
|
||||
mu4e-view-buffer)
|
||||
((eq major-mode 'mu4e-view-mode)
|
||||
mu4e-hdrs-buffer)))
|
||||
mu4e~hdrs-buffer)))
|
||||
(other-win (and other-buf (get-buffer-window other-buf))))
|
||||
(if (window-live-p other-win)
|
||||
(select-window other-win)
|
||||
|
@ -526,11 +556,7 @@ that has a live window), and vice versa."
|
|||
process."
|
||||
(let ((type (plist-get info :info)))
|
||||
(cond
|
||||
((eq type 'add)
|
||||
;; update our path=>docid map; we use this when composing messages to
|
||||
;; add draft messages to the db, so when we're sending them, we can move
|
||||
;; to the sent folder using the `mu4e-proc-move'.
|
||||
(puthash (plist-get info :path) (plist-get info :docid) mu4e-path-docid-map))
|
||||
((eq type 'add) t) ;; do nothing
|
||||
((eq type 'index)
|
||||
(if (eq (plist-get info :status) 'running)
|
||||
(message (format "Indexing... processed %d, updated %d"
|
||||
|
@ -555,9 +581,9 @@ process."
|
|||
(defvar mu4e-update-timer nil
|
||||
"*internal* The mu4e update timer.")
|
||||
|
||||
(defun mu4e-proc-is-running ()
|
||||
(defun mu4e~proc-is-running ()
|
||||
"Whether the mu process is running."
|
||||
(and mu4e-mu-proc (eq (process-status mu4e-mu-proc) 'run)))
|
||||
(and mu4e~proc-process (eq (process-status mu4e~proc-process) 'run)))
|
||||
|
||||
|
||||
(defun* mu4e (&key (hide-ui nil))
|
||||
|
@ -567,7 +593,7 @@ server has the expected values. If keyword argument :hide-ui is
|
|||
non-nil, don't show the UI."
|
||||
(interactive)
|
||||
;; if we're already running, simply go to the main view
|
||||
(if (mu4e-proc-is-running)
|
||||
(if (mu4e~proc-is-running)
|
||||
(unless hide-ui
|
||||
(mu4e-main-view))
|
||||
(progn
|
||||
|
@ -594,7 +620,7 @@ non-nil, don't show the UI."
|
|||
(message "Started mu4e with %d message%s in store"
|
||||
doccount (if (= doccount 1) "" "s")))))
|
||||
;; send the ping
|
||||
(mu4e-proc-ping))))))
|
||||
(mu4e~proc-ping))))))
|
||||
|
||||
(defun mu4e-quit()
|
||||
"Quit the mu4e session."
|
||||
|
@ -604,7 +630,7 @@ non-nil, don't show the UI."
|
|||
(when mu4e-update-timer
|
||||
(cancel-timer mu4e-update-timer)
|
||||
(setq mu4e-update-timer nil))
|
||||
(mu4e-kill-proc)
|
||||
(mu4e~proc-kill)
|
||||
(kill-buffer)))
|
||||
|
||||
|
||||
|
|
|
@ -483,9 +483,9 @@ in which case it will be equal to `:to'.)")
|
|||
|
||||
;; headers
|
||||
(defvar mu4e-last-expr nil "*internal* The most recent search expression.")
|
||||
(defconst mu4e-hdrs-buffer-name "*mu4e-headers*"
|
||||
(defconst mu4e~hdrs-buffer-name "*mu4e-headers*"
|
||||
"*internal* Name of the buffer for message headers.")
|
||||
(defvar mu4e-hdrs-buffer nil "*internal* Buffer for message headers")
|
||||
(defvar mu4e~hdrs-buffer nil "*internal* Buffer for message headers")
|
||||
|
||||
;; view
|
||||
(defconst mu4e-view-buffer-name "*mu4e-view*"
|
||||
|
@ -503,10 +503,6 @@ viewed in view mode.")
|
|||
(defconst mu4e-log-buffer-name "*mu4e-log*"
|
||||
"*internal* Name of the logging buffer.")
|
||||
|
||||
(defvar mu4e-mu-proc nil "*internal* The mu-server process")
|
||||
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; misc other stuff
|
||||
|
@ -523,66 +519,66 @@ viewed in view mode.")
|
|||
;; our handlers funcs
|
||||
;; these handler funcs define what happens when we receive a certain message
|
||||
;; from the server
|
||||
(defun mu4e--default-handler (&rest args)
|
||||
(defun mu4e~default-handler (&rest args)
|
||||
"*internal* Dummy handler function."
|
||||
(error "Not handled: %S" args))
|
||||
|
||||
(defvar mu4e-error-func 'mu4e--default-handler
|
||||
(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.")
|
||||
`mu4e~proc-filter' for the format.")
|
||||
|
||||
(defvar mu4e-update-func 'mu4e--default-handler
|
||||
(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.")
|
||||
`mu4e~proc-filter' for the format.")
|
||||
|
||||
(defvar mu4e-remove-func 'mu4e--default-handler
|
||||
(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
|
||||
(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
|
||||
(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.")
|
||||
argument. See `mu4e~proc-filter' for the format.")
|
||||
|
||||
(defvar mu4e-header-func 'mu4e--default-handler
|
||||
(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.")
|
||||
`mu4e~proc-filter' for the format.")
|
||||
|
||||
(defvar mu4e-found-func 'mu4e--default-handler
|
||||
(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.")
|
||||
`mu4e~proc-filter' for the format.")
|
||||
|
||||
(defvar mu4e-erase-func 'mu4e--default-handler
|
||||
(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.")
|
||||
`mu4e~proc-filter' for the format.")
|
||||
|
||||
(defvar mu4e-compose-func 'mu4e--default-handler
|
||||
(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
|
||||
symbol (either reply or forward). See `mu4e~proc-filter' for the
|
||||
format of <msg-plist>.")
|
||||
|
||||
(defvar mu4e-info-func 'mu4e--default-handler
|
||||
(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
|
||||
(defvar mu4e-pong-func 'mu4e~default-handler
|
||||
"A function called for each (:pong type ....) sexp received from
|
||||
the server process.")
|
||||
|
||||
(defvar mu4e-temp-func 'mu4e--default-handler
|
||||
(defvar mu4e-temp-func 'mu4e~default-handler
|
||||
"A function called for each (:temp <file> <cookie>) sexp received
|
||||
from the server process.")
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -29,19 +29,23 @@
|
|||
(require 'mu4e-utils) ;; utility functions
|
||||
(require 'mu4e-vars)
|
||||
(require 'mu4e-mark)
|
||||
(require 'mu4e-proc)
|
||||
|
||||
;; we prefer the improved fill-region
|
||||
(require 'filladapt nil 'noerror)
|
||||
(require 'comint)
|
||||
|
||||
;; some buffer-local variables
|
||||
(defvar mu4e--view-hdrs-buffer nil
|
||||
(defvar mu4e~view-hdrs-buffer nil
|
||||
"*internal* Headers buffer connected to this view.")
|
||||
|
||||
(defvar mu4e~view-lines-wrapped nil "*internal* Whether lines are wrapped.")
|
||||
(defvar mu4e~view-cited-hidden nil "*internal* Whether cited lines are hidden.")
|
||||
|
||||
(defun mu4e-view-message-with-msgid (msgid)
|
||||
"View message with MSGID. This is meant for external programs
|
||||
wanting to show specific messages - for example, `mu4e-org'."
|
||||
(mu4e-proc-view msgid))
|
||||
(mu4e~proc-view msgid))
|
||||
|
||||
(defun mu4e-view-message-text (msg)
|
||||
"Return the message to display (as a string), based on the MSG
|
||||
|
@ -52,16 +56,16 @@ plist."
|
|||
(let ((fieldname (cdr (assoc field mu4e-header-names)))
|
||||
(fieldval (plist-get msg field)))
|
||||
(case field
|
||||
(:subject (mu4e-view-header fieldname fieldval))
|
||||
(:path (mu4e-view-header fieldname fieldval))
|
||||
(:maildir (mu4e-view-header fieldname fieldval))
|
||||
(:flags (mu4e-view-header fieldname
|
||||
(:subject (mu4e~view-construct-header fieldname fieldval))
|
||||
(:path (mu4e~view-construct-header fieldname fieldval))
|
||||
(:maildir (mu4e~view-construct-header fieldname fieldval))
|
||||
(:flags (mu4e~view-construct-header fieldname
|
||||
(if fieldval (format "%S" fieldval) "")))
|
||||
;; contact fields
|
||||
(:to (mu4e-view-contacts msg field))
|
||||
(:from (mu4e-view-contacts msg field))
|
||||
(:cc (mu4e-view-contacts msg field))
|
||||
(:bcc (mu4e-view-contacts msg field))
|
||||
(:to (mu4e~view-construct-contacts msg field))
|
||||
(:from (mu4e~view-construct-contacts msg field))
|
||||
(:cc (mu4e~view-construct-contacts msg field))
|
||||
(:bcc (mu4e~view-construct-contacts msg field))
|
||||
|
||||
;; if we (`user-mail-address' are the From, show To, otherwise,
|
||||
;; show From
|
||||
|
@ -69,21 +73,21 @@ plist."
|
|||
(let* ((from (plist-get msg :from))
|
||||
(from (and from (cdar from))))
|
||||
(if (and from (string-match mu4e-user-mail-address-regexp from))
|
||||
(mu4e-view-contacts msg :to)
|
||||
(mu4e-view-contacts msg :from))))
|
||||
(mu4e~view-construct-contacts msg :to)
|
||||
(mu4e~view-construct-contacts msg :from))))
|
||||
;; date
|
||||
(:date
|
||||
(let ((datestr
|
||||
(when fieldval (format-time-string mu4e-view-date-format
|
||||
fieldval))))
|
||||
(if datestr (mu4e-view-header fieldname datestr) "")))
|
||||
(if datestr (mu4e~view-construct-header fieldname datestr) "")))
|
||||
;; size
|
||||
(:size
|
||||
(let* (size (mu4e-view-size msg)
|
||||
(sizestr (when size (format "%d bytes" size))))
|
||||
(if sizestr (mu4e-view-header fieldname sizestr))))
|
||||
(if sizestr (mu4e~view-construct-header fieldname sizestr))))
|
||||
;; attachments
|
||||
(:attachments (mu4e-view-attachments msg))
|
||||
(:attachments (mu4e~view-construct-attachments msg))
|
||||
(t (error "Unsupported field: %S" field)))))
|
||||
mu4e-view-fields "")
|
||||
"\n"
|
||||
|
@ -95,8 +99,8 @@ plist."
|
|||
'In sync' here means that moving to the next/previous message in
|
||||
the the message view affects HDRSBUF, as does marking etc. If
|
||||
UPDATE is nil, the current message may be (visually) 'massaged',
|
||||
based on the settings of `mu4e-view-wrap-lines' and
|
||||
`mu4e-view-hide-cited'.
|
||||
based on the settings of `mu4e~view-wrap-lines' and
|
||||
`mu4e~view-hide-cited'.
|
||||
|
||||
As a side-effect, a message that is being viewed loses its 'unread'
|
||||
marking if it still had that."
|
||||
|
@ -112,30 +116,30 @@ marking if it still had that."
|
|||
(setq ;; these are buffer-local
|
||||
buffer-read-only t
|
||||
mu4e-current-msg msg
|
||||
mu4e--view-hdrs-buffer hdrsbuf
|
||||
mu4e-link-map (make-hash-table :size 32 :rehash-size 2 :weakness nil))
|
||||
mu4e~view-hdrs-buffer hdrsbuf
|
||||
mu4e~view-link-map (make-hash-table :size 32 :rehash-size 2 :weakness nil))
|
||||
|
||||
(switch-to-buffer buf)
|
||||
(goto-char (point-min))
|
||||
|
||||
(mu4e-color-cited)
|
||||
(mu4e-mark-footer)
|
||||
(mu4e-make-urls-clickable)
|
||||
(mu4e~view-fontify-cited)
|
||||
(mu4e~view-fontify-footer)
|
||||
(mu4e~view-make-urls-clickable)
|
||||
|
||||
(unless update
|
||||
;; if we're showing the message for the first time, use the values of
|
||||
;; user-settable variables `mu4e-view-wrap-lines' and
|
||||
;; `mu4e-view-hide-cited' to determine whether we should wrap/hide
|
||||
;; user-settable variables `mu4e~view-wrap-lines' and
|
||||
;; `mu4e~view-hide-cited' to determine whether we should wrap/hide
|
||||
(progn
|
||||
(when mu4e-view-wrap-lines (mu4e-view-wrap-lines))
|
||||
(when mu4e-view-hide-cited (mu4e-view-hide-cited))))
|
||||
(when mu4e~view-lines-wrapped (mu4e~view-wrap-lines))
|
||||
(when mu4e~view-cited-hidden (mu4e~view-hide-cited))))
|
||||
|
||||
;; no use in trying to set flags again
|
||||
(unless update
|
||||
(mu4e-view-mark-as-read-maybe)))))
|
||||
(mu4e~view-mark-as-read-maybe)))))
|
||||
|
||||
|
||||
(defun mu4e-view-header (key val &optional dont-propertize-val)
|
||||
(defun mu4e~view-construct-header (key val &optional dont-propertize-val)
|
||||
"Return header KEY with value VAL if VAL is non-nil. If
|
||||
DONT-PROPERTIZE-VAL is non-nil, do not add text-properties to VAL."
|
||||
(if val
|
||||
|
@ -155,7 +159,7 @@ DONT-PROPERTIZE-VAL is non-nil, do not add text-properties to VAL."
|
|||
""))
|
||||
|
||||
|
||||
(defun mu4e-view-contacts (msg field)
|
||||
(defun mu4e~view-construct-contacts (msg field)
|
||||
"Add a header for a contact field (ie., :to, :from, :cc, :bcc)."
|
||||
(let* ((lst (plist-get msg field))
|
||||
(fieldname (cdr (assoc field mu4e-header-names)))
|
||||
|
@ -173,11 +177,11 @@ DONT-PROPERTIZE-VAL is non-nil, do not add text-properties to VAL."
|
|||
'help-echo email)))
|
||||
lst ", "))))
|
||||
(if contacts
|
||||
(mu4e-view-header fieldname contacts)
|
||||
(mu4e~view-construct-header fieldname contacts)
|
||||
"")))
|
||||
|
||||
|
||||
(defun mu4e-open-save-attach-func (msg attachnum is-open)
|
||||
(defun mu4e~view-open-save-attach-func (msg attachnum is-open)
|
||||
"Return a function that offers to save attachment NUM. If IS-OPEN
|
||||
is nil, and otherwise open it."
|
||||
(lexical-let ((msg msg) (attachnum attachnum) (is-open is-open))
|
||||
|
@ -189,7 +193,7 @@ is nil, and otherwise open it."
|
|||
|
||||
;; note -- attachments have an index which is needed for the backend, which does
|
||||
;; not necessarily follow 1,2,3,4 etc.
|
||||
(defun mu4e-view-attachments (msg)
|
||||
(defun mu4e~view-construct-attachments (msg)
|
||||
"Display attachment information; the field looks like something like:
|
||||
:attachments ((:index 4 :name \"test123.doc\"
|
||||
:mime-type \"application/msword\" :size 1234))."
|
||||
|
@ -202,11 +206,11 @@ is nil, and otherwise open it."
|
|||
(size (plist-get att :size))
|
||||
(map (make-sparse-keymap)))
|
||||
(incf id)
|
||||
(define-key map [mouse-2] (mu4e-open-save-attach-func msg id nil))
|
||||
(define-key map [?\r] (mu4e-open-save-attach-func msg id nil))
|
||||
(define-key map [S-mouse-2](mu4e-open-save-attach-func msg id t))
|
||||
(define-key map [mouse-2] (mu4e~view-open-save-attach-func msg id nil))
|
||||
(define-key map [?\r] (mu4e~view-open-save-attach-func msg id nil))
|
||||
(define-key map [S-mouse-2](mu4e~view-open-save-attach-func msg id t))
|
||||
(define-key map (kbd "<S-return>")
|
||||
(mu4e-open-save-attach-func msg id t))
|
||||
(mu4e~view-open-save-attach-func msg id t))
|
||||
(concat
|
||||
(propertize (format "[%d]" id) 'face 'mu4e-view-attach-number-face)
|
||||
(propertize name 'face 'mu4e-view-link-face
|
||||
|
@ -214,10 +218,10 @@ is nil, and otherwise open it."
|
|||
(when (and size (> size 0))
|
||||
(concat (format "(%s)"
|
||||
(propertize (mu4e-display-size size)
|
||||
'face 'mu4e-view-header-key-face)))))))
|
||||
'face 'mu4e-header-key-face)))))))
|
||||
(plist-get msg :attachments) ", ")))
|
||||
(unless (zerop id)
|
||||
(mu4e-view-header (format "Attachments(%d)" id) attstr t))))
|
||||
(mu4e~view-construct-header (format "Attachments(%d)" id) attstr t))))
|
||||
|
||||
|
||||
(defvar mu4e-view-mode-map nil
|
||||
|
@ -263,11 +267,11 @@ is nil, and otherwise open it."
|
|||
#'(lambda () (interactive) (scroll-up -1)))
|
||||
|
||||
;; navigation between messages
|
||||
(define-key map "p" 'mu4e--view-prev-header)
|
||||
(define-key map "n" 'mu4e--view-next-header)
|
||||
(define-key map "p" 'mu4e~view-prev-header)
|
||||
(define-key map "n" 'mu4e~view-next-header)
|
||||
;; the same
|
||||
(define-key map (kbd "<M-down>") 'mu4e--view-next-header)
|
||||
(define-key map (kbd "<M-up>") 'mu4e--view-prev-header)
|
||||
(define-key map (kbd "<M-down>") 'mu4e~view-next-header)
|
||||
(define-key map (kbd "<M-up>") 'mu4e~view-prev-header)
|
||||
|
||||
;; switching to view mode (if it's visible)
|
||||
(define-key map "y" 'mu4e-select-other-view)
|
||||
|
@ -315,7 +319,7 @@ is nil, and otherwise open it."
|
|||
(define-key menumap [hide-cited]
|
||||
'("Toggle hide cited" . mu4e-view-toggle-hide-cited))
|
||||
(define-key menumap [raw-view]
|
||||
'("View raw message" . mu4e-raw-view))
|
||||
'("View raw message" . mu4e-view-raw-message))
|
||||
(define-key menumap [pipe]
|
||||
'("Pipe through shell" . mu4e-view-pipe))
|
||||
;; (define-key menumap [inspect]
|
||||
|
@ -347,27 +351,24 @@ is nil, and otherwise open it."
|
|||
(define-key menumap [jump] '("Jump to maildir" . mu4e-jump-to-maildir))
|
||||
|
||||
(define-key menumap [sepa4] '("--"))
|
||||
(define-key menumap [next] '("Next" . mu4e--view-next-header))
|
||||
(define-key menumap [previous] '("Previous" . mu4e--view-prev-header)))
|
||||
(define-key menumap [next] '("Next" . mu4e~view-next-header))
|
||||
(define-key menumap [previous] '("Previous" . mu4e~view-prev-header)))
|
||||
map)))
|
||||
|
||||
(fset 'mu4e-view-mode-map mu4e-view-mode-map)
|
||||
|
||||
|
||||
(defvar mu4e-lines-wrapped nil "*internal* Whether lines are wrapped.")
|
||||
(defvar mu4e-cited-hidden nil "*internal* Whether cited lines are hidden.")
|
||||
|
||||
(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-hdrs-buffer)
|
||||
(make-local-variable 'mu4e~view-hdrs-buffer)
|
||||
(make-local-variable 'mu4e-current-msg)
|
||||
(make-local-variable 'mu4e-link-map)
|
||||
(make-local-variable 'mu4e~view-link-map)
|
||||
|
||||
(make-local-variable 'mu4e-lines-wrapped)
|
||||
(make-local-variable 'mu4e-cited-hidden)
|
||||
(make-local-variable 'mu4e~view-lines-wrapped)
|
||||
(make-local-variable 'mu4e~view-cited-hidden)
|
||||
|
||||
(setq buffer-undo-list t) ;; don't record undo info
|
||||
|
||||
|
@ -386,7 +387,7 @@ is nil, and otherwise open it."
|
|||
;; we mark messages are as read when we leave the message; i.e., when skipping
|
||||
;; to the next/previous one, or leaving the view buffer altogether.
|
||||
|
||||
(defun mu4e-view-mark-as-read-maybe ()
|
||||
(defun mu4e~view-mark-as-read-maybe ()
|
||||
"Clear the current message's New/Unread status and set it to
|
||||
Seen; if the message is not New/Unread, do nothing."
|
||||
(when mu4e-current-msg
|
||||
|
@ -394,9 +395,9 @@ Seen; if the message is not New/Unread, do nothing."
|
|||
(docid (plist-get mu4e-current-msg :docid)))
|
||||
;; is it a new message?
|
||||
(when (or (member 'unread flags) (member 'new flags))
|
||||
(mu4e-proc-move docid nil "+S-u-N")))))
|
||||
(mu4e~proc-move docid nil "+S-u-N")))))
|
||||
|
||||
(defun mu4e-color-cited ()
|
||||
(defun mu4e~view-fontify-cited ()
|
||||
"Colorize message content based on the citation level."
|
||||
(save-excursion
|
||||
(let ((more-lines t))
|
||||
|
@ -426,7 +427,7 @@ Seen; if the message is not New/Unread, do nothing."
|
|||
;; would lead to an infinite loop
|
||||
(not (= (point-max) (line-end-position)))))))))
|
||||
|
||||
(defun mu4e-mark-footer ()
|
||||
(defun mu4e~view-fontify-footer ()
|
||||
"Give the message footers a distinctive color."
|
||||
(let ((inhibit-read-only t))
|
||||
(save-excursion
|
||||
|
@ -436,15 +437,15 @@ Seen; if the message is not New/Unread, do nothing."
|
|||
(when p
|
||||
(add-text-properties p (point-max) '(face mu4e-footer-face)))))))
|
||||
|
||||
(defvar mu4e-link-map nil
|
||||
(defvar mu4e~view-link-map nil
|
||||
"*internal* A map of some number->url so we can jump to url by number.")
|
||||
|
||||
(defconst mu4e-url-regexp
|
||||
(defconst mu4e~view-url-regexp
|
||||
"\\(https?://[-+a-zA-Z0-9.?_$%/+&#@!~,:;=/()]+\\)"
|
||||
"*internal* regexp that matches URLs; match-string 1 will contain
|
||||
the matched URL, if any.")
|
||||
|
||||
(defun mu4e-browse-url-func (url)
|
||||
(defun mu4e~view-browse-url-func (url)
|
||||
"Return a function that executes `browse-url' with URL."
|
||||
(lexical-let ((url url))
|
||||
(lambda ()
|
||||
|
@ -453,18 +454,18 @@ Seen; if the message is not New/Unread, do nothing."
|
|||
|
||||
|
||||
;; this is fairly simplistic...
|
||||
(defun mu4e-make-urls-clickable ()
|
||||
(defun mu4e~view-make-urls-clickable ()
|
||||
"Turn things that look like URLs into clickable things, and
|
||||
number them so they can be opened using `mu4e-view-go-to-url'."
|
||||
(let ((num 0))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward mu4e-url-regexp nil t)
|
||||
(while (re-search-forward mu4e~view-url-regexp nil t)
|
||||
(let ((url (match-string 0))
|
||||
(map (make-sparse-keymap)))
|
||||
(define-key map [mouse-2] (mu4e-browse-url-func url))
|
||||
(define-key map [?\r] (mu4e-browse-url-func url))
|
||||
(puthash (incf num) url mu4e-link-map)
|
||||
(define-key map [mouse-2] (mu4e~view-browse-url-func url))
|
||||
(define-key map [?\r] (mu4e~view-browse-url-func url))
|
||||
(puthash (incf num) url mu4e~view-link-map)
|
||||
(add-text-properties 0 (length url)
|
||||
`(face mu4e-view-link-face
|
||||
mouse-face highlight
|
||||
|
@ -474,80 +475,64 @@ number them so they can be opened using `mu4e-view-go-to-url'."
|
|||
'face 'mu4e-view-url-number-face))))))))
|
||||
|
||||
|
||||
;; functions for org-contacts
|
||||
(defun mu4e-view-snarf-from (name-or-email)
|
||||
"Get the From:-data for the current message; NAME-OR-EMAIL should
|
||||
be a symbol 'name or 'email to get the corresponding field. If the
|
||||
field is not found, \"\" is returned.
|
||||
|
||||
You can use this with e.g. org-contact with a template like:
|
||||
(\"c\" \"Contacts\" entry (file \"~/Org/contacts.org\")
|
||||
\"* %(mu4e-view-snarf-from 'name)
|
||||
:PROPERTIES:
|
||||
:EMAIL: %(mu4e-view-snarf-from 'email)
|
||||
:END:\")))
|
||||
|
||||
See the `org-contacts' documentation for more details."
|
||||
;; FIXME: we need to explictly go to some view buffer, since when using this
|
||||
;; from org-capture, we'll be taken to the capture buffer instead.
|
||||
(with-current-buffer mu4e-view-buffer-name
|
||||
(unless (eq major-mode 'mu4e-view-mode)
|
||||
(error "Not in mu4e-view mode."))
|
||||
(unless mu4e-current-msg
|
||||
(error "No current message."))
|
||||
(let ((from (car-safe (plist-get mu4e-current-msg :from))))
|
||||
(cond
|
||||
((not from) "") ;; nothing found
|
||||
((eq name-or-email 'name)
|
||||
(or (car-safe from) ""))
|
||||
((eq name-or-email 'email)
|
||||
(or (cdr-safe from) ""))
|
||||
(t (error "Not supported: %S" name-or-email))))))
|
||||
|
||||
(defun mu4e-view-wrap-lines ()
|
||||
(defun mu4e~view-wrap-lines ()
|
||||
"Wrap lines in the message body."
|
||||
(save-excursion
|
||||
(let ((inhibit-read-only t))
|
||||
(goto-char (point-min))
|
||||
(when (search-forward "\n\n") ;; search for the message body
|
||||
(fill-region (point) (point-max)))
|
||||
(setq mu4e-lines-wrapped t))))
|
||||
(setq mu4e~view-lines-wrapped t))))
|
||||
|
||||
(defun mu4e-view-hide-cited ()
|
||||
(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 "^[:blank:]*>")
|
||||
(setq mu4e-cited-hidden t))))
|
||||
(setq mu4e~view-cited-hidden t))))
|
||||
|
||||
|
||||
(defun mu4e~view-hdrs-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."
|
||||
(when (buffer-live-p mu4e~view-hdrs-buffer)
|
||||
(with-current-buffer mu4e~view-hdrs-buffer
|
||||
(mu4e~hdrs-move lines))))
|
||||
|
||||
(defun mu4e~view-next-header()(interactive)(mu4e~view-hdrs-move 1))
|
||||
(defun mu4e~view-prev-header()(interactive)(mu4e~view-hdrs-move -1))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Interactive functions
|
||||
|
||||
|
||||
(defun mu4e-view-toggle-wrap-lines ()
|
||||
"Toggle line wrap in the message body."
|
||||
(interactive)
|
||||
(if mu4e-lines-wrapped
|
||||
(if mu4e~view-lines-wrapped
|
||||
(mu4e-view-refresh)
|
||||
(mu4e-view-wrap-lines)))
|
||||
(mu4e~view-wrap-lines)))
|
||||
|
||||
(defun mu4e-view-toggle-hide-cited ()
|
||||
"Toggle hiding of cited lines in the message body."
|
||||
(interactive)
|
||||
(if mu4e-cited-hidden
|
||||
(if mu4e~view-cited-hidden
|
||||
(mu4e-view-refresh)
|
||||
(mu4e-view-hide-cited)))
|
||||
(mu4e~view-hide-cited)))
|
||||
|
||||
(defun mu4e-view-refresh ()
|
||||
"Redisplay the current message, without wrapped lines or hidden
|
||||
citations."
|
||||
(interactive)
|
||||
(mu4e-view mu4e-current-msg mu4e--view-hdrs-buffer t)
|
||||
(mu4e-view mu4e-current-msg mu4e~view-hdrs-buffer t)
|
||||
(setq
|
||||
mu4e-lines-wrapped nil
|
||||
mu4e-cited-hidden nil))
|
||||
mu4e~view-lines-wrapped nil
|
||||
mu4e~view-cited-hidden nil))
|
||||
|
||||
(defun mu4e-view-kill-buffer-and-window ()
|
||||
"Quit the message view and return to the headers."
|
||||
|
@ -558,18 +543,6 @@ citations."
|
|||
(kill-buffer-and-window)
|
||||
(kill-buffer)))))
|
||||
|
||||
(defun mu4e--view-hdrs-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."
|
||||
(when (buffer-live-p mu4e--view-hdrs-buffer)
|
||||
(with-current-buffer mu4e--view-hdrs-buffer
|
||||
(mu4e--hdrs-move lines))))
|
||||
|
||||
(defun mu4e--view-next-header()(interactive)(mu4e--view-hdrs-move 1))
|
||||
(defun mu4e--view-prev-header()(interactive)(mu4e--view-hdrs-move -1))
|
||||
|
||||
|
||||
(defun mu4e-view-action (&optional msg)
|
||||
"Ask user for some action to apply on MSG (or message-at-point,
|
||||
if nil), then do it. The actions are specified in
|
||||
|
@ -582,7 +555,7 @@ if nil), then do it. The actions are specified in
|
|||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; attachment handling
|
||||
(defun mu4e--get-attach-num (prompt msg)
|
||||
(defun mu4e~view-get-attach-num (prompt msg)
|
||||
"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."
|
||||
|
@ -593,7 +566,7 @@ if nil), then do it. The actions are specified in
|
|||
(read-number (format "%s (1): " prompt) 1)
|
||||
(read-number (format "%s (1-%d): " prompt count)))))
|
||||
|
||||
(defun mu4e--get-attach (msg attnum)
|
||||
(defun mu4e~view-get-attach (msg attnum)
|
||||
"Return the attachment plist in MSG corresponding to attachment
|
||||
number ATTNUM."
|
||||
(let ((attlist (plist-get msg :attachments)))
|
||||
|
@ -607,8 +580,8 @@ message-at-point if nil) to disk."
|
|||
(error "`mu4e-attachment-dir' is not set"))
|
||||
(let* ((msg (or msg (mu4e-message-at-point)))
|
||||
(attnum (or attnum
|
||||
(mu4e--get-attach-num "Attachment to save" msg)))
|
||||
(att (mu4e--get-attach msg attnum))
|
||||
(mu4e~view-get-attach-num "Attachment to save" msg)))
|
||||
(att (mu4e~view-get-attach msg attnum))
|
||||
(path (concat mu4e-attachment-dir "/" (plist-get att :name)))
|
||||
(index (plist-get att :index))
|
||||
(retry t))
|
||||
|
@ -617,7 +590,7 @@ message-at-point if nil) to disk."
|
|||
(setq retry
|
||||
(and (file-exists-p path)
|
||||
(not (y-or-n-p (concat "Overwrite " path "?"))))))
|
||||
(mu4e-proc-extract
|
||||
(mu4e~proc-extract
|
||||
'save (plist-get msg :docid) index path)))
|
||||
|
||||
|
||||
|
@ -627,42 +600,42 @@ message-at-point if nil)."
|
|||
(interactive)
|
||||
(let* ((msg (or msg (mu4e-message-at-point)))
|
||||
(attnum (or attnum
|
||||
(mu4e--get-attach-num "Attachment to open" msg)))
|
||||
(att (mu4e--get-attach msg attnum))
|
||||
(mu4e~view-get-attach-num "Attachment to open" msg)))
|
||||
(att (mu4e~view-get-attach msg attnum))
|
||||
(index (plist-get att :index)))
|
||||
(mu4e-proc-extract 'open (plist-get msg :docid) index)))
|
||||
(mu4e~proc-extract 'open (plist-get msg :docid) index)))
|
||||
|
||||
|
||||
(defun mu4e--temp-action (docid index what &optional param)
|
||||
(defun mu4e~temp-action (docid index what &optional param)
|
||||
"Open attachment INDEX for message with DOCID, and invoke
|
||||
ACTION."
|
||||
(interactive)
|
||||
(mu4e-proc-extract 'temp docid index nil what param))
|
||||
(mu4e~proc-extract 'temp docid index nil what param))
|
||||
|
||||
(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--get-attach msg attachnum))
|
||||
(let* ((att (mu4e~view-get-attach msg attachnum))
|
||||
(cmd (or cmd (read-string "Shell command to open it with: ")))
|
||||
(index (plist-get att :index)))
|
||||
(mu4e--temp-action (plist-get msg :docid) index "open-with" cmd)))
|
||||
(mu4e~temp-action (plist-get msg :docid) index "open-with" cmd)))
|
||||
|
||||
(defun mu4e-view-pipe-attachment (msg attachnum &optional pipecmd)
|
||||
"Feed MSG's attachment ATTACHNUM throught pipe PIPECMD; if
|
||||
PIPECMD is nil, ask user for it."
|
||||
(interactive)
|
||||
(let* ((att (mu4e--get-attach msg attachnum))
|
||||
(let* ((att (mu4e~view-get-attach msg attachnum))
|
||||
(pipecmd (or pipecmd (read-string "Pipe: ")))
|
||||
(index (plist-get att :index)))
|
||||
(mu4e--temp-action (plist-get msg :docid) index "pipe" pipecmd)))
|
||||
(mu4e~temp-action (plist-get 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--get-attach msg attachnum))
|
||||
(let* ((att (mu4e~view-get-attach msg attachnum))
|
||||
(index (plist-get att :index)))
|
||||
(mu4e--temp-action (plist-get msg :docid) index "emacs")))
|
||||
(mu4e~temp-action (plist-get msg :docid) index "emacs")))
|
||||
|
||||
|
||||
(defun mu4e-view-attachment-action (&optional msg)
|
||||
|
@ -674,7 +647,7 @@ message-at-point, then do it. The actions are specified in
|
|||
(actionfunc (mu4e-choose-action
|
||||
"Action on attachment: "
|
||||
mu4e-view-attachment-actions))
|
||||
(attnum (mu4e--get-attach-num "Which attachment" msg)))
|
||||
(attnum (mu4e~view-get-attach-num "Which attachment" msg)))
|
||||
(when (and actionfunc attnum)
|
||||
(funcall actionfunc msg attnum))))
|
||||
|
||||
|
@ -683,7 +656,7 @@ message-at-point, then do it. The actions are specified in
|
|||
;; want to do something with one of the attachments.
|
||||
(defun mu4e-view-temp-handler (path what param)
|
||||
"Handler function for doing things with temp files (ie.,
|
||||
attachments) in response to a (mu4e-proc-extract 'temp ... )."
|
||||
attachments) in response to a (mu4e~proc-extract 'temp ... )."
|
||||
(cond
|
||||
((string= what "open-with")
|
||||
;; 'param' will be the program to open-with
|
||||
|
@ -701,21 +674,18 @@ attachments) in response to a (mu4e-proc-extract 'temp ... )."
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;; marking
|
||||
(defun mu4e--view-mark-set (mark)
|
||||
(defun mu4e~view-mark-set (mark)
|
||||
"Set mark on the current messages."
|
||||
(unless (buffer-live-p mu4e--view-hdrs-buffer)
|
||||
(unless (buffer-live-p mu4e~view-hdrs-buffer)
|
||||
(error "No headers buffer available"))
|
||||
(let ((docid (mu4e-msg-field mu4e-current-msg :docid)))
|
||||
(with-current-buffer mu4e--view-hdrs-buffer
|
||||
(with-current-buffer mu4e~view-hdrs-buffer
|
||||
(if (eq mark 'move)
|
||||
(mu4e-mark-for-move-set)
|
||||
(mu4e-mark-at-point mark)))))
|
||||
;; (when (not (eq mark 'unmark))
|
||||
;; (mu4e--view-next-header)
|
||||
;; (mu4e-view-message)))))
|
||||
|
||||
|
||||
|
||||
(defun mu4e--split-view-p ()
|
||||
(defun mu4e~split-view-p ()
|
||||
"Return t if we're in split-view, nil otherwise."
|
||||
(member mu4e-split-view '(horizontal vertical)))
|
||||
|
||||
|
@ -723,7 +693,7 @@ attachments) in response to a (mu4e-proc-extract 'temp ... )."
|
|||
"If we're in split-view, unmark all messages. Otherwise, warn
|
||||
user that unmarking only works in the header list."
|
||||
(interactive)
|
||||
(if (mu4e--split-view-p)
|
||||
(if (mu4e~split-view-p)
|
||||
(mu4e-mark-unmark-all)
|
||||
(message "Unmarking needs to be done in the header list view")))
|
||||
|
||||
|
@ -731,52 +701,52 @@ user that unmarking only works in the header list."
|
|||
"If we're in split-view, unmark message at point. Otherwise, warn
|
||||
user that unmarking only works in the header list."
|
||||
(interactive)
|
||||
(if (mu4e--split-view-p)
|
||||
(mu4e--view-mark-set 'unmark)
|
||||
(if (mu4e~split-view-p)
|
||||
(mu4e~view-mark-set 'unmark)
|
||||
(message "Unmarking needs to be done in the header list view")))
|
||||
|
||||
(defun mu4e-view-mark-for-move ()
|
||||
"Mark the current message for moving."
|
||||
(interactive)
|
||||
(mu4e--view-mark-set 'move)
|
||||
(mu4e--view-next-header))
|
||||
(mu4e~view-mark-set 'move)
|
||||
(mu4e~view-next-header))
|
||||
|
||||
(defun mu4e-view-mark-for-trash ()
|
||||
"Mark the current message for moving to the trash folder."
|
||||
(interactive)
|
||||
(mu4e--view-mark-set 'trash)
|
||||
(mu4e--view-next-header))
|
||||
(mu4e~view-mark-set 'trash)
|
||||
(mu4e~view-next-header))
|
||||
|
||||
(defun mu4e-view-mark-for-delete ()
|
||||
"Mark the current message for deletion."
|
||||
(interactive)
|
||||
(mu4e--view-mark-set 'delete)
|
||||
(mu4e--view-next-header))
|
||||
(mu4e~view-mark-set 'delete)
|
||||
(mu4e~view-next-header))
|
||||
|
||||
(defun mu4e-view-marked-execute ()
|
||||
"If we're in split-view, execute the marks. Otherwise, warn user
|
||||
that execution can only take place in n the header list."
|
||||
(interactive)
|
||||
(if (mu4e--split-view-p)
|
||||
(with-current-buffer mu4e--view-hdrs-buffer
|
||||
(if (mu4e~split-view-p)
|
||||
(with-current-buffer mu4e~view-hdrs-buffer
|
||||
(mu4e-mark-execute-all))
|
||||
(message "Execution needs to be done in the header list view")))
|
||||
|
||||
(defun mu4e-view-go-to-url (num)
|
||||
"Go to a numbered url."
|
||||
(interactive "nGo to url with number: ")
|
||||
(let ((url (gethash num mu4e-link-map)))
|
||||
(let ((url (gethash num mu4e~view-link-map)))
|
||||
(unless url (error "Invalid number for URL"))
|
||||
(browse-url url)))
|
||||
|
||||
(defconst mu4e-view-raw-buffer-name "*mu4e-raw-view*"
|
||||
(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-field-at-point :path))
|
||||
(buf (get-buffer-create mu4e-view-raw-buffer-name)))
|
||||
(buf (get-buffer-create mu4e~view-raw-buffer-name)))
|
||||
(unless (and path (file-readable-p path))
|
||||
(error "Not a readable file: %S" path))
|
||||
(with-current-buffer buf
|
||||
|
@ -788,8 +758,8 @@ that execution can only take place in n the header list."
|
|||
(switch-to-buffer buf)))
|
||||
|
||||
(defun mu4e-view-pipe (cmd)
|
||||
"Pipe the message through shell command CMD, and display the
|
||||
results."
|
||||
"Pipe the message at point through shell command CMD, and display
|
||||
the results."
|
||||
(interactive "sShell command: ")
|
||||
(let ((path (mu4e-field-at-point :path)))
|
||||
(mu4e-process-file-through-pipe path cmd)))
|
||||
|
|
|
@ -45,12 +45,12 @@
|
|||
;;
|
||||
;;
|
||||
;; these are all defined in mu4e-hdrs
|
||||
(setq mu4e-update-func 'mu4e-hdrs-update-handler)
|
||||
(setq mu4e-header-func 'mu4e-hdrs-header-handler)
|
||||
(setq mu4e-found-func 'mu4e-hdrs-found-handler)
|
||||
(setq mu4e-view-func 'mu4e-hdrs-view-handler)
|
||||
(setq mu4e-remove-func 'mu4e-hdrs-remove-handler)
|
||||
(setq mu4e-erase-func 'mu4e-hdrs-clear)
|
||||
(setq mu4e-update-func 'mu4e~hdrs-update-handler)
|
||||
(setq mu4e-header-func 'mu4e~hdrs-header-handler)
|
||||
(setq mu4e-found-func 'mu4e~hdrs-found-handler)
|
||||
(setq mu4e-view-func 'mu4e~hdrs-view-handler)
|
||||
(setq mu4e-remove-func 'mu4e~hdrs-remove-handler)
|
||||
(setq mu4e-erase-func 'mu4e~hdrs-clear)
|
||||
|
||||
;; these ones are define in mu4e-utils
|
||||
(setq mu4e-info-func 'mu4e-info-handler)
|
||||
|
@ -59,13 +59,13 @@
|
|||
;; registers mu4e-pong func
|
||||
|
||||
;; this one is defined in mu4e-compose
|
||||
(setq mu4e-compose-func 'mu4e-compose-handler)
|
||||
(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)
|
||||
(setq mu4e-temp-func 'mu4e~view-temp-handler)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user