* mu4e: centralize some of the fontification code; cleanup signature support

This commit is contained in:
djcb 2013-10-20 15:41:47 +03:00
parent 55d6057dac
commit 9c8101d949
7 changed files with 93 additions and 95 deletions

View File

@ -117,7 +117,7 @@ for quering the message information."
:safe 'symbolp
:group 'mu4e-compose)
(defvar mu4e-compose-pre-hook nil
(defcustom mu4e-compose-pre-hook nil
"Hook run just *before* message composition starts.
If the compose-type is either 'reply' or 'forward', the variable
`mu4e-compose-parent-message' points to the message replied to /
@ -127,7 +127,9 @@ Note that there is no draft message yet when this hook runs, it
is meant for influencing the how mu4e constructs the draft
message. If you want to do something with the draft messages after
it has been constructed, `mu4e-compose-mode-hook' would be the
place to do that.")
place to do that."
:type 'hook
:group 'mu4e-compose)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -265,6 +267,8 @@ appear on disk."
\\{message-mode-map}."
(progn
(use-local-map mu4e-compose-mode-map)
(set (make-local-variable 'message-signature)
mu4e-compose-signature)
(make-local-variable 'message-default-charset)
;; if the default charset is not set, use UTF-8
(unless message-default-charset
@ -360,10 +364,6 @@ tempfile)."
(dolist (att includes)
(mml-attach-file
(plist-get att :file-name) (plist-get att :mime-type))))
;; include the message signature (if it's set); but not when editing an
;; existing message.
(unless (eq compose-type 'edit)
(message-insert-signature))
;; buffer is not user-modified yet
(mu4e~compose-set-friendly-buffer-name compose-type)
(set-buffer-modified-p nil)
@ -377,9 +377,8 @@ tempfile)."
;; hide some headers
(mu4e~compose-hide-headers)
;; switch on the mode
(run-with-timer 0.01 nil #'(lambda () (mu4e-compose-mode))))
(mu4e-compose-mode))
(defun mu4e-sent-handler (docid path)
"Handler function, called with DOCID and PATH for the just-sent
message. For Forwarded ('Passed') and Replied messages, try to set

View File

@ -32,6 +32,7 @@
(require 'mu4e-vars)
(require 'mu4e-utils)
(require 'mu4e-message)
(require 'message) ;; mail-header-separator
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -43,27 +44,45 @@
:type 'boolean
:group 'mu4e-compose)
(defcustom mu4e-compose-cite-function
(or message-cite-function 'message-cite-original-without-signature)
"The function to use to cite message in replies and forwarded
messages. This is the mu4e-specific version of
`message-cite-function'."
:type 'function
:group 'mu4e-compose)
(defcustom mu4e-compose-signature
(or message-signature "Sent with my mu4e")
"The message signature (i.e. the blob at the bottom of
messages). This is the mu4e-specific version of
`message-signature'."
:type 'sexp
:group 'mu4e-compose)
(defun mu4e~draft-user-agent-construct ()
"Return the User-Agent string for mu4e.
This is either the value of `mu4e-user-agent', or, if not set, a
string based on the versions of mu4e and emacs."
(format "mu4e %s; emacs %s" mu4e-mu-version emacs-version))
(defun mu4e~draft-cite-original (msg)
"Return a cited version of the original message MSG as a plist.
This function use gnus' `message-cite-function', and as such all
its settings apply."
This function uses gnus' `mu4e-compose-cite-function', and as such
all its settings apply."
(with-temp-buffer
(when (fboundp 'mu4e-view-message-text) ;; keep bytecompiler happy
(insert (mu4e-view-message-text msg))
;; this seems to be needed, otherwise existing signatures
;; won't be stripped
(message-yank-original)
(goto-char (point-min))
(push-mark (point-max))
(funcall message-cite-function)
;; set the the signature separator to 'loose', since in the real world,
;; many message don't follow the standard...
(let ((message-signature-separator "^-- *$"))
(funcall mu4e-compose-cite-function))
(pop-mark)
(goto-char (point-min))
(mu4e~fontify-cited)
(buffer-string))))
(defun mu4e~draft-header (hdr val)
@ -219,7 +238,7 @@ separator is never written to the message file. Also see
'intangible t
'read-only "Can't touch this"
'rear-nonsticky t
'font-lock-face 'mu4e-separator-face)))
'font-lock-face 'mu4e-compose-separator-face)))
(widen)
;; search for the first empty line
(goto-char (point-min))
@ -260,9 +279,7 @@ If there is just one recipient of ORIGMSG do nothing."
(defun mu4e~draft-message-filename-construct (&optional flagstr)
"Construct a randomized name for a message file with flags FLAGSTR.
It looks something like
<time>-<random>.<hostname>:2,
You can append flags."
(let* ((hostname
(downcase
@ -393,40 +410,17 @@ from either `mu4e~draft-reply-construct', or
(reply (mu4e~draft-reply-construct msg))
(forward (mu4e~draft-forward-construct msg))
(new (mu4e~draft-newmsg-construct))
(t (mu4e-error "unsupported compose-type %S" compose-type))))))
;; evaluate mu4e~drafts-drafts-folder once, here, and use that value throughout.
(t (mu4e-error "unsupported compose-type %S" compose-type))))
;; include the message signature (if it's set)
(let ((message-signature mu4e-compose-signature))
(message-insert-signature)
(mu4e~fontify-signature))))
;; evaluate mu4e~drafts-drafts-folder once, here, and use that value
;; throughout.
(set (make-local-variable 'mu4e~draft-drafts-folder) draft-dir)
(put 'mu4e~draft-drafts-folder 'permanent-local t)
(unless mu4e~draft-drafts-folder
(mu4e-error "failed to determine drafts folder"))))
;; (defun mu4e-draft-setup-fcc ()
;; "Setup Fcc, based on `mu4e-sent-messages-behavior'. If needed,
;; set the Fcc header, and register the handler function."
;; (let* ((mdir
;; (case mu4e-sent-messages-behavior
;; (delete nil)
;; (trash (mu4e-get-trash-folder mu4e-compose-parent-message))
;; (sent (mu4e-get-sent-folder mu4e-compose-parent-message))
;; (otherwise
;; (mu4e-error "unsupported value '%S' `mu4e-sent-messages-behavior'."
;; mu4e-sent-messages-behavior))))
;; (fccfile (and mdir
;; (concat mu4e-maildir mdir "/cur/"
;; (mu4e~compose-message-filename-construct "S")))))
;; ;; if there's an fcc header, add it to the file
;; (when fccfile
;; (message-add-header (concat "Fcc: " fccfile "\n"))
;; ;; sadly, we cannot define as 'buffer-local'... this will screw up gnus
;; ;; etc. if you run it after mu4e so, (hack hack) we reset it to the old
;; ;; handler after we've done our thing.
;; (setq message-fcc-handler-function
;; (lexical-let ((maildir mdir) (old-handler message-fcc-handler-function))
;; (lambda (file)
;; (setq message-fcc-handler-function old-handler) ;; reset the fcc handler
;; (write-file file) ;; writing maildirs files is easy
;; (mu4e~proc-add file maildir))))))) ;; update the database
(provide 'mu4e-draft)

View File

@ -749,7 +749,6 @@ user-interaction ongoing."
"Major mode for displaying mu4e search results.
\\{mu4e-headers-mode-map}."
(use-local-map mu4e-headers-mode-map)
(make-local-variable 'mu4e~headers-proc)
(make-local-variable 'mu4e~highlighted-docid)
(make-local-variable 'global-mode-string)

View File

@ -1081,5 +1081,49 @@ receive (:info add :path <path> :docid <docid>) as well as (:update
<msg-sexp>)."
(mu4e~proc-add path maildir))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e~fontify-cited ()
"Colorize message content based on the citation level. This is
used in the view and compose modes."
(save-excursion
(let ((more-lines t))
(goto-char (point-min))
(when (search-forward-regexp "^\n") ;; search the first empty line
(while more-lines
;; Get the citation level at point -- i.e., the number of '>'
;; prefixes, starting with 0 for 'no citation'
(beginning-of-line 1)
;; consider only lines that heuristically look like a citation line...
(when (looking-at "[[:blank:]]*[^[:blank:]\n]*[[:blank:]]*>")
(let* ((level (how-many ">" (line-beginning-position 1)
(line-end-position 1)))
(face
(unless (zerop level)
(intern-soft (format "mu4e-cited-%d-face" level)))))
(when face
(add-text-properties (line-beginning-position 1)
(line-end-position 1) `(face ,face)))))
(setq more-lines
(and (= 0 (forward-line 1))
;; we need to add this weird check below; it seems in some cases
;; `forward-line' continues to return 0, even when at the end,
;; which would lead to an infinite loop
(not (= (point-max) (line-end-position))))))))))
(defun mu4e~fontify-signature ()
"Give the message signatures a distinctive color. This is used in
the view and compose modes."
(let ((inhibit-read-only t))
(save-excursion
;; give the footer a different color...
(goto-char (point-min))
(let ((p (search-forward "^-- *$" nil t)))
(when p
(add-text-properties p (point-max) '(face mu4e-footer-face)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'mu4e-utils)
;;; End of mu4e-utils.el

View File

@ -407,9 +407,9 @@ I.e. a message with the draft flag set."
'((t :inherit font-lock-preprocessor-face))
"Face for the mark in the headers list."
:group 'mu4e-faces)
(defface mu4e-header-key-face
'((t :inherit message-header-name :bold t))
'((t :inherit message-header-name-face :bold t))
"Face for a header key (such as \"Foo\" in \"Subject:\ Foo\")."
:group 'mu4e-faces)

View File

@ -241,8 +241,8 @@ marking if it still had that."
(erase-buffer)
(insert (mu4e-view-message-text msg))
(goto-char (point-min))
(mu4e~view-fontify-cited)
(mu4e~view-fontify-footer)
(mu4e~fontify-cited)
(mu4e~fontify-signature)
(mu4e~view-make-urls-clickable)
(mu4e~view-show-images-maybe msg)
@ -708,43 +708,6 @@ If the message is not New/Unread, do nothing."
;; this message will be marked as read.
(mu4e~proc-move msgid nil "+S-u-N")))))
(defun mu4e~view-fontify-cited ()
"Colorize message content based on the citation level."
(save-excursion
(let ((more-lines t))
(goto-char (point-min))
(when (search-forward-regexp "^\n") ;; search the first empty line
(while more-lines
;; Get the citation level at point -- i.e., the number of '>'
;; prefixes, starting with 0 for 'no citation'
(beginning-of-line 1)
;; consider only lines that heuristically look like a citation line...
(when (looking-at "[[:blank:]]*[^[:blank:]\n]*[[:blank:]]*>")
(let* ((level (how-many ">" (line-beginning-position 1)
(line-end-position 1)))
(face
(unless (zerop level)
(intern-soft (format "mu4e-cited-%d-face" level)))))
(when face
(add-text-properties (line-beginning-position 1)
(line-end-position 1) `(face ,face)))))
(setq more-lines
(and (= 0 (forward-line 1))
;; we need to add this weird check below; it seems in some cases
;; `forward-line' continues to return 0, even when at the end,
;; which would lead to an infinite loop
(not (= (point-max) (line-end-position))))))))))
(defun mu4e~view-fontify-footer ()
"Give the message footers a distinctive color."
(let ((inhibit-read-only t))
(save-excursion
;; give the footer a different color...
(goto-char (point-min))
(let ((p (search-forward "\n-- \n" nil t)))
(when p
(add-text-properties p (point-max) '(face mu4e-footer-face)))))))
(defun mu4e~view-browse-url-func (url)
"Return a function that executes `browse-url' with URL.
What browser is called is depending on

View File

@ -2564,7 +2564,7 @@ it work with @t{mu4e}:
@lisp
(require 'mu-cite)
(setq message-cite-function 'mu-cite-original)
(setq mu4e-cite-function 'mu-cite-original)
(setq mu-cite-top-format
'("On " date ", " from " wrote:\n\n"))
(setq mu-cite-prefix-format '(" > ")))
@ -2712,8 +2712,7 @@ customize.
(setq mu4e-reply-to-address "foo@@bar.com"
user-mail-address "foo@@bar.com"
user-full-name "Foo X. Bar")
;; include in message with C-c C-w
(setq message-signature
(setq mu4e-compose-signature
"Foo X. Bar\nhttp://www.example.com\n")
;; smtp mail setting
@ -2861,7 +2860,7 @@ Next step: let's make a @t{mu4e} configuration for this:
(setq
user-mail-address "USERNAME@@gmail.com"
user-full-name "Foo X. Bar"
message-signature
mu4e-compose-signature
(concat
"Foo X. Bar\n"
"http://www.example.com\n"))