Mercurial > emacs
comparison lisp/mh-e/mh-e.el @ 68465:37d03b3298bf
The Great Cleanup
Remove circular dependencies.
mh-e.el now includes few require statements and stands alone. Other
files should need to require mh-e.el, which requires mh-loaddefs.el,
plus variable-only files such as mh-scan.el.
Remove unneeded require statements.
Remove unneeded load statements, or replace them with non-fatal
require statements.
Break out components into their own files that were often spread
between many files. As a result, many functions that are now only used
within a single file no longer need to be autoloaded.
Rearrange and provide consistent headings.
Untabify.
* mh-acros.el: Update commentary to reflect current usage. Add
autoload cookies to all macros.
(mh-require-cl): Merge docstring and comment.
(mh-do-in-xemacs): Fix typo in docstring.
(assoc-string): Move to new file mh-compat.el.
(with-mh-folder-updating, mh-in-show-buffer)
(mh-do-at-event-location, mh-seq-msgs): Move here from mh-utils.el.
(mh-iterate-on-messages-in-region, mh-iterate-on-range): Move here
from mh-seq.el.
* mh-alias.el (mh-address-mail-regexp)
(mh-goto-address-find-address-at-point): Move here from mh-utils.el.
(mh-folder-line-matches-show-buffer-p): Move here from mh-e.el.
* mh-buffers.el: Update descriptive text.
* mh-comp.el (mh-note-repl, mh-note-forw, mh-note-dist): Move to new
file mh-scan.el.
(mh-yank-hooks, mh-to-field-choices, mh-position-on-field)
(mh-letter-menu, mh-letter-mode-help-messages)
(mh-letter-buttons-init-flag, mh-letter-mode)
(mh-font-lock-field-data, mh-letter-header-end)
(mh-auto-fill-for-letter, mh-to-field, mh-to-fcc)
(mh-file-is-vcard-p, mh-insert-signature, mh-check-whom)
(mh-insert-letter, mh-extract-from-attribution, mh-yank-cur-msg)
(mh-filter-out-non-text, mh-insert-prefix-string)
(mh-current-fill-prefix, mh-open-line, mh-complete-word)
(mh-folder-expand-at-point, mh-letter-complete-function-alist)
(mh-letter-complete, mh-letter-complete-or-space)
(mh-letter-confirm-address, mh-letter-header-field-at-point)
(mh-letter-next-header-field-or-indent)
(mh-letter-next-header-field, mh-letter-previous-header-field)
(mh-letter-skipped-header-field-p)
(mh-letter-skip-leading-whitespace-in-header-field)
(mh-hidden-header-keymap)
(mh-letter-toggle-header-field-display-button)
(mh-letter-toggle-header-field-display)
(mh-letter-truncate-header-field, mh-letter-mode-map): Move to new
file mh-letter.el.
(mh-letter-mode-map, mh-sent-from-folder, mh-send-args)
(mh-pgp-support-flag, mh-x-mailer-string)
(mh-letter-header-field-regexp): Move to mh-e.el.
(mh-goto-header-field, mh-goto-header-end)
(mh-extract-from-header-value, mh-beginning-of-word): Move to
mh-utils.el.
(mh-insert-header-separator): Move to mh-comp.el.
(mh-display-completion-list-compat): Move to new file mh-compat.el.
* mh-compat.el: New file.
(assoc-string): Move here from mh-acros.el.
(mh-display-completion-list): Move here from mh-comp.el.
* mh-customize.el: Move content into mh-e.el and remove.
* mh-e.el (mh-folder-mode-map, mh-folder-seq-tool-bar-map)
(mh-folder-tool-bar-map, mh-inc-spool-map, mh-letter-mode-map)
(mh-letter-tool-bar-map, mh-search-mode-map, mh-show-mode-map)
(mh-show-seq-tool-bar-map, mh-show-tool-bar-map): All maps now
declared here so that they can be used in docstrings.
(mh-sent-from-folder, mh-sent-from-msg)
(mh-letter-header-field-regexp, mh-pgp-support-flag)
(mh-x-mailer-string): Move here from mh-comp.el.
(mh-folder-line-matches-show-buffer-p): Move to mh-alias.el.
(mh-thread-scan-line-map, mh-thread-scan-line-map-stack): Move here
from mh-seq.el.
(mh-draft-folder, mh-inbox, mh-user-path, mh-current-folder)
(mh-previous-window-config, mh-seen-list, mh-seq-list)
(mh-show-buffer, mh-showing-mode, mh-globals-hash)
(mh-show-folder-buffer, mh-mail-header-separator)
(mh-unseen-seq, mh-previous-seq, mh-page-to-next-msg-flag)
(mh-signature-separator, mh-signature-separator-regexp)
(mh-list-to-string, mh-list-to-string-1): Move here from mh-utils.el.
(mh-index-max-cmdline-args, mh-xargs, mh-quote-for-shell)
(mh-exec-cmd, mh-exec-cmd-error, mh-exec-cmd-daemon)
(mh-exec-cmd-env-daemon, mh-process-daemon, mh-exec-cmd-quiet)
(mh-exec-cmd-output)
(mh-exchange-point-and-mark-preserving-active-mark)
(mh-exec-lib-cmd-output, mh-handle-process-error): Move here from
deprecated file mh-exec.el.
(mh-path): Move here from deprecated file mh-customize.el.
(mh-sys-path, mh-variants, mh-variant-in-use, mh-progs, mh-lib)
(mh-flists-present-flag, mh-variants, mh-variant-mh-info)
(mh-variant-mu-mh-info, mh-variant-nmh-info, mh-file-command-p)
(mh-variant-set-variant, mh-variant-p, mh-profile-component)
(mh-profile-component-value, mh-defface-compat): Move here from
deprecated file mh-init.el.
(mh-goto-next-button, mh-folder-mime-action)
(mh-folder-toggle-mime-part, mh-folder-inline-mime-part)
(mh-folder-save-mime-part, mh-toggle-mime-buttons): Move to to
mh-mime.el.
(mh-scan-format-mh, mh-scan-format-nmh, mh-note-deleted)
(mh-note-refiled, mh-note-cur, mh-scan-good-msg-regexp)
(mh-scan-deleted-msg-regexp, mh-scan-refiled-msg-regexp)
(mh-scan-valid-regexp, mh-scan-cur-msg-number-regexp)
(mh-scan-date-regexp, mh-scan-rcpt-regexp, mh-scan-body-regexp)
(mh-scan-subject-regexp, mh-scan-sent-to-me-sender-regexp)
(mh-scan-cmd-note-width, mh-scan-destination-width)
(mh-scan-date-width, mh-scan-date-flag-width)
(mh-scan-from-mbox-width, mh-scan-from-mbox-sep-width)
(mh-scan-field-destination-offset)
(mh-scan-field-from-start-offset, mh-scan-field-from-end-offset)
(mh-scan-field-subject-start-offset, mh-scan-format)
(mh-msg-num-width-to-column, mh-set-cmd-note): Move to new file
mh-scan.el.
(mh-partial-folder-mode-line-annotation)
(mh-folder-font-lock-keywords, mh-folder-font-lock-subject)
(mh-generate-sequence-font-lock, mh-last-destination)
(mh-last-destination-write, mh-first-msg-num, mh-last-msg-num)
(mh-rmail, mh-nmail, mh-delete-msg, mh-delete-msg-no-motion)
(mh-execute-commands, mh-first-msg, mh-header-display)
(mh-inc-folder, mh-last-msg, mh-next-undeleted-msg)
(mh-folder-from-address, mh-prompt-for-refile-folder)
(mh-refile-msg, mh-refile-or-write-again, mh-quit, mh-page-msg)
(mh-previous-page, mh-previous-undeleted-msg)
(mh-previous-unread-msg, mh-next-button, mh-prev-button)
(mh-reset-threads-and-narrowing, mh-rescan-folder)
(mh-write-msg-to-file, mh-toggle-showing, mh-undo)
(mh-visit-folder, mh-update-sequences, mh-delete-a-msg)
(mh-refile-a-msg, mh-next-msg, mh-next-unread-msg)
(mh-set-scan-mode, mh-undo-msg, mh-make-folder)
(mh-folder-sequence-menu, mh-folder-message-menu)
(mh-folder-folder-menu, mh-remove-xemacs-horizontal-scrollbar)
(mh-write-file-functions-compat, mh-folder-mode)
(mh-restore-desktop-buffer, mh-scan-folder)
(mh-regenerate-headers, mh-generate-new-cmd-note)
(mh-get-new-mail, mh-make-folder-mode-line, mh-goto-cur-msg)
(mh-process-or-undo-commands, mh-process-commands)
(mh-update-unseen, mh-delete-scan-msgs)
(mh-outstanding-commands-p): Move to new file mh-folder.el.
(mh-mapc, mh-colors-available-p, mh-colors-in-use-p)
(mh-make-local-vars, mh-coalesce-msg-list, mh-greaterp)
(mh-lessp): Move to mh-utils.el.
(mh-parse-flist-output-line, mh-folder-size-folder)
(mh-folder-size-flist, mh-folder-size, mh-add-sequence-notation)
(mh-remove-sequence-notation, mh-remove-cur-notation)
(mh-remove-all-notation, mh-delete-seq-locally)
(mh-read-folder-sequences, mh-read-msg-list)
(mh-notate-user-sequences, mh-internal-seqs, mh-internal-seq)
(mh-valid-seq-p, mh-delete-msg-from-seq, mh-catchup)
(mh-delete-a-msg-from-seq, mh-undefine-sequence)
(mh-define-sequence, mh-seq-containing-msg): Move to mh-seq.el.
(mh-xemacs-flag)
(mh-customize, mh-e, mh-alias, mh-folder, mh-folder-selection)
(mh-identity, mh-inc, mh-junk, mh-letter, mh-ranges)
(mh-scan-line-formats, mh-search, mh-sending-mail, mh-sequences)
(mh-show, mh-speedbar, mh-thread, mh-tool-bar, mh-hooks)
(mh-faces, mh-alias-completion-ignore-case-flag)
(mh-alias-expand-aliases-flag, mh-alias-flash-on-comma)
(mh-alias-insert-file, mh-alias-insertion-location)
(mh-alias-local-users, mh-alias-local-users-prefix)
(mh-alias-passwd-gecos-comma-separator-flag)
(mh-new-messages-folders, mh-ticked-messages-folders)
(mh-large-folder, mh-recenter-summary-flag)
(mh-recursive-folders-flag, mh-sortm-args)
(mh-default-folder-for-message-function, mh-default-folder-list)
(mh-default-folder-must-exist-flag, mh-default-folder-prefix)
(mh-identity-list, mh-auto-fields-list)
(mh-auto-fields-prompt-flag, mh-identity-default)
(mh-identity-handlers, mh-inc-prog, mh-inc-spool-list)
(mh-junk-choice, mh-junk-function-alist, mh-junk-choose)
(mh-junk-background, mh-junk-disposition, mh-junk-program)
(mh-compose-insertion, mh-compose-skipped-header-fields)
(mh-compose-space-does-completion-flag)
(mh-delete-yanked-msg-window-flag)
(mh-extract-from-attribution-verb, mh-ins-buf-prefix)
(mh-letter-complete-function, mh-letter-fill-column)
(mh-mml-method-default, mh-signature-file-name)
(mh-signature-separator-flag, mh-x-face-file, mh-yank-behavior)
(mh-interpret-number-as-range-flag, mh-adaptive-cmd-note-flag)
(mh-scan-format-file-check, mh-scan-format-file)
(mh-adaptive-cmd-note-flag-check, mh-scan-prog)
(mh-search-program, mh-compose-forward-as-mime-flag)
(mh-compose-letter-function, mh-compose-prompt-flag)
(mh-forward-subject-format, mh-insert-x-mailer-flag)
(mh-redist-full-contents-flag, mh-reply-default-reply-to)
(mh-reply-show-message-flag, mh-refile-preserves-sequences-flag)
(mh-tick-seq, mh-update-sequences-after-mh-show-flag)
(mh-bury-show-buffer-flag, mh-clean-message-header-flag)
(mh-decode-mime-flag, mh-display-buttons-for-alternatives-flag)
(mh-display-buttons-for-inline-parts-flag)
(mh-do-not-confirm-flag, mh-fetch-x-image-url)
(mh-graphical-smileys-flag, mh-graphical-emphasis-flag)
(mh-highlight-citation-style)
(mh-invisible-header-fields-internal)
(mh-delay-invisible-header-generation-flag)
(mh-invisible-header-fields, mh-invisible-header-fields-default)
(mh-invisible-header-fields-compiled, mh-invisible-headers)
(mh-lpr-command-format, mh-max-inline-image-height)
(mh-max-inline-image-width, mh-mhl-format-file)
(mh-mime-save-parts-default-directory, mh-print-background-flag)
(mh-show-maximum-size, mh-show-use-goto-addr-flag)
(mh-show-use-xface-flag, mh-store-default-directory)
(mh-summary-height, mh-speed-update-interval)
(mh-show-threads-flag, mh-tool-bar-search-function)
(mh-after-commands-processed-hook, mh-alias-reloaded-hook)
(mh-before-commands-processed-hook, mh-before-quit-hook)
(mh-before-send-letter-hook, mh-delete-msg-hook)
(mh-find-path-hook, mh-folder-mode-hook, mh-forward-hook)
(mh-inc-folder-hook, mh-insert-signature-hook)
(mh-kill-folder-suppress-prompt-hooks, mh-letter-mode-hook)
(mh-mh-to-mime-hook, mh-search-mode-hook, mh-quit-hook)
(mh-refile-msg-hook, mh-show-hook, mh-show-mode-hook)
(mh-unseen-updated-hook, mh-min-colors-defined-flag)
(mh-folder-address, mh-folder-body)
(mh-folder-cur-msg-number, mh-folder-date, mh-folder-deleted)
(mh-folder-followup, mh-folder-msg-number, mh-folder-refiled)
(mh-folder-sent-to-me-hint, mh-folder-sent-to-me-sender)
(mh-folder-subject, mh-folder-tick, mh-folder-to)
(mh-search-folder, mh-letter-header-field, mh-show-cc)
(mh-show-date, mh-show-from, mh-show-header, mh-show-pgg-bad)
(mh-show-pgg-good, mh-show-pgg-unknown, mh-show-signature)
(mh-show-subject, mh-show-to, mh-show-xface, mh-speedbar-folder)
(mh-speedbar-folder-with-unseen-messages)
(mh-speedbar-selected-folder)
(mh-speedbar-selected-folder-with-unseen-messages): Move here from
deprecated file mh-customize.el.
* mh-exec.el: Move content into mh-e.el and remove.
* mh-folder.el: New file. Contains mh-folder-mode from mh-e.el
* mh-funcs.el (mh-note-copied, mh-note-printed): Move to new file
mh-scan.el.
(mh-ephem-message, mh-help, mh-prefix-help): Move to mh-utils.el.
* mh-gnus.el (mm-uu-dissect-text-parts): Add.
(mh-mail-abbrev-make-syntax-table): Move to mh-utils.el and rename to
mail-abbrev-make-syntax-table.
* mh-identity.el (mh-identity-menu): New variable for existing menu.
(mh-identity-make-menu-no-autoload): New alias for
mh-identity-make-menu which can be called from mh-e.el.
(mh-identity-list-set): Move to mh-e.el.
(mh-identity-add-menu): New function
(mh-insert-identity): Add optional argument maybe-insert so that local
variable mh-identity-local does not have to be visible.
(mh-identity-handler-default):
* mh-inc.el (mh-inc-spool-map): Move declaration to mh-e.el (with rest
of keymaps). Update key binding for ? to call mh-help with help
messages in new argument.
(mh-inc-spool-make-no-autoload): New alias for mh-inc-spool-make which
can be called from mh-e.el.
(mh-inc-spool-list-set): Simplify update of mh-inc-spool-map-help.
* mh-init.el: Move content into mh-e.el and remove.
* mh-junk.el: Update requires, untabify, and add mh-autoload cookies.
* mh-letter.el: New file. Contains mh-letter-mode from mh-comp.el.
* mh-limit.el: New file. Contains display limit commands from
mh-mime.el.
* mh-mime.el: Rearrange for consistency with other files.
(mh-buffer-data, mh-mm-inline-media-tests): Move here from
mh-utils.el.
(mh-folder-inline-mime-part, mh-folder-save-mime-part)
(mh-folder-toggle-mime-part, mh-toggle-mime-buttons)
(mh-goto-next-button): Move here from mh-e.el.
* mh-print.el: Rearrange for consistency with other files.
* mh-scan.el: New file. Contains scan line constants and utilities
from XXX, mh-funcs, mh-utils.el.
* mh-search.el: Rearrange for consistency with other files.
(mh-search-mode-map): Drop C-c C-f {dr} bindings since these fields
which don't exist in the saved header. Replace C-c C-f f with C-c C-f
m per mail-mode consistency.
(mh-search-mode): Use mh-set-help instead of setting mh-help-messages.
* mh-seq.el (mh-thread-message, mh-thread-container)
(mh-thread-id-hash, mh-thread-subject-hash, mh-thread-id-table)
(mh-thread-id-index-map, mh-thread-index-id-map)
(mh-thread-scan-line-map, mh-thread-scan-line-map-stack)
(mh-thread-subject-container-hash, mh-thread-duplicates)
(mh-thread-history, mh-thread-body-width)
(mh-thread-find-msg-subject mh-thread-initialize-hash)
(mh-thread-initialize, mh-thread-id-container)
(mh-thread-remove-parent-link, mh-thread-add-link)
(mh-thread-ancestor-p, mh-thread-get-message-container)
(mh-thread-get-message, mh-thread-canonicalize-id)
(mh-thread-prune-subject, mh-thread-container-subject)
(mh-thread-rewind-pruning, mh-thread-prune-containers)
(mh-thread-sort-containers, mh-thread-group-by-subject)
(mh-thread-process-in-reply-to, mh-thread-set-tables)
(mh-thread-update-id-index-maps, mh-thread-generate)
(mh-thread-inc, mh-thread-generate-scan-lines)
(mh-thread-parse-scan-line, mh-thread-update-scan-line-map)
(mh-thread-add-spaces, mh-thread-print-scan-lines)
(mh-thread-folder, mh-toggle-threads, mh-thread-forget-message)
(mh-thread-current-indentation-level, mh-thread-next-sibling)
(mh-thread-previous-sibling, mh-thread-immediate-ancestor)
(mh-thread-ancestor, mh-thread-find-children)
(mh-message-id-regexp, mh-thread-delete, mh-thread-refile): Move to
new file mh-thread.el.
(mh-subject-to-sequence, mh-subject-to-sequence-unthreaded)
(mh-subject-to-sequence-threaded, mh-edit-pick-expr)
(mh-pick-args-list, mh-narrow-to-subject, mh-narrow-to-from)
(mh-narrow-to-cc, mh-narrow-to-to, mh-narrow-to-header-field)
(mh-current-message-header-field, mh-narrow-to-range)
(mh-delete-subject, mh-delete-subject-or-thread): Move to new file
mh-limit.el.
(mh-iterate-on-messages-in-region, mh-iterate-on-range): Move to
mh-acros.el.
(mh-internal-seqs, mh-catchup, mh-delete-msg-from-seq)
(mh-internal-seq, mh-valid-seq-p, mh-seq-containing-msg)
(mh-define-sequence, mh-undefine-sequence)
(mh-delete-a-msg-from-seq, mh-delete-seq-locally)
(mh-folder-size, mh-folder-size-flist, mh-folder-size-folder)
(mh-parse-flist-output-line, mh-read-folder-sequences)
(mh-read-msg-list, mh-notate-user-sequences)
(mh-remove-cur-notation, mh-add-sequence-notation)
(mh-remove-sequence-notation, mh-remove-all-notation): Move here from
mh-e.el.
(mh-make-seq, mh-seq-name, mh-find-seq, mh-seq-to-msgs)
(mh-add-msgs-to-seq, mh-notate): Move here from mh-utils.el.
* mh-show.el: New file. Contains mh-show-mode from mh-utils.el.
* mh-speed.el: Rearrange for consistency with other files.
* mh-thread.el: New file. Contains threading code from mh-seq.el.
* mh-tool-bar.el: New file. Contains tool bar creation code from
deprecated file mh-customize.el.
* mh-utils.el (recursive-load-depth-limit): Remove setting. No longer
needed.
(mh-scan-msg-number-regexp, mh-scan-msg-overflow-regexp)
(mh-scan-msg-format-regexp, mh-scan-msg-format-string)
(mh-scan-msg-search-regexp, mh-cmd-note, mh-note-seq)
(mh-update-scan-format, mh-msg-num-width): Move to new file
mh-scan.el.
(mh-show-buffer-mode-line-buffer-id, mh-letter-header-font-lock)
(mh-header-field-font-lock, mh-header-to-font-lock)
(mh-header-cc-font-lock, mh-header-subject-font-lock)
(mh-show-font-lock-keywords)
(mh-show-font-lock-keywords-with-cite)
(mh-show-font-lock-fontify-region)
(mh-gnus-article-highlight-citation, mh-showing-with-headers)
(mh-start-of-uncleaned-message, mh-invalidate-show-buffer)
(mh-unvisit-file, mh-defun-show-buffer, mh-show-mode-map)
(mh-show-sequence-menu, mh-show-message-menu)
(mh-show-folder-menu, mh-show-mode, mh-show-addr)
(mh-maybe-show, mh-show, mh-show-msg, mh-show-unquote-From)
(mh-msg-folder, mh-display-msg, mh-clean-msg-header): Move to new file
mh-show.el.
(mh-mail-header-separator, mh-signature-separator-regexp)
(mh-signature-separator, mh-globals-hash, mh-user-path)
(mh-draft-folder, mh-unseen-seq, mh-previous-seq, mh-inbox)
(mh-previous-window-config, mh-current-folder mh-show-buffer)
(mh-showing-mode, mh-show-mode-map, mh-show-folder-buffer)
(mh-showing-mode, mh-seq-list, mh-seen-list, mh-summary-height)
(mh-list-to-string, mh-list-to-string-1): Move to mh-e.el.
(mh-buffer-data, mh-mm-inline-media-tests): Move to mh-mime.el.
(mh-address-mail-regexp, mh-goto-address-find-address-at-point): Move
to mh-alias.el.
(mh-letter-font-lock-keywords): Move to new file mh-letter.el.
(mh-folder-filename, mh-msg-count, mh-recenter, mh-msg-filename)
(mh-show-mouse, mh-modify, mh-goto-msg, mh-set-folder-modified-p):
Move to new file mh-folder.el.
(with-mh-folder-updating, mh-in-show-buffer)
(mh-do-at-event-location, mh-seq-msgs): Moved to mh-acros.el.
(mh-make-seq, mh-seq-name, mh-notate, mh-find-seq)
(mh-seq-to-msgs, mh-add-msgs-to-seq, mh-canonicalize-sequence): Moved
to mh-seq.el.
(mh-show-xface-function, mh-uncompface-executable, mh-face-to-png)
(mh-uncompface, mh-icontopbm, mh-face-foreground-compat)
(mh-face-background-compat, mh-face-display-function)
(mh-show-xface, mh-picon-directory-list)
(mh-picon-existing-directory-list)
(mh-picon-cache, mh-picon-image-types)
(mh-picon-set-directory-list, mh-picon-get-image)
(mh-picon-file-contents, mh-picon-generate-path)
(mh-x-image-cache-directory, mh-x-image-scaling-function)
(mh-wget-executable, mh-wget-choice, mh-wget-option)
(mh-x-image-temp-file, mh-x-image-url, mh-x-image-marker)
(mh-x-image-url-cache-file, mh-x-image-scale-with-pnm)
(mh-x-image-scale-with-convert)
(url-unreserved-chars, url-hexify-string)
(mh-x-image-url-cache-canonicalize)
(mh-x-image-set-download-state, mh-x-image-get-download-state)
(mh-x-image-url-fetch-image, mh-x-image-display)
(mh-x-image-scale-and-display, mh-x-image-url-sane-p)
(mh-x-image-url-display): Move to new file mh-xface.el.
(mh-logo-display): Call mh-image-load-path.
(mh-find-path-run, mh-find-path): Move here from deprecated file
mh-init.el.
(mh-help-messages): Now an alist of modes to an alist of messages.
(mh-set-help): New function used to set mh-help-messages
(mh-help): Adjust for new format of mh-help-messages. Add
help-messages argument.
(mh-prefix-help): Refactor to use mh-help.
(mh-coalesce-msg-list, mh-greaterp, mh-lessp): Move here from mh-e.el.
(mh-clear-sub-folders-cache): New function added to avoid exposing
mh-sub-folders-cache variable.
* mh-xface.el: New file. Contains X-Face and Face header field display
routines from mh-utils.el.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Sun, 29 Jan 2006 19:34:57 +0000 |
parents | 0c77c0b9a620 |
children | fef251da6e07 |
comparison
equal
deleted
inserted
replaced
68464:79464a6167f5 | 68465:37d03b3298bf |
---|---|
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
27 ;; Boston, MA 02110-1301, USA. | 27 ;; Boston, MA 02110-1301, USA. |
28 | 28 |
29 ;;; Commentary: | 29 ;;; Commentary: |
30 | 30 |
31 ;; How to Use: | 31 ;; How to use: |
32 ;; M-x mh-rmail to read mail. Type C-h m there for a list of commands. | 32 ;; M-x mh-rmail to read mail. Type C-h m there for a list of commands. |
33 ;; C-u M-x mh-rmail to visit any folder. | 33 ;; C-u M-x mh-rmail to visit any folder. |
34 ;; M-x mh-smail to send mail. From within the mail reader, "m" works, too. | 34 ;; M-x mh-smail to send mail. From within the mail reader, "s" works, too. |
35 | 35 |
36 ;; Your .emacs might benefit from these bindings: | 36 ;; Your .emacs might benefit from these bindings: |
37 ;; (global-set-key "\C-cr" 'mh-rmail) | 37 ;; (global-set-key "\C-cr" 'mh-rmail) |
38 ;; (global-set-key "\C-xm" 'mh-smail) | 38 ;; (global-set-key "\C-xm" 'mh-smail) |
39 ;; (global-set-key "\C-x4m" 'mh-smail-other-window) | 39 ;; (global-set-key "\C-x4m" 'mh-smail-other-window) |
40 | 40 |
41 ;; If Emacs can't find mh-rmail or mh-smail, add the following to ~/.emacs: | |
42 ;; (require 'mh-autoloads) | |
43 | |
44 ;; If you want to customize MH-E before explicitly loading it, add this: | |
45 ;; (require 'mh-cus-load) | |
46 | |
41 ;; MH (Message Handler) is a powerful mail reader. | 47 ;; MH (Message Handler) is a powerful mail reader. |
42 | 48 |
43 ;; The MH newsgroup is comp.mail.mh; the mailing list is mh-users@ics.uci.edu | 49 ;; The MH newsgroup is comp.mail.mh; the mailing list is mh-users@ics.uci.edu |
44 ;; (send to mh-users-request to be added). See the monthly Frequently Asked | 50 ;; (send to mh-users-request to be added). See the monthly Frequently Asked |
45 ;; Questions posting there for information on getting MH and MH-E: | 51 ;; Questions posting there for information on getting MH and MH-E: |
57 | 63 |
58 ;; Mailing Lists: | 64 ;; Mailing Lists: |
59 ;; mh-e-users@lists.sourceforge.net | 65 ;; mh-e-users@lists.sourceforge.net |
60 ;; mh-e-announce@lists.sourceforge.net | 66 ;; mh-e-announce@lists.sourceforge.net |
61 ;; mh-e-devel@lists.sourceforge.net | 67 ;; mh-e-devel@lists.sourceforge.net |
62 ;; | 68 |
63 ;; Subscribe by sending a "subscribe" message to | 69 ;; Subscribe by sending a "subscribe" message to |
64 ;; <list>-request@lists.sourceforge.net, or by using the web interface at | 70 ;; <list>-request@lists.sourceforge.net, or by using the web interface at |
65 ;; https://sourceforge.net/mail/?group_id=13357 | 71 ;; https://sourceforge.net/mail/?group_id=13357 |
66 | 72 |
67 ;; Bug Reports: | 73 ;; Bug Reports: |
68 ;; https://sourceforge.net/tracker/?group_id=13357&atid=113357 | 74 ;; https://sourceforge.net/tracker/?group_id=13357&atid=113357 |
69 ;; Include the output of M-x mh-version in any bug report. | 75 ;; Include the output of M-x mh-version in the bug report unless |
76 ;; you're 110% sure we won't ask for it. | |
70 | 77 |
71 ;; Feature Requests: | 78 ;; Feature Requests: |
72 ;; https://sourceforge.net/tracker/?atid=363357&group_id=13357&func=browse | 79 ;; https://sourceforge.net/tracker/?group_id=13357&atid=363357 |
73 | 80 |
74 ;; Support: | 81 ;; Support: |
75 ;; https://sourceforge.net/tracker/?group_id=13357&atid=213357 | 82 ;; https://sourceforge.net/tracker/?group_id=13357&atid=213357 |
76 | 83 |
77 ;;; Change Log: | 84 ;;; Change Log: |
83 ;; Maintenance picked up by Bill Wohler and the | 90 ;; Maintenance picked up by Bill Wohler and the |
84 ;; SourceForge Crew <http://mh-e.sourceforge.net/>, 2001. | 91 ;; SourceForge Crew <http://mh-e.sourceforge.net/>, 2001. |
85 | 92 |
86 ;;; Code: | 93 ;;; Code: |
87 | 94 |
88 ;;(message "> mh-e") | 95 ;; Provide functions to the rest of MH-E. However, mh-e.el must not |
89 (provide 'mh-e) | 96 ;; use any definitions in files that require mh-e from mh-loaddefs, |
90 | 97 ;; for if it does it will introduce a require loop. |
91 (eval-when-compile (require 'mh-acros)) | 98 (require 'mh-loaddefs) |
99 | |
92 (mh-require-cl) | 100 (mh-require-cl) |
93 | 101 |
94 (require 'easymenu) | 102 (eval-and-compile |
95 (require 'gnus-util) | 103 (defvar mh-xemacs-flag (featurep 'xemacs) |
104 "Non-nil means the current Emacs is XEmacs.")) | |
105 (mh-do-in-xemacs | |
106 (require 'mh-xemacs)) | |
107 | |
96 (require 'mh-buffers) | 108 (require 'mh-buffers) |
97 (require 'mh-seq) | 109 (require 'mh-compat) |
98 (require 'mh-utils) | |
99 ;;(message "< mh-e") | |
100 | |
101 (defconst mh-version "7.85+cvs" "Version number of MH-E.") | |
102 | |
103 (defvar mh-partial-folder-mode-line-annotation "select" | |
104 "Annotation when displaying part of a folder. | |
105 The string is displayed after the folder's name. nil for no | |
106 annotation.") | |
107 | 110 |
108 | 111 |
109 | 112 |
110 ;;; Scan Line Formats | 113 ;;; Global Variables |
111 | 114 |
112 ;; Parameterize MH-E to work with different scan formats. The defaults work | 115 ;; Try to keep variables local to a single file. Provide accessors if |
113 ;; with the standard MH scan listings, in which the first 4 characters on | 116 ;; variables are shared. Use this section as a last resort. |
114 ;; the line are the message number, followed by two places for notations. | 117 |
115 | 118 (defconst mh-version "7.85+sans-entropy" "Version number of MH-E.") |
116 ;; The following scan formats are passed to the scan program if the setting of | 119 |
117 ;; `mh-scan-format-file' is t. They are identical except the later one makes | 120 ;; Variants |
118 ;; use of the nmh `decode' function to decode RFC 2047 encodings. If you just | 121 |
119 ;; want to change the column of the notations, use the `mh-set-cmd-note' | 122 (defvar mh-sys-path |
120 ;; function. | 123 '("/usr/local/nmh/bin" ; nmh default |
121 | 124 "/usr/local/bin/mh/" |
122 (defvar mh-scan-format-mh | 125 "/usr/local/mh/" |
123 (concat | 126 "/usr/bin/mh/" ; Ultrix 4.2, Linux |
124 "%4(msg)" | 127 "/usr/new/mh/" ; Ultrix < 4.2 |
125 "%<(cur)+%| %>" | 128 "/usr/contrib/mh/bin/" ; BSDI |
126 "%<{replied}-" | 129 "/usr/pkg/bin/" ; NetBSD |
127 "%?(nonnull(comp{to}))%<(mymbox{to})t%>" | 130 "/usr/local/bin/" |
128 "%?(nonnull(comp{cc}))%<(mymbox{cc})c%>" | 131 "/usr/local/bin/mu-mh/" ; GNU mailutils - default |
129 "%?(nonnull(comp{bcc}))%<(mymbox{bcc})b%>" | 132 "/usr/bin/mu-mh/") ; GNU mailutils - packaged |
130 "%?(nonnull(comp{newsgroups}))n%>" | 133 "List of directories to search for variants of the MH variant. |
131 "%<(zero) %>" | 134 The list `exec-path' is searched in addition to this list. |
132 "%02(mon{date})/%02(mday{date})%<{date} %|*%>" | 135 There's no need for users to modify this list. Instead add extra |
133 "%<(mymbox{from})%<{to}To:%14(friendly{to})%>%>" | 136 directories to the customizable variable `mh-path'.") |
134 "%<(zero)%17(friendly{from})%> " | 137 |
135 "%{subject}%<{body}<<%{body}%>") | 138 (defvar mh-variants nil |
136 "*Scan format string for MH. | 139 "List describing known MH variants. |
137 This string is passed to the scan program via the -format | 140 Do not access this variable directly as it may not have yet been initialized. |
138 argument. This format is identical to the default except that | 141 Use the function `mh-variants' instead.") |
139 additional hints for fontification have been added to the fifth | 142 |
140 column (remember that in Emacs, the first column is 0). | 143 (defvar mh-variant-in-use nil |
141 | 144 "The MH variant currently in use; a string with variant and version number. |
142 The values of the fifth column, in priority order, are: \"-\" if | 145 This differs from `mh-variant' when the latter is set to |
143 the message has been replied to, t if an address on the To: line | 146 \"autodetect\".") |
144 matches one of the mailboxes of the current user, \"c\" if the Cc: | 147 |
145 line matches, \"b\" if the Bcc: line matches, and \"n\" if a | 148 (defvar mh-progs nil |
146 non-empty Newsgroups: header is present.") | 149 "Directory containing MH commands, such as inc, repl, and rmm.") |
147 | 150 |
148 (defvar mh-scan-format-nmh | 151 ;;;###autoload |
149 (concat | 152 (put 'mh-progs 'risky-local-variable t) |
150 "%4(msg)" | 153 |
151 "%<(cur)+%| %>" | 154 (defvar mh-lib nil |
152 "%<{replied}-" | 155 "Directory containing the MH library. |
153 "%?(nonnull(comp{to}))%<(mymbox{to})t%>" | 156 This directory contains, among other things, the components file.") |
154 "%?(nonnull(comp{cc}))%<(mymbox{cc})c%>" | 157 |
155 "%?(nonnull(comp{bcc}))%<(mymbox{bcc})b%>" | 158 ;;;###autoload |
156 "%?(nonnull(comp{newsgroups}))n%>" | 159 (put 'mh-lib 'risky-local-variable t) |
157 "%<(zero) %>" | 160 |
158 "%02(mon{date})/%02(mday{date})%<{date} %|*%>" | 161 (defvar mh-lib-progs nil |
159 "%<(mymbox{from})%<{to}To:%14(decode(friendly{to}))%>%>" | 162 "Directory containing MH helper programs. |
160 "%<(zero)%17(decode(friendly{from}))%> " | 163 This directory contains, among other things, the mhl program.") |
161 "%(decode{subject})%<{body}<<%{body}%>") | 164 |
162 "*Scan format string for nmh. | 165 ;;;###autoload |
163 This string is passed to the scan program via the -format arg. | 166 (put 'mh-lib-progs 'risky-local-variable t) |
164 This format is identical to the default except that additional | 167 |
165 hints for fontification have been added to the fifth | 168 ;; Profile Components |
166 column (remember that in Emacs, the first column is 0). | 169 |
167 | 170 (defvar mh-draft-folder nil |
168 The values of the fifth column, in priority order, are: \"-\" if | 171 "Cached value of the \"Draft-Folder:\" MH profile component. |
169 the message has been replied to, t if an address on the To: field | 172 Name of folder containing draft messages. |
170 matches one of the mailboxes of the current user, \"c\" if the Cc: | 173 Nil means do not use a draft folder.") |
171 field matches, \"b\" if the Bcc: field matches, and \"n\" if a | 174 |
172 non-empty Newsgroups: field is present.") | 175 (defvar mh-inbox nil |
173 | 176 "Cached value of the \"Inbox:\" MH profile component. |
174 (defvar mh-note-deleted ?D | 177 Set to \"+inbox\" if no such component. |
175 "Messages that have been deleted are marked by this character. | 178 Name of the Inbox folder.") |
176 See also `mh-scan-deleted-msg-regexp'.") | 179 |
177 | 180 (defvar mh-user-path nil |
178 (defvar mh-note-refiled ?^ | 181 "Cached value of the \"Path:\" MH profile component. |
179 "Messages that have been refiled are marked by this character. | 182 User's mail folder directory.") |
180 See also `mh-scan-refiled-msg-regexp'.") | 183 |
181 | 184 ;; Maps declared here so that they can be used in docstrings. |
182 (defvar mh-note-cur ?+ | |
183 "The current message (in MH, not in MH-E) is marked by this character. | |
184 See also `mh-scan-cur-msg-number-regexp'.") | |
185 | |
186 (defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^D^0-9]" | |
187 "This regular expression matches \"good\" messages. | |
188 | |
189 It must match from the beginning of the line. Note that the | |
190 default setting of `mh-folder-font-lock-keywords' expects this | |
191 expression to contain at least one parenthesized expression which | |
192 matches the message number as in the default of | |
193 | |
194 \"^\\\\( *[0-9]+\\\\)[^D^0-9]\". | |
195 | |
196 This expression includes the leading space within the parenthesis | |
197 since it looks better to highlight it as well. The highlighting | |
198 is done with the face `mh-folder-msg-number'. This regular | |
199 expression should be correct as it is needed by non-fontification | |
200 functions.") | |
201 | |
202 (defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D" | |
203 "This regular expression matches deleted messages. | |
204 | |
205 It must match from the beginning of the line. Note that the | |
206 default setting of `mh-folder-font-lock-keywords' expects this | |
207 expression to contain at least one parenthesized expression which | |
208 matches the message number as in the default of | |
209 | |
210 \"^\\\\( *[0-9]+\\\\)D\". | |
211 | |
212 This expression includes the leading space within the parenthesis | |
213 since it looks better to highlight it as well. The highlighting | |
214 is done with the face `mh-folder-deleted'. This regular | |
215 expression should be correct as it is needed by non-fontification | |
216 functions. See also `mh-note-deleted'.") | |
217 | |
218 (defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^" | |
219 "This regular expression matches refiled messages. | |
220 | |
221 It must match from the beginning of the line. Note that the | |
222 default setting of `mh-folder-font-lock-keywords' expects this | |
223 expression to contain at least one parenthesized expression which | |
224 matches the message number as in the default of | |
225 | |
226 \"^\\\\( *[0-9]+\\\\)\\\\^\". | |
227 | |
228 This expression includes the leading space within the parenthesis | |
229 since it looks better to highlight it as well. The highlighting | |
230 is done with the face `mh-folder-refiled'. This regular | |
231 expression should be correct as it is needed by non-fontification | |
232 functions. See also `mh-note-refiled'.") | |
233 | |
234 (defvar mh-scan-valid-regexp "^ *[0-9]" | |
235 "This regular expression describes a valid scan line. | |
236 | |
237 This is used to eliminate error messages that are occasionally | |
238 produced by \"inc\".") | |
239 | |
240 (defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*" | |
241 "This regular expression matches the current message. | |
242 | |
243 It must match from the beginning of the line. Note that the | |
244 default setting of `mh-folder-font-lock-keywords' expects this | |
245 expression to contain at least one parenthesized expression which | |
246 matches the message number as in the default of | |
247 | |
248 \"^\\\\( *[0-9]+\\\\+\\\\).*\". | |
249 | |
250 This expression includes the leading space and current message | |
251 marker \"+\" within the parenthesis since it looks better to | |
252 highlight these items as well. The highlighting is done with the | |
253 face `mh-folder-cur-msg-number'. This regular expression should | |
254 be correct as it is needed by non-fontification functions. See | |
255 also `mh-note-cur'.") | |
256 | |
257 (defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)" | |
258 "This regular expression matches a valid date. | |
259 | |
260 It must not be anchored to the beginning or the end of the line. | |
261 Note that the default setting of `mh-folder-font-lock-keywords' | |
262 expects this expression to contain only one parenthesized | |
263 expression which matches the date field as in the default of | |
264 \"\\\\([0-9][0-9]/[0-9][0-9]\\\\)\"}. If this regular expression | |
265 is not correct, the date will not be highlighted with the face | |
266 `mh-folder-date'.") | |
267 | |
268 (defvar mh-scan-rcpt-regexp "\\(To:\\)\\(..............\\)" | |
269 "This regular expression specifies the recipient in messages you sent. | |
270 | |
271 Note that the default setting of `mh-folder-font-lock-keywords' | |
272 expects this expression to contain two parenthesized expressions. | |
273 The first is expected to match the \"To:\" that the default scan | |
274 format file generates. The second is expected to match the | |
275 recipient's name as in the default of | |
276 \"\\\\(To:\\\\)\\\\(..............\\\\)\". If this regular | |
277 expression is not correct, the \"To:\" string will not be | |
278 highlighted with the face `mh-folder-to' and the recipient will | |
279 not be highlighted with the face `mh-folder-address'") | |
280 | |
281 (defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)" | |
282 "This regular expression matches the message body fragment. | |
283 | |
284 Note that the default setting of `mh-folder-font-lock-keywords' | |
285 expects this expression to contain at least one parenthesized | |
286 expression which matches the body text as in the default of | |
287 \"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this regular expression is | |
288 not correct, the body fragment will not be highlighted with the | |
289 face `mh-folder-body'.") | |
290 | |
291 (defvar mh-scan-subject-regexp | |
292 "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)" | |
293 "This regular expression matches the subject. | |
294 | |
295 It must match from the beginning of the line. Note that the | |
296 default setting of `mh-folder-font-lock-keywords' expects this | |
297 expression to contain at least three parenthesized expressions. | |
298 The first is expected to match the \"Re:\" string, if any, and is | |
299 highlighted with the face `mh-folder-followup'. The second | |
300 matches an optional bracketed number after \"Re:\", such as in | |
301 \"Re[2]:\" (and is thus a sub-expression of the first expression) | |
302 and the third is expected to match the subject line itself which | |
303 is highlighted with the face `mh-folder-subject'. For example, | |
304 the default (broken on multiple lines for readability) is | |
305 | |
306 ^ *[0-9]+........[ ]*................... | |
307 \\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)* | |
308 \\\\([^<\\n]*\\\\) | |
309 | |
310 This regular expression should be correct as it is needed by | |
311 non-fontification functions.") | |
312 | |
313 (defvar mh-scan-sent-to-me-sender-regexp | |
314 "^ *[0-9]+.\\([bct]\\).....[ ]*\\(..................\\)" | |
315 "This regular expression matches messages sent to us. | |
316 | |
317 Note that the default setting of `mh-folder-font-lock-keywords' | |
318 expects this expression to contain at least two parenthesized | |
319 expressions. The first should match the fontification hint (see | |
320 `mh-scan-format-nmh') and the second should match the user name | |
321 as in the default of | |
322 | |
323 ^ *[0-9]+.\\\\([bct]\\\\).....[ ]*\\\\(..................\\\\) | |
324 | |
325 If this regular expression is not correct, the notation hints | |
326 will not be highlighted with the face | |
327 `mh-mh-folder-sent-to-me-hint' and the sender will not be | |
328 highlighted with the face `mh-folder-sent-to-me-sender'.") | |
329 | |
330 | |
331 | |
332 (defvar mh-folder-font-lock-keywords | |
333 (list | |
334 ;; Folders when displaying index buffer | |
335 (list "^\\+.*" | |
336 '(0 'mh-search-folder)) | |
337 ;; Marked for deletion | |
338 (list (concat mh-scan-deleted-msg-regexp ".*") | |
339 '(0 'mh-folder-deleted)) | |
340 ;; Marked for refile | |
341 (list (concat mh-scan-refiled-msg-regexp ".*") | |
342 '(0 'mh-folder-refiled)) | |
343 ;; After subject | |
344 (list mh-scan-body-regexp | |
345 '(1 'mh-folder-body nil t)) | |
346 ;; Subject | |
347 '(mh-folder-font-lock-subject | |
348 (1 'mh-folder-followup append t) | |
349 (2 'mh-folder-subject append t)) | |
350 ;; Current message number | |
351 (list mh-scan-cur-msg-number-regexp | |
352 '(1 'mh-folder-cur-msg-number)) | |
353 ;; Message number | |
354 (list mh-scan-good-msg-regexp | |
355 '(1 'mh-folder-msg-number)) | |
356 ;; Date | |
357 (list mh-scan-date-regexp | |
358 '(1 'mh-folder-date)) | |
359 ;; Messages from me (To:) | |
360 (list mh-scan-rcpt-regexp | |
361 '(1 'mh-folder-to) | |
362 '(2 'mh-folder-address)) | |
363 ;; Messages to me | |
364 (list mh-scan-sent-to-me-sender-regexp | |
365 '(1 'mh-folder-sent-to-me-hint) | |
366 '(2 'mh-folder-sent-to-me-sender))) | |
367 "Keywords (regular expressions) used to fontify the MH-Folder buffer.") | |
368 | |
369 (defvar mh-scan-cmd-note-width 1 | |
370 "Number of columns consumed by the cmd-note field in `mh-scan-format'. | |
371 | |
372 This column will have one of the values: \" \", \"D\", \"^\", \"+\" and | |
373 where \" \" is the default value, | |
374 | |
375 \"D\" is the `mh-note-deleted' character, | |
376 \"^\" is the `mh-note-refiled' character, and | |
377 \"+\" is the `mh-note-cur' character.") | |
378 | |
379 (defvar mh-scan-destination-width 1 | |
380 "Number of columns consumed by the destination field in `mh-scan-format'. | |
381 | |
382 This column will have one of \" \", \"%\", \"-\", \"t\", \"c\", \"b\", or \"n\" | |
383 in it. | |
384 | |
385 \" \" blank space is the default character. | |
386 \"%\" indicates that the message in in a named MH sequence. | |
387 \"-\" indicates that the message has been annotated with a replied field. | |
388 \"t\" indicates that the message contains mymbox in the To: field. | |
389 \"c\" indicates that the message contains mymbox in the Cc: field. | |
390 \"b\" indicates that the message contains mymbox in the Bcc: field. | |
391 \"n\" indicates that the message contains a Newsgroups: field.") | |
392 | |
393 (defvar mh-scan-date-width 5 | |
394 "Number of columns consumed by the date field in `mh-scan-format'. | |
395 This column will typically be of the form mm/dd.") | |
396 | |
397 (defvar mh-scan-date-flag-width 1 | |
398 "Number of columns consumed to flag (in)valid dates in `mh-scan-format'. | |
399 This column will have \" \" for valid and \"*\" for invalid or | |
400 missing dates.") | |
401 | |
402 (defvar mh-scan-from-mbox-width 17 | |
403 "Number of columns consumed with the \"From:\" line in `mh-scan-format'. | |
404 This column will have a friendly name or e-mail address of the | |
405 originator, or a \"To: address\" for outgoing e-mail messages.") | |
406 | |
407 (defvar mh-scan-from-mbox-sep-width 2 | |
408 "Number of columns consumed by whitespace after from-mbox in `mh-scan-format'. | |
409 This column will only ever have spaces in it.") | |
410 | |
411 (defvar mh-scan-field-destination-offset | |
412 (+ mh-scan-cmd-note-width) | |
413 "The offset from the `mh-cmd-note' for the destination column.") | |
414 | |
415 (defvar mh-scan-field-from-start-offset | |
416 (+ mh-scan-cmd-note-width | |
417 mh-scan-destination-width | |
418 mh-scan-date-width | |
419 mh-scan-date-flag-width) | |
420 "The offset from the `mh-cmd-note' to find the start of \"From:\" address.") | |
421 | |
422 (defvar mh-scan-field-from-end-offset | |
423 (+ mh-scan-field-from-start-offset mh-scan-from-mbox-width) | |
424 "The offset from the `mh-cmd-note' to find the end of \"From:\" address.") | |
425 | |
426 (defvar mh-scan-field-subject-start-offset | |
427 (+ mh-scan-cmd-note-width | |
428 mh-scan-destination-width | |
429 mh-scan-date-width | |
430 mh-scan-date-flag-width | |
431 mh-scan-from-mbox-width | |
432 mh-scan-from-mbox-sep-width) | |
433 "The offset from the `mh-cmd-note' to find the start of the subject.") | |
434 | |
435 (defun mh-folder-font-lock-subject (limit) | |
436 "Return MH-E scan subject strings to font-lock between point and LIMIT." | |
437 (if (not (re-search-forward mh-scan-subject-regexp limit t)) | |
438 nil | |
439 (if (match-beginning 1) | |
440 (set-match-data (list (match-beginning 1) (match-end 3) | |
441 (match-beginning 1) (match-end 3) nil nil)) | |
442 (set-match-data (list (match-beginning 3) (match-end 3) | |
443 nil nil (match-beginning 3) (match-end 3)))) | |
444 t)) | |
445 | |
446 | |
447 | |
448 ;; Fontifify unseen mesages in bold. | |
449 | |
450 (defmacro mh-generate-sequence-font-lock (seq prefix face) | |
451 "Generate the appropriate code to fontify messages in SEQ. | |
452 PREFIX is used to generate unique names for the variables and | |
453 functions defined by the macro. So a different prefix should be | |
454 provided for every invocation. | |
455 FACE is the font-lock face used to display the matching scan lines." | |
456 (let ((cache (intern (format "mh-folder-%s-seq-cache" prefix))) | |
457 (func (intern (format "mh-folder-font-lock-%s" prefix)))) | |
458 `(progn | |
459 (defvar ,cache nil | |
460 "Internal cache variable used for font-lock in MH-E. | |
461 Should only be non-nil through font-lock stepping, and nil once | |
462 font-lock is done highlighting.") | |
463 (make-variable-buffer-local ',cache) | |
464 | |
465 (defun ,func (limit) | |
466 "Return unseen message lines to font-lock between point and LIMIT." | |
467 (if (not ,cache) (setq ,cache (mh-seq-msgs (mh-find-seq ,seq)))) | |
468 (let ((cur-msg (mh-get-msg-num nil))) | |
469 (cond ((not ,cache) | |
470 nil) | |
471 ((>= (point) limit) ;Presumably at end of buffer | |
472 (setq ,cache nil) | |
473 nil) | |
474 ((member cur-msg ,cache) | |
475 (let ((bpoint (progn (beginning-of-line)(point))) | |
476 (epoint (progn (forward-line 1)(point)))) | |
477 (if (<= limit (point)) (setq ,cache nil)) | |
478 (set-match-data (list bpoint epoint bpoint epoint)) | |
479 t)) | |
480 (t | |
481 ;; move forward one line at a time, checking each message | |
482 (while (and (= 0 (forward-line 1)) | |
483 (> limit (point)) | |
484 (not (member (mh-get-msg-num nil) ,cache)))) | |
485 ;; Examine how we must have exited the loop... | |
486 (let ((cur-msg (mh-get-msg-num nil))) | |
487 (cond ((or (<= limit (point)) | |
488 (not (member cur-msg ,cache))) | |
489 (setq ,cache nil) | |
490 nil) | |
491 ((member cur-msg ,cache) | |
492 (let ((bpoint (progn (beginning-of-line) (point))) | |
493 (epoint (progn (forward-line 1) (point)))) | |
494 (if (<= limit (point)) (setq ,cache nil)) | |
495 (set-match-data | |
496 (list bpoint epoint bpoint epoint)) | |
497 t)))))))) | |
498 | |
499 (setq mh-folder-font-lock-keywords | |
500 (append mh-folder-font-lock-keywords | |
501 (list (list ',func (list 1 '',face 'prepend t)))))))) | |
502 | |
503 (mh-generate-sequence-font-lock mh-unseen-seq unseen bold) | |
504 (mh-generate-sequence-font-lock mh-tick-seq tick mh-folder-tick) | |
505 | |
506 | |
507 | |
508 ;;; Internal variables: | |
509 | |
510 (defvar mh-last-destination nil | |
511 "Destination of last refile or write command.") | |
512 | |
513 (defvar mh-last-destination-folder nil | |
514 "Destination of last refile command.") | |
515 | |
516 (defvar mh-last-destination-write nil | |
517 "Destination of last write command.") | |
518 | 185 |
519 (defvar mh-folder-mode-map (make-keymap) | 186 (defvar mh-folder-mode-map (make-keymap) |
520 "Keymap for MH folders.") | 187 "Keymap for MH-Folder mode.") |
188 | |
189 (defvar mh-folder-seq-tool-bar-map nil | |
190 "Keymap for MH-Folder tool bar.") | |
191 | |
192 (defvar mh-folder-tool-bar-map nil | |
193 "Keymap for MH-Folder tool bar.") | |
194 | |
195 (defvar mh-inc-spool-map (make-sparse-keymap) | |
196 "Keymap for MH-E's mh-inc-spool commands.") | |
197 | |
198 (defvar mh-letter-mode-map (copy-keymap text-mode-map) | |
199 "Keymap for MH-Letter mode.") | |
200 | |
201 (defvar mh-letter-tool-bar-map nil | |
202 "Keymap for MH-Letter tool bar.") | |
203 | |
204 (defvar mh-search-mode-map (make-sparse-keymap) | |
205 "Keymap for MH-Search mode.") | |
206 | |
207 (defvar mh-show-mode-map (make-sparse-keymap) | |
208 "Keymap MH-Show mode.") | |
209 | |
210 (defvar mh-show-seq-tool-bar-map nil | |
211 "Keymap for MH-Show tool bar.") | |
212 | |
213 (defvar mh-show-tool-bar-map nil | |
214 "Keymap for MH-Show tool bar.") | |
215 | |
216 ;; MH-Folder Locals (alphabetical) | |
521 | 217 |
522 (defvar mh-arrow-marker nil | 218 (defvar mh-arrow-marker nil |
523 "Marker for arrow display in fringe.") | 219 "Marker for arrow display in fringe.") |
220 | |
221 (defvar mh-colors-available-flag nil | |
222 "Non-nil means colors are available.") | |
223 | |
224 (defvar mh-current-folder nil | |
225 "Name of current folder, a string.") | |
524 | 226 |
525 (defvar mh-delete-list nil | 227 (defvar mh-delete-list nil |
526 "List of message numbers to delete. | 228 "List of message numbers to delete. |
527 This variable can be used by | 229 This variable can be used by |
528 `mh-before-commands-processed-hook'.") | 230 `mh-before-commands-processed-hook'.") |
529 | 231 |
232 (defvar mh-folder-view-stack nil | |
233 "Stack of previous folder views.") | |
234 | |
235 (defvar mh-index-data nil | |
236 "Info about index search results.") | |
237 | |
238 (defvar mh-index-previous-search nil) | |
239 | |
240 (defvar mh-index-msg-checksum-map nil) | |
241 | |
242 (defvar mh-index-checksum-origin-map nil) | |
243 | |
244 (defvar mh-index-sequence-search-flag nil) | |
245 | |
246 (defvar mh-mode-line-annotation nil | |
247 "Message range displayed in buffer.") | |
248 | |
249 (defvar mh-next-direction 'forward | |
250 "Direction to move to next message.") | |
251 | |
252 (defvar mh-previous-window-config nil | |
253 "Window configuration before MH-E command.") | |
254 | |
530 (defvar mh-refile-list nil | 255 (defvar mh-refile-list nil |
531 "List of folder names in `mh-seq-list'. | 256 "List of folder names in `mh-seq-list'. |
532 This variable can be used by | 257 This variable can be used by |
533 `mh-before-commands-processed-hook'.") | 258 `mh-before-commands-processed-hook'.") |
259 | |
260 (defvar mh-seen-list nil | |
261 "List of displayed messages to be removed from the \"Unseen\" sequence.") | |
262 | |
263 (defvar mh-seq-list nil | |
264 "Alist of this folder's sequences. | |
265 Elements have the form (SEQUENCE . MESSAGES).") | |
266 | |
267 (defvar mh-sequence-notation-history nil | |
268 "Remember original notation that is overwritten by `mh-note-seq'.") | |
269 | |
270 (defvar mh-show-buffer nil | |
271 "Buffer that displays message for this folder.") | |
272 | |
273 (defvar mh-showing-mode nil | |
274 "If non-nil, show the message in a separate window.") | |
275 | |
276 (defvar mh-view-ops nil | |
277 "Stack of operations that change the folder view. | |
278 These operations include narrowing or threading.") | |
279 | |
280 ;; MH-Show Locals (alphabetical) | |
281 | |
282 (defvar mh-globals-hash (make-hash-table) | |
283 "Keeps track of MIME data on a per buffer basis.") | |
284 | |
285 (defvar mh-show-folder-buffer nil | |
286 "Keeps track of folder whose message is being displayed.") | |
287 | |
288 ;; MH-Letter Locals | |
534 | 289 |
535 (defvar mh-folders-changed nil | 290 (defvar mh-folders-changed nil |
536 "Lists which folders were affected by deletes and refiles. | 291 "Lists which folders were affected by deletes and refiles. |
537 This list will always include the current folder | 292 This list will always include the current folder |
538 `mh-current-folder'. This variable can be used by | 293 `mh-current-folder'. This variable can be used by |
539 `mh-after-commands-processed-hook'.") | 294 `mh-after-commands-processed-hook'.") |
540 | 295 |
541 (defvar mh-next-direction 'forward | 296 (defvar mh-mail-header-separator "--------" |
542 "Direction to move to next message.") | 297 "*Line used by MH to separate headers from text in messages being composed. |
543 | 298 |
544 (defvar mh-view-ops () | 299 This variable should not be used directly in programs. Programs |
545 "Stack of operations that change the folder view. | 300 should use `mail-header-separator' instead. |
546 These operations include narrowing or threading.") | 301 `mail-header-separator' is initialized to |
547 | 302 `mh-mail-header-separator' in `mh-letter-mode'; in other |
548 (defvar mh-folder-view-stack () | 303 contexts, you may have to perform this initialization yourself. |
549 "Stack of previous folder views.") | 304 |
550 | 305 Do not make this a regular expression as it may be the argument |
551 (defvar mh-index-data nil | 306 to `insert' and it is passed through `regexp-quote' before being |
552 "Info about index search results.") | 307 used by functions like `re-search-forward'.") |
553 | 308 |
554 (defvar mh-index-previous-search nil) | 309 (defvar mh-sent-from-folder nil |
555 (defvar mh-index-msg-checksum-map nil) | 310 "Folder of msg assoc with this letter.") |
556 (defvar mh-index-checksum-origin-map nil) | 311 |
557 (defvar mh-index-sequence-search-flag nil) | 312 (defvar mh-sent-from-msg nil |
558 | 313 "Number of msg assoc with this letter.") |
559 (defvar mh-first-msg-num nil | 314 |
560 "Number of first message in buffer.") | 315 ;; Sequences |
561 | 316 |
562 (defvar mh-last-msg-num nil | 317 (defvar mh-unseen-seq nil |
563 "Number of last msg in buffer.") | 318 "Cached value of the \"Unseen-Sequence:\" MH profile component. |
564 | 319 Name of the Unseen sequence.") |
565 (defvar mh-mode-line-annotation nil | 320 |
566 "Message range displayed in buffer.") | 321 (defvar mh-previous-seq nil |
567 | 322 "Cached value of the \"Previous-Sequence:\" MH profile component. |
568 (defvar mh-sequence-notation-history nil | 323 Name of the Previous sequence.") |
569 "Remember original notation that is overwritten by `mh-note-seq'.") | 324 |
570 | 325 ;; Etc. (alphabetical) |
571 (defvar mh-colors-available-flag nil | 326 |
572 "Non-nil means colors are available.") | 327 (defvar mh-flists-present-flag nil |
328 "Non-nil means that we have \"flists\".") | |
329 | |
330 (defvar mh-index-data-file ".mhe_index" | |
331 "MH-E specific file where index seach info is stored.") | |
332 | |
333 (defvar mh-letter-header-field-regexp "^\\([A-Za-z][A-Za-z0-9-]*\\):") | |
334 | |
335 (defvar mh-page-to-next-msg-flag nil | |
336 "Non-nil means next SPC or whatever goes to next undeleted message.") | |
337 | |
338 (defvar mh-pgp-support-flag (not (not (locate-library "mml2015"))) | |
339 "Non-nil means PGP support is available.") | |
340 | |
341 (defvar mh-signature-separator "-- \n" | |
342 "Text of a signature separator. | |
343 | |
344 A signature separator is used to separate the body of a message | |
345 from the signature. This can be used by user agents such as MH-E | |
346 to render the signature differently or to suppress the inclusion | |
347 of the signature in a reply. Use `mh-signature-separator-regexp' | |
348 when searching for a separator.") | |
349 | |
350 (defvar mh-signature-separator-regexp "^-- $" | |
351 "This regular expression matches the signature separator. | |
352 See `mh-signature-separator'.") | |
353 | |
354 (defvar mh-thread-scan-line-map nil | |
355 "Map of message index to various parts of the scan line.") | |
356 (make-variable-buffer-local 'mh-thread-scan-line-map) | |
357 | |
358 (defvar mh-thread-scan-line-map-stack nil | |
359 "Old map of message index to various parts of the scan line. | |
360 This is the original map that is stored when the folder is | |
361 narrowed.") | |
362 (make-variable-buffer-local 'mh-thread-scan-line-map-stack) | |
363 | |
364 (defvar mh-x-mailer-string nil | |
365 "*String containing the contents of the X-Mailer header field. | |
366 If nil, this variable is initialized to show the version of MH-E, | |
367 Emacs, and MH the first time a message is composed.") | |
573 | 368 |
574 | 369 |
575 | 370 |
576 ;;; Macros and generic functions: | 371 ;;; MH-E Entry Points |
577 | |
578 (defun mh-mapc (function list) | |
579 "Apply FUNCTION to each element of LIST for side effects only." | |
580 (while list | |
581 (funcall function (car list)) | |
582 (setq list (cdr list)))) | |
583 | |
584 (defun mh-scan-format () | |
585 "Return the output format argument for the scan program." | |
586 (if (equal mh-scan-format-file t) | |
587 (list "-format" (if (mh-variant-p 'nmh 'mu-mh) | |
588 (list (mh-update-scan-format | |
589 mh-scan-format-nmh mh-cmd-note)) | |
590 (list (mh-update-scan-format | |
591 mh-scan-format-mh mh-cmd-note)))) | |
592 (if (not (equal mh-scan-format-file nil)) | |
593 (list "-form" mh-scan-format-file)))) | |
594 | |
595 | |
596 | |
597 ;;; Entry points: | |
598 | |
599 ;;;###autoload | |
600 (defun mh-rmail (&optional arg) | |
601 "Incorporate new mail with MH. | |
602 Scan an MH folder if ARG is non-nil. | |
603 | |
604 This function is an entry point to MH-E, the Emacs interface to | |
605 the MH mail system." | |
606 (interactive "P") | |
607 (mh-find-path) | |
608 (if arg | |
609 (call-interactively 'mh-visit-folder) | |
610 (unless (get-buffer mh-inbox) | |
611 (mh-visit-folder mh-inbox (symbol-name mh-unseen-seq))) | |
612 (mh-inc-folder))) | |
613 | |
614 ;;;###autoload | |
615 (defun mh-nmail (&optional arg) | |
616 "Check for new mail in inbox folder. | |
617 Scan an MH folder if ARG is non-nil. | |
618 | |
619 This function is an entry point to MH-E, the Emacs interface to | |
620 the MH mail system." | |
621 (interactive "P") | |
622 (mh-find-path) ; init mh-inbox | |
623 (if arg | |
624 (call-interactively 'mh-visit-folder) | |
625 (mh-visit-folder mh-inbox))) | |
626 | |
627 | |
628 | |
629 ;;; User executable MH-E commands: | |
630 | |
631 (defun mh-delete-msg (range) | |
632 "Delete RANGE\\<mh-folder-mode-map>. | |
633 | |
634 To mark a message for deletion, use this command. A \"D\" is | |
635 placed by the message in the scan window, and the next undeleted | |
636 message is displayed. If the previous command had been | |
637 \\[mh-previous-undeleted-msg], then the next message displayed is | |
638 the first undeleted message previous to the message just deleted. | |
639 Use \\[mh-next-undeleted-msg] to force subsequent | |
640 \\[mh-delete-msg] commands to move forward to the next undeleted | |
641 message after deleting the message under the cursor. | |
642 | |
643 The hook `mh-delete-msg-hook' is called after you mark a message | |
644 for deletion. For example, a past maintainer of MH-E used this | |
645 once when he kept statistics on his mail usage. | |
646 | |
647 Check the documentation of `mh-interactive-range' to see how | |
648 RANGE is read in interactive use." | |
649 (interactive (list (mh-interactive-range "Delete"))) | |
650 (mh-delete-msg-no-motion range) | |
651 (if (looking-at mh-scan-deleted-msg-regexp) | |
652 (mh-next-msg))) | |
653 | |
654 (defun mh-delete-msg-no-motion (range) | |
655 "Delete RANGE, don't move to next message. | |
656 | |
657 This command marks the RANGE for deletion but leaves the cursor | |
658 at the current message in case you wish to perform other | |
659 operations on the message. | |
660 | |
661 Check the documentation of `mh-interactive-range' to see how | |
662 RANGE is read in interactive use." | |
663 (interactive (list (mh-interactive-range "Delete"))) | |
664 (mh-iterate-on-range () range | |
665 (mh-delete-a-msg nil))) | |
666 | |
667 (defun mh-execute-commands () | |
668 "Process outstanding delete and refile requests\\<mh-folder-mode-map>. | |
669 | |
670 If you've marked messages to be deleted or refiled and you want | |
671 to go ahead and delete or refile the messages, use this command. | |
672 Many MH-E commands that may affect the numbering of the | |
673 messages (such as \\[mh-rescan-folder] or \\[mh-pack-folder]) | |
674 will ask if you want to process refiles or deletes first and then | |
675 either run this command for you or undo the pending refiles and | |
676 deletes, which are lost. | |
677 | |
678 This function runs `mh-before-commands-processed-hook' before the | |
679 commands are processed and `mh-after-commands-processed-hook' | |
680 after the commands are processed." | |
681 (interactive) | |
682 (if mh-folder-view-stack (mh-widen t)) | |
683 (mh-process-commands mh-current-folder) | |
684 (mh-set-scan-mode) | |
685 (mh-goto-cur-msg) ; after mh-set-scan-mode for efficiency | |
686 (mh-make-folder-mode-line) | |
687 t) ; return t for write-file-functions | |
688 | |
689 (defun mh-first-msg () | |
690 "Display first message." | |
691 (interactive) | |
692 (goto-char (point-min)) | |
693 (while (and (not (eobp)) (not (looking-at mh-scan-valid-regexp))) | |
694 (forward-line 1))) | |
695 | |
696 (defun mh-header-display () | |
697 "Display message with all header fields\\<mh-folder-mode-map>. | |
698 | |
699 Use the command \\[mh-show] to show the message normally again." | |
700 (interactive) | |
701 (and (not mh-showing-with-headers) | |
702 (or mh-mhl-format-file mh-clean-message-header-flag) | |
703 (mh-invalidate-show-buffer)) | |
704 (let ((mh-decode-mime-flag nil) | |
705 (mh-mhl-format-file nil) | |
706 (mh-clean-message-header-flag nil)) | |
707 (mh-show-msg nil) | |
708 (mh-in-show-buffer (mh-show-buffer) | |
709 (goto-char (point-min)) | |
710 (mh-recenter 0)) | |
711 (setq mh-showing-with-headers t))) | |
712 | |
713 (defun mh-inc-folder (&optional file folder) | |
714 "Incorporate new mail into a folder. | |
715 | |
716 You can incorporate mail from any file into the current folder by | |
717 specifying a prefix argument; you'll be prompted for the name of | |
718 the FILE to use as well as the destination FOLDER | |
719 | |
720 The hook `mh-inc-folder-hook' is run after incorporating new | |
721 mail. | |
722 | |
723 Do not call this function from outside MH-E; use \\[mh-rmail] | |
724 instead." | |
725 (interactive (list (if current-prefix-arg | |
726 (expand-file-name | |
727 (read-file-name "inc mail from file: " | |
728 mh-user-path))) | |
729 (if current-prefix-arg | |
730 (mh-prompt-for-folder "inc mail into" mh-inbox t)))) | |
731 (if (not folder) | |
732 (setq folder mh-inbox)) | |
733 (let ((threading-needed-flag nil)) | |
734 (let ((config (current-window-configuration))) | |
735 (when (and mh-show-buffer (get-buffer mh-show-buffer)) | |
736 (delete-windows-on mh-show-buffer)) | |
737 (cond ((not (get-buffer folder)) | |
738 (mh-make-folder folder) | |
739 (setq threading-needed-flag mh-show-threads-flag) | |
740 (setq mh-previous-window-config config)) | |
741 ((not (eq (current-buffer) (get-buffer folder))) | |
742 (switch-to-buffer folder) | |
743 (setq mh-previous-window-config config)))) | |
744 (mh-get-new-mail file) | |
745 (when (and threading-needed-flag | |
746 (save-excursion | |
747 (goto-char (point-min)) | |
748 (or (null mh-large-folder) | |
749 (not (equal (forward-line (1+ mh-large-folder)) 0)) | |
750 (and (message "Not threading since the number of messages exceeds `mh-large-folder'") | |
751 nil)))) | |
752 (mh-toggle-threads)) | |
753 (beginning-of-line) | |
754 (if (and mh-showing-mode (looking-at mh-scan-valid-regexp)) (mh-show)) | |
755 (run-hooks 'mh-inc-folder-hook))) | |
756 | |
757 (defun mh-last-msg () | |
758 "Display last message." | |
759 (interactive) | |
760 (goto-char (point-max)) | |
761 (while (and (not (bobp)) (not (looking-at mh-scan-valid-regexp))) | |
762 (forward-line -1)) | |
763 (mh-recenter nil)) | |
764 | |
765 (defun mh-next-undeleted-msg (&optional count wait-after-complaining-flag) | |
766 "Display next message. | |
767 | |
768 This command can be given a prefix argument COUNT to specify how | |
769 many unread messages to skip. | |
770 | |
771 In a program, pause for a second after printing message if we are | |
772 at the last undeleted message and optional argument | |
773 WAIT-AFTER-COMPLAINING-FLAG is non-nil." | |
774 (interactive "p") | |
775 (setq mh-next-direction 'forward) | |
776 (forward-line 1) | |
777 (cond ((re-search-forward mh-scan-good-msg-regexp nil t count) | |
778 (beginning-of-line) | |
779 (mh-maybe-show)) | |
780 (t (forward-line -1) | |
781 (message "No more undeleted messages") | |
782 (if wait-after-complaining-flag (sit-for 1))))) | |
783 | |
784 (defun mh-folder-from-address () | |
785 "Derive folder name from sender. | |
786 | |
787 The name of the folder is derived as follows: | |
788 | |
789 a) The folder name associated with the first address found in | |
790 the list `mh-default-folder-list' is used. Each element in | |
791 this list contains a \"Check Recipient\" item. If this item is | |
792 turned on, then the address is checked against the recipient | |
793 instead of the sender. This is useful for mailing lists. | |
794 | |
795 b) An alias prefixed by `mh-default-folder-prefix' | |
796 corresponding to the address is used. The prefix is used to | |
797 prevent clutter in your mail directory. | |
798 | |
799 Return nil if a folder name was not derived, or if the variable | |
800 `mh-default-folder-must-exist-flag' is t and the folder does not | |
801 exist." | |
802 ;; Loop for all entries in mh-default-folder-list | |
803 (save-restriction | |
804 (goto-char (point-min)) | |
805 (re-search-forward "\n\n" nil 'limit) | |
806 (narrow-to-region (point-min) (point)) | |
807 (let ((to/cc (concat (or (message-fetch-field "to") "") ", " | |
808 (or (message-fetch-field "cc") ""))) | |
809 (from (or (message-fetch-field "from") "")) | |
810 folder-name) | |
811 (setq folder-name | |
812 (loop for list in mh-default-folder-list | |
813 when (string-match (nth 0 list) (if (nth 2 list) to/cc from)) | |
814 return (nth 1 list) | |
815 finally return nil)) | |
816 | |
817 ;; Make sure a result from `mh-default-folder-list' begins with "+" | |
818 ;; since 'mh-expand-file-name below depends on it | |
819 (when (and folder-name (not (eq (aref folder-name 0) ?+))) | |
820 (setq folder-name (concat "+" folder-name))) | |
821 | |
822 ;; If not, is there an alias for the address? | |
823 (when (not folder-name) | |
824 (let* ((from-header (mh-extract-from-header-value)) | |
825 (address (and from-header | |
826 (nth 1 (mail-extract-address-components | |
827 from-header)))) | |
828 (alias (and address (mh-alias-address-to-alias address)))) | |
829 (when alias | |
830 (setq folder-name | |
831 (and alias (concat "+" mh-default-folder-prefix alias)))))) | |
832 | |
833 ;; If mh-default-folder-must-exist-flag set, check that folder exists. | |
834 (if (and folder-name | |
835 (or (not mh-default-folder-must-exist-flag) | |
836 (file-exists-p (mh-expand-file-name folder-name)))) | |
837 folder-name)))) | |
838 | |
839 (defun mh-prompt-for-refile-folder () | |
840 "Prompt the user for a folder in which the message should be filed. | |
841 The folder is returned as a string. | |
842 | |
843 The default folder name is generated by the option | |
844 `mh-default-folder-for-message-function' if it is non-nil or | |
845 `mh-folder-from-address'." | |
846 (mh-prompt-for-folder | |
847 "Destination" | |
848 (let ((refile-file (ignore-errors (mh-msg-filename (mh-get-msg-num t))))) | |
849 (if (null refile-file) "" | |
850 (save-excursion | |
851 (set-buffer (get-buffer-create mh-temp-buffer)) | |
852 (erase-buffer) | |
853 (insert-file-contents refile-file) | |
854 (or (and mh-default-folder-for-message-function | |
855 (let ((buffer-file-name refile-file)) | |
856 (funcall mh-default-folder-for-message-function))) | |
857 (mh-folder-from-address) | |
858 (and (eq 'refile (car mh-last-destination-folder)) | |
859 (symbol-name (cdr mh-last-destination-folder))) | |
860 "")))) | |
861 t)) | |
862 | |
863 (defun mh-refile-msg (range folder &optional dont-update-last-destination-flag) | |
864 "Refile (output) RANGE into FOLDER. | |
865 | |
866 You are prompted for the folder name. Note that this command can also | |
867 be used to create folders. If you specify a folder that does not | |
868 exist, you will be prompted to create it. | |
869 | |
870 The hook `mh-refile-msg-hook' is called after a message is marked to | |
871 be refiled. | |
872 | |
873 Check the documentation of `mh-interactive-range' to see how RANGE is | |
874 read in interactive use. | |
875 | |
876 In a program, the variables `mh-last-destination' and | |
877 `mh-last-destination-folder' are not updated if | |
878 DONT-UPDATE-LAST-DESTINATION-FLAG is non-nil." | |
879 (interactive (list (mh-interactive-range "Refile") | |
880 (intern (mh-prompt-for-refile-folder)))) | |
881 (unless dont-update-last-destination-flag | |
882 (setq mh-last-destination (cons 'refile folder) | |
883 mh-last-destination-folder mh-last-destination)) | |
884 (mh-iterate-on-range () range | |
885 (mh-refile-a-msg nil folder)) | |
886 (when (looking-at mh-scan-refiled-msg-regexp) (mh-next-msg))) | |
887 | |
888 (defun mh-refile-or-write-again (range &optional interactive-flag) | |
889 "Repeat last output command. | |
890 | |
891 If you are refiling several messages into the same folder, you | |
892 can use this command to repeat the last | |
893 refile (\\[mh-refile-msg]) or write (\\[mh-write-msg-to-file]). | |
894 You can use a range. | |
895 | |
896 Check the documentation of `mh-interactive-range' to see how RANGE is | |
897 read in interactive use. | |
898 | |
899 In a program, a non-nil INTERACTIVE-FLAG means that the function was | |
900 called interactively." | |
901 (interactive (list (mh-interactive-range "Redo") t)) | |
902 (if (null mh-last-destination) | |
903 (error "No previous refile or write")) | |
904 (cond ((eq (car mh-last-destination) 'refile) | |
905 (mh-refile-msg range (cdr mh-last-destination)) | |
906 (message "Destination folder: %s" (cdr mh-last-destination))) | |
907 (t | |
908 (mh-iterate-on-range msg range | |
909 (apply 'mh-write-msg-to-file msg (cdr mh-last-destination))) | |
910 (mh-next-msg interactive-flag)))) | |
911 | |
912 (defun mh-quit () | |
913 "Quit the current MH-E folder. | |
914 | |
915 When you want to quit using MH-E and go back to editing, you can use | |
916 this command. This buries the buffers of the current MH-E folder and | |
917 restores the buffers that were present when you first ran | |
918 \\[mh-rmail]. It also removes any MH-E working buffers whose name | |
919 begins with \" *mh-\" or \"*MH-E \". You can later restore your MH-E | |
920 session by selecting the \"+inbox\" buffer or by running \\[mh-rmail] | |
921 again. | |
922 | |
923 The two hooks `mh-before-quit-hook' and `mh-quit-hook' are called by | |
924 this function. The former one is called before the quit occurs, so you | |
925 might use it to perform any MH-E operations; you could perform some | |
926 query and abort the quit or call `mh-execute-commands', for example. | |
927 The latter is not run in an MH-E context, so you might use it to | |
928 modify the window setup." | |
929 (interactive) | |
930 (run-hooks 'mh-before-quit-hook) | |
931 (let ((show-buffer (get-buffer mh-show-buffer))) | |
932 (when show-buffer | |
933 (kill-buffer show-buffer))) | |
934 (mh-update-sequences) | |
935 (mh-destroy-postponed-handles) | |
936 (bury-buffer (current-buffer)) | |
937 | |
938 ;; Delete all MH-E temporary and working buffers. | |
939 (dolist (buffer (buffer-list)) | |
940 (when (or (string-match "^ \\*mh-" (buffer-name buffer)) | |
941 (string-match "^\\*MH-E " (buffer-name buffer))) | |
942 (kill-buffer buffer))) | |
943 | |
944 (if mh-previous-window-config | |
945 (set-window-configuration mh-previous-window-config)) | |
946 (run-hooks 'mh-quit-hook)) | |
947 | |
948 (defun mh-page-msg (&optional lines) | |
949 "Display next page in message. | |
950 | |
951 You can give this command a prefix argument that specifies the | |
952 number of LINES to scroll. This command will also show the next | |
953 undeleted message if it is used at the bottom of a message." | |
954 (interactive "P") | |
955 (if mh-showing-mode | |
956 (if mh-page-to-next-msg-flag | |
957 (if (equal mh-next-direction 'backward) | |
958 (mh-previous-undeleted-msg) | |
959 (mh-next-undeleted-msg)) | |
960 (if (mh-in-show-buffer (mh-show-buffer) | |
961 (pos-visible-in-window-p (point-max))) | |
962 (progn | |
963 (message | |
964 "End of message (Type %s to read %s undeleted message)" | |
965 (single-key-description last-input-event) | |
966 (if (equal mh-next-direction 'backward) | |
967 "previous" | |
968 "next")) | |
969 (setq mh-page-to-next-msg-flag t)) | |
970 (scroll-other-window lines))) | |
971 (mh-show))) | |
972 | |
973 (defun mh-previous-page (&optional lines) | |
974 "Display next page in message. | |
975 | |
976 You can give this command a prefix argument that specifies the | |
977 number of LINES to scroll." | |
978 (interactive "P") | |
979 (mh-in-show-buffer (mh-show-buffer) | |
980 (scroll-down lines))) | |
981 | |
982 (defun mh-previous-undeleted-msg (&optional count wait-after-complaining-flag) | |
983 "Display previous message. | |
984 | |
985 This command can be given a prefix argument COUNT to specify how | |
986 many unread messages to skip. | |
987 | |
988 In a program, pause for a second after printing message if we are | |
989 at the last undeleted message and optional argument | |
990 WAIT-AFTER-COMPLAINING-FLAG is non-nil." | |
991 (interactive "p") | |
992 (setq mh-next-direction 'backward) | |
993 (beginning-of-line) | |
994 (cond ((re-search-backward mh-scan-good-msg-regexp nil t count) | |
995 (mh-maybe-show)) | |
996 (t (message "No previous undeleted message") | |
997 (if wait-after-complaining-flag (sit-for 1))))) | |
998 | |
999 (defun mh-previous-unread-msg (&optional count) | |
1000 "Display previous unread message. | |
1001 | |
1002 This command can be given a prefix argument COUNT to specify how | |
1003 many unread messages to skip." | |
1004 (interactive "p") | |
1005 (unless (> count 0) | |
1006 (error "The function `mh-previous-unread-msg' expects positive argument")) | |
1007 (setq count (1- count)) | |
1008 (let ((unread-sequence (cdr (assoc mh-unseen-seq mh-seq-list))) | |
1009 (cur-msg (mh-get-msg-num nil))) | |
1010 (cond ((and (not cur-msg) (not (bobp)) | |
1011 ;; If we are at the end of the buffer back up one line and go | |
1012 ;; to unread message after that. | |
1013 (progn | |
1014 (forward-line -1) | |
1015 (setq cur-msg (mh-get-msg-num nil))) | |
1016 nil)) | |
1017 ((or (null unread-sequence) (not cur-msg)) | |
1018 ;; No unread message or there aren't any messages in buffer... | |
1019 (message "No more unread messages")) | |
1020 ((progn | |
1021 ;; Skip count messages... | |
1022 (while (and unread-sequence (>= (car unread-sequence) cur-msg)) | |
1023 (setq unread-sequence (cdr unread-sequence))) | |
1024 (while (> count 0) | |
1025 (setq unread-sequence (cdr unread-sequence)) | |
1026 (setq count (1- count))) | |
1027 (not (car unread-sequence))) | |
1028 (message "No more unread messages")) | |
1029 (t (loop for msg in unread-sequence | |
1030 when (mh-goto-msg msg t) return nil | |
1031 finally (message "No more unread messages")))))) | |
1032 | |
1033 (defun mh-goto-next-button (backward-flag &optional criterion) | |
1034 "Search for next button satisfying criterion. | |
1035 | |
1036 If BACKWARD-FLAG is non-nil search backward in the buffer for a mime | |
1037 button. | |
1038 If CRITERION is a function or a symbol which has a function binding | |
1039 then that function must return non-nil at the button we stop." | |
1040 (unless (or (and (symbolp criterion) (fboundp criterion)) | |
1041 (functionp criterion)) | |
1042 (setq criterion (lambda (x) t))) | |
1043 ;; Move to the next button in the buffer satisfying criterion | |
1044 (goto-char (or (save-excursion | |
1045 (beginning-of-line) | |
1046 ;; Find point before current button | |
1047 (let ((point-before-current-button | |
1048 (save-excursion | |
1049 (while (get-text-property (point) 'mh-data) | |
1050 (unless (= (forward-line | |
1051 (if backward-flag 1 -1)) | |
1052 0) | |
1053 (if backward-flag | |
1054 (goto-char (point-min)) | |
1055 (goto-char (point-max))))) | |
1056 (point)))) | |
1057 ;; Skip over current button | |
1058 (while (and (get-text-property (point) 'mh-data) | |
1059 (not (if backward-flag (bobp) (eobp)))) | |
1060 (forward-line (if backward-flag -1 1))) | |
1061 ;; Stop at next MIME button if any exists. | |
1062 (block loop | |
1063 (while (/= (progn | |
1064 (unless (= (forward-line | |
1065 (if backward-flag -1 1)) | |
1066 0) | |
1067 (if backward-flag | |
1068 (goto-char (point-max)) | |
1069 (goto-char (point-min))) | |
1070 (beginning-of-line)) | |
1071 (point)) | |
1072 point-before-current-button) | |
1073 (when (and (get-text-property (point) 'mh-data) | |
1074 (funcall criterion (point))) | |
1075 (return-from loop (point)))) | |
1076 nil))) | |
1077 (point)))) | |
1078 | |
1079 (defun mh-next-button (&optional backward-flag) | |
1080 "Go to the next button. | |
1081 | |
1082 If the end of the buffer is reached then the search wraps over to | |
1083 the start of the buffer. | |
1084 | |
1085 If an optional prefix argument BACKWARD-FLAG is given, the cursor | |
1086 will move to the previous button." | |
1087 (interactive (list current-prefix-arg)) | |
1088 (unless mh-showing-mode | |
1089 (mh-show)) | |
1090 (mh-in-show-buffer (mh-show-buffer) | |
1091 (mh-goto-next-button backward-flag))) | |
1092 | |
1093 (defun mh-prev-button () | |
1094 "Go to the previous button. | |
1095 | |
1096 If the beginning of the buffer is reached then the search wraps | |
1097 over to the end of the buffer." | |
1098 (interactive) | |
1099 (mh-next-button t)) | |
1100 | |
1101 (defun mh-folder-mime-action (part-index action include-security-flag) | |
1102 "Go to PART-INDEX and carry out ACTION. | |
1103 | |
1104 If PART-INDEX is nil then go to the next part in the buffer. The | |
1105 search for the next buffer wraps around if end of buffer is reached. | |
1106 If argument INCLUDE-SECURITY-FLAG is non-nil then include security | |
1107 info buttons when searching for a suitable parts." | |
1108 (unless mh-showing-mode | |
1109 (mh-show)) | |
1110 (mh-in-show-buffer (mh-show-buffer) | |
1111 (let ((criterion | |
1112 (cond (part-index | |
1113 (lambda (p) | |
1114 (let ((part (get-text-property p 'mh-part))) | |
1115 (and (integerp part) (= part part-index))))) | |
1116 (t (lambda (p) | |
1117 (if include-security-flag | |
1118 (get-text-property p 'mh-data) | |
1119 (integerp (get-text-property p 'mh-part))))))) | |
1120 (point (point))) | |
1121 (cond ((and (get-text-property point 'mh-part) | |
1122 (or (null part-index) | |
1123 (= (get-text-property point 'mh-part) part-index))) | |
1124 (funcall action)) | |
1125 ((and (get-text-property point 'mh-data) | |
1126 include-security-flag | |
1127 (null part-index)) | |
1128 (funcall action)) | |
1129 (t | |
1130 (mh-goto-next-button nil criterion) | |
1131 (if (= (point) point) | |
1132 (message "No matching MIME part found") | |
1133 (funcall action))))))) | |
1134 | |
1135 (defun mh-folder-toggle-mime-part (part-index) | |
1136 "View attachment. | |
1137 | |
1138 This command displays (or hides) the attachment associated with | |
1139 the button under the cursor. If the cursor is not located over a | |
1140 button, then the cursor first moves to the next button, wrapping | |
1141 to the beginning of the message if necessary. This command has | |
1142 the advantage over related commands of working from the MH-Folder | |
1143 buffer. | |
1144 | |
1145 You can also provide a numeric prefix argument PART-INDEX to view | |
1146 the attachment labeled with that number. If Emacs does not know | |
1147 how to display the attachment, then Emacs offers to save the | |
1148 attachment in a file." | |
1149 (interactive "P") | |
1150 (when (consp part-index) (setq part-index (car part-index))) | |
1151 (mh-folder-mime-action part-index #'mh-press-button t)) | |
1152 | |
1153 (defun mh-folder-inline-mime-part (part-index) | |
1154 "Show attachment verbatim. | |
1155 | |
1156 You can view the raw contents of an attachment with this command. | |
1157 This command displays (or hides) the contents of the attachment | |
1158 associated with the button under the cursor verbatim. If the | |
1159 cursor is not located over a button, then the cursor first moves | |
1160 to the next button, wrapping to the beginning of the message if | |
1161 necessary. | |
1162 | |
1163 You can also provide a numeric prefix argument PART-INDEX to view | |
1164 the attachment labeled with that number." | |
1165 (interactive "P") | |
1166 (when (consp part-index) (setq part-index (car part-index))) | |
1167 (mh-folder-mime-action part-index #'mh-mime-inline-part nil)) | |
1168 | |
1169 (defun mh-folder-save-mime-part (part-index) | |
1170 "Save (output) attachment. | |
1171 | |
1172 This command saves the attachment associated with the button under the | |
1173 cursor. If the cursor is not located over a button, then the cursor | |
1174 first moves to the next button, wrapping to the beginning of the | |
1175 message if necessary. | |
1176 | |
1177 You can also provide a numeric prefix argument PART-INDEX to save the | |
1178 attachment labeled with that number. | |
1179 | |
1180 This command prompts you for a filename and suggests a specific name | |
1181 if it is available." | |
1182 (interactive "P") | |
1183 (when (consp part-index) (setq part-index (car part-index))) | |
1184 (mh-folder-mime-action part-index #'mh-mime-save-part nil)) | |
1185 | |
1186 (defun mh-reset-threads-and-narrowing () | |
1187 "Reset all variables pertaining to threads and narrowing. | |
1188 Also removes all content from the folder buffer." | |
1189 (setq mh-view-ops ()) | |
1190 (setq mh-folder-view-stack ()) | |
1191 (setq mh-thread-scan-line-map-stack ()) | |
1192 (let ((buffer-read-only nil)) (erase-buffer))) | |
1193 | |
1194 (defun mh-rescan-folder (&optional range dont-exec-pending) | |
1195 "Rescan folder\\<mh-folder-mode-map>. | |
1196 | |
1197 This command is useful to grab all messages in your \"+inbox\" after | |
1198 processing your new mail for the first time. If you don't want to | |
1199 rescan the entire folder, this command will accept a RANGE. Check the | |
1200 documentation of `mh-interactive-range' to see how RANGE is read in | |
1201 interactive use. | |
1202 | |
1203 This command will ask if you want to process refiles or deletes first | |
1204 and then either run \\[mh-execute-commands] for you or undo the | |
1205 pending refiles and deletes, which are lost. | |
1206 | |
1207 In a program, the processing of outstanding commands is not performed | |
1208 if DONT-EXEC-PENDING is non-nil." | |
1209 (interactive (list (if current-prefix-arg | |
1210 (mh-read-range "Rescan" mh-current-folder t nil t | |
1211 mh-interpret-number-as-range-flag) | |
1212 nil))) | |
1213 (setq mh-next-direction 'forward) | |
1214 (let ((threaded-flag (memq 'unthread mh-view-ops)) | |
1215 (msg-num (mh-get-msg-num nil))) | |
1216 (mh-scan-folder mh-current-folder (or range "all") dont-exec-pending) | |
1217 ;; If there isn't a cur sequence, mh-scan-folder goes to the first message. | |
1218 ;; Try to stay where we were. | |
1219 (if (null (car (mh-seq-to-msgs 'cur))) | |
1220 (mh-goto-msg msg-num t t)) | |
1221 (cond (threaded-flag (mh-toggle-threads)) | |
1222 (mh-index-data (mh-index-insert-folder-headers))))) | |
1223 | |
1224 (defun mh-write-msg-to-file (message file no-header) | |
1225 "Append MESSAGE to end of FILE\\<mh-folder-mode-map>. | |
1226 | |
1227 You are prompted for the filename. If the file already exists, | |
1228 the message is appended to it. You can also write the message to | |
1229 the file without the header by specifying a prefix argument | |
1230 NO-HEADER. Subsequent writes to the same file can be made with | |
1231 the command \\[mh-refile-or-write-again]." | |
1232 (interactive | |
1233 (list (mh-get-msg-num t) | |
1234 (let ((default-dir (if (eq 'write (car mh-last-destination-write)) | |
1235 (file-name-directory | |
1236 (car (cdr mh-last-destination-write))) | |
1237 default-directory))) | |
1238 (read-file-name (format "Save message%s in file: " | |
1239 (if current-prefix-arg " body" "")) | |
1240 default-dir | |
1241 (if (eq 'write (car mh-last-destination-write)) | |
1242 (car (cdr mh-last-destination-write)) | |
1243 (expand-file-name "mail.out" default-dir)))) | |
1244 current-prefix-arg)) | |
1245 (let ((msg-file-to-output (mh-msg-filename message)) | |
1246 (output-file (mh-expand-file-name file))) | |
1247 (setq mh-last-destination (list 'write file (if no-header 'no-header)) | |
1248 mh-last-destination-write mh-last-destination) | |
1249 (save-excursion | |
1250 (set-buffer (get-buffer-create mh-temp-buffer)) | |
1251 (erase-buffer) | |
1252 (insert-file-contents msg-file-to-output) | |
1253 (goto-char (point-min)) | |
1254 (if no-header (search-forward "\n\n")) | |
1255 (append-to-file (point) (point-max) output-file)))) | |
1256 | |
1257 (defun mh-toggle-showing () | |
1258 "Toggle between MH-Folder and MH-Folder Show modes. | |
1259 | |
1260 This command switches between MH-Folder mode and MH-Folder Show | |
1261 mode. MH-Folder mode turns off the associated show buffer so that | |
1262 you can perform operations on the messages quickly without | |
1263 reading them. This is an excellent way to prune out your junk | |
1264 mail or to refile a group of messages to another folder for later | |
1265 examination." | |
1266 (interactive) | |
1267 (if mh-showing-mode | |
1268 (mh-set-scan-mode) | |
1269 (mh-show))) | |
1270 | |
1271 (defun mh-undo (range) | |
1272 "Undo pending deletes or refiles in RANGE. | |
1273 | |
1274 If you've deleted a message or refiled it, but changed your mind, | |
1275 you can cancel the action before you've executed it. Use this | |
1276 command to undo a refile on or deletion of a single message. You | |
1277 can also undo refiles and deletes for messages that are found in | |
1278 a given RANGE. | |
1279 | |
1280 Check the documentation of `mh-interactive-range' to see how | |
1281 RANGE is read in interactive use." | |
1282 (interactive (list (mh-interactive-range "Undo"))) | |
1283 (cond ((numberp range) | |
1284 (let ((original-position (point))) | |
1285 (beginning-of-line) | |
1286 (while (not (or (looking-at mh-scan-deleted-msg-regexp) | |
1287 (looking-at mh-scan-refiled-msg-regexp) | |
1288 (and (eq mh-next-direction 'forward) (bobp)) | |
1289 (and (eq mh-next-direction 'backward) | |
1290 (save-excursion (forward-line) (eobp))))) | |
1291 (forward-line (if (eq mh-next-direction 'forward) -1 1))) | |
1292 (if (or (looking-at mh-scan-deleted-msg-regexp) | |
1293 (looking-at mh-scan-refiled-msg-regexp)) | |
1294 (progn | |
1295 (mh-undo-msg (mh-get-msg-num t)) | |
1296 (mh-maybe-show)) | |
1297 (goto-char original-position) | |
1298 (error "Nothing to undo")))) | |
1299 (t (mh-iterate-on-range () range | |
1300 (mh-undo-msg nil)))) | |
1301 (if (not (mh-outstanding-commands-p)) | |
1302 (mh-set-folder-modified-p nil))) | |
1303 | |
1304 (defun mh-folder-line-matches-show-buffer-p () | |
1305 "Return t if the message under point in folder-mode is in the show buffer. | |
1306 Return nil in any other circumstance (no message under point, no | |
1307 show buffer, the message in the show buffer doesn't match." | |
1308 (and (eq major-mode 'mh-folder-mode) | |
1309 (mh-get-msg-num nil) | |
1310 mh-show-buffer | |
1311 (get-buffer mh-show-buffer) | |
1312 (buffer-file-name (get-buffer mh-show-buffer)) | |
1313 (string-match ".*/\\([0-9]+\\)$" | |
1314 (buffer-file-name (get-buffer mh-show-buffer))) | |
1315 (string-equal | |
1316 (match-string 1 (buffer-file-name (get-buffer mh-show-buffer))) | |
1317 (int-to-string (mh-get-msg-num nil))))) | |
1318 | 372 |
1319 (eval-when-compile (require 'gnus)) | 373 (eval-when-compile (require 'gnus)) |
1320 | 374 |
1321 (defmacro mh-macro-expansion-time-gnus-version () | 375 (defmacro mh-macro-expansion-time-gnus-version () |
1322 "Return Gnus version available at macro expansion time. | 376 "Return Gnus version available at macro expansion time. |
1360 (call-process "uname" nil t nil "-a") | 414 (call-process "uname" nil t nil "-a") |
1361 (file-error)) | 415 (file-error)) |
1362 (goto-char (point-min)) | 416 (goto-char (point-min)) |
1363 (display-buffer mh-info-buffer)) | 417 (display-buffer mh-info-buffer)) |
1364 | 418 |
1365 (defun mh-parse-flist-output-line (line &optional current-folder) | 419 |
1366 "Parse LINE to generate folder name, unseen messages and total messages. | 420 |
1367 If CURRENT-FOLDER is non-nil then it contains the current folder | 421 ;;; Support Routines |
1368 name and it is used to avoid problems in corner cases involving | 422 |
1369 folders whose names end with a '+' character." | 423 (defun mh-list-to-string (l) |
1370 (with-temp-buffer | 424 "Flatten the list L and make every element of the new list into a string." |
1371 (insert line) | 425 (nreverse (mh-list-to-string-1 l))) |
1372 (goto-char (point-max)) | 426 |
1373 (let (folder unseen total p) | 427 (defun mh-list-to-string-1 (l) |
1374 (when (search-backward " out of " (point-min) t) | 428 "Flatten the list L and make every element of the new list into a string." |
1375 (setq total (string-to-number | 429 (let ((new-list nil)) |
1376 (buffer-substring-no-properties | 430 (while l |
1377 (match-end 0) (line-end-position)))) | 431 (cond ((null (car l))) |
1378 (when (search-backward " in sequence " (point-min) t) | 432 ((symbolp (car l)) |
1379 (setq p (point)) | 433 (setq new-list (cons (symbol-name (car l)) new-list))) |
1380 (when (search-backward " has " (point-min) t) | 434 ((numberp (car l)) |
1381 (setq unseen (string-to-number (buffer-substring-no-properties | 435 (setq new-list (cons (int-to-string (car l)) new-list))) |
1382 (match-end 0) p))) | 436 ((equal (car l) "")) |
1383 (while (eq (char-after) ? ) | 437 ((stringp (car l)) (setq new-list (cons (car l) new-list))) |
1384 (backward-char)) | 438 ((listp (car l)) |
1385 (setq folder (buffer-substring-no-properties | 439 (setq new-list (nconc (mh-list-to-string-1 (car l)) |
1386 (point-min) (1+ (point)))) | 440 new-list))) |
1387 (when (and (equal (aref folder (1- (length folder))) ?+) | 441 (t (error "Bad element in `mh-list-to-string': %s" (car l)))) |
1388 (equal current-folder folder)) | 442 (setq l (cdr l))) |
1389 (setq folder (substring folder 0 (1- (length folder))))) | 443 new-list)) |
1390 (values (format "+%s" folder) unseen total))))))) | 444 |
1391 | 445 |
1392 (defun mh-folder-size-folder (folder) | 446 |
1393 "Find size of FOLDER using \"folder\"." | 447 ;;; MH-E Process Support |
1394 (with-temp-buffer | 448 |
1395 (let ((u (length (cdr (assoc mh-unseen-seq | 449 (defvar mh-index-max-cmdline-args 500 |
1396 (mh-read-folder-sequences folder nil)))))) | 450 "Maximum number of command line args.") |
1397 (call-process (expand-file-name "folder" mh-progs) nil t nil | 451 |
1398 "-norecurse" folder) | 452 (defun mh-xargs (cmd &rest args) |
453 "Partial imitation of xargs. | |
454 The current buffer contains a list of strings, one on each line. | |
455 The function will execute CMD with ARGS and pass the first | |
456 `mh-index-max-cmdline-args' strings to it. This is repeated till | |
457 all the strings have been used." | |
458 (goto-char (point-min)) | |
459 (let ((current-buffer (current-buffer))) | |
460 (with-temp-buffer | |
461 (let ((out (current-buffer))) | |
462 (set-buffer current-buffer) | |
463 (while (not (eobp)) | |
464 (let ((arg-list (reverse args)) | |
465 (count 0)) | |
466 (while (and (not (eobp)) (< count mh-index-max-cmdline-args)) | |
467 (push (buffer-substring-no-properties (point) (line-end-position)) | |
468 arg-list) | |
469 (incf count) | |
470 (forward-line)) | |
471 (apply #'call-process cmd nil (list out nil) nil | |
472 (nreverse arg-list)))) | |
473 (erase-buffer) | |
474 (insert-buffer-substring out))))) | |
475 | |
476 ;; XXX This should be applied anywhere MH-E calls out to /bin/sh. | |
477 (defun mh-quote-for-shell (string) | |
478 "Quote STRING for /bin/sh. | |
479 Adds double-quotes around entire string and quotes the characters | |
480 \\, `, and $ with a backslash." | |
481 (concat "\"" | |
482 (loop for x across string | |
483 concat (format (if (memq x '(?\\ ?` ?$)) "\\%c" "%c") x)) | |
484 "\"")) | |
485 | |
486 (defun mh-exec-cmd (command &rest args) | |
487 "Execute mh-command COMMAND with ARGS. | |
488 The side effects are what is desired. Any output is assumed to be | |
489 an error and is shown to the user. The output is not read or | |
490 parsed by MH-E." | |
491 (save-excursion | |
492 (set-buffer (get-buffer-create mh-log-buffer)) | |
493 (let* ((initial-size (mh-truncate-log-buffer)) | |
494 (start (point)) | |
495 (args (mh-list-to-string args))) | |
496 (apply 'call-process (expand-file-name command mh-progs) nil t nil args) | |
497 (when (> (buffer-size) initial-size) | |
498 (save-excursion | |
499 (goto-char start) | |
500 (insert "Errors when executing: " command) | |
501 (loop for arg in args do (insert " " arg)) | |
502 (insert "\n")) | |
503 (save-window-excursion | |
504 (switch-to-buffer-other-window mh-log-buffer) | |
505 (sit-for 5)))))) | |
506 | |
507 (defun mh-exec-cmd-error (env command &rest args) | |
508 "In environment ENV, execute mh-command COMMAND with ARGS. | |
509 ENV is nil or a string of space-separated \"var=value\" elements. | |
510 Signals an error if process does not complete successfully." | |
511 (save-excursion | |
512 (set-buffer (get-buffer-create mh-temp-buffer)) | |
513 (erase-buffer) | |
514 (let ((process-environment process-environment)) | |
515 ;; XXX: We should purge the list that split-string returns of empty | |
516 ;; strings. This can happen in XEmacs if leading or trailing spaces | |
517 ;; are present. | |
518 (dolist (elem (if (stringp env) (split-string env " ") ())) | |
519 (push elem process-environment)) | |
520 (mh-handle-process-error | |
521 command (apply #'call-process (expand-file-name command mh-progs) | |
522 nil t nil (mh-list-to-string args)))))) | |
523 | |
524 (defun mh-exec-cmd-daemon (command filter &rest args) | |
525 "Execute MH command COMMAND in the background. | |
526 | |
527 If FILTER is non-nil then it is used to process the output | |
528 otherwise the default filter `mh-process-daemon' is used. See | |
529 `set-process-filter' for more details of FILTER. | |
530 | |
531 ARGS are passed to COMMAND as command line arguments." | |
532 (save-excursion | |
533 (set-buffer (get-buffer-create mh-log-buffer)) | |
534 (mh-truncate-log-buffer)) | |
535 (let* ((process-connection-type nil) | |
536 (process (apply 'start-process | |
537 command nil | |
538 (expand-file-name command mh-progs) | |
539 (mh-list-to-string args)))) | |
540 (set-process-filter process (or filter 'mh-process-daemon)) | |
541 process)) | |
542 | |
543 (defun mh-exec-cmd-env-daemon (env command filter &rest args) | |
544 "In ennvironment ENV, execute mh-command COMMAND in the background. | |
545 | |
546 ENV is nil or a string of space-separated \"var=value\" elements. | |
547 Signals an error if process does not complete successfully. | |
548 | |
549 If FILTER is non-nil then it is used to process the output | |
550 otherwise the default filter `mh-process-daemon' is used. See | |
551 `set-process-filter' for more details of FILTER. | |
552 | |
553 ARGS are passed to COMMAND as command line arguments." | |
554 (let ((process-environment process-environment)) | |
555 (dolist (elem (if (stringp env) (split-string env " ") ())) | |
556 (push elem process-environment)) | |
557 (apply #'mh-exec-cmd-daemon command filter args))) | |
558 | |
559 (defun mh-process-daemon (process output) | |
560 "PROCESS daemon that puts OUTPUT into a temporary buffer. | |
561 Any output from the process is displayed in an asynchronous | |
562 pop-up window." | |
563 (with-current-buffer (get-buffer-create mh-log-buffer) | |
564 (insert-before-markers output) | |
565 (display-buffer mh-log-buffer))) | |
566 | |
567 (defun mh-exec-cmd-quiet (raise-error command &rest args) | |
568 "Signal RAISE-ERROR if COMMAND with ARGS fails. | |
569 Execute MH command COMMAND with ARGS. ARGS is a list of strings. | |
570 Return at start of mh-temp buffer, where output can be parsed and | |
571 used. | |
572 Returns value of `call-process', which is 0 for success, unless | |
573 RAISE-ERROR is non-nil, in which case an error is signaled if | |
574 `call-process' returns non-0." | |
575 (set-buffer (get-buffer-create mh-temp-buffer)) | |
576 (erase-buffer) | |
577 (let ((value | |
578 (apply 'call-process | |
579 (expand-file-name command mh-progs) nil t nil | |
580 args))) | |
581 (goto-char (point-min)) | |
582 (if raise-error | |
583 (mh-handle-process-error command value) | |
584 value))) | |
585 | |
586 (defun mh-exec-cmd-output (command display &rest args) | |
587 "Execute MH command COMMAND with DISPLAY flag and ARGS. | |
588 Put the output into buffer after point. | |
589 Set mark after inserted text. | |
590 Output is expected to be shown to user, not parsed by MH-E." | |
591 (push-mark (point) t) | |
592 (apply 'call-process | |
593 (expand-file-name command mh-progs) nil t display | |
594 (mh-list-to-string args)) | |
595 | |
596 ;; The following is used instead of 'exchange-point-and-mark because the | |
597 ;; latter activates the current region (between point and mark), which | |
598 ;; turns on highlighting. So prior to this bug fix, doing "inc" would | |
599 ;; highlight a region containing the new messages, which is undesirable. | |
600 ;; The bug wasn't seen in emacs21 but still occurred in XEmacs21.4. | |
601 (mh-exchange-point-and-mark-preserving-active-mark)) | |
602 | |
603 ;; Shush compiler. | |
604 (eval-when-compile (mh-do-in-xemacs (defvar mark-active))) | |
605 | |
606 (defun mh-exchange-point-and-mark-preserving-active-mark () | |
607 "Put the mark where point is now, and point where the mark is now. | |
608 This command works even when the mark is not active, and | |
609 preserves whether the mark is active or not." | |
610 (interactive nil) | |
611 (let ((is-active (and (boundp 'mark-active) mark-active))) | |
612 (let ((omark (mark t))) | |
613 (if (null omark) | |
614 (error "No mark set in this buffer")) | |
615 (set-mark (point)) | |
616 (goto-char omark) | |
617 (if (boundp 'mark-active) | |
618 (setq mark-active is-active)) | |
619 nil))) | |
620 | |
621 (defun mh-exec-lib-cmd-output (command &rest args) | |
622 "Execute MH library command COMMAND with ARGS. | |
623 Put the output into buffer after point. | |
624 Set mark after inserted text." | |
625 (apply 'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args)) | |
626 | |
627 (defun mh-handle-process-error (command status) | |
628 "Raise error if COMMAND returned non-zero STATUS, otherwise return STATUS." | |
629 (if (equal status 0) | |
630 status | |
631 (goto-char (point-min)) | |
632 (insert (if (integerp status) | |
633 (format "%s: exit code %d\n" command status) | |
634 (format "%s: %s\n" command status))) | |
635 (save-excursion | |
636 (let ((error-message (buffer-substring (point-min) (point-max)))) | |
637 (set-buffer (get-buffer-create mh-log-buffer)) | |
638 (mh-truncate-log-buffer) | |
639 (insert error-message))) | |
640 (error "%s failed, check buffer %s for error message" | |
641 command mh-log-buffer))) | |
642 | |
643 | |
644 | |
645 ;;; Variant Support | |
646 | |
647 (defcustom mh-path nil | |
648 "*Additional list of directories to search for MH. | |
649 See `mh-variant'." | |
650 :group 'mh-e | |
651 :type '(repeat (directory))) | |
652 | |
653 (defun mh-variants () | |
654 "Return a list of installed variants of MH on the system. | |
655 This function looks for MH in `mh-sys-path', `mh-path' and | |
656 `exec-path'. The format of the list of variants that is returned | |
657 is described by the variable `mh-variants'." | |
658 (if mh-variants | |
659 mh-variants | |
660 (let ((list-unique)) | |
661 ;; Make a unique list of directories, keeping the given order. | |
662 ;; We don't want the same MH variant to be listed multiple times. | |
663 (loop for dir in (append mh-path mh-sys-path exec-path) do | |
664 (setq dir (file-chase-links (directory-file-name dir))) | |
665 (add-to-list 'list-unique dir)) | |
666 (loop for dir in (nreverse list-unique) do | |
667 (when (and dir (file-directory-p dir) (file-readable-p dir)) | |
668 (let ((variant (mh-variant-info dir))) | |
669 (if variant | |
670 (add-to-list 'mh-variants variant))))) | |
671 mh-variants))) | |
672 | |
673 (defun mh-variant-info (dir) | |
674 "Return MH variant found in DIR, or nil if none present." | |
675 (save-excursion | |
676 (let ((tmp-buffer (get-buffer-create mh-temp-buffer))) | |
677 (set-buffer tmp-buffer) | |
678 (cond | |
679 ((mh-variant-mh-info dir)) | |
680 ((mh-variant-nmh-info dir)) | |
681 ((mh-variant-mu-mh-info dir)))))) | |
682 | |
683 (defun mh-variant-mh-info (dir) | |
684 "Return info for MH variant in DIR assuming a temporary buffer is setup." | |
685 ;; MH does not have the -version option. | |
686 ;; Its version number is included in the output of "-help" as: | |
687 ;; | |
688 ;; version: MH 6.8.4 #2[UCI] (burrito) of Fri Jan 15 20:01:39 EST 1999 | |
689 ;; options: [ATHENA] [BIND] [DUMB] [LIBLOCKFILE] [LOCALE] [MAILGROUP] [MHE] | |
690 ;; [MHRC] [MIME] [MORE='"/usr/bin/sensible-pager"'] [NLINK_HACK] | |
691 ;; [NORUSERPASS] [OVERHEAD] [POP] [POPSERVICE='"pop-3"'] [RENAME] | |
692 ;; [RFC1342] [RPATHS] [RPOP] [SENDMTS] [SMTP] [SOCKETS] | |
693 ;; [SPRINTFTYPE=int] [SVR4] [SYS5] [SYS5DIR] [TERMINFO] | |
694 ;; [TYPESIG=void] [UNISTD] [UTK] [VSPRINTF] | |
695 (let ((mhparam (expand-file-name "mhparam" dir))) | |
696 (when (mh-file-command-p mhparam) | |
697 (erase-buffer) | |
698 (call-process mhparam nil '(t nil) nil "-help") | |
1399 (goto-char (point-min)) | 699 (goto-char (point-min)) |
1400 (if (re-search-forward " has \\([0-9]+\\) " nil t) | 700 (when (search-forward-regexp "version: MH \\(\\S +\\)" nil t) |
1401 (values (string-to-number (match-string 1)) u folder) | 701 (let ((version (format "MH %s" (match-string 1)))) |
1402 (values 0 u folder))))) | 702 (erase-buffer) |
1403 | 703 (call-process mhparam nil '(t nil) nil "libdir") |
1404 (defun mh-folder-size-flist (folder) | 704 (goto-char (point-min)) |
1405 "Find size of FOLDER using \"flist\"." | 705 (when (search-forward-regexp "^.*$" nil t) |
1406 (with-temp-buffer | 706 (let ((libdir (match-string 0))) |
1407 (call-process (expand-file-name "flist" mh-progs) nil t nil "-showzero" | 707 `(,version |
1408 "-norecurse" folder "-sequence" (symbol-name mh-unseen-seq)) | 708 (variant mh) |
709 (mh-lib-progs ,libdir) | |
710 (mh-lib ,libdir) | |
711 (mh-progs ,dir) | |
712 (flists nil))))))))) | |
713 | |
714 (defun mh-variant-mu-mh-info (dir) | |
715 "Return info for GNU mailutils variant in DIR. | |
716 This assumes that a temporary buffer is setup." | |
717 ;; 'mhparam -version' output: | |
718 ;; mhparam (GNU mailutils 0.3.2) | |
719 (let ((mhparam (expand-file-name "mhparam" dir))) | |
720 (when (mh-file-command-p mhparam) | |
721 (erase-buffer) | |
722 (call-process mhparam nil '(t nil) nil "-version") | |
723 (goto-char (point-min)) | |
724 (when (search-forward-regexp "mhparam (\\(GNU [Mm]ailutils \\S +\\))" | |
725 nil t) | |
726 (let ((version (match-string 1)) | |
727 (mh-progs dir)) | |
728 `(,version | |
729 (variant mu-mh) | |
730 (mh-lib-progs ,(mh-profile-component "libdir")) | |
731 (mh-lib ,(mh-profile-component "etcdir")) | |
732 (mh-progs ,dir) | |
733 (flists ,(file-exists-p | |
734 (expand-file-name "flists" dir))))))))) | |
735 | |
736 (defun mh-variant-nmh-info (dir) | |
737 "Return info for nmh variant in DIR assuming a temporary buffer is setup." | |
738 ;; `mhparam -version' outputs: | |
739 ;; mhparam -- nmh-1.1-RC1 [compiled on chaak at Fri Jun 20 11:03:28 PDT 2003] | |
740 (let ((mhparam (expand-file-name "mhparam" dir))) | |
741 (when (mh-file-command-p mhparam) | |
742 (erase-buffer) | |
743 (call-process mhparam nil '(t nil) nil "-version") | |
744 (goto-char (point-min)) | |
745 (when (search-forward-regexp "mhparam -- nmh-\\(\\S +\\)" nil t) | |
746 (let ((version (format "nmh %s" (match-string 1))) | |
747 (mh-progs dir)) | |
748 `(,version | |
749 (variant nmh) | |
750 (mh-lib-progs ,(mh-profile-component "libdir")) | |
751 (mh-lib ,(mh-profile-component "etcdir")) | |
752 (mh-progs ,dir) | |
753 (flists ,(file-exists-p | |
754 (expand-file-name "flists" dir))))))))) | |
755 | |
756 (defun mh-file-command-p (file) | |
757 "Return t if file FILE is the name of a executable regular file." | |
758 (and (file-regular-p file) (file-executable-p file))) | |
759 | |
760 (defun mh-variant-set-variant (variant) | |
761 "Setup the system variables for the MH variant named VARIANT. | |
762 If VARIANT is a string, use that key in the alist returned by the | |
763 function `mh-variants'. | |
764 If VARIANT is a symbol, select the first entry that matches that | |
765 variant." | |
766 (cond | |
767 ((stringp variant) ;e.g. "nmh 1.1-RC1" | |
768 (when (assoc variant (mh-variants)) | |
769 (let* ((alist (cdr (assoc variant (mh-variants)))) | |
770 (lib-progs (cadr (assoc 'mh-lib-progs alist))) | |
771 (lib (cadr (assoc 'mh-lib alist))) | |
772 (progs (cadr (assoc 'mh-progs alist))) | |
773 (flists (cadr (assoc 'flists alist)))) | |
774 ;;(set-default mh-variant variant) | |
775 (setq mh-x-mailer-string nil | |
776 mh-flists-present-flag flists | |
777 mh-lib-progs lib-progs | |
778 mh-lib lib | |
779 mh-progs progs | |
780 mh-variant-in-use variant)))) | |
781 ((symbolp variant) ;e.g. 'nmh (pick the first match) | |
782 (loop for variant-list in (mh-variants) | |
783 when (eq variant (cadr (assoc 'variant (cdr variant-list)))) | |
784 return (let* ((version (car variant-list)) | |
785 (alist (cdr variant-list)) | |
786 (lib-progs (cadr (assoc 'mh-lib-progs alist))) | |
787 (lib (cadr (assoc 'mh-lib alist))) | |
788 (progs (cadr (assoc 'mh-progs alist))) | |
789 (flists (cadr (assoc 'flists alist)))) | |
790 ;;(set-default mh-variant flavor) | |
791 (setq mh-x-mailer-string nil | |
792 mh-flists-present-flag flists | |
793 mh-lib-progs lib-progs | |
794 mh-lib lib | |
795 mh-progs progs | |
796 mh-variant-in-use version) | |
797 t))))) | |
798 | |
799 (defun mh-variant-p (&rest variants) | |
800 "Return t if variant is any of VARIANTS. | |
801 Currently known variants are 'MH, 'nmh, and 'mu-mh." | |
802 (let ((variant-in-use | |
803 (cadr (assoc 'variant (assoc mh-variant-in-use (mh-variants)))))) | |
804 (not (null (member variant-in-use variants))))) | |
805 | |
806 (defun mh-profile-component (component) | |
807 "Return COMPONENT value from mhparam, or nil if unset." | |
808 (save-excursion | |
809 (mh-exec-cmd-quiet nil "mhparam" "-components" component) | |
810 (mh-profile-component-value component))) | |
811 | |
812 (defun mh-profile-component-value (component) | |
813 "Find and return the value of COMPONENT in the current buffer. | |
814 Returns nil if the component is not in the buffer." | |
815 (let ((case-fold-search t)) | |
1409 (goto-char (point-min)) | 816 (goto-char (point-min)) |
1410 (multiple-value-bind (folder unseen total) | 817 (cond ((not (re-search-forward (format "^%s:" component) nil t)) nil) |
1411 (mh-parse-flist-output-line | 818 ((looking-at "[\t ]*$") nil) |
1412 (buffer-substring (point) (line-end-position))) | 819 (t |
1413 (values total unseen folder)))) | 820 (re-search-forward "[\t ]*\\([^\t \n].*\\)$" nil t) |
1414 | 821 (let ((start (match-beginning 1))) |
1415 (defun mh-folder-size (folder) | 822 (end-of-line) |
1416 "Find size of FOLDER." | 823 (buffer-substring start (point))))))) |
1417 (if mh-flists-present-flag | 824 |
1418 (mh-folder-size-flist folder) | 825 (defun mh-variant-set (variant) |
1419 (mh-folder-size-folder folder))) | 826 "Set the MH variant to VARIANT. |
1420 | 827 Sets `mh-progs', `mh-lib', `mh-lib-progs' and |
1421 (defun mh-visit-folder (folder &optional range index-data) | 828 `mh-flists-present-flag'. |
1422 "Visit FOLDER. | 829 If the VARIANT is \"autodetect\", then first try nmh, then MH and |
1423 | 830 finally GNU mailutils." |
1424 When you want to read the messages that you have refiled into folders, | 831 (interactive |
1425 use this command to visit the folder. You are prompted for the folder | 832 (list (completing-read |
1426 name. | 833 "MH variant: " |
1427 | 834 (mapcar (lambda (x) (list (car x))) (mh-variants)) |
1428 The folder buffer will show just unseen messages if there are any; | 835 nil t))) |
1429 otherwise, it will show all the messages in the buffer as long there | 836 (let ((valid-list (mapcar (lambda (x) (car x)) (mh-variants)))) |
1430 are fewer than `mh-large-folder' messages. If there are more, then you | 837 (cond |
1431 are prompted for a range of messages to scan. | 838 ((eq variant 'none)) |
1432 | 839 ((eq variant 'autodetect) |
1433 You can provide a prefix argument in order to specify a RANGE of | 840 (cond |
1434 messages to show when you visit the folder. In this case, regions are | 841 ((mh-variant-set-variant 'nmh) |
1435 not used to specify the range and `mh-large-folder' is ignored. Check | 842 (message "%s installed as MH variant" mh-variant-in-use)) |
1436 the documentation of `mh-interactive-range' to see how RANGE is read | 843 ((mh-variant-set-variant 'mh) |
1437 in interactive use. | 844 (message "%s installed as MH variant" mh-variant-in-use)) |
1438 | 845 ((mh-variant-set-variant 'mu-mh) |
1439 Note that this command can also be used to create folders. If you | 846 (message "%s installed as MH variant" mh-variant-in-use)) |
1440 specify a folder that does not exist, you will be prompted to create | 847 (t |
1441 it. | 848 (message "No MH variant found on the system")))) |
1442 | 849 ((member variant valid-list) |
1443 Do not call this function from outside MH-E; use \\[mh-rmail] instead. | 850 (when (not (mh-variant-set-variant variant)) |
1444 | 851 (message "Warning: %s variant not found. Autodetecting..." variant) |
1445 If, in a program, RANGE is nil (the default), then all messages in | 852 (mh-variant-set 'autodetect))) |
1446 FOLDER are displayed. If an index buffer is being created then | 853 (t |
1447 INDEX-DATA is used to initialize the index buffer specific data | 854 (message "Unknown variant; use %s" |
1448 structures." | 855 (mapconcat '(lambda (x) (format "%s" (car x))) |
1449 (interactive (let ((folder-name (mh-prompt-for-folder "Visit" mh-inbox t))) | 856 (mh-variants) " or ")))))) |
1450 (list folder-name | 857 |
1451 (mh-read-range "Scan" folder-name t nil | 858 (defcustom mh-variant 'autodetect |
1452 current-prefix-arg | 859 "*Specifies the variant used by MH-E. |
1453 mh-interpret-number-as-range-flag)))) | 860 |
1454 (let ((config (current-window-configuration)) | 861 The default setting of this option is \"Auto-detect\" which means |
1455 (current-buffer (current-buffer)) | 862 that MH-E will automatically choose the first of nmh, MH, or GNU |
1456 (threaded-view-flag mh-show-threads-flag)) | 863 mailutils that it finds in the directories listed in |
1457 (delete-other-windows) | 864 `mh-path' (which you can customize), `mh-sys-path', and |
1458 (save-excursion | 865 `exec-path'. If, for example, you have both nmh and mailutils |
1459 (when (get-buffer folder) | 866 installed and `mh-variant-in-use' was initialized to nmh but you |
1460 (set-buffer folder) | 867 want to use mailutils, then you can set this option to |
1461 (setq threaded-view-flag (memq 'unthread mh-view-ops)))) | 868 \"mailutils\". |
1462 (when index-data | 869 |
1463 (mh-make-folder folder) | 870 When this variable is changed, MH-E resets `mh-progs', `mh-lib', |
1464 (setq mh-index-data (car index-data) | 871 `mh-lib-progs', `mh-flists-present-flag', and `mh-variant-in-use' |
1465 mh-index-msg-checksum-map (make-hash-table :test #'equal) | 872 accordingly." |
1466 mh-index-checksum-origin-map (make-hash-table :test #'equal)) | 873 :type `(radio |
1467 (mh-index-update-maps folder (cadr index-data)) | 874 (const :tag "Auto-detect" autodetect) |
1468 (mh-index-create-sequences)) | 875 ,@(mapcar (lambda (x) `(const ,(car x))) (mh-variants))) |
1469 (mh-scan-folder folder (or range "all")) | 876 :set (lambda (symbol value) |
1470 (cond ((and threaded-view-flag | 877 (set-default symbol value) ;Done in mh-variant-set-variant! |
1471 (save-excursion | 878 (mh-variant-set value)) |
1472 (goto-char (point-min)) | 879 :group 'mh-e) |
1473 (or (null mh-large-folder) | |
1474 (not (equal (forward-line (1+ mh-large-folder)) 0)) | |
1475 (and (message "Not threading since the number of messages exceeds `mh-large-folder'") | |
1476 nil)))) | |
1477 (mh-toggle-threads)) | |
1478 (mh-index-data | |
1479 (mh-index-insert-folder-headers))) | |
1480 (unless (eq current-buffer (current-buffer)) | |
1481 (setq mh-previous-window-config config))) | |
1482 nil) | |
1483 | |
1484 (defun mh-update-sequences () | |
1485 "Flush MH-E's state out to MH. | |
1486 | |
1487 This function updates the sequence specified by your | |
1488 \"Unseen-Sequence:\" profile component, \"cur\", and the sequence | |
1489 listed by the `mh-tick-seq' option which is \"tick\" by default. | |
1490 The message at the cursor is used for \"cur\"." | |
1491 (interactive) | |
1492 ;; mh-update-sequences is the opposite of mh-read-folder-sequences, | |
1493 ;; which updates MH-E's state from MH. | |
1494 (let ((folder-set (mh-update-unseen)) | |
1495 (new-cur (mh-get-msg-num nil))) | |
1496 (if new-cur | |
1497 (let ((seq-entry (mh-find-seq 'cur))) | |
1498 (mh-remove-cur-notation) | |
1499 (setcdr seq-entry | |
1500 (list new-cur)) ;delete-seq-locally, add-msgs-to-seq | |
1501 (mh-define-sequence 'cur (list new-cur)) | |
1502 (beginning-of-line) | |
1503 (if (looking-at mh-scan-good-msg-regexp) | |
1504 (mh-notate-cur))) | |
1505 (or folder-set | |
1506 (save-excursion | |
1507 ;; psg - mh-current-folder is nil if mh-summary-height < 4 ! | |
1508 ;; So I added this sanity check. | |
1509 (if (stringp mh-current-folder) | |
1510 (mh-exec-cmd-quiet t "folder" mh-current-folder "-fast") | |
1511 (mh-exec-cmd-quiet t "folder" "-fast"))))))) | |
1512 | 880 |
1513 | 881 |
1514 | 882 |
1515 ;;; Support routines. | 883 ;;; MH-E Customization |
1516 | 884 |
1517 (defun mh-delete-a-msg (message) | 885 ;; All of the defgroups, defcustoms, and deffaces in MH-E are found |
1518 "Delete MESSAGE. | 886 ;; here. This makes it possible to customize modules that aren't |
1519 If MESSAGE is nil then the message at point is deleted. | 887 ;; loaded yet. It also makes it easier to organize the customization |
1520 The hook `mh-delete-msg-hook' is called after you mark a message | 888 ;; groups. |
1521 for deletion. For example, a past maintainer of MH-E used this | 889 |
1522 once when he kept statistics on his mail usage." | 890 ;; This section contains the following sub-sections: |
1523 (save-excursion | 891 |
1524 (if (numberp message) | 892 ;; 1. MH-E Customization Groups |
1525 (mh-goto-msg message nil t) | 893 |
1526 (beginning-of-line) | 894 ;; These are the customization group definitions. Every group has a |
1527 (setq message (mh-get-msg-num t))) | 895 ;; associated manual node. The ordering is alphabetical, except for |
1528 (if (looking-at mh-scan-refiled-msg-regexp) | 896 ;; the groups mh-faces and mh-hooks which are last . |
1529 (error "Message %d is refiled; undo refile before deleting" message)) | 897 |
1530 (if (looking-at mh-scan-deleted-msg-regexp) | 898 ;; 2. MH-E Customization |
1531 nil | 899 |
1532 (mh-set-folder-modified-p t) | 900 ;; These are the actual customization variables. There is a |
1533 (setq mh-delete-list (cons message mh-delete-list)) | 901 ;; sub-section for each group in the MH-E Customization Groups |
1534 (mh-notate nil mh-note-deleted mh-cmd-note) | 902 ;; section, in the same order, separated by page breaks. Within |
1535 (run-hooks 'mh-delete-msg-hook)))) | 903 ;; each section, variables are sorted alphabetically. |
1536 | 904 |
1537 (defun mh-refile-a-msg (message folder) | 905 ;; 3. Hooks |
1538 "Refile MESSAGE in FOLDER. | 906 |
1539 If MESSAGE is nil then the message at point is refiled. | 907 ;; All hooks must be placed in the mh-hook group; in addition, add |
1540 Folder is a symbol, not a string. | 908 ;; the group associated with the manual node in which the hook is |
1541 The hook `mh-refile-msg-hook' is called after a message is marked to | 909 ;; described. Since the mh-hook group appears near the end of this |
1542 be refiled." | 910 ;; section, the hooks will appear at the end of these other groups. |
1543 (save-excursion | 911 |
1544 (if (numberp message) | 912 ;; 4. Faces |
1545 (mh-goto-msg message nil t) | 913 |
1546 (beginning-of-line) | 914 ;; All faces must be placed in the mh-faces group; in addition, add |
1547 (setq message (mh-get-msg-num t))) | 915 ;; the group associated with the manual node in which the face is |
1548 (cond ((looking-at mh-scan-deleted-msg-regexp) | 916 ;; described. Since the mh-faces group appears near the end of this |
1549 (error "Message %d is deleted; undo delete before moving" message)) | 917 ;; section, the faces will appear at the end of these other groups. |
1550 ((looking-at mh-scan-refiled-msg-regexp) | 918 |
1551 (if (y-or-n-p | 919 (defun mh-customize (&optional delete-other-windows-flag) |
1552 (format "Message %d already refiled; copy to %s as well? " | 920 "Customize MH-E variables. |
1553 message folder)) | 921 If optional argument DELETE-OTHER-WINDOWS-FLAG is non-nil, other |
1554 (mh-exec-cmd "refile" (mh-get-msg-num t) "-link" | 922 windows in the frame are removed." |
1555 "-src" mh-current-folder | 923 (interactive "P") |
1556 (symbol-name folder)) | 924 (customize-group 'mh-e) |
1557 (message "Message not copied"))) | 925 (when delete-other-windows-flag |
1558 (t | 926 (delete-other-windows))) |
1559 (mh-set-folder-modified-p t) | |
1560 (cond ((null (assoc folder mh-refile-list)) | |
1561 (push (list folder message) mh-refile-list)) | |
1562 ((not (member message (cdr (assoc folder mh-refile-list)))) | |
1563 (push message (cdr (assoc folder mh-refile-list))))) | |
1564 (mh-notate nil mh-note-refiled mh-cmd-note) | |
1565 (run-hooks 'mh-refile-msg-hook))))) | |
1566 | |
1567 (defun mh-next-msg (&optional wait-after-complaining-flag) | |
1568 "Move backward or forward to the next undeleted message in the buffer. | |
1569 If optional argument WAIT-AFTER-COMPLAINING-FLAG is non-nil and | |
1570 we are at the last message, then wait for a second after telling | |
1571 the user that there aren't any more unread messages." | |
1572 (if (eq mh-next-direction 'forward) | |
1573 (mh-next-undeleted-msg 1 wait-after-complaining-flag) | |
1574 (mh-previous-undeleted-msg 1 wait-after-complaining-flag))) | |
1575 | |
1576 (defun mh-next-unread-msg (&optional count) | |
1577 "Display next unread message. | |
1578 | |
1579 This command can be given a prefix argument COUNT to specify how | |
1580 many unread messages to skip." | |
1581 (interactive "p") | |
1582 (unless (> count 0) | |
1583 (error "The function `mh-next-unread-msg' expects positive argument")) | |
1584 (setq count (1- count)) | |
1585 (let ((unread-sequence (reverse (cdr (assoc mh-unseen-seq mh-seq-list)))) | |
1586 (cur-msg (mh-get-msg-num nil))) | |
1587 (cond ((and (not cur-msg) (not (bobp)) | |
1588 ;; If we are at the end of the buffer back up one line and go | |
1589 ;; to unread message after that. | |
1590 (progn | |
1591 (forward-line -1) | |
1592 (setq cur-msg (mh-get-msg-num nil))) | |
1593 nil)) | |
1594 ((or (null unread-sequence) (not cur-msg)) | |
1595 ;; No unread message or there aren't any messages in buffer... | |
1596 (message "No more unread messages")) | |
1597 ((progn | |
1598 ;; Skip messages | |
1599 (while (and unread-sequence (>= cur-msg (car unread-sequence))) | |
1600 (setq unread-sequence (cdr unread-sequence))) | |
1601 (while (> count 0) | |
1602 (setq unread-sequence (cdr unread-sequence)) | |
1603 (setq count (1- count))) | |
1604 (not (car unread-sequence))) | |
1605 (message "No more unread messages")) | |
1606 (t (loop for msg in unread-sequence | |
1607 when (mh-goto-msg msg t) return nil | |
1608 finally (message "No more unread messages")))))) | |
1609 | |
1610 (defun mh-set-scan-mode () | |
1611 "Display the scan listing buffer, but do not show a message." | |
1612 (if (get-buffer mh-show-buffer) | |
1613 (delete-windows-on mh-show-buffer)) | |
1614 (mh-showing-mode 0) | |
1615 (force-mode-line-update) | |
1616 (if mh-recenter-summary-flag | |
1617 (mh-recenter nil))) | |
1618 | |
1619 (defun mh-undo-msg (msg) | |
1620 "Undo the deletion or refile of one MSG. | |
1621 If MSG is nil then act on the message at point" | |
1622 (save-excursion | |
1623 (if (numberp msg) | |
1624 (mh-goto-msg msg t t) | |
1625 (beginning-of-line) | |
1626 (setq msg (mh-get-msg-num t))) | |
1627 (cond ((memq msg mh-delete-list) | |
1628 (setq mh-delete-list (delq msg mh-delete-list))) | |
1629 (t | |
1630 (dolist (folder-msg-list mh-refile-list) | |
1631 (setf (cdr folder-msg-list) (remove msg (cdr folder-msg-list)))) | |
1632 (setq mh-refile-list (loop for x in mh-refile-list | |
1633 unless (null (cdr x)) collect x)))) | |
1634 (mh-notate nil ? mh-cmd-note))) | |
1635 | 927 |
1636 | 928 |
1637 | 929 |
1638 ;;; The folder data abstraction. | 930 ;;; MH-E Customization Groups |
1639 | 931 |
1640 (defvar mh-index-data-file ".mhe_index" | 932 (defgroup mh-e nil |
1641 "MH-E specific file where index seach info is stored.") | 933 "Emacs interface to the MH mail system. |
1642 | 934 MH is the Rand Mail Handler. Other implementations include nmh |
1643 (defun mh-make-folder (name) | 935 and GNU mailutils." |
1644 "Create a new mail folder called NAME. | 936 :link '(custom-manual "(mh-e)Top") |
1645 Make it the current folder." | 937 :group 'mail) |
1646 (switch-to-buffer name) | 938 |
1647 (setq buffer-read-only nil) | 939 (defgroup mh-alias nil |
1648 (erase-buffer) | 940 "Aliases." |
1649 (if mh-adaptive-cmd-note-flag | 941 :link '(custom-manual "(mh-e)Aliases") |
1650 (mh-set-cmd-note (mh-msg-num-width-to-column (mh-msg-num-width name)))) | 942 :prefix "mh-alias-" |
1651 (setq buffer-read-only t) | 943 :group 'mh-e) |
1652 (mh-folder-mode) | 944 |
1653 (mh-set-folder-modified-p nil) | 945 (defgroup mh-folder nil |
1654 (setq buffer-file-name mh-folder-filename) | 946 "Organizing your mail with folders." |
1655 (when (and (not mh-index-data) | 947 :prefix "mh-" |
1656 (file-exists-p (concat buffer-file-name mh-index-data-file))) | 948 :link '(custom-manual "(mh-e)Folders") |
1657 (mh-index-read-data)) | 949 :group 'mh-e) |
1658 (mh-make-folder-mode-line)) | 950 |
1659 | 951 (defgroup mh-folder-selection nil |
1660 ;; Ensure new buffers won't get this mode if default-major-mode is nil. | 952 "Folder selection." |
1661 (put 'mh-folder-mode 'mode-class 'special) | 953 :prefix "mh-" |
954 :link '(custom-manual "(mh-e)Folder Selection") | |
955 :group 'mh-e) | |
956 | |
957 (defgroup mh-identity nil | |
958 "Identities." | |
959 :link '(custom-manual "(mh-e)Identities") | |
960 :prefix "mh-identity-" | |
961 :group 'mh-e) | |
962 | |
963 (defgroup mh-inc nil | |
964 "Incorporating your mail." | |
965 :prefix "mh-inc-" | |
966 :link '(custom-manual "(mh-e)Incorporating Mail") | |
967 :group 'mh-e) | |
968 | |
969 (defgroup mh-junk nil | |
970 "Dealing with junk mail." | |
971 :link '(custom-manual "(mh-e)Junk") | |
972 :prefix "mh-junk-" | |
973 :group 'mh-e) | |
974 | |
975 (defgroup mh-letter nil | |
976 "Editing a draft." | |
977 :prefix "mh-" | |
978 :link '(custom-manual "(mh-e)Editing Drafts") | |
979 :group 'mh-e) | |
980 | |
981 (defgroup mh-ranges nil | |
982 "Ranges." | |
983 :prefix "mh-" | |
984 :link '(custom-manual "(mh-e)Ranges") | |
985 :group 'mh-e) | |
986 | |
987 (defgroup mh-scan-line-formats nil | |
988 "Scan line formats." | |
989 :link '(custom-manual "(mh-e)Scan Line Formats") | |
990 :prefix "mh-" | |
991 :group 'mh-e) | |
992 | |
993 (defgroup mh-search nil | |
994 "Searching." | |
995 :link '(custom-manual "(mh-e)Searching") | |
996 :prefix "mh-search-" | |
997 :group 'mh-e) | |
998 | |
999 (defgroup mh-sending-mail nil | |
1000 "Sending mail." | |
1001 :prefix "mh-" | |
1002 :link '(custom-manual "(mh-e)Sending Mail") | |
1003 :group 'mh-e) | |
1004 | |
1005 (defgroup mh-sequences nil | |
1006 "Sequences." | |
1007 :prefix "mh-" | |
1008 :link '(custom-manual "(mh-e)Sequences") | |
1009 :group 'mh-e) | |
1010 | |
1011 (defgroup mh-show nil | |
1012 "Reading your mail." | |
1013 :prefix "mh-" | |
1014 :link '(custom-manual "(mh-e)Reading Mail") | |
1015 :group 'mh-e) | |
1016 | |
1017 (defgroup mh-speedbar nil | |
1018 "The speedbar." | |
1019 :prefix "mh-speed-" | |
1020 :link '(custom-manual "(mh-e)Speedbar") | |
1021 :group 'mh-e) | |
1022 | |
1023 (defgroup mh-thread nil | |
1024 "Threading." | |
1025 :prefix "mh-thread-" | |
1026 :link '(custom-manual "(mh-e)Threading") | |
1027 :group 'mh-e) | |
1028 | |
1029 (defgroup mh-tool-bar nil | |
1030 "The tool bar" | |
1031 :link '(custom-manual "(mh-e)Tool Bar") | |
1032 :prefix "mh-" | |
1033 :group 'mh-e) | |
1034 | |
1035 (defgroup mh-hooks nil | |
1036 "MH-E hooks." | |
1037 :link '(custom-manual "(mh-e)Top") | |
1038 :prefix "mh-" | |
1039 :group 'mh-e) | |
1040 | |
1041 (defgroup mh-faces nil | |
1042 "Faces used in MH-E." | |
1043 :link '(custom-manual "(mh-e)Top") | |
1044 :prefix "mh-" | |
1045 :group 'faces | |
1046 :group 'mh-e) | |
1662 | 1047 |
1663 | 1048 |
1664 | 1049 |
1665 ;;; Build mh-folder-mode menu | 1050 ;;; Emacs Interface to the MH Mail System (:group mh-e) |
1666 | 1051 |
1667 ;; Menu extracted from mh-menubar.el V1.1 (31 July 2001) | 1052 ;; See Variant Support, above. |
1668 ;; Menus for folder mode: folder, message, sequence (in that order) | 1053 |
1669 ;; folder-mode "Sequence" menu | 1054 ;;; Aliases (:group 'mh-alias) |
1670 (easy-menu-define | 1055 |
1671 mh-folder-sequence-menu mh-folder-mode-map "Menu for MH-E folder-sequence." | 1056 (defcustom mh-alias-completion-ignore-case-flag t |
1672 '("Sequence" | 1057 "*Non-nil means don't consider case significant in MH alias completion. |
1673 ["Add Message to Sequence..." mh-put-msg-in-seq (mh-get-msg-num nil)] | 1058 |
1674 ["List Sequences for Message" mh-msg-is-in-seq (mh-get-msg-num nil)] | 1059 As MH ignores case in the aliases, so too does MH-E. However, you |
1675 ["Delete Message from Sequence..." mh-delete-msg-from-seq | 1060 may turn off this option to make case significant which can be |
1676 (mh-get-msg-num nil)] | 1061 used to segregate completion of your aliases. You might use |
1677 ["List Sequences in Folder..." mh-list-sequences t] | 1062 lowercase for mailing lists and uppercase for people." |
1678 ["Delete Sequence..." mh-delete-seq t] | 1063 :type 'boolean |
1679 ["Narrow to Sequence..." mh-narrow-to-seq t] | 1064 :group 'mh-alias) |
1680 ["Widen from Sequence" mh-widen mh-folder-view-stack] | 1065 |
1681 "--" | 1066 (defcustom mh-alias-expand-aliases-flag nil |
1682 ["Narrow to Subject Sequence" mh-narrow-to-subject t] | 1067 "*Non-nil means to expand aliases entered in the minibuffer. |
1683 ["Narrow to Tick Sequence" mh-narrow-to-tick | 1068 |
1684 (and mh-tick-seq (mh-seq-msgs (mh-find-seq mh-tick-seq)))] | 1069 In other words, aliases entered in the minibuffer will be |
1685 ["Delete Rest of Same Subject" mh-delete-subject t] | 1070 expanded to the full address in the message draft. By default, |
1686 ["Toggle Tick Mark" mh-toggle-tick t] | 1071 this expansion is not performed." |
1687 "--" | 1072 :type 'boolean |
1688 ["Push State Out to MH" mh-update-sequences t])) | 1073 :group 'mh-alias) |
1689 | 1074 |
1690 ;; folder-mode "Message" menu | 1075 (defcustom mh-alias-flash-on-comma t |
1691 (easy-menu-define | 1076 "*Specify whether to flash address or warn on translation. |
1692 mh-folder-message-menu mh-folder-mode-map "Menu for MH-E folder-message." | 1077 |
1693 '("Message" | 1078 This option controls the behavior when a [comma] is pressed while |
1694 ["Show Message" mh-show (mh-get-msg-num nil)] | 1079 entering aliases or addresses. The default setting flashes the |
1695 ["Show Message with Header" mh-header-display (mh-get-msg-num nil)] | 1080 address associated with an address in the minibuffer briefly, but |
1696 ["Next Message" mh-next-undeleted-msg t] | 1081 does not display a warning if the alias is not found." |
1697 ["Previous Message" mh-previous-undeleted-msg t] | 1082 :type '(choice (const :tag "Flash but Don't Warn If No Alias" t) |
1698 ["Go to First Message" mh-first-msg t] | 1083 (const :tag "Flash and Warn If No Alias" 1) |
1699 ["Go to Last Message" mh-last-msg t] | 1084 (const :tag "Don't Flash Nor Warn If No Alias" nil)) |
1700 ["Go to Message by Number..." mh-goto-msg t] | 1085 :group 'mh-alias) |
1701 ["Modify Message" mh-modify t] | 1086 |
1702 ["Delete Message" mh-delete-msg (mh-get-msg-num nil)] | 1087 (defcustom mh-alias-insert-file nil |
1703 ["Refile Message" mh-refile-msg (mh-get-msg-num nil)] | 1088 "*Filename used to store a new MH-E alias. |
1704 ["Undo Delete/Refile" mh-undo (mh-outstanding-commands-p)] | 1089 |
1705 ["Execute Delete/Refile" mh-execute-commands | 1090 The default setting of this option is \"Use Aliasfile Profile |
1706 (mh-outstanding-commands-p)] | 1091 Component\". This option can also hold the name of a file or a |
1707 "--" | 1092 list a file names. If this option is set to a list of file names, |
1708 ["Compose a New Message" mh-send t] | 1093 or the \"Aliasfile:\" profile component contains more than one file |
1709 ["Reply to Message..." mh-reply (mh-get-msg-num nil)] | 1094 name, MH-E will prompt for one of them when MH-E adds an alias." |
1710 ["Forward Message..." mh-forward (mh-get-msg-num nil)] | 1095 :type '(choice (const :tag "Use Aliasfile Profile Component" nil) |
1711 ["Redistribute Message..." mh-redistribute (mh-get-msg-num nil)] | 1096 (file :tag "Alias File") |
1712 ["Edit Message Again" mh-edit-again (mh-get-msg-num nil)] | 1097 (repeat :tag "List of Alias Files" file)) |
1713 ["Re-edit a Bounced Message" mh-extract-rejected-mail t] | 1098 :group 'mh-alias) |
1714 "--" | 1099 |
1715 ["Copy Message to Folder..." mh-copy-msg (mh-get-msg-num nil)] | 1100 (defcustom mh-alias-insertion-location 'sorted |
1716 ["Print Message" mh-print-msg (mh-get-msg-num nil)] | 1101 "Specifies where new aliases are entered in alias files. |
1717 ["Write Message to File..." mh-write-msg-to-file | 1102 |
1718 (mh-get-msg-num nil)] | 1103 This option is set to \"Alphabetical\" by default. If you organize |
1719 ["Pipe Message to Command..." mh-pipe-msg (mh-get-msg-num nil)] | 1104 your alias file in other ways, then adding aliases to the \"Top\" |
1720 ["Unpack Uuencoded Message..." mh-store-msg (mh-get-msg-num nil)] | 1105 or \"Bottom\" of your alias file might be more appropriate." |
1721 ["Burst Digest Message" mh-burst-digest (mh-get-msg-num nil)])) | 1106 :type '(choice (const :tag "Alphabetical" sorted) |
1722 | 1107 (const :tag "Top" top) |
1723 ;; folder-mode "Folder" menu | 1108 (const :tag "Bottom" bottom)) |
1724 (easy-menu-define | 1109 :group 'mh-alias) |
1725 mh-folder-folder-menu mh-folder-mode-map "Menu for MH-E folder." | 1110 |
1726 '("Folder" | 1111 (defcustom mh-alias-local-users t |
1727 ["Incorporate New Mail" mh-inc-folder t] | 1112 "*If on, local users are added to alias completion. |
1728 ["Toggle Show/Folder" mh-toggle-showing t] | 1113 |
1729 ["Execute Delete/Refile" mh-execute-commands | 1114 Aliases are created from \"/etc/passwd\" entries with a user ID |
1730 (mh-outstanding-commands-p)] | 1115 larger than a magical number, typically 200. This can be a handy |
1731 ["Rescan Folder" mh-rescan-folder t] | 1116 tool on a machine where you and co-workers exchange messages. |
1732 ["Thread Folder" mh-toggle-threads | 1117 These aliases have the form \"local.first.last\" if a real name is |
1733 (not (memq 'unthread mh-view-ops))] | 1118 present in the password file. Otherwise, the alias will have the |
1734 ["Pack Folder" mh-pack-folder t] | 1119 form \"local.login\". |
1735 ["Sort Folder" mh-sort-folder t] | 1120 |
1736 "--" | 1121 If you're on a system with thousands of users you don't know, and |
1737 ["List Folders" mh-list-folders t] | 1122 the loading of local aliases slows MH-E down noticeably, then |
1738 ["Visit a Folder..." mh-visit-folder t] | 1123 turn this option off. |
1739 ["View New Messages" mh-index-new-messages t] | 1124 |
1740 ["Search..." mh-search t] | 1125 This option also takes a string which is executed to generate the |
1741 "--" | 1126 password file. For example, use \"ypcat passwd\" to obtain the |
1742 ["Quit MH-E" mh-quit t])) | 1127 NIS password file." |
1128 :type '(choice (boolean) (string)) | |
1129 :group 'mh-alias) | |
1130 | |
1131 (defcustom mh-alias-local-users-prefix "local." | |
1132 "*String prefixed to the real names of users from the password file. | |
1133 This option can also be set to \"Use Login\". | |
1134 | |
1135 For example, consider the following password file entry: | |
1136 | |
1137 psg:x:1000:1000:Peter S Galbraith,,,:/home/psg:/bin/tcsh | |
1138 | |
1139 The following settings of this option will produce the associated | |
1140 aliases: | |
1141 | |
1142 \"local.\" local.peter.galbraith | |
1143 \"\" peter.galbraith | |
1144 Use Login psg | |
1145 | |
1146 This option has no effect if variable `mh-alias-local-users' is | |
1147 turned off." | |
1148 :type '(choice (const :tag "Use Login" nil) | |
1149 (string)) | |
1150 :group 'mh-alias) | |
1151 | |
1152 (defcustom mh-alias-passwd-gecos-comma-separator-flag t | |
1153 "*Non-nil means the gecos field in the password file uses a comma separator. | |
1154 | |
1155 In the example in `mh-alias-local-users-prefix', commas are used | |
1156 to separate different values within the so-called gecos field. | |
1157 This is a fairly common usage. However, in the rare case that the | |
1158 gecos field in your password file is not separated by commas and | |
1159 whose contents may contain commas, you can turn this option off." | |
1160 :type 'boolean | |
1161 :group 'mh-alias) | |
1743 | 1162 |
1744 | 1163 |
1745 | 1164 |
1746 (defmacro mh-remove-xemacs-horizontal-scrollbar () | 1165 ;;; Organizing Your Mail with Folders (:group 'mh-folder) |
1747 "Get rid of the horizontal scrollbar that XEmacs insists on putting in." | 1166 |
1748 (when mh-xemacs-flag | 1167 (defcustom mh-new-messages-folders t |
1749 `(if (and (featurep 'scrollbar) | 1168 "Folders searched for the \"unseen\" sequence. |
1750 (fboundp 'set-specifier)) | 1169 |
1751 (set-specifier horizontal-scrollbar-visible-p nil | 1170 Set this option to \"Inbox\" to search the \"+inbox\" folder or |
1752 (cons (current-buffer) nil))))) | 1171 \"All\" to search all of the top level folders. Otherwise, list |
1753 | 1172 the folders that should be searched with the \"Choose Folders\" |
1754 (defmacro mh-write-file-functions-compat () | 1173 menu item. |
1755 "Return `write-file-functions' if it exists. | 1174 |
1756 Otherwise return `local-write-file-hooks'. This macro exists | 1175 See also `mh-recursive-folders-flag'." |
1757 purely for compatibility. The former symbol is used in Emacs 21.4 | 1176 :type '(choice (const :tag "Inbox" t) |
1758 onward while the latter is used in previous versions and XEmacs." | 1177 (const :tag "All" nil) |
1759 (if (boundp 'write-file-functions) | 1178 (repeat :tag "Choose Folders" (string :tag "Folder"))) |
1760 ''write-file-functions ;Emacs 21.4 | 1179 :group 'mh-folder) |
1761 ''local-write-file-hooks)) ;XEmacs | 1180 |
1762 | 1181 (defcustom mh-ticked-messages-folders t |
1763 ;; Register mh-folder-mode as supporting which-function-mode... | 1182 "Folders searched for `mh-tick-seq'. |
1764 (load "which-func" t t) | 1183 |
1765 (when (and (boundp 'which-func-modes) | 1184 Set this option to \"Inbox\" to search the \"+inbox\" folder or |
1766 (not (member 'mh-folder-mode which-func-modes))) | 1185 \"All\" to search all of the top level folders. Otherwise, list |
1767 (push 'mh-folder-mode which-func-modes)) | 1186 the folders that should be searched with the \"Choose Folders\" |
1768 | 1187 menu item. |
1769 ;; Shush compiler. | 1188 |
1770 (eval-when-compile | 1189 See also `mh-recursive-folders-flag'." |
1771 (defvar desktop-save-buffer) | 1190 :type '(choice (const :tag "Inbox" t) |
1772 (defvar font-lock-auto-fontify)) | 1191 (const :tag "All" nil) |
1773 | 1192 (repeat :tag "Choose Folders" (string :tag "Folder"))) |
1774 (defvar mh-folder-buttons-init-flag nil) | 1193 :group 'mh-folder) |
1775 | 1194 |
1776 ;; Autoload cookie needed by desktop.el | 1195 (defcustom mh-large-folder 200 |
1777 ;;;###autoload | 1196 "The number of messages that indicates a large folder. |
1778 (define-derived-mode mh-folder-mode fundamental-mode "MH-Folder" | 1197 |
1779 "Major MH-E mode for \"editing\" an MH folder scan listing.\\<mh-folder-mode-map> | 1198 If a folder is deemed to be large, that is the number of messages |
1780 | 1199 in it exceed this value, then confirmation is needed when it is |
1781 You can show the message the cursor is pointing to, and step through | 1200 visited. Even when `mh-show-threads-flag' is non-nil, the folder |
1782 the messages. Messages can be marked for deletion or refiling into | 1201 is not automatically threaded, if it is large. If set to nil all |
1783 another folder; these commands are executed all at once with a | 1202 folders are treated as if they are small." |
1784 separate command. | 1203 :type '(choice (const :tag "No Limit") integer) |
1785 | 1204 :group 'mh-folder) |
1786 Options that control this mode can be changed with | 1205 |
1787 \\[customize-group]; specify the \"mh\" group. In particular, please | 1206 (defcustom mh-recenter-summary-flag nil |
1788 see the `mh-scan-format-file' option if you wish to modify scan's | 1207 "*Non-nil means to recenter the summary window. |
1789 format. | 1208 |
1790 | 1209 If this option is turned on, recenter the summary window when the |
1791 When a folder is visited, the hook `mh-folder-mode-hook' is run. | 1210 show window is toggled off." |
1792 | 1211 :type 'boolean |
1793 Ranges | 1212 :group 'mh-folder) |
1794 ====== | 1213 |
1795 Many commands that operate on individual messages, such as | 1214 (defcustom mh-recursive-folders-flag nil |
1796 `mh-forward' or `mh-refile-msg' take a RANGE argument. This argument | 1215 "*Non-nil means that commands which operate on folders do so recursively." |
1797 can be used in several ways. | 1216 :type 'boolean |
1798 | 1217 :group 'mh-folder) |
1799 If you provide the prefix argument (\\[universal-argument]) to | 1218 |
1800 these commands, then you will be prompted for the message range. | 1219 (defcustom mh-sortm-args nil |
1801 This can be any valid MH range which can include messages, | 1220 "*Additional arguments for \"sortm\"\\<mh-folder-mode-map>. |
1802 sequences, and the abbreviations (described in the mh(1) man | 1221 |
1803 page): | 1222 This option is consulted when a prefix argument is used with |
1804 | 1223 \\[mh-sort-folder]. Normally default arguments to \"sortm\" are |
1805 <num1>-<num2> | 1224 specified in the MH profile. This option may be used to provide |
1806 Indicates all messages in the range <num1> to <num2>, inclusive. | 1225 an alternate view. For example, \"'(\"-nolimit\" \"-textfield\" |
1807 The range must be nonempty. | 1226 \"subject\")\" is a useful setting." |
1808 | 1227 :type 'string |
1809 <num>:N | 1228 :group 'mh-folder) |
1810 <num>:+N | |
1811 <num>:-N | |
1812 Up to N messages beginning with (or ending with) message num. Num | |
1813 may be any of the predefined symbols: first, prev, cur, next or | |
1814 last. | |
1815 | |
1816 first:N | |
1817 prev:N | |
1818 next:N | |
1819 last:N | |
1820 The first, previous, next or last messages, if they exist. | |
1821 | |
1822 all | |
1823 All of the messages. | |
1824 | |
1825 For example, a range that shows all of these things is `1 2 3 | |
1826 5-10 last:5 unseen'. | |
1827 | |
1828 If the option `transient-mark-mode' is set to t and you set a | |
1829 region in the MH-Folder buffer, then the MH-E command will | |
1830 perform the operation on all messages in that region. | |
1831 | |
1832 \\{mh-folder-mode-map}" | |
1833 (mh-do-in-gnu-emacs | |
1834 (unless mh-folder-buttons-init-flag | |
1835 (mh-tool-bar-folder-buttons-init) | |
1836 (setq mh-folder-buttons-init-flag t))) | |
1837 (make-local-variable 'font-lock-defaults) | |
1838 (setq font-lock-defaults '(mh-folder-font-lock-keywords t)) | |
1839 (make-local-variable 'desktop-save-buffer) | |
1840 (setq desktop-save-buffer t) | |
1841 (mh-make-local-vars | |
1842 'mh-colors-available-flag (mh-colors-available-p) | |
1843 ; Do we have colors available | |
1844 'mh-current-folder (buffer-name) ; Name of folder, a string | |
1845 'mh-show-buffer (format "show-%s" (buffer-name)) ; Buffer that displays msgs | |
1846 'mh-folder-filename ; e.g. "/usr/foobar/Mail/inbox/" | |
1847 (file-name-as-directory (mh-expand-file-name (buffer-name))) | |
1848 'mh-display-buttons-for-inline-parts-flag | |
1849 mh-display-buttons-for-inline-parts-flag ; Allow for display of buttons to | |
1850 ; be toggled. | |
1851 'mh-arrow-marker (make-marker) ; Marker where arrow is displayed | |
1852 'overlay-arrow-position nil ; Allow for simultaneous display in | |
1853 'overlay-arrow-string ">" ; different MH-E buffers. | |
1854 'mh-showing-mode nil ; Show message also? | |
1855 'mh-delete-list nil ; List of msgs nums to delete | |
1856 'mh-refile-list nil ; List of folder names in mh-seq-list | |
1857 'mh-seq-list nil ; Alist of (seq . msgs) nums | |
1858 'mh-seen-list nil ; List of displayed messages | |
1859 'mh-next-direction 'forward ; Direction to move to next message | |
1860 'mh-view-ops () ; Stack that keeps track of the order | |
1861 ; in which narrowing/threading has been | |
1862 ; carried out. | |
1863 'mh-folder-view-stack () ; Stack of previous views of the | |
1864 ; folder. | |
1865 'mh-index-data nil ; If the folder was created by a call | |
1866 ; to mh-search, this contains info | |
1867 ; about the search results. | |
1868 'mh-index-previous-search nil ; folder, indexer, search-regexp | |
1869 'mh-index-msg-checksum-map nil ; msg -> checksum map | |
1870 'mh-index-checksum-origin-map nil ; checksum -> ( orig-folder, orig-msg ) | |
1871 'mh-index-sequence-search-flag nil ; folder resulted from sequence search | |
1872 'mh-first-msg-num nil ; Number of first msg in buffer | |
1873 'mh-last-msg-num nil ; Number of last msg in buffer | |
1874 'mh-msg-count nil ; Number of msgs in buffer | |
1875 'mh-mode-line-annotation nil ; Indicates message range | |
1876 'mh-sequence-notation-history (make-hash-table) | |
1877 ; Remember what is overwritten by | |
1878 ; mh-note-seq. | |
1879 'imenu-create-index-function 'mh-index-create-imenu-index | |
1880 ; Setup imenu support | |
1881 'mh-previous-window-config nil) ; Previous window configuration | |
1882 (mh-remove-xemacs-horizontal-scrollbar) | |
1883 (setq truncate-lines t) | |
1884 (auto-save-mode -1) | |
1885 (setq buffer-offer-save t) | |
1886 (mh-make-local-hook (mh-write-file-functions-compat)) | |
1887 (add-hook (mh-write-file-functions-compat) 'mh-execute-commands nil t) | |
1888 (make-local-variable 'revert-buffer-function) | |
1889 (make-local-variable 'hl-line-mode) ; avoid pollution | |
1890 (mh-funcall-if-exists hl-line-mode 1) | |
1891 (setq revert-buffer-function 'mh-undo-folder) | |
1892 (or (assq 'mh-showing-mode minor-mode-alist) | |
1893 (setq minor-mode-alist | |
1894 (cons '(mh-showing-mode " Show") minor-mode-alist))) | |
1895 (easy-menu-add mh-folder-sequence-menu) | |
1896 (easy-menu-add mh-folder-message-menu) | |
1897 (easy-menu-add mh-folder-folder-menu) | |
1898 (set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map) | |
1899 (mh-funcall-if-exists mh-tool-bar-init :folder) | |
1900 (if (and mh-xemacs-flag | |
1901 font-lock-auto-fontify) | |
1902 (turn-on-font-lock))) ; Force font-lock in XEmacs. | |
1903 | |
1904 (defun mh-toggle-mime-buttons () | |
1905 "Toggle option `mh-display-buttons-for-inline-parts-flag'." | |
1906 (interactive) | |
1907 (setq mh-display-buttons-for-inline-parts-flag | |
1908 (not mh-display-buttons-for-inline-parts-flag)) | |
1909 (mh-show nil t)) | |
1910 | |
1911 (defun mh-colors-available-p () | |
1912 "Check if colors are available in the Emacs being used." | |
1913 (or mh-xemacs-flag | |
1914 (let ((color-cells (display-color-cells))) | |
1915 (and (numberp color-cells) (>= color-cells 8))))) | |
1916 | |
1917 (defun mh-colors-in-use-p () | |
1918 "Check if colors are being used in the folder buffer." | |
1919 (and mh-colors-available-flag font-lock-mode)) | |
1920 | |
1921 (defun mh-make-local-vars (&rest pairs) | |
1922 "Initialize local variables according to the variable-value PAIRS." | |
1923 | |
1924 (while pairs | |
1925 (set (make-local-variable (car pairs)) (car (cdr pairs))) | |
1926 (setq pairs (cdr (cdr pairs))))) | |
1927 | |
1928 (defun mh-restore-desktop-buffer (desktop-buffer-file-name | |
1929 desktop-buffer-name | |
1930 desktop-buffer-misc) | |
1931 "Restore an MH folder buffer specified in a desktop file. | |
1932 When desktop creates a buffer, DESKTOP-BUFFER-FILE-NAME holds the | |
1933 file name to visit, DESKTOP-BUFFER-NAME holds the desired buffer | |
1934 name, and DESKTOP-BUFFER-MISC holds a list of miscellaneous info | |
1935 used by the `desktop-buffer-handlers' functions." | |
1936 (mh-find-path) | |
1937 (mh-visit-folder desktop-buffer-name) | |
1938 (current-buffer)) | |
1939 | |
1940 ;; desktop-buffer-mode-handlers appeared in Emacs 22. | |
1941 (if (fboundp 'desktop-buffer-mode-handlers) | |
1942 (add-to-list 'desktop-buffer-mode-handlers | |
1943 '(mh-folder-mode . mh-restore-desktop-buffer))) | |
1944 | |
1945 (defun mh-scan-folder (folder range &optional dont-exec-pending) | |
1946 "Scan FOLDER over RANGE. | |
1947 | |
1948 After the scan is performed, switch to the buffer associated with | |
1949 FOLDER. | |
1950 | |
1951 Check the documentation of `mh-interactive-range' to see how RANGE is | |
1952 read in interactive use. | |
1953 | |
1954 The processing of outstanding commands is not performed if | |
1955 DONT-EXEC-PENDING is non-nil." | |
1956 (when (stringp range) | |
1957 (setq range (delete "" (split-string range "[ \t\n]")))) | |
1958 (cond ((null (get-buffer folder)) | |
1959 (mh-make-folder folder)) | |
1960 (t | |
1961 (unless dont-exec-pending | |
1962 (mh-process-or-undo-commands folder) | |
1963 (mh-reset-threads-and-narrowing)) | |
1964 (switch-to-buffer folder))) | |
1965 (mh-regenerate-headers range) | |
1966 (if (zerop (buffer-size)) | |
1967 (if (equal range "all") | |
1968 (message "Folder %s is empty" folder) | |
1969 (message "No messages in %s, range %s" folder range)) | |
1970 (mh-goto-cur-msg)) | |
1971 (when (mh-outstanding-commands-p) | |
1972 (mh-notate-deleted-and-refiled))) | |
1973 | |
1974 (defun mh-msg-num-width-to-column (width) | |
1975 "Return the column for notations given message number WIDTH. | |
1976 Note that columns in Emacs start with 0. | |
1977 | |
1978 If `mh-scan-format-file' is set to \"Use MH-E scan Format\" this | |
1979 means that either `mh-scan-format-mh' or `mh-scan-format-nmh' are | |
1980 in use. This function therefore assumes that the first column is | |
1981 empty (to provide room for the cursor), the following WIDTH | |
1982 columns contain the message number, and the column for notations | |
1983 comes after that." | |
1984 (if (eq mh-scan-format-file t) | |
1985 (max (1+ width) 2) | |
1986 (error "%s %s" "Can't call `mh-msg-num-width-to-column' when" | |
1987 "`mh-scan-format-file' is not set to \"Use MH-E scan Format\""))) | |
1988 | |
1989 (defun mh-set-cmd-note (column) | |
1990 "Set `mh-cmd-note' to COLUMN. | |
1991 Note that columns in Emacs start with 0." | |
1992 (setq mh-cmd-note column)) | |
1993 | |
1994 (defun mh-regenerate-headers (range &optional update) | |
1995 "Scan folder over RANGE. | |
1996 If UPDATE, append the scan lines, otherwise replace." | |
1997 (let ((folder mh-current-folder) | |
1998 (range (if (and range (atom range)) (list range) range)) | |
1999 scan-start) | |
2000 (message "Scanning %s..." folder) | |
2001 (mh-remove-all-notation) | |
2002 (with-mh-folder-updating (nil) | |
2003 (if update | |
2004 (goto-char (point-max)) | |
2005 (delete-region (point-min) (point-max)) | |
2006 (if mh-adaptive-cmd-note-flag | |
2007 (mh-set-cmd-note (mh-msg-num-width-to-column (mh-msg-num-width | |
2008 folder))))) | |
2009 (setq scan-start (point)) | |
2010 (apply #'mh-exec-cmd-output | |
2011 mh-scan-prog nil | |
2012 (mh-scan-format) | |
2013 "-noclear" "-noheader" | |
2014 "-width" (window-width) | |
2015 folder range) | |
2016 (goto-char scan-start) | |
2017 (cond ((looking-at "scan: no messages in") | |
2018 (keep-lines mh-scan-valid-regexp)) ; Flush random scan lines | |
2019 ((looking-at (if (mh-variant-p 'mu-mh) | |
2020 "scan: message set .* does not exist" | |
2021 "scan: bad message list ")) | |
2022 (keep-lines mh-scan-valid-regexp)) | |
2023 ((looking-at "scan: ")) ; Keep error messages | |
2024 (t | |
2025 (keep-lines mh-scan-valid-regexp))) ; Flush random scan lines | |
2026 (setq mh-seq-list (mh-read-folder-sequences folder nil)) | |
2027 (mh-notate-user-sequences) | |
2028 (or update | |
2029 (setq mh-mode-line-annotation | |
2030 (if (equal range '("all")) | |
2031 nil | |
2032 mh-partial-folder-mode-line-annotation))) | |
2033 (mh-make-folder-mode-line)) | |
2034 (message "Scanning %s...done" folder))) | |
2035 | |
2036 (defun mh-generate-new-cmd-note (folder) | |
2037 "Fix the `mh-cmd-note' value for this FOLDER. | |
2038 | |
2039 After doing an `mh-get-new-mail' operation in this FOLDER, at least | |
2040 one line that looks like a truncated message number was found. | |
2041 | |
2042 Remove the text added by the last `mh-inc' command. It should be the | |
2043 messages cur-last. Call `mh-set-cmd-note', adjusting the notation | |
2044 column with the width of the largest message number in FOLDER. | |
2045 | |
2046 Reformat the message number width on each line in the buffer and trim | |
2047 the line length to fit in the window. | |
2048 | |
2049 Rescan the FOLDER in the range cur-last in order to display the | |
2050 messages that were removed earlier. They should all fit in the scan | |
2051 line now with no message truncation." | |
2052 (save-excursion | |
2053 (let ((maxcol (1- (window-width))) | |
2054 (old-cmd-note mh-cmd-note) | |
2055 mh-cmd-note-fmt | |
2056 msgnum) | |
2057 ;; Nuke all of the lines just added by the last inc | |
2058 (delete-char (- (point-max) (point))) | |
2059 ;; Update the current buffer to reflect the new mh-cmd-note | |
2060 ;; value needed to display messages. | |
2061 (mh-set-cmd-note (mh-msg-num-width-to-column (mh-msg-num-width folder))) | |
2062 (setq mh-cmd-note-fmt (concat "%" (format "%d" mh-cmd-note) "d")) | |
2063 ;; Cleanup the messages that are in the buffer right now | |
2064 (goto-char (point-min)) | |
2065 (cond ((memq 'unthread mh-view-ops) | |
2066 (mh-thread-add-spaces (- mh-cmd-note old-cmd-note))) | |
2067 (t (while (re-search-forward mh-scan-msg-number-regexp nil 0 1) | |
2068 ;; reformat the number to fix in mh-cmd-note columns | |
2069 (setq msgnum (string-to-number | |
2070 (buffer-substring | |
2071 (match-beginning 1) (match-end 1)))) | |
2072 (replace-match (format mh-cmd-note-fmt msgnum)) | |
2073 ;; trim the line to fix in the window | |
2074 (end-of-line) | |
2075 (let ((eol (point))) | |
2076 (move-to-column maxcol) | |
2077 (if (<= (point) eol) | |
2078 (delete-char (- eol (point)))))))) | |
2079 ;; now re-read the lost messages | |
2080 (goto-char (point-max)) | |
2081 (prog1 (point) | |
2082 (mh-regenerate-headers "cur-last" t))))) | |
2083 | |
2084 (defun mh-get-new-mail (maildrop-name) | |
2085 "Read new mail from MAILDROP-NAME into the current buffer. | |
2086 Return in the current buffer." | |
2087 (let ((point-before-inc (point)) | |
2088 (folder mh-current-folder) | |
2089 (new-mail-flag nil)) | |
2090 (with-mh-folder-updating (t) | |
2091 (if maildrop-name | |
2092 (message "inc %s -file %s..." folder maildrop-name) | |
2093 (message "inc %s..." folder)) | |
2094 (setq mh-next-direction 'forward) | |
2095 (goto-char (point-max)) | |
2096 (mh-remove-cur-notation) | |
2097 (let ((start-of-inc (point))) | |
2098 (if maildrop-name | |
2099 ;; I think MH 5 used "-ms-file" instead of "-file", | |
2100 ;; which would make inc'ing from maildrops fail. | |
2101 (mh-exec-cmd-output mh-inc-prog nil folder | |
2102 (mh-scan-format) | |
2103 "-file" (expand-file-name maildrop-name) | |
2104 "-width" (window-width) | |
2105 "-truncate") | |
2106 (mh-exec-cmd-output mh-inc-prog nil | |
2107 (mh-scan-format) | |
2108 "-width" (window-width))) | |
2109 (if maildrop-name | |
2110 (message "inc %s -file %s...done" folder maildrop-name) | |
2111 (message "inc %s...done" folder)) | |
2112 (goto-char start-of-inc) | |
2113 (cond ((save-excursion | |
2114 (re-search-forward "^inc: no mail" nil t)) | |
2115 (message "No new mail%s%s" (if maildrop-name " in " "") | |
2116 (if maildrop-name maildrop-name ""))) | |
2117 ((and (when mh-folder-view-stack | |
2118 (let ((saved-text (buffer-substring-no-properties | |
2119 start-of-inc (point-max)))) | |
2120 (delete-region start-of-inc (point-max)) | |
2121 (unwind-protect (mh-widen t) | |
2122 (mh-remove-cur-notation) | |
2123 (goto-char (point-max)) | |
2124 (setq start-of-inc (point)) | |
2125 (insert saved-text) | |
2126 (goto-char start-of-inc)))) | |
2127 nil)) | |
2128 ((re-search-forward "^inc:" nil t) ; Error messages | |
2129 (error "Error incorporating mail")) | |
2130 ((and | |
2131 (equal mh-scan-format-file t) | |
2132 mh-adaptive-cmd-note-flag | |
2133 ;; Have we reached an edge condition? | |
2134 (save-excursion | |
2135 (re-search-forward mh-scan-msg-overflow-regexp nil 0 1)) | |
2136 (setq start-of-inc (mh-generate-new-cmd-note folder)) | |
2137 nil)) | |
2138 (t | |
2139 (setq new-mail-flag t))) | |
2140 (keep-lines mh-scan-valid-regexp) ; Flush random scan lines | |
2141 (let* ((sequences (mh-read-folder-sequences folder t)) | |
2142 (new-cur (assoc 'cur sequences)) | |
2143 (new-unseen (assoc mh-unseen-seq sequences))) | |
2144 (unless (assoc 'cur mh-seq-list) | |
2145 (push (list 'cur) mh-seq-list)) | |
2146 (unless (assoc mh-unseen-seq mh-seq-list) | |
2147 (push (list mh-unseen-seq) mh-seq-list)) | |
2148 (setcdr (assoc 'cur mh-seq-list) (cdr new-cur)) | |
2149 (setcdr (assoc mh-unseen-seq mh-seq-list) (cdr new-unseen))) | |
2150 (when (equal (point-max) start-of-inc) | |
2151 (mh-notate-cur)) | |
2152 (if new-mail-flag | |
2153 (progn | |
2154 (mh-make-folder-mode-line) | |
2155 (when (mh-speed-flists-active-p) | |
2156 (mh-speed-flists t mh-current-folder)) | |
2157 (when (memq 'unthread mh-view-ops) | |
2158 (mh-thread-inc folder start-of-inc)) | |
2159 (mh-goto-cur-msg)) | |
2160 (goto-char point-before-inc)) | |
2161 (mh-notate-user-sequences (cons start-of-inc (point-max))))))) | |
2162 | |
2163 (defun mh-make-folder-mode-line (&optional ignored) | |
2164 "Set the fields of the mode line for a folder buffer. | |
2165 The optional argument is now obsolete and IGNORED. It used to be | |
2166 used to pass in what is now stored in the buffer-local variable | |
2167 `mh-mode-line-annotation'." | |
2168 (save-excursion | |
2169 (save-window-excursion | |
2170 (mh-first-msg) | |
2171 (let ((new-first-msg-num (mh-get-msg-num nil))) | |
2172 (when (or (not (memq 'unthread mh-view-ops)) | |
2173 (null mh-first-msg-num) | |
2174 (null new-first-msg-num) | |
2175 (< new-first-msg-num mh-first-msg-num)) | |
2176 (setq mh-first-msg-num new-first-msg-num))) | |
2177 (mh-last-msg) | |
2178 (let ((new-last-msg-num (mh-get-msg-num nil))) | |
2179 (when (or (not (memq 'unthread mh-view-ops)) | |
2180 (null mh-last-msg-num) | |
2181 (null new-last-msg-num) | |
2182 (> new-last-msg-num mh-last-msg-num)) | |
2183 (setq mh-last-msg-num new-last-msg-num))) | |
2184 (setq mh-msg-count (if mh-first-msg-num | |
2185 (count-lines (point-min) (point-max)) | |
2186 0)) | |
2187 (setq mode-line-buffer-identification | |
2188 (list (format " {%%b%s} %s msg%s" | |
2189 (if mh-mode-line-annotation | |
2190 (format "/%s" mh-mode-line-annotation) | |
2191 "") | |
2192 (if (zerop mh-msg-count) | |
2193 "no" | |
2194 (format "%d" mh-msg-count)) | |
2195 (if (zerop mh-msg-count) | |
2196 "s" | |
2197 (cond ((> mh-msg-count 1) | |
2198 (format "s (%d-%d)" mh-first-msg-num | |
2199 mh-last-msg-num)) | |
2200 (mh-first-msg-num | |
2201 (format " (%d)" mh-first-msg-num)) | |
2202 ("")))))) | |
2203 (mh-logo-display)))) | |
2204 | |
2205 (defun mh-add-sequence-notation (msg internal-seq-flag) | |
2206 "Add sequence notation to the MSG on the current line. | |
2207 If INTERNAL-SEQ-FLAG is non-nil, then refontify the scan line if | |
2208 font-lock is turned on." | |
2209 (with-mh-folder-updating (t) | |
2210 (save-excursion | |
2211 (beginning-of-line) | |
2212 (if internal-seq-flag | |
2213 (progn | |
2214 ;; Change the buffer so that if transient-mark-mode is active | |
2215 ;; and there is an active region it will get deactivated as in | |
2216 ;; the case of user sequences. | |
2217 (mh-notate nil nil mh-cmd-note) | |
2218 (when font-lock-mode | |
2219 (font-lock-fontify-region (point) (line-end-position)))) | |
2220 (forward-char (+ mh-cmd-note mh-scan-field-destination-offset)) | |
2221 (let ((stack (gethash msg mh-sequence-notation-history))) | |
2222 (setf (gethash msg mh-sequence-notation-history) | |
2223 (cons (char-after) stack))) | |
2224 (mh-notate nil mh-note-seq | |
2225 (+ mh-cmd-note mh-scan-field-destination-offset)))))) | |
2226 | |
2227 (defun mh-remove-sequence-notation (msg internal-seq-flag &optional all) | |
2228 "Remove sequence notation from the MSG on the current line. | |
2229 If INTERNAL-SEQ-FLAG is non-nil, then `font-lock' was used to | |
2230 highlight the sequence. In that case, no notation needs to be removed. | |
2231 Otherwise the effect of inserting `mh-note-seq' needs to be reversed. | |
2232 If ALL is non-nil, then all sequence marks on the scan line are | |
2233 removed." | |
2234 (with-mh-folder-updating (t) | |
2235 ;; This takes care of internal sequences... | |
2236 (mh-notate nil nil mh-cmd-note) | |
2237 (unless internal-seq-flag | |
2238 ;; ... and this takes care of user sequences. | |
2239 (let ((stack (gethash msg mh-sequence-notation-history))) | |
2240 (while (and all (cdr stack)) | |
2241 (setq stack (cdr stack))) | |
2242 (when stack | |
2243 (save-excursion | |
2244 (beginning-of-line) | |
2245 (forward-char (+ mh-cmd-note mh-scan-field-destination-offset)) | |
2246 (delete-char 1) | |
2247 (insert (car stack)))) | |
2248 (setf (gethash msg mh-sequence-notation-history) (cdr stack)))))) | |
2249 | |
2250 (defun mh-remove-cur-notation () | |
2251 "Remove old cur notation." | |
2252 (let ((cur-msg (car (mh-seq-to-msgs 'cur)))) | |
2253 (save-excursion | |
2254 (when (and cur-msg | |
2255 (mh-goto-msg cur-msg t t) | |
2256 (looking-at mh-scan-cur-msg-number-regexp)) | |
2257 (mh-notate nil ? mh-cmd-note) | |
2258 (setq overlay-arrow-position nil))))) | |
2259 | |
2260 (defun mh-remove-all-notation () | |
2261 "Remove all notations on all scan lines that MH-E introduces." | |
2262 (save-excursion | |
2263 (setq overlay-arrow-position nil) | |
2264 (goto-char (point-min)) | |
2265 (mh-iterate-on-range msg (cons (point-min) (point-max)) | |
2266 (mh-notate nil ? mh-cmd-note) | |
2267 (mh-remove-sequence-notation msg nil t)) | |
2268 (clrhash mh-sequence-notation-history))) | |
2269 | |
2270 (defun mh-goto-cur-msg (&optional minimal-changes-flag) | |
2271 "Position the cursor at the current message. | |
2272 When optional argument MINIMAL-CHANGES-FLAG is non-nil, the | |
2273 function doesn't recenter the folder buffer." | |
2274 (let ((cur-msg (car (mh-seq-to-msgs 'cur)))) | |
2275 (cond ((and cur-msg | |
2276 (mh-goto-msg cur-msg t t)) | |
2277 (unless minimal-changes-flag | |
2278 (mh-notate-cur) | |
2279 (mh-recenter 0) | |
2280 (mh-maybe-show cur-msg))) | |
2281 (t | |
2282 (setq overlay-arrow-position nil) | |
2283 (message "No current message"))))) | |
2284 | |
2285 (defun mh-process-or-undo-commands (folder) | |
2286 "If FOLDER has outstanding commands, then either process or discard them. | |
2287 Called by functions like `mh-sort-folder', so also invalidate | |
2288 show buffer." | |
2289 (set-buffer folder) | |
2290 (if (mh-outstanding-commands-p) | |
2291 (if (or mh-do-not-confirm-flag | |
2292 (y-or-n-p | |
2293 "Process outstanding deletes and refiles? ")) | |
2294 (mh-process-commands folder) | |
2295 (set-buffer folder) | |
2296 (mh-undo-folder))) | |
2297 (mh-update-unseen) | |
2298 (mh-invalidate-show-buffer)) | |
2299 | |
2300 (defun mh-process-commands (folder) | |
2301 "Process outstanding commands for FOLDER. | |
2302 | |
2303 This function runs `mh-before-commands-processed-hook' before the | |
2304 commands are processed and `mh-after-commands-processed-hook' | |
2305 after the commands are processed." | |
2306 (message "Processing deletes and refiles for %s..." folder) | |
2307 (set-buffer folder) | |
2308 (with-mh-folder-updating (nil) | |
2309 ;; Run the before hook -- the refile and delete lists are still valid | |
2310 (run-hooks 'mh-before-commands-processed-hook) | |
2311 | |
2312 ;; Update the unseen sequence if it exists | |
2313 (mh-update-unseen) | |
2314 | |
2315 (let ((redraw-needed-flag mh-index-data) | |
2316 (folders-changed (list mh-current-folder)) | |
2317 (seq-map (and mh-refile-list mh-refile-preserves-sequences-flag | |
2318 (mh-create-sequence-map mh-seq-list))) | |
2319 (dest-map (and mh-refile-list mh-refile-preserves-sequences-flag | |
2320 (make-hash-table)))) | |
2321 ;; Remove invalid scan lines if we are in an index folder and then remove | |
2322 ;; the real messages | |
2323 (when mh-index-data | |
2324 (mh-index-delete-folder-headers) | |
2325 (setq folders-changed | |
2326 (append folders-changed (mh-index-execute-commands)))) | |
2327 | |
2328 ;; Then refile messages | |
2329 (mh-mapc #'(lambda (folder-msg-list) | |
2330 (let* ((dest-folder (symbol-name (car folder-msg-list))) | |
2331 (last (car (mh-translate-range dest-folder "last"))) | |
2332 (msgs (cdr folder-msg-list))) | |
2333 (push dest-folder folders-changed) | |
2334 (setq redraw-needed-flag t) | |
2335 (apply #'mh-exec-cmd | |
2336 "refile" "-src" folder dest-folder | |
2337 (mh-coalesce-msg-list msgs)) | |
2338 (mh-delete-scan-msgs msgs) | |
2339 ;; Preserve sequences in destination folder... | |
2340 (when mh-refile-preserves-sequences-flag | |
2341 (clrhash dest-map) | |
2342 (loop for i from (1+ (or last 0)) | |
2343 for msg in (sort (copy-sequence msgs) #'<) | |
2344 do (loop for seq-name in (gethash msg seq-map) | |
2345 do (push i (gethash seq-name dest-map)))) | |
2346 (maphash | |
2347 #'(lambda (seq msgs) | |
2348 ;; Can't be run in the background, since the | |
2349 ;; current folder is changed by mark this could | |
2350 ;; lead to a race condition with the next refile. | |
2351 (apply #'mh-exec-cmd "mark" | |
2352 "-sequence" (symbol-name seq) dest-folder | |
2353 "-add" (mapcar #'(lambda (x) (format "%s" x)) | |
2354 (mh-coalesce-msg-list msgs)))) | |
2355 dest-map)))) | |
2356 mh-refile-list) | |
2357 (setq mh-refile-list ()) | |
2358 | |
2359 ;; Now delete messages | |
2360 (cond (mh-delete-list | |
2361 (setq redraw-needed-flag t) | |
2362 (apply 'mh-exec-cmd "rmm" folder | |
2363 (mh-coalesce-msg-list mh-delete-list)) | |
2364 (mh-delete-scan-msgs mh-delete-list) | |
2365 (setq mh-delete-list nil))) | |
2366 | |
2367 ;; Don't need to remove sequences since delete and refile do so. | |
2368 ;; Mark cur message | |
2369 (if (> (buffer-size) 0) | |
2370 (mh-define-sequence 'cur (list (or (mh-get-msg-num nil) "last")))) | |
2371 | |
2372 ;; Redraw folder buffer if needed | |
2373 (when (and redraw-needed-flag) | |
2374 (when (mh-speed-flists-active-p) | |
2375 (apply #'mh-speed-flists t folders-changed)) | |
2376 (cond ((memq 'unthread mh-view-ops) (mh-thread-inc folder (point-max))) | |
2377 (mh-index-data (mh-index-insert-folder-headers)))) | |
2378 | |
2379 (and (buffer-file-name (get-buffer mh-show-buffer)) | |
2380 (not (file-exists-p (buffer-file-name (get-buffer mh-show-buffer)))) | |
2381 ;; If "inc" were to put a new msg in this file, | |
2382 ;; we would not notice, so mark it invalid now. | |
2383 (mh-invalidate-show-buffer)) | |
2384 | |
2385 (setq mh-seq-list (mh-read-folder-sequences mh-current-folder nil)) | |
2386 (mh-remove-all-notation) | |
2387 (mh-notate-user-sequences) | |
2388 | |
2389 ;; Run the after hook -- now folders-changed is valid, | |
2390 ;; but not the lists of specific messages. | |
2391 (let ((mh-folders-changed folders-changed)) | |
2392 (run-hooks 'mh-after-commands-processed-hook))) | |
2393 | |
2394 (message "Processing deletes and refiles for %s...done" folder))) | |
2395 | |
2396 (defun mh-update-unseen () | |
2397 "Synchronize the unseen sequence with MH. | |
2398 Return non-nil iff the MH folder was set. | |
2399 The hook `mh-unseen-updated-hook' is called after the unseen sequence | |
2400 is updated." | |
2401 (if mh-seen-list | |
2402 (let* ((unseen-seq (mh-find-seq mh-unseen-seq)) | |
2403 (unseen-msgs (mh-seq-msgs unseen-seq))) | |
2404 (if unseen-msgs | |
2405 (progn | |
2406 (mh-undefine-sequence mh-unseen-seq mh-seen-list) | |
2407 (run-hooks 'mh-unseen-updated-hook) | |
2408 (while mh-seen-list | |
2409 (setq unseen-msgs (delq (car mh-seen-list) unseen-msgs)) | |
2410 (setq mh-seen-list (cdr mh-seen-list))) | |
2411 (setcdr unseen-seq unseen-msgs) | |
2412 t) ;since we set the folder | |
2413 (setq mh-seen-list nil))))) | |
2414 | |
2415 (defun mh-delete-scan-msgs (msgs) | |
2416 "Delete the scan listing lines for MSGS." | |
2417 (save-excursion | |
2418 (while msgs | |
2419 (when (mh-goto-msg (car msgs) t t) | |
2420 (when (memq 'unthread mh-view-ops) | |
2421 (mh-thread-forget-message (car msgs))) | |
2422 (mh-delete-line 1)) | |
2423 (setq msgs (cdr msgs))))) | |
2424 | |
2425 (defun mh-outstanding-commands-p () | |
2426 "Return non-nil if there are outstanding deletes or refiles." | |
2427 (save-excursion | |
2428 (when (eq major-mode 'mh-show-mode) | |
2429 (set-buffer mh-show-folder-buffer)) | |
2430 (or mh-delete-list mh-refile-list))) | |
2431 | |
2432 (defun mh-coalesce-msg-list (messages) | |
2433 "Given a list of MESSAGES, return a list of message number ranges. | |
2434 This is the inverse of `mh-read-msg-list', which expands ranges. | |
2435 Message lists passed to MH programs should be processed by this | |
2436 function to avoid exceeding system command line argument limits." | |
2437 (let ((msgs (sort (copy-sequence messages) 'mh-greaterp)) | |
2438 (range-high nil) | |
2439 (prev -1) | |
2440 (ranges nil)) | |
2441 (while prev | |
2442 (if range-high | |
2443 (if (or (not (numberp prev)) | |
2444 (not (equal (car msgs) (1- prev)))) | |
2445 (progn ;non-sequential, flush old range | |
2446 (if (eq prev range-high) | |
2447 (setq ranges (cons range-high ranges)) | |
2448 (setq ranges (cons (format "%s-%s" prev range-high) ranges))) | |
2449 (setq range-high nil)))) | |
2450 (or range-high | |
2451 (setq range-high (car msgs))) ;start new or first range | |
2452 (setq prev (car msgs)) | |
2453 (setq msgs (cdr msgs))) | |
2454 ranges)) | |
2455 | |
2456 (defun mh-greaterp (msg1 msg2) | |
2457 "Return the greater of two message indicators MSG1 and MSG2. | |
2458 Strings are \"smaller\" than numbers. | |
2459 Valid values are things like \"cur\", \"last\", 1, and 1820." | |
2460 (if (numberp msg1) | |
2461 (if (numberp msg2) | |
2462 (> msg1 msg2) | |
2463 t) | |
2464 (if (numberp msg2) | |
2465 nil | |
2466 (string-lessp msg2 msg1)))) | |
2467 | |
2468 (defun mh-lessp (msg1 msg2) | |
2469 "Return the lesser of two message indicators MSG1 and MSG2. | |
2470 Strings are \"smaller\" than numbers. | |
2471 Valid values are things like \"cur\", \"last\", 1, and 1820." | |
2472 (not (mh-greaterp msg1 msg2))) | |
2473 | 1229 |
2474 | 1230 |
2475 | 1231 |
2476 ;;; Basic sequence handling | 1232 ;;; Folder Selection (:group 'mh-folder-selection) |
2477 | 1233 |
2478 (defun mh-delete-seq-locally (seq) | 1234 (defcustom mh-default-folder-for-message-function nil |
2479 "Remove MH-E's record of SEQ." | 1235 "Function to select a default folder for refiling or \"Fcc:\". |
2480 (let ((entry (mh-find-seq seq))) | 1236 |
2481 (setq mh-seq-list (delq entry mh-seq-list)))) | 1237 The current buffer is set to the message being refiled with point |
2482 | 1238 at the start of the message. This function should return the |
2483 (defun mh-read-folder-sequences (folder save-refiles) | 1239 default folder as a string with a leading \"+\" sign. It can also |
2484 "Read and return the predefined sequences for a FOLDER. | 1240 return nil so that the last folder name is used as the default, |
2485 If SAVE-REFILES is non-nil, then keep the sequences | 1241 or an empty string to suppress the default entirely." |
2486 that note messages to be refiled." | 1242 :type 'function |
2487 (let ((seqs ())) | 1243 :group 'mh-folder-selection) |
2488 (cond (save-refiles | 1244 |
2489 (mh-mapc (function (lambda (seq) ; Save the refiling sequences | 1245 (defcustom mh-default-folder-list nil |
2490 (if (mh-folder-name-p (mh-seq-name seq)) | 1246 "*List of addresses and folders. |
2491 (setq seqs (cons seq seqs))))) | 1247 |
2492 mh-seq-list))) | 1248 The folder name associated with the first address found in this |
2493 (save-excursion | 1249 list is used as the default for `mh-refile-msg' and similar |
2494 (if (eq 0 (mh-exec-cmd-quiet nil "mark" folder "-list")) | 1250 functions. Each element in this list contains a \"Check Recipient\" |
2495 (progn | 1251 item. If this item is turned on, then the address is checked |
2496 ;; look for name in line of form "cur: 4" or "myseq (private): 23" | 1252 against the recipient instead of the sender. This is useful for |
2497 (while (re-search-forward "^[^: ]+" nil t) | 1253 mailing lists. |
2498 (setq seqs (cons (mh-make-seq (intern (buffer-substring | 1254 |
2499 (match-beginning 0) | 1255 See `mh-prompt-for-refile-folder' and `mh-folder-from-address' |
2500 (match-end 0))) | 1256 for more information." |
2501 (mh-read-msg-list)) | 1257 :type '(repeat (list (regexp :tag "Address") |
2502 seqs))) | 1258 (string :tag "Folder") |
2503 (delete-region (point-min) (point))))) ; avoid race with | 1259 (boolean :tag "Check Recipient"))) |
2504 ; mh-process-daemon | 1260 :group 'mh-folder-selection) |
2505 seqs)) | 1261 |
2506 | 1262 (defcustom mh-default-folder-must-exist-flag t |
2507 (defun mh-read-msg-list () | 1263 "*Non-nil means guessed folder name must exist to be used. |
2508 "Return a list of message numbers from point to the end of the line. | 1264 |
2509 Expands ranges into set of individual numbers." | 1265 If the derived folder does not exist, and this option is on, then |
2510 (let ((msgs ()) | 1266 the last folder name used is suggested. This is useful if you get |
2511 (end-of-line (save-excursion (end-of-line) (point))) | 1267 mail from various people for whom you have an alias, but file |
2512 num) | 1268 them all in the same project folder. |
2513 (while (re-search-forward "[0-9]+" end-of-line t) | 1269 |
2514 (setq num (string-to-number (buffer-substring (match-beginning 0) | 1270 See `mh-prompt-for-refile-folder' and `mh-folder-from-address' |
2515 (match-end 0)))) | 1271 for more information." |
2516 (cond ((looking-at "-") ; Message range | 1272 :type 'boolean |
2517 (forward-char 1) | 1273 :group 'mh-folder-selection) |
2518 (re-search-forward "[0-9]+" end-of-line t) | 1274 |
2519 (let ((num2 (string-to-number | 1275 (defcustom mh-default-folder-prefix "" |
2520 (buffer-substring (match-beginning 0) | 1276 "*Prefix used for folder names generated from aliases. |
2521 (match-end 0))))) | 1277 The prefix is used to prevent clutter in your mail directory. |
2522 (if (< num2 num) | 1278 |
2523 (error "Bad message range: %d-%d" num num2)) | 1279 See `mh-prompt-for-refile-folder' and `mh-folder-from-address' |
2524 (while (<= num num2) | 1280 for more information." |
2525 (setq msgs (cons num msgs)) | 1281 :type 'string |
2526 (setq num (1+ num))))) | 1282 :group 'mh-folder-selection) |
2527 ((not (zerop num)) ;"pick" outputs "0" to mean no match | |
2528 (setq msgs (cons num msgs))))) | |
2529 msgs)) | |
2530 | |
2531 (defun mh-notate-user-sequences (&optional range) | |
2532 "Mark user-defined sequences in RANGE. | |
2533 | |
2534 Check the documentation of `mh-interactive-range' to see how | |
2535 RANGE is read in interactive use; if nil all messages are | |
2536 notated." | |
2537 (unless range | |
2538 (setq range (cons (point-min) (point-max)))) | |
2539 (let ((seqs mh-seq-list) | |
2540 (msg-hash (make-hash-table))) | |
2541 (dolist (seq seqs) | |
2542 (dolist (msg (mh-seq-msgs seq)) | |
2543 (push (car seq) (gethash msg msg-hash)))) | |
2544 (mh-iterate-on-range msg range | |
2545 (loop for seq in (gethash msg msg-hash) | |
2546 do (mh-add-sequence-notation msg (mh-internal-seq seq)))))) | |
2547 | |
2548 (defvar mh-internal-seqs '(answered cur deleted forwarded printed)) | |
2549 | |
2550 (defun mh-internal-seq (name) | |
2551 "Return non-nil if NAME is the name of an internal MH-E sequence." | |
2552 (or (memq name mh-internal-seqs) | |
2553 (eq name mh-unseen-seq) | |
2554 (and (mh-colors-in-use-p) mh-tick-seq (eq name mh-tick-seq)) | |
2555 (eq name mh-previous-seq) | |
2556 (mh-folder-name-p name))) | |
2557 | |
2558 (defun mh-valid-seq-p (name) | |
2559 "Return non-nil if NAME is a valid MH sequence name." | |
2560 (and (symbolp name) | |
2561 (string-match "^[a-zA-Z][a-zA-Z0-9]*$" (symbol-name name)))) | |
2562 | |
2563 (defun mh-delete-msg-from-seq (range sequence &optional internal-flag) | |
2564 "Delete RANGE from SEQUENCE. | |
2565 | |
2566 Check the documentation of `mh-interactive-range' to see how | |
2567 RANGE is read in interactive use. | |
2568 | |
2569 In a program, non-nil INTERNAL-FLAG means do not inform MH of the | |
2570 change." | |
2571 (interactive (list (mh-interactive-range "Delete") | |
2572 (mh-read-seq-default "Delete from" t) | |
2573 nil)) | |
2574 (let ((entry (mh-find-seq sequence)) | |
2575 (user-sequence-flag (not (mh-internal-seq sequence))) | |
2576 (folders-changed (list mh-current-folder)) | |
2577 (msg-list ())) | |
2578 (when entry | |
2579 (mh-iterate-on-range msg range | |
2580 (push msg msg-list) | |
2581 ;; Calling "mark" repeatedly takes too long. So we will pretend here | |
2582 ;; that we are just modifying an internal sequence... | |
2583 (when (memq msg (cdr entry)) | |
2584 (mh-remove-sequence-notation msg (not user-sequence-flag))) | |
2585 (mh-delete-a-msg-from-seq msg sequence t)) | |
2586 ;; ... and here we will "mark" all the messages at one go. | |
2587 (unless internal-flag (mh-undefine-sequence sequence msg-list)) | |
2588 (when (and mh-index-data (not internal-flag)) | |
2589 (setq folders-changed | |
2590 (append folders-changed | |
2591 (mh-index-delete-from-sequence sequence msg-list)))) | |
2592 (when (and (eq sequence mh-unseen-seq) (mh-speed-flists-active-p)) | |
2593 (apply #'mh-speed-flists t folders-changed))))) | |
2594 | |
2595 (defun mh-catchup (range) | |
2596 "Delete RANGE from the \"unseen\" sequence. | |
2597 | |
2598 Check the documentation of `mh-interactive-range' to see how | |
2599 RANGE is read in interactive use." | |
2600 (interactive (list (mh-interactive-range "Catchup" | |
2601 (cons (point-min) (point-max))))) | |
2602 (mh-delete-msg-from-seq range mh-unseen-seq)) | |
2603 | |
2604 (defun mh-delete-a-msg-from-seq (msg sequence internal-flag) | |
2605 "Delete MSG from SEQUENCE. | |
2606 If INTERNAL-FLAG is non-nil, then do not inform MH of the | |
2607 change." | |
2608 (let ((entry (mh-find-seq sequence))) | |
2609 (when (and entry (memq msg (mh-seq-msgs entry))) | |
2610 (if (not internal-flag) | |
2611 (mh-undefine-sequence sequence (list msg))) | |
2612 (setcdr entry (delq msg (mh-seq-msgs entry)))))) | |
2613 | |
2614 (defun mh-undefine-sequence (seq msgs) | |
2615 "Remove from the SEQ the list of MSGS." | |
2616 (when (and (mh-valid-seq-p seq) msgs) | |
2617 (apply #'mh-exec-cmd "mark" mh-current-folder "-delete" | |
2618 "-sequence" (symbol-name seq) (mh-coalesce-msg-list msgs)))) | |
2619 | |
2620 (defun mh-define-sequence (seq msgs) | |
2621 "Define the SEQ to contain the list of MSGS. | |
2622 Do not mark pseudo-sequences or empty sequences. | |
2623 Signals an error if SEQ is an invalid name." | |
2624 (if (and msgs | |
2625 (mh-valid-seq-p seq) | |
2626 (not (mh-folder-name-p seq))) | |
2627 (save-excursion | |
2628 (mh-exec-cmd-error nil "mark" mh-current-folder "-add" "-zero" | |
2629 "-sequence" (symbol-name seq) | |
2630 (mh-coalesce-msg-list msgs))))) | |
2631 | |
2632 (defun mh-seq-containing-msg (msg &optional include-internal-flag) | |
2633 "Return a list of the sequences containing MSG. | |
2634 If INCLUDE-INTERNAL-FLAG non-nil, include MH-E internal sequences | |
2635 in list." | |
2636 (let ((l mh-seq-list) | |
2637 (seqs ())) | |
2638 (while l | |
2639 (and (memq msg (mh-seq-msgs (car l))) | |
2640 (or include-internal-flag | |
2641 (not (mh-internal-seq (mh-seq-name (car l))))) | |
2642 (setq seqs (cons (mh-seq-name (car l)) seqs))) | |
2643 (setq l (cdr l))) | |
2644 seqs)) | |
2645 | 1283 |
2646 | 1284 |
2647 | 1285 |
2648 ;;; Build mh-folder-mode keymap: | 1286 ;;; Identities (:group 'mh-identity) |
2649 | 1287 |
2650 (suppress-keymap mh-folder-mode-map) | 1288 (eval-and-compile |
2651 | 1289 (unless (fboundp 'mh-identity-make-menu-no-autoload) |
2652 ;; Use defalias to make sure the documented primary key bindings | 1290 (defun mh-identity-make-menu-no-autoload () |
2653 ;; appear in menu lists. | 1291 "Temporary definition. |
2654 (defalias 'mh-alt-show 'mh-show) | 1292 Real definition will take effect when mh-identity is loaded." |
2655 (defalias 'mh-alt-refile-msg 'mh-refile-msg) | 1293 nil))) |
2656 (defalias 'mh-alt-send 'mh-send) | 1294 |
2657 (defalias 'mh-alt-visit-folder 'mh-visit-folder) | 1295 (defcustom mh-identity-list nil |
2658 | 1296 "*List of identities. |
2659 ;; Save the "b" binding for a future `back'. Maybe? | 1297 |
2660 (gnus-define-keys mh-folder-mode-map | 1298 To customize this option, click on the \"INS\" button and enter a label |
2661 " " mh-page-msg | 1299 such as \"Home\" or \"Work\". Then click on the \"INS\" button with the |
2662 "!" mh-refile-or-write-again | 1300 label \"Add at least one item below\". Then choose one of the items in |
2663 "'" mh-toggle-tick | 1301 the \"Value Menu\". |
2664 "," mh-header-display | 1302 |
2665 "." mh-alt-show | 1303 You can specify an alternate \"From:\" header field using the \"From |
2666 ";" mh-toggle-mh-decode-mime-flag | 1304 Field\" menu item. You must include a valid email address. A standard |
2667 ">" mh-write-msg-to-file | 1305 format is \"First Last <login@@host.domain>\". If you use an initial |
2668 "?" mh-help | 1306 with a period, then you must quote your name as in '\"First I. Last\" |
2669 "E" mh-extract-rejected-mail | 1307 <login@@host.domain>'. People usually list the name of the company |
2670 "M" mh-modify | 1308 where they work using the \"Organization Field\" menu item. Set any |
2671 "\177" mh-previous-page | 1309 arbitrary header field and value in the \"Other Field\" menu item. |
2672 "\C-d" mh-delete-msg-no-motion | 1310 Unless the header field is a standard one, precede the name of your |
2673 "\t" mh-index-next-folder | 1311 field's label with \"X-\", as in \"X-Fruit-of-the-Day:\". The value of |
2674 [backtab] mh-index-previous-folder | 1312 \"Attribution Verb\" overrides the setting of |
2675 "\M-\t" mh-index-previous-folder | 1313 `mh-extract-from-attribution-verb'. Set your signature with the |
2676 "\e<" mh-first-msg | 1314 \"Signature\" menu item. You can specify the contents of |
2677 "\e>" mh-last-msg | 1315 `mh-signature-file-name', a file, or a function. Specify a different |
2678 "\ed" mh-redistribute | 1316 key to sign or encrypt messages with the \"GPG Key ID\" menu item. |
2679 "\r" mh-show | 1317 |
2680 "^" mh-alt-refile-msg | 1318 You can select the identities you have added via the menu called |
2681 "c" mh-copy-msg | 1319 \"Identity\" in the MH-Letter buffer. You can also use |
2682 "d" mh-delete-msg | 1320 \\[mh-insert-identity]. To clear the fields and signature added by the |
2683 "e" mh-edit-again | 1321 identity, select the \"None\" identity. |
2684 "f" mh-forward | 1322 |
2685 "g" mh-goto-msg | 1323 The \"Identity\" menu contains two other items to save you from having |
2686 "i" mh-inc-folder | 1324 to set the identity on every message. The menu item \"Set Default for |
2687 "k" mh-delete-subject-or-thread | 1325 Session\" can be used to set the default identity to the current |
2688 "m" mh-alt-send | 1326 identity until you exit Emacs. The menu item \"Save as Default\" sets |
2689 "n" mh-next-undeleted-msg | 1327 the option `mh-identity-default' to the current identity setting. You |
2690 "\M-n" mh-next-unread-msg | 1328 can also customize the `mh-identity-default' option in the usual |
2691 "o" mh-refile-msg | 1329 fashion." |
2692 "p" mh-previous-undeleted-msg | 1330 :type '(repeat (list :tag "" |
2693 "\M-p" mh-previous-unread-msg | 1331 (string :tag "Label") |
2694 "q" mh-quit | 1332 (repeat :tag "Add at least one item below" |
2695 "r" mh-reply | 1333 (choice |
2696 "s" mh-send | 1334 (cons :tag "From Field" |
2697 "t" mh-toggle-showing | 1335 (const "From") |
2698 "u" mh-undo | 1336 (string :tag "Value")) |
2699 "v" mh-index-visit-folder | 1337 (cons :tag "Organization Field" |
2700 "x" mh-execute-commands | 1338 (const "Organization") |
2701 "|" mh-pipe-msg) | 1339 (string :tag "Value")) |
2702 | 1340 (cons :tag "Other Field" |
2703 (gnus-define-keys (mh-folder-map "F" mh-folder-mode-map) | 1341 (string :tag "Field") |
2704 "?" mh-prefix-help | 1342 (string :tag "Value")) |
2705 "'" mh-index-ticked-messages | 1343 (cons :tag "Attribution Verb" |
2706 "S" mh-sort-folder | 1344 (const ":attribution-verb") |
2707 "c" mh-catchup | 1345 (string :tag "Value")) |
2708 "f" mh-alt-visit-folder | 1346 (cons :tag "Signature" |
2709 "k" mh-kill-folder | 1347 (const :tag "Signature" |
2710 "l" mh-list-folders | 1348 ":signature") |
2711 "n" mh-index-new-messages | 1349 (choice |
2712 "o" mh-alt-visit-folder | 1350 (const :tag "mh-signature-file-name" |
2713 "p" mh-pack-folder | 1351 nil) |
2714 "q" mh-index-sequenced-messages | 1352 (file) |
2715 "r" mh-rescan-folder | 1353 (function))) |
2716 "s" mh-search | 1354 (cons :tag "GPG Key ID" |
2717 "u" mh-undo-folder | 1355 (const :tag "GPG Key ID" |
2718 "v" mh-visit-folder) | 1356 ":pgg-default-user-id") |
2719 | 1357 (string :tag "Value")))))) |
2720 (define-key mh-folder-mode-map "I" mh-inc-spool-map) | 1358 :set (lambda (symbol value) |
2721 | 1359 (set-default symbol value) |
2722 (gnus-define-keys (mh-junk-map "J" mh-folder-mode-map) | 1360 (mh-identity-make-menu-no-autoload)) |
2723 "?" mh-prefix-help | 1361 :group 'mh-identity) |
2724 "b" mh-junk-blacklist | 1362 |
2725 "w" mh-junk-whitelist) | 1363 (defcustom mh-auto-fields-list nil |
2726 | 1364 "List of recipients for which header lines are automatically inserted. |
2727 (gnus-define-keys (mh-ps-print-map "P" mh-folder-mode-map) | 1365 |
2728 "?" mh-prefix-help | 1366 This option can be used to set the identity depending on the |
2729 "C" mh-ps-print-toggle-color | 1367 recipient. To customize this option, click on the \"INS\" button and |
2730 "F" mh-ps-print-toggle-faces | 1368 enter a regular expression for the recipient's address. Click on the |
2731 "f" mh-ps-print-msg-file | 1369 \"INS\" button with the \"Add at least one item below\" label. Then choose |
2732 "l" mh-print-msg | 1370 one of the items in the \"Value Menu\". |
2733 "p" mh-ps-print-msg) | 1371 |
2734 | 1372 The \"Identity\" menu item is used to select an identity from those |
2735 (gnus-define-keys (mh-sequence-map "S" mh-folder-mode-map) | 1373 configured in `mh-identity-list'. All of the information for that |
2736 "'" mh-narrow-to-tick | 1374 identity will be added if the recipient matches. The \"Fcc Field\" menu |
2737 "?" mh-prefix-help | 1375 item is used to select a folder that is used in the \"Fcc:\" header. |
2738 "d" mh-delete-msg-from-seq | 1376 When you send the message, MH will put a copy of your message in this |
2739 "k" mh-delete-seq | 1377 folder. The \"Mail-Followup-To Field\" menu item is used to insert an |
2740 "l" mh-list-sequences | 1378 \"Mail-Followup-To:\" header field with the recipients you provide. If |
2741 "n" mh-narrow-to-seq | 1379 the recipient's mail user agent supports this header field (as nmh |
2742 "p" mh-put-msg-in-seq | 1380 does), then their replies will go to the addresses listed. This is |
2743 "s" mh-msg-is-in-seq | 1381 useful if their replies go both to the list and to you and you don't |
2744 "w" mh-widen) | 1382 have a mechanism to suppress duplicates. If you reply to someone not |
2745 | 1383 on the list, you must either remove the \"Mail-Followup-To:\" field, or |
2746 (gnus-define-keys (mh-thread-map "T" mh-folder-mode-map) | 1384 ensure the recipient is also listed there so that he receives replies |
2747 "?" mh-prefix-help | 1385 to your reply. Other header fields may be added using the \"Other |
2748 "u" mh-thread-ancestor | 1386 Field\" menu item. |
2749 "p" mh-thread-previous-sibling | 1387 |
2750 "n" mh-thread-next-sibling | 1388 These fields can only be added after the recipient is known. Once the |
2751 "t" mh-toggle-threads | 1389 header contains one or more recipients, run the |
2752 "d" mh-thread-delete | 1390 \\[mh-insert-auto-fields] command or choose the \"Identity -> Insert |
2753 "o" mh-thread-refile) | 1391 Auto Fields\" menu item to insert these fields manually. However, you |
2754 | 1392 can just send the message and the fields will be added automatically. |
2755 (gnus-define-keys (mh-limit-map "/" mh-folder-mode-map) | 1393 You are given a chance to see these fields and to confirm them before |
2756 "'" mh-narrow-to-tick | 1394 the message is actually sent. You can do away with this confirmation |
2757 "?" mh-prefix-help | 1395 by turning off the option `mh-auto-fields-prompt-flag'. |
2758 "c" mh-narrow-to-cc | 1396 |
2759 "g" mh-narrow-to-range | 1397 You should avoid using the same header field in `mh-auto-fields-list' |
2760 "m" mh-narrow-to-from | 1398 and `mh-identity-list' definitions that may apply to the same message |
2761 "s" mh-narrow-to-subject | 1399 as the result is undefined." |
2762 "t" mh-narrow-to-to | 1400 :type `(repeat |
2763 "w" mh-widen) | 1401 (list :tag "" |
2764 | 1402 (string :tag "Recipient") |
2765 (gnus-define-keys (mh-extract-map "X" mh-folder-mode-map) | 1403 (repeat :tag "Add at least one item below" |
2766 "?" mh-prefix-help | 1404 (choice |
2767 "s" mh-store-msg ;shar | 1405 (cons :tag "Identity" |
2768 "u" mh-store-msg) ;uuencode | 1406 (const ":identity") |
2769 | 1407 ,(append |
2770 (gnus-define-keys (mh-digest-map "D" mh-folder-mode-map) | 1408 '(radio) |
2771 " " mh-page-digest | 1409 (mapcar |
2772 "?" mh-prefix-help | 1410 (function (lambda (arg) `(const ,arg))) |
2773 "\177" mh-page-digest-backwards | 1411 (mapcar 'car mh-identity-list)))) |
2774 "b" mh-burst-digest) | 1412 (cons :tag "Fcc Field" |
2775 | 1413 (const "fcc") |
2776 (gnus-define-keys (mh-mime-map "K" mh-folder-mode-map) | 1414 (string :tag "Value")) |
2777 "?" mh-prefix-help | 1415 (cons :tag "Mail-Followup-To Field" |
2778 "a" mh-mime-save-parts | 1416 (const "Mail-Followup-To") |
2779 "e" mh-display-with-external-viewer | 1417 (string :tag "Value")) |
2780 "i" mh-folder-inline-mime-part | 1418 (cons :tag "Other Field" |
2781 "o" mh-folder-save-mime-part | 1419 (string :tag "Field") |
2782 "t" mh-toggle-mime-buttons | 1420 (string :tag "Value")))))) |
2783 "v" mh-folder-toggle-mime-part | 1421 :group 'mh-identity) |
2784 "\t" mh-next-button | 1422 |
2785 [backtab] mh-prev-button | 1423 (defcustom mh-auto-fields-prompt-flag t |
2786 "\M-\t" mh-prev-button) | 1424 "*Non-nil means to prompt before sending if fields inserted. |
2787 | 1425 See `mh-auto-fields-list'." |
2788 (cond | 1426 :type 'boolean |
2789 (mh-xemacs-flag | 1427 :group 'mh-identity) |
2790 (define-key mh-folder-mode-map [button2] 'mh-show-mouse)) | 1428 |
2791 (t | 1429 (defcustom mh-identity-default nil |
2792 (define-key mh-folder-mode-map [mouse-2] 'mh-show-mouse))) | 1430 "Default identity to use when `mh-letter-mode' is called. |
2793 | 1431 See `mh-identity-list'." |
2794 ;; "C-c /" prefix is used in mh-folder-mode by pgp.el and mailcrypt | 1432 :type (append |
1433 '(radio) | |
1434 (cons '(const :tag "None" nil) | |
1435 (mapcar (function (lambda (arg) `(const ,arg))) | |
1436 (mapcar 'car mh-identity-list)))) | |
1437 :group 'mh-identity) | |
1438 | |
1439 (defcustom mh-identity-handlers | |
1440 '(("From" . mh-identity-handler-top) | |
1441 (":default" . mh-identity-handler-bottom) | |
1442 (":attribution-verb" . mh-identity-handler-attribution-verb) | |
1443 (":signature" . mh-identity-handler-signature) | |
1444 (":pgg-default-user-id" . mh-identity-handler-gpg-identity)) | |
1445 "Handler functions for fields in `mh-identity-list'. | |
1446 | |
1447 This option is used to change the way that fields, signatures, | |
1448 and attributions in `mh-identity-list' are added. To customize | |
1449 `mh-identity-handlers', replace the name of an existing handler | |
1450 function associated with the field you want to change with the | |
1451 name of a function you have written. You can also click on an | |
1452 \"INS\" button and insert a field of your choice and the name of | |
1453 the function you have written to handle it. | |
1454 | |
1455 The \"Field\" field can be any field that you've used in your | |
1456 `mh-identity-list'. The special fields \":attribution-verb\", | |
1457 \":signature\", or \":pgg-default-user-id\" are used for the | |
1458 `mh-identity-list' choices \"Attribution Verb\", \"Signature\", and | |
1459 \"GPG Key ID\" respectively. | |
1460 | |
1461 The handler associated with the \":default\" field is used when no | |
1462 other field matches. | |
1463 | |
1464 The handler functions are passed two or three arguments: the | |
1465 FIELD itself (for example, \"From\"), or one of the special | |
1466 fields (for example, \":signature\"), and the ACTION 'remove or | |
1467 'add. If the action is 'add, an additional argument | |
1468 containing the VALUE for the field is given." | |
1469 :type '(repeat (cons (string :tag "Field") function)) | |
1470 :group 'mh-identity) | |
2795 | 1471 |
2796 | 1472 |
2797 | 1473 |
2798 ;;; Help Messages | 1474 ;;; Incorporating Your Mail (:group 'mh-inc) |
2799 | 1475 |
2800 ;; If you add a new prefix, add appropriate text to the nil key. | 1476 (defcustom mh-inc-prog "inc" |
2801 ;; | 1477 "*Program to incorporate new mail into a folder. |
2802 ;; In general, messages are grouped logically. Taking the main commands for | 1478 |
2803 ;; example, the first line is "ways to view messages," the second line is | 1479 This program generates a one-line summary for each of the new |
2804 ;; "things you can do with messages", and the third is "composing" messages. | 1480 messages. Unless it is an absolute pathname, the file is assumed |
2805 ;; | 1481 to be in the `mh-progs' directory. You may also link a file to |
2806 ;; When adding a new prefix, ensure that the help message contains "what" the | 1482 \"inc\" that uses a different format. You'll then need to modify |
2807 ;; prefix is for. For example, if the word "folder" were not present in the | 1483 several scan line format variables appropriately." |
2808 ;; "F" entry, it would not be clear what these commands operated upon. | 1484 :type 'string |
2809 (defvar mh-help-messages | 1485 :group 'mh-inc) |
2810 '((nil "[i]nc, [.]show, [,]show all, [n]ext, [p]revious,\n" | 1486 |
2811 "[d]elete, [o]refile, e[x]ecute,\n" | 1487 (eval-and-compile |
2812 "[s]end, [r]eply,\n" | 1488 (unless (fboundp 'mh-inc-spool-make-no-autoload) |
2813 "[;]toggle MIME decoding.\n" | 1489 (defun mh-inc-spool-make-no-autoload () |
2814 "Prefix characters:\n [F]older, [S]equence, [J]unk, MIME [K]eys," | 1490 "Temporary definition. |
2815 "\n [T]hread, [/]limit, e[X]tract, [D]igest, [I]nc spools.") | 1491 Real definition will take effect when mh-inc is loaded." |
2816 | 1492 nil))) |
2817 (?F "[l]ist; [v]isit folder;\n" | 1493 |
2818 "[n]ew messages; [']ticked messages; [s]earch;\n" | 1494 (defcustom mh-inc-spool-list nil |
2819 "[p]ack; [S]ort; [r]escan; [k]ill") | 1495 "*Alternate spool files. |
2820 (?P "[p]rint message to [f]ile; old-style [l]pr printing;\n" | 1496 |
2821 "Toggle printing of [C]olors, [F]aces") | 1497 You can use the `mh-inc-spool-list' variable to direct MH-E to |
2822 (?S "[p]ut message in sequence, [n]arrow, [']narrow to ticked, [w]iden,\n" | 1498 retrieve mail from arbitrary spool files other than your system |
2823 "[s]equences, [l]ist,\n" | 1499 mailbox, file it in folders other than your \"+inbox\", and assign |
2824 "[d]elete message from sequence, [k]ill sequence") | 1500 key bindings to incorporate this mail. |
2825 (?T "[t]oggle, [d]elete, [o]refile thread") | 1501 |
2826 (?/ "Limit to [c]c, ran[g]e, fro[m], [s]ubject, [t]o; [w]iden") | 1502 Suppose you are subscribed to the \"mh-e-devel\" mailing list and |
2827 (?X "un[s]har, [u]udecode message") | 1503 you use \"procmail\" to filter this mail into \"~/mail/mh-e\" with |
2828 (?D "[b]urst digest") | 1504 the following recipe in \".procmailrc\": |
2829 (?K "[v]iew, [i]nline, [o]utput/save MIME part; save [a]ll parts; \n" | 1505 |
2830 "[TAB] next; [SHIFT-TAB] previous") | 1506 MAILDIR=$HOME/mail |
2831 (?J "[b]lacklist, [w]hitelist message")) | 1507 :0: |
2832 "Key binding cheat sheet. | 1508 * ^From mh-e-devel-admin@stop.mail-abuse.org |
2833 | 1509 mh-e |
2834 This is an associative array which is used to show the most common commands. | 1510 |
2835 The key is a prefix char. The value is one or more strings which are | 1511 In order to incorporate \"~/mail/mh-e\" into \"+mh-e\" with an |
2836 concatenated together and displayed in the minibuffer if ? is pressed after | 1512 \"I m\" (mh-inc-spool-mh-e) command, customize this option, and click |
2837 the prefix character. The special key nil is used to display the | 1513 on the \"INS\" button. Enter a \"Spool File\" of \"~/mail/mh-e\", a |
2838 non-prefixed commands. | 1514 \"Folder\" of \"mh-e\", and a \"Key Binding\" of \"m\". |
2839 | 1515 |
2840 The substitutions described in `substitute-command-keys' are performed as | 1516 You can use \"xbuffy\" to automate the incorporation of this mail |
2841 well.") | 1517 using the \"gnudoit\" command in the \"gnuserv\" package as follows: |
1518 | |
1519 box ~/mail/mh-e | |
1520 title mh-e | |
1521 origMode | |
1522 polltime 10 | |
1523 headertime 0 | |
1524 command gnudoit -q '(mh-inc-spool-mh-e)'" | |
1525 :type '(repeat (list (file :tag "Spool File") | |
1526 (string :tag "Folder") | |
1527 (character :tag "Key Binding"))) | |
1528 :set (lambda (symbol value) | |
1529 (set-default symbol value) | |
1530 (mh-inc-spool-make-no-autoload)) | |
1531 :group 'mh-inc) | |
2842 | 1532 |
2843 | 1533 |
2844 | 1534 |
2845 (dolist (mess '("^Cursor not pointing to message$" | 1535 ;;; Dealing with Junk Mail (:group 'mh-junk) |
2846 "^There is no other window$")) | 1536 |
2847 (add-to-list 'debug-ignored-errors mess)) | 1537 (defvar mh-junk-choice nil |
1538 "Chosen spam fighting program.") | |
1539 | |
1540 ;; Available spam filter interfaces | |
1541 (defvar mh-junk-function-alist | |
1542 '((spamassassin mh-spamassassin-blacklist mh-spamassassin-whitelist) | |
1543 (bogofilter mh-bogofilter-blacklist mh-bogofilter-whitelist) | |
1544 (spamprobe mh-spamprobe-blacklist mh-spamprobe-whitelist)) | |
1545 "Available choices of spam programs to use. | |
1546 | |
1547 This is an alist. For each element there are functions that | |
1548 blacklist a message as spam and whitelist a message incorrectly | |
1549 classified as spam.") | |
1550 | |
1551 (defun mh-junk-choose (symbol value) | |
1552 "Choose spam program to use. | |
1553 | |
1554 The function is always called with SYMBOL bound to | |
1555 `mh-junk-program' and VALUE bound to the new value of | |
1556 `mh-junk-program'. The function sets the variable | |
1557 `mh-junk-choice' in addition to `mh-junk-program'." | |
1558 (set symbol value) ;XXX shouldn't this be set-default? | |
1559 (setq mh-junk-choice | |
1560 (or value | |
1561 (loop for element in mh-junk-function-alist | |
1562 until (executable-find (symbol-name (car element))) | |
1563 finally return (car element))))) | |
1564 | |
1565 (defcustom mh-junk-background nil | |
1566 "If on, spam programs are run in background. | |
1567 | |
1568 By default, the programs are run in the foreground, but this can | |
1569 be slow when junking large numbers of messages. If you have | |
1570 enough memory or don't junk that many messages at the same time, | |
1571 you might try turning on this option." | |
1572 :type '(choice (const :tag "Off" nil) | |
1573 (const :tag "On" 0)) | |
1574 :group 'mh-junk) | |
1575 | |
1576 (defcustom mh-junk-disposition nil | |
1577 "Disposition of junk mail." | |
1578 :type '(choice (const :tag "Delete Spam" nil) | |
1579 (string :tag "Spam Folder")) | |
1580 :group 'mh-junk) | |
1581 | |
1582 (defcustom mh-junk-program nil | |
1583 "Spam program that MH-E should use. | |
1584 | |
1585 The default setting of this option is \"Auto-detect\" which means | |
1586 that MH-E will automatically choose one of SpamAssassin, | |
1587 bogofilter, or SpamProbe in that order. If, for example, you have | |
1588 both SpamAssassin and bogofilter installed and you want to use | |
1589 bogofilter, then you can set this option to \"Bogofilter\"." | |
1590 :type '(choice (const :tag "Auto-detect" nil) | |
1591 (const :tag "SpamAssassin" spamassassin) | |
1592 (const :tag "Bogofilter" bogofilter) | |
1593 (const :tag "SpamProbe" spamprobe)) | |
1594 :set 'mh-junk-choose | |
1595 :group 'mh-junk) | |
1596 | |
1597 | |
1598 | |
1599 ;;; Editing a Draft (:group 'mh-letter) | |
1600 | |
1601 (defcustom mh-compose-insertion (if (locate-library "mml") 'mml 'mh) | |
1602 "Type of tags used when composing MIME messages. | |
1603 | |
1604 In addition to MH-style directives, MH-E also supports MML (MIME | |
1605 Meta Language) tags. (see Info node `(emacs-mime)Composing'). | |
1606 This option can be used to choose between them. By default, this | |
1607 option is set to \"MML\" if it is supported since it provides a | |
1608 lot more functionality. This option can also be set to \"MH\" if | |
1609 MH-style directives are preferred." | |
1610 :type '(choice (const :tag "MML" mml) | |
1611 (const :tag "MH" mh)) | |
1612 :group 'mh-letter) | |
1613 | |
1614 (defcustom mh-compose-skipped-header-fields | |
1615 '("From" "Organization" "References" "In-Reply-To" | |
1616 "X-Face" "Face" "X-Image-URL" "X-Mailer") | |
1617 "List of header fields to skip over when navigating in draft." | |
1618 :type '(repeat (string :tag "Field")) | |
1619 :group 'mh-letter) | |
1620 | |
1621 (defcustom mh-compose-space-does-completion-flag nil | |
1622 "*Non-nil means \\<mh-letter-mode-map>\\[mh-letter-complete-or-space] does completion in message header." | |
1623 :type 'boolean | |
1624 :group 'mh-letter) | |
1625 | |
1626 (defcustom mh-delete-yanked-msg-window-flag nil | |
1627 "*Non-nil means delete any window displaying the message. | |
1628 | |
1629 This deletes the window containing the original message after | |
1630 yanking it with \\<mh-letter-mode-map>\\[mh-yank-cur-msg] to make | |
1631 more room on your screen for your reply." | |
1632 :type 'boolean | |
1633 :group 'mh-letter) | |
1634 | |
1635 (defcustom mh-extract-from-attribution-verb "wrote:" | |
1636 "*Verb to use for attribution when a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]. | |
1637 | |
1638 The attribution consists of the sender's name and email address | |
1639 followed by the content of this option. This option can be set to | |
1640 \"wrote:\", \"a écrit:\", and \"schrieb:\". You can also use the | |
1641 \"Custom String\" menu item to enter your own verb." | |
1642 :type '(choice (const "wrote:") | |
1643 (const "a écrit:") | |
1644 (const "schrieb:") | |
1645 (string :tag "Custom String")) | |
1646 :group 'mh-letter) | |
1647 | |
1648 (defcustom mh-ins-buf-prefix "> " | |
1649 "*String to put before each line of a yanked or inserted message. | |
1650 | |
1651 The prefix \"> \" is the default setting of this option. I | |
1652 suggest that you not modify this option since it is used by many | |
1653 mailers and news readers: messages are far easier to read if | |
1654 several included messages have all been indented by the same | |
1655 string. | |
1656 | |
1657 This prefix is not inserted if you use one of the supercite | |
1658 flavors of `mh-yank-behavior' or you have added a | |
1659 `mail-citation-hook'." | |
1660 :type 'string | |
1661 :group 'mh-letter) | |
1662 | |
1663 (defcustom mh-letter-complete-function 'ispell-complete-word | |
1664 "*Function to call when completing outside of address or folder fields. | |
1665 | |
1666 In the body of the message, | |
1667 \\<mh-letter-mode-map>\\[mh-letter-complete] runs this function, | |
1668 which is set to \"ispell-complete-word\" by default." | |
1669 :type '(choice function (const nil)) | |
1670 :group 'mh-letter) | |
1671 | |
1672 (defcustom mh-letter-fill-column 72 | |
1673 "*Fill column to use in MH Letter mode. | |
1674 | |
1675 By default, this option is 72 to allow others to quote your | |
1676 message without line wrapping." | |
1677 :type 'integer | |
1678 :group 'mh-letter) | |
1679 | |
1680 (defcustom mh-mml-method-default (if mh-pgp-support-flag "pgpmime" "none") | |
1681 "Default method to use in security tags. | |
1682 | |
1683 This option is used to select between a variety of mail security | |
1684 mechanisms. The default is \"PGP (MIME)\" if it is supported\; | |
1685 otherwise, the default is \"None\". Other mechanisms include | |
1686 vanilla \"PGP\" and \"S/MIME\". | |
1687 | |
1688 The `pgg' customization group may have some settings which may | |
1689 interest you (see Info node `(pgg)'). | |
1690 | |
1691 In particular, I turn on the option `pgg-encrypt-for-me' so that | |
1692 all messages I encrypt are encrypted with my public key as well. | |
1693 If you keep a copy of all of your outgoing mail with a \"Fcc:\" | |
1694 header field, this setting is vital so that you can read the mail | |
1695 you write!" | |
1696 :type '(choice (const :tag "PGP (MIME)" "pgpmime") | |
1697 (const :tag "PGP" "pgp") | |
1698 (const :tag "S/MIME" "smime") | |
1699 (const :tag "None" "none")) | |
1700 :group 'mh-letter) | |
1701 | |
1702 (defcustom mh-signature-file-name "~/.signature" | |
1703 "*Source of user's signature. | |
1704 | |
1705 By default, the text of your signature is taken from the file | |
1706 \"~/.signature\". You can read from other sources by changing this | |
1707 option. This file may contain a vCard in which case an attachment is | |
1708 added with the vCard. | |
1709 | |
1710 This option may also be a symbol, in which case that function is | |
1711 called. You may not want a signature separator to be added for you; | |
1712 instead you may want to insert one yourself. Options that you may find | |
1713 useful to do this include `mh-signature-separator' (when inserting a | |
1714 signature separator) and `mh-signature-separator-regexp' (for finding | |
1715 said separator). The function `mh-signature-separator-p', which | |
1716 reports t if the buffer contains a separator, may be useful as well. | |
1717 | |
1718 The signature is inserted into your message with the command | |
1719 \\<mh-letter-mode-map>\\[mh-insert-signature] or with the option | |
1720 `mh-identity-list'." | |
1721 :type 'file | |
1722 :group 'mh-letter) | |
1723 | |
1724 (defcustom mh-signature-separator-flag t | |
1725 "*Non-nil means a signature separator should be inserted. | |
1726 | |
1727 It is not recommended that you change this option since various | |
1728 mail user agents, including MH-E, use the separator to present | |
1729 the signature differently, and to suppress the signature when | |
1730 replying or yanking a letter into a draft." | |
1731 :type 'boolean | |
1732 :group 'mh-letter) | |
1733 | |
1734 (defcustom mh-x-face-file "~/.face" | |
1735 "*File containing face header field to insert in outgoing mail. | |
1736 | |
1737 If the file starts with either of the strings \"X-Face:\", \"Face:\" | |
1738 or \"X-Image-URL:\" then the contents are added to the message header | |
1739 verbatim. Otherwise it is assumed that the file contains the value of | |
1740 the \"X-Face:\" header field. | |
1741 | |
1742 The \"X-Face:\" header field, which is a low-resolution, black and | |
1743 white image, can be generated using the \"compface\" command (see URL | |
1744 `ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z'). The | |
1745 \"Online X-Face Converter\" is a useful resource for quick conversion | |
1746 of images into \"X-Face:\" header fields (see URL | |
1747 `http://www.dairiki.org/xface/'). | |
1748 | |
1749 Use the \"make-face\" script to convert a JPEG image to the higher | |
1750 resolution, color, \"Face:\" header field (see URL | |
1751 `http://quimby.gnus.org/circus/face/make-face'). | |
1752 | |
1753 The URL of any image can be used for the \"X-Image-URL:\" field and no | |
1754 processing of the image is required. | |
1755 | |
1756 To prevent the setting of any of these header fields, either set | |
1757 `mh-x-face-file' to nil, or simply ensure that the file defined by | |
1758 this option doesn't exist." | |
1759 :type 'file | |
1760 :group 'mh-letter) | |
1761 | |
1762 (defcustom mh-yank-behavior 'attribution | |
1763 "*Controls which part of a message is yanked by \\<mh-letter-mode-map>\\[mh-yank-cur-msg]. | |
1764 | |
1765 To include the entire message, including the entire header, use | |
1766 \"Body and Header\". Use \"Body\" to yank just the body without | |
1767 the header. To yank only the portion of the message following the | |
1768 point, set this option to \"Below Point\". | |
1769 | |
1770 Choose \"Invoke supercite\" to pass the entire message and header | |
1771 through supercite. | |
1772 | |
1773 If the \"Body With Attribution\" setting is used, then the | |
1774 message minus the header is yanked and a simple attribution line | |
1775 is added at the top using the value of the option | |
1776 `mh-extract-from-attribution-verb'. This is the default. | |
1777 | |
1778 If the \"Invoke supercite\" or \"Body With Attribution\" settings | |
1779 are used, the \"-noformat\" argument is passed to the \"repl\" | |
1780 program to override a \"-filter\" or \"-format\" argument. These | |
1781 settings also have \"Automatically\" variants that perform the | |
1782 action automatically when you reply so that you don't need to use | |
1783 \\[mh-yank-cur-msg] at all. Note that this automatic action is | |
1784 only performed if the show buffer matches the message being | |
1785 replied to. People who use the automatic variants tend to turn on | |
1786 the option `mh-delete-yanked-msg-window-flag' as well so that the | |
1787 show window is never displayed. | |
1788 | |
1789 If the show buffer has a region, the option `mh-yank-behavior' is | |
1790 ignored unless its value is one of Attribution variants in which | |
1791 case the attribution is added to the yanked region. | |
1792 | |
1793 If this option is set to one of the supercite flavors, the hook | |
1794 `mail-citation-hook' is ignored and `mh-ins-buf-prefix' is not | |
1795 inserted." | |
1796 :type '(choice (const :tag "Body and Header" t) | |
1797 (const :tag "Body" body) | |
1798 (const :tag "Below Point" nil) | |
1799 (const :tag "Invoke supercite" supercite) | |
1800 (const :tag "Invoke supercite, Automatically" autosupercite) | |
1801 (const :tag "Body With Attribution" attribution) | |
1802 (const :tag "Body With Attribution, Automatically" | |
1803 autoattrib)) | |
1804 :group 'mh-letter) | |
1805 | |
1806 | |
1807 | |
1808 ;;; Ranges (:group 'mh-ranges) | |
1809 | |
1810 (defcustom mh-interpret-number-as-range-flag t | |
1811 "*Non-nil means interpret a number as a range. | |
1812 | |
1813 Since one of the most frequent ranges used is \"last:N\", MH-E | |
1814 will interpret input such as \"200\" as \"last:200\" if this | |
1815 option is on (which is the default). If you need to scan just the | |
1816 message 200, then use the range \"200:200\"." | |
1817 :type 'boolean | |
1818 :group 'mh-ranges) | |
1819 | |
1820 | |
1821 | |
1822 ;;; Scan Line Formats (:group 'mh-scan-line-formats) | |
1823 | |
1824 (eval-and-compile | |
1825 (unless (fboundp 'mh-adaptive-cmd-note-flag-check) | |
1826 (defun mh-adaptive-cmd-note-flag-check (symbol value) | |
1827 "Temporary definition. | |
1828 Real definition, below, uses variables that aren't defined yet." | |
1829 (set-default symbol value)))) | |
1830 | |
1831 (defcustom mh-adaptive-cmd-note-flag t | |
1832 "*Non-nil means that the message number width is determined dynamically. | |
1833 | |
1834 If you've created your own format to handle long message numbers, | |
1835 you'll be pleased to know you no longer need it since MH-E adapts its | |
1836 internal format based upon the largest message number if this option | |
1837 is on (the default). This option may only be turned on when | |
1838 `mh-scan-format-file' is set to \"Use MH-E scan Format\". | |
1839 | |
1840 If you prefer fixed-width message numbers, turn off this option and | |
1841 call `mh-set-cmd-note' with the width specified by your format file | |
1842 \(see `mh-scan-format-file'). For example, the default width is 4, so | |
1843 you would use \"(mh-set-cmd-note 4)\"." | |
1844 :type 'boolean | |
1845 :group 'mh-scan-line-formats | |
1846 :set 'mh-adaptive-cmd-note-flag-check) | |
1847 | |
1848 (defun mh-scan-format-file-check (symbol value) | |
1849 "Check if desired setting is legal. | |
1850 Throw an error if user tries to set `mh-scan-format-file' to | |
1851 anything but t when `mh-adaptive-cmd-note-flag' is on. Otherwise, | |
1852 set SYMBOL to VALUE." | |
1853 (if (and (not (eq value t)) | |
1854 (eq mh-adaptive-cmd-note-flag t)) | |
1855 (error "%s %s" "You must turn off `mh-adaptive-cmd-note-flag'" | |
1856 "unless you use \"Use MH-E scan Format\"") | |
1857 (set-default symbol value))) | |
1858 | |
1859 (defcustom mh-scan-format-file t | |
1860 "Specifies the format file to pass to the scan program. | |
1861 | |
1862 The default setting for this option is \"Use MH-E scan Format\". This | |
1863 means that the format string will be taken from the either | |
1864 `mh-scan-format-mh' or `mh-scan-format-nmh' depending on whether MH or | |
1865 nmh (or GNU mailutils) is in use. This setting also enables you to | |
1866 turn on the `mh-adaptive-cmd-note-flag' option. | |
1867 | |
1868 You can also set this option to \"Use Default scan Format\" to get the | |
1869 same output as you would get if you ran \"scan\" from the shell. If | |
1870 you have a format file that you want MH-E to use but not MH, you can | |
1871 set this option to \"Specify a scan Format File\" and enter the name | |
1872 of your format file. | |
1873 | |
1874 If you change the format of the scan lines you'll need to tell MH-E | |
1875 how to parse the new format. As you will see, quite a lot of variables | |
1876 are involved to do that. Use \"\\[apropos] RET mh-scan.*regexp\" to | |
1877 obtain a list of these variables. You will also have to call | |
1878 `mh-set-cmd-note' if your notations are not in column 4 (columns in | |
1879 Emacs start with 0)." | |
1880 :type '(choice (const :tag "Use MH-E scan Format" t) | |
1881 (const :tag "Use Default scan Format" nil) | |
1882 (file :tag "Specify a scan Format File")) | |
1883 :group 'mh-scan-line-formats | |
1884 :set 'mh-scan-format-file-check) | |
1885 | |
1886 (defun mh-adaptive-cmd-note-flag-check (symbol value) | |
1887 "Check if desired setting is legal. | |
1888 Throw an error if user tries to turn on | |
1889 `mh-adaptive-cmd-note-flag' when `mh-scan-format-file' isn't t. | |
1890 Otherwise, set SYMBOL to VALUE." | |
1891 (if (and value | |
1892 (not (eq mh-scan-format-file t))) | |
1893 (error "%s %s" "Can't turn on unless `mh-scan-format-file'" | |
1894 "is set to \"Use MH-E scan Format\"") | |
1895 (set-default symbol value))) | |
1896 | |
1897 (defcustom mh-scan-prog "scan" | |
1898 "*Program used to scan messages. | |
1899 | |
1900 The name of the program that generates a listing of one line per | |
1901 message is held in this option. Unless this variable contains an | |
1902 absolute pathname, it is assumed to be in the `mh-progs' | |
1903 directory. You may link another program to `scan' (see | |
1904 \"mh-profile(5)\") to produce a different type of listing." | |
1905 :type 'string | |
1906 :group 'mh-scan-line-formats) | |
1907 (make-variable-buffer-local 'mh-scan-prog) | |
1908 | |
1909 | |
1910 | |
1911 ;;; Searching (:group 'mh-search) | |
1912 | |
1913 (defcustom mh-search-program nil | |
1914 "Search program that MH-E shall use. | |
1915 | |
1916 The default setting of this option is \"Auto-detect\" which means | |
1917 that MH-E will automatically choose one of swish++, swish-e, | |
1918 mairix, namazu, pick and grep in that order. If, for example, you | |
1919 have both swish++ and mairix installed and you want to use | |
1920 mairix, then you can set this option to \"mairix\". | |
1921 | |
1922 More information about setting up an indexing program to use with | |
1923 MH-E can be found in the documentation of `mh-search'." | |
1924 :type '(choice (const :tag "Auto-detect" nil) | |
1925 (const :tag "swish++" swish++) | |
1926 (const :tag "swish-e" swish) | |
1927 (const :tag "mairix" mairix) | |
1928 (const :tag "namazu" namazu) | |
1929 (const :tag "pick" pick) | |
1930 (const :tag "grep" grep)) | |
1931 :group 'mh-search) | |
1932 | |
1933 | |
1934 | |
1935 ;;; Sending Mail (:group 'mh-sending-mail) | |
1936 | |
1937 (defcustom mh-compose-forward-as-mime-flag t | |
1938 "*Non-nil means that messages are forwarded as attachments. | |
1939 | |
1940 By default, this option is on which means that the forwarded | |
1941 messages are included as attachments. If you would prefer to | |
1942 forward your messages verbatim (as text, inline), then turn off | |
1943 this option. Forwarding messages verbatim works well for short, | |
1944 textual messages, but your recipient won't be able to view any | |
1945 non-textual attachments that were in the forwarded message. Be | |
1946 aware that if you have \"forw: -mime\" in your MH profile, then | |
1947 forwarded messages will always be included as attachments | |
1948 regardless of the settings of this option." | |
1949 :type 'boolean | |
1950 :group 'mh-sending-mail) | |
1951 | |
1952 (defcustom mh-compose-letter-function nil | |
1953 "Invoked when starting a new draft. | |
1954 | |
1955 However, it is the last function called before you edit your | |
1956 message. The consequence of this is that you can write a function | |
1957 to write and send the message for you. This function is passed | |
1958 three arguments: the contents of the TO, SUBJECT, and CC header | |
1959 fields." | |
1960 :type '(choice (const nil) function) | |
1961 :group 'mh-sending-mail) | |
1962 | |
1963 (defcustom mh-compose-prompt-flag nil | |
1964 "*Non-nil means prompt for header fields when composing a new draft." | |
1965 :type 'boolean | |
1966 :group 'mh-sending-mail) | |
1967 | |
1968 (defcustom mh-forward-subject-format "%s: %s" | |
1969 "*Format string for forwarded message subject. | |
1970 | |
1971 This option is a string which includes two escapes (\"%s\"). The | |
1972 first \"%s\" is replaced with the sender of the original message, | |
1973 and the second one is replaced with the original \"Subject:\"." | |
1974 :type 'string | |
1975 :group 'mh-sending-mail) | |
1976 | |
1977 (defcustom mh-insert-x-mailer-flag t | |
1978 "*Non-nil means append an \"X-Mailer:\" header field to the header. | |
1979 | |
1980 This header field includes the version of MH-E and Emacs that you | |
1981 are using. If you don't want to participate in our marketing, you | |
1982 can turn this option off." | |
1983 :type 'boolean | |
1984 :group 'mh-sending-mail) | |
1985 | |
1986 (defcustom mh-redist-full-contents-flag nil | |
1987 "*Non-nil means the \"dist\" command needs entire letter for redistribution. | |
1988 | |
1989 This option must be turned on if \"dist\" requires the whole | |
1990 letter for redistribution, which is the case if \"send\" is | |
1991 compiled with the BERK option (which many people abhor). If you | |
1992 find that MH will not allow you to redistribute a message that | |
1993 has been redistributed before, turn off this option." | |
1994 :type 'boolean | |
1995 :group 'mh-sending-mail) | |
1996 | |
1997 (defcustom mh-reply-default-reply-to nil | |
1998 "*Sets the person or persons to whom a reply will be sent. | |
1999 | |
2000 This option is set to \"Prompt\" by default so that you are | |
2001 prompted for the recipient of a reply. If you find that most of | |
2002 the time that you specify \"cc\" when you reply to a message, set | |
2003 this option to \"cc\". Other choices include \"from\", \"to\", or | |
2004 \"all\". You can always edit the recipients in the draft." | |
2005 :type '(choice (const :tag "Prompt" nil) | |
2006 (const "from") | |
2007 (const "to") | |
2008 (const "cc") | |
2009 (const "all")) | |
2010 :group 'mh-sending-mail) | |
2011 | |
2012 (defcustom mh-reply-show-message-flag t | |
2013 "*Non-nil means the MH-Show buffer is displayed when replying. | |
2014 | |
2015 If you include the message automatically, you can hide the | |
2016 MH-Show buffer by turning off this option. | |
2017 | |
2018 See also `mh-reply'." | |
2019 :type 'boolean | |
2020 :group 'mh-sending-mail) | |
2021 | |
2022 | |
2023 | |
2024 ;;; Sequences (:group 'mh-sequences) | |
2025 | |
2026 ;; If `mh-unpropagated-sequences' becomes a defcustom, add the following to | |
2027 ;; the docstring: "Additional sequences that should not to be preserved can be | |
2028 ;; specified by setting `mh-unpropagated-sequences' appropriately." XXX | |
2029 | |
2030 (defcustom mh-refile-preserves-sequences-flag t | |
2031 "*Non-nil means that sequences are preserved when messages are refiled. | |
2032 | |
2033 If a message is in any sequence (except \"Previous-Sequence:\" | |
2034 and \"cur\") when it is refiled, then it will still be in those | |
2035 sequences in the destination folder. If this behavior is not | |
2036 desired, then turn off this option." | |
2037 :type 'boolean | |
2038 :group 'mh-sequences) | |
2039 | |
2040 (defcustom mh-tick-seq 'tick | |
2041 "The name of the MH sequence for ticked messages. | |
2042 | |
2043 You can customize this option if you already use the \"tick\" | |
2044 sequence for your own use. You can also disable all of the | |
2045 ticking functions by choosing the \"Disable Ticking\" item but | |
2046 there isn't much advantage to that." | |
2047 :type '(choice (const :tag "Disable Ticking" nil) | |
2048 symbol) | |
2049 :group 'mh-sequences) | |
2050 | |
2051 (defcustom mh-update-sequences-after-mh-show-flag t | |
2052 "*Non-nil means flush MH sequences to disk after message is shown\\<mh-folder-mode-map>. | |
2053 | |
2054 Three sequences are maintained internally by MH-E and pushed out | |
2055 to MH when a message is shown. They include the sequence | |
2056 specified by your \"Unseen-Sequence:\" profile entry, \"cur\", | |
2057 and the sequence listed by the option `mh-tick-seq' which is | |
2058 \"tick\" by default. If you do not like this behavior, turn off | |
2059 this option. You can then update the state manually with the | |
2060 \\[mh-execute-commands], \\[mh-quit], or \\[mh-update-sequences] | |
2061 commands." | |
2062 :type 'boolean | |
2063 :group 'mh-sequences) | |
2064 | |
2065 | |
2066 | |
2067 ;;; Reading Your Mail (:group 'mh-show) | |
2068 | |
2069 (defcustom mh-bury-show-buffer-flag t | |
2070 "*Non-nil means show buffer is buried. | |
2071 | |
2072 One advantage of not burying the show buffer is that one can | |
2073 delete the show buffer more easily in an electric buffer list | |
2074 because of its proximity to its associated MH-Folder buffer. Try | |
2075 running \\[electric-buffer-list] to see what I mean." | |
2076 :type 'boolean | |
2077 :group 'mh-show) | |
2078 | |
2079 (defcustom mh-clean-message-header-flag t | |
2080 "*Non-nil means remove extraneous header fields. | |
2081 | |
2082 See also `mh-invisible-header-fields-default' and | |
2083 `mh-invisible-header-fields'." | |
2084 :type 'boolean | |
2085 :group 'mh-show) | |
2086 | |
2087 (defcustom mh-decode-mime-flag (not (not (locate-library "mm-decode"))) | |
2088 "*Non-nil means attachments are handled\\<mh-folder-mode-map>. | |
2089 | |
2090 MH-E can handle attachments as well if the Gnus `mm-decode' | |
2091 library is present. If so, this option will be on. Otherwise, | |
2092 you'll see the MIME body parts rather than text or attachments. | |
2093 There isn't much point in turning off this option; however, you | |
2094 can inspect it if it appears that the body parts are not being | |
2095 interpreted correctly or toggle it with the command | |
2096 \\[mh-toggle-mh-decode-mime-flag] to view the raw message. | |
2097 | |
2098 This option also controls the display of quoted-printable | |
2099 messages and other graphical widgets. See the options | |
2100 `mh-graphical-smileys-flag' and `mh-graphical-emphasis-flag'." | |
2101 :type 'boolean | |
2102 :group 'mh-show) | |
2103 | |
2104 (defcustom mh-display-buttons-for-alternatives-flag nil | |
2105 "*Non-nil means display buttons for all alternative attachments. | |
2106 | |
2107 Sometimes, a mail program will produce multiple alternatives of | |
2108 the attachment in increasing degree of faithfulness to the | |
2109 original content. By default, only the preferred alternative is | |
2110 displayed. If this option is on, then the preferred part is shown | |
2111 inline and buttons are shown for each of the other alternatives." | |
2112 :type 'boolean | |
2113 :group 'mh-show) | |
2114 | |
2115 (defcustom mh-display-buttons-for-inline-parts-flag nil | |
2116 "*Non-nil means display buttons for all inline attachments\\<mh-folder-mode-map>. | |
2117 | |
2118 The sender can request that attachments should be viewed inline so | |
2119 that they do not really appear like an attachment at all to the | |
2120 reader. Most of the time, this is desirable, so by default MH-E | |
2121 suppresses the buttons for inline attachments. On the other hand, you | |
2122 may receive code or HTML which the sender has added to his message as | |
2123 inline attachments so that you can read them in MH-E. In this case, it | |
2124 is useful to see the buttons so that you know you don't have to cut | |
2125 and paste the code into a file; you can simply save the attachment. | |
2126 | |
2127 If you want to make the buttons visible for inline attachments, you | |
2128 can use the command \\[mh-toggle-mime-buttons] to toggle the | |
2129 visibility of these buttons. You can turn on these buttons permanently | |
2130 by turning on this option. | |
2131 | |
2132 MH-E cannot display all attachments inline however. It can display | |
2133 text (including HTML) and images." | |
2134 :type 'boolean | |
2135 :group 'mh-show) | |
2136 | |
2137 (defcustom mh-do-not-confirm-flag nil | |
2138 "*Non-nil means non-reversible commands do not prompt for confirmation. | |
2139 | |
2140 Commands such as `mh-pack-folder' prompt to confirm whether to | |
2141 process outstanding moves and deletes or not before continuing. | |
2142 Turning on this option means that these actions will be | |
2143 performed--which is usually desired but cannot be | |
2144 retracted--without question." | |
2145 :type 'boolean | |
2146 :group 'mh-show) | |
2147 | |
2148 (defcustom mh-fetch-x-image-url nil | |
2149 "*Control fetching of \"X-Image-URL:\" header field image. | |
2150 | |
2151 Ths option controls the fetching of the \"X-Image-URL:\" header | |
2152 field image with the following values: | |
2153 | |
2154 Ask Before Fetching | |
2155 You are prompted before the image is fetched. MH-E will | |
2156 remember your reply and will either use the already fetched | |
2157 image the next time the same URL is encountered or silently | |
2158 skip it if you didn't fetch it the first time. This is a | |
2159 good setting. | |
2160 | |
2161 Never Fetch | |
2162 Images are never fetched and only displayed if they are | |
2163 already present in the cache. This is the default. | |
2164 | |
2165 There isn't a value of \"Always Fetch\" for privacy and DOS (denial of | |
2166 service) reasons. For example, fetching a URL can tip off a spammer | |
2167 that you've read his email (which is why you shouldn't blindly answer | |
2168 yes if you've set this option to \"Ask Before Fetching\"). Someone may | |
2169 also flood your network and fill your disk drive by sending a torrent | |
2170 of messages, each specifying a unique URL to a very large file. | |
2171 | |
2172 The cache of images is found in the directory \".mhe-x-image-cache\" | |
2173 within your MH directory. You can add your own face to the \"From:\" | |
2174 field too. See Info node `(mh-e)Picture'. | |
2175 | |
2176 This setting only has effect if the option `mh-show-use-xface-flag' is | |
2177 turned on." | |
2178 | |
2179 :type '(choice (const :tag "Ask Before Fetching" ask) | |
2180 (const :tag "Never Fetch" nil)) | |
2181 :group 'mh-show) | |
2182 | |
2183 (defcustom mh-graphical-smileys-flag t | |
2184 "*Non-nil means graphical smileys are displayed. | |
2185 | |
2186 It is a long standing custom to inject body language using a | |
2187 cornucopia of punctuation, also known as the \"smileys\". MH-E | |
2188 can render these as graphical widgets if this option is turned | |
2189 on, which it is by default. Smileys include patterns such as :-) | |
2190 and ;-). | |
2191 | |
2192 This option is disabled if the option `mh-decode-mime-flag' is | |
2193 turned off." | |
2194 :type 'boolean | |
2195 :group 'mh-show) | |
2196 | |
2197 (defcustom mh-graphical-emphasis-flag t | |
2198 "*Non-nil means graphical emphasis is displayed. | |
2199 | |
2200 A few typesetting features are indicated in ASCII text with | |
2201 certain characters. If your terminal supports it, MH-E can render | |
2202 these typesetting directives naturally if this option is turned | |
2203 on, which it is by default. For example, _underline_ will be | |
2204 underlined, *bold* will appear in bold, /italics/ will appear in | |
2205 italics, and so on. See the option `gnus-emphasis-alist' for the | |
2206 whole list. | |
2207 | |
2208 This option is disabled if the option `mh-decode-mime-flag' is | |
2209 turned off." | |
2210 :type 'boolean | |
2211 :group 'mh-show) | |
2212 | |
2213 (defcustom mh-highlight-citation-style 'gnus | |
2214 "Style for highlighting citations. | |
2215 | |
2216 If the sender of the message has cited other messages in his | |
2217 message, then MH-E will highlight these citations to emphasize | |
2218 the sender's actual response. This option can be customized to | |
2219 change the highlighting style. The \"Multicolor\" method uses a | |
2220 different color for each indentation while the \"Monochrome\" | |
2221 method highlights all citations in red. To disable highlighting | |
2222 of citations entirely, choose \"None\"." | |
2223 :type '(choice (const :tag "Multicolor" gnus) | |
2224 (const :tag "Monochrome" font-lock) | |
2225 (const :tag "None" nil)) | |
2226 :group 'mh-show) | |
2227 | |
2228 ;; Keep fields alphabetized. Mention source, if known. | |
2229 (defvar mh-invisible-header-fields-internal | |
2230 '("Approved:" | |
2231 "Autoforwarded:" | |
2232 "Bestservhost:" | |
2233 "Cancel-Lock:" ; NNTP posts | |
2234 "Content-" ; RFC 2045 | |
2235 "Delivered-To:" ; Egroups/yahoogroups mailing list manager | |
2236 "Delivery-Date:" ; MH | |
2237 "Delivery:" | |
2238 "DomainKey-Signature:" ;http://antispam.yahoo.com/domainkeys | |
2239 "Encoding:" | |
2240 "Envelope-to:" | |
2241 "Errors-To:" | |
2242 "Face:" ; Gnus Face header | |
2243 "Forwarded:" ; MH | |
2244 "From " ; sendmail | |
2245 "Importance:" ; MS Outlook | |
2246 "In-Reply-To:" ; MH | |
2247 "Lines:" | |
2248 "List-" ; Mailman mailing list manager | |
2249 "List-" ; Unknown mailing list managers | |
2250 "List-Subscribe:" ; Unknown mailing list managers | |
2251 "List-Unsubscribe:" ; Unknown mailing list managers | |
2252 "Mail-from:" ; MH | |
2253 "Mailing-List:" ; Egroups/yahoogroups mailing list manager | |
2254 "Message-Id:" ; RFC 822 | |
2255 "Mime-Version" ; RFC 2045 | |
2256 "NNTP-" ; News | |
2257 "Old-Return-Path:" | |
2258 "Original-Encoded-Information-Types:" ; X400 | |
2259 "Original-Lines:" ; mail to news | |
2260 "Original-NNTP-" ; mail to news | |
2261 "Original-Newsgroups:" ; mail to news | |
2262 "Original-Path:" ; mail to news | |
2263 "Original-Received:" ; mail to news | |
2264 "Original-To:" ; mail to news | |
2265 "Original-X-" ; mail to news | |
2266 "Originator:" | |
2267 "P1-Content-Type:" ; X400 | |
2268 "P1-Message-Id:" ; X400 | |
2269 "P1-Recipient:" ; X400 | |
2270 "Path:" | |
2271 "Precedence:" | |
2272 "Prev-Resent" ; MH | |
2273 "Priority:" | |
2274 "Received:" ; RFC 822 | |
2275 "Received-SPF:" ; Gmail | |
2276 "References:" | |
2277 "Remailed-" ; MH | |
2278 "Replied:" ; MH | |
2279 "Resent" ; MH | |
2280 "Return-Path:" ; RFC 822 | |
2281 "Sensitivity:" ; MS Outlook | |
2282 "Status:" ; sendmail | |
2283 "Thread-" | |
2284 "Ua-Content-Id:" ; X400 | |
2285 ;; "User-Agent:" ; Similar to X-Mailer, so display it. | |
2286 "Via:" ; MH | |
2287 "X-Abuse-Info:" | |
2288 "X-Abuse-and-DMCA-" | |
2289 "X-Accept-Language:" | |
2290 "X-Accept-Language:" ; Netscape/Mozilla | |
2291 "X-Ack:" | |
2292 "X-Administrivia-To:" | |
2293 "X-AntiAbuse:" ; cPanel | |
2294 "X-Apparently-From:" ; MS Outlook | |
2295 "X-Apparently-To:" ; Egroups/yahoogroups mailing list manager | |
2296 "X-Authentication-Warning:" ; sendmail | |
2297 "X-Beenthere:" ; Mailman mailing list manager | |
2298 "X-Bogosity:" ; bogofilter | |
2299 "X-Bugzilla-*" ; Bugzilla | |
2300 "X-Complaints-To:" | |
2301 "X-ContentStamp:" ; NetZero | |
2302 "X-Cron-Env:" | |
2303 "X-DMCA" | |
2304 "X-Delivered" | |
2305 "X-ELNK-Trace:" ; Earthlink mailer | |
2306 "X-Envelope-Date:" ; GNU mailutils | |
2307 "X-Envelope-From:" | |
2308 "X-Envelope-Sender:" | |
2309 "X-Envelope-To:" | |
2310 "X-Evolution:" ; Evolution mail client | |
2311 "X-Face:" | |
2312 "X-Folder:" ; Spam | |
2313 "X-From-Line" | |
2314 "X-Gmail-" ; Gmail | |
2315 "X-Gnus-Mail-Source:" ; gnus | |
2316 "X-Greylist:" ; milter-greylist-1.2.1 | |
2317 "X-Habeas-SWE-1:" ; Spam | |
2318 "X-Habeas-SWE-2:" ; Spam | |
2319 "X-Habeas-SWE-3:" ; Spam | |
2320 "X-Habeas-SWE-4:" ; Spam | |
2321 "X-Habeas-SWE-5:" ; Spam | |
2322 "X-Habeas-SWE-6:" ; Spam | |
2323 "X-Habeas-SWE-7:" ; Spam | |
2324 "X-Habeas-SWE-8:" ; Spam | |
2325 "X-Habeas-SWE-9:" ; Spam | |
2326 "X-Info:" ; NTMail | |
2327 "X-Juno-" ; Juno | |
2328 "X-List-Host:" ; Unknown mailing list managers | |
2329 "X-List-Subscribe:" ; Unknown mailing list managers | |
2330 "X-List-Unsubscribe:" ; Unknown mailing list managers | |
2331 "X-Listprocessor-" ; ListProc(tm) by CREN | |
2332 "X-Listserver:" ; Unknown mailing list managers | |
2333 "X-Loop:" ; Unknown mailing list managers | |
2334 "X-Lumos-SenderID:" ; Roving ConstantContact | |
2335 "X-MAIL-INFO:" ; NetZero | |
2336 "X-MHE-Checksum" ; Checksum added during index search | |
2337 "X-MIME-Autoconverted:" ; sendmail | |
2338 "X-MIMETrack:" | |
2339 "X-MS-" ; MS Outlook | |
2340 "X-MailScanner" ; ListProc(tm) by CREN | |
2341 "X-Mailing-List:" ; Unknown mailing list managers | |
2342 "X-Mailman-Version:" ; Mailman mailing list manager | |
2343 "X-Majordomo:" ; Majordomo mailing list manager | |
2344 "X-Message-Id" | |
2345 "X-MessageWall-Score:" ; Unknown mailing list manager, AUC TeX | |
2346 "X-MimeOLE:" ; MS Outlook | |
2347 "X-Mms-" ; T-Mobile pictures | |
2348 "X-Mozilla-Status:" ; Netscape/Mozilla | |
2349 "X-Msmail-" ; MS Outlook | |
2350 "X-NAI-Spam-" ; Network Associates Inc. SpamKiller | |
2351 "X-News:" ; News | |
2352 "X-No-Archive:" | |
2353 "X-Notes-Item:" ; Lotus Notes Domino structured header | |
2354 "X-OperatingSystem:" | |
2355 ;;"X-Operator:" ; Similar to X-Mailer, so display it | |
2356 "X-Orcl-Content-Type:" | |
2357 "X-Original-Complaints-To:" | |
2358 "X-Original-Date:" ; SourceForge mailing list manager | |
2359 "X-Original-To:" | |
2360 "X-Original-Trace:" | |
2361 "X-OriginalArrivalTime:" ; Hotmail | |
2362 "X-Originating-IP:" ; Hotmail | |
2363 "X-Postfilter:" | |
2364 "X-Priority:" ; MS Outlook | |
2365 "X-Qotd-" ; User added | |
2366 "X-RM" | |
2367 "X-Received-Date:" | |
2368 "X-Received:" | |
2369 "X-Request-" | |
2370 "X-Return-Path-Hint:" ; Roving ConstantContact | |
2371 "X-Roving-*" ; Roving ConstantContact | |
2372 "X-SBClass:" ; Spam | |
2373 "X-SBNote:" ; Spam | |
2374 "X-SBPass:" ; Spam | |
2375 "X-SBRule:" ; Spam | |
2376 "X-SMTP-" | |
2377 "X-Scanned-By" | |
2378 "X-Sender:" | |
2379 "X-Server-Date:" | |
2380 "X-Server-Uuid:" | |
2381 "X-Sieve:" ; Sieve filtering | |
2382 "X-Source" | |
2383 "X-Spam-" ; Spamassassin | |
2384 "X-SpamBouncer:" ; Spam | |
2385 "X-Status" | |
2386 "X-Submissions-To:" | |
2387 "X-Telecom-Digest" | |
2388 "X-Trace:" | |
2389 "X-UID" | |
2390 "X-UIDL:" | |
2391 "X-UNTD-" ; NetZero | |
2392 "X-USANET-" ; usa.net | |
2393 "X-UserInfo1:" | |
2394 "X-VSMLoop:" ; NTMail | |
2395 "X-Virus-Scanned" ; amavisd-new | |
2396 "X-Vms-To:" | |
2397 "X-WebTV-Signature:" | |
2398 "X-Wss-Id:" ; Worldtalk gateways | |
2399 "X-Yahoo" | |
2400 "X-eGroups-" ; Egroups/yahoogroups mailing list manager | |
2401 "X-pgp:" | |
2402 "X-submission-address:" | |
2403 "X400-" ; X400 | |
2404 "Xref:") | |
2405 "List of default header fields that are not to be shown. | |
2406 | |
2407 Do not alter this variable directly. Instead, add entries from | |
2408 here that you would like to be displayed in | |
2409 `mh-invisible-header-fields-default' and add entries to hide in | |
2410 `mh-invisible-header-fields'.") | |
2411 | |
2412 (eval-and-compile | |
2413 (unless (fboundp 'mh-invisible-headers) | |
2414 (defun mh-invisible-headers () | |
2415 "Temporary definition. | |
2416 Real definition, below, uses variables that aren't defined yet." | |
2417 nil))) | |
2418 | |
2419 (defvar mh-delay-invisible-header-generation-flag t | |
2420 "Non-nil means to delay the generation of invisible header fields. | |
2421 Because the function `mh-invisible-headers' uses both | |
2422 `mh-invisible-header-fields' and `mh-invisible-header-fields', it | |
2423 cannot be run until both variables have been initialized.") | |
2424 | |
2425 (defcustom mh-invisible-header-fields nil | |
2426 "*Additional header fields to hide. | |
2427 | |
2428 Header fields that you would like to hide that aren't listed in | |
2429 `mh-invisible-header-fields-default' can be added to this option | |
2430 with a couple of caveats. Regular expressions are not allowed. | |
2431 Unique fields should have a \":\" suffix; otherwise, the element | |
2432 can be used to render invisible an entire class of fields that | |
2433 start with the same prefix. If you think a header field should be | |
2434 generally ignored, report a bug (see URL | |
2435 `https://sourceforge.net/tracker/?group_id=13357&atid=113357'). | |
2436 | |
2437 See also `mh-clean-message-header-flag'." | |
2438 | |
2439 :type '(repeat (string :tag "Header field")) | |
2440 :set (lambda (symbol value) | |
2441 (set-default symbol value) | |
2442 (mh-invisible-headers)) | |
2443 :group 'mh-show) | |
2444 | |
2445 (defcustom mh-invisible-header-fields-default nil | |
2446 "*List of hidden header fields. | |
2447 | |
2448 The header fields listed in this option are hidden, although you | |
2449 can check off any field that you would like to see. | |
2450 | |
2451 Header fields that you would like to hide that aren't listed can | |
2452 be added to the option `mh-invisible-header-fields'. | |
2453 | |
2454 See also `mh-clean-message-header-flag'." | |
2455 :type `(set ,@(mapcar (lambda (x) `(const ,x)) | |
2456 mh-invisible-header-fields-internal)) | |
2457 :set (lambda (symbol value) | |
2458 (set-default symbol value) | |
2459 (mh-invisible-headers)) | |
2460 :group 'mh-show) | |
2461 | |
2462 (defvar mh-invisible-header-fields-compiled nil | |
2463 "*Regexp matching lines in a message header that are not to be shown. | |
2464 Do not alter this variable directly. Instead, customize | |
2465 `mh-invisible-header-fields-default' checking for fields normally | |
2466 hidden that you wish to display, and add extra entries to hide in | |
2467 `mh-invisible-header-fields'.") | |
2468 | |
2469 (defun mh-invisible-headers () | |
2470 "Make or remake the variable `mh-invisible-header-fields-compiled'. | |
2471 Done using `mh-invisible-header-fields-internal' as input, from | |
2472 which entries from `mh-invisible-header-fields-default' are | |
2473 removed and entries from `mh-invisible-header-fields' are added." | |
2474 (let ((fields mh-invisible-header-fields-internal)) | |
2475 (when mh-invisible-header-fields-default | |
2476 ;; Remove entries from `mh-invisible-header-fields-default' | |
2477 (setq fields | |
2478 (loop for x in fields | |
2479 unless (member x mh-invisible-header-fields-default) | |
2480 collect x))) | |
2481 (when (and (boundp 'mh-invisible-header-fields) | |
2482 mh-invisible-header-fields) | |
2483 (dolist (x mh-invisible-header-fields) | |
2484 (unless (member x fields) (setq fields (cons x fields))))) | |
2485 (if fields | |
2486 (setq mh-invisible-header-fields-compiled | |
2487 (concat | |
2488 "^" | |
2489 ;; workaround for insufficient default | |
2490 (let ((max-specpdl-size 1000)) | |
2491 (regexp-opt fields t)))) | |
2492 (setq mh-invisible-header-fields-compiled nil)))) | |
2493 | |
2494 ;; Compile invisible header fields. | |
2495 (mh-invisible-headers) | |
2496 | |
2497 (defcustom mh-lpr-command-format "lpr -J '%s'" | |
2498 "*Command used to print\\<mh-folder-mode-map>. | |
2499 | |
2500 This option contains the Unix command line which performs the | |
2501 actual printing for the \\[mh-print-msg] command. The string can | |
2502 contain one escape, \"%s\", which is replaced by the name of the | |
2503 folder and the message number and is useful for print job names. | |
2504 I use \"mpage -h'%s' -b Letter -H1of -mlrtb -P\" which produces a | |
2505 nice header and adds a bit of margin so the text fits within my | |
2506 printer's margins. | |
2507 | |
2508 This options is not used by the commands \\[mh-ps-print-msg] or | |
2509 \\[mh-ps-print-msg-file]." | |
2510 :type 'string | |
2511 :group 'mh-show) | |
2512 | |
2513 (defcustom mh-max-inline-image-height nil | |
2514 "*Maximum inline image height if \"Content-Disposition:\" is not present. | |
2515 | |
2516 Some older mail programs do not insert this needed plumbing to | |
2517 tell MH-E whether to display the attachments inline or not. If | |
2518 this is the case, MH-E will display these images inline if they | |
2519 are smaller than the window. However, you might want to allow | |
2520 larger images to be displayed inline. To do this, you can change | |
2521 the options `mh-max-inline-image-width' and | |
2522 `mh-max-inline-image-height' from their default value of zero to | |
2523 a large number. The size of your screen is a good choice for | |
2524 these numbers." | |
2525 :type '(choice (const nil) integer) | |
2526 :group 'mh-show) | |
2527 | |
2528 (defcustom mh-max-inline-image-width nil | |
2529 "*Maximum inline image width if \"Content-Disposition:\" is not present. | |
2530 | |
2531 Some older mail programs do not insert this needed plumbing to | |
2532 tell MH-E whether to display the attachments inline or not. If | |
2533 this is the case, MH-E will display these images inline if they | |
2534 are smaller than the window. However, you might want to allow | |
2535 larger images to be displayed inline. To do this, you can change | |
2536 the options `mh-max-inline-image-width' and | |
2537 `mh-max-inline-image-height' from their default value of zero to | |
2538 a large number. The size of your screen is a good choice for | |
2539 these numbers." | |
2540 :type '(choice (const nil) integer) | |
2541 :group 'mh-show) | |
2542 | |
2543 (defcustom mh-mhl-format-file nil | |
2544 "*Specifies the format file to pass to the \"mhl\" program. | |
2545 | |
2546 Normally MH-E takes care of displaying messages itself (rather than | |
2547 calling an MH program to do the work). If you'd rather have \"mhl\" | |
2548 display the message (within MH-E), change this option from its default | |
2549 value of \"Use Default mhl Format (Printing Only)\". | |
2550 | |
2551 You can set this option to \"Use Default mhl Format\" to get the same | |
2552 output as you would get if you ran \"mhl\" from the shell. | |
2553 | |
2554 If you have a format file that you want MH-E to use, you can set this | |
2555 option to \"Specify an mhl Format File\" and enter the name of your | |
2556 format file. Your format file should specify a non-zero value for | |
2557 \"overflowoffset\" to allow MH-E to parse the header. Note that | |
2558 \"mhl\" is always used for printing and forwarding; in this case, the | |
2559 value of this option is consulted if you have specified a format | |
2560 file." | |
2561 :type '(choice (const :tag "Use Default mhl Format (Printing Only)" nil) | |
2562 (const :tag "Use Default mhl Format" t) | |
2563 (file :tag "Specify an mhl Format File")) | |
2564 :group 'mh-show) | |
2565 | |
2566 (defcustom mh-mime-save-parts-default-directory t | |
2567 "Default directory to use for \\<mh-folder-mode-map>\\[mh-mime-save-parts]. | |
2568 | |
2569 The default value for this option is \"Prompt Always\" so that | |
2570 you are always prompted for the directory in which to save the | |
2571 attachments. However, if you usually use the same directory | |
2572 within a session, then you can set this option to \"Prompt the | |
2573 First Time\" to avoid the prompt each time. you can make this | |
2574 directory permanent by choosing \"Directory\" and entering the | |
2575 directory's name." | |
2576 :type '(choice (const :tag "Prompt the First Time" nil) | |
2577 (const :tag "Prompt Always" t) | |
2578 directory) | |
2579 :group 'mh-show) | |
2580 | |
2581 (defcustom mh-print-background-flag nil | |
2582 "*Non-nil means messages should be printed in the background\\<mh-folder-mode-map>. | |
2583 | |
2584 Normally messages are printed in the foreground. If this is slow on | |
2585 your system, you may elect to turn off this option to print in the | |
2586 background. | |
2587 | |
2588 WARNING: If you do this, do not delete the message until it is printed | |
2589 or else the output may be truncated. | |
2590 | |
2591 This option is not used by the commands \\[mh-ps-print-msg] or | |
2592 \\[mh-ps-print-msg-file]." | |
2593 :type 'boolean | |
2594 :group 'mh-show) | |
2595 | |
2596 (defcustom mh-show-maximum-size 0 | |
2597 "*Maximum size of message (in bytes) to display automatically. | |
2598 | |
2599 This option provides an opportunity to skip over large messages | |
2600 which may be slow to load. The default value of 0 means that all | |
2601 message are shown regardless of size." | |
2602 :type 'integer | |
2603 :group 'mh-show) | |
2604 | |
2605 (defcustom mh-show-use-goto-addr-flag (and (boundp 'goto-address-highlight-p) | |
2606 goto-address-highlight-p) | |
2607 "*Non-nil means highlight URLs and email addresses\\<goto-address-highlight-keymap>. | |
2608 | |
2609 To send a message using the highlighted email address or to view | |
2610 the web page for the highlighted URL, use the middle mouse button | |
2611 or \\[goto-address-at-point]. | |
2612 | |
2613 See Info node `(mh-e)Sending Mail' to see how to configure Emacs | |
2614 to send the message using MH-E. | |
2615 | |
2616 The default value of this option comes from the value of | |
2617 `goto-address-highlight-p'." | |
2618 :type 'boolean | |
2619 :group 'mh-show) | |
2620 | |
2621 (defcustom mh-show-use-xface-flag (>= emacs-major-version 21) | |
2622 "*Non-nil means display face images in MH-show buffers. | |
2623 | |
2624 MH-E can display the content of \"Face:\", \"X-Face:\", and | |
2625 \"X-Image-URL:\" header fields. If any of these fields occur in the | |
2626 header of your message, the sender's face will appear in the \"From:\" | |
2627 header field. If more than one of these fields appear, then the first | |
2628 field found in the order \"Face:\", \"X-Face:\", and \"X-Image-URL:\" | |
2629 will be used. | |
2630 | |
2631 The option `mh-show-use-xface-flag' is used to turn this feature on | |
2632 and off. This feature will be turned on by default if your system | |
2633 supports it. | |
2634 | |
2635 The first header field used, if present, is the Gnus-specific | |
2636 \"Face:\" field. The \"Face:\" field appeared in GNU Emacs 21 and | |
2637 XEmacs. For more information, see URL | |
2638 `http://quimby.gnus.org/circus/face/'. Next is the traditional | |
2639 \"X-Face:\" header field. The display of this field requires the | |
2640 \"uncompface\" program (see URL | |
2641 `ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z'). Recent | |
2642 versions of XEmacs have internal support for \"X-Face:\" images. If | |
2643 your version of XEmacs does not, then you'll need both \"uncompface\" | |
2644 and the x-face package (see URL `ftp://ftp.jpl.org/pub/elisp/'). | |
2645 | |
2646 Finally, MH-E will display images referenced by the \"X-Image-URL:\" | |
2647 header field if neither the \"Face:\" nor the \"X-Face:\" fields are | |
2648 present. The display of the images requires \"wget\" (see URL | |
2649 `http://www.gnu.org/software/wget/wget.html'), \"fetch\", or \"curl\" | |
2650 to fetch the image and the \"convert\" program from the ImageMagick | |
2651 suite (see URL `http://www.imagemagick.org/'). Of the three header | |
2652 fields this is the most efficient in terms of network usage since the | |
2653 image doesn't need to be transmitted with every single mail. | |
2654 | |
2655 The option `mh-fetch-x-image-url' controls the fetching of the | |
2656 \"X-Image-URL:\" header field image." | |
2657 :type 'boolean | |
2658 :group 'mh-show) | |
2659 | |
2660 (defcustom mh-store-default-directory nil | |
2661 "*Default directory for \\<mh-folder-mode-map>\\[mh-store-msg]. | |
2662 | |
2663 If you would like to change the initial default directory, | |
2664 customize this option, change the value from \"Current\" to | |
2665 \"Directory\", and then enter the name of the directory for storing | |
2666 the content of these messages." | |
2667 :type '(choice (const :tag "Current" nil) | |
2668 directory) | |
2669 :group 'mh-show) | |
2670 | |
2671 (defcustom mh-summary-height nil | |
2672 "*Number of lines in MH-Folder buffer (including the mode line). | |
2673 | |
2674 The default value of this option is \"Automatic\" which means | |
2675 that the MH-Folder buffer will maintain the same proportional | |
2676 size if the frame is resized. If you'd prefer a fixed height, | |
2677 then choose the \"Fixed Size\" option and enter the number of | |
2678 lines you'd like to see." | |
2679 :type '(choice (const :tag "Automatic" nil) | |
2680 (integer :tag "Fixed Size")) | |
2681 :group 'mh-show) | |
2682 | |
2683 | |
2684 | |
2685 ;;; The Speedbar (:group 'mh-speedbar) | |
2686 | |
2687 (defcustom mh-speed-update-interval 60 | |
2688 "Time between speedbar updates in seconds. | |
2689 Set to 0 to disable automatic update." | |
2690 :type 'integer | |
2691 :group 'mh-speedbar) | |
2692 | |
2693 | |
2694 | |
2695 ;;; Threading (:group 'mh-thread) | |
2696 | |
2697 (defcustom mh-show-threads-flag nil | |
2698 "*Non-nil means new folders start in threaded mode. | |
2699 | |
2700 Threading large number of messages can be time consuming so this | |
2701 option is turned off by default. If you turn this option on, then | |
2702 threading will be done only if the number of messages being | |
2703 threaded is less than `mh-large-folder'." | |
2704 :type 'boolean | |
2705 :group 'mh-thread) | |
2706 | |
2707 | |
2708 | |
2709 ;;; The Tool Bar (:group 'mh-tool-bar) | |
2710 | |
2711 ;; mh-tool-bar-folder-buttons and mh-tool-bar-letter-buttons defined | |
2712 ;; dynamically in mh-tool-bar.el. | |
2713 | |
2714 (defcustom mh-tool-bar-search-function 'mh-search | |
2715 "*Function called by the tool bar search button. | |
2716 | |
2717 By default, this is set to `mh-search'. You can also choose | |
2718 \"Other Function\" from the \"Value Menu\" and enter a function | |
2719 of your own choosing." | |
2720 :type '(choice (const mh-search) | |
2721 (function :tag "Other Function")) | |
2722 :group 'mh-tool-bar) | |
2723 | |
2724 ;; XEmacs has a couple of extra customizations... | |
2725 (mh-do-in-xemacs | |
2726 (defcustom mh-xemacs-use-tool-bar-flag mh-xemacs-has-tool-bar-flag | |
2727 "*If non-nil, use tool bar. | |
2728 | |
2729 This option controls whether to show the MH-E icons at all. By | |
2730 default, this option is turned on if the window system supports | |
2731 tool bars. If your system doesn't support tool bars, then you | |
2732 won't be able to turn on this option." | |
2733 :type 'boolean | |
2734 :group 'mh-tool-bar | |
2735 :set (lambda (symbol value) | |
2736 (if (and (eq value t) | |
2737 (not mh-xemacs-has-tool-bar-flag)) | |
2738 (error "Tool bar not supported")) | |
2739 (set-default symbol value))) | |
2740 | |
2741 (defcustom mh-xemacs-tool-bar-position nil | |
2742 "*Tool bar location. | |
2743 | |
2744 This option controls the placement of the tool bar along the four | |
2745 edges of the frame. You can choose from one of \"Same As Default | |
2746 Tool Bar\", \"Top\", \"Bottom\", \"Left\", or \"Right\". If this | |
2747 variable is set to anything other than \"Same As Default Tool | |
2748 Bar\" and the default tool bar is in a different location, then | |
2749 two tool bars will be displayed: the MH-E tool bar and the | |
2750 default tool bar." | |
2751 :type '(radio (const :tag "Same As Default Tool Bar" :value nil) | |
2752 (const :tag "Top" :value top) | |
2753 (const :tag "Bottom" :value bottom) | |
2754 (const :tag "Left" :value left) | |
2755 (const :tag "Right" :value right)) | |
2756 :group 'mh-tool-bar)) | |
2757 | |
2758 | |
2759 | |
2760 ;;; Hooks (:group 'mh-hooks + group where hook described) | |
2761 | |
2762 (defcustom mh-after-commands-processed-hook nil | |
2763 "Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] after performing outstanding requests. | |
2764 | |
2765 Variables that are useful in this hook include | |
2766 `mh-folders-changed', which lists which folders were affected by | |
2767 deletes and refiles. This list will always include the current | |
2768 folder, which is also available in `mh-current-folder'." | |
2769 :type 'hook | |
2770 :group 'mh-hooks | |
2771 :group 'mh-folder) | |
2772 | |
2773 (defcustom mh-alias-reloaded-hook nil | |
2774 "Hook run by `mh-alias-reload' after loading aliases." | |
2775 :type 'hook | |
2776 :group 'mh-hooks | |
2777 :group 'mh-alias) | |
2778 | |
2779 (defcustom mh-before-commands-processed-hook nil | |
2780 "Hook run by \\<mh-folder-mode-map>\\[mh-execute-commands] before performing outstanding requests. | |
2781 | |
2782 Variables that are useful in this hook include `mh-delete-list' | |
2783 and `mh-refile-list' which can be used to see which changes will | |
2784 be made to the current folder, `mh-current-folder'." | |
2785 :type 'hook | |
2786 :group 'mh-hooks | |
2787 :group 'mh-folder) | |
2788 | |
2789 (defcustom mh-before-quit-hook nil | |
2790 "Hook run by \\<mh-folder-mode-map>\\[mh-quit] before quitting MH-E. | |
2791 | |
2792 This hook is called before the quit occurs, so you might use it | |
2793 to perform any MH-E operations; you could perform some query and | |
2794 abort the quit or call `mh-execute-commands', for example. | |
2795 | |
2796 See also `mh-quit-hook'." | |
2797 :type 'hook | |
2798 :group 'mh-hooks | |
2799 :group 'mh-folder) | |
2800 | |
2801 (defcustom mh-before-send-letter-hook nil | |
2802 "Hook run at the beginning of the \\<mh-letter-mode-map>\\[mh-send-letter] command. | |
2803 | |
2804 For example, if you want to check your spelling in your message | |
2805 before sending, add the `ispell-message' function." | |
2806 :type 'hook | |
2807 :options '(ispell-message) | |
2808 :group 'mh-hooks | |
2809 :group 'mh-letter) | |
2810 | |
2811 (defcustom mh-delete-msg-hook nil | |
2812 "Hook run by \\<mh-letter-mode-map>\\[mh-delete-msg] after marking each message for deletion. | |
2813 | |
2814 For example, a past maintainer of MH-E used this once when he | |
2815 kept statistics on his mail usage." | |
2816 :type 'hook | |
2817 :group 'mh-hooks | |
2818 :group 'mh-show) | |
2819 | |
2820 (defcustom mh-find-path-hook nil | |
2821 "Hook run by `mh-find-path' after reading the user's MH profile. | |
2822 | |
2823 This hook can be used the change the value of the variables that | |
2824 `mh-find-path' sets if you need to run with different values | |
2825 between MH and MH-E." | |
2826 :type 'hook | |
2827 :group 'mh-hooks | |
2828 :group 'mh-e) | |
2829 | |
2830 (defcustom mh-folder-mode-hook nil | |
2831 "Hook run by `mh-folder-mode' when visiting a new folder." | |
2832 :type 'hook | |
2833 :group 'mh-hooks | |
2834 :group 'mh-folder) | |
2835 | |
2836 (defcustom mh-forward-hook nil | |
2837 "Hook run by `mh-forward' on a forwarded letter." | |
2838 :type 'hook | |
2839 :group 'mh-hooks | |
2840 :group 'mh-sending-mail) | |
2841 | |
2842 (defcustom mh-inc-folder-hook nil | |
2843 "Hook run by \\<mh-folder-mode-map>\\[mh-inc-folder] after incorporating mail into a folder." | |
2844 :type 'hook | |
2845 :group 'mh-hooks | |
2846 :group 'mh-inc) | |
2847 | |
2848 (defcustom mh-insert-signature-hook nil | |
2849 "Hook run by \\<mh-letter-mode-map>\\[mh-insert-signature] after signature has been inserted. | |
2850 | |
2851 Hook functions may access the actual name of the file or the | |
2852 function used to insert the signature with | |
2853 `mh-signature-file-name'." | |
2854 :type 'hook | |
2855 :group 'mh-hooks | |
2856 :group 'mh-letter) | |
2857 | |
2858 (defcustom mh-kill-folder-suppress-prompt-hooks '(mh-search-p) | |
2859 "Abnormal hook run at the beginning of \\<mh-folder-mode-map>\\[mh-kill-folder]. | |
2860 | |
2861 The hook functions are called with no arguments and should return | |
2862 a non-nil value to suppress the normal prompt when you remove a | |
2863 folder. This is useful for folders that are easily regenerated. | |
2864 | |
2865 The default value of `mh-search-p' suppresses the prompt on | |
2866 folders generated by searching. | |
2867 | |
2868 WARNING: Use this hook with care. If there is a bug in your hook | |
2869 which returns t on \"+inbox\" and you hit \\[mh-kill-folder] by | |
2870 accident in the \"+inbox\" folder, you will not be happy." | |
2871 :type 'hook | |
2872 :group 'mh-hooks | |
2873 :group 'mh-folder) | |
2874 | |
2875 (defcustom mh-letter-mode-hook nil | |
2876 "Hook run by `mh-letter-mode' on a new letter. | |
2877 | |
2878 This hook allows you to do some processing before editing a | |
2879 letter. For example, you may wish to modify the header after | |
2880 \"repl\" has done its work, or you may have a complicated | |
2881 \"components\" file and need to tell MH-E where the cursor should | |
2882 go." | |
2883 :type 'hook | |
2884 :group 'mh-hooks | |
2885 :group 'mh-sending-mail) | |
2886 | |
2887 (defcustom mh-mh-to-mime-hook nil | |
2888 "Hook run on the formatted letter by \\<mh-letter-mode-map>\\[mh-mh-to-mime]." | |
2889 :type 'hook | |
2890 :group 'mh-hooks | |
2891 :group 'mh-letter) | |
2892 | |
2893 (defcustom mh-search-mode-hook nil | |
2894 "Hook run upon entry to `mh-search-mode'\\<mh-folder-mode-map>. | |
2895 | |
2896 If you find that you do the same thing over and over when editing | |
2897 the search template, you may wish to bind some shortcuts to keys. | |
2898 This can be done with this hook which is called when | |
2899 \\[mh-search] is run on a new pattern." | |
2900 :type 'hook | |
2901 :group 'mh-hooks | |
2902 :group 'mh-search) | |
2903 | |
2904 (defcustom mh-quit-hook nil | |
2905 "Hook run by \\<mh-folder-mode-map>\\[mh-quit] after quitting MH-E. | |
2906 | |
2907 This hook is not run in an MH-E context, so you might use it to | |
2908 modify the window setup. | |
2909 | |
2910 See also `mh-before-quit-hook'." | |
2911 :type 'hook | |
2912 :group 'mh-hooks | |
2913 :group 'mh-folder) | |
2914 | |
2915 (defcustom mh-refile-msg-hook nil | |
2916 "Hook run by \\<mh-folder-mode-map>\\[mh-refile-msg] after marking each message for refiling." | |
2917 :type 'hook | |
2918 :group 'mh-hooks | |
2919 :group 'mh-folder) | |
2920 | |
2921 (defcustom mh-show-hook nil | |
2922 "Hook run after \\<mh-folder-mode-map>\\[mh-show] shows a message. | |
2923 | |
2924 It is the last thing called after messages are displayed. It's | |
2925 used to affect the behavior of MH-E in general or when | |
2926 `mh-show-mode-hook' is too early. See `mh-show-mode-hook'." | |
2927 :type 'hook | |
2928 :group 'mh-hooks | |
2929 :group 'mh-show) | |
2930 | |
2931 (defcustom mh-show-mode-hook nil | |
2932 "Hook run upon entry to `mh-show-mode'. | |
2933 | |
2934 This hook is called early on in the process of the message | |
2935 display. It is usually used to perform some action on the | |
2936 message's content. See `mh-show-hook'." | |
2937 :type 'hook | |
2938 :group 'mh-hooks | |
2939 :group 'mh-show) | |
2940 | |
2941 (defcustom mh-unseen-updated-hook nil | |
2942 "Hook run after the unseen sequence has been updated. | |
2943 | |
2944 The variable `mh-seen-list' can be used by this hook to obtain | |
2945 the list of messages which were removed from the unseen | |
2946 sequence." | |
2947 :type 'hook | |
2948 :group 'mh-hooks | |
2949 :group 'mh-sequences) | |
2950 | |
2951 | |
2952 | |
2953 ;;; Faces (:group 'mh-faces + group where faces described) | |
2954 | |
2955 (if (boundp 'facemenu-unlisted-faces) | |
2956 (add-to-list 'facemenu-unlisted-faces "^mh-")) | |
2957 | |
2958 (defvar mh-min-colors-defined-flag (and (not mh-xemacs-flag) | |
2959 (>= emacs-major-version 22)) | |
2960 "Non-nil means defface supports min-colors display requirement.") | |
2961 | |
2962 (defun mh-defface-compat (spec) | |
2963 "Convert SPEC for defface if necessary to run on older platforms. | |
2964 Modifies SPEC in place and returns it. See `defface' for the spec definition. | |
2965 | |
2966 When `mh-min-colors-defined-flag' is nil, this function finds | |
2967 display entries with \"min-colors\" requirements and either | |
2968 removes the \"min-colors\" requirement or strips the display | |
2969 entirely if the display does not support the number of specified | |
2970 colors." | |
2971 (if mh-min-colors-defined-flag | |
2972 spec | |
2973 (let ((cells (display-color-cells)) | |
2974 new-spec) | |
2975 ;; Remove entries with min-colors, or delete them if we have fewer colors | |
2976 ;; than they specify. | |
2977 (loop for entry in (reverse spec) do | |
2978 (let ((requirement (if (eq (car entry) t) | |
2979 nil | |
2980 (assoc 'min-colors (car entry))))) | |
2981 (if requirement | |
2982 (when (>= cells (nth 1 requirement)) | |
2983 (setq new-spec (cons (cons (delq requirement (car entry)) | |
2984 (cdr entry)) | |
2985 new-spec))) | |
2986 (setq new-spec (cons entry new-spec))))) | |
2987 new-spec))) | |
2988 | |
2989 (defface mh-folder-address '((t (:inherit mh-folder-subject))) | |
2990 "Recipient face." | |
2991 :group 'mh-faces | |
2992 :group 'mh-folder) | |
2993 | |
2994 (defface mh-folder-body | |
2995 '((((class color)) | |
2996 (:inherit mh-folder-msg-number)) | |
2997 (t | |
2998 (:inherit mh-folder-msg-number :italic t))) | |
2999 "Body text face." | |
3000 :group 'mh-faces | |
3001 :group 'mh-folder) | |
3002 | |
3003 (defface mh-folder-cur-msg-number | |
3004 '((t | |
3005 (:inherit mh-folder-msg-number :bold t))) | |
3006 "Current message number face." | |
3007 :group 'mh-faces | |
3008 :group 'mh-folder) | |
3009 | |
3010 (defface mh-folder-date '((t (:inherit mh-folder-msg-number))) | |
3011 "Date face." | |
3012 :group 'mh-faces | |
3013 :group 'mh-folder) | |
3014 | |
3015 (defface mh-folder-deleted '((t (:inherit mh-folder-msg-number))) | |
3016 "Deleted message face." | |
3017 :group 'mh-faces | |
3018 :group 'mh-folder) | |
3019 | |
3020 (defface mh-folder-followup | |
3021 '((((class color) (background light)) | |
3022 (:foreground "blue3")) | |
3023 (((class color) (background dark)) | |
3024 (:foreground "LightGoldenRod")) | |
3025 (t | |
3026 (:bold t))) | |
3027 "\"Re:\" face." | |
3028 :group 'mh-faces | |
3029 :group 'mh-folder) | |
3030 | |
3031 (defface mh-folder-msg-number | |
3032 (mh-defface-compat | |
3033 '((((class color) (min-colors 88) (background light)) | |
3034 (:foreground "snow4")) | |
3035 (((class color) (min-colors 88) (background dark)) | |
3036 (:foreground "snow3")) | |
3037 (((class color)) | |
3038 (:foreground "cyan")))) | |
3039 | |
3040 "Message number face." | |
3041 :group 'mh-faces | |
3042 :group 'mh-folder) | |
3043 | |
3044 (defface mh-folder-refiled | |
3045 (mh-defface-compat | |
3046 '((((class color) (min-colors 88) (background light)) | |
3047 (:foreground "DarkGoldenrod")) | |
3048 (((class color) (min-colors 88) (background dark)) | |
3049 (:foreground "LightGoldenrod")) | |
3050 (((class color)) | |
3051 (:foreground "yellow" :weight light)) | |
3052 (((class grayscale) (background light)) | |
3053 (:foreground "Gray90" :bold t :italic t)) | |
3054 (((class grayscale) (background dark)) | |
3055 (:foreground "DimGray" :bold t :italic t)) | |
3056 (t | |
3057 (:bold t :italic t)))) | |
3058 "Refiled message face." | |
3059 :group 'mh-faces | |
3060 :group 'mh-folder) | |
3061 | |
3062 (defface mh-folder-sent-to-me-hint '((t (:inherit mh-folder-date))) | |
3063 "Fontification hint face in messages sent directly to us. | |
3064 The detection of messages sent to us is governed by the scan | |
3065 format `mh-scan-format-nmh' and the regular expression | |
3066 `mh-scan-sent-to-me-sender-regexp'." | |
3067 :group 'mh-faces | |
3068 :group 'mh-folder) | |
3069 | |
3070 (defface mh-folder-sent-to-me-sender '((t (:inherit mh-folder-followup))) | |
3071 "Sender face in messages sent directly to us. | |
3072 The detection of messages sent to us is governed by the scan | |
3073 format `mh-scan-format-nmh' and the regular expression | |
3074 `mh-scan-sent-to-me-sender-regexp'." | |
3075 :group 'mh-faces | |
3076 :group 'mh-folder) | |
3077 | |
3078 (defface mh-folder-subject | |
3079 '((((class color) (background light)) | |
3080 (:foreground "blue4")) | |
3081 (((class color) (background dark)) | |
3082 (:foreground "yellow")) | |
3083 (t | |
3084 (:bold t))) | |
3085 "Subject face." | |
3086 :group 'mh-faces | |
3087 :group 'mh-folder) | |
3088 | |
3089 (defface mh-folder-tick | |
3090 '((((class color) (background dark)) | |
3091 (:background "#dddf7e")) | |
3092 (((class color) (background light)) | |
3093 (:background "#dddf7e")) | |
3094 (t | |
3095 (:underline t))) | |
3096 "Ticked message face." | |
3097 :group 'mh-faces | |
3098 :group 'mh-folder) | |
3099 | |
3100 (defface mh-folder-to | |
3101 (mh-defface-compat | |
3102 '((((class color) (min-colors 88) (background light)) | |
3103 (:foreground "RosyBrown")) | |
3104 (((class color) (min-colors 88) (background dark)) | |
3105 (:foreground "LightSalmon")) | |
3106 (((class color)) | |
3107 (:foreground "green")) | |
3108 (((class grayscale) (background light)) | |
3109 (:foreground "DimGray" :italic t)) | |
3110 (((class grayscale) (background dark)) | |
3111 (:foreground "LightGray" :italic t)) | |
3112 (t | |
3113 (:italic t)))) | |
3114 "\"To:\" face." | |
3115 :group 'mh-faces | |
3116 :group 'mh-folder) | |
3117 | |
3118 (defface mh-search-folder | |
3119 '((((class color) (background light)) | |
3120 (:foreground "dark green" :bold t)) | |
3121 (((class color) (background dark)) | |
3122 (:foreground "indian red" :bold t)) | |
3123 (t | |
3124 (:bold t))) | |
3125 "Folder heading face in MH-Folder buffers created by searches." | |
3126 :group 'mh-faces | |
3127 :group 'mh-search) | |
3128 | |
3129 (defface mh-letter-header-field | |
3130 '((((class color) (background light)) | |
3131 (:background "gray90")) | |
3132 (((class color) (background dark)) | |
3133 (:background "gray10")) | |
3134 (t | |
3135 (:bold t))) | |
3136 "Editable header field value face in draft buffers." | |
3137 :group 'mh-faces | |
3138 :group 'mh-letter) | |
3139 | |
3140 (defface mh-show-cc | |
3141 (mh-defface-compat | |
3142 '((((class color) (min-colors 88) (background light)) | |
3143 (:foreground "DarkGoldenrod")) | |
3144 (((class color) (min-colors 88) (background dark)) | |
3145 (:foreground "LightGoldenrod")) | |
3146 (((class color)) | |
3147 (:foreground "yellow" :weight light)) | |
3148 (((class grayscale) (background light)) | |
3149 (:foreground "Gray90" :bold t :italic t)) | |
3150 (((class grayscale) (background dark)) | |
3151 (:foreground "DimGray" :bold t :italic t)) | |
3152 (t | |
3153 (:bold t :italic t)))) | |
3154 "Face used to highlight \"cc:\" header fields." | |
3155 :group 'mh-faces | |
3156 :group 'mh-show) | |
3157 | |
3158 (defface mh-show-date | |
3159 (mh-defface-compat | |
3160 '((((class color) (min-colors 88) (background light)) | |
3161 (:foreground "ForestGreen")) | |
3162 (((class color) (min-colors 88) (background dark)) | |
3163 (:foreground "PaleGreen")) | |
3164 (((class color)) | |
3165 (:foreground "green")) | |
3166 (((class grayscale) (background light)) | |
3167 (:foreground "Gray90" :bold t)) | |
3168 (((class grayscale) (background dark)) | |
3169 (:foreground "DimGray" :bold t)) | |
3170 (t | |
3171 (:bold t :underline t)))) | |
3172 "Face used to highlight \"Date:\" header fields." | |
3173 :group 'mh-faces | |
3174 :group 'mh-show) | |
3175 | |
3176 (defface mh-show-from | |
3177 '((((class color) (background light)) | |
3178 (:foreground "red3")) | |
3179 (((class color) (background dark)) | |
3180 (:foreground "cyan")) | |
3181 (t | |
3182 (:bold t))) | |
3183 "Face used to highlight \"From:\" header fields." | |
3184 :group 'mh-faces | |
3185 :group 'mh-show) | |
3186 | |
3187 (defface mh-show-header | |
3188 (mh-defface-compat | |
3189 '((((class color) (min-colors 88) (background light)) | |
3190 (:foreground "RosyBrown")) | |
3191 (((class color) (min-colors 88) (background dark)) | |
3192 (:foreground "LightSalmon")) | |
3193 (((class color)) | |
3194 (:foreground "green")) | |
3195 (((class grayscale) (background light)) | |
3196 (:foreground "DimGray" :italic t)) | |
3197 (((class grayscale) (background dark)) | |
3198 (:foreground "LightGray" :italic t)) | |
3199 (t | |
3200 (:italic t)))) | |
3201 "Face used to deemphasize less interesting header fields." | |
3202 :group 'mh-faces | |
3203 :group 'mh-show) | |
3204 | |
3205 (defface mh-show-pgg-bad '((t (:bold t :foreground "DeepPink1"))) | |
3206 "Bad PGG signature face." | |
3207 :group 'mh-faces | |
3208 :group 'mh-show) | |
3209 | |
3210 (defface mh-show-pgg-good '((t (:bold t :foreground "LimeGreen"))) | |
3211 "Good PGG signature face." | |
3212 :group 'mh-faces | |
3213 :group 'mh-show) | |
3214 | |
3215 (defface mh-show-pgg-unknown '((t (:bold t :foreground "DarkGoldenrod2"))) | |
3216 "Unknown or untrusted PGG signature face." | |
3217 :group 'mh-faces | |
3218 :group 'mh-show) | |
3219 | |
3220 (defface mh-show-signature '((t (:italic t))) | |
3221 "Signature face." | |
3222 :group 'mh-faces | |
3223 :group 'mh-show) | |
3224 | |
3225 (defface mh-show-subject '((t (:inherit mh-folder-subject))) | |
3226 "Face used to highlight \"Subject:\" header fields." | |
3227 :group 'mh-faces | |
3228 :group 'mh-show) | |
3229 | |
3230 (defface mh-show-to | |
3231 '((((class color) (background light)) | |
3232 (:foreground "SaddleBrown")) | |
3233 (((class color) (background dark)) | |
3234 (:foreground "burlywood")) | |
3235 (((class grayscale) (background light)) | |
3236 (:foreground "DimGray" :underline t)) | |
3237 (((class grayscale) (background dark)) | |
3238 (:foreground "LightGray" :underline t)) | |
3239 (t (:underline t))) | |
3240 "Face used to highlight \"To:\" header fields." | |
3241 :group 'mh-faces | |
3242 :group 'mh-show) | |
3243 | |
3244 (defface mh-show-xface '((t (:inherit (mh-show-from highlight)))) | |
3245 "X-Face image face. | |
3246 The background and foreground are used in the image." | |
3247 :group 'mh-faces | |
3248 :group 'mh-show) | |
3249 | |
3250 (defface mh-speedbar-folder | |
3251 '((((class color) (background light)) | |
3252 (:foreground "blue4")) | |
3253 (((class color) (background dark)) | |
3254 (:foreground "light blue"))) | |
3255 "Basic folder face." | |
3256 :group 'mh-faces | |
3257 :group 'mh-speedbar) | |
3258 | |
3259 (defface mh-speedbar-folder-with-unseen-messages | |
3260 '((t | |
3261 (:inherit mh-speedbar-folder :bold t))) | |
3262 "Folder face when folder contains unread messages." | |
3263 :group 'mh-faces | |
3264 :group 'mh-speedbar) | |
3265 | |
3266 (defface mh-speedbar-selected-folder | |
3267 '((((class color) (background light)) | |
3268 (:foreground "red1" :underline t)) | |
3269 (((class color) (background dark)) | |
3270 (:foreground "red1" :underline t)) | |
3271 (t | |
3272 (:underline t))) | |
3273 "Selected folder face." | |
3274 :group 'mh-faces | |
3275 :group 'mh-speedbar) | |
3276 | |
3277 (defface mh-speedbar-selected-folder-with-unseen-messages | |
3278 '((t | |
3279 (:inherit mh-speedbar-selected-folder :bold t))) | |
3280 "Selected folder face when folder contains unread messages." | |
3281 :group 'mh-faces | |
3282 :group 'mh-speedbar) | |
2848 | 3283 |
2849 (provide 'mh-e) | 3284 (provide 'mh-e) |
2850 | 3285 |
2851 ;; Local Variables: | 3286 ;; Local Variables: |
2852 ;; indent-tabs-mode: nil | 3287 ;; indent-tabs-mode: nil |