* mu4e: add tooltips for header fields in message, headers view

This commit is contained in:
djcb 2012-07-10 11:51:54 +03:00
parent 706a686134
commit 129b5ad264
4 changed files with 137 additions and 116 deletions

View File

@ -54,7 +54,7 @@
respective widths in characters. A width of `nil' means
'unrestricted', and this is best reserved fo the rightmost (last)
field. For the complete list of available headers, see
`mu4e-header-names'"
`mu4e-header-info'."
:type (list 'symbol)
:group 'mu4e-headers)
@ -528,17 +528,21 @@ after the end of the search results."
(cons
(make-string
(+ mu4e~mark-fringe-len (floor (fringe-columns 'left t))) ?\s)
(map 'list
(mapcar
(lambda (item)
(let ((field (cdr (assoc (car item) mu4e-header-names)))
(width (cdr item)))
(let* ((info (cadr (assoc (car item) mu4e-header-info)))
(name (plist-get info :shortname))
(help (plist-get info :help))
(width (cdr item)))
(message "%S %S" item info)
(concat
(propertize
(if width
(truncate-string-to-width field width 0 ?\s t)
field)
'face 'mu4e-header-title-face) " ")))
mu4e-headers-fields))))
(truncate-string-to-width name width 0 ?\s t)
name)
'face 'mu4e-header-title-face
'help-echo help) " ")))
mu4e-headers-fields))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; higlighting

View File

@ -455,7 +455,7 @@ there is no message at point."
msg)))
(defun mu4e-field-at-point (field)
"Get FIELD (a symbol, see `mu4e-header-names') for the message at
"Get FIELD (a symbol, see `mu4e-header-info') for the message at
point in eiter the headers buffer or the view buffer."
(plist-get (mu4e-message-at-point t) field))
@ -635,8 +635,9 @@ FUNC (if non-nil) afterwards."
doccount (if (= doccount 1) "" "s")))))
;; send the ping
(mu4e~proc-ping)
;; get the address list
(when mu4e-compose-complete-addresses
;; get the address list if it's not already set.
(when (and mu4e-compose-complete-addresses
(not mu4e~contacts-for-completion))
(setq mu4e-contacts-func 'mu4e~fill-contacts)
(mu4e~proc-contacts
mu4e-compose-complete-only-personal
@ -651,7 +652,8 @@ FUNC (if non-nil) afterwards."
(cancel-timer mu4e-update-timer)
(setq
mu4e-update-timer nil
mu4e~maildir-list nil))
mu4e~maildir-list nil
mu4e~contacts-for-completion nil))
(mu4e~proc-kill)
;; kill all main/view/headers buffer
(mapcar
@ -661,7 +663,6 @@ FUNC (if non-nil) afterwards."
(kill-buffer))))
(buffer-list)))
(defvar mu4e-update-timer nil
"*internal* The mu4e update timer.")

View File

