mirror of https://github.com/djcb/mu.git
* mu4e: restructure code a bit and enable byte-compilation
This commit is contained in:
parent
b943f5630e
commit
edda59bff7
|
@ -29,7 +29,13 @@ else
|
||||||
guile=
|
guile=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS=m4 man src $(widgets) $(guile) emacs contrib toys
|
if HAVE_EMACS
|
||||||
|
emacs=emacs
|
||||||
|
else
|
||||||
|
emacs=
|
||||||
|
endif
|
||||||
|
|
||||||
|
SUBDIRS=m4 man src $(widgets) $(guile) $(emacs) contrib toys
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS=-I m4
|
ACLOCAL_AMFLAGS=-I m4
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,9 @@ AC_SYS_LARGEFILE
|
||||||
AC_CHECK_PROG(have_makeinfo,makeinfo,yes,no)
|
AC_CHECK_PROG(have_makeinfo,makeinfo,yes,no)
|
||||||
AM_CONDITIONAL(HAVE_MAKEINFO,test "x$have_makeinfo" = "xyes")
|
AM_CONDITIONAL(HAVE_MAKEINFO,test "x$have_makeinfo" = "xyes")
|
||||||
|
|
||||||
|
# we need emacs for byte-compiling mu4e
|
||||||
|
AM_PATH_LISPDIR
|
||||||
|
AM_CONDITIONAL(HAVE_EMACS,test "x$lispdir" != "xno")
|
||||||
|
|
||||||
# we need some special tricks for filesystems that don't have d_type;
|
# we need some special tricks for filesystems that don't have d_type;
|
||||||
# e.g. Solaris. See mu-maildir.c. Explicitly disabling it is for
|
# e.g. Solaris. See mu-maildir.c. Explicitly disabling it is for
|
||||||
|
@ -281,6 +283,7 @@ src/Makefile
|
||||||
src/tests/Makefile
|
src/tests/Makefile
|
||||||
widgets/Makefile
|
widgets/Makefile
|
||||||
emacs/Makefile
|
emacs/Makefile
|
||||||
|
emacs/mu4e-version.el
|
||||||
guile/Makefile
|
guile/Makefile
|
||||||
guile/mu/Makefile
|
guile/mu/Makefile
|
||||||
guile/examples/Makefile
|
guile/examples/Makefile
|
||||||
|
|
|
@ -18,27 +18,23 @@ include $(top_srcdir)/gtest.mk
|
||||||
|
|
||||||
SUBDIRS=
|
SUBDIRS=
|
||||||
|
|
||||||
BUILT_SOURCES=mu4e-version.el
|
|
||||||
|
|
||||||
mu4e-version.el: $(top_srcdir)/configure.ac
|
|
||||||
@echo -e ";; auto-generated\n\
|
|
||||||
(defconst mu4e-mu-version \"$(VERSION)\" \"Required mu binary version.\")\n\
|
|
||||||
(provide 'mu4e-version)\n" >$@
|
|
||||||
|
|
||||||
info_TEXINFOS=mu4e.texi
|
info_TEXINFOS=mu4e.texi
|
||||||
mu4e_TEXINFOS=fdl.texi
|
mu4e_TEXINFOS=fdl.texi
|
||||||
|
|
||||||
elispdir= ${prefix}/share/emacs/site-lisp/mu4e/
|
lispdir=${prefix}/share/emacs/site-lisp/mu4e/
|
||||||
elisp_DATA= \
|
|
||||||
mu4e.el \
|
dist_lisp_LISP= \
|
||||||
|
mu4e-utils.el \
|
||||||
mu4e-hdrs.el \
|
mu4e-hdrs.el \
|
||||||
mu4e-view.el \
|
|
||||||
mu4e-proc.el \
|
|
||||||
mu4e-main.el \
|
mu4e-main.el \
|
||||||
|
mu4e-proc.el \
|
||||||
|
mu4e-raw-view.el \
|
||||||
mu4e-send.el \
|
mu4e-send.el \
|
||||||
mu4e-speedbar.el \
|
mu4e-speedbar.el \
|
||||||
mu4e-utils.el \
|
mu4e-vars.el \
|
||||||
mu4e-version.el \
|
mu4e-version.el \
|
||||||
|
mu4e-view.el \
|
||||||
|
mu4e.el \
|
||||||
org-mu4e.el
|
org-mu4e.el
|
||||||
|
|
||||||
EXTRA_DIST=$(elisp_DATA)
|
EXTRA_DIST=$(elisp_DATA)
|
||||||
|
|
|
@ -27,19 +27,13 @@
|
||||||
;; headers like 'To:' or 'Subject:')
|
;; headers like 'To:' or 'Subject:')
|
||||||
|
|
||||||
;; Code:
|
;; Code:
|
||||||
|
|
||||||
(eval-when-compile (require 'cl))
|
|
||||||
|
|
||||||
(require 'hl-line)
|
(require 'hl-line)
|
||||||
|
|
||||||
(require 'mu4e-proc)
|
(require 'mu4e-proc)
|
||||||
(require 'mu4e-utils) ;; utility functions
|
(require 'mu4e-utils) ;; utility functions
|
||||||
|
(require 'mu4e-vars)
|
||||||
|
|
||||||
;;;; internal variables/constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; internal variables/constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
(defvar mu4e-last-expr nil "*internal* The most recent search expression.")
|
|
||||||
(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")
|
|
||||||
(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.")
|
message headers to put marks.")
|
||||||
|
|
||||||
|
@ -120,7 +114,9 @@ headers."
|
||||||
(when (and viewbuf (buffer-live-p viewbuf))
|
(when (and viewbuf (buffer-live-p viewbuf))
|
||||||
(with-current-buffer viewbuf
|
(with-current-buffer viewbuf
|
||||||
(when (eq docid (plist-get mu4e-current-msg :docid))
|
(when (eq docid (plist-get mu4e-current-msg :docid))
|
||||||
(setq mu4e-current-msg msg)))))
|
(setq mu4e-current-msg msg)
|
||||||
|
;; and re-highlight this message
|
||||||
|
(mu4e-hdrs-highlight docid)))))
|
||||||
|
|
||||||
;; now, if this update was about *moving* a message, we don't show it
|
;; 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
|
;; anymore (of course, we cannot be sure if the message really no
|
||||||
|
@ -234,7 +230,9 @@ after the end of the search results."
|
||||||
(insert (propertize str 'face 'mu4e-system-face 'intangible t))
|
(insert (propertize str 'face 'mu4e-system-face 'intangible t))
|
||||||
(unless (= 0 count)
|
(unless (= 0 count)
|
||||||
(message "Found %d matching message%s"
|
(message "Found %d matching message%s"
|
||||||
count (if (= 1 count) "" "s"))))))))
|
count (if (= 1 count) "" "s"))
|
||||||
|
;; highlight the first message
|
||||||
|
(mu4e-hdrs-highlight (mu4e--docid-at-point (point-min)))))))))
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
|
@ -336,7 +334,6 @@ after the end of the search results."
|
||||||
(define-key menumap [next] '("Next" . mu4e-next-header))
|
(define-key menumap [next] '("Next" . mu4e-next-header))
|
||||||
(define-key menumap [previous] '("Previous" . mu4e-prev-header))
|
(define-key menumap [previous] '("Previous" . mu4e-prev-header))
|
||||||
(define-key menumap [sepa4] '("--")))
|
(define-key menumap [sepa4] '("--")))
|
||||||
|
|
||||||
map)))
|
map)))
|
||||||
|
|
||||||
(fset 'mu4e-hdrs-mode-map mu4e-hdrs-mode-map)
|
(fset 'mu4e-hdrs-mode-map mu4e-hdrs-mode-map)
|
||||||
|
@ -394,7 +391,27 @@ after the end of the search results."
|
||||||
mu4e-headers-fields))))
|
mu4e-headers-fields))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
(defun mu4e-select-headers-window-if-visible ()
|
;;; higlighting
|
||||||
|
(defvar mu4e--highlighted-docid nil
|
||||||
|
"*internal* The highlighted 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
|
||||||
|
(save-excursion
|
||||||
|
;; first, unhighlight the previously highlighted docid, if any
|
||||||
|
(when (and mu4e--highlighted-docid
|
||||||
|
(mu4e--goto-docid mu4e--highlighted-docid))
|
||||||
|
(hl-line-unhighlight))
|
||||||
|
;; now, highlight the new one
|
||||||
|
(when (mu4e--goto-docid docid)
|
||||||
|
(hl-line-highlight)))
|
||||||
|
(setq mu4e--highlighted-docid docid)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
(defun mu4e-select-headers-window-if-visible ()
|
||||||
"When there is a visible window for the headers buffer, make sure
|
"When there is a visible window for the headers buffer, make sure
|
||||||
to select it. This is needed when adding new headers, otherwise
|
to select it. This is needed when adding new headers, otherwise
|
||||||
adding a lot of new headers looks really choppy."
|
adding a lot of new headers looks really choppy."
|
||||||
|
@ -436,8 +453,6 @@ of the beginning of the line."
|
||||||
(setq newpoint (point)))))
|
(setq newpoint (point)))))
|
||||||
newpoint)) ;; return the point, or nil if not found
|
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
|
"Return the pos of the beginning of the line with the header with
|
||||||
docid DOCID, or nil if it cannot be found."
|
docid DOCID, or nil if it cannot be found."
|
||||||
|
@ -482,11 +497,7 @@ at (point-max) otherwise. If MSG is not nil, add it as the text-property `msg'."
|
||||||
(concat
|
(concat
|
||||||
(mu4e--docid-cookie docid)
|
(mu4e--docid-cookie docid)
|
||||||
mu4e-hdrs-fringe str "\n")
|
mu4e-hdrs-fringe str "\n")
|
||||||
'docid docid 'msg msg))
|
'docid docid 'msg msg)))))))
|
||||||
;; if it's the first header, highlight it
|
|
||||||
(when is-first-header
|
|
||||||
(goto-char (point-min))
|
|
||||||
(hl-line-highlight)))))))
|
|
||||||
|
|
||||||
(defun mu4e-hdrs-remove-header (docid)
|
(defun mu4e-hdrs-remove-header (docid)
|
||||||
"Remove header with DOCID at POINT."
|
"Remove header with DOCID at POINT."
|
||||||
|
@ -746,7 +757,7 @@ do a new search."
|
||||||
(when (mu4e-handle-marks)
|
(when (mu4e-handle-marks)
|
||||||
(if mu4e-last-expr
|
(if mu4e-last-expr
|
||||||
(mu4e-hdrs-search mu4e-last-expr)
|
(mu4e-hdrs-search mu4e-last-expr)
|
||||||
(mu4e-search))))
|
(call-interactively 'mu4e-search))))
|
||||||
|
|
||||||
(defun mu4e--hdrs-move (lines)
|
(defun mu4e--hdrs-move (lines)
|
||||||
"Move point LINES lines forward (if LINES is positive) or
|
"Move point LINES lines forward (if LINES is positive) or
|
||||||
|
@ -756,12 +767,11 @@ docid. Otherwise, return nil."
|
||||||
(unless (buffer-live-p mu4e-hdrs-buffer)
|
(unless (buffer-live-p mu4e-hdrs-buffer)
|
||||||
(error "Headers buffer is not alive %S" (current-buffer)))
|
(error "Headers buffer is not alive %S" (current-buffer)))
|
||||||
(set-window-point (get-buffer-window mu4e-hdrs-buffer) (point))
|
(set-window-point (get-buffer-window mu4e-hdrs-buffer) (point))
|
||||||
(hl-line-unhighlight)
|
|
||||||
(let ((succeeded (= 0 (forward-line lines)))
|
(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
|
;; trick to move point, even if this function is called when this window
|
||||||
;; is not visible
|
;; is not visible
|
||||||
(hl-line-highlight)
|
(mu4e-hdrs-highlight docid)
|
||||||
;; return the docid only if the move succeeded
|
;; return the docid only if the move succeeded
|
||||||
(when succeeded docid))))
|
(when succeeded docid))))
|
||||||
|
|
||||||
|
@ -803,7 +813,7 @@ not provided, function asks for it."
|
||||||
(concat "/" target)))
|
(concat "/" target)))
|
||||||
(fulltarget (concat mu4e-maildir target)))
|
(fulltarget (concat mu4e-maildir target)))
|
||||||
(when (or (file-directory-p fulltarget)
|
(when (or (file-directory-p fulltarget)
|
||||||
(and (yes-or-no-(point)
|
(and (yes-or-no-p
|
||||||
(format "%s does not exist. Create now?" fulltarget))
|
(format "%s does not exist. Create now?" fulltarget))
|
||||||
(mu4e-proc-mkdir fulltarget)))
|
(mu4e-proc-mkdir fulltarget)))
|
||||||
(mu4e-hdrs-mark 'move target)
|
(mu4e-hdrs-mark 'move target)
|
||||||
|
|
|
@ -23,9 +23,11 @@
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(eval-when-compile (require 'cl))
|
(require 'mu4e-vars)
|
||||||
|
(require 'mu4e-utils)
|
||||||
|
(require 'mu4e-version)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; internal vars
|
;; internal vars
|
||||||
|
|
||||||
(defvar mu4e-mu-proc nil
|
(defvar mu4e-mu-proc nil
|
||||||
|
@ -106,10 +108,6 @@ process."
|
||||||
;; add draft messages to the db, so when we're sending them, we can move
|
;; add draft messages to the db, so when we're sending them, we can move
|
||||||
;; to the sent folder using the `mu4e-proc-move'.
|
;; to the sent folder using the `mu4e-proc-move'.
|
||||||
(puthash (plist-get info :path) (plist-get info :docid) mu4e-path-docid-map))
|
(puthash (plist-get info :path) (plist-get info :docid) mu4e-path-docid-map))
|
||||||
((eq type 'version)
|
|
||||||
(setq
|
|
||||||
mu4e-version (plist-get info :version)
|
|
||||||
mu4e-doccount (plist-get-info :doccount)))
|
|
||||||
((eq type 'index)
|
((eq type 'index)
|
||||||
(if (eq (plist-get info :status) 'running)
|
(if (eq (plist-get info :status) 'running)
|
||||||
(message (format "Indexing... processed %d, updated %d"
|
(message (format "Indexing... processed %d, updated %d"
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
;;; mu4e-raw-view.el -- part of mu4e, the mu mail user agent
|
||||||
|
;;
|
||||||
|
;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema
|
||||||
|
|
||||||
|
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
|
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
;;
|
||||||
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; In this file we define mu4e-view-mode (+ helper functions), which is used for
|
||||||
|
;; viewing e-mail messages
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(eval-when-compile (require 'cl))
|
||||||
|
|
||||||
|
(require 'mu4e-utils) ;; utility functions
|
||||||
|
|
||||||
|
;; raw mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; some buffer-local variables
|
||||||
|
(defconst mu4e-raw-view-buffer-name "*mu4e-raw-view*"
|
||||||
|
"*internal* Name for the raw message view buffer")
|
||||||
|
|
||||||
|
(defvar mu4e-raw-view-buffer nil "*internal* The raw view buffer.")
|
||||||
|
|
||||||
|
(defvar mu4e-raw-view-mode-map nil
|
||||||
|
"Keymap for \"*mu4e-raw-view*\" buffers.")
|
||||||
|
|
||||||
|
(unless mu4e-raw-view-mode-map
|
||||||
|
(setq mu4e-raw-view-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
|
||||||
|
(define-key map "q" 'mu4e-raw-view-quit-buffer)
|
||||||
|
(define-key map "." 'mu4e-raw-view-quit-buffer)
|
||||||
|
|
||||||
|
;; intra-message navigation
|
||||||
|
(define-key map (kbd "SPC") 'scroll-up)
|
||||||
|
(define-key map (kbd "<home>")
|
||||||
|
'(lambda () (interactive) (goto-char (point-min))))
|
||||||
|
(define-key map (kbd "<end>")
|
||||||
|
'(lambda () (interactive) (goto-char (point-max))))
|
||||||
|
(define-key map (kbd "RET")
|
||||||
|
'(lambda () (interactive) (scroll-up 1)))
|
||||||
|
(define-key map (kbd "<backspace>")
|
||||||
|
'(lambda () (interactive) (scroll-up -1)))
|
||||||
|
map)))
|
||||||
|
|
||||||
|
(fset 'mu4e-raw-view-mode-map mu4e-raw-view-mode-map)
|
||||||
|
|
||||||
|
(define-derived-mode mu4e-raw-view-mode special-mode
|
||||||
|
"mu4e:raw"
|
||||||
|
"Major mode for viewing of raw e-mail message in mu4e.
|
||||||
|
\\{mu4e-raw-view-mode-map}.")
|
||||||
|
|
||||||
|
|
||||||
|
(defun mu4e-raw-view-message (msg view-buffer)
|
||||||
|
"Display the raw contents of message MSG in a new buffer."
|
||||||
|
(let ((buf (get-buffer-create mu4e-raw-view-buffer-name))
|
||||||
|
(inhibit-read-only t)
|
||||||
|
(file (plist-get msg :path)))
|
||||||
|
(unless (and file (file-readable-p file))
|
||||||
|
(error "Not a readable file: %S" file))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(erase-buffer)
|
||||||
|
(insert-file-contents file)
|
||||||
|
;; initialize view-mode
|
||||||
|
(mu4e-raw-view-mode)
|
||||||
|
(setq mu4e-raw-view-buffer view-buffer)
|
||||||
|
(switch-to-buffer buf)
|
||||||
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun mu4e-view-shell-command-on-raw-message (msg view-buffer cmd)
|
||||||
|
"Process the raw message with shell command CMD."
|
||||||
|
(let ((buf (get-buffer-create mu4e-raw-view-buffer-name))
|
||||||
|
(inhibit-read-only t)
|
||||||
|
(file (plist-get msg :path)))
|
||||||
|
(unless (and file (file-readable-p file))
|
||||||
|
(error "Not a readable file: %S" file))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(erase-buffer)
|
||||||
|
(process-file-shell-command cmd file buf)
|
||||||
|
(mu4e-raw-view-mode)
|
||||||
|
(setq mu4e-raw-view-buffer view-buffer)
|
||||||
|
(switch-to-buffer buf)
|
||||||
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun mu4e-raw-view-quit-buffer ()
|
||||||
|
"Quit the raw view and return to the message."
|
||||||
|
(interactive)
|
||||||
|
(kill-buffer))
|
||||||
|
|
||||||
|
(provide 'mu4e-raw-view)
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
@ -26,10 +26,11 @@
|
||||||
;; gnus' message mode
|
;; gnus' message mode
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
;; we use some stuff from gnus..
|
||||||
|
(require 'cl)
|
||||||
|
|
||||||
(eval-when-compile (require 'cl))
|
(require 'mu4e-utils)
|
||||||
|
(require 'mu4e-vars)
|
||||||
;; we use some stuff from gnus...
|
|
||||||
(require 'message)
|
(require 'message)
|
||||||
(require 'mail-parse)
|
(require 'mail-parse)
|
||||||
(require 'smtpmail)
|
(require 'smtpmail)
|
||||||
|
@ -159,7 +160,7 @@ separator is never written to file. Also see
|
||||||
(replace-match
|
(replace-match
|
||||||
(propertize mail-header-separator 'read-only t 'intangible t))
|
(propertize mail-header-separator 'read-only t 'intangible t))
|
||||||
;; no empty line? then append one
|
;; no empty line? then append one
|
||||||
((progn )
|
(progn
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(insert (concat "\n" mail-header-separator "\n"))))))
|
(insert (concat "\n" mail-header-separator "\n"))))))
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'speedbar)
|
||||||
|
|
||||||
(defvar mu4e-main-speedbar-key-map nil
|
(defvar mu4e-main-speedbar-key-map nil
|
||||||
"Keymap used when in mu4e display mode.")
|
"Keymap used when in mu4e display mode.")
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,9 @@
|
||||||
;; Utility functions used in the mu4e
|
;; Utility functions used in the mu4e
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
(require 'cl)
|
||||||
(require 'html2text)
|
(require 'html2text)
|
||||||
|
|
||||||
(eval-when-compile (require 'cl))
|
|
||||||
|
|
||||||
(defun mu4e-create-maildir-maybe (dir)
|
(defun mu4e-create-maildir-maybe (dir)
|
||||||
"Offer to create DIR if it does not exist yet. Return t if the
|
"Offer to create DIR if it does not exist yet. Return t if the
|
||||||
dir already existed, or has been created, nil otherwise."
|
dir already existed, or has been created, nil otherwise."
|
||||||
|
@ -303,7 +302,7 @@ point in eiter the headers buffer or the view buffer."
|
||||||
((eq major-mode 'mu4e-hdrs-mode)
|
((eq major-mode 'mu4e-hdrs-mode)
|
||||||
(get-text-property (point) 'msg))
|
(get-text-property (point) 'msg))
|
||||||
((eq major-mode 'mu4e-view-mode)
|
((eq major-mode 'mu4e-view-mode)
|
||||||
mu4e--current-msg))))
|
mu4e-current-msg))))
|
||||||
(unless msg (error "No message at point"))
|
(unless msg (error "No message at point"))
|
||||||
(plist-get msg field)))
|
(plist-get msg field)))
|
||||||
|
|
||||||
|
@ -318,7 +317,6 @@ instead of erroring out."
|
||||||
(delete-windows-on buf) ;; destroy all windows for this buffer
|
(delete-windows-on buf) ;; destroy all windows for this buffer
|
||||||
(kill-buffer))))
|
(kill-buffer))))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-select-other-view ()
|
(defun mu4e-select-other-view ()
|
||||||
"When the headers view is selected, select the message view (if
|
"When the headers view is selected, select the message view (if
|
||||||
that has a live window), and vice versa."
|
that has a live window), and vice versa."
|
||||||
|
@ -334,6 +332,48 @@ that has a live window), and vice versa."
|
||||||
(select-window other-win)
|
(select-window other-win)
|
||||||
(message "No window to switch to"))))
|
(message "No window to switch to"))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
(defvar mu4e-update-timer nil
|
||||||
|
"*internal* The mu4e update timer.")
|
||||||
|
|
||||||
|
(defun mu4e ()
|
||||||
|
"Start mu4e. We do this by sending a 'ping' to the mu server
|
||||||
|
process, and start the main view if the 'pong' we receive from the
|
||||||
|
server has the expected values."
|
||||||
|
(interactive)
|
||||||
|
(if (buffer-live-p (get-buffer mu4e-main-buffer-name))
|
||||||
|
(switch-to-buffer mu4e-main-buffer-name)
|
||||||
|
(mu4e-check-requirements)
|
||||||
|
;; explicit version checks are a bit questionable,
|
||||||
|
;; better to check for specific features
|
||||||
|
(if (< emacs-major-version 23)
|
||||||
|
(error "Emacs >= 23.x is required for mu4e")
|
||||||
|
(progn
|
||||||
|
(setq mu4e-proc-pong-func
|
||||||
|
(lambda (version doccount)
|
||||||
|
(unless (string= version mu4e-mu-version)
|
||||||
|
(error "mu server has version %s, but we need %s"
|
||||||
|
version mu4e-mu-version))
|
||||||
|
(mu4e-main-view)
|
||||||
|
(when (and mu4e-update-interval (null mu4e-update-timer))
|
||||||
|
(setq mu4e-update-timer
|
||||||
|
(run-at-time
|
||||||
|
0 mu4e-update-interval
|
||||||
|
'mu4e-update-mail)))
|
||||||
|
(message "Started mu4e with %d message%s in store"
|
||||||
|
doccount (if (= doccount 1) "" "s"))))
|
||||||
|
(mu4e-proc-ping)))))
|
||||||
|
|
||||||
|
(defun mu4e-quit()
|
||||||
|
"Quit the mu4e session."
|
||||||
|
(interactive)
|
||||||
|
(when (y-or-n-p "Are you sure you want to quit? ")
|
||||||
|
(message nil)
|
||||||
|
(when mu4e-update-timer
|
||||||
|
(cancel-timer mu4e-update-timer)
|
||||||
|
(setq mu4e-update-timer nil))
|
||||||
|
(mu4e-kill-proc)
|
||||||
|
(kill-buffer)))
|
||||||
|
|
||||||
(provide 'mu4e-utils)
|
(provide 'mu4e-utils)
|
||||||
;;; End of mu4e-utils.el
|
;;; End of mu4e-utils.el
|
||||||
|
|
|
@ -0,0 +1,472 @@
|
||||||
|
;;; mu4e-vars.el -- part of mu4e, the mu mail user agent
|
||||||
|
;;
|
||||||
|
;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema
|
||||||
|
|
||||||
|
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
|
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
;;
|
||||||
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Customization
|
||||||
|
|
||||||
|
(defgroup mu4e nil
|
||||||
|
"mu4e - mu for emacs"
|
||||||
|
:group 'local)
|
||||||
|
|
||||||
|
(defcustom mu4e-mu-home nil
|
||||||
|
"Location of the mu homedir, or nil for the default."
|
||||||
|
:type 'directory
|
||||||
|
:group 'mu4e
|
||||||
|
:safe 'stringp)
|
||||||
|
|
||||||
|
(defcustom mu4e-mu-binary (executable-find "mu")
|
||||||
|
"Name of the mu-binary to use; if it cannot be found in your
|
||||||
|
PATH, you can specify the full path."
|
||||||
|
:type 'file
|
||||||
|
:group 'mu4e
|
||||||
|
:safe 'stringp)
|
||||||
|
|
||||||
|
(defcustom mu4e-maildir (expand-file-name "~/Maildir")
|
||||||
|
"Your Maildir directory; by default, mu4e assumes
|
||||||
|
~/Maildir."
|
||||||
|
:type 'directory
|
||||||
|
:safe 'stringp
|
||||||
|
:group 'mu4e)
|
||||||
|
|
||||||
|
(defcustom mu4e-get-mail-command nil
|
||||||
|
"Shell command to run to retrieve new mail; e.g. 'offlineimap' or
|
||||||
|
'fetchmail'."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e
|
||||||
|
:safe 'stringp)
|
||||||
|
|
||||||
|
(defcustom mu4e-update-interval nil
|
||||||
|
"Number of seconds between automatic calls to retrieve mail and
|
||||||
|
update the database. If nil, don't update automatically. Note,
|
||||||
|
changes in `mu4e-update-interval' only take effect after restarting
|
||||||
|
mu4d."
|
||||||
|
:type 'integer
|
||||||
|
:group 'mu4e
|
||||||
|
:safe 'integerp)
|
||||||
|
|
||||||
|
(defcustom mu4e-attachment-dir (expand-file-name "~/")
|
||||||
|
"Default directory for saving attachments."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e
|
||||||
|
:safe 'stringp)
|
||||||
|
|
||||||
|
(defvar mu4e-user-mail-address-regexp "$^"
|
||||||
|
"Regular expression matching the user's mail address(es). This is
|
||||||
|
used to distinguish ourselves from others, e.g. when replying and
|
||||||
|
in :from-or-to headers. By default, match nothing.")
|
||||||
|
|
||||||
|
(defvar mu4e-date-format-long "%c"
|
||||||
|
"Date format to use in the message view, in the format of
|
||||||
|
`format-time-string'.")
|
||||||
|
|
||||||
|
(defvar mu4e-search-results-limit 1000
|
||||||
|
"Maximum number of search results (or -1 for unlimited). Since
|
||||||
|
limiting search results speeds up searches significantly, it's
|
||||||
|
useful to limit this. Note, to ignore the limit, use a prefix
|
||||||
|
argument (C-u) before invoking the search.")
|
||||||
|
|
||||||
|
(defvar mu4e-debug nil
|
||||||
|
"When set to non-nil, log debug information to the *mu4e-log* buffer.")
|
||||||
|
|
||||||
|
(defvar mu4e-bookmarks
|
||||||
|
'( ("flag:unread AND NOT flag:trashed" "Unread messages" ?u)
|
||||||
|
("date:today..now" "Today's messages" ?t)
|
||||||
|
("date:7d..now" "Last 7 days" ?w)
|
||||||
|
("mime:image/*" "Messages with images" ?p))
|
||||||
|
"A list of pre-defined queries; these will show up in the main
|
||||||
|
screen. Each of the list elements is a three-element list of the
|
||||||
|
form (QUERY DESCRIPTION KEY), where QUERY is a string with a mu
|
||||||
|
query, DESCRIPTION is a short description of the query (this will
|
||||||
|
show up in the UI), and KEY is a shortcut key for the query.")
|
||||||
|
|
||||||
|
(defvar mu4e-split-view 'horizontal
|
||||||
|
"How to show messages / headers; a symbol which is either:
|
||||||
|
* a symbol 'horizontal: split horizontally (headers on top)
|
||||||
|
* a symbol 'vertical: split vertically (headers on the left).
|
||||||
|
* anything else: don't split (show either headers or messages, not both)
|
||||||
|
Also see `mu4e-headers-visible-lines' and `mu4e-headers-visible-columns'.")
|
||||||
|
|
||||||
|
;; Sending
|
||||||
|
(defgroup mu4e-sending nil
|
||||||
|
"E-mail-sending related settings for mu4e."
|
||||||
|
:group 'mu4e)
|
||||||
|
|
||||||
|
(defcustom mu4e-sent-messages-behavior 'sent
|
||||||
|
"Determines what mu4e does with sent messages - this is a symbol
|
||||||
|
which can be either:
|
||||||
|
'sent --> move the sent message to the Sent-folder (`mu4e-sent-folder')
|
||||||
|
'trash --> move the sent message to the Trash-folder (`mu4e-trash-folder')
|
||||||
|
'delete --> delete the sent message.
|
||||||
|
Note, when using GMail/IMAP, you should set this to either 'trash
|
||||||
|
or 'delete, since GMail already takes care of keeping copies in the
|
||||||
|
sent folder."
|
||||||
|
:type 'symbol
|
||||||
|
:safe 'symbolp
|
||||||
|
:group 'mu4e-sending)
|
||||||
|
|
||||||
|
;; Folders
|
||||||
|
|
||||||
|
(defgroup mu4e-folders nil
|
||||||
|
"Special folders."
|
||||||
|
:group 'mu4e)
|
||||||
|
|
||||||
|
(defcustom mu4e-sent-folder "/sent"
|
||||||
|
"Your folder for sent messages, relative to `mu4e-maildir',
|
||||||
|
e.g. \"/Sent Items\"."
|
||||||
|
:type 'string
|
||||||
|
:safe 'stringp
|
||||||
|
:group 'mu4e-folders)
|
||||||
|
|
||||||
|
(defcustom mu4e-drafts-folder "/drafts"
|
||||||
|
"Your folder for draft messages, relative to `mu4e-maildir',
|
||||||
|
e.g. \"/drafts\""
|
||||||
|
:type 'string
|
||||||
|
:safe 'stringp
|
||||||
|
:group 'mu4e-folders)
|
||||||
|
|
||||||
|
(defcustom mu4e-trash-folder "/trash"
|
||||||
|
"Your folder for trashed messages, relative to `mu4e-maildir',
|
||||||
|
e.g. \"/trash\"."
|
||||||
|
:type 'string
|
||||||
|
:safe 'stringp
|
||||||
|
:group 'mu4e-folders)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom mu4e-maildir-shortcuts nil
|
||||||
|
"A list of maildir shortcuts to enable quickly going to the
|
||||||
|
particular for, or quickly moving messages towards them (i.e.,
|
||||||
|
archiving or refiling). The list contains elements of the form
|
||||||
|
(maildir . shortcut), where MAILDIR is a maildir (such as
|
||||||
|
\"/archive/\"), and shortcut a single shortcut character. With
|
||||||
|
this, in the header buffer and view buffer you can execute
|
||||||
|
`mu4e-mark-for-move-quick' (or 'm', by default) or
|
||||||
|
`mu4e-jump-to-maildir' (or 'j', by default), followed by the
|
||||||
|
designated shortcut character for the maildir.")
|
||||||
|
|
||||||
|
;; the headers view
|
||||||
|
(defgroup mu4e-headers nil
|
||||||
|
"Settings for the headers view."
|
||||||
|
:group 'mu4e)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom mu4e-headers-fields
|
||||||
|
'( (:date . 25)
|
||||||
|
(:flags . 6)
|
||||||
|
(:from . 22)
|
||||||
|
(:subject . nil))
|
||||||
|
"A list of header fields to show in the headers buffer, and their
|
||||||
|
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'"
|
||||||
|
:type (list 'symbol)
|
||||||
|
:group 'mu4e-headers)
|
||||||
|
|
||||||
|
(defcustom mu4e-headers-date-format "%x %X"
|
||||||
|
"Date format to use in the headers view, in the format of
|
||||||
|
`format-time-string'."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e-headers)
|
||||||
|
|
||||||
|
(defcustom mu4e-headers-leave-behavior 'ask
|
||||||
|
"What to do when user leaves the headers view (e.g. quits,
|
||||||
|
refreshes or does a new search). Value is one of the following
|
||||||
|
symbols:
|
||||||
|
- ask (ask the user whether to ignore the marks)
|
||||||
|
- apply (automatically apply the marks before doing anything else)
|
||||||
|
- ignore (automatically ignore the marks without asking)."
|
||||||
|
:type 'symbol
|
||||||
|
:group 'mu4e-headers)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom mu4e-headers-visible-lines 10
|
||||||
|
"Number of lines to display in the header view when using the
|
||||||
|
horizontal split-view. This includes the header-line at the top,
|
||||||
|
and the mode-line."
|
||||||
|
:type 'integer
|
||||||
|
:group 'mu4e-headers)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom mu4e-headers-visible-columns 30
|
||||||
|
"Number of columns to display for the header view when using the
|
||||||
|
vertical split-view."
|
||||||
|
:type 'integer
|
||||||
|
:group 'mu4e-headers)
|
||||||
|
|
||||||
|
;; the message view
|
||||||
|
(defgroup mu4e-view nil
|
||||||
|
"Settings for the message view."
|
||||||
|
:group 'mu4e)
|
||||||
|
|
||||||
|
(defcustom mu4e-view-fields
|
||||||
|
'(:from :to :cc :subject :flags :date :maildir :attachments)
|
||||||
|
"Header fields to display in the message view buffer. For the
|
||||||
|
complete list of available headers, see `mu4e-header-names'."
|
||||||
|
:type (list 'symbol)
|
||||||
|
:group 'mu4e-view)
|
||||||
|
|
||||||
|
(defcustom mu4e-view-date-format "%c"
|
||||||
|
"Date format to use in the message view, in the format of
|
||||||
|
`format-time-string'."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e-view)
|
||||||
|
|
||||||
|
(defcustom mu4e-view-prefer-html nil
|
||||||
|
"Whether to base the body display on the HTML-version of the
|
||||||
|
e-mail message (if there is any."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'mu4e-view)
|
||||||
|
|
||||||
|
(defcustom mu4e-html2text-command nil
|
||||||
|
"Shel command that converts HTML from stdin into plain text on
|
||||||
|
stdout. If this is not defined, the emacs `html2text' tool will be
|
||||||
|
used when faced with html-only message. If you use htmltext, it's
|
||||||
|
recommended you use \"html2text -utf8 -width 72\"."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e-view
|
||||||
|
:safe 'stringp)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom mu4e-view-wrap-lines nil
|
||||||
|
"Whether to automatically wrap lines in the body of messages when
|
||||||
|
viewing them. Note that wrapping does not work well with all
|
||||||
|
messages, but you can always toggle between wrapped/unwrapped
|
||||||
|
display with `mu4e-view-toggle-wrap-lines (default keybinding: <w>)."
|
||||||
|
:group 'mu4e-view)
|
||||||
|
|
||||||
|
(defcustom mu4e-view-wrap-lines nil
|
||||||
|
"Whether to automatically wrap lines in the body of messages when
|
||||||
|
viewing them. Note that wrapping does not work well with all
|
||||||
|
messages, but you can always toggle between wrapped/unwrapped
|
||||||
|
display with `mu4e-view-toggle-wrap-lines (default keybinding: <w>)."
|
||||||
|
:group 'mu4e-view)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom mu4e-view-hide-cited nil
|
||||||
|
"Whether to automatically hide cited parts of messages (as
|
||||||
|
determined by the presence of '> ' at the beginning of the
|
||||||
|
line). Note that you can always toggle between hidden/unhidden
|
||||||
|
display with `mu4e-view-toggle-hide-cited (default keybinding:
|
||||||
|
<w>)."
|
||||||
|
:group 'mu4e-view)
|
||||||
|
|
||||||
|
|
||||||
|
;; Composing / Sending messages
|
||||||
|
(defgroup mu4e-compose nil
|
||||||
|
"Customizations for composing/sending messages."
|
||||||
|
:group 'mu4e)
|
||||||
|
|
||||||
|
(defcustom mu4e-send-citation-prefix "> "
|
||||||
|
"String to prefix cited message parts with."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e-compose)
|
||||||
|
|
||||||
|
(defcustom mu4e-send-reply-prefix "Re: "
|
||||||
|
"String to prefix the subject of replied messages with."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e-compose)
|
||||||
|
|
||||||
|
(defcustom mu4e-send-forward-prefix "Fwd: "
|
||||||
|
"String to prefix the subject of forwarded messages with."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e-compose)
|
||||||
|
|
||||||
|
(defcustom mu4e-user-agent nil
|
||||||
|
"The user-agent string; leave at `nil' for the default."
|
||||||
|
:type 'string
|
||||||
|
:group 'mu4e-compose)
|
||||||
|
|
||||||
|
(defcustom mu4e-sent-messages-behavior 'sent
|
||||||
|
"Determines what mu4e does with sent messages - this is a symbol
|
||||||
|
which can be either:
|
||||||
|
'sent --> move the sent message to the Sent-folder (`mu4e-sent-folder')
|
||||||
|
'trash --> move the sent message to the Trash-folder (`mu4e-trash-folder')
|
||||||
|
'delete --> delete the sent message.
|
||||||
|
Note, when using GMail/IMAP, you should set this to either 'trash
|
||||||
|
or 'delete, since GMail already takes care of keeping copies in the
|
||||||
|
sent folder."
|
||||||
|
:type 'symbol
|
||||||
|
:safe 'symbolp
|
||||||
|
:group 'mu4e-compose)
|
||||||
|
|
||||||
|
|
||||||
|
;; Faces
|
||||||
|
|
||||||
|
(defgroup mu4e-faces nil
|
||||||
|
"Type faces (fonts) used in mu4e."
|
||||||
|
:group 'mu4e
|
||||||
|
:group 'faces)
|
||||||
|
|
||||||
|
|
||||||
|
(defface mu4e-unread-face
|
||||||
|
'((t :inherit font-lock-keyword-face :bold t))
|
||||||
|
"Face for an unread message header."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-moved-face
|
||||||
|
'((t :inherit font-lock-comment-face :slant italic))
|
||||||
|
"Face for a message header that has been moved to some
|
||||||
|
folder (it's still visible in the search results, since we cannot
|
||||||
|
be sure it no longer matches)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-trashed-face
|
||||||
|
'((t :inherit font-lock-comment-face :strike-through t))
|
||||||
|
"Face for an message header in the trash folder."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-draft-face
|
||||||
|
'((t :inherit font-lock-string-face))
|
||||||
|
"Face for a draft message header (i.e., a message with the draft
|
||||||
|
flag set)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-header-face
|
||||||
|
'((t :inherit default))
|
||||||
|
"Face for a header without any special flags."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-header-title-face
|
||||||
|
'((t :inherit font-lock-type-face))
|
||||||
|
"Face for a header title in the headers view."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-view-header-key-face
|
||||||
|
'((t :inherit font-lock-builtin-face :bold t))
|
||||||
|
"Face for a header title (such as \"Subject\") in the message
|
||||||
|
view."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-header-highlight-face
|
||||||
|
'((t :inherit default :weight bold :underline t))
|
||||||
|
"Face for the header at point."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-view-header-value-face
|
||||||
|
'((t :inherit font-lock-doc-face))
|
||||||
|
"Face for a header value (such as \"Re: Hello!\") in the message
|
||||||
|
view."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-view-link-face
|
||||||
|
'((t :inherit font-lock-type-face :underline t))
|
||||||
|
"Face for showing URLs and attachments in the message view."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-highlight-face
|
||||||
|
'((t :inherit font-lock-pseudo-keyword-face :bold t))
|
||||||
|
"Face for highlighting things."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-title-face
|
||||||
|
'((t :inherit font-lock-type-face :bold t))
|
||||||
|
"Face for a header title in the headers view."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-view-url-number-face
|
||||||
|
'((t :inherit font-lock-reference-face :bold t))
|
||||||
|
"Face for the number tags for URLs."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-view-attach-number-face
|
||||||
|
'((t :inherit font-lock-variable-name-face :bold t))
|
||||||
|
"Face for the number tags for attachments."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-cited-1-face
|
||||||
|
'((t :inherit font-lock-builtin-face :bold nil :italic t))
|
||||||
|
"Face for cited message parts (level 1)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-cited-2-face
|
||||||
|
'((t :inherit font-lock-type-face :bold nil :italic t))
|
||||||
|
"Face for cited message parts (level 2)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-cited-3-face
|
||||||
|
'((t :inherit font-lock-variable-name-face :bold nil :italic t))
|
||||||
|
"Face for cited message parts (level 3)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-cited-4-face
|
||||||
|
'((t :inherit font-lock-pseudo-keyword-face :bold nil :italic t))
|
||||||
|
"Face for cited message parts (level 4)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-view-footer-face
|
||||||
|
'((t :inherit font-lock-comment-face))
|
||||||
|
"Face for message footers (signatures)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-hdrs-marks-face
|
||||||
|
'((t :inherit font-lock-preprocessor-face))
|
||||||
|
"Face for the mark in the headers list."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
(defface mu4e-system-face
|
||||||
|
'((t :inherit font-lock-comment-face :slant italic))
|
||||||
|
"Face for system message (such as the footers for message
|
||||||
|
headers)."
|
||||||
|
:group 'mu4e-faces)
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; internal variables / constants
|
||||||
|
|
||||||
|
(defconst mu4e-header-names
|
||||||
|
'( (:attachments . "Attach")
|
||||||
|
(:bcc . "Bcc")
|
||||||
|
(:cc . "Cc")
|
||||||
|
(:date . "Date")
|
||||||
|
(:flags . "Flgs")
|
||||||
|
(:from . "From")
|
||||||
|
(:from-or-to . "From/To")
|
||||||
|
(:maildir . "Maildir")
|
||||||
|
(:path . "Path")
|
||||||
|
(:subject . "Subject")
|
||||||
|
(:to . "To"))
|
||||||
|
"A 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 ,
|
||||||
|
in which case it will be equal to `:to'.)")
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; run-time vars used in multiple places
|
||||||
|
|
||||||
|
;; headers
|
||||||
|
(defvar mu4e-last-expr nil "*internal* The most recent search expression.")
|
||||||
|
(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")
|
||||||
|
|
||||||
|
;; view
|
||||||
|
(defconst mu4e-view-buffer-name "*mu4e-view*"
|
||||||
|
"*internal* Name for the message view buffer")
|
||||||
|
(defvar mu4e-view-buffer nil "*internal* The view buffer.")
|
||||||
|
(defvar mu4e-current-msg nil
|
||||||
|
"*internal* The plist describing the currently viewed message.")
|
||||||
|
|
||||||
|
(provide 'mu4e-vars)
|
|
@ -0,0 +1,7 @@
|
||||||
|
;; auto-generated
|
||||||
|
(defconst mu4e-mu-version "@PACKAGE_STRING@"
|
||||||
|
"Required mu binary version; mu4e's verson must agree with
|
||||||
|
this.")
|
||||||
|
|
||||||
|
(provide 'mu4e-version)
|
||||||
|
|
|
@ -26,25 +26,18 @@
|
||||||
;; viewing e-mail messages
|
;; viewing e-mail messages
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(eval-when-compile (require 'cl))
|
|
||||||
|
|
||||||
(require 'mu4e-utils) ;; utility functions
|
(require 'mu4e-utils) ;; utility functions
|
||||||
|
(require 'mu4e-vars)
|
||||||
|
(require 'mu4e-raw-view)
|
||||||
|
|
||||||
;; we prefer the improved fill-region
|
;; we prefer the improved fill-region
|
||||||
(require 'filladapt nil 'noerror)
|
(require 'filladapt nil 'noerror)
|
||||||
(require 'comint)
|
(require 'comint)
|
||||||
|
|
||||||
(defconst mu4e-view-buffer-name "*mu4e-view*"
|
|
||||||
"*internal* Name for the message view buffer")
|
|
||||||
|
|
||||||
(defvar mu4e-view-buffer nil "*internal* The view buffer.")
|
|
||||||
|
|
||||||
;; some buffer-local variables
|
;; some buffer-local variables
|
||||||
(defvar mu4e-hdrs-buffer nil
|
(defvar mu4e-hdrs-buffer nil
|
||||||
"*internal* Headers buffer connected to this view.")
|
"*internal* Headers buffer connected to this view.")
|
||||||
|
|
||||||
(defvar mu4e-current-msg nil
|
|
||||||
"*internal* The plist describing the current message.")
|
|
||||||
|
|
||||||
(defun mu4e-view-message-with-msgid (msgid)
|
(defun mu4e-view-message-with-msgid (msgid)
|
||||||
"View message with MSGID. This is meant for external programs
|
"View message with MSGID. This is meant for external programs
|
||||||
wanting to show specific messages - for example, `mu4e-org'."
|
wanting to show specific messages - for example, `mu4e-org'."
|
||||||
|
@ -98,8 +91,9 @@ marking if it still had that."
|
||||||
fieldval))))
|
fieldval))))
|
||||||
(if datestr (mu4e-view-header fieldname datestr) "")))
|
(if datestr (mu4e-view-header fieldname datestr) "")))
|
||||||
;; size
|
;; size
|
||||||
(:size (mu4e-view-size msg)
|
(:size
|
||||||
(let ((sizestr (when size (format "%d bytes"))))
|
(let* (size (mu4e-view-size msg)
|
||||||
|
(sizestr (when size (format "%d bytes" size))))
|
||||||
(if sizestr (mu4e-view-header fieldname sizestr))))
|
(if sizestr (mu4e-view-header fieldname sizestr))))
|
||||||
;; attachments
|
;; attachments
|
||||||
(:attachments (mu4e-view-attachments msg))
|
(:attachments (mu4e-view-attachments msg))
|
||||||
|
@ -464,82 +458,7 @@ number them so they can be opened using `mu4e-view-go-to-url'."
|
||||||
'face 'mu4e-view-url-number-face))))))))
|
'face 'mu4e-view-url-number-face))))))))
|
||||||
|
|
||||||
|
|
||||||
;; raw mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;; some buffer-local variables
|
|
||||||
(defconst mu4e-raw-view-buffer-name "*mu4e-raw-view*"
|
|
||||||
"*internal* Name for the raw message view buffer")
|
|
||||||
|
|
||||||
(defvar mu4e-raw-view-buffer nil "*internal* The raw view buffer.")
|
|
||||||
|
|
||||||
(defvar mu4e-raw-view-mode-map nil
|
|
||||||
"Keymap for \"*mu4e-raw-view*\" buffers.")
|
|
||||||
|
|
||||||
(unless mu4e-raw-view-mode-map
|
|
||||||
(setq mu4e-raw-view-mode-map
|
|
||||||
(let ((map (make-sparse-keymap)))
|
|
||||||
|
|
||||||
(define-key map "q" 'mu4e-raw-view-quit-buffer)
|
|
||||||
(define-key map "." 'mu4e-raw-view-quit-buffer)
|
|
||||||
|
|
||||||
;; intra-message navigation
|
|
||||||
(define-key map (kbd "SPC") 'scroll-up)
|
|
||||||
(define-key map (kbd "<home>")
|
|
||||||
'(lambda () (interactive) (goto-char (point-min))))
|
|
||||||
(define-key map (kbd "<end>")
|
|
||||||
'(lambda () (interactive) (goto-char (point-max))))
|
|
||||||
(define-key map (kbd "RET")
|
|
||||||
'(lambda () (interactive) (scroll-up 1)))
|
|
||||||
(define-key map (kbd "<backspace>")
|
|
||||||
'(lambda () (interactive) (scroll-up -1)))
|
|
||||||
map)))
|
|
||||||
|
|
||||||
(fset 'mu4e-raw-view-mode-map mu4e-raw-view-mode-map)
|
|
||||||
|
|
||||||
(define-derived-mode mu4e-raw-view-mode special-mode
|
|
||||||
"mu4e:raw"
|
|
||||||
"Major mode for viewing of raw e-mail message in mu4e.
|
|
||||||
\\{mu4e-raw-view-mode-map}.")
|
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-raw-view-message (msg view-buffer)
|
|
||||||
"Display the raw contents of message MSG in a new buffer."
|
|
||||||
(let ((buf (get-buffer-create mu4e-raw-view-buffer-name))
|
|
||||||
(inhibit-read-only t)
|
|
||||||
(file (plist-get msg :path)))
|
|
||||||
(unless (and file (file-readable-p file))
|
|
||||||
(error "Not a readable file: %S" file))
|
|
||||||
(with-current-buffer buf
|
|
||||||
(erase-buffer)
|
|
||||||
(insert-file file)
|
|
||||||
;; initialize view-mode
|
|
||||||
(mu4e-raw-view-mode)
|
|
||||||
(setq mu4e-raw-view-buffer view-buffer)
|
|
||||||
(switch-to-buffer buf)
|
|
||||||
(goto-char (point-min)))))
|
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-view-shell-command-on-raw-message (msg view-buffer cmd)
|
|
||||||
"Process the raw message with shell command CMD."
|
|
||||||
(let ((buf (get-buffer-create mu4e-raw-view-buffer-name))
|
|
||||||
(inhibit-read-only t)
|
|
||||||
(file (plist-get msg :path)))
|
|
||||||
(unless (and file (file-readable-p file))
|
|
||||||
(error "Not a readable file: %S" file))
|
|
||||||
(with-current-buffer buf
|
|
||||||
(erase-buffer)
|
|
||||||
(process-file-shell-command cmd file buf)
|
|
||||||
(mu4e-raw-view-mode)
|
|
||||||
(setq mu4e-raw-view-buffer view-buffer)
|
|
||||||
(switch-to-buffer buf)
|
|
||||||
(goto-char (point-min)))))
|
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-raw-view-quit-buffer ()
|
|
||||||
"Quit the raw view and return to the message."
|
|
||||||
(interactive)
|
|
||||||
(kill-buffer))
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;; functions for org-contacts
|
;; functions for org-contacts
|
||||||
|
|
||||||
|
@ -658,10 +577,10 @@ citations."
|
||||||
|
|
||||||
(defun mu4e-view-extract-attachment (attnum)
|
(defun mu4e-view-extract-attachment (attnum)
|
||||||
"Extract the attachment with ATTNUM."
|
"Extract the attachment with ATTNUM."
|
||||||
|
(interactive "nAttachment to extract:")
|
||||||
(unless mu4e-attachment-dir (error "`mu4e-attachment-dir' is not set"))
|
(unless mu4e-attachment-dir (error "`mu4e-attachment-dir' is not set"))
|
||||||
(when (or (null mu4e-attach-map) (zerop (hash-table-count mu4e-attach-map)))
|
(when (or (null mu4e-attach-map) (zerop (hash-table-count mu4e-attach-map)))
|
||||||
(error "No attachments for this message"))
|
(error "No attachments for this message"))
|
||||||
(interactive "nAttachment to extract:")
|
|
||||||
(let* ((att (gethash attnum mu4e-attach-map))
|
(let* ((att (gethash attnum mu4e-attach-map))
|
||||||
(path (and att (concat mu4e-attachment-dir
|
(path (and att (concat mu4e-attachment-dir
|
||||||
"/" (plist-get att :name))))
|
"/" (plist-get att :name))))
|
||||||
|
@ -677,9 +596,9 @@ citations."
|
||||||
|
|
||||||
(defun mu4e-view-open-attachment (attnum)
|
(defun mu4e-view-open-attachment (attnum)
|
||||||
"Extract the attachment with ATTNUM"
|
"Extract the attachment with ATTNUM"
|
||||||
|
(interactive "nAttachment to open:")
|
||||||
(unless mu4e-attach-map
|
(unless mu4e-attach-map
|
||||||
(error "No attachments for this message"))
|
(error "No attachments for this message"))
|
||||||
(interactive "nAttachment to open:")
|
|
||||||
(let* ((att (gethash attnum mu4e-attach-map))
|
(let* ((att (gethash attnum mu4e-attach-map))
|
||||||
(id (and att (plist-get att :index))))
|
(id (and att (plist-get att :index))))
|
||||||
(unless id (error "Not a valid attachment number"))
|
(unless id (error "Not a valid attachment number"))
|
||||||
|
|
471
emacs/mu4e.el
471
emacs/mu4e.el
|
@ -40,476 +40,5 @@
|
||||||
;; mu4e-version.el is autogenerated, and defines mu4e-mu-version
|
;; mu4e-version.el is autogenerated, and defines mu4e-mu-version
|
||||||
(require 'mu4e-version)
|
(require 'mu4e-version)
|
||||||
|
|
||||||
;; Customization
|
|
||||||
|
|
||||||
(defgroup mu4e nil
|
|
||||||
"mu4e - mu for emacs"
|
|
||||||
:group 'local)
|
|
||||||
|
|
||||||
(defcustom mu4e-mu-home nil
|
|
||||||
"Location of the mu homedir, or nil for the default."
|
|
||||||
:type 'directory
|
|
||||||
:group 'mu4e
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defcustom mu4e-mu-binary (executable-find "mu")
|
|
||||||
"Name of the mu-binary to use; if it cannot be found in your
|
|
||||||
PATH, you can specify the full path."
|
|
||||||
:type 'file
|
|
||||||
:group 'mu4e
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defcustom mu4e-maildir (expand-file-name "~/Maildir")
|
|
||||||
"Your Maildir directory; by default, mu4e assumes
|
|
||||||
~/Maildir."
|
|
||||||
:type 'directory
|
|
||||||
:safe 'stringp
|
|
||||||
:group 'mu4e)
|
|
||||||
|
|
||||||
(defcustom mu4e-get-mail-command nil
|
|
||||||
"Shell command to run to retrieve new mail; e.g. 'offlineimap' or
|
|
||||||
'fetchmail'."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defcustom mu4e-update-interval nil
|
|
||||||
"Number of seconds between automatic calls to retrieve mail and
|
|
||||||
update the database. If nil, don't update automatically. Note,
|
|
||||||
changes in `mu4e-update-interval' only take effect after restarting
|
|
||||||
mu4d."
|
|
||||||
:type 'integer
|
|
||||||
:group 'mu4e
|
|
||||||
:safe 'integerp)
|
|
||||||
|
|
||||||
(defcustom mu4e-attachment-dir (expand-file-name "~/")
|
|
||||||
"Default directory for saving attachments."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defvar mu4e-user-mail-address-regexp "$^"
|
|
||||||
"Regular expression matching the user's mail address(es). This is
|
|
||||||
used to distinguish ourselves from others, e.g. when replying and
|
|
||||||
in :from-or-to headers. By default, match nothing.")
|
|
||||||
|
|
||||||
(defvar mu4e-date-format-long "%c"
|
|
||||||
"Date format to use in the message view, in the format of
|
|
||||||
`format-time-string'.")
|
|
||||||
|
|
||||||
(defvar mu4e-search-results-limit 1000
|
|
||||||
"Maximum number of search results (or -1 for unlimited). Since
|
|
||||||
limiting search results speeds up searches significantly, it's
|
|
||||||
useful to limit this. Note, to ignore the limit, use a prefix
|
|
||||||
argument (C-u) before invoking the search.")
|
|
||||||
|
|
||||||
(defvar mu4e-debug nil
|
|
||||||
"When set to non-nil, log debug information to the *mu4e-log* buffer.")
|
|
||||||
|
|
||||||
(defvar mu4e-bookmarks
|
|
||||||
'( ("flag:unread AND NOT flag:trashed" "Unread messages" ?u)
|
|
||||||
("date:today..now" "Today's messages" ?t)
|
|
||||||
("date:7d..now" "Last 7 days" ?w)
|
|
||||||
("mime:image/*" "Messages with images" ?p))
|
|
||||||
"A list of pre-defined queries; these will show up in the main
|
|
||||||
screen. Each of the list elements is a three-element list of the
|
|
||||||
form (QUERY DESCRIPTION KEY), where QUERY is a string with a mu
|
|
||||||
query, DESCRIPTION is a short description of the query (this will
|
|
||||||
show up in the UI), and KEY is a shortcut key for the query.")
|
|
||||||
|
|
||||||
(defvar mu4e-split-view 'horizontal
|
|
||||||
"How to show messages / headers; a symbol which is either:
|
|
||||||
* a symbol 'horizontal: split horizontally (headers on top)
|
|
||||||
* a symbol 'vertical: split vertically (headers on the left).
|
|
||||||
* anything else: don't split (show either headers or messages, not both)
|
|
||||||
Also see `mu4e-headers-visible-lines' and `mu4e-headers-visible-columns'.")
|
|
||||||
|
|
||||||
;; Sending
|
|
||||||
(defgroup mu4e-sending nil
|
|
||||||
"E-mail-sending related settings for mu4e.")
|
|
||||||
|
|
||||||
(defcustom mu4e-sent-messages-behavior 'sent
|
|
||||||
"Determines what mu4e does with sent messages - this is a symbol
|
|
||||||
which can be either:
|
|
||||||
'sent --> move the sent message to the Sent-folder (`mu4e-sent-folder')
|
|
||||||
'trash --> move the sent message to the Trash-folder (`mu4e-trash-folder')
|
|
||||||
'delete --> delete the sent message.
|
|
||||||
Note, when using GMail/IMAP, you should set this to either 'trash
|
|
||||||
or 'delete, since GMail already takes care of keeping copies in the
|
|
||||||
sent folder."
|
|
||||||
:type 'symbol
|
|
||||||
:safe 'symbolp
|
|
||||||
:group 'mu4e-sending)
|
|
||||||
|
|
||||||
;; Folders
|
|
||||||
|
|
||||||
(defgroup mu4e-folders nil
|
|
||||||
"Special folders."
|
|
||||||
:group 'mu4e)
|
|
||||||
|
|
||||||
(defcustom mu4e-sent-folder "/sent"
|
|
||||||
"Your folder for sent messages, relative to `mu4e-maildir',
|
|
||||||
e.g. \"/Sent Items\"."
|
|
||||||
:type 'string
|
|
||||||
:safe 'stringp
|
|
||||||
:group 'mu4e-folders)
|
|
||||||
|
|
||||||
(defcustom mu4e-drafts-folder "/drafts"
|
|
||||||
"Your folder for draft messages, relative to `mu4e-maildir',
|
|
||||||
e.g. \"/drafts\""
|
|
||||||
:type 'string
|
|
||||||
:safe 'stringp
|
|
||||||
:group 'mu4e-folders)
|
|
||||||
|
|
||||||
(defcustom mu4e-trash-folder "/trash"
|
|
||||||
"Your folder for trashed messages, relative to `mu4e-maildir',
|
|
||||||
e.g. \"/trash\"."
|
|
||||||
:type 'string
|
|
||||||
:safe 'stringp
|
|
||||||
:group 'mu4e-folders)
|
|
||||||
|
|
||||||
|
|
||||||
(defcustom mu4e-maildir-shortcuts nil
|
|
||||||
"A list of maildir shortcuts to enable quickly going to the
|
|
||||||
particular for, or quickly moving messages towards them (i.e.,
|
|
||||||
archiving or refiling). The list contains elements of the form
|
|
||||||
(maildir . shortcut), where MAILDIR is a maildir (such as
|
|
||||||
\"/archive/\"), and shortcut a single shortcut character. With
|
|
||||||
this, in the header buffer and view buffer you can execute
|
|
||||||
`mu4e-mark-for-move-quick' (or 'm', by default) or
|
|
||||||
`mu4e-jump-to-maildir' (or 'j', by default), followed by the
|
|
||||||
designated shortcut character for the maildir.")
|
|
||||||
|
|
||||||
;; the headers view
|
|
||||||
(defgroup mu4e-headers nil
|
|
||||||
"Settings for the headers view."
|
|
||||||
:group 'mu4e)
|
|
||||||
|
|
||||||
|
|
||||||
(defcustom mu4e-headers-fields
|
|
||||||
'( (:date . 25)
|
|
||||||
(:flags . 6)
|
|
||||||
(:from . 22)
|
|
||||||
(:subject . nil))
|
|
||||||
"A list of header fields to show in the headers buffer, and their
|
|
||||||
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'"
|
|
||||||
:type (list 'symbol)
|
|
||||||
:group 'mu4e-headers)
|
|
||||||
|
|
||||||
(defcustom mu4e-headers-date-format "%x %X"
|
|
||||||
"Date format to use in the headers view, in the format of
|
|
||||||
`format-time-string'."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e-headers)
|
|
||||||
|
|
||||||
(defcustom mu4e-headers-leave-behavior 'ask
|
|
||||||
"What to do when user leaves the headers view (e.g. quits,
|
|
||||||
refreshes or does a new search). Value is one of the following
|
|
||||||
symbols:
|
|
||||||
- ask (ask the user whether to ignore the marks)
|
|
||||||
- apply (automatically apply the marks before doing anything else)
|
|
||||||
- ignore (automatically ignore the marks without asking)."
|
|
||||||
:type 'symbol
|
|
||||||
:group 'mu4e-headers)
|
|
||||||
|
|
||||||
|
|
||||||
(defcustom mu4e-headers-visible-lines 8
|
|
||||||
"Number of lines to display in the header view when using the
|
|
||||||
horizontal split-view."
|
|
||||||
:type 'integer
|
|
||||||
:group 'mu4e-headers)
|
|
||||||
|
|
||||||
|
|
||||||
(defcustom mu4e-headers-visible-columns 30
|
|
||||||
"Number of columns to display for the header view when using the
|
|
||||||
vertical split-view."
|
|
||||||
:type 'integer
|
|
||||||
:group 'mu4e-headers)
|
|
||||||
|
|
||||||
;; the message view
|
|
||||||
(defgroup mu4e-view nil
|
|
||||||
"Settings for the message view."
|
|
||||||
:group 'mu4e)
|
|
||||||
|
|
||||||
(defcustom mu4e-view-fields
|
|
||||||
'(:from :to :cc :subject :flags :date :maildir :attachments)
|
|
||||||
"Header fields to display in the message view buffer. For the
|
|
||||||
complete list of available headers, see `mu4e-header-names'."
|
|
||||||
:type (list 'symbol)
|
|
||||||
:group 'mu4e-view)
|
|
||||||
|
|
||||||
(defcustom mu4e-view-date-format "%c"
|
|
||||||
"Date format to use in the message view, in the format of
|
|
||||||
`format-time-string'."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e-view)
|
|
||||||
|
|
||||||
(defcustom mu4e-view-prefer-html nil
|
|
||||||
"Whether to base the body display on the HTML-version of the
|
|
||||||
e-mail message (if there is any."
|
|
||||||
:type 'boolean
|
|
||||||
:group 'mu4e-view)
|
|
||||||
|
|
||||||
(defcustom mu4e-html2text-command nil
|
|
||||||
"Shel command that converts HTML from stdin into plain text on
|
|
||||||
stdout. If this is not defined, the emacs `html2text' tool will be
|
|
||||||
used when faced with html-only message. If you use htmltext, it's
|
|
||||||
recommended you use \"html2text -utf8 -width 72\"."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e-view
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
|
|
||||||
(defcustom mu4e-view-wrap-lines nil
|
|
||||||
"Whether to automatically wrap lines in the body of messages when
|
|
||||||
viewing them. Note that wrapping does not work well with all
|
|
||||||
messages, but you can always toggle between wrapped/unwrapped
|
|
||||||
display with `mu4e-view-toggle-wrap-lines (default keybinding: <w>)."
|
|
||||||
:group 'mu4e-view)
|
|
||||||
|
|
||||||
(defcustom mu4e-view-wrap-lines nil
|
|
||||||
"Whether to automatically wrap lines in the body of messages when
|
|
||||||
viewing them. Note that wrapping does not work well with all
|
|
||||||
messages, but you can always toggle between wrapped/unwrapped
|
|
||||||
display with `mu4e-view-toggle-wrap-lines (default keybinding: <w>)."
|
|
||||||
:group 'mu4e-view)
|
|
||||||
|
|
||||||
|
|
||||||
(defcustom mu4e-view-hide-cited nil
|
|
||||||
"Whether to automatically hide cited parts of messages (as
|
|
||||||
determined by the presence of '> ' at the beginning of the
|
|
||||||
line). Note that you can always toggle between hidden/unhidden
|
|
||||||
display with `mu4e-view-toggle-hide-cited (default keybinding:
|
|
||||||
<w>)."
|
|
||||||
:group 'mu4e-view)
|
|
||||||
|
|
||||||
|
|
||||||
;; Composing / Sending messages
|
|
||||||
(defgroup mu4e-compose nil
|
|
||||||
"Customizations for composing/sending messages."
|
|
||||||
:group 'mu4e)
|
|
||||||
|
|
||||||
(defcustom mu4e-send-citation-prefix "> "
|
|
||||||
"String to prefix cited message parts with."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e-compose)
|
|
||||||
|
|
||||||
(defcustom mu4e-send-reply-prefix "Re: "
|
|
||||||
"String to prefix the subject of replied messages with."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e-compose)
|
|
||||||
|
|
||||||
(defcustom mu4e-send-forward-prefix "Fwd: "
|
|
||||||
"String to prefix the subject of forwarded messages with."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e-compose)
|
|
||||||
|
|
||||||
(defcustom mu4e-user-agent nil
|
|
||||||
"The user-agent string; leave at `nil' for the default."
|
|
||||||
:type 'string
|
|
||||||
:group 'mu4e-compose)
|
|
||||||
|
|
||||||
(defcustom mu4e-sent-messages-behavior 'sent
|
|
||||||
"Determines what mu4e does with sent messages - this is a symbol
|
|
||||||
which can be either:
|
|
||||||
'sent --> move the sent message to the Sent-folder (`mu4e-sent-folder')
|
|
||||||
'trash --> move the sent message to the Trash-folder (`mu4e-trash-folder')
|
|
||||||
'delete --> delete the sent message.
|
|
||||||
Note, when using GMail/IMAP, you should set this to either 'trash
|
|
||||||
or 'delete, since GMail already takes care of keeping copies in the
|
|
||||||
sent folder."
|
|
||||||
:type 'symbol
|
|
||||||
:safe 'symbolp
|
|
||||||
:group 'mu4e-compose)
|
|
||||||
|
|
||||||
|
|
||||||
;; Faces
|
|
||||||
|
|
||||||
(defgroup mu4e-faces nil
|
|
||||||
"Type faces (fonts) used in mu4e."
|
|
||||||
:group 'mu4e
|
|
||||||
:group 'faces)
|
|
||||||
|
|
||||||
|
|
||||||
(defface mu4e-unread-face
|
|
||||||
'((t :inherit font-lock-keyword-face :bold t))
|
|
||||||
"Face for an unread message header."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-moved-face
|
|
||||||
'((t :inherit font-lock-comment-face :slant italic))
|
|
||||||
"Face for a message header that has been moved to some
|
|
||||||
folder (it's still visible in the search results, since we cannot
|
|
||||||
be sure it no longer matches)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-trashed-face
|
|
||||||
'((t :inherit font-lock-comment-face :strike-through t))
|
|
||||||
"Face for an message header in the trash folder."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-draft-face
|
|
||||||
'((t :inherit font-lock-string-face))
|
|
||||||
"Face for a draft message header (i.e., a message with the draft
|
|
||||||
flag set)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-header-face
|
|
||||||
'((t :inherit default))
|
|
||||||
"Face for a header without any special flags."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-header-title-face
|
|
||||||
'((t :inherit font-lock-type-face))
|
|
||||||
"Face for a header title in the headers view."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-view-header-key-face
|
|
||||||
'((t :inherit font-lock-builtin-face :bold t))
|
|
||||||
"Face for a header title (such as \"Subject\") in the message
|
|
||||||
view."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-header-highlight-face
|
|
||||||
'((t :inherit default :weight bold :underline t))
|
|
||||||
"Face for the header at point."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-view-header-value-face
|
|
||||||
'((t :inherit font-lock-doc-face))
|
|
||||||
"Face for a header value (such as \"Re: Hello!\") in the message
|
|
||||||
view."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-view-link-face
|
|
||||||
'((t :inherit font-lock-type-face :underline t))
|
|
||||||
"Face for showing URLs and attachments in the message view."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-highlight-face
|
|
||||||
'((t :inherit font-lock-pseudo-keyword-face :bold t))
|
|
||||||
"Face for highlighting things."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-title-face
|
|
||||||
'((t :inherit font-lock-type-face :bold t))
|
|
||||||
"Face for a header title in the headers view."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-view-url-number-face
|
|
||||||
'((t :inherit font-lock-reference-face :bold t))
|
|
||||||
"Face for the number tags for URLs."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-view-attach-number-face
|
|
||||||
'((t :inherit font-lock-variable-name-face :bold t))
|
|
||||||
"Face for the number tags for attachments."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-cited-1-face
|
|
||||||
'((t :inherit font-lock-builtin-face :bold nil :italic t))
|
|
||||||
"Face for cited message parts (level 1)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-cited-2-face
|
|
||||||
'((t :inherit font-lock-type-face :bold nil :italic t))
|
|
||||||
"Face for cited message parts (level 2)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-cited-3-face
|
|
||||||
'((t :inherit font-lock-variable-name-face :bold nil :italic t))
|
|
||||||
"Face for cited message parts (level 3)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-cited-4-face
|
|
||||||
'((t :inherit font-lock-pseudo-keyword-face :bold nil :italic t))
|
|
||||||
"Face for cited message parts (level 4)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-view-footer-face
|
|
||||||
'((t :inherit font-lock-comment-face))
|
|
||||||
"Face for message footers (signatures)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-hdrs-marks-face
|
|
||||||
'((t :inherit font-lock-preprocessor-face))
|
|
||||||
"Face for the mark in the headers list."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
(defface mu4e-system-face
|
|
||||||
'((t :inherit font-lock-comment-face :slant italic))
|
|
||||||
"Face for system message (such as the footers for message
|
|
||||||
headers)."
|
|
||||||
:group 'mu4e-faces)
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; internal variables / constants
|
|
||||||
|
|
||||||
(defconst mu4e-header-names
|
|
||||||
'( (:attachments . "Attach")
|
|
||||||
(:bcc . "Bcc")
|
|
||||||
(:cc . "Cc")
|
|
||||||
(:date . "Date")
|
|
||||||
(:flags . "Flgs")
|
|
||||||
(:from . "From")
|
|
||||||
(:from-or-to . "From/To")
|
|
||||||
(:maildir . "Maildir")
|
|
||||||
(:path . "Path")
|
|
||||||
(:subject . "Subject")
|
|
||||||
(:to . "To"))
|
|
||||||
"A 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 ,
|
|
||||||
in which case it will be equal to `:to'.)")
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
(defvar mu4e-update-timer nil
|
|
||||||
"*internal* The mu4e update timer.")
|
|
||||||
|
|
||||||
(defun mu4e ()
|
|
||||||
"Start mu4e. We do this by sending a 'ping' to the mu server
|
|
||||||
process, and start the main view if the 'pong' we receive from the
|
|
||||||
server has the expected values."
|
|
||||||
(interactive)
|
|
||||||
(if (buffer-live-p (get-buffer mu4e-main-buffer-name))
|
|
||||||
(switch-to-buffer mu4e-main-buffer-name)
|
|
||||||
(mu4e-check-requirements)
|
|
||||||
;; explicit version checks are a bit questionable,
|
|
||||||
;; better to check for specific features
|
|
||||||
(if (< emacs-major-version 23)
|
|
||||||
(error "Emacs >= 23.x is required for mu4e")
|
|
||||||
(progn
|
|
||||||
(setq mu4e-proc-pong-func
|
|
||||||
(lambda (version doccount)
|
|
||||||
(unless (string= version mu4e-mu-version)
|
|
||||||
(error "mu server has version %s, but we need %s"
|
|
||||||
version mu4e-mu-version))
|
|
||||||
(mu4e-main-view)
|
|
||||||
(when (and mu4e-update-interval (null mu4e-update-timer))
|
|
||||||
(setq mu4e-update-timer
|
|
||||||
(run-at-time
|
|
||||||
0 mu4e-update-interval
|
|
||||||
'mu4e-update-mail)))
|
|
||||||
(message "Started mu4e with %d message%s in store"
|
|
||||||
doccount (if (= doccount 1) "" "s"))))
|
|
||||||
(mu4e-proc-ping)))))
|
|
||||||
|
|
||||||
(defun mu4e-quit()
|
|
||||||
"Quit the mu4e session."
|
|
||||||
(interactive)
|
|
||||||
(when (y-or-n-p "Are you sure you want to quit? ")
|
|
||||||
(message nil)
|
|
||||||
(when mu4e-update-timer
|
|
||||||
(cancel-timer mu4e-update-timer)
|
|
||||||
(setq mu4e-update-timer nil))
|
|
||||||
(mu4e-kill-proc)
|
|
||||||
(kill-buffer)))
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
(provide 'mu4e)
|
(provide 'mu4e)
|
||||||
|
|
Loading…
Reference in New Issue