Skip to content

Latest commit

 

History

History
943 lines (756 loc) · 52.4 KB

starter-kit-mu4e-with-offlineimap.org

File metadata and controls

943 lines (756 loc) · 52.4 KB

mu4e Customizations

This is part of the Emacs Starter Kit.

Path to installation

This is the path where mu4e got installed when I did the installation of mu and mu4e thru the Debian repository with maildir-utils.

NB: I disabled now that we are using use-package… but I had to re-enable it or else it won’t work.

;; in Debian
;;  (add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e")

;; In Ubuntu
  (add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e")
  (setq mu4e-mu-binary (executable-find "/usr/bin/mu"))

Note that if I installed mu manually, these are the paths in the officePC.

(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e")
(setq mu4e-mu-binary (executable-find "/usr/local/bin/mu"))

The critical files for using mu4e

The following files live in the directory /usr/share/emacs/site-lisp/mu4e

In the DW’s setup, he uses use-package. Because we haven’t ued elpa to install mu4e, we use :ensure nil.

It is key that mu4e and mu stay in sync-ed so we work with the two that we install with our package manager.

Below, bear in mind that

:load-path  /usr/share/emacs/site-lisp/mu4e/

might be needed. Apparently not in Ubuntu, might be needed in other distros.

Bits taken out:

;; mu4e-mu-binary (executable-find “/usr/bin/mu”)

Read https://jherrlin.github.io/posts/emacs-mu4e/ for much of this customization.

(use-package mu4e
  :bind ("C-*" . mu4e)
  :ensure nil
  :init

  (defun work/mu4e-bookmark-num-days-old-query (days-old)
    (interactive (list (read-number "Show days old messages: " 7)))
    (let ((start-date (subtract-time (current-time) (days-to-time days-old))))
      (concat "maildir:/work/INBOX AND date:"
              (format-time-string "%Y%m%d" start-date))))

  (defun personal/mu4e-bookmark-num-days-old-query (days-old)
    (interactive (list (read-number "Show days old messages: " 7)))
    (let ((start-date (subtract-time (current-time) (days-to-time days-old))))
      (concat "maildir:/personal/INBOX AND date:"
              (format-time-string "%Y%m%d" start-date))))

  (add-hook 'mu4e-headers-mode-hook
            (defun my/mu4e-change-headers ()
              (interactive)
              (setq mu4e-headers-fields
                    `((:date . 25) ;; alternatively, use :date
                      (:flags . 6)
                      (:from . 22)
                      (:thread-subject . ,(- (window-body-width) 70)) ;; alternatively, use  :subject
                      (:size . 7)
                      ))))

  (defun sign-or-encrypt-message ()
    (let ((answer (read-from-minibuffer "Sign or encrypt?\nEmpty to do nothing.\n[s/e]: ")))
      (cond
       ((string-equal answer "s") (progn
                                    (message "Signing message.")
                                    (mml-secure-message-sign-pgpmime)))
       ((string-equal answer "e") (progn
                                    (message "Encrypt and signing message.")
                                    (mml-secure-message-encrypt-pgpmime)))
       (t (progn
            (message "Dont signing or encrypting message.")
            nil)))))

  ;; (add-hook 'message-send-hook 'sign-or-encrypt-message)

  (add-hook 'message-mode-hook 'turn-on-orgtbl)
  :config
  (setq mail-user-agent 'mu4e-user-agent)
  (setq mu4e-maildir (expand-file-name "~/Maildir")
        mu4e-sent-folder nil ;; must be configured later by context
        mu4e-drafts-folder nil ;; must be configured later by context
        mu4e-trash-folder nil ;; must be configured later by context
        mu4e-refile-folder nil ;; must be configured later by context
        mu4e-change-filenames-when-moving t
        message-kill-buffer-on-exit t
        mu4e-attachment-dir  "~/Downloads"
        mu4e-save-multiple-attachments-without-asking t
        mu4e-completing-read-function 'completing-read
        mu4e-compose-complete-addresses t
        mu4e-compose-context-policy nil
        mu4e-compose-dont-reply-to-self t
        mu4e-compose-keep-self-cc nil
        mu4e-context-policy 'pick-first
        mu4e-get-mail-command "offlineimap"
        mu4e-headers-date-format "%d/%m/%Y %H:%M"
        mu4e-headers-fields
        `((:human-date . 20) ;; alternatively, use :date
          (:flags . 6)
          (:mailing-list . 10)
          (:from . 22)
          (:subject))
        mu4e-headers-include-related 'nil
        mu4e-sent-messages-behavior 'delete
        mu4e-view-show-addresses t
        mm-sign-option 'guided
        mu4e-view-scroll-to-next 'nil
        mu4e-headers-time-format "%R"
        mu4e-mu-binary "/usr/local/bin/mu"
        mu4e-decryption-policy t
        mml-secure-openpgp-encrypt-to-self nil
        mu4e-split-view nil
        mu4e-confirm-quit nil
        mu4e-hide-index-messages nil
        mu4e-index-cleanup t   ;; don't do a full cleanup check (see mu-index manpage)
        mu4e-index-lazy-check nil  ;; don't consider up-to-date dirs
        mu4e-view-fields '(:from :to :cc :bcc :subject :flags :date :maildir :mailing-list :tags :attachments :signature :decryption)
        ))
;; (require 'mu4e)         ;; disabled in Ubuntu until I fix it... Now with the aid of DW I'm going to use <use-package> instead
(require 'org-mu4e)        ;;store org-mode links to messages
(require 'mu4e-contrib)   

Receiving emails: Setting up the MU mail server

Introduced by DGM on 4 august 2019 following https://www.reddit.com/r/emacs/comments/bfsck6/mu4e_for_dummies/

Sending emails with msmtp

(setq message-send-mail-function 'message-send-mail-with-sendmail
      sendmail-program "/usr/bin/msmtp")

;; Commented out by DGM on 4 august because I am trying to be able to choose where to send from.
;;        user-full-name "Daniel Guinea"
;;        user-mail-address "daniel.guinea.uned@gmail.com")

Sending html email

org-mime can be used to send HTML email using Org-mode HTML export.

(use-package org-mime
  :after org
  :defer t)

;; convert org mode to HTML automatically
(setq org-mu4e-convert-to-html t)

Signature

Tip from http://www.macs.hw.ac.uk/~rs46/posts/2014-11-16-mu4e-signatures.html for inserting different signatures

  (defun my/mu4e-choose-signature ()
    "Insert one of a number of signatures"
    (interactive)
    (let ((message-signature
            (mu4e-read-option "Signature:"
              '(("formal" .
                (concat
             "Daniel Guinea\n"
             "Dept. Sociología I\nFacultad de CC.PP. y Sociología\nUniversidad Nacional de Educación a Distancia (UNED)\nCalle Obispo Trejo 2, Madrid 28040\nemail: daniel.guinea@poli.uned.es\nTel. +34 91 398 9441"))
                 ("informal" .
                "Daniel\n")))))
      (message-insert-signature)))

;; Now that I am using org mode somehow when composing emails, this keybind is already in use
(add-hook 'mu4e-compose-mode-hook
            (lambda () (local-set-key (kbd "C-c C-w") #'my/mu4e-choose-signature)))

Context feature of mu4e

Note that Set format=flowed:

  • mu4e sets up visual-line-mode and also fill (M-q) to do the right thing. Each paragraph is a single long line; at sending, emacs will add the special line continuation characters.

Also, note that it is preferably to use context names starting with different letters, because the first letter is automatically used as a short-cut, so you will be able to switch between the two contexts simply using ;w and ;p.

Note, mu4e-maildir takes an actual filesystem-path, the other folder names are all relative to mu4e-maildir. Also note that this must not be a symbolic link.

(setq mu4e-contexts
      `( ,(make-mu4e-context
           :name "work"
           :enter-func (lambda () (mu4e-message "Entering work context")
                         (when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
                           (revert-buffer)))
           :leave-func (lambda () (mu4e-message "Leaving work context")
                         (when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
                           (revert-buffer)))
           ;; we match based on the contact-fields of the message
           :match-func (lambda (msg)
                         (when msg
                           (or (mu4e-message-contact-field-matches msg
                                                                   :to "daniel.guinea.uned@gmail.com")
                               (mu4e-message-contact-field-matches msg
                                                                   :from "daniel.guinea.uned@gmail.com")
                               (mu4e-message-contact-field-matches msg
                                                                   :to "daniel.guinea@poli.uned.es")
                               (mu4e-message-contact-field-matches msg
                                                                   :from "daniel.guinea@poli.uned.es")
                               )))
           :vars '(( user-mail-address . "daniel.guinea.uned@gmail.com")
                   ( user-full-name . "Daniel Guinea")
                   (mu4e-compose-format-flowed . t)
                   (mu4e-sent-folder . "/[Gmail].Sent Mail")
                   (mu4e-drafts-folder . "/[Gmail].Drafts")
                   (mu4e-trash-folder . "/[Gmail].Trash")
                   (mu4e-refile-folder . "/[Gmail].All Mail")
                   (mu4e-maildir-shortcuts . ( ("/INBOX"            . ?i)
                                               ("/[Gmail].Sent Mail" . ?s)
                                               ("/[Gmail].Drafts"    . ?d)
                                               ("/[Gmail].Trash"     . ?t)
                                               ("/[Gmail].All Mail"  . ?a)
                                               ("/[Gmail].Spam"      . ?b)))
                   (mu4e-bookmarks . (
                                      ( :name "Messages with attachment"
                                        :query "(maildir:/INBOX OR maildir:/[Gmail].Spam) AND flag:attach"
                                        :key ?a)
                                      ( :name "Big messages"
                                        :query "(maildir:/INBOX OR maildir:/[Gmail].Spam) AND size:5M..500M"
                                        :key ?b)
                                      ( :name "Eurostat"
                                        :key  ?e
                                        :query "(maildir:/INBOX OR maildir:/[Gmail].Spam OR maildir:/[Gmail].Drafts OR maildir:/[Gmail].Trash) AND (from:nicoletta.schweikle-hilgner@ec.europa.eu OR from:ESTAT-Microdata-access@ec.europa.eu OR from:estat-microdata-access@ec.europa.eu OR from:Fabienne.MONTAIGNE@ec.europa.eu OR from:Patrick.PILLARD@ec.europa.eu OR from:Karien.Reinig@ec.europa.eu OR from:S-CIRCABC@nomail.ec.europa.eu)")
                                      ( :name "Máster FOL"
                                        :key  ?f
                                        :query "(maildir:/INBOX OR maildir:/[Gmail].Spam OR maildir:/[Gmail].Drafts OR maildir:/[Gmail].Trash) AND (subject:tfm OR subject:TFM OR body:tfm OR body:TFM OR subject:\"trabajo fin de master\" OR body:\"trabajo fin de master\" OR from:\"Ana María González\" OR from:gabriela.topa1@gmail.com OR from:\"Gabriela Topa\" OR from:gtopa@psi.uned.es OR from:\"Máster Formación Profesorado\" OR from:master-formacionprofesorado@adm.uned.es OR from:\"M. Angeles Serrano Garcia\" OR from:maserrano@pas.uned.es OR from:\"M. del Puerto Hojas Rosales\" OR from:mhojas@pas.uned.es OR from:\"Ana María González\" OR from:amgonzalez@edu.uned.es OR subjetc:\"TFM\")")
                                      (:name "Inbox messages in the last ?x days"
                                             :query ,(lambda () (call-interactively 'work/mu4e-bookmark-num-days-old-query))
                                             :key ?h)
                                      ( :name "Messages with images"
                                        :query "maildir:/INBOX AND mime:image/*"
                                        :key ?i)
                                      ( :name "Unread (pending) messages"
                                        :query "(maildir:/INBOX OR maildir:/[Gmail].Spam) AND flag:unread AND NOT flag:trashed"
                                        :key ?p)
                                      (:name "Ricardo"
                                             :key  ?r
                                             :query "(maildir:/INBOX OR maildir:/personal/INBOX OR maildir:/[Gmail].Spam OR maildir:/personal/[Gmail].Spam OR maildir:/[Gmail].Drafts OR maildir:/personal/[Gmail].Drafts OR maildir:/[Gmail].Trash OR maildir:/personal/[Gmail].Trash) AND (from:ricardo.mora.villarrubia@gmail.com OR from:ricardo.mora@uc3m.es OR from:ricardo.mora.villarrubia@outlook.com OR from:\"Ricardo Mora\" OR from:ricmora@eco.uc3m.es OR from:\"Adelheid Holl\" OR from:a.holl@csic.es)")
                                      ( :name "Sent in last 7 days"
                                        :key  ?s
                                        :query "maildir:\"/[Gmail].Sent Mail\" AND date:7d..now")
                                      ( :name "Today's messages"
                                        :query "(maildir:/INBOX OR maildir:/[Gmail].Spam) AND date:today..now"
                                        :key ?t)
                                      (  :name "UNED"
                                         :key  ?u
                                         :query "(maildir:/INBOX OR maildir:/[Gmail].Spam OR maildir:/[Gmail].Drafts OR maildir:/[Gmail].Trash) AND (from:\"Maria Angel\" OR from:departamentos.polisoci@adm.uned.es OR from:secretaria.poli.soci@adm.uned.es OR from:decanato.polisoci@adm.uned.es OR from:negociado-pruebas-presenciales@adm.uned.es OR from:vicepruebas@adm.uned.es OR from:vrector-pruebas-presen@adm.uned.es OR from:coord.pruebas@adm.uned.es OR from:pruebaspresenciales@adm.uned.es OR from:gastosextraordinariospruebas@adm.uned.es OR from:\"Secretaria Docente\" OR from:\"Secretaría Docente\" OR from:secdoc.cee@adm.uned.es OR from:\"MARIA ANGELES RODRIGUEZ SANTOS\" OR from:secretaria-ecoemp@adm.uned.es OR from:\"Secretaría Facultad CC. Economicas\" OR from:secadi.polisoci@adm.uned.es OR from:\"Secadi\" OR from:\"GUADALUPE DAMAS JURADO\" OR from:gdamas@pas.uned.es OR from:llosada@edu.uned.es OR from:egiralde@pas.uned.es OR from:\"MARIA GOMEZ ESCARDA\" OR from:mgomez@poli.uned.es OR from:sociologiauno@adm.uned.es OR from:vrector-profesorado@adm.uned.es OR from:\"Vicerrectorado de Profesorado\" OR from:vrector-gradoyposgrado@adm.uned.es OR from:vadj.grado@adm.uned.es OR from:alba.vrector@adm.uned.es) OR (subject:tfg OR subject:TFG OR body:tfg OR body:TFG OR subject:\"trabajo fin de grado\" OR body:\"trabajo fin de grado\" OR subject:\"/ex.men.*/\" OR body:\"/ex.men.*/\" OR subject:\"sociologia aplicada\" OR body:\"sociologia aplicada\" OR subject:/modelo.*/)")
                                      ( :name "Work-hunt"
                                        :key  ?w
                                        :query "(maidlir:/INBOX OR maildir:/personal/INBOX OR maildir:/[Gmail].Spam OR maildir:/personal/[Gmail].Spam OR maildir:/[Gmail].Drafts OR maildir:/personal/[Gmail].Drafts OR maildir:/[Gmail].Trash OR maildir:/personal/[Gmail].Trash) AND (from:\"Belén Barreiro\" OR from:bbarreiro@40db.es OR from:40db.es OR from:\"Mónica Méndez\" OR from:monica.mendez@cis.es OR from:\"Luis Manuel Ayus oSanchez\" Or from:luis.ayuso@uma.es OR from:\"Juan Ignacio Martinez Pastor\" OR from:jimartinez@poli.uned.es OR from:ecb@uma.es)")
                                      ( :name "Unread messages"
                                        :key  ?x
                                        :query "flag:unread AND maildir:/INBOX AND NOT flag:trashed")))))
         ,(make-mu4e-context
           :name "personal"
           :enter-func (lambda () (mu4e-message "Switch to personal context")
                         (when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
                           (revert-buffer)))
           :leave-func (lambda () (mu4e-message "Leaving personal context")
                         (when (string-match-p (buffer-name (current-buffer)) "mu4e-main")
                           (revert-buffer)))
           ;; we match based on the maildir of the message
           ;; this matches maildir /personal and its sub-directories
           :match-func (lambda (msg)
                         (when msg
                           (or (string-match-p "^/personal" (mu4e-message-field msg :maildir))
                               (mu4e-message-contact-field-matches msg :to "daniel.guinea.martin@gmail.com")
                               (mu4e-message-contact-field-matches msg :from "daniel.guinea.martin@gmail.com")
                               (mu4e-message-contact-field-matches msg :cc "daniel.guinea.martin@gmail.com")
                               (mu4e-message-contact-field-matches msg :bcc "daniel.guinea.martin@gmail.com"))))
           :vars '( (user-mail-address . "daniel.guinea.martin@gmail.com")
                    (user-full-name . "Daniel")
                    (mu4e-sent-folder . "/personal/[Gmail].Sent Mail")
                    (mu4e-drafts-folder . "/personal/[Gmail].Drafts")
                    (mu4e-trash-folder . "/personal/[Gmail].Trash")
                    (mu4e-refile-folder . "/personal/[Gmail].All Mail")
                    (mu4e-compose-format-flowed . t)
                    (mu4e-maildir-shortcuts . ( ("/personal/INBOX"             . ?i)
                                                ("/personal/[Gmail].Sent Mail" . ?s)
                                                ("/personal/[Gmail].Drafts"    . ?d)
                                                ("/personal/[Gmail].Trash"     . ?t)
                                                ("/personal/[Gmail].All Mail"  . ?a)
                                                ("/personal/[Gmail].Spam"      . ?b)))
                    (mu4e-bookmarks  .
                                     ((:name "Ave María"
                                             :key  ?m
                                             :query "(maildir:/INBOX OR maildir:/personal/INBOX OR maildir:/[Gmail].Spam OR maildir:/personal/[Gmail].Spam OR maildir:/[Gmail].Drafts OR maildir:/personal/[Gmail].Drafts OR maildir:/[Gmail].Trash OR maildir:/personal/[Gmail].Trash) AND (from:\"Kenedy Alva\" OR from:kenedy@gmail.com OR from:\"Paz Torrente\" OR from:paztorrente@gmail.com OR from:\"Javier Martín\" OR from:javiermartinr@gmail.com OR from:\"Canal de Isabel II\" OR from:comunicaciones.comerciales@canaldeisabelsegunda.es OR from:\"Jazztel\" OR from:att.cliente.jazztel@jazztel.com)")
                                      ( :name "Messages with attachment"
                                        :query "(maildir:/personal/INBOX OR /personal/[Gmail].Spam) AND flag:attach"
                                        :key ?a)
                                      ( :name "Big messages"
                                        :query "(maildir:/personal/INBOX OR /personal/[Gmail].Spam) AND size:5M..500M"
                                        :key ?b)
                                      ( :name "Operation D"
                                        :key  ?d
                                        :query "(maildir:/INBOX OR maildir:/personal/INBOX OR maildir:/[Gmail].Spam OR maildir:/personal/[Gmail].Spam OR maildir:/[Gmail].Drafts OR maildir:/personal/[Gmail].Drafts OR maildir:/[Gmail].Trash OR maildir:/personal/[Gmail].Trash) AND (from:\"Paula Zingoni\" OR from:paulazingoni@gmail.com OR from:\"Croydon County\" OR from:\"Family\" OR from:family.croydon.countycourt@justice.gov.uk OR from:\"Jose Antonio Arcila\" OR from:joseantonio@arcila-abogados.es OR from:\"Elena Benítez Imedio\" OR from:ebi@ayuelajimenez.es OR from:ebi@ebiroy.com OR from:\"Juan Antonio Montoro\" OR from:jmontoro@euroconsejo.org OR from:\"Pablo Velasco Espinosa\" OR from:pvelasco@euroconsejo.org OR from:mensajeria@phidias.es OR from:\"Montessori School\" OR from:\"Mataespesa Montessori School\" OR from:mataespesa@montessorischool.es OR from:\"Laura Romay\" OR from:\"Anna Dick\" OR from:anna.dick@montessorischool.es OR form:\"Gema Baeza Gómez\" OR from:gbg@ayuelajimenez.es)")
                                      (:name "Inbox messages in the last ?x days"
                                             :query ,(lambda () (call-interactively 'personal/mu4e-bookmark-num-days-old-query))
                                             :key ?h)
                                      ( :name "Messages with images"
                                        :query "(maildir:/personal/INBOX OR /personal/[Gmail].Spam) AND mime:image/*"
                                        :key ?i)
                                      ( :name "Unread (pending) messages"
                                        :query "(maildir:/personal/INBOX OR /personal/[Gmail].Spam) AND flag:unread AND NOT flag:trashed"
                                        :key ?p)
                                      ( :name "Sent in last 7 days"
                                        :key  ?s
                                        :query "maildir:\"/personal/[Gmail].Sent Mail\" AND date:7d..now")
                                      ( :name "Today's messages"
                                        :query "maildir:/personal/INBOX AND date:today..now"
                                        :key ?t)
                                      ( :name "Twyford"
                                        :key  ?y
                                        :query "maildir:/personal/INBOX AND (from:SC3074602a@schoolcomms.com OR from:\"TWY\" OR from:DataTeam@twyford.ealing.sch.uk OR from:\"TWYFORD CE HIGH SCHOOL\" OR from:a.holl@csic.es OR from:6thform@twyford.ealing.sch.uk OR from:\"6th Form - TWY\" OR from:Admissions@twyford.ealing.sch.uk OR from:\"Admissions - TWY\" OR from:marthur@twyford.ealing.sch.uk OR from:\"Michael Arthur\" OR from:\"Lucille De Costa\")")
                                      ( :name "Unread messages (Personal inbox)"
                                        :key  ?x
                                        :query "flag:unread AND maildir:/personal/INBOX AND NOT flag:trashed")))))))

Context tricks

It is possible to automatically fill mu4e-user-address-list by concatenating the user-mail-address fields of all contexts:

This sets `mu4e-user-mail-address-list’ to the concatenation of all `user-mail-address’ values for all contexts. If you have other mail addresses as well, you’ll need to add those manually.

 (setq mu4e-user-mail-address-list
   (delq nil
     (mapcar (lambda (context)
		(when (mu4e-context-vars context)
		  (cdr (assq 'user-mail-address (mu4e-context-vars context)))))
	mu4e-contexts)))

Attachments

Gnus for attaching

I don’t know the use of this but I had it, so…

(require 'gnus-dired)
;; make the `gnus-dired-mail-buffers' function also work on
;; message-mode derived modes, such as mu4e-compose-mode
(defun gnus-dired-mail-buffers ()
  "Return a list of active message buffers."
  (let (buffers)
    (save-current-buffer
      (dolist (buffer (buffer-list t))
        (set-buffer buffer)
        (when (and (derived-mode-p 'message-mode)
                   (null message-sent-message-via))
          (push (buffer-name buffer) buffers))))
    (nreverse buffers)))

 (setq gnus-dired-mail-mode 'mu4e-user-agent)
 (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode)

Saving attachments

(setq mu4e-save-multiple-attachments-without-asking t)

Customizing the main view

version 1.4.12 way of doing it

(add-to-list 'mu4e-bookmarks
             ;; add bookmark for recent messages on the Mu mailing list.
             '(( :name "Unread messages (Work inbox)"
                 :key  ?x
                 :query "flag:unread AND maildir:\"/work/INBOX\" AND NOT flag:trashed")
               ( :name "Ave María"
                 :key  ?a
                 :query "maildir:\"/work/INBOX\" OR maildir:\"/personal/INBOX\" OR maildir:\"/work/[work].Spam\" OR maildir:\"/personal/[personal].Spam\" OR maildir:\"/work/[work].Drafts\" OR maildir:\"/personal/[personal].Drafts\" OR maildir:\"/work/[work].Trash\" OR maildir:\"/personal/[personal].Trash\") AND (from:\"Kenedy Alva\" OR from:kenedy@gmail.com OR from:\"Paz Torrente\" OR from:paztorrente@gmail.com OR from:\"Javier Martín\" OR from:javiermartinr@gmail.com OR from:\"Canal de Isabel II\" OR from:comunicaciones.comerciales@canaldeisabelsegunda.es OR from:\"Jazztel\" OR from:att.cliente.jazztel@jazztel.com")
               ( :name "BICI"
                 :key  ?b
                 :query "from:\"BICI\" OR from:bici@adm.uned.es")
               ( :name "Convalidaciones"
                 :key  ?c
                 :query "maildir:\"/work/INBOX\" OR maildir:\"/work/[work].Spam\" OR maildir:\"/work/[work].Drafts\" OR maildir:\"/work/[work].Trash\") AND (from:convalid.empresariales@adm.uned.es OR from:\"Negociado de atención al estudiante\" OR from:estudiantes.polisoci@adm.uned.es OR from:\"CARMEN DIAZ BRAGADO\" OR from:cadiaz@pas.uned.es OR subject:convalidación OR subject:convalidacion OR subject:convalidaciones OR body:convalidación OR body:convalidacion  OR body:convalidaciones OR subject:reconocimiento OR subject:Reconocimiento OR subject:reconocimientos OR subject:Reconocimientos OR body:reconocimiento OR body:Reconocimiento OR body:reconocimientos OR body:Reconocimientos")
               ( :name "Operation D"
                 :key  ?d
                 :query "maildir:\"/work/INBOX\" OR maildir:\"/personal/INBOX\" OR maildir:\"/work/[work].Spam\" OR maildir:\"/personal/[personal].Spam\" OR maildir:\"/work/[work].Drafts\" OR maildir:\"/personal/[personal].Drafts\" OR maildir:\"/work/[work].Trash\" OR maildir:\"/personal/[personal].Trash\") AND (from:\"Paula Zingoni\" OR from:paulazingoni@gmail.com OR from:\"Croydon County\" OR from:\"Family\" OR from:family.croydon.countycourt@justice.gov.uk OR from:\"Jose Antonio Arcila\" OR from:joseantonio@arcila-abogados.es OR from:\"Elena Benítez Imedio\" OR from:ebi@ayuelajimenez.es OR from:ebi@ebiroy.com OR from:\"Juan Antonio Montoro\" OR from:jmontoro@euroconsejo.org OR from:\"Pablo Velasco Espinosa\" OR from:pvelasco@euroconsejo.org OR from:mensajeria@phidias.es OR from:\"Montessori School\" OR from:\"Mataespesa Montessori School\" OR from:mataespesa@montessorischool.es OR from:\"Laura Romay\" OR from:\"Anna Dick\" OR from:anna.dick@montessorischool.es OR form:\"Gema Baeza Gómez\" OR from:gbg@ayuelajimenez.es")
               ( :name "Eurostat"
                 :key  ?e
                 :query "maildir:\"/work/INBOX\" OR maildir:\"/work/[work].Spam\" OR maildir:\"/work/[work].Drafts\" OR maildir:\"/work/[work].Trash\") AND (from:\"SCHWEIKLE-HILGNER Nicoletta\" OR from:nicoletta.schweikle-hilgner@ec.europa.eu) OR from:ESTAT-Microdata-access@ec.europa.eu OR from:estat-microdata-access@ec.europa.eu OR from:Fabienne.MONTAIGNE@ec.europa.eu OR from:Patrick.PILLARD@ec.europa.eu OR from:Karien.Reinig@ec.europa.eu OR from:S-CIRCABC@nomail.ec.europa.eu OR from:\"Dominique REUTER-WAGNER\"")
               ( :name "Work-hunt"
                 :key  ?h
                 :query "maidlir:\"/work/INBOX\" OR maildir:\"/personal/INBOX\" OR maildir:\"/work/[work].Spam\" OR maildir:\"/personal/[personal].Spam\" OR maildir:\"/work/[work].Drafts\" OR maildir:\"/personal/[personal].Drafts\" OR maildir:\"/work/[work].Trash\" OR maildir:\"/personal/[personal].Trash\") AND (from:\"Belén Barreiro\" OR from:bbarreiro@40db.es OR from:40db.es OR from:\"Mónica Méndez\" OR from:monica.mendez@cis.es) OR from:\"Luis Manuel Ayuso Sanchez\" Or from:luis.ayuso@uma.es OR from:\"Juan Ignacio Martinez Pastor\" OR from:jimartinez@poli.uned.es OR from:ecb@uma.es")
               ( :name "Fac., Dept., Vicerrec., TFG, Exámenes, Económicas"
                 :key  ?f
                 :query "maildir:\"/work/INBOX\" OR maildir:\"/work/[work].Spam\"  OR maildir:\"/work/[work].Drafts\" OR maildir:\"/work/[work].Trash\") AND ((from:\"Maria Angel\" OR from:departamentos.polisoci@adm.uned.es OR from:secretaria.poli.soci@adm.uned.es OR from:decanato.polisoci@adm.uned.es OR from:negociado-pruebas-presenciales@adm.uned.es OR from:vicepruebas@adm.uned.es OR from:vrector-pruebas-presen@adm.uned.es OR from:coord.pruebas@adm.uned.es OR from:pruebaspresenciales@adm.uned.es OR from:gastosextraordinariospruebas@adm.uned.es OR from:\"Secretaria Docente\" OR from:\"Secretaría Docente\" OR from:secdoc.cee@adm.uned.es OR from:\"MARIA ANGELES RODRIGUEZ SANTOS\" OR from:secretaria-ecoemp@adm.uned.es OR from:\"Secretaría Facultad CC. Economicas\" OR from:secadi.polisoci@adm.uned.es OR from:\"Secadi\" OR from:\"GUADALUPE DAMAS JURADO\" OR from:gdamas@pas.uned.es OR from:llosada@edu.uned.es OR from:egiralde@pas.uned.es OR from:\"MARIA GOMEZ ESCARDA\" OR from:mgomez@poli.uned.es OR from:sociologiauno@adm.uned.es OR from:vrector-profesorado@adm.uned.es OR from:\"Vicerrectorado de Profesorado\" OR from:vrector-gradoyposgrado@adm.uned.es OR from:vadj.grado@adm.uned.es OR from:alba.vrector@adm.uned.es) OR (subject:tfg OR subject:TFG OR body:tfg OR body:TFG OR subject:\"trabajo fin de grado\" OR body:\"trabajo fin de grado\" OR subject:\"/ex.men.*/\" OR body:\"/ex.men.*/\" OR subject:\"sociologia aplicada\"  OR body:\"sociologia aplicada\" OR subject:/modelo.*/")
               ( :name "Master FOL"
                 :key  ?t
                 :query "maildir:\"/work/INBOX\" OR maildir:\"/work/[work].Spam\" OR maildir:\"/work/[work].Drafts\" OR maildir:\"/work/[work].Trash\") AND (subject:tfm OR subject:TFM OR body:tfm OR body:TFM OR subject:\"trabajo fin de master\" OR body:\"trabajo fin de master\" OR from:\"Ana María González\" OR from:gabriela.topa1@gmail.com OR from:\"Gabriela Topa\" OR from:gtopa@psi.uned.es OR from:\"Máster Formación Profesorado\" OR from:master-formacionprofesorado@adm.uned.es OR from:\"M. Angeles Serrano Garcia\" OR from:maserrano@pas.uned.es OR from:\"M. del Puerto Hojas Rosales\" OR from:mhojas@pas.uned.es OR from:\"Ana María González\" OR from:amgonzalez@edu.uned.es OR subjetc:\"TFM\"")
               ( :name "Ricardo"
                 :key  ?r
                 :query "maildir:\"/work/INBOX\" OR maildir:\"/personal/INBOX\" OR maildir:\"/work/[work].Spam\" OR maildir:\"/personal/[personal].Spam\" OR maildir:\"/work/[work].Drafts\" OR maildir:\"/personal/[personal].Drafts\" OR maildir:\"/work/[work].Trash\" OR maildir:\"/personal/[personal].Trash\") AND (from:ricardo.mora.villarrubia@gmail.com OR from:ricardo.mora@uc3m.es OR from:ricardo.mora.villarrubia@outlook.com OR from:\"Ricardo Mora\" OR from:ricmora@eco.uc3m.es OR from:\"Adelheid Holl\" OR from:a.holl@csic.es")
               ( :name "Sent in last 7 days"
                 :key  ?s
                 :query "maildir:\"/personal/[personal].Sent Mail\" OR maildir:\"/work/[work].Sent Mail\") AND date:7d..now")
               ( :name "Twyford"
                 :key  ?y
                 :query "maildir:\"/personal/INBOX\") AND (from:SC3074602a@schoolcomms.com OR from:\"TWY\" OR from:DataTeam@twyford.ealing.sch.uk OR from:\"TWYFORD CE HIGH SCHOOL\" OR from:a.holl@csic.es OR from:6thform@twyford.ealing.sch.uk OR from:\"6th Form - TWY\" OR from:Admissions@twyford.ealing.sch.uk OR from:\"Admissions - TWY\" OR from:marthur@twyford.ealing.sch.uk OR from:\"Michael Arthur\" OR from:\"Lucille De Costa\"")))

Org capture templates, including some for emails

Placed here so that they work with emails. Restore to this location when I manage to make mu4e work.

Article from The Reddit Workflow, accessible at https://www.reddit.com/r/emacs/comments/4gudyw/help_me_with_my_orgmode_workflow_for_notetaking/

Read this on email handling: http://pragmaticemacs.com/emacs/master-your-inbox-with-mu4e-and-org-mode/

On capturing URLs and content from web pages (and drilling org-drill items from these), read https://orgmode.org/worg/org-contrib/org-drill.html.

Templates with shortcuts u and w taken from org-drill manual.

The ‘Respond later’ template is a customised TODO which includes some extra email information. This relies on the extended email properties made available in the Org-mode -> Custom Links -> mu4e section of this config.

First, template for contacts from: https://www.reddit.com/r/emacs/comments/8toivy/tip_how_to_manage_your_contacts_with_orgcontacts/

Add field :BIRTHDAY: %^{yyyy-mm-dd only add when i want to. Otherwise, if date not valid (YYYY-MM-DD), agenda fails

(defvar my/org-contacts-template "* %(org-contacts-template-name)
:PROPERTIES:
:ADDRESS: %^{Calle, Ciudad, CP, País}
:EMAIL: %(org-contacts-template-email)
:TEL: %^{Tel}
:CELL: %^{Mobile}
:NOTE: %^{NOTE}
:END:" "Template for org-contacts.")
(setq org-capture-templates `(
                              ("a"  "Article"  entry
                               (file+headline "/home/dgm/Dropbox/gtd/bibliography.org" "Bibliography")
                               "* %a %^g
                                    \n:PROPERTIES:
                                    \n:Created: %U
                                    \n:END:
                                    \n%i
                                    \nBrief description:
                                    \n%?"
                               :immediate-finish t
                               :prepend t
                               :empty-lines 0
                               :created t)
                              ("c" "Contact" entry (file+headline "/home/dgm/Dropbox/gtd/contacts.org" "Contacts"),
                               my/org-contacts-template
                               :empty-lines 1)
                              ("f" "Financial entries (Ledger)")
                              ("fc" "Checking" plain
                               (file "~/documents/personal/finanzas/ledger/journal.dat")
                               "%(org-read-date) %^{Payee}
                               Expenses:%^{Account}  $%^{Amount}"
                               :immediate-finish t)
                              ("fv" "Visa (Credit card)" plain
                               (file "~/documents/personal/finanzas/ledger/journal.dat")
                               "%(org-read-date) %^{Payee}
                                Expenses:%^{Account}  $%^{Amount}
                                Liabilities:Visa"
                               :immediate-finish t)
                              ("fm" "Metalico" plain
                               (file "~/documents/personal/finanzas/ledger/journal.dat")
                               "%(org-read-date) * %^{Payee}
                                Expenses:Cash
                                Expenses:%^{Account}  %^{Amount}")
                              ("j" "Journal" entry
                               (file+datetree "/home/dgm/Dropbox/gtd/journal.org")
                               "* %? \n Added on: %U")
                              ("l" "Life-related Idea" entry
                               (file+headline "~/Dropbox/gtd/notes.org" "Life-related Ideas")
                               "* %?\nCaptured on %U from %a\n"
                                :prepend t)
                              ("n" "Note" entry
                               (file+headline "~/Dropbox/gtd/notes.org" "Notes")
                               "* %?\nCaptured on %U from %a\n"
                                :prepend t)
                              ("p" "Project-related Idea" entry
                               (file+headline "~/Dropbox/gtd/notes.org" "Project-related Ideas")
                               "* %?\nCaptured on %U from %a\n"
                                :prepend t)
                              ("r" "Respond later" entry
                               (file+headline "~/Dropbox/gtd/inbox.org" "Email")
                               "* TODO Respond to %a, email by %:from \nEntry added on: %U \n"
                               :empty-lines 0
                               :immediate-finish t
                               :prepend t)
                              ("t" "Todo [inbox]" entry
                               (file+headline "/home/dgm/Dropbox/gtd/inbox.org" "Tasks")
                               "* TODO %i%? \nEntry added on: %U from %a\n"
                                :prepend t)
                              ("T" "Tickler" entry
                               (file+headline "/home/dgm/Dropbox/gtd/tickler.org" "Tickler")
                               "* %i%? \nEntry added on: %U from %a\n"
                                :prepend t)
                              ("u" "URLs to remember" entry
                               (file+headline  "/home/dgm/Dropbox/gtd/URLs.org" "URLs")
                               ,(concat "* TODO Read this URL: '%:description'\nURL: %l\nDate:%U\n\n")
                               :empty-lines 0
                               :immediate-finish t
                               :prepend t)
                              ("w" "Capture web snippet" entry
                               (file+headline "~/Dropbox/gtd/notes.org" "Webs")
                               ,(concat "* Web: '%:description'\n\nURL: %l\nTime:%U\n\nContents:\n\n %i\n")
                               :empty-lines 1
                               :immediate-finish t
                               :prepend t)
                              ;;("w"
                              ;;"Capture web snippet"
                              ;;entry
                              ;;(file+headline "~/Dropbox/gtd/notes.org" "Webs")
                              ;; ,(concat "* Web: '%:description'        :"
                              ;;          ":\n:PROPERTIES:\n:DATE_ADDED: %u\n:SOURCE_URL: %c\n:END:\n\n%i\n%?\n")
                              ;; :empty-lines 1
                              ;; :immediate-finish t)
                              ))

Original template:

(setq org-capture-templates '(
                              ("t" "Todo [inbox]" entry
                               (file+headline "/home/dgm/Dropbox/gtd/inbox.org" "Tasks")
                                 "* TODO %i%? \nEntry added on: %U from %a\n")
                                ("T" "Tickler" entry
                                 (file+headline "/home/dgm/Dropbox/gtd/tickler.org" "Tickler")
                                 "* %i%?
                                      \nEntry added on: %U from %a\n")
                                ("j" "Journal" entry
                                 (file+datetree "/home/dgm/Dropbox/gtd/journal.org")
                                 "* %?
                                      \n Added on: %U")
                                ("n" "Note" entry
                                 (file "~/Dropbox/gtd/notes.org")
                                  "* %?\nCaptured on %U from %a\n")
                                ("a"  "Article"  entry  
                                 (file+headline "/home/dgm/Dropbox/gtd/bibliography.org" "Bibliography") 
                                  "* %a %^g
                                  \n:PROPERTIES: 
                                  \n:Created: %U
                                  \n:END:
                                  \n%i
                                  \nBrief description:
                                  \n%?"  
                                :immediate-finish t 
                                :prepend t  
                                :empty-lines 1  
                                :created t)))

Bits deteled after the Todo “t” capture template:

;;               \nEntry created from this heading or email: %a")

From caolan: https://caolan.org/dotfiles/emacs.html#orgd96aeb0 I’ve disabled it because it was too cumbersome and i’ve realized that it doesn’t not add the origin file from which I capture in the case of emails!

;; (push `("t" "Todo" entry (file+headline "/home/dgm/Dropbox/gtd/inbox.org" "Tasks")
;;        ,(string-join
;;          '("* TODO %^{Description}"
;;            "  %?"
;;            "  %a"
;;            "  :LOGBOOK:"
;;            "  - Captured on %U from %a"
;;            "  :END:")
;;          "\n"))
;;      org-capture-templates)

As Caolan (https://caolan.org/dotfiles/emacs.html#orgd96aeb0) says, during expansion of the template, %a has been replaced by a link to the location from where you called the capture command. This can be extremely useful for deriving tasks from emails, for example. This tip from the Org-mode manual. The %U will be replaced with the time of the capture, this is an ‘inactive’ timestamp meaning it won’t show up in the agenda view.

Tip from https://lists.gnu.org/archive/html/emacs-orgmode/2007-08/msg00253.html for having agenda show 30 days: (setq org-agenda-span (quote month))

Make some e-mails stand out a bit.

(set-face-foreground 'mu4e-unread-face "#8b8b00")
(set-face-attribute 'mu4e-flagged-face nil :inherit 'font-lock-warning-face)

Viewing images

Viewing images is not trivial. See https://groups.google.com/forum/#!topic/mu-discuss/0QIgZ27x3Is and https://caolan.org/dotfiles/emacs.html#orgd96aeb0.

Finally, I adopted the solution by Caolan, who thinks the included mu4e-shr2text command, which uses the shr package (also used by eww) to render HTML too slow and have switched to using w3m with the display_link_number option.

On 4 august I comment out the line (setq mu4e-html2text-command "w3m -dump -s -T text/html -o display_link_number=true") because I think this is cared for in the init.el

(setq mu4e-view-show-images t
      mu4e-show-images t
      mu4e-view-image-max-width 800)

(when (fboundp 'imagemagick-register-types)
    (imagemagick-register-types))

;; (setq mu4e-view-prefer-html t)  ;; trying this off as https://www.djcbsoftware.nl/code/mu/mu4e/Displaying-rich_002dtext-messages.html recommends

;; (setq mu4e-html2text-command "w3m -dump -s -T text/html -o display_link_number=true")

As I said, now I have the following as suggested by ~/documents/elibrary/computing/Linux/linuxFormat/tips/emacs2-email-video-246February2019.pdf

And it is fine; it’s either that or mu4e-shr2text but with the latter I get just the same as I get in EWW if I follow the action of viewing the message in my browser. Then I can open Chromium with & and see it as intended. With pandoc I get a wonderfully formatted plain-text message.

;;(setq mu4e-html2text-command 'mu4e-shr2text)
(setq mu4e-html2text-command "iconv -c -t utf-8 | pandoc -f html -t plain")

;; If I use shr, it is convinient to make =shr/eww= readable with dark themes, i.e., if you're using a dark theme, and the messages are hard to read, it can help to change the luminosity, e.g.:
(setq shr-color-visible-luminance-min 80)

Alternative from https://etienne.depar.is/emacs.d/mu4e.html that works worse:

(setq mu4e-html2text-command "w3m -dump -T text/html -cols 72 -o display_link_number=true -o auto_image=false -o display_image=false -o ignore_null_img_alt=true")

Call EWW to display HTML messages by pressing aV to view in browser

  • NB: the point is to open the message, and then press a and then V

I still can’t see HTML messages okay. Trying this tip from https://irreal.org/blog/?p=6122

(defun jcs-view-in-eww (msg)
    (eww-browse-url (concat "file://" (mu4e~write-body-to-html msg))))

;; Arrange to view messages in either the default browser or EWW
(add-to-list 'mu4e-view-actions '("ViewInBrowser" . mu4e-action-view-in-browser) t)
(add-to-list 'mu4e-view-actions '("Eww view" . jcs-view-in-eww) t)

Miscellanea

Preview mail file in a new buffer

This function may be called externally to display an email content when we know its file path. From: https://etienne.depar.is/emacs.d/mu4e.html

(defun ed/preview-some-mail-at (path)
  (interactive "fPath: ")
  (call-process
   "mu" nil
   (switch-to-buffer (generate-new-buffer "*mail preview*") t)
   t "view" (expand-file-name path))
  (with-current-buffer "*mail preview*"
    (goto-char (point-min))
    (mu4e~fontify-cited)
    (mu4e~fontify-signature)
    (while (re-search-forward "^\\(\\w+:\\) \\(.*\\)$" nil t)
      (let ((key (match-string 1))
            (value (match-string 2)))
        (beginning-of-line)
        (delete-region (point) (line-end-position))
        (insert (concat (propertize key 'face 'mu4e-header-key-face) " "))
        (if (or (string= key "From:")
                (string= key "To:"))
            (insert (propertize value 'face 'mu4e-special-header-value-face))
          (insert (propertize value 'face 'mu4e-header-value-face)))))
    (forward-line)
    (beginning-of-line)
    (insert "\n")
    (read-only-mode)
    (local-set-key (kbd "q") #'kill-this-buffer)))

Get the first name of the person you are replying to

Finally, I got it working from here: http://pragmaticemacs.com/emacs/customise-the-reply-quote-string-in-mu4e/

;; function to return first name of email recipients
;; used by yasnippet
;; inspired by
;;http://blog.binchen.org/posts/how-to-use-yasnippets-to-produce-email-templates-in-emacs.html
(defun bjm/mu4e-get-names-for-yasnippet ()
  "Return comma separated string of names for an email"
  (interactive)
  (let ((email-name "") str email-string email-list email-name2 tmpname)
    (save-excursion
      (goto-char (point-min))
      ;; first line in email could be some hidden line containing NO to field
      (setq str (buffer-substring-no-properties (point-min) (point-max))))
    ;; take name from TO field - match series of names
    (when (string-match "^To: \"?\\(.+\\)" str)
      (setq email-string (match-string 1 str)))
    ;;split to list by comma
    (setq email-list (split-string email-string " *, *"))
    ;;loop over emails
    (dolist (tmpstr email-list)
      ;;get first word of email string
      (setq tmpname (car (split-string tmpstr " ")))
      ;;remove whitespace or ""
      (setq tmpname (replace-regexp-in-string "[ \"]" "" tmpname))
      ;;join to string
      (setq email-name
            (concat email-name ", " tmpname)))
    ;;remove initial comma
    (setq email-name (replace-regexp-in-string "^, " "" email-name))

    ;;see if we want to use the name in the FROM field
    ;;get name in FROM field if available, but only if there is only
    ;;one name in TO field
    (if (< (length email-list) 2)
        (when (string-match "^On.+, \\([^ ,\n]+\\).+wrote:$" str)
          (progn
            (setq email-name2 (match-string 1 str))
            ;;prefer name in FROM field if TO field has "@"
            (when (string-match "@" email-name)
              (setq email-name email-name2))
            )))
    email-name))

And not off to customise the reply quote string in mu4e:

;; customize the reply-quote-string
(setq message-citation-line-format "On %a %d %b %Y at %R, %f wrote:\n")
;; choose to use the formatted string
(setq message-citation-line-function 'message-insert-formatted-citation-line)

helm-mu

Read https://martinralbrecht.wordpress.com/2016/05/30/handling-email-with-emacs/#more-1336

(use-package helm-mu
  :defer t
  :config (progn
            (bind-key "S" #'helm-mu mu4e-main-mode-map)))

;;(when (reéquire 'helm-mu nil t)
;;  (dolist (map (list mu4e-headers-mode-map mu4e-main-mode-map mu4e-view-mode-map))
;;    (define-key map "m" 'helm-mu)))

View e-mails with width restriction, but wider for HTML

(defun malb/mu4e-view-mode-hook ()
  "View e-mails with width restriction, but wider for HTML."
  (if (boundp 'msg)
      (let* ((txt (mu4e-message-field msg :body-txt))
             (html (mu4e-message-field msg :body-html)))
        (cond
         ((and (> (* mu4e-view-html-plaintext-ratio-heuristic
                     (length txt)) (length html))
               (or (not mu4e-view-prefer-html) (not html)))
          (set-fill-column 72))
         (t
          (set-fill-column 120))))
    (set-fill-column 72))
  (visual-line-mode 1))
  ;; (visual-fill-column-mode 1)) dgm 22 dic 2020

(add-hook 'mu4e-view-mode-hook #'malb/mu4e-view-mode-hook)

Fixing header update

    

Provide

(provide 'starter-kit-mu4e)

Final message

(message "Starter Kit User Mu4e File loaded.")