@ -150,14 +150,13 @@ the address fields (this excludes mailing list messages)."
:type 'string
:group 'mu4e-compose)
(defcustom mu4e-compose-complete-ignore-address-regexp "noreply"
(defcustom mu4e-compose-complete-ignore-address-regexp "no-?reply"
"Ignore any e-mail addresses for completion if they match this
regexp."
:type 'string
:group 'mu4e-compose)
;; Folders
(defgroup mu4e-folders nil
"Special folders."
@ -331,8 +330,6 @@ flag set)."
:group 'mu4e-faces)
(defface mu4e-system-face
'((t :inherit font-lock-comment-face :slant italic))
"Face for system message (such as the footers for message
@ -342,27 +339,7 @@ headers)."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; internal variables / constants
(defconst mu4e-header-names
'( (:attachments . "Attach")
(:bcc . "Bcc")
(:cc . "Cc")
(:date . "Date")
(:flags . "Flags")
(:from . "From")
(:from-or-to . "From/To")
(:maildir . "Maildir")
(:path . "Path")
(:subject . "Subject")
(:to . "To"))
"An alist of all possible header fields; this is used in the UI (the
column headers in the header list, and the fields the message
view). Most fields should be self-explanatory. A special one is
`:from-or-to', which is equal to `:from' unless `:from' matches
`mu4e-user-mail-address-regexp', in which case it will be equal to
`:to'.")
(defconst mu4e-logo
(propertize "mu4e" 'face 'mu4e-title-face)
"A propertized string for the mu4e 'logo'.")
@ -370,30 +347,69 @@ view). Most fields should be self-explanatory. A special one is
(defconst mu4e-prefix
(concat "[" mu4e-logo "]")
"Prefix for mu4e minibuffer input.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; internal variables / constants
(defconst mu4e-header-names
'( (:attachments . "Attach")
(:bcc . "Bcc")
(:cc . "Cc")
(:date . "Date")
(:flags . "Flags")
(:from . "From")
(:from-or-to . "From/To")
(:maildir . "Maildir")
(:path . "Path")
(:subject . "Subject")
(:to . "To"))
"An alist of all possible header fields; this is used in the UI (the
column headers in the header list, and the fields the message
view). Most fields should be self-explanatory. A special one is
`:from-or-to', which is equal to `:from' unless `:from' matches
`mu4e-user-mail-address-regexp', in which case it will be equal to
`:to'.")
(defconst mu4e-header-info
'( (:attachments .
( :name "Attachments"
:shortname "Atts"
:help "Message attachments"))
(:bcc .
( :name "Bcc"
:shortname "Bcc"
:help "Blind Carbon-Copy recipients for the message"
:sortable t))
(:cc
( :name "Cc"
:shortname "Cc"
:help "Carbon-Copy recipients for the message"
:sortable t))
(:date
( :name "Date"
:shortname "Date"
:help "Date/time when the message was written"
:sortable t))
(:flags
( :name "Flags"
:shortname "Flgs"
:help "Flags for the message"
:sortable t))
(:from
( :name "From"
:shortname "From"
:help "The sender of the message"
:sortable t))
(:from-or-to
( :name "From/To"
:shortname "From/To"
:help "Sender of the message if it's not me; otherwise
the recipient"
:sortable t))
(:maildir
( :name "Maildir"
:shortname "Maildir"
:help "Maildir for this message"
:sortable t))
(:path
( :name "Path"
:shortname "Path"
:help "Full filesystem path to the message"
:sortable t))
(:subject
( :name "Subject"
:shortname "S"
:help "Subject of the message"
:sortable t))
(:to
( :name "To"
:shortname "T"
:help "Recipient of the message"
:sortable t)))
"An alist of all possible header fields and information about
them.; this is used in the UI (the column headers in the header
list, and the fields the message view). Most fields should be
self-explanatory. A special one is `:from-or-to', which is equal to
`:from' unless `:from' matches `mu4e-user-mail-address-regexp', in
which case it will be equal to `:to'.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -49,7 +49,7 @@
(defcustom mu4e-view-fields
'(:from :to :cc :subject :flags :date :maildir :attachments)
"Header fields to display in the message view buffer. For the
complete list of available headers, see `mu4e-header-names'."
complete list of available headers, see `mu4e-header-info'."
:type (list 'symbol)
:group 'mu4e-view)
@ -104,11 +104,12 @@ buffer."
("view as pdf" . mu4e-action-view-as-pdf))
"List of actions to perform on messages in view mode. The actions
are of the form:
(NAME SHORTCUT FUNC)
(NAME FUNC)
where:
* NAME is the name of the action (e.g. \"Count lines\")
* SHORTCUT is a one-character shortcut to call this action
* FUNC is a function which receives a message plist as an argument.")
* FUNC is a function which receives a message plist as an argument.
The first letter of NAME is used as a shortcut character.")
(defvar mu4e-view-attachment-actions
'( ("wopen-with" . mu4e-view-open-attachment-with)
@ -116,12 +117,13 @@ where:
("|pipe" . mu4e-view-pipe-attachment))
"List of actions to perform on message attachments. The actions
are of the form:
(NAME SHORTCUT FUNC)
(NAME FUNC)
where:
* NAME is the name of the action (e.g. \"Count lines\")
* SHORTCUT is a one-character shortcut to call this action
* FUNC is a function which receives two arguments: the message
plist and the attachment number.")
* FUNC is a function which receives two arguments: the message
plist and the attachment number.
The first letter of NAME is used as a shortcut character.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -157,13 +159,12 @@ plist."
(concat
(mapconcat
(lambda (field)
(let ((fieldname (cdr (assoc field mu4e-header-names)))
(fieldval (plist-get msg field)))
(let ((fieldval (plist-get msg field)))
(case field
(: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
(:subject (mu4e~view-construct-header field fieldval))
(:path (mu4e~view-construct-header field fieldval))
(:maildir (mu4e~view-construct-header field fieldval))
(:flags (mu4e~view-construct-header field
(if fieldval (format "%S" fieldval) "")))
;; contact fields
(:to (mu4e~view-construct-contacts msg field))
@ -184,12 +185,12 @@ plist."
(let ((datestr
(when fieldval (format-time-string mu4e-view-date-format
fieldval))))
(if datestr (mu4e~view-construct-header fieldname datestr) "")))
(if datestr (mu4e~view-construct-header field datestr) "")))
;; size
(:size
(let* (size (mu4e-view-size msg)
(sizestr (when size (format "%d bytes" size))))
(if sizestr (mu4e~view-construct-header fieldname sizestr))))
(if sizestr (mu4e~view-construct-header field sizestr))))
;; attachments
(:attachments (mu4e~view-construct-attachments msg))
(t (error "Unsupported field: %S" field)))))
@ -237,47 +238,46 @@ marking if it still had that."
(mu4e~view-mark-as-read-maybe))))))
(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
(with-temp-buffer
(insert (propertize key 'face 'mu4e-view-header-key-face) ": "
(if dont-propertize-val
val
(propertize val 'face 'mu4e-view-header-value-face)) "\n")
;; temporarily set the fill column <margin> positions to the right, so
;; we can indent following lines with positions
(let*((margin 1) (fill-column (- fill-column margin)))
(fill-region (point-min) (point-max))
(goto-char (point-min))
(while (and (zerop (forward-line 1)) (not (looking-at "^$")))
(indent-to-column margin)))
(buffer-string))
""))
(defun mu4e~view-construct-header (field val &optional dont-propertize-val)
"Return header field FIELD (as in `mu4e-header-info') with value
VAL if VAL is non-nil. If DONT-PROPERTIZE-VAL is non-nil, do not
add text-properties to VAL."
(let* ((info (cadr (assoc field mu4e-header-info)))
(key (plist-get info :name))
(help (plist-get info :help)))
(if (and val (> (length val) 0))
(with-temp-buffer
(insert (propertize key
'face 'mu4e-view-header-key-face
'help-echo help) ": "
(if dont-propertize-val
val
(propertize val 'face 'mu4e-view-header-value-face)) "\n")
;; temporarily set the fill column <margin> positions to the right, so
;; we can indent following lines with positions
(let*((margin 1) (fill-column (- fill-column margin)))
(fill-region (point-min) (point-max))
(goto-char (point-min))
(while (and (zerop (forward-line 1)) (not (looking-at "^$")))
(indent-to-column margin)))
(buffer-string))
"")))
(defun mu4e~view-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)))
(contacts
(and lst
(mapconcat
(lambda(c)
(let ((name (car c)) (email (cdr c)))
(propertize
(if name
(if mu4e-view-show-addresses
(format "%s <%s>" name email)
(format "%s" name))
(format "%s" email))
'help-echo email)))
lst ", "))))
(if contacts
(mu4e~view-construct-header fieldname contacts)
"")))
(mu4e~view-construct-header field
(mapconcat
(lambda(c)
(let ((name (car c)) (email (cdr c)))
(propertize
(if name
(if mu4e-view-show-addresses
(format "%s <%s>" name email)
(format "%s" name))
(format "%s" email))
'help-echo email)))
(plist-get msg field) ", ")))
(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."