/
mu4e-org.el
147 lines (122 loc) · 5.28 KB
/
mu4e-org.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
;;; mu4e-org -- Org-links to mu4e messages/queries -*- lexical-binding: t -*-
;; Copyright (C) 2012-2022 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Keywords: outlines, hypermedia, calendar, mail
;; This file is not part of GNU Emacs.
;; mu4e 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 1the License, or
;; (at your option) any later version.
;; mu4e 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 mu4e. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; The expect version here is org 9.x.
;;; Code:
(require 'org)
(require 'mu4e-view)
(require 'mu4e-contacts)
(defgroup mu4e-org nil
"Settings for the Org mode related functionality in mu4e."
:group 'mu4e
:group 'org)
(defcustom mu4e-org-link-desc-func
(lambda (msg) (or (plist-get msg :subject) "No subject"))
"Function that takes a msg and returns a description.
This can be used in org capture templates and storing links.
Example usage:
(defun my-link-descr (msg)
(let ((subject (or (plist-get msg :subject)
\"No subject\"))
(date (or (format-time-string mu4e-headers-date-format
(mu4e-msg-field msg :date))
\"No date\")))
(concat subject \" \" date)))
(setq org-mu4e-link-desc-func 'my-link-descr)"
:type '(function)
:group 'mu4e-org)
(defvar mu4e-org-link-query-in-headers-mode nil
"Prefer linking to the query rather than to the message.
If non-nil, `org-store-link' in `mu4e-headers-mode' links to the
the current query; otherwise, it links to the message at point.")
(defun mu4e--org-store-link-query ()
"Store a link to a mu4e query."
(setq org-store-link-plist nil) ; reset
(org-store-link-props
:type "mu4e"
:query (mu4e-last-query)
:date (format-time-string "%FT%T") ;; avoid error
:link (concat "mu4e:query:" (mu4e-last-query))
:description (format "[%s]" (mu4e-last-query))))
(defun mu4e--org-store-link-message ()
"Store a link to a mu4e message."
(setq org-store-link-plist nil)
(let* ((msg (mu4e-message-at-point))
(from (car-safe (plist-get msg :from)))
(to (car-safe (plist-get msg :to)))
(date (format-time-string "%FT%T" (plist-get msg :date)))
(msgid (or (plist-get msg :message-id)
(mu4e-error "Cannot link message without message-id")))
(props `(:type "mu4e"
:date ,date
:from ,(mu4e-contact-full from)
:fromname ,(mu4e-contact-name from)
:fromnameoraddress ,(or (mu4e-contact-name from)
(mu4e-contact-email from)) ;; mu4e-specific
:maildir ,(plist-get msg :maildir)
:message-id ,msgid
:path ,(plist-get msg :path)
:subject ,(plist-get msg :subject)
:to ,(mu4e-contact-full to)
:tonameoraddress ,(or (mu4e-contact-name to)
(mu4e-contact-email to)) ;; mu4e-specific
:link ,(concat "mu4e:msgid:" msgid)
:description ,(funcall mu4e-org-link-desc-func msg))))
(message "PROPS %S" props)
(apply #'org-store-link-props props)))
(defun mu4e-org-store-link ()
"Store a link to a mu4e message or query.
It links to the last known query when in `mu4e-headers-mode' with
`mu4e-org-link-query-in-headers-mode' set; otherwise it links to
a specific message, based on its message-id, so that links stay
valid even after moving the message around."
(let ((view-mode-p (mu4e-is-mode-or-derived-p 'mu4e-view-mode))
(headers-mode-p (mu4e-is-mode-or-derived-p 'mu4e-headers-mode))
(message-p (mu4e-message-at-point)))
(if view-mode-p
(mu4e--org-store-link-message)
(if headers-mode-p
(if (or (not message-p) mu4e-org-link-query-in-headers-mode)
(mu4e--org-store-link-query)
(mu4e--org-store-link-message))))))
(defun mu4e-org-open (link)
"Open the org LINK.
Open the mu4e message (for links starting with 'msgid:') or run
the query (for links starting with 'query:')."
(require 'mu4e)
(cond
((string-match "^msgid:\\(.+\\)" link)
(mu4e-view-message-with-message-id (match-string 1 link)))
((string-match "^query:\\(.+\\)" link)
(mu4e-search (match-string 1 link) current-prefix-arg))
(t (mu4e-error "Unrecognized link type '%s'" link))))
(make-obsolete 'org-mu4e-open 'mu4e-org-open "1.3.6")
(defun mu4e-org-store-and-capture ()
"Store a link to the current message or query.
\(depending on `mu4e-org-link-query-in-headers-mode', and capture
it with org)."
(interactive)
(call-interactively 'org-store-link)
(org-capture))
(make-obsolete 'org-mu4e-store-and-capture
'mu4e-org-store-and-capture "1.3.6")
;; install mu4e-link support.
(org-link-set-parameters "mu4e"
:follow #'mu4e-org-open
:store #'mu4e-org-store-link)
(provide 'mu4e-org)
;;; mu4e-org.el ends here