From dc8a06e6a633a813a8fa582f0c2bd72e9dcf9b76 Mon Sep 17 00:00:00 2001 From: yoctocell Date: Wed, 6 Jan 2021 18:36:36 +0100 Subject: Add comments and restructure * git-email.el: --- git-email.el | 193 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 100 insertions(+), 93 deletions(-) (limited to 'git-email.el') diff --git a/git-email.el b/git-email.el index 11901bc..84e5eaf 100644 --- a/git-email.el +++ b/git-email.el @@ -48,6 +48,7 @@ (require 'project) (require 'message) +;;; Customization options (defgroup git-email nil "Work with git and email." :group 'convenience) @@ -99,14 +100,6 @@ in you git config. If the variable is not set, the 'to' address will be empty." :type '(string) :group 'git-email) -(defcustom git-email-revision-limit 100 - "How many revisions to show when in `git-email-format-patch'." - :type 'int - :group 'git-email) - -(defface git-email-revision-face '((t :inherit font-lock-comment-face)) - "Face used for the revision when selecting from the minibuffer.") - (defcustom git-email-apply-patch-function 'git-email--shell-command-on-body "Function that executes a shell command on the body of the message. @@ -121,43 +114,22 @@ variable." :type 'string :group 'git-email) -;; Compile warnings +(defcustom git-email-revision-limit 100 + "How many revisions to show when in `git-email-format-patch'." + :type 'int + :group 'git-email) + +(defface git-email-revision-face '((t :inherit font-lock-comment-face)) + "Face used for the revision when selecting from the minibuffer.") + +;;; Remove Compiler warnings (declare-function dired-get-filename "dired.el") (declare-function dired-map-over-marks "dired.el") (declare-function ibuffer-get-marked-buffers "ibuffer.el") (declare-function vc-dir-marked-files "vc-dir.el") (declare-function vc-dir-current-file "vc-dir.el") -(defun git-email-send-all () - "Send all unsent emails." - (interactive) - (let ((buffers (message-buffers))) - (mapc (lambda (b) (switch-to-buffer b) - (funcall git-email-send-email-function)) - buffers))) - -(defun git-email--shell-command-on-body (command) - "Get the body of the message in the current buffer and run COMMAND on it." - (shell-command-on-region (point-min) (point-max) command)) - -(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))) - +;;; Get files to send (defun git-email--extract-diff (patch-file) "Extract the diff from PATCH-FILE." (with-temp-buffer @@ -217,6 +189,63 @@ If no marks are found, return the filename at point." (when (mapcar 'git-email--check-file files) files))) +;;; Get contents from patch +(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--remove-subject (header) + "Remove HEADER if it is the subject." + (not (string-equal (symbol-name (car header)) "subject"))) + +(defun git-email--compose-email (patch-file) + "Given a PATCH-FILE, compose an email. +Extracts the relevant headers and the diff from the PATCH-FILE and inserts +them into the message buffer." + (let* ((default-directory (cdr (project-current))) + (headers (git-email--extract-headers patch-file)) + ;; Remove empty headers. + (used-headers (seq-filter + (lambda (header) + (not (string-equal (car (cdr header)) ""))) + headers)) + ;; Get 'to' address from git. + (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-email-function to (cadr (assoc 'subject used-headers)) + ;; Remove 'subject' header, otherwise two subject headers will be + ;; inserted. + (seq-filter 'git-email--remove-subject used-headers)) + (goto-char (point-min)) + ;; Insert diff at the beginning of the body + (let ((body (or (re-search-forward "<#part \\(encrypt\\|sign\\)=.*mime>" nil t) + (re-search-forward "--text follows this line--" nil t)))) + (goto-char (+ body 1)) + (save-excursion + (insert diff))) + ;; Jump to subject if it is a cover letter + (when (re-search-backward "\\*\\*\\* SUBJECT HERE \\*\\*\\*" nil t) + (kill-line)))) + +;;; Format patches (defun git-email--get-revision () "Let the user choose a git revision from the minibuffer." (interactive) @@ -254,25 +283,6 @@ If no marks are found, return the filename at point." action colored-revs string pred))))) (substring (completing-read "Revision: " sorted-revs) 0 7))) -;;;###autoload -(defun git-email-apply-patch (project) - "Apply the patch in the current buffer using 'git am' in PROJECT." - (interactive (list (project-prompt-project-dir))) - (let ((default-directory project)) - (push (list project) project--list) - (funcall git-email-apply-patch-function - git-email-apply-patch-command))) - -;;;###autoload -(defun git-email-send-email () - "Send patch(es) to someone." - (interactive) - (let ((files (git-email--get-files))) - (dolist (file files) - (run-hooks 'git-email-pre-compose-email-hook) - (git-email--compose-email file) - (run-hooks 'git-email-post-compose-email-hook)))) - ;;;###autoload (defun git-email-format-patch (&optional args) "Format and send patch(es) using 'git format-patch'. @@ -300,42 +310,39 @@ arguments in `git-email-format-patch-default-args' will be used." (git-email--compose-email file) (run-hooks 'git-email-post-compose-email-hook)))) -(defun git-email--remove-subject (header) - "Remove HEADER if it is the subject." - (not (string-equal (symbol-name (car header)) "subject"))) -(defun git-email--compose-email (patch-file) - "Given a PATCH-FILE, compose an email. -Extracts the relevant headers and the diff from the PATCH-FILE and inserts -them into the message buffer." - (let* ((default-directory (cdr (project-current))) - (headers (git-email--extract-headers patch-file)) - ;; Remove empty headers. - (used-headers (seq-filter - (lambda (header) - (not (string-equal (car (cdr header)) ""))) - headers)) - ;; Get 'to' address from git. - (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-email-function to (cadr (assoc 'subject used-headers)) - ;; Remove 'subject' header, otherwise two subject headers will be - ;; inserted. - (seq-filter 'git-email--remove-subject used-headers)) - (goto-char (point-min)) - ;; Insert diff at the beginning of the body - (let ((body (or (re-search-forward "<#part \\(encrypt\\|sign\\)=.*mime>" nil t) - (re-search-forward "--text follows this line--" nil t)))) - (goto-char (+ body 1)) - (save-excursion - (insert diff))) - ;; Jump to subject if it is a cover letter - (when (re-search-backward "\\*\\*\\* SUBJECT HERE \\*\\*\\*" nil t) - (kill-line)))) +;;; Operate on emails +(defun git-email-send-all () + "Send all unsent emails." + (interactive) + (let ((buffers (message-buffers))) + (mapc (lambda (b) (switch-to-buffer b) + (funcall git-email-send-email-function)) + buffers))) + +;;;###autoload +(defun git-email-send-email () + "Send patch(es) to someone." + (interactive) + (let ((files (git-email--get-files))) + (dolist (file files) + (run-hooks 'git-email-pre-compose-email-hook) + (git-email--compose-email file) + (run-hooks 'git-email-post-compose-email-hook)))) + +;;; Apply patches +(defun git-email--shell-command-on-body (command) + "Get the body of the message in the current buffer and run COMMAND on it." + (shell-command-on-region (point-min) (point-max) command)) + +;;;###autoload +(defun git-email-apply-patch (project) + "Apply the patch in the current buffer using 'git am' in PROJECT." + (interactive (list (project-prompt-project-dir))) + (let ((default-directory project)) + (push (list project) project--list) + (funcall git-email-apply-patch-function + git-email-apply-patch-command))) (provide 'git-email) -- cgit v1.2.3