Commit | Line | Data |
---|---|---|
c3d9274a BW |
1 | ;;; mh-customize.el --- MH-E customization |
2 | ||
924df208 | 3 | ;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. |
c3d9274a BW |
4 | |
5 | ;; Author: Bill Wohler <wohler@newt.com> | |
6 | ;; Maintainer: Bill Wohler <wohler@newt.com> | |
7 | ;; Keywords: mail | |
8 | ;; See: mh-e.el | |
9 | ||
10 | ;; This file is part of GNU Emacs. | |
11 | ||
12 | ;; GNU Emacs is free software; you can redistribute it and/or modify | |
13 | ;; it under the terms of the GNU General Public License as published by | |
14 | ;; the Free Software Foundation; either version 2, or (at your option) | |
15 | ;; any later version. | |
16 | ||
17 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;; GNU General Public License for more details. | |
21 | ||
22 | ;; You should have received a copy of the GNU General Public License | |
23 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
24 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
25 | ;; Boston, MA 02111-1307, USA. | |
26 | ||
27 | ;;; Commentary: | |
28 | ||
924df208 BW |
29 | ;; All of the defgroups, defcustoms, and deffaces in MH-E are found |
30 | ;; here. This makes it possible to customize modules that aren't loaded | |
31 | ;; yet. It also makes it easier to organize the customization groups. | |
c3d9274a BW |
32 | |
33 | ;; This file contains the following sections: | |
34 | ;; | |
35 | ;; 1. MH-E Customization Groups | |
36 | ;; | |
37 | ;; These are the customization group definitions. These are organized in a | |
38 | ;; logical order. High-level, windows and toolbar, folder, message, | |
39 | ;; composing and hooks. | |
40 | ;; | |
41 | ;; 2. MH-E Customization | |
42 | ;; | |
43 | ;; Here are the actual customization variables. There is a sub-section for | |
44 | ;; each group in the MH-E Customization Groups section. Within each | |
45 | ;; section, variables are sorted alphabetically. The manual section | |
46 | ;; dictates which group a variable should be placed. New variables should | |
47 | ;; be placed in the section where they would most likely be defined. | |
48 | ;; | |
49 | ;; All hooks should be placed in the 'mh-hook group; in addition, add the | |
50 | ;; group in which the hook is defined in the manual (or, if it is new, | |
51 | ;; where it would be defined). These two actions insures that the hooks | |
52 | ;; appear last in each group. | |
53 | ;; | |
54 | ;; 3. Faces | |
55 | ||
56 | ;;; Change Log: | |
57 | ||
c3d9274a | 58 | ;;; Code: |
3d7ca223 BW |
59 | (provide 'mh-customize) |
60 | (require 'mh-e) | |
c3d9274a BW |
61 | |
62 | ;;;###mh-autoload | |
3d7ca223 BW |
63 | (defun mh-customize (&optional delete-other-windows-flag) |
64 | "Customize MH-E variables. | |
65 | With optional argument DELETE-OTHER-WINDOWS-FLAG, other windows in the frame | |
66 | are removed." | |
67 | (interactive "P") | |
68 | (customize-group 'mh) | |
69 | (when delete-other-windows-flag | |
70 | (delete-other-windows))) | |
c3d9274a BW |
71 | |
72 | ;;; MH-E Customization Groups | |
73 | ||
74 | (defgroup mh nil | |
75 | "GNU Emacs interface to the MH mail system." | |
76 | :link '(custom-manual "(mh-e)Top") | |
77 | :group 'mail) | |
78 | ||
79 | (defgroup mh-toolbar nil | |
80 | "Toolbar configuration." | |
81 | :prefix "mh-" | |
82 | :group 'mh) | |
83 | ||
84 | (defgroup mh-speed nil | |
85 | "Speedbar and folder configuration." | |
86 | :prefix "mh-" | |
87 | :link '(custom-manual "(mh-e)Customizing Moving Mail") | |
88 | :group 'mh) | |
89 | ||
90 | (defgroup mh-folder nil | |
91 | "Options for controlling scan listing." | |
92 | :prefix "mh-" | |
93 | :link '(custom-manual "(mh-e)Customizing Moving Mail") | |
94 | :group 'mh) | |
95 | ||
924df208 BW |
96 | (defgroup mh-index nil |
97 | "Indexed searching." | |
98 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
99 | :prefix "mh-" | |
100 | :group 'mh) | |
101 | ||
102 | (defgroup mh-junk nil | |
103 | "Spam handling." | |
104 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
105 | :prefix "mh-junk-" | |
106 | :group 'mh) | |
107 | ||
c3d9274a BW |
108 | (defgroup mh-show nil |
109 | "Message display." | |
110 | :prefix "mh-" | |
111 | :link '(custom-manual "(mh-e)Customizing Reading") | |
112 | :group 'mh) | |
113 | ||
924df208 BW |
114 | (defgroup mh-faces nil |
115 | "Faces used in MH-E." | |
116 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
117 | :prefix "mh-" | |
118 | :group 'faces | |
119 | :group 'mh) | |
120 | ||
c3d9274a BW |
121 | (defgroup mh-letter nil |
122 | "Composing messages." | |
123 | :prefix "mh-" | |
124 | :link '(custom-manual "(mh-e)Customizing Sending") | |
125 | :group 'mh) | |
126 | ||
127 | (defgroup mh-alias nil | |
128 | "Alias handling." | |
129 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
130 | :prefix "mh-alias-" | |
131 | :group 'mh) | |
132 | ||
c3d9274a BW |
133 | (defgroup mh-identity nil |
134 | "Multiple personalities." | |
135 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
136 | :prefix "mh-" | |
137 | :group 'mh) | |
138 | ||
c3d9274a BW |
139 | (defgroup mh-hooks nil |
140 | "MH-E hooks." | |
141 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
142 | :prefix "mh-" | |
143 | :group 'mh) | |
144 | ||
145 | ;;; Faces | |
146 | ||
147 | (defgroup mh-speed-faces nil | |
148 | "Faces used in speedbar." | |
149 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
150 | :prefix "mh-" | |
151 | :group 'mh-faces | |
152 | :group 'mh-speed) | |
153 | ||
154 | (defgroup mh-folder-faces nil | |
155 | "Faces used in scan listing." | |
156 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
157 | :prefix "mh-" | |
158 | :group 'mh-faces | |
159 | :group 'mh-folder) | |
160 | ||
161 | (defgroup mh-show-faces nil | |
162 | "Faces used in message display." | |
163 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
164 | :prefix "mh-" | |
165 | :group 'mh-faces | |
166 | :group 'mh-show) | |
167 | ||
168 | (defgroup mh-index-faces nil | |
169 | "Faces used in indexed searches." | |
170 | :link '(custom-manual "(mh-e)Customizing mh-e") | |
171 | :prefix "mh-" | |
172 | :group 'mh-faces | |
173 | :group 'mh-index) | |
174 | ||
175 | \f | |
176 | ||
177 | ;;; MH-E Customization (:group mh) | |
178 | ||
179 | ;;; Toolbar configuration (:group 'mh-toolbar) | |
180 | ||
c3d9274a BW |
181 | (defcustom mh-tool-bar-search-function 'mh-search-folder |
182 | "*Function called by the tool-bar search button. | |
183 | See `mh-search-folder' and `mh-index-search' for details." | |
184 | :type '(choice (const mh-search-folder) | |
185 | (const mh-index-search) | |
186 | (function :tag "Other function")) | |
187 | :group 'mh-toolbar) | |
188 | ||
924df208 BW |
189 | ;; Functions called from the tool bar |
190 | (defun mh-tool-bar-search (&optional arg) | |
191 | "Interactively call `mh-tool-bar-search-function'. | |
192 | Optional argument ARG is not used." | |
193 | (interactive "P") | |
194 | (call-interactively mh-tool-bar-search-function)) | |
195 | ||
196 | (defun mh-tool-bar-customize () | |
197 | "Call `mh-customize' from the toolbar." | |
198 | (interactive) | |
199 | (mh-customize t)) | |
200 | ||
201 | (defun mh-tool-bar-folder-help () | |
202 | "Visit \"(mh-e)Top\"." | |
203 | (interactive) | |
204 | (Info-goto-node "(mh-e)Top") | |
205 | (delete-other-windows)) | |
206 | ||
207 | (defun mh-tool-bar-letter-help () | |
208 | "Visit \"(mh-e)Draft Editing\"." | |
209 | (interactive) | |
210 | (Info-goto-node "(mh-e)Draft Editing") | |
211 | (delete-other-windows)) | |
212 | ||
213 | (defmacro mh-tool-bar-reply-generator (function recipient folder-buffer-flag) | |
214 | "Generate FUNCTION that replies to RECIPIENT. | |
215 | If FOLDER-BUFFER-FLAG is nil then the function generated | |
216 | When INCLUDE-FLAG is non-nil, include message body being replied to." | |
217 | `(defun ,function (&optional arg) | |
218 | ,(format "Reply to \"%s\".\nWhen ARG is non-nil include message in reply." | |
219 | recipient) | |
220 | (interactive "P") | |
221 | ,(if folder-buffer-flag nil '(set-buffer mh-show-folder-buffer)) | |
222 | (mh-reply (mh-get-msg-num nil) ,recipient arg))) | |
223 | ||
224 | (mh-tool-bar-reply-generator mh-tool-bar-reply-from "from" t) | |
225 | (mh-tool-bar-reply-generator mh-show-tool-bar-reply-from "from" nil) | |
226 | (mh-tool-bar-reply-generator mh-tool-bar-reply-to "to" t) | |
227 | (mh-tool-bar-reply-generator mh-show-tool-bar-reply-to "to" nil) | |
228 | (mh-tool-bar-reply-generator mh-tool-bar-reply-all "all" t) | |
229 | (mh-tool-bar-reply-generator mh-show-tool-bar-reply-all "all" nil) | |
230 | ||
231 | ;; XEmacs has a couple of extra customizations... | |
232 | (mh-do-in-xemacs | |
233 | (require 'mh-xemacs-icons) | |
234 | (defcustom mh-xemacs-use-toolbar-flag (if (and (featurep 'toolbar) | |
235 | (featurep 'xpm) | |
236 | (device-on-window-system-p)) | |
237 | t | |
238 | nil) | |
239 | "*If non-nil, use toolbar. | |
240 | ||
241 | This will default to t if you are in an environment that supports | |
242 | toolbars and xpm." | |
243 | :type 'boolean | |
244 | :group 'mh-toolbar) | |
245 | ||
246 | (defcustom mh-xemacs-toolbar-position (if mh-xemacs-use-toolbar-flag | |
247 | 'default | |
248 | nil) | |
249 | "*Where to put the toolbar. | |
250 | ||
251 | Valid non-nil values are \"default\", \"top\", \"bottom\", \"left\", | |
252 | \"right\". These match the four edges of the frame, with \"default\" | |
253 | meaning \"use the same position as the default-toolbar\". | |
254 | ||
255 | A nil value means do not use a toolbar. | |
256 | ||
257 | If this variable is set to anything other than \"default\" and the | |
258 | default-toolbar has a different positional setting from the value of | |
259 | this variable, then two toolbars will be displayed. The MH-E toolbar | |
260 | and the default-toolbar." | |
261 | :type '(radio (const :tag "Same position as the \"default-toolbar\"" | |
262 | :value default) | |
263 | (const :tag "Along the top edge of the frame" | |
264 | :value top) | |
265 | (const :tag "Along the bottom edge of the frame" | |
266 | :value bottom) | |
267 | (const :tag "Along the left edge of the frame" | |
268 | :value left) | |
269 | (const :tag "Along the right edge of the frame" | |
270 | :value right) | |
271 | (const :tag "Don't use a toolbar" nil)) | |
272 | :group 'mh-toolbar)) | |
273 | ||
274 | (defmacro mh-tool-bar-define (defaults &rest buttons) | |
275 | "Define a tool bar for MH-E. | |
276 | DEFAULTS is the list of buttons that are present by default. It is a list of | |
277 | lists where the sublists are of the following form: | |
278 | ||
279 | (:KEYWORD FUNC1 FUNC2 FUNC3 ...) | |
280 | ||
281 | Here :KEYWORD is one of :folder or :letter. If it is :folder then the default | |
282 | buttons in the folder and show mode buffers are being specified. If it is | |
283 | :letter then the default buttons in the letter mode are listed. FUNC1, FUNC2, | |
284 | FUNC3, ... are the names of the functions that the buttons would execute. | |
285 | ||
286 | Each element of BUTTONS is a list of four things: | |
287 | ||
288 | (FUNCTION MODES ICON DOC) | |
289 | ||
290 | where, | |
291 | ||
292 | FUNCTION is the name of the function that will be executed when the button | |
293 | is clicked. | |
294 | ||
295 | MODES is a list of symbols. List elements must be from `folder', `letter' and | |
296 | `sequence'. If `folder' is present then the button is available in the | |
297 | folder and show buffer. If the name of FUNCTION is of the form \"mh-foo\", | |
298 | where foo is some arbitrary string, then we check if the function | |
299 | `mh-show-foo' exists. If it exists then that function is used in the show | |
300 | buffer. Otherwise the original function `mh-foo' is used in the show buffer | |
301 | as well. Presence of `sequence' is handled similar to the above. The only | |
302 | difference is that the button is shown only when the folder is narrowed to a | |
303 | sequence. If `letter' is present in MODES, then the button is available | |
304 | during draft editing and runs FUNCTION when clicked. | |
305 | ||
306 | ICON is the icon that is drawn in the button. | |
307 | ||
308 | DOC is the documentation for the button. It is used in tool-tips and in | |
309 | providing other help to the user. GNU Emacs uses only the first line of the | |
310 | string. So the DOC should be formatted such that the first line is useful and | |
311 | complete without the rest of the string." | |
312 | ;; The following variable names have been carefully chosen to make code | |
313 | ;; generation easier. Modifying the names should be done carefully. | |
314 | (let (folder-buttons folder-docs folder-button-setter sequence-button-setter | |
315 | show-buttons show-button-setter show-seq-button-setter | |
316 | letter-buttons letter-docs letter-button-setter | |
317 | folder-defaults letter-defaults | |
318 | folder-vectors show-vectors letter-vectors) | |
319 | (dolist (x defaults) | |
320 | (cond ((eq (car x) :folder) (setq folder-defaults (cdr x))) | |
321 | ((eq (car x) :letter) (setq letter-defaults (cdr x))))) | |
322 | (dolist (button buttons) | |
323 | (unless (and (listp button) (equal (length button) 4)) | |
324 | (error "Incorrect MH-E tool-bar button specification: %s" button)) | |
325 | (let* ((name (nth 0 button)) | |
326 | (name-str (symbol-name name)) | |
327 | (icon (nth 2 button)) | |
328 | (xemacs-icon (mh-do-in-xemacs | |
329 | (cdr (assoc (intern icon) mh-xemacs-icon-map)))) | |
330 | (full-doc (nth 3 button)) | |
331 | (doc (if (string-match "\\(.*\\)\n" full-doc) | |
332 | (match-string 1 full-doc) | |
333 | full-doc)) | |
334 | (modes (nth 1 button)) | |
335 | functions show-sym) | |
336 | (when (memq 'letter modes) (setq functions `(:letter ,name))) | |
337 | (when (or (memq 'folder modes) (memq 'sequence modes)) | |
338 | (setq functions | |
339 | (append `(,(if (memq 'folder modes) :folder :sequence) ,name) | |
340 | functions)) | |
341 | (setq show-sym | |
342 | (if (string-match "^mh-\\(.*\\)$" name-str) | |
343 | (intern (concat "mh-show-" (match-string 1 name-str))) | |
344 | name)) | |
345 | (setq functions | |
346 | (append `(,(if (memq 'folder modes) :show :show-seq) | |
347 | ,(if (fboundp show-sym) show-sym name)) | |
348 | functions))) | |
349 | (do ((functions functions (cddr functions))) | |
350 | ((null functions)) | |
351 | (let* ((type (car functions)) | |
352 | (function (cadr functions)) | |
353 | (type1 (substring (symbol-name type) 1)) | |
354 | (vector-list (cond ((eq type :show) 'show-vectors) | |
355 | ((eq type :show-seq) 'show-vectors) | |
356 | ((eq type :letter) 'letter-vectors) | |
357 | (t 'folder-vectors))) | |
358 | (list (cond ((eq type :letter) 'mh-tool-bar-letter-buttons) | |
359 | (t 'mh-tool-bar-folder-buttons))) | |
360 | (key (intern (concat "mh-" type1 "toolbar-" name-str))) | |
361 | (setter (intern (concat type1 "-button-setter"))) | |
362 | (mbuttons (cond ((eq type :letter) 'letter-buttons) | |
363 | ((eq type :show) 'show-buttons) | |
364 | ((eq type :show-seq) 'show-buttons) | |
365 | (t 'folder-buttons))) | |
366 | (docs (cond ((eq mbuttons 'letter-buttons) 'letter-docs) | |
367 | ((eq mbuttons 'folder-buttons) 'folder-docs)))) | |
368 | (add-to-list vector-list `[,xemacs-icon ,function t ,full-doc]) | |
369 | (add-to-list | |
370 | setter `(when (member ',name ,list) | |
371 | (mh-funcall-if-exists | |
372 | tool-bar-add-item ,icon ',function ',key :help ,doc))) | |
373 | (add-to-list mbuttons name) | |
374 | (if docs (add-to-list docs doc)))))) | |
375 | (setq folder-buttons (nreverse folder-buttons) | |
376 | letter-buttons (nreverse letter-buttons) | |
377 | show-buttons (nreverse show-buttons) | |
378 | letter-docs (nreverse letter-docs) | |
379 | folder-docs (nreverse folder-docs) | |
380 | folder-vectors (nreverse folder-vectors) | |
381 | show-vectors (nreverse show-vectors) | |
382 | letter-vectors (nreverse letter-vectors)) | |
383 | (dolist (x folder-defaults) | |
384 | (unless (memq x folder-buttons) | |
385 | (error "Folder defaults contains unknown button '%s'" x))) | |
386 | (dolist (x letter-defaults) | |
387 | (unless (memq x letter-buttons) | |
388 | (error "Letter defaults contains unknown button '%s'" x))) | |
389 | `(eval-when (compile load eval) | |
390 | (defvar mh-folder-tool-bar-map nil) | |
391 | (defvar mh-folder-seq-tool-bar-map nil) | |
392 | (defvar mh-show-tool-bar-map nil) | |
393 | (defvar mh-show-seq-tool-bar-map nil) | |
394 | (defvar mh-letter-tool-bar-map nil) | |
395 | ;; GNU Emacs tool bar specific code | |
396 | (mh-do-in-gnu-emacs | |
397 | ;; Custom setter functions | |
398 | (defun mh-tool-bar-folder-buttons-set (symbol value) | |
399 | "Construct toolbar for `mh-folder-mode' and `mh-show-mode'." | |
400 | (set-default symbol value) | |
401 | (setq mh-folder-tool-bar-map | |
402 | (let ((tool-bar-map (make-sparse-keymap))) | |
403 | ,@(nreverse folder-button-setter) | |
404 | tool-bar-map)) | |
405 | (setq mh-show-tool-bar-map | |
406 | (let ((tool-bar-map (make-sparse-keymap))) | |
407 | ,@(nreverse show-button-setter) | |
408 | tool-bar-map)) | |
409 | (setq mh-show-seq-tool-bar-map | |
410 | (let ((tool-bar-map (copy-keymap mh-show-tool-bar-map))) | |
411 | ,@(nreverse show-seq-button-setter) | |
412 | tool-bar-map)) | |
413 | (setq mh-folder-seq-tool-bar-map | |
414 | (let ((tool-bar-map (copy-keymap mh-folder-tool-bar-map))) | |
415 | ,@(nreverse sequence-button-setter) | |
416 | tool-bar-map))) | |
417 | (defun mh-tool-bar-letter-buttons-set (symbol value) | |
418 | "Construct toolbar for `mh-letter-mode'." | |
419 | (set-default symbol value) | |
420 | (setq mh-letter-tool-bar-map | |
421 | (let ((tool-bar-map (make-sparse-keymap))) | |
422 | ,@(nreverse letter-button-setter) | |
423 | tool-bar-map)))) | |
424 | ;; XEmacs specific code | |
425 | (mh-do-in-xemacs | |
426 | (defvar mh-toolbar-folder-vector-map | |
427 | ',(loop for button in folder-buttons | |
428 | for vector in folder-vectors | |
429 | collect (cons button vector))) | |
430 | (defvar mh-toolbar-show-vector-map | |
431 | ',(loop for button in show-buttons | |
432 | for vector in show-vectors | |
433 | collect (cons button vector))) | |
434 | (defvar mh-toolbar-letter-vector-map | |
435 | ',(loop for button in letter-buttons | |
436 | for vector in letter-vectors | |
437 | collect (cons button vector))) | |
438 | (defvar mh-toolbar-folder-buttons nil) | |
439 | (defvar mh-toolbar-show-buttons nil) | |
440 | (defvar mh-toolbar-letter-buttons nil) | |
441 | ;; Custom setter functions | |
442 | (defun mh-tool-bar-letter-buttons-set (symbol value) | |
443 | (set-default symbol value) | |
444 | (setq mh-toolbar-letter-buttons | |
445 | (loop for b in value | |
446 | collect (cdr (assoc b mh-toolbar-letter-vector-map))))) | |
447 | (defun mh-tool-bar-folder-buttons-set (symbol value) | |
448 | (set-default symbol value) | |
449 | (setq mh-toolbar-folder-buttons | |
450 | (loop for b in value | |
451 | collect (cdr (assoc b mh-toolbar-folder-vector-map)))) | |
452 | (setq mh-toolbar-show-buttons | |
453 | (loop for b in value | |
454 | collect (cdr (assoc b mh-toolbar-show-vector-map))))) | |
455 | ;; Initialize toolbar | |
456 | (defun mh-toolbar-init (mode) | |
457 | "Install toolbar in MODE." | |
458 | (let ((toolbar (cond ((eq mode :folder) mh-toolbar-folder-buttons) | |
459 | ((eq mode :letter) mh-toolbar-letter-buttons) | |
460 | ((eq mode :show) mh-toolbar-show-buttons))) | |
461 | (height 37) | |
462 | (width 40) | |
463 | (buffer (current-buffer))) | |
464 | (when (and mh-xemacs-toolbar-position mh-xemacs-use-toolbar-flag) | |
465 | (cond | |
466 | ((eq mh-xemacs-toolbar-position 'top) | |
467 | (set-specifier top-toolbar (cons buffer toolbar)) | |
468 | (set-specifier top-toolbar-visible-p t) | |
469 | (set-specifier top-toolbar-height height)) | |
470 | ((eq mh-xemacs-toolbar-position 'bottom) | |
471 | (set-specifier bottom-toolbar (cons buffer toolbar)) | |
472 | (set-specifier bottom-toolbar-visible-p t) | |
473 | (set-specifier bottom-toolbar-height height)) | |
474 | ((eq mh-xemacs-toolbar-position 'left) | |
475 | (set-specifier left-toolbar (cons buffer toolbar)) | |
476 | (set-specifier left-toolbar-visible-p t) | |
477 | (set-specifier left-toolbar-width width)) | |
478 | ((eq mh-xemacs-toolbar-position 'right) | |
479 | (set-specifier right-toolbar (cons buffer toolbar)) | |
480 | (set-specifier right-toolbar-visible-p t) | |
481 | (set-specifier right-toolbar-width width)) | |
482 | (t (set-specifier default-toolbar (cons buffer toolbar)))))))) | |
483 | ;; Declare customizable toolbars | |
484 | (custom-declare-variable | |
485 | 'mh-tool-bar-folder-buttons | |
486 | '(list ,@(mapcar (lambda (x) `(quote ,x)) folder-defaults)) | |
487 | "Choose buttons to include in MH-E folder/show toolbar." | |
488 | :group 'mh-toolbar :set 'mh-tool-bar-folder-buttons-set | |
489 | :type '(set ,@(loop for x in folder-buttons | |
490 | for y in folder-docs | |
491 | collect `(const :tag ,y ,x)))) | |
492 | (custom-declare-variable | |
493 | 'mh-tool-bar-letter-buttons | |
494 | '(list ,@(mapcar (lambda (x) `(quote ,x)) letter-defaults)) | |
495 | "Choose buttons to include in MH-E letter toolbar." | |
496 | :group 'mh-toolbar :set 'mh-tool-bar-letter-buttons-set | |
497 | :type '(set ,@(loop for x in letter-buttons | |
498 | for y in letter-docs | |
499 | collect `(const :tag ,y ,x))))))) | |
500 | ||
501 | (mh-tool-bar-define | |
502 | ((:folder mh-inc-folder mh-mime-save-parts mh-previous-undeleted-msg | |
503 | mh-page-msg mh-next-undeleted-msg mh-delete-msg mh-refile-msg | |
504 | mh-undo mh-execute-commands mh-toggle-tick mh-reply | |
505 | mh-alias-grab-from-field mh-send mh-rescan-folder | |
506 | mh-tool-bar-search mh-visit-folder | |
507 | mh-tool-bar-customize mh-tool-bar-folder-help mh-widen) | |
508 | (:letter mh-send-letter mh-compose-insertion ispell-message save-buffer | |
509 | undo kill-region menu-bar-kill-ring-save yank mh-fully-kill-draft | |
510 | mh-tool-bar-customize mh-tool-bar-letter-help)) | |
511 | ;; Folder/Show buffer buttons | |
512 | (mh-inc-folder (folder) "mail" | |
513 | "Incorporate new mail in Inbox | |
514 | This button runs `mh-inc-folder' which drags any | |
515 | new mail into your Inbox folder.") | |
516 | (mh-mime-save-parts (folder) "attach" | |
517 | "Save MIME parts from this message | |
518 | This button runs `mh-mime-save-parts' which saves a message's | |
519 | different parts into separate files.") | |
520 | (mh-previous-undeleted-msg (folder) "left_arrow" | |
521 | "Go to the previous undeleted message | |
522 | This button runs `mh-previous-undeleted-msg'") | |
523 | (mh-page-msg (folder) "page-down" | |
524 | "Page the current message forwards\nThis button runs `mh-page-msg'") | |
525 | (mh-next-undeleted-msg (folder) "right_arrow" | |
526 | "Go to the next undeleted message\nThe button runs `mh-next-undeleted-msg'") | |
527 | (mh-delete-msg (folder) "close" | |
528 | "Mark this message for deletion\nThis button runs `mh-delete-msg'") | |
529 | (mh-refile-msg (folder) "refile" | |
530 | "Refile this message\nThis button runs `mh-refile-msg'") | |
531 | (mh-undo (folder) "undo" "Undo last operation\nThis button runs `undo'") | |
532 | (mh-execute-commands (folder) "execute" | |
533 | "Perform moves and deletes\nThis button runs `mh-execute-commands'") | |
534 | (mh-toggle-tick (folder) "highlight" | |
535 | "Toggle tick mark\nThis button runs `mh-toggle-tick'") | |
536 | (mh-toggle-showing (folder) "show" | |
537 | "Toggle showing message\nThis button runs `mh-toggle-showing'") | |
538 | (mh-tool-bar-reply-from (folder) "reply-from" "Reply to \"from\"") | |
539 | (mh-tool-bar-reply-to (folder) "reply-to" "Reply to \"to\"") | |
540 | (mh-tool-bar-reply-all (folder) "reply-all" "Reply to \"all\"") | |
541 | (mh-reply (folder) "mail/reply2" | |
542 | "Reply to this message\nThis button runs `mh-reply'") | |
543 | (mh-alias-grab-from-field (folder) "alias" | |
544 | "Grab From alias\nThis button runs `mh-alias-grab-from-field'") | |
545 | (mh-send (folder) "mail_compose" | |
546 | "Compose new message\nThis button runs `mh-send'") | |
547 | (mh-rescan-folder (folder) "rescan" | |
548 | "Rescan this folder\nThis button runs `mh-rescan-folder'") | |
549 | (mh-pack-folder (folder) "repack" | |
550 | "Repack this folder\nThis button runs `mh-pack-folder'") | |
551 | (mh-tool-bar-search (folder) "search" | |
552 | "Search\nThis button runs `mh-tool-bar-search-function'") | |
553 | (mh-visit-folder (folder) "fld_open" | |
554 | "Visit other folder\nThis button runs `mh-visit-folder'") | |
555 | ;; Letter buffer buttons | |
556 | (mh-send-letter (letter) "mail_send" "Send this letter") | |
557 | (mh-compose-insertion (letter) "attach" "Insert attachment") | |
558 | (ispell-message (letter) "spell" "Check spelling") | |
559 | (save-buffer (letter) "save" "Save current buffer to its file") | |
560 | (undo (letter) "undo" "Undo last operation") | |
561 | (kill-region (letter) "cut" | |
562 | "Cut (kill) text in region between mark and current position") | |
563 | (menu-bar-kill-ring-save (letter) "copy" | |
564 | "Copy text in region between mark and current position") | |
565 | (yank (letter) "paste" "Paste (yank) text cut or copied earlier") | |
566 | (mh-fully-kill-draft (letter) "close" "Kill this draft") | |
567 | ;; Common buttons | |
568 | (mh-tool-bar-customize (folder letter) "preferences" "MH-E Preferences") | |
569 | (mh-tool-bar-folder-help (folder) "help" | |
570 | "Help! (general help)\nThis button runs `Info-goto-node'") | |
571 | (mh-tool-bar-letter-help (letter) "help" | |
572 | "Help! (general help)\nThis button runs `Info-goto-node'") | |
573 | ;; Folder narrowed to sequence buttons | |
574 | (mh-widen (sequence) "widen" | |
575 | "Widen from the sequence\nThis button runs `mh-widen'")) | |
c3d9274a BW |
576 | |
577 | \f | |
578 | ||
579 | ;;; Speedbar and folder configuration (:group 'mh-speed) | |
580 | ||
581 | (defcustom mh-large-folder 200 | |
582 | "The number of messages that indicates a large folder. | |
583 | If a folder is deemed to be large, that is the number of messages in it exceed | |
584 | this value, then confirmation is needed when it is visited. Even when | |
585 | `mh-show-threads-flag' is non-nil, the folder is not automatically threaded, if | |
586 | it is large. If set to nil all folders are treated as if they are small." | |
587 | :type '(choice (const :tag "No limit") integer) | |
588 | :group 'mh-speed) | |
589 | ||
590 | (defcustom mh-speed-flists-interval 60 | |
591 | "Time between calls to flists in seconds. | |
592 | If 0, flists is not called repeatedly." | |
593 | :type 'integer | |
594 | :group 'mh-speed) | |
595 | ||
596 | (defcustom mh-speed-run-flists-flag t | |
597 | "Non-nil means flists is used. | |
598 | If non-nil, flists is executed every `mh-speed-flists-interval' seconds to | |
599 | update the display of the number of unseen and total messages in each folder. | |
600 | If resources are limited, this can be set to nil and the speedbar display can | |
601 | be updated manually with the \\[mh-speed-flists] command." | |
602 | :type 'boolean | |
603 | :group 'mh-speed) | |
604 | ||
3d7ca223 BW |
605 | \f |
606 | ||
c3d9274a BW |
607 | ;;; Options for controlling scan listing (:group 'mh-folder) |
608 | ||
609 | (defcustom mh-adaptive-cmd-note-flag t | |
610 | "*Non-nil means that the message number width is determined dynamically. | |
611 | This is done once when a folder is first opened by running scan on the last | |
612 | message of the folder. The message number for the last message is extracted | |
613 | and its width calculated. This width is used when calling `mh-set-cmd-note'. | |
614 | ||
615 | If you prefer fixed-width message numbers, set this variable to nil and call | |
616 | `mh-set-cmd-note' with the width specified by the scan format in | |
617 | `mh-scan-format-file'. For example, the default width is 4, so you would use | |
618 | \"(mh-set-cmd-note 4)\" if `mh-scan-format-file' were nil." | |
619 | :type 'boolean | |
620 | :group 'mh-folder) | |
621 | ||
3d7ca223 BW |
622 | (defcustom mh-default-folder-list nil |
623 | "*Alist of addresses and folders. | |
624 | When refiling messages, these folders are the default that is provided if the | |
924df208 BW |
625 | sender (or recipient if the Check Recipient checkbox has been selected) has |
626 | the associated address, a regexp. The first entry to match will be used, so | |
627 | order them according to the wanted priority. You do not need to list your | |
628 | aliases here as that lookup is already performed. | |
629 | ||
3d7ca223 BW |
630 | See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more |
631 | information." | |
924df208 BW |
632 | :type '(repeat (list (regexp :tag "Address") |
633 | (string :tag "Folder") | |
634 | (boolean :tag "Check Recipient"))) | |
3d7ca223 BW |
635 | :group 'mh-folder) |
636 | ||
637 | (defcustom mh-default-folder-must-exist-flag t | |
638 | "*Non-nil means guessed folder name must exist to be used. | |
639 | If this variable is t, then the guessed name is only used if the folder | |
640 | already exists\; if the folder doesn't exist, then the last folder name used | |
641 | is suggested. This is useful if you get mail from various people for whom you | |
642 | have an alias, but file them all in the same project folder. | |
643 | See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more | |
644 | information." | |
c3d9274a BW |
645 | :type 'boolean |
646 | :group 'mh-folder) | |
647 | ||
3d7ca223 BW |
648 | (defcustom mh-default-folder-prefix "" |
649 | "*Prefix used for guessed folder names. | |
650 | This can be used to put folders associated with your aliases in a sub-folder | |
651 | so as to not clutter your mail directory. | |
652 | See `mh-prompt-for-refile-folder' and `mh-folder-from-address' for more | |
653 | information." | |
654 | :type 'string | |
655 | :group 'mh-folder) | |
656 | ||
c3d9274a BW |
657 | (defcustom mh-inc-prog "inc" |
658 | "*Program to run to incorporate new mail into a folder. | |
659 | Normally \"inc\". This file is searched for relative to | |
660 | the `mh-progs' directory unless it is an absolute pathname." | |
661 | :type 'string | |
662 | :group 'mh-folder) | |
663 | ||
924df208 BW |
664 | |
665 | (defcustom mh-inc-spool-list nil | |
666 | "*Alist of alternate spool files, corresponding folders and keybindings. | |
667 | Here's an example. Suppose you have subscribed to the MH-E devel mailing | |
668 | list. You could filter its mail into a separate spool file named | |
669 | ~/mail/mh-e using Procmail and a .procmailrc entry like: | |
670 | ||
671 | MAILDIR=$HOME/mail #you'd better make sure it exists | |
672 | :0: | |
673 | * ^From mh-e-devel-admin@lists.sourceforge.net | |
674 | mh-e | |
675 | ||
676 | If you wanted to incorporate that spool file into an MH folder called | |
677 | mh-e by pressing \"I m\" in folder-mode or by `M-x mh-inc-spool-mh-e', | |
678 | you would setup `mh-inc-spool-list' with an entry: | |
679 | ||
680 | Spool file: ~/mail/mh-e | |
681 | Folder: mh-e | |
682 | Key binding: m | |
683 | ||
684 | Then, you could also install `xbuffy' and configure an extra mailbox like so: | |
685 | ||
686 | box ~/mail/mh-e | |
687 | title mh-e | |
688 | origMode | |
689 | polltime 10 | |
690 | headertime 0 | |
691 | command gnudoit -q '(mh-inc-spool-mh-e)' | |
692 | ||
693 | Note that the entry above uses the gnuserv package to communicate the | |
694 | command `mh-inc-spool-mh-e' to Emacs. It will incorporate the spool file | |
695 | when clicking the xbuffy box with the middle mouse button." | |
696 | :type '(repeat (list (file :tag "Spool file") | |
697 | (string :tag "Folder") | |
698 | (character :tag "Key binding"))) | |
699 | :set 'mh-inc-spool-list-set | |
700 | :group 'mh-folder) | |
701 | ||
c3d9274a BW |
702 | (defcustom mh-lpr-command-format "lpr -J '%s'" |
703 | "*Format for Unix command that prints a message. | |
704 | The string should be a Unix command line, with the string '%s' where | |
705 | the job's name (folder and message number) should appear. The formatted | |
706 | message text is piped to this command when you type \\<mh-folder-mode-map>`\\[mh-print-msg]'." | |
707 | :type 'string | |
708 | :group 'mh-folder) | |
709 | ||
710 | (defcustom mh-mime-save-parts-default-directory t | |
711 | "Default directory to use for `mh-mime-save-parts'. | |
712 | If nil, prompt and set for next time the command is used during same session. | |
713 | If t, prompt always" | |
714 | :type '(choice (const :tag "Prompt the first time" nil) | |
715 | (const :tag "Prompt always" t) | |
716 | directory) | |
717 | :group 'mh-folder) | |
718 | ||
c3d9274a BW |
719 | (defcustom mh-print-background-flag nil |
720 | "*Non-nil means messages should be printed in the background. | |
721 | WARNING: do not delete the messages until printing is finished; | |
722 | otherwise, your output may be truncated." | |
723 | :type 'boolean | |
724 | :group 'mh-folder) | |
725 | ||
924df208 BW |
726 | (defcustom mh-recenter-summary-flag nil |
727 | "*Non-nil means to recenter the summary window. | |
728 | Recenter the summary window when the show window is toggled off if non-nil." | |
729 | :type 'boolean | |
730 | :group 'mh-folder) | |
731 | ||
c3d9274a BW |
732 | (defcustom mh-recursive-folders-flag nil |
733 | "*Non-nil means that commands which operate on folders do so recursively." | |
734 | :type 'boolean | |
735 | :group 'mh-folder) | |
736 | ||
737 | (defcustom mh-scan-format-file t | |
738 | "Specifies the format file to pass to the scan program. | |
739 | If t, the format string will be taken from the either `mh-scan-format-mh' | |
740 | or `mh-scan-format-nmh' depending on whether MH or nmh is in use. | |
741 | If nil, the default scan output will be used. | |
742 | ||
743 | If you customize the scan format, you may need to modify a few variables | |
744 | containing regexps that MH-E uses to identify specific portions of the output. | |
745 | Use `M-x apropos RET mh-scan.*regexp' to obtain a list of these variables. You | |
746 | may also have to call `mh-set-cmd-note' with the width of your message | |
747 | numbers. See also `mh-adaptive-cmd-note-flag'." | |
748 | :type '(choice (const :tag "Use MH-E scan format" t) | |
749 | (const :tag "Use default scan format" nil) | |
750 | (file :tag "Specify a scan format file")) | |
751 | :group 'mh-folder) | |
752 | ||
753 | (defcustom mh-scan-prog "scan" | |
754 | "*Program to run to generate one-line-per-message listing of a folder. | |
755 | Normally \"scan\" or a file name linked to scan. This file is searched | |
756 | for relative to the `mh-progs' directory unless it is an absolute pathname." | |
757 | :type 'string | |
758 | :group 'mh-folder) | |
759 | (make-variable-buffer-local 'mh-scan-prog) | |
760 | ||
761 | (defcustom mh-show-threads-flag nil | |
762 | "Non-nil means new folders start in threaded mode. | |
763 | Threading large number of messages can be time consuming. So if the flag is | |
764 | non-nil then threading will be done only if the number of messages being | |
765 | threaded is less than `mh-large-folder'." | |
766 | :type 'boolean | |
767 | :group 'mh-folder) | |
768 | ||
769 | (defcustom mh-store-default-directory nil | |
770 | "*Last directory used by \\[mh-store-msg]; default for next store. | |
771 | A directory name string, or nil to use current directory." | |
772 | :type '(choice (const :tag "Current" nil) | |
773 | directory) | |
774 | :group 'mh-folder) | |
775 | ||
924df208 BW |
776 | (defcustom mh-tick-seq 'tick |
777 | "The name of the MH tick sequence." | |
778 | :type '(choice (const :tag "Disable ticking" nil) | |
779 | symbol) | |
780 | :group 'mh-folder) | |
781 | ||
c3d9274a BW |
782 | (defcustom mh-update-sequences-after-mh-show-flag t |
783 | "*Non-nil means `mh-update-sequence' is called from `mh-show-mode'. | |
784 | If set, `mh-update-sequence' is run every time a message is shown, telling | |
785 | MH or nmh that this is your current message. It's useful, for example, to | |
786 | display MIME content using \"M-! mhshow RET\"" | |
787 | :type 'boolean | |
788 | :group 'mh-folder) | |
789 | ||
3d7ca223 BW |
790 | \f |
791 | ||
924df208 BW |
792 | ;;; Indexed searching (:group 'mh-index) |
793 | ||
794 | (defcustom mh-index-new-messages-folders t | |
795 | "Folders searched for `mh-unseen-seq'. | |
796 | If t, then `mh-inbox' is searched. If nil, all the top level folders are | |
797 | searched. Otherwise the list of folders specified as strings are searched. | |
798 | See also `mh-recursive-folders-flag'." | |
799 | :group 'mh-index | |
800 | :type '(choice (const :tag "Inbox" t) | |
801 | (const :tag "All" nil) | |
802 | (repeat :tag "Choose folders" (string :tag "Folder")))) | |
803 | ||
804 | (defcustom mh-index-program nil | |
805 | "Indexing program that MH-E shall use. | |
806 | The possible choices are swish++, swish-e, mairix, namazu, glimpse, pick and | |
807 | grep. By default this variable is nil which means that the programs are tried | |
808 | in order and the first one found is used. | |
809 | ||
810 | More information about setting up an indexing program to use with MH-E can be | |
811 | found in the documentation of `mh-index-search'." | |
812 | :type '(choice (const :tag "Auto-detect" nil) | |
813 | (const :tag "swish++" swish++) | |
814 | (const :tag "swish-e" swish) | |
815 | (const :tag "mairix" mairix) | |
816 | (const :tag "namazu" namazu) | |
817 | (const :tag "glimpse" glimpse) | |
818 | (const :tag "pick" pick) | |
819 | (const :tag "grep" grep)) | |
820 | :group 'mh-index) | |
821 | ||
822 | \f | |
823 | ||
824 | ;;; Spam Handling (:group 'mh-junk) | |
825 | ||
826 | ;; Spam fighting program chosen | |
827 | (defvar mh-junk-choice nil) | |
828 | ||
829 | ;; Available spam filter interfaces | |
830 | (defvar mh-junk-function-alist | |
831 | '((bogofilter mh-bogofilter-blacklist mh-bogofilter-whitelist) | |
832 | (spamprobe mh-spamprobe-blacklist mh-spamprobe-whitelist) | |
833 | (spamassassin mh-spamassassin-blacklist mh-spamassassin-whitelist)) | |
834 | "Available choices of spam programs to use. | |
835 | This is an alist. For each element there are functions that blacklist a message | |
836 | as spam and whitelist a message incorrectly classified as spam.") | |
837 | ||
838 | (defun mh-junk-choose (symbol value) | |
839 | "Choose spam program to use. | |
840 | The function is always called with SYMBOL bound to `mh-junk-program' and VALUE | |
841 | bound to the new value of `mh-junk-program'. The function sets the variable | |
842 | `mh-junk-choice' in addition to `mh-junk-program'." | |
843 | (set symbol value) | |
844 | (setq mh-junk-choice | |
845 | (or value | |
846 | (loop for element in mh-junk-function-alist | |
847 | until (executable-find (symbol-name (car element))) | |
848 | finally return (car element))))) | |
849 | ||
850 | ;; User customizable variables | |
851 | (defcustom mh-junk-mail-folder nil | |
852 | "Folder to put spam mail in. | |
853 | If nil then the spam is deleted." | |
854 | :type '(choice (const :tag "Delete spam" nil) | |
855 | (string :tag "Spam folder")) | |
856 | :group 'mh-junk) | |
857 | ||
858 | (defcustom mh-junk-program nil | |
859 | "Spam program that MH-E shall use. | |
860 | The possible choices are bogofilter, spamprobe, and spamassassin. By default | |
861 | this variable is nil which means that the programs are tried in order and the | |
862 | first one found is used." | |
863 | :type '(choice (const :tag "auto-detect" nil) | |
864 | (const :tag "bogofilter" bogofilter) | |
865 | (const :tag "spamprobe" spamprobe) | |
866 | (const :tag "spamassassin" spamassassin)) | |
867 | :set 'mh-junk-choose | |
868 | :group 'mh-junk) | |
869 | ||
870 | \f | |
871 | ||
c3d9274a BW |
872 | ;;; Message display (:group 'mh-show) |
873 | ||
874 | (defcustom mh-bury-show-buffer-flag t | |
875 | "*Non-nil means that the displayed show buffer for a folder is buried." | |
876 | :type 'boolean | |
877 | :group 'mh-show) | |
878 | ||
879 | (defcustom mh-clean-message-header-flag t | |
880 | "*Non-nil means clean headers of messages that are displayed or inserted. | |
881 | The variables `mh-invisible-headers' and `mh-visible-headers' control | |
882 | what is removed." | |
883 | :type 'boolean | |
884 | :group 'mh-show) | |
885 | ||
886 | (defcustom mh-decode-mime-flag (not (not (locate-library "mm-decode"))) | |
887 | "*Non-nil means that Gnus is used to show MIME attachments with Gnus." | |
888 | :type 'boolean | |
889 | :group 'mh-show) | |
890 | ||
c3d9274a BW |
891 | (defcustom mh-display-buttons-for-inline-parts-flag nil |
892 | "*Non-nil means display buttons for all inline MIME parts. | |
893 | If non-nil, buttons are displayed for all MIME parts. Inline parts start off | |
894 | in displayed state but they can be hidden by clicking the button. If nil no | |
895 | buttons are shown for inline parts." | |
896 | :type 'boolean | |
897 | :group 'mh-show) | |
898 | ||
899 | (defcustom mh-do-not-confirm-flag nil | |
900 | "*Non-nil means do not prompt for confirmation. | |
901 | Commands such as `mh-pack-folder' prompt to confirm whether to process | |
902 | outstanding moves and deletes or not before continuing. A non-nil setting will | |
903 | perform the action--which is usually desired but cannot be retracted--without | |
904 | question." | |
905 | :type 'boolean | |
906 | :group 'mh-show) | |
907 | ||
924df208 BW |
908 | (defcustom mh-fetch-x-image-url nil |
909 | "Control fetching of X-Image-URL header field image. | |
910 | This setting only has effect if `mh-show-use-xface-flag' is non-nil. | |
911 | ||
912 | If set to t, the image is fetched. | |
913 | ||
914 | If set to 'ask, the user is prompted before the image is fetched. MH-E will | |
915 | remember your reply and will either use the already fetched image the next time | |
916 | the same URL is encountered or silently skip it if you didn't fetch it the | |
917 | first time. | |
918 | ||
919 | If set to nil, the default, images are not fetched and only displayed if they | |
920 | are already present in the cache." | |
921 | :type '(choice (const :tag "Always fetch" t) | |
922 | (const :tag "Ask before fetching" ask) | |
923 | (const :tag "Never fetch" nil)) | |
924 | :group 'mh-show) | |
925 | ||
c3d9274a BW |
926 | (defcustom mh-graphical-smileys-flag t |
927 | "*Non-nil means graphical smileys are displayed. | |
928 | Non-nil means that small graphics will be used in the show buffer instead of | |
929 | patterns like :-), ;-) etc. The setting only has effect if | |
930 | `mh-decode-mime-flag' is non-nil." | |
931 | :type 'boolean | |
932 | :group 'mh-show) | |
933 | ||
934 | (defcustom mh-graphical-emphasis-flag t | |
935 | "*Non-nil means graphical emphasis is displayed. | |
936 | Non-nil means that _underline_ will be underlined, *bold* will appear in bold, | |
937 | /italic/ will appear in italic etc. See `gnus-emphasis-alist' for the whole | |
938 | list. The setting only has effect if `mh-decode-mime-flag' is non-nil." | |
939 | :type 'boolean | |
940 | :group 'mh-show) | |
941 | ||
942 | (defcustom mh-highlight-citation-p 'gnus | |
943 | "How to highlight citations in show buffers. | |
944 | The gnus method uses a different color for each indentation." | |
3d7ca223 | 945 | :type '(choice (const :tag "Use Gnus" gnus) |
c3d9274a BW |
946 | (const :tag "Use font-lock" font-lock) |
947 | (const :tag "Don't fontify" nil)) | |
948 | :group 'mh-show) | |
949 | ||
924df208 BW |
950 | (defvar mh-invisible-headers nil |
951 | "*Regexp matching lines in a message header that are not to be shown. | |
952 | Use the function `mh-invisible-headers' to generate this variable. | |
953 | If `mh-visible-headers' is non-nil, it is used instead to specify what | |
954 | to keep.") | |
955 | ||
956 | (defun mh-invisible-headers () | |
957 | "Make or remake the variable `mh-invisible-headers'. | |
958 | Done using `mh-invisible-header-fields' as input." | |
959 | (setq mh-invisible-headers | |
960 | (concat | |
961 | "^" | |
962 | (let ((max-specpdl-size 1000) ;workaround for insufficient default | |
963 | (fields mh-invisible-header-fields)) | |
964 | (regexp-opt fields t))))) | |
965 | ||
966 | (defun mh-invisible-header-fields-set (symbol value) | |
967 | "Update `mh-invisible-header-fields'. | |
968 | The function is called with SYMBOL bound to `mh-invisible-header-fields' and | |
969 | VALUE is the the list of headers that are invisible. As a side effect, the | |
970 | variable `mh-invisible-fields' is set." | |
971 | (set-default symbol value) | |
972 | (mh-invisible-headers)) | |
973 | ||
974 | ;; Keep fields alphabetized. Mention source, if known. | |
975 | (defcustom mh-invisible-header-fields | |
976 | '("Approved:" | |
977 | "Autoforwarded:" | |
978 | "Bestservhost:" | |
979 | "Cancel-Lock:" ; NNTP posts | |
980 | "Content-" ; RFC 2045 | |
981 | "Delivered-To:" ; Egroups/yahoogroups mailing list manager | |
982 | "Delivery-Date:" ; MH | |
983 | "Delivery:" | |
984 | "Encoding:" | |
985 | "Errors-To:" | |
986 | "Face:" ; Gnus Face header | |
987 | "Forwarded:" ; MH | |
988 | "From " ; sendmail | |
989 | "Importance:" ; MS Outlook | |
990 | "In-Reply-To:" ; MH | |
991 | "Lines:" | |
992 | "List-" ; Mailman mailing list manager | |
993 | "List-" ; Unknown mailing list managers | |
994 | "List-Subscribe:" ; Unknown mailing list managers | |
995 | "List-Unsubscribe:" ; Unknown mailing list managers | |
996 | "Mail-from:" ; MH | |
997 | "Mailing-List:" ; Egroups/yahoogroups mailing list manager | |
998 | "Message-Id:" ; RFC 822 | |
999 | "Mime-Version" ; RFC 2045 | |
1000 | "NNTP-" ; News | |
1001 | "Old-Return-Path:" | |
1002 | "Original-Encoded-Information-Types:" ; X400 | |
1003 | "Original-Lines:" ; mail to news | |
1004 | "Original-Newsgroups:" ; mail to news | |
1005 | "Original-NNTP-" ; mail to news | |
1006 | "Original-Path:" ; mail to news | |
1007 | "Original-Received:" ; mail to news | |
1008 | "Original-To:" ; mail to news | |
1009 | "Original-X-" ; mail to news | |
1010 | "P1-Content-Type:" ; X400 | |
1011 | "P1-Message-Id:" ; X400 | |
1012 | "P1-Recipient:" ; X400 | |
1013 | "Path:" | |
1014 | "Precedence:" | |
1015 | "Prev-Resent" ; MH | |
1016 | "Priority:" | |
1017 | "Received:" ; RFC 822 | |
1018 | "References:" | |
1019 | "Remailed-" ; MH | |
1020 | "Replied:" ; MH | |
1021 | "Resent" ; MH | |
1022 | "Return-Path:" ; RFC 822 | |
1023 | "Sensitivity:" ; MS Outlook | |
1024 | "Status:" ; sendmail | |
1025 | "Ua-Content-Id:" ; X400 | |
1026 | "User-Agent:" | |
1027 | "Via:" ; MH | |
1028 | "X-Abuse-Info:" | |
1029 | "X-Accept-Language:" | |
1030 | "X-Accept-Language:" ; Netscape/Mozilla | |
1031 | "X-Ack:" | |
1032 | "X-Apparently-From:" ; MS Outlook | |
1033 | "X-Apparently-To:" ; Egroups/yahoogroups mailing list manager | |
1034 | "X-Authentication-Warning:" ; sendmail | |
1035 | "X-Beenthere:" ; Mailman mailing list manager | |
1036 | "X-Bogosity:" ; bogofilter | |
1037 | "X-Complaints-To:" | |
1038 | "X-Cron-Env:" | |
1039 | "X-Delivered" | |
1040 | "X-Envelope-Sender:" | |
1041 | "X-Envelope-To:" | |
1042 | "X-Face:" | |
1043 | "X-Folder:" ; Spam | |
1044 | "X-From-Line" | |
1045 | "X-Gnus-Mail-Source:" ; gnus | |
1046 | "X-Habeas-SWE-1:" ; Spam | |
1047 | "X-Habeas-SWE-2:" ; Spam | |
1048 | "X-Habeas-SWE-3:" ; Spam | |
1049 | "X-Habeas-SWE-4:" ; Spam | |
1050 | "X-Habeas-SWE-5:" ; Spam | |
1051 | "X-Habeas-SWE-6:" ; Spam | |
1052 | "X-Habeas-SWE-7:" ; Spam | |
1053 | "X-Habeas-SWE-8:" ; Spam | |
1054 | "X-Habeas-SWE-9:" ; Spam | |
1055 | "X-Info:" ; NTMail | |
1056 | "X-Juno-" ; Juno | |
1057 | "X-List-Host:" ; Unknown mailing list managers | |
1058 | "X-List-Subscribe:" ; Unknown mailing list managers | |
1059 | "X-List-Unsubscribe:" ; Unknown mailing list managers | |
1060 | "X-Listserver:" ; Unknown mailing list managers | |
1061 | "X-Loop:" ; Unknown mailing list managers | |
1062 | "X-MIME-Autoconverted:" ; sendmail | |
1063 | "X-MIMETrack:" | |
1064 | "X-MS-TNEF-Correlator:" ; MS Outlook | |
1065 | "X-Mailing-List:" ; Unknown mailing list managers | |
1066 | "X-Mailman-Version:" ; Mailman mailing list manager | |
1067 | "X-Majordomo:" ; Majordomo mailing list manager | |
1068 | "X-Message-Id" | |
1069 | "X-MHE-Checksum" ; Checksum added during index search | |
1070 | "X-MimeOLE:" ; MS Outlook | |
1071 | "X-Mozilla-Status:" ; Netscape/Mozilla | |
1072 | "X-Msmail-" ; MS Outlook | |
1073 | "X-News:" ; News | |
1074 | "X-No-Archive:" | |
1075 | "X-Notes-Item:" ; Lotus Notes Domino structured header | |
1076 | "X-Orcl-Content-Type:" | |
1077 | "X-Original-Complaints-To:" | |
1078 | "X-Original-Date:" ; SourceForge mailing list manager | |
1079 | "X-Original-Trace:" | |
1080 | "X-OriginalArrivalTime:" ; Hotmail | |
1081 | "X-Originating-IP:" ; Hotmail | |
1082 | "X-Priority:" ; MS Outlook | |
1083 | "X-Qotd-" ; User added | |
1084 | "X-Received-Date:" | |
1085 | "X-Received:" | |
1086 | "X-Request-" | |
1087 | "X-SBClass:" ; Spam | |
1088 | "X-SBNote:" ; Spam | |
1089 | "X-SBPass:" ; Spam | |
1090 | "X-SBRule:" ; Spam | |
1091 | "X-Scanned-By" | |
1092 | "X-Sender:" | |
1093 | "X-Server-Date:" | |
1094 | "X-Server-Uuid:" | |
1095 | "X-Sieve:" ; Sieve filtering | |
1096 | "X-Spam-Checker-Version:" ; Spamassassin | |
1097 | "X-Spam-Level:" ; Spamassassin | |
1098 | "X-Spam-Score:" ; Spamassassin | |
1099 | "X-Spam-Status:" ; Spamassassin | |
1100 | "X-SpamBouncer:" ; Spam | |
1101 | "X-Trace:" | |
1102 | "X-UIDL:" | |
1103 | "X-UserInfo1:" | |
1104 | "X-VSMLoop:" ; NTMail | |
1105 | "X-Vms-To:" | |
1106 | "X-Wss-Id:" ; Worldtalk gateways | |
1107 | "X-eGroups-" ; Egroups/yahoogroups mailing list manager | |
1108 | "X-pgp:" | |
1109 | "X-submission-address:" | |
1110 | "X400-" ; X400 | |
1111 | "Xref:") | |
1112 | "*List of header fields that are not to be shown. | |
1113 | Regexps are not allowed. Unique fields should have a \":\" suffix; otherwise, | |
1114 | the element can be used to render invisible an entire class of fields that | |
1115 | start with the same prefix. | |
1116 | This variable is ignored if `mh-visible-headers' is set." | |
1117 | :type '(repeat (string :tag "Header field")) | |
1118 | :set 'mh-invisible-header-fields-set | |
1119 | :group 'mh-show) | |
1120 | ||
c3d9274a BW |
1121 | (defcustom mh-max-inline-image-height nil |
1122 | "*Maximum inline image height if Content-Disposition is not present. | |
1123 | If nil, image will be displayed if its height is smaller than the height of | |
1124 | the window." | |
1125 | :type '(choice (const nil) integer) | |
1126 | :group 'mh-show) | |
1127 | ||
1128 | (defcustom mh-max-inline-image-width nil | |
1129 | "*Maximum inline image width if Content-Disposition is not present. | |
1130 | If nil, image will be displayed if its width is smaller than the width of the | |
1131 | window." | |
1132 | :type '(choice (const nil) integer) | |
1133 | :group 'mh-show) | |
1134 | ||
1135 | (defcustom mh-show-maximum-size 0 | |
1136 | "*Maximum size of message (in bytes) to display automatically. | |
1137 | Provides an opportunity to skip over large messages which may be slow to load. | |
1138 | Use a value of 0 to display all messages automatically regardless of size." | |
1139 | :type 'integer | |
1140 | :group 'mh-show) | |
1141 | ||
1142 | ;; Use goto-addr if it was already loaded (which probably sets this | |
1143 | ;; variable to t), or if this variable is otherwise set to t. | |
1144 | (defcustom mh-show-use-goto-addr-flag (and (boundp 'goto-address-highlight-p) | |
1145 | goto-address-highlight-p) | |
1146 | "*Non-nil means highlight URLs and email addresses. | |
1147 | The `goto-addr' module is used." | |
1148 | :type 'boolean | |
1149 | :group 'mh-show) | |
1150 | ||
924df208 BW |
1151 | (defcustom mh-show-use-xface-flag (>= emacs-major-version 21) |
1152 | "*Non-nil means display face images in `mh-show-mode'. | |
1153 | This flag controls the display of three kinds of faces. | |
1154 | ||
1155 | The first is the traditional X-Face header field. For GNU Emacs 21 | |
1156 | and above, the `uncompface' binary is required to be in the execute | |
1157 | PATH for the display of X-Face images. It can be obtained from | |
1158 | ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z. | |
1159 | ||
1160 | If the XEmacs you are using has internal support for X-Face images, then MH-E | |
1161 | will display X-Face images in XEmacs \"out of the box\". Even if you don't have | |
1162 | X-Face support compiled into your XEmacs, you can still see the X-Face images | |
1163 | in MH-E with the aid of an external x-face package and `uncompface'. It is | |
1164 | available from ftp://ftp.jpl.org/pub/elisp/. Download it, put its files in the | |
1165 | `load-path' and MH-E will invoke it automatically. | |
1166 | ||
1167 | Second, MH-E supports the display of the Gnus-specific Face | |
1168 | header field in GNU Emacs >= 21 and XEmacs. No external packages | |
1169 | are required. More information about the Face header can be found | |
1170 | at: http://quimby.gnus.org/circus/face/. | |
1171 | ||
1172 | Finally, MH-E can also display images from the X-Image-URL header field. The | |
1173 | display of the images requires the `wget' program, available from | |
1174 | http://www.gnu.org/software/wget/wget.html, to fetch the image and the | |
1175 | `convert' program from the ImageMagick suite, available from | |
1176 | http://www.imagemagick.org/. Of the three header fields this is the most | |
1177 | efficient in terms of network usage since the image doesn't need to be | |
1178 | transmitted with every single mail. However its display needs the recipient to | |
1179 | fetch a URL and this can be misused. So it is disabled by default. It can be | |
1180 | enabled by customizing `mh-fetch-x-image-url'. Setting that to ask for | |
1181 | confirmation before fetching seems like a good choice. | |
1182 | ||
1183 | Versions of GNU Emacs prior to 21.1 don't support the display of | |
1184 | inline images. So face images are not displayed in these versions." | |
c3d9274a BW |
1185 | :type 'boolean |
1186 | :group 'mh-show) | |
1187 | ||
1188 | (defcustom mh-summary-height (or (and (fboundp 'frame-height) | |
1189 | (> (frame-height) 24) | |
1190 | (min 10 (/ (frame-height) 6))) | |
1191 | 4) | |
1192 | "*Number of lines in MH-Folder window (including the mode line)." | |
1193 | :type 'integer | |
1194 | :group 'mh-show) | |
1195 | ||
1196 | (defcustom mh-visible-headers nil | |
1197 | "*Contains a regexp specifying the headers to keep when cleaning. | |
1198 | Only used if `mh-clean-message-header-flag' is non-nil. Setting it overrides | |
1199 | the variable `mh-invisible-headers'." | |
1200 | :type '(choice (const nil) regexp) | |
1201 | :group 'mh-show) | |
1202 | ||
1203 | (defcustom mhl-formfile nil | |
1204 | "*Name of format file to be used by mhl to show and print messages. | |
1205 | A value of t means use the default format file. | |
1206 | nil means don't use mhl to format messages when showing; mhl is still used, | |
1207 | with the default format file, to format messages when printing them. | |
1208 | The format used should specify a non-zero value for overflowoffset so | |
1209 | the message continues to conform to RFC 822 and MH-E can parse the headers." | |
1210 | :type '(choice (const nil) (const t) string) | |
1211 | :group 'mh-show) | |
1212 | (put 'mhl-formfile 'info-file "mh-e") | |
1213 | ||
3d7ca223 BW |
1214 | \f |
1215 | ||
c3d9274a BW |
1216 | ;;; Composing messages (:group 'mh-letter) |
1217 | ||
1218 | (defcustom mh-compose-insertion (if (locate-library "mml") 'gnus 'mhn) | |
1219 | "Use either 'gnus or 'mhn to insert MIME message directives in messages." | |
3d7ca223 | 1220 | :type '(choice (const :tag "Use Gnus" gnus) |
c3d9274a BW |
1221 | (const :tag "Use mhn" mhn)) |
1222 | :group 'mh-letter) | |
1223 | ||
1224 | (defcustom mh-compose-letter-function nil | |
1225 | "Invoked when setting up a letter draft. | |
1226 | It is passed three arguments: TO recipients, SUBJECT, and CC recipients." | |
1227 | :type '(choice (const nil) function) | |
1228 | :group 'mh-letter) | |
1229 | ||
1230 | (defcustom mh-delete-yanked-msg-window-flag nil | |
1231 | "*Non-nil means delete any window displaying the message. | |
1232 | Controls window display when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]. | |
1233 | If non-nil, yanking the current message into a draft letter deletes any | |
1234 | windows displaying the message." | |
1235 | :type 'boolean | |
1236 | :group 'mh-letter) | |
1237 | ||
1238 | (defcustom mh-extract-from-attribution-verb "wrote:" | |
1239 | "*Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]." | |
1240 | :type '(choice (const "wrote:") | |
1241 |