aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey C Honig2012-11-24 21:21:02 -0500
committerJeffrey C Honig2012-11-24 21:21:02 -0500
commit855c6482c077b22383f8ad4b29db2d091e7e83f4 (patch)
treeca83f6e6432acdc3e94fe6d73ccfd968fc77752f
parent624d4a5cfbc96febb046c9acd7019ffbe2a977ab (diff)
downloademacs-855c6482c077b22383f8ad4b29db2d091e7e83f4.tar.gz
emacs-855c6482c077b22383f8ad4b29db2d091e7e83f4.zip
(mh-edit-again): Use the components file to specify
default values for missing headers in the draft. (mh-regexp-in-field-syntax-table, mh-fcc-syntax-table) (mh-addr-syntax-table, mh-regexp-in-field-p): Use a syntax table so we'll properly parse non-address fields. (mh-components-to-list, mh-extract-header-field): New functions to read components file. (mh-find-components, mh-send-sub): Move code to locate components file into a new function. (mh-insert-auto-fields, mh-modify-header-field): New syntax for calling mh-regexp-in-field-p. (closes SF #1708292)
-rw-r--r--lisp/mh-e/ChangeLog15
-rw-r--r--lisp/mh-e/mh-comp.el174
2 files changed, 162 insertions, 27 deletions
diff --git a/lisp/mh-e/ChangeLog b/lisp/mh-e/ChangeLog
index 6b2086eff3b..8bb1659a1c0 100644
--- a/lisp/mh-e/ChangeLog
+++ b/lisp/mh-e/ChangeLog
@@ -1,3 +1,18 @@
12012-11-25 Jeffrey C Honig <jch@honig.net>
2
3 * mh-comp.el: (mh-edit-again): Use the components file to specify
4 default values for missing headers in the draft.
5 (mh-regexp-in-field-syntax-table, mh-fcc-syntax-table)
6 (mh-addr-syntax-table, mh-regexp-in-field-p): Use a syntax table
7 so we'll properly parse non-address fields.
8 (mh-components-to-list, mh-extract-header-field): New functions to
9 read components file.
10 (mh-find-components, mh-send-sub): Move code to locate components
11 file into a new function.
12 (mh-insert-auto-fields, mh-modify-header-field): New syntax for
13 calling mh-regexp-in-field-p.
14 (closes SF #1708292)
15
12012-01-07 Jeffrey C Honig <jch@honig.net> 162012-01-07 Jeffrey C Honig <jch@honig.net>
2 17
3 * mh-e.el (mh-invisible-header-fields-internal): Added: X-xsi. 18 * mh-e.el (mh-invisible-header-fields-internal): Added: X-xsi.
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
index eceb7a5fe3a..f7a610e6c58 100644
--- a/lisp/mh-e/mh-comp.el
+++ b/lisp/mh-e/mh-comp.el
@@ -121,6 +121,42 @@ Used by the \\[mh-edit-again] and \\[mh-extract-rejected-mail] commands.")
121 syntax-table) 121 syntax-table)
122 "Syntax table used by MH-E while in MH-Letter mode.") 122 "Syntax table used by MH-E while in MH-Letter mode.")
123 123
124(defvar mh-regexp-in-field-syntax-table nil
125 "Specify a syntax table for mh-regexp-in-field-p to use instead of determining")
126
127(defvar mh-fcc-syntax-table
128 (let ((syntax-table (make-syntax-table text-mode-syntax-table)))
129 (modify-syntax-entry ?+ "w" syntax-table)
130 (modify-syntax-entry ?/ "w" syntax-table)
131 syntax-table)
132 "Syntax table used by MH-E while searching an Fcc field.")
133
134(defvar mh-addr-syntax-table
135 (let ((syntax-table (make-syntax-table text-mode-syntax-table)))
136 (modify-syntax-entry ?! "w" syntax-table)
137 (modify-syntax-entry ?# "w" syntax-table)
138 (modify-syntax-entry ?$ "w" syntax-table)
139 (modify-syntax-entry ?% "w" syntax-table)
140 (modify-syntax-entry ?& "w" syntax-table)
141 (modify-syntax-entry ?' "w" syntax-table)
142 (modify-syntax-entry ?* "w" syntax-table)
143 (modify-syntax-entry ?+ "w" syntax-table)
144 (modify-syntax-entry ?- "w" syntax-table)
145 (modify-syntax-entry ?/ "w" syntax-table)
146 (modify-syntax-entry ?= "w" syntax-table)
147 (modify-syntax-entry ?? "w" syntax-table)
148 (modify-syntax-entry ?^ "w" syntax-table)
149 (modify-syntax-entry ?_ "w" syntax-table)
150 (modify-syntax-entry ?` "w" syntax-table)
151 (modify-syntax-entry ?{ "w" syntax-table)
152 (modify-syntax-entry ?| "w" syntax-table)
153 (modify-syntax-entry ?} "w" syntax-table)
154 (modify-syntax-entry ?~ "w" syntax-table)
155 (modify-syntax-entry ?. "w" syntax-table)
156 (modify-syntax-entry ?@ "w" syntax-table)
157 syntax-table)
158 "Syntax table used by MH-E while searching an address field.")
159
124(defvar mh-send-args "" 160(defvar mh-send-args ""
125 "Extra args to pass to \"send\" command.") 161 "Extra args to pass to \"send\" command.")
126 162
@@ -391,6 +427,42 @@ See also `mh-send'."
391 (mh-read-draft "clean-up" (mh-msg-filename message) nil))))) 427 (mh-read-draft "clean-up" (mh-msg-filename message) nil)))))
392 (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil) 428 (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil)
393 (mh-insert-header-separator) 429 (mh-insert-header-separator)
430 ;; Merge in components
431 (mh-mapc (function (lambda (header-field)
432 (let ((field (car header-field))
433 (value (cdr header-field))
434 (case-fold-search t))
435 (cond
436 ;; Address field
437 ((string-match field "^To$\\|^Cc$\\|^From$")
438 (cond
439 ((not (mh-goto-header-field (concat field ":")))
440 ;; Header field does not exist, add it
441 (mh-goto-header-end 0)
442 (insert field ": " value "\n"))
443 ((string-equal value "")
444 ;; Header field already exists and no value
445 )
446 (t
447 ;; Header field exists and we have a value
448 (let (address mailbox (alias (mh-alias-expand value)))
449 (and alias
450 (setq address (ietf-drums-parse-address alias))
451 (setq mailbox (car address)))
452 ;; XXX - Need to parse all addresses out of field
453 (if (and
454 (not (mh-regexp-in-field-p (concat "\\b" (regexp-quote value) "\\b") field))
455 mailbox
456 (not (mh-regexp-in-field-p (concat "\\b" (regexp-quote mailbox) "\\b") field)))
457 (insert " " value ","))
458 ))))
459 ((string-match field "^Fcc$")
460 ;; Folder reference
461 (mh-modify-header-field field value))
462 ;; Text field, that's an easy case
463 (t
464 (mh-modify-header-field field value))))))
465 (mh-components-to-list (mh-find-components)))
394 (goto-char (point-min)) 466 (goto-char (point-min))
395 (save-buffer) 467 (save-buffer)
396 (mh-compose-and-send-mail draft "" from-folder nil nil nil nil nil nil 468 (mh-compose-and-send-mail draft "" from-folder nil nil nil nil nil nil
@@ -398,6 +470,34 @@ See also `mh-send'."
398 (mh-letter-mode-message) 470 (mh-letter-mode-message)
399 (mh-letter-adjust-point))) 471 (mh-letter-adjust-point)))
400 472
473(defun mh-extract-header-field ()
474 "Extract field name and field value from the field at point.
475Returns a list of field name and value (which may be null)."
476 (let ((end (save-excursion (mh-header-field-end)
477 (point))))
478 (if (looking-at mh-letter-header-field-regexp)
479 (save-excursion
480 (goto-char (match-end 1))
481 (forward-char 1)
482 (skip-chars-forward " \t")
483 (cons (match-string-no-properties 1) (buffer-substring-no-properties (point) end))))))
484
485
486(defun mh-components-to-list (components)
487 "Read in the components file and convert to a list of field names and values."
488 (with-current-buffer (get-buffer-create mh-temp-buffer)
489 (erase-buffer)
490 (insert-file-contents components)
491 (goto-char (point-min))
492 (let
493 ((header-fields nil))
494 (while (mh-in-header-p)
495 (setq header-fields (append header-fields (list (mh-extract-header-field))))
496 (mh-header-field-end)
497 (forward-char 1)
498 )
499 header-fields)))
500
401;;;###mh-autoload 501;;;###mh-autoload
402(defun mh-extract-rejected-mail (message) 502(defun mh-extract-rejected-mail (message)
403 "Edit a MESSAGE that was returned by the mail system. 503 "Edit a MESSAGE that was returned by the mail system.
@@ -773,6 +873,22 @@ Optional argument BUFFER can be used to specify the buffer."
773 (t 873 (t
774 nil)))) 874 nil))))
775 875
876(defun mh-find-components ()
877 "Return the path to the components file."
878 (let (components)
879 (cond
880 ((file-exists-p
881 (setq components
882 (expand-file-name mh-comp-formfile mh-user-path)))
883 components)
884 ((file-exists-p
885 (setq components
886 (expand-file-name mh-comp-formfile mh-lib)))
887 components)
888 (t
889 (error "Can't find %s in %s or %s"
890 mh-comp-formfile mh-user-path mh-lib)))))
891
776(defun mh-send-sub (to cc subject config) 892(defun mh-send-sub (to cc subject config)
777 "Do the real work of composing and sending a letter. 893 "Do the real work of composing and sending a letter.
778Expects the TO, CC, and SUBJECT fields as arguments. 894Expects the TO, CC, and SUBJECT fields as arguments.
@@ -782,19 +898,7 @@ CONFIG is the window configuration before sending mail."
782 (message "Composing a message...") 898 (message "Composing a message...")
783 (let ((draft (mh-read-draft 899 (let ((draft (mh-read-draft
784 "message" 900 "message"
785 (let (components) 901 (mh-find-components)
786 (cond
787 ((file-exists-p
788 (setq components
789 (expand-file-name mh-comp-formfile mh-user-path)))
790 components)
791 ((file-exists-p
792 (setq components
793 (expand-file-name mh-comp-formfile mh-lib)))
794 components)
795 (t
796 (error "Can't find %s in %s or %s"
797 mh-comp-formfile mh-user-path mh-lib))))
798 nil))) 902 nil)))
799 (mh-insert-fields "To:" to "Subject:" subject "Cc:" cc) 903 (mh-insert-fields "To:" to "Subject:" subject "Cc:" cc)
800 (goto-char (point-max)) 904 (goto-char (point-max))
@@ -1036,7 +1140,7 @@ added; otherwise return nil."
1036 (while list 1140 (while list
1037 (let ((regexp (nth 0 (car list))) 1141 (let ((regexp (nth 0 (car list)))
1038 (entries (nth 1 (car list)))) 1142 (entries (nth 1 (car list))))
1039 (when (mh-regexp-in-field-p regexp "To:" "cc:") 1143 (when (mh-regexp-in-field-p regexp mh-addr-syntax-table "To:" "cc:")
1040 (setq mh-insert-auto-fields-done-local t) 1144 (setq mh-insert-auto-fields-done-local t)
1041 (setq fields-inserted t) 1145 (setq fields-inserted t)
1042 (if (not non-interactive) 1146 (if (not non-interactive)
@@ -1071,7 +1175,7 @@ discarded."
1071 (insert " " value) 1175 (insert " " value)
1072 (delete-region (point) (mh-line-end-position))) 1176 (delete-region (point) (mh-line-end-position)))
1073 ((and (not overwrite-flag) 1177 ((and (not overwrite-flag)
1074 (mh-regexp-in-field-p (concat "\\b" value "\\b") field)) 1178 (mh-regexp-in-field-p (concat "\\b" (regexp-quote value) "\\b") field))
1075 ;; Already there, do nothing. 1179 ;; Already there, do nothing.
1076 ) 1180 )
1077 ((and (not overwrite-flag) 1181 ((and (not overwrite-flag)
@@ -1083,18 +1187,34 @@ discarded."
1083 1187
1084(defun mh-regexp-in-field-p (regexp &rest fields) 1188(defun mh-regexp-in-field-p (regexp &rest fields)
1085 "Non-nil means REGEXP was found in FIELDS." 1189 "Non-nil means REGEXP was found in FIELDS."
1086 (save-excursion 1190 (let ((old-syntax-table (syntax-table)))
1087 (let ((search-result nil) 1191 (unwind-protect
1088 (field)) 1192 (save-excursion
1089 (while fields 1193 (let ((search-result nil)
1090 (setq field (car fields)) 1194 (field))
1091 (if (and (mh-goto-header-field field) 1195 (while fields
1092 (re-search-forward 1196 (let ((field (car fields))
1093 regexp (save-excursion (mh-header-field-end)(point)) t)) 1197 (syntax-table mh-regexp-in-field-syntax-table))
1094 (setq fields nil 1198 (if (null syntax-table)
1095 search-result t) 1199 (let ((case-fold-search t))
1096 (setq fields (cdr fields)))) 1200 (cond
1097 search-result))) 1201 ((string-match field "^To$\\|^[BD]?cc$\\|^From$")
1202 (setq syntax-table mh-addr-syntax-table))
1203 ((string-match field "^Fcc$")
1204 (setq syntax-table mh-fcc-syntax-table))
1205 (t
1206 (setq syntax-table (syntax-table)))
1207 )))
1208 (if (and (mh-goto-header-field field)
1209 (set-syntax-table syntax-table)
1210 (re-search-forward
1211 regexp (save-excursion (mh-header-field-end)(point)) t))
1212 (setq fields nil
1213 search-result t)
1214 (setq fields (cdr fields)))
1215 (set-syntax-table old-syntax-table)))
1216 search-result))
1217 (set-syntax-table old-syntax-table))))
1098 1218
1099(defun mh-ascii-buffer-p () 1219(defun mh-ascii-buffer-p ()
1100 "Check if current buffer is entirely composed of ASCII. 1220 "Check if current buffer is entirely composed of ASCII.