diff options
| author | Mike Kupfer | 2018-08-04 18:06:37 -0700 |
|---|---|---|
| committer | Mike Kupfer | 2018-08-04 18:06:37 -0700 |
| commit | e1646e1e2864d6eaf567f4fe77cc11d3e17dde51 (patch) | |
| tree | 355b76ad040d7a9538649c3d141280e6f8032713 | |
| parent | f7d65a5e972ce8563e7b7861f6f7f3508f275f12 (diff) | |
| download | emacs-e1646e1e2864d6eaf567f4fe77cc11d3e17dde51.tar.gz emacs-e1646e1e2864d6eaf567f4fe77cc11d3e17dde51.zip | |
Fix mh-redistribute to work with nmh 1.5 and identities (SF#268)
Co-authored-by: Jeffrey C Honig <jch@honig.net>
* lisp/mh-e/mh-comp.el (mh-redistribute): Add a non-optional
identity parameter. Use mh-bare-components to generate a draft,
then apply identity-specific settings. Add more details to the
"Resent" annotation line.
(mh-dist-formfile): New.
(mh-bare-components): Add a formfile argument.
(mh-edit-again, mh-send-sub): Track the change to
mh-bare-components.
* lisp/mh-e/mh-identity.el (mh-select-identity)
(mh-identity-field): New.
| -rw-r--r-- | lisp/mh-e/mh-comp.el | 100 | ||||
| -rw-r--r-- | lisp/mh-e/mh-identity.el | 27 |
2 files changed, 103 insertions, 24 deletions
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el index 2b49fae2a6d..5c474b4b90c 100644 --- a/lisp/mh-e/mh-comp.el +++ b/lisp/mh-e/mh-comp.el | |||
| @@ -77,6 +77,14 @@ Default is \"components\". | |||
| 77 | If not an absolute file name, the file is searched for first in the | 77 | If not an absolute file name, the file is searched for first in the |
| 78 | user's MH directory, then in the system MH lib directory.") | 78 | user's MH directory, then in the system MH lib directory.") |
| 79 | 79 | ||
| 80 | (defvar mh-dist-formfile "distcomps" | ||
| 81 | "Name of file to be used as a skeleton for redistributing messages. | ||
| 82 | |||
| 83 | Default is \"distcomps\". | ||
| 84 | |||
| 85 | If not an absolute file name, the file is searched for first in the | ||
| 86 | user's MH directory, then in the system MH lib directory.") | ||
| 87 | |||
| 80 | (defvar mh-repl-formfile "replcomps" | 88 | (defvar mh-repl-formfile "replcomps" |
| 81 | "Name of file to be used as a skeleton for replying to messages. | 89 | "Name of file to be used as a skeleton for replying to messages. |
| 82 | 90 | ||
| @@ -413,7 +421,7 @@ See also `mh-send'." | |||
| 413 | (interactive (list (mh-get-msg-num t))) | 421 | (interactive (list (mh-get-msg-num t))) |
| 414 | (let* ((from-folder mh-current-folder) | 422 | (let* ((from-folder mh-current-folder) |
| 415 | (config (current-window-configuration)) | 423 | (config (current-window-configuration)) |
| 416 | (components-file (mh-bare-components)) | 424 | (components-file (mh-bare-components mh-comp-formfile)) |
| 417 | (draft | 425 | (draft |
| 418 | (cond ((and mh-draft-folder (equal from-folder mh-draft-folder)) | 426 | (cond ((and mh-draft-folder (equal from-folder mh-draft-folder)) |
| 419 | (pop-to-buffer (find-file-noselect (mh-msg-filename message)) | 427 | (pop-to-buffer (find-file-noselect (mh-msg-filename message)) |
| @@ -649,15 +657,16 @@ Original message has headers FROM and SUBJECT." | |||
| 649 | (format mh-forward-subject-format from subject)) | 657 | (format mh-forward-subject-format from subject)) |
| 650 | 658 | ||
| 651 | ;;;###mh-autoload | 659 | ;;;###mh-autoload |
| 652 | (defun mh-redistribute (to cc &optional message) | 660 | (defun mh-redistribute (to cc identity &optional message) |
| 653 | "Redistribute a message. | 661 | "Redistribute a message. |
| 654 | 662 | ||
| 655 | This command is similar in function to forwarding mail, but it | 663 | This command is similar in function to forwarding mail, but it |
| 656 | does not allow you to edit the message, nor does it add your name | 664 | does not allow you to edit the message, nor does it add your name |
| 657 | to the \"From\" header field. It appears to the recipient as if | 665 | to the \"From\" header field. It appears to the recipient as if |
| 658 | the message had come from the original sender. When you run this | 666 | the message had come from the original sender. When you run this |
| 659 | command, you are prompted for the TO and CC recipients. The | 667 | command, you are prompted for the TO and CC recipients. You are |
| 660 | default MESSAGE is the current message. | 668 | also prompted for the sending IDENTITY to use. The default |
| 669 | MESSAGE is the current message. | ||
| 661 | 670 | ||
| 662 | Also investigate the command \\[mh-edit-again] for another way to | 671 | Also investigate the command \\[mh-edit-again] for another way to |
| 663 | redistribute messages. | 672 | redistribute messages. |
| @@ -668,6 +677,9 @@ The hook `mh-annotate-msg-hook' is run after annotating the | |||
| 668 | message and scan line." | 677 | message and scan line." |
| 669 | (interactive (list (mh-read-address "Redist-To: ") | 678 | (interactive (list (mh-read-address "Redist-To: ") |
| 670 | (mh-read-address "Redist-Cc: ") | 679 | (mh-read-address "Redist-Cc: ") |
| 680 | (if mh-identity-list | ||
| 681 | (mh-select-identity mh-identity-default) | ||
| 682 | nil) | ||
| 671 | (mh-get-msg-num t))) | 683 | (mh-get-msg-num t))) |
| 672 | (or message | 684 | (or message |
| 673 | (setq message (mh-get-msg-num t))) | 685 | (setq message (mh-get-msg-num t))) |
| @@ -677,14 +689,51 @@ message and scan line." | |||
| 677 | (if mh-redist-full-contents-flag | 689 | (if mh-redist-full-contents-flag |
| 678 | (mh-msg-filename message) | 690 | (mh-msg-filename message) |
| 679 | nil) | 691 | nil) |
| 680 | nil))) | 692 | nil)) |
| 681 | (mh-goto-header-end 0) | 693 | (from (mh-identity-field identity "From")) |
| 682 | (insert "Resent-To: " to "\n") | 694 | (fcc (mh-identity-field identity "Fcc")) |
| 683 | (if (not (equal cc "")) (insert "Resent-cc: " cc "\n")) | 695 | (bcc (mh-identity-field identity "Bcc")) |
| 684 | (mh-clean-msg-header | 696 | comp-fcc comp-to comp-cc comp-bcc) |
| 685 | (point-min) | 697 | (if mh-redist-full-contents-flag |
| 686 | "^Message-Id:\\|^Received:\\|^Return-Path:\\|^Sender:\\|^Date:\\|^From:" | 698 | (mh-clean-msg-header |
| 687 | nil) | 699 | (point-min) |
| 700 | "^Message-Id:\\|^Received:\\|^Return-Path:\\|^Date:\\|^Resent-.*:" | ||
| 701 | nil)) | ||
| 702 | ;; Read fields from the distcomps file and put them in our | ||
| 703 | ;; draft. For "To", "Cc", "Bcc", and "Fcc", multiple headers are | ||
| 704 | ;; combined into a single header with comma-separated entries. | ||
| 705 | ;; For "From", the first value wins, with the identity's "From" | ||
| 706 | ;; trumping anything in the distcomps file. | ||
| 707 | (let ((components-file (mh-bare-components mh-dist-formfile))) | ||
| 708 | (mh-mapc | ||
| 709 | (function | ||
| 710 | (lambda (header-field) | ||
| 711 | (let ((field (car header-field)) | ||
| 712 | (value (cdr header-field)) | ||
| 713 | (case-fold-search t)) | ||
| 714 | (cond | ||
| 715 | ((string-match field "^Resent-Fcc$") | ||
| 716 | (setq comp-fcc value)) | ||
| 717 | ((string-match field "^Resent-From$") | ||
| 718 | (or from | ||
| 719 | (setq from value))) | ||
| 720 | ((string-match field "^Resent-To$") | ||
| 721 | (setq comp-to value)) | ||
| 722 | ((string-match field "^Resent-Cc$") | ||
| 723 | (setq comp-cc value)) | ||
| 724 | ((string-match field "^Resent-Bcc$") | ||
| 725 | (setq comp-bcc value)) | ||
| 726 | ((string-match field "^Resent-.*$") | ||
| 727 | (mh-insert-fields field value)))))) | ||
| 728 | (mh-components-to-list components-file)) | ||
| 729 | (delete-file components-file)) | ||
| 730 | (mh-insert-fields "Resent-To:" (mapconcat 'identity (list to comp-to) ", ") | ||
| 731 | "Resent-Cc:" (mapconcat 'identity (list cc comp-cc) ", ") | ||
| 732 | "Resent-Fcc:" (mapconcat 'identity (list fcc | ||
| 733 | comp-fcc) ", ") | ||
| 734 | "Resent-Bcc:" (mapconcat 'identity (list bcc | ||
| 735 | comp-bcc) ", ") | ||
| 736 | "Resent-From:" from) | ||
| 688 | (save-buffer) | 737 | (save-buffer) |
| 689 | (message "Redistributing...") | 738 | (message "Redistributing...") |
| 690 | (let ((env "mhdist=1")) | 739 | (let ((env "mhdist=1")) |
| @@ -702,7 +751,8 @@ message and scan line." | |||
| 702 | ;; Annotate... | 751 | ;; Annotate... |
| 703 | (mh-annotate-msg message folder mh-note-dist | 752 | (mh-annotate-msg message folder mh-note-dist |
| 704 | "-component" "Resent:" | 753 | "-component" "Resent:" |
| 705 | "-text" (format "\"%s %s\"" to cc))) | 754 | "-text" (format "\"To: %s Cc: %s From: %s\"" |
| 755 | to cc from))) | ||
| 706 | (kill-buffer draft) | 756 | (kill-buffer draft) |
| 707 | (message "Redistributing...done")))) | 757 | (message "Redistributing...done")))) |
| 708 | 758 | ||
| @@ -898,7 +948,7 @@ CONFIG is the window configuration before sending mail." | |||
| 898 | (message "Composing a message...") | 948 | (message "Composing a message...") |
| 899 | (let ((draft (mh-read-draft | 949 | (let ((draft (mh-read-draft |
| 900 | "message" | 950 | "message" |
| 901 | (mh-bare-components) | 951 | (mh-bare-components mh-comp-formfile) |
| 902 | t))) | 952 | t))) |
| 903 | (mh-insert-fields "To:" to "Subject:" subject "Cc:" cc) | 953 | (mh-insert-fields "To:" to "Subject:" subject "Cc:" cc) |
| 904 | (goto-char (point-max)) | 954 | (goto-char (point-max)) |
| @@ -908,23 +958,25 @@ CONFIG is the window configuration before sending mail." | |||
| 908 | (mh-letter-mode-message) | 958 | (mh-letter-mode-message) |
| 909 | (mh-letter-adjust-point)))) | 959 | (mh-letter-adjust-point)))) |
| 910 | 960 | ||
| 911 | (defun mh-bare-components () | 961 | (defun mh-bare-components (formfile) |
| 912 | "Generate a temporary, clean components file and return its path." | 962 | "Generate a temporary, clean components file from FORMFILE. |
| 913 | ;; Let comp(1) create the skeleton for us. This is particularly | 963 | Return the path to the temporary file." |
| 964 | ;; Let comp(1) create the skeleton for us. This is particularly | ||
| 914 | ;; important with nmh-1.5, because its default "components" needs | 965 | ;; important with nmh-1.5, because its default "components" needs |
| 915 | ;; some processing before it can be used. Unfortunately, comp(1) | 966 | ;; some processing before it can be used. Unfortunately, comp(1) |
| 916 | ;; doesn't have a -build option. So, to avoid the possibility of | 967 | ;; didn't have a -build option until later versions of nmh. So, to |
| 917 | ;; clobbering an existing draft, create a temporary directory and | 968 | ;; avoid the possibility of clobbering an existing draft, create |
| 918 | ;; use it as the drafts folder. Then copy the skeleton to a regular | 969 | ;; a temporary directory and use it as the drafts folder. Then |
| 919 | ;; temp file, and return the regular temp file. | 970 | ;; copy the skeleton to a regular temp file, and return the |
| 971 | ;; regular temp file. | ||
| 920 | (let (new | 972 | (let (new |
| 921 | (temp-folder (make-temp-file | 973 | (temp-folder (make-temp-file |
| 922 | (concat mh-user-path "draftfolder.") t))) | 974 | (concat mh-user-path "draftfolder.") t))) |
| 923 | (mh-exec-cmd "comp" "-nowhatnowproc" | 975 | (mh-exec-cmd "comp" "-nowhatnowproc" |
| 924 | "-draftfolder" (format "+%s" | 976 | "-draftfolder" (format "+%s" |
| 925 | (file-name-nondirectory temp-folder)) | 977 | (file-name-nondirectory temp-folder)) |
| 926 | (if (stringp mh-comp-formfile) | 978 | (if (stringp formfile) |
| 927 | (list "-form" mh-comp-formfile))) | 979 | (list "-form" formfile))) |
| 928 | (setq new (make-temp-file "comp.")) | 980 | (setq new (make-temp-file "comp.")) |
| 929 | (rename-file (concat temp-folder "/" "1") new t) | 981 | (rename-file (concat temp-folder "/" "1") new t) |
| 930 | ;; The temp folder could contain various metadata files. Rather | 982 | ;; The temp folder could contain various metadata files. Rather |
diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el index fd7c2b83fe7..a1eb22ff18e 100644 --- a/lisp/mh-e/mh-identity.el +++ b/lisp/mh-e/mh-identity.el | |||
| @@ -132,6 +132,33 @@ valid header field." | |||
| 132 | 'mh-identity-handler-default)) | 132 | 'mh-identity-handler-default)) |
| 133 | 133 | ||
| 134 | ;;;###mh-autoload | 134 | ;;;###mh-autoload |
| 135 | (defun mh-select-identity (default) | ||
| 136 | "Prompt for and return an identity. | ||
| 137 | If DEFAULT is non-nil, it will be used if the user doesn't enter a | ||
| 138 | different identity. | ||
| 139 | |||
| 140 | See `mh-identity-list'." | ||
| 141 | (let (identity) | ||
| 142 | (setq identity | ||
| 143 | (completing-read | ||
| 144 | "Identity: " | ||
| 145 | (cons '("None") | ||
| 146 | (mapcar 'list (mapcar 'car mh-identity-list))) | ||
| 147 | nil t default nil default)) | ||
| 148 | (if (eq identity "None") | ||
| 149 | nil | ||
| 150 | identity))) | ||
| 151 | |||
| 152 | ;;;###mh-autoload | ||
| 153 | (defun mh-identity-field (identity field) | ||
| 154 | "Return the specified FIELD of the given IDENTITY. | ||
| 155 | |||
| 156 | See `mh-identity-list'." | ||
| 157 | (let* ((pers-list (cadr (assoc identity mh-identity-list))) | ||
| 158 | (value (cdr (assoc field pers-list)))) | ||
| 159 | value)) | ||
| 160 | |||
| 161 | ;;;###mh-autoload | ||
| 135 | (defun mh-insert-identity (identity &optional maybe-insert) | 162 | (defun mh-insert-identity (identity &optional maybe-insert) |
| 136 | "Insert fields specified by given IDENTITY. | 163 | "Insert fields specified by given IDENTITY. |
| 137 | 164 | ||