blob: 5a12e1c480230d372c1a4f58237fb123db47e304 (
plain) (
blame)
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
|
;;; git-email.el --- Work with git and email -*- lexical-binding: t; -*-
;; Copyright (C) 2021 yoctocell
;; Author: yoctocell <public@yoctocell.xyz>
;; URL: https://git.sr.ht/~yoctocell/git-email
;; Version: 0.1.0
;; Package-Requires: ((emacs "25.1"))
;; Keywords: git email
;; License: GNU General Public License >= 3
;; This program 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.
;; This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This package integrates with git and email and offers two main functions
;; - `git-email-send-email' and `git-email-apply-patch'.
;;
;; `git-email-send-email' sends an email based on a patch file generated by
;; 'git format-patch'. It inserts the relevant headers and the diff into the
;; message buffer.
;;
;; `git-email-apply-patch' will apply the patch that you are currently viewing
;; and it will ask to for the project that the patch belongs to.
;;; TODO:
;; * Add proper syntax highlighting to diffs in the message buffer.
;;; Code:
(defgroup git-email nil
"Work with git and email."
:group 'convenience)
(defcustom git-email-compose-message-function 'message-mail
"The function used to compose patch mail."
:group 'git-email
:type 'symbol)
(defcustom git-email-headers
'("subject" "from" "in-reply-to" "message-id")
"List of headers that should get inserted into the message buffer.
The 'to' address will always be inserted based on the 'sendemail.to' variable
in you git config. If the variable is not set, the 'to' address will be empty.
To insert the 'references' header, you have to set `message-header-format-alist'
to something like this.
(setq message-header-format-alist
'((From)
(Newsgroups)
(To)
(Cc)
(Subject)
(In-Reply-To)
(Fcc)
(Bcc)
(Date)
(Organization)
(Distribution)
(Lines)
(Expires)
(Message-ID)
(References)
(User-Agent)))
Otherwise `mail-header-format' will try to parse it differently, which we don't
want."
:group 'git-email
:type '(string))
(defun git-email--extract-header (header)
"Extract HEADER from current buffer."
(goto-char (point-min))
(buffer-substring-no-properties
(if (re-search-forward (format " *%s: +" header) nil t)
(point)
(point-at-eol))
(point-at-eol)))
(defun git-email--extract-headers (patch-file)
"Extract headers from PATCH-FILE.
If the header is not found, return an empty string."
(with-temp-buffer
(insert-file-contents patch-file)
(mapcar (lambda (header)
`(,header ,(git-email--extract-header header)))
git-email-headers)))
(defun git-email--extract-diff (patch-file)
"Extract the diff from PATCH-FILE."
(with-temp-buffer
(insert-file-contents patch-file)
(goto-char (point-min))
(buffer-substring-no-properties
(- (re-search-forward "\n\n") 1)
(point-max))))
(defun git-email-send-email (patch-file)
"Given a PATCH-FILE, send an email.
Extracts the relevant headers and the diff from the PATCH-FILE and inserts
them into the message buffer."
(interactive)
(let* ((default-directory (cdr (project-current)))
(headers (git-email--extract-headers patch-file))
(used-headers (seq-filter
(lambda (header)
(not (string-equal (car (cdr header)) "")))
headers))
(sendemail-to
(shell-command-to-string "git config --list | grep sendemail.to"))
(to (if (string-equal sendemail-to "")
"to"
(substring sendemail-to 13 -1))) ; Remove newline
(diff (git-email--extract-diff patch-file)))
(funcall git-email-compose-message-function to (cadr (assoc "subject" used-headers))
used-headers)
;; (let ((body (or (re-search-forward "<#part .*>")
;; (re-search-forward "--text follows this line--"))))
(goto-char (point-max))
(insert diff)))
(provide 'git-email)
;;; git-email.el ends here
